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) {