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 @@
               }
   
           }
  -
  -
       }
   
   }
  

Reply via email to