mcardle     2005/11/04 17:56:30 CET

  Modified files:
    src/net/sf/j2ep/responsehandlers ResponseHandlerBase.java 
  Log:
  * deals with ETag and If-conditional HTTP headers
  
  Revision  Changes    Path
  1.9       +142 -71   
esi_server/src/net/sf/j2ep/responsehandlers/ResponseHandlerBase.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/net/sf/j2ep/responsehandlers/ResponseHandlerBase.java.diff?r1=1.8&r2=1.9&f=h
  
  
  
  Index: ResponseHandlerBase.java
  ===================================================================
  RCS file: 
/home/cvs/repository/esi_server/src/net/sf/j2ep/responsehandlers/ResponseHandlerBase.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ResponseHandlerBase.java  26 Oct 2005 13:45:22 -0000      1.8
  +++ ResponseHandlerBase.java  4 Nov 2005 16:56:30 -0000       1.9
  @@ -24,6 +24,9 @@
   import java.net.UnknownHostException;
   import java.util.Vector;
   import java.util.Enumeration;
  +import java.util.Date;
  +import java.text.DateFormat;
  +import java.text.ParseException;
   
   import javax.servlet.ServletResponse;
   import javax.servlet.http.HttpServletResponse;
  @@ -88,7 +91,7 @@
   
           //TODO: this must be configurable from Config file
           if ( this.methodToServer.getName().equals("GET") ||
  -             this.methodToServer.getName().equals("HEAD") ) {
  +                this.methodToServer.getName().equals("HEAD") ) {
               this.cacheMethod = true;
           }
           else this.cacheMethod = false;
  @@ -188,8 +191,8 @@
   
           //fragmentCache.add(cacheKey, this.method, cacheByteContent);
           fragmentCache.add(cacheKey, this.methodToServer, cacheByteContent,
  -                          requestHandler.getClientRequestURL().toString(),
  -                        null, null, null ,null);  
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  +                requestHandler.getClientRequestURL().toString(),
  +                null, null, null ,null);  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   
   
       }
  @@ -248,6 +251,11 @@
        * @param clientResponse The response that will have headers written to 
it
        */
       protected void 
copyHeadersFromServerResponseToClientResponse(HttpServletResponse 
clientResponse) {
  +        copyHeadersFromServerResponseToClientResponse( clientResponse, 
false);
  +    }
  +
  +    protected void 
copyHeadersFromServerResponseToClientResponse(HttpServletResponse 
clientResponse,
  +                                                                 boolean 
ignoreCookies) {
           Header[] headers = methodToServer.getResponseHeaders();
   
           for (int i=0; i < headers.length; i++) {
  @@ -255,8 +263,9 @@
               String name = header.getName();
               boolean contentLength = name.equalsIgnoreCase("content-length");
               boolean connection = name.equalsIgnoreCase("connection");
  +            boolean cookie = name.equalsIgnoreCase("set-cookie");
   
  -            if (!contentLength && !connection) {
  +            if (!contentLength && !connection ) {
                   clientResponse.addHeader(name, header.getValue());
               }
           }
  @@ -302,8 +311,8 @@
   
               ProxyFilter.getHttpClient().executeMethod(methodToServer);
   
  -            //printRequestHeaders(methodToServer);
  -            //printResponseHeaders(methodToServer);
  +            printRequestHeaders(methodToServer);
  +            printResponseHeaders(methodToServer);
   
               if (methodToServer.getStatusCode() == 405) {
                   Header allow = methodToServer.getResponseHeader("allow");
  @@ -319,7 +328,7 @@
   
   
   
  -        public void process(HttpServletResponse clientResponse, 
HttpServletRequest clientRequest) throws IOException, MethodNotAllowedException 
{
  +    public void process(HttpServletResponse clientResponse, 
HttpServletRequest clientRequest) throws IOException, MethodNotAllowedException 
{
   
           String cacheKey = 
CacheAdminstrator.getInstance().generateEntryKey(this.requestHandler);
   
  @@ -358,13 +367,23 @@
               //reset the method to the cached one so we can take the settings 
from that one
               this.methodToServer = 
cacheObject.getUrlCacheObject().getMethod();
   
  -            copyHeadersFromServerResponseToClientResponse(clientResponse);
  -            //TODO: set cookies here
  -            clientResponse.setStatus(getStatusCode());
  -
  -            if (!methodToServer.getName().equals("HEAD")) //since there is 
no content for HEAD requests
  -                sendStreamToClientFromCache(clientResponse, cacheKey, 
cachedByteContent);
  -
  +            copyHeadersFromServerResponseToClientResponse(clientResponse, 
true); //doesn't copy over saved cookie
  +            //copy the Cookie in the client request to the one sent back to 
the client
  +            //and not the old one stored in the cache as they might be for 
different sessions
  +            clientResponse.addHeader("Set-Cookie", 
clientRequest.getHeader("Cookie"));
  +
  +            boolean return304NotModified = 
checkIfConditionalHtppHeaders(clientRequest, cacheObject);
  +
  +            if (return304NotModified) {
  +                log.debug("Returning a HTPP 304 for 
"+cacheObject.getUrlCacheObject().getUrl());
  +                clientResponse.setStatus(304); //HTTP 304: the document was 
not modified
  +                //no data sent since request object hasn't changed
  +            }
  +            else {
  +                clientResponse.setStatus(getStatusCode());
  +                if (!methodToServer.getName().equals("HEAD")) //since there 
is no content for HEAD requests
  +                    sendStreamToClientFromCache(clientResponse, cacheKey, 
cachedByteContent);
  +            }
           }
   
       }
  @@ -390,14 +409,14 @@
               //TODO: esi headers??
   
               GetThread thread = new GetThread(ProxyFilter.getHttpClient(),
  -                                getMethod,
  -                                this,
  -                                clientResponse,
  -                                clientRequest,
  -                                urlKey,
  -                                urlObj, //TODO: will be NULL
  -                                clientRequestUrl
  -                                );
  +                    getMethod,
  +                    this,
  +                    clientResponse,
  +                    clientRequest,
  +                    urlKey,
  +                    urlObj, //TODO: will be NULL
  +                    clientRequestUrl
  +            );
   
               threads.add(thread);
               thread.start();
  @@ -416,13 +435,12 @@
                       //Need to support all other methods POST 
!!!!!!!!!!!!!!!!!!!!!!
                       GetMethod getMethod = Utils.copyMethod(methodToServer);
                       try {
  -                        URI uri = new 
URI(urlObj.getReferencedObjsUrls()[i]); //TODO: what is this esacpe shit
  +                        URI uri = new 
URI(urlObj.getReferencedObjsUrls()[i]); //TODO: what is this esacpe business?
                           //we don't want to fetch the original URL from 
methodToServer
                           // but the one referenced here
                           getMethod.setURI(uri);
                       } catch (URIException e) {
  -
  -                        e.printStackTrace();  //To change body of catch 
statement use File | Settings | File Templates.
  +                        e.printStackTrace();
                       }
                       getMethod.setFollowRedirects(true);
                       //TODO: statusCode ??
  @@ -430,14 +448,14 @@
                       //TODO: esi headers??
   
                       GetThread thread = new 
GetThread(ProxyFilter.getHttpClient(),
  -                                getMethod,
  -                                this,
  -                                clientResponse,
  -                                clientRequest,
  -                                refUrlKey,
  -                                null, //TODO: urlcacheobject will be NULL
  -                                null //because this is an internal demand 
and there is no clientRequestUrl
  -                                );
  +                            getMethod,
  +                            this,
  +                            clientResponse,
  +                            clientRequest,
  +                            refUrlKey,
  +                            null, //TODO: urlcacheobject will be NULL
  +                            null //because this is an internal demand and 
there is no clientRequestUrl
  +                    );
   
                       threads.add(thread);
                       thread.start();
  @@ -458,58 +476,111 @@
           }
       }
   
  -     public static void getRidOfDodgyRequestHeaders(HttpMethod method) {
  -                //****************************************** MEGA HACK 
*************************************
  -            String ifnonematch = "";
  -            try {
  -                if (method.getRequestHeader("if-none-match").getValue() 
!=null) {
  -                    log.debug("removed if-none-match 
["+method.getRequestHeader("if-none-match")+"] ");
  -                    method.removeRequestHeader("if-none-match");
  -                }
  +    private boolean checkIfConditionalHtppHeaders(HttpServletRequest 
clientRequest, CacheObject cacheObject) {
  +        boolean return304NotModified = false;
   
  -            } catch (Exception ex) {
  -                //log.debug(" no if-none-match 
["+method.getResponseHeader("if-none-match")+"]  ex: "+ex);
  +        //check Entity Tag Revalidation
  +        String eTagHeader = clientRequest.getHeader("If-None-Match");
  +        if (eTagHeader !=null) {
  +            Header eTagRespHeader = 
this.methodToServer.getResponseHeader("ETag");
  +            if (eTagRespHeader!=null)  {
  +                String[] eTag = eTagRespHeader.getValue().split(",");
  +                for (int i = 0; i<eTag.length; i++) { //since there can be 
more than one ETag e.g. If-None-March: "foobar","A34FAC0095","Profiles in 
Courage"
  +                    if (eTagHeader.equals(eTag[i])) {
  +                        log.debug("Detected a HTPP 304 for "+eTagHeader);
  +                        return304NotModified = true;
  +                    }
  +                }
               }
  -            String ifmodifiedsince = "";
  +        }
  +
  +        String modSinceHeader = clientRequest.getHeader("If-Modified-Since");
  +        if ((eTagHeader!=null ^ return304NotModified==false)  //If an 
HTTP/1.1 cache or server receives a request with both If-Modified-Since and 
entity tag conditional headers, it must not return a 304 Not Modified response 
unless doing so is consistent with all of the conditional header fields in the 
request.
  +                && modSinceHeader !=null) {
  +
               try {
  -                if (method.getRequestHeader("if-modified-since").getValue() 
!=null) {
  -                    log.debug("removed if-modified-since 
["+method.getRequestHeader("if-modified-since")+"] ");
  -                    method.removeRequestHeader("if-modified-since");
  +                //First check if the object has been changed in the cache 
since If-Modified-Since date
  +                Date modSinceHeaderDate = 
DateFormat.getDateInstance().parse(modSinceHeader);
  +                if 
(cacheObject.getUrlCacheObject().getLastUpdateDate().after(modSinceHeaderDate) 
) {
  +                    log.debug("Detected a HTPP 304 for "+modSinceHeader);
  +                    return304NotModified = true;
  +                }
  +                //if it hasn't, then still check if the stored Expires 
header date is after the If-Modified-Since date
  +                else {
  +                    //TODO: rename vars to something more meaningful
  +                    Header expiresRespHeader = 
this.methodToServer.getResponseHeader("Expires");
  +                    if (expiresRespHeader!=null)   {
  +                        String expiresHeader = expiresRespHeader.getValue();
  +                        try {
  +                            Date expiresHeaderDate = 
DateFormat.getDateInstance().parse(expiresHeader);
  +                            if (modSinceHeaderDate.after(expiresHeaderDate)) 
{
  +                                log.debug("Detected a HTPP 304 for 
"+expiresRespHeader);
  +                                return304NotModified = true;
  +                            }
  +                        } catch (ParseException e) {
  +                            log.debug("Error trying to parse Expires Header 
date ["+expiresHeader+"] : "+e);
  +                        }
  +                    }
                   }
  +            } catch (ParseException e) {
  +                log.debug("Badly formatted If-Modified-Since Header date 
["+modSinceHeader+"] in client Request : "+e);
  +            }
  +        }
  +        return return304NotModified;
  +    }
   
  -            } catch (Exception ex) {
  -                //log.debug(" no if-modified-since 
["+method.getResponseHeader("if-modified-since")+"]  ex: "+ex);
  +    public static void getRidOfDodgyRequestHeaders(HttpMethod method) {
  +        //****************************************** MEGA HACK 
*************************************
  +        String ifnonematch = "";
  +        try {
  +            if (method.getRequestHeader("if-none-match").getValue() !=null) {
  +                log.debug("removed if-none-match 
["+method.getRequestHeader("if-none-match")+"] ");
  +                method.removeRequestHeader("if-none-match");
               }
   
  -            //****************************************** MEGA HACK 
*************************************
  -     }
  +        } catch (Exception ex) {
  +            //log.debug(" no if-none-match 
["+method.getResponseHeader("if-none-match")+"]  ex: "+ex);
  +        }
  +        String ifmodifiedsince = "";
  +        try {
  +            if (method.getRequestHeader("if-modified-since").getValue() 
!=null) {
  +                log.debug("removed if-modified-since 
["+method.getRequestHeader("if-modified-since")+"] ");
  +                method.removeRequestHeader("if-modified-since");
  +            }
   
  -    public static void getRidOfDodgyResponseHeaders(HttpMethod method) {
  -            //****************************************** MEGA HACK 
*************************************
  -            String ETag = "";
  -            try {
  -                if (method.getRequestHeader("ETag").getValue() !=null) {
  -                    log.debug("removed ETag 
["+method.getRequestHeader("ETag")+"] ");
  -                    method.removeRequestHeader("ETag");
  -                }
  +        } catch (Exception ex) {
  +            //log.debug(" no if-modified-since 
["+method.getResponseHeader("if-modified-since")+"]  ex: "+ex);
  +        }
  +
  +        //****************************************** MEGA HACK 
*************************************
  +    }
   
  -            } catch (Exception ex) {
  -                //log.debug(" no ETag ["+method.getResponseHeader("ETag")+"] 
 ex: "+ex);
  +    public static void getRidOfDodgyResponseHeaders(HttpMethod method) {
  +        //****************************************** MEGA HACK 
*************************************
  +        String ETag = "";
  +        try {
  +            if (method.getRequestHeader("ETag").getValue() !=null) {
  +                log.debug("removed ETag 
["+method.getRequestHeader("ETag")+"] ");
  +                method.removeRequestHeader("ETag");
               }
   
  -            String LastModified = "";
  -            try {
  -                if (method.getRequestHeader("Last-Modified").getValue() 
!=null) {
  -                    log.debug("removed Last-Modified 
["+method.getRequestHeader("Last-Modified")+"] ");
  -                    method.removeRequestHeader("Last-Modified");
  -                }
  +        } catch (Exception ex) {
  +            //log.debug(" no ETag ["+method.getResponseHeader("ETag")+"]  
ex: "+ex);
  +        }
   
  -            } catch (Exception ex) {
  -                //log.debug(" no ETag 
["+method.getResponseHeader("Last-Modified")+"]  ex: "+ex);
  +        String LastModified = "";
  +        try {
  +            if (method.getRequestHeader("Last-Modified").getValue() !=null) {
  +                log.debug("removed Last-Modified 
["+method.getRequestHeader("Last-Modified")+"] ");
  +                method.removeRequestHeader("Last-Modified");
               }
   
  -            //****************************************** MEGA HACK 
*************************************
  -     }
  +        } catch (Exception ex) {
  +            //log.debug(" no ETag 
["+method.getResponseHeader("Last-Modified")+"]  ex: "+ex);
  +        }
  +
  +        //****************************************** MEGA HACK 
*************************************
  +    }
   
   
       public static void printRequestHeaders(HttpMethod method) {
  

Reply via email to