mcardle 2005/11/18 17:17:29 CET
Modified files:
src/org/jahia/esi GetThread.java
Log:
* supports HTTP redirection
* supports detailed error page
* deals with chunked HTTP transfers
* fixed URL escape problem
Revision Changes Path
1.7 +64 -23 esi_server/src/org/jahia/esi/GetThread.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/GetThread.java.diff?r1=1.6&r2=1.7&f=h
Index: GetThread.java
===================================================================
RCS file: /home/cvs/repository/esi_server/src/org/jahia/esi/GetThread.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- GetThread.java 8 Nov 2005 10:57:03 -0000 1.6
+++ GetThread.java 18 Nov 2005 16:17:29 -0000 1.7
@@ -60,6 +60,7 @@
private String urlToServer;
private String clientRequestUrl;
private boolean success = true;
+ private boolean redirectDetected = false;
long expirationDateInSecs = (new Date()).getTime();
long expirationInSecs = EsiConst.DEFAULT_EXPIRATION;
@@ -101,7 +102,9 @@
public String getUrlKey() {
return urlKey;
}
-
+ public int getId() {
+ return id;
+ }
public UrlCacheObject getUrlObj() {
return urlObj;
}
@@ -117,6 +120,14 @@
this.success = success;
}
+ public boolean isRedirectDetected() {
+ return redirectDetected;
+ }
+
+ public void setRedirectDetected(boolean redirectDetected) {
+ this.redirectDetected = redirectDetected;
+ }
+
/**
* Executes the GetMethod and prints some satus information.
*/
@@ -129,8 +140,11 @@
//******************** FETCH ************************
byte[] bytes = null;
+
try {
bytes = retrieveBytesFromServer();
+ ResponseHandlerBase.printRequestHeaders(this.methodToServer,
"from GetThread -"+id+"- for clientRequestUrl:"+clientRequestUrl);
+ ResponseHandlerBase.printResponseHeaders(this.methodToServer,
"from GetThread -"+id+"- for clientRequestUrl:"+clientRequestUrl);
}
catch (TransferFailedException e) {
log.error(id + " - error: " + e);
@@ -138,13 +152,24 @@
String urlKey =
CacheAdminstrator.getInstance().generateEntryKey("GET" , clientRequestUrl );
StringBuffer errorMsg = new StringBuffer("<b>ESI ERROR: Could
not fetch the object (urlKey:[").append(urlKey).append("]) due to error: ");
errorMsg.append(e.toString()).append(" - Http Status Code
").append(this.methodToServer.getStatusLine().toString())
- .append(" - for client request:
").append(clientRequestUrl).append("</b>");
- fragmentCache.addUnfectched ( urlKey , this.methodToServer ,
errorMsg.toString() , this.clientRequestUrl);
+ .append(" - for client request:
").append(clientRequestUrl).append("</b> <br><br>Exception: " +
e.toString()).append(new String(bytes));
+ fragmentCache.addUnfectched ( urlKey ,
+ this.methodToServer ,
+ Utils.getErrorPage(errorMsg.toString()) ,
+ this.clientRequestUrl);
+ return;
+ }
+ catch (RedirectException e) {
+ setSuccess(false);
+ setRedirectDetected(true);
+ String urlKey =
CacheAdminstrator.getInstance().generateEntryKey("GET" , clientRequestUrl );
+ fragmentCache.addUnfectched ( urlKey , this.methodToServer ,
"Redirected - this should never appear anywhere to the browser" ,
this.clientRequestUrl);
return;
}
//******************** CHECK CONTENT TYPE ************************
//***********************************************
+ //TODO: forget about contentLength when Transfer-Encoding=chunked !
int contentLength = -1;
try {
String contentLengthStr =
methodToServer.getResponseHeader("Content-Length").getValue().toLowerCase();
@@ -182,6 +207,9 @@
//if (contentLength !=-1 &&
contentLength<CACHEABLE_CONTENT_MAX_SIZE_BYTES ) {
// TODO: revert to Cacheless Passthrough for content which is
over the threshold size
+ // a bit too late though since we have already transfered
it
+ // maybe just detect content length, if available, and
quit. If no content length, then just go ahead with caching
+ //TODO: forget about contentLength when
Transfer-Encoding=chunked !
//}
//send to user by returning
@@ -214,7 +242,7 @@
removeTagsToReplace.add(esiRemove);
}
else if (node instanceof EsiIncludeTag) {
- log.debug("detected node : "+node.toHtml());
+ log.debug(id + " -detected node : "+node.toHtml());
esiT = (EsiIncludeTag) node;
String src = esiT.getAttribute("src");
@@ -229,13 +257,13 @@
//Need to support all other methods POST
!!!!!!!!!!!!!!!!!!!!!!
GetMethod tagGetMethod =
Utils.copyMethod(methodToServer);
try {
- URI uri = new URI(src); //TODO: what is this
esacpe shit
+ URI uri = new URI(src, true); //TODO: what is
this esacpe shit
tagGetMethod.setURI(uri);
} catch (URIException e) {
e.printStackTrace(); //To change body of catch
statement use File | Settings | File Templates.
}
- tagGetMethod.setFollowRedirects(true);
+ tagGetMethod.setFollowRedirects(false);
//TODO: statusCode ??
//TODO: cookies??
//TODO: esi headers??
@@ -252,12 +280,13 @@
null //because this is an internal demand
and there is no clientRequestUrl
);
threads.add(thread);
+ thread.setName("from:GetThread,["+
tagCacheKey.substring(tagCacheKey.length()-15)+"]id:"+id);
thread.start();
}
+
}
}
-
//wait for each thread to finish before continuing
Enumeration threadEnum = threads.elements();
while (threadEnum.hasMoreElements()) {
@@ -270,6 +299,7 @@
}
}
+
String[] refObjs = new String[tagsToReplace.size()];
String[] refObjsUrls = new String[tagsToReplace.size()];
int[] referencedObjsStartIndex = new int[tagsToReplace.size()];
@@ -298,7 +328,7 @@
log.debug(id + " replacing node : "+esiTag.toHtml()+" with
cached content of length ["+cachedByteContent.length+"]");
//TODO: should really implement a NodeList.replace method
esiTag.setTagName ("WAS:ESIINCLUDECLASS");
- esiTag.setEndTag(new EsiIncludeTag());
+ //esiTag.setEndTag(new EsiIncludeTag());
removeAllAttributes(esiTag);
TextNode fragContentTextNode = new TextNode (new
String(cachedByteContent));
NodeList children = new NodeList (fragContentTextNode);
@@ -323,7 +353,7 @@
log.debug(id + "clearing esi:REMOVE node :
"+esiRemoveTag.toHtml()+" ");
esiRemoveTag.setTagName ("WAS:ESIREMOVECLASS");
- esiRemoveTag.setEndTag(new EsiRemoveTag());
+ //esiRemoveTag.setEndTag(new EsiRemoveTag());
TextNode blankContentTextNode = new TextNode (new
String(""));
NodeList children = new NodeList (blankContentTextNode);
esiRemoveTag.setChildren (children);
@@ -356,7 +386,7 @@
private byte[] retrieveBytesFromServer()
- throws TransferFailedException {
+ throws TransferFailedException, RedirectException {
byte[] bytes = null;
@@ -402,18 +432,21 @@
if (bytes==null) {
log.error(id + " - bytes is NULL. No content
returned. bytes["+bytes+"]");
- log.error(id + " - therefore setting it to some
random one byte value. ++++++++++++++++++++++++++++++");
+ log.error(id + " - therefore setting it to 0 byte
value. ++++++++++++++++++++++++++++++");
bytes[0] = 0;
}
log.debug(id + " - " + bytes.length + " bytes read");
-
- //TODO: NEED TO CHECK RESPONSE ESI HEADERS
}
+ //HttpClient will automatically retry up to 5 times those
methods that fail
+ // with a transport exception while the HTTP request is
still being transmitted to the target server
+ //But HttpClient will make no attempt to recover from any
logical or HTTP protocol error
+ // (those derived from HttpException class).
catch (HttpException e )
//catch ( HttpRecoverableException e )
{
attempt++;
+ log.info(id + " -Error retrieving ["+urlToServer+"] on
attempt ["+attempt+"] due to HttpException:"+e+", but trying again.");
}
catch ( IOException e )
{
@@ -423,6 +456,11 @@
}
+ if (attempt >=
GeneralSettings.getInstance().getNumberOfAttempts()) {
+ log.error(id + " - Error retrieving ["+urlToServer+"] after
["+attempt+"] attempts.");
+ throw new TransferFailedException( "Error retrieving
["+urlToServer+"] after ["+attempt+"] attempts." );
+ }
+
// Check that we didn't run out of retries.
switch ( statusCode )
{
@@ -436,21 +474,26 @@
throw new TransferFailedException(
"Failed to transfer file: " + urlToServer + "
after " + attempt + " attempts" );
case HttpStatus.SC_FORBIDDEN:
- throw new TransferFailedException( "Access denided to: "
+ urlToServer );
+ throw new TransferFailedException( "Access denied to: "
+ urlToServer + " - " + methodToServer.getStatusText());
case HttpStatus.SC_UNAUTHORIZED:
- throw new TransferFailedException( "Not authorized." );
+ throw new TransferFailedException( "Not authorized." + "
- " + methodToServer.getStatusText());
case HttpStatus.SC_NOT_FOUND:
- throw new TransferFailedException( "File: " +
urlToServer + " does not exist" );
+ throw new TransferFailedException( "File: " +
urlToServer + " does not exist" + " - " + methodToServer.getStatusText() );
+ case HttpStatus.SC_MOVED_TEMPORARILY :
+ case HttpStatus.SC_MOVED_PERMANENTLY :
+ case HttpStatus.SC_TEMPORARY_REDIRECT :
+ log.info(id + " - Detected a "+statusCode+"
Redirect on File: " + urlToServer + " ");
+ throw new RedirectException( "Detected a
"+statusCode+" Redirect on File: " + urlToServer + " " );
case HttpStatus.SC_NOT_MODIFIED:
- log.error( "304 on File: " + urlToServer + " which is
IMPOSSIBLE ");
+ log.error(id + " - 304 on File: " + urlToServer + "
which is IMPOSSIBLE ");
throw new TransferFailedException( "304 on File: " +
urlToServer + " which is IMPOSSIBLE " );
//add more entries here
default :
throw new TransferFailedException(
- "Failed to transfer file: " + urlToServer + ".
Return code is: " + statusCode );
+ "Failed to transfer file: " + urlToServer + ".
Return code is: " + statusCode + " - " + methodToServer.getStatusText());
}
}
@@ -460,7 +503,7 @@
log.debug(id + " - connection released");
//ResponseHandlerBase.printRequestHeaders(methodToServer);
- ResponseHandlerBase.printResponseHeaders(methodToServer);
+ //ResponseHandlerBase.printResponseHeaders(methodToServer);
parseEsiResponseHeaders();
}
@@ -476,7 +519,7 @@
String ifnonematch = "";
try {
if (methodToServer.getRequestHeader("if-none-match").getValue()
!=null) {
- log.debug("removed if-none-match
["+methodToServer.getRequestHeader("if-none-match")+"] ");
+ log.debug(id + " - removed if-none-match
["+methodToServer.getRequestHeader("if-none-match")+"] ");
methodToServer.removeRequestHeader("if-none-match");
}
@@ -486,7 +529,7 @@
String ifmodifiedsince = "";
try {
if
(methodToServer.getRequestHeader("if-modified-since").getValue() !=null) {
- log.debug("removed if-modified-since
["+methodToServer.getRequestHeader("if-modified-since")+"] ");
+ log.debug(id + " - removed if-modified-since
["+methodToServer.getRequestHeader("if-modified-since")+"] ");
methodToServer.removeRequestHeader("if-modified-since");
}
@@ -610,8 +653,6 @@
}
}
-
-
}
}