mcardle     2005/10/25 14:32:20 CEST

  Modified files:
    src/net/sf/j2ep/responsehandlers ResponseHandlerBase.java 
    src/org/jahia/esi    FragmentCache.java GetThread.java 
                         Log4jInitServlet.java UrlCacheObject.java 
                         Utils.java 
  Added files:
    src/org/jahia/esi    EsiConst.java 
  Log:
  * supports expiration and ESI response header parsing
  
  Revision  Changes    Path
  1.6       +2 -5      
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.5&r2=1.6&f=h
  1.1       +51 -0     esi_server/src/org/jahia/esi/EsiConst.java (new)
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/EsiConst.java?rev=1.1&content-type=text/plain
  1.6       +94 -49    esi_server/src/org/jahia/esi/FragmentCache.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/FragmentCache.java.diff?r1=1.5&r2=1.6&f=h
  1.2       +108 -17   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.1&r2=1.2&f=h
  1.3       +1 -1      esi_server/src/org/jahia/esi/Log4jInitServlet.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/Log4jInitServlet.java.diff?r1=1.2&r2=1.3&f=h
  1.5       +51 -16    esi_server/src/org/jahia/esi/UrlCacheObject.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/UrlCacheObject.java.diff?r1=1.4&r2=1.5&f=h
  1.2       +2 -2      esi_server/src/org/jahia/esi/Utils.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/esi_server/src/org/jahia/esi/Utils.java.diff?r1=1.1&r2=1.2&f=h
  
  
  
  Index: ResponseHandlerBase.java
  ===================================================================
  RCS file: 
/home/cvs/repository/esi_server/src/net/sf/j2ep/responsehandlers/ResponseHandlerBase.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ResponseHandlerBase.java  19 Oct 2005 17:34:20 -0000      1.5
  +++ ResponseHandlerBase.java  25 Oct 2005 12:32:19 -0000      1.6
  @@ -348,7 +348,7 @@
                   fetch ( clientResponse, clientRequest, cacheKey , 
clientRequestUrl);
               }
               else {
  -                log.debug(" * Case 3: in cache => return from cache *");
  +                log.debug (" * Case 3: in cache => return from cache *");
               }
   
               cacheObject = fragmentCache.get(cacheKey);
  @@ -369,9 +369,6 @@
       }
   
   
  -
  -    //UrlCacheObject urlObj = (UrlCacheObject) 
fragmentCache.getHashCache().get(urlKey);
  -
       public void fetch (HttpServletResponse clientResponse, 
HttpServletRequest clientRequest
               , String urlKey, String clientRequestUrl) {
           //can be called because object is not in cache, or some sub-object 
is not in cache
  @@ -380,7 +377,7 @@
   
           UrlCacheObject urlObj = (UrlCacheObject) 
fragmentCache.getHashCache().get(urlKey);
   
  -         Vector threads = new Vector();
  +        Vector threads = new Vector();
   
           if (urlObj==null) {
               //TODO:Need to support all other methods such as POST 
!!!!!!!!!!!!!!!!!!!!!!
  
  
  
  Index: EsiConst.java
  ====================================================================
  package org.jahia.esi;
  
  
  import java.util.HashMap;
  
  /**
   * Created by IntelliJ IDEA.
   * User: MC
   * Date: July-2005
   * Defines constants values used by the JESI Taglibs
   */
  
  public class EsiConst {
  
      public static final String FRAGMENT_URL_MARKER = "__esi_fragment";
      public static final String SURROGATE_CAPABILITY_HEADER = 
"Surrogate-Capability";
      public static final String SURROGATE_CONTROL_HEADER = "Surrogate-Control";
      public static final String SURROGATE_10 = "Surrogate/1.0";
      public static final String ESI_10 = "ESI/1.0";
      public static final String CONTENT_ESI_10 = "content=\"ESI/1.0\"";  
//process standard ESI tags
      public static final int DEFAULT_EXPIRATION = 86400;
      public static final String INFINITY_EXPIRATION_MARKER = "infinity"; 
//max-age=infinity specifies that the document never expires
      public static final int INFINITY_EXPIRATION = -1;
      public static final String ESI_INLINE_10 = "ESI-Inline/1.0"; //process 
<esi:inline> tags
      public static final String ESI_INV_10 = "ESI-INV/1.0"; //process 
<esi:invalidate> tags
      public static final int DEFAULT_DELAY = 0;
      public static final String NO_STORE = "no-store";
  
      /*The no-store-remote directive has similar semantics to the no-store 
directive,
      except that it is only be honored by remote caches. Generally, this means 
those caches
      that are more than one or two hops from the application Web server, such 
as caches in a
      Content Delivery Network (CDN).
      This directive is especially useful if you want to cache changing content 
locally, where
      invalidation propagation is immediate, but not in a distributed network 
of upstream
      ESI processors, where invalidation may take several minutes. [extract 
from Oracle 10g manual]*/
      public static final String NO_STORE_REMOTE = "no-store-remote"; //TODO: 
currently identical behaviour to no-store
  
      public static final String UNSET = "unset";
      public static final String USER = "user";
      public static final String GROUP = "group";
      public static final String ACL_GROUP = "aclGroup";
  
      public static HashMap RESERVED_PARAM_NAMES;
      static
      {
          RESERVED_PARAM_NAMES = new HashMap();
          RESERVED_PARAM_NAMES.put(EsiConst.FRAGMENT_URL_MARKER, "");
      }
  
  }
  
  
  
  
  Index: FragmentCache.java
  ===================================================================
  RCS file: 
/home/cvs/repository/esi_server/src/org/jahia/esi/FragmentCache.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FragmentCache.java        19 Oct 2005 17:34:21 -0000      1.5
  +++ FragmentCache.java        25 Oct 2005 12:32:19 -0000      1.6
  @@ -5,6 +5,10 @@
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.commons.httpclient.HttpMethod;
  +import org.apache.commons.httpclient.URI;
  +import org.apache.commons.httpclient.URIException;
  +import org.apache.commons.httpclient.methods.GetMethod;
  +import net.sf.j2ep.ProxyFilter;
   
   /**
    * Created by IntelliJ IDEA.
  @@ -50,7 +54,7 @@
       }
   
       public HashMap getHashCache() {
  -           return hashCache;
  +        return hashCache;
       }
   
       public void updateReferenceCount(String[] refObjs) {
  @@ -60,12 +64,12 @@
                       String urlKey = refObjs[i];
                       UrlCacheObject urlObj = (UrlCacheObject) 
hashCache.get(urlKey);
                       //sanity check, shouldn't have to do it
  -                        if (urlObj.getReferenceCount()>=0) {
  -                            urlObj.incReferenceCount();
  -                            log.debug("Increasing reference count for 
Fragment at urlKey  ["+urlKey +"]. ReferenceCount is now 
["+urlObj.getReferenceCount()+"]");
  -                        }
  -                        else //TODO: check if it can be ZERO
  -                            
log.error("IMPOSSIBLE---------------------------- reference count shouldn't be 
negative or 0 for Fragment at urlKey  ["+urlKey +"]. ReferenceCount is 
["+urlObj.getReferenceCount()+"]");
  +                    if (urlObj.getReferenceCount()>=0) {
  +                        urlObj.incReferenceCount();
  +                        log.debug("Increasing reference count for Fragment 
at urlKey  ["+urlKey +"]. ReferenceCount is now 
["+urlObj.getReferenceCount()+"]");
  +                    }
  +                    else //TODO: check if it can be ZERO
  +                        log.error("IMPOSSIBLE---------------------------- 
reference count shouldn't be negative or 0 for Fragment at urlKey  ["+urlKey 
+"]. ReferenceCount is ["+urlObj.getReferenceCount()+"]");
                   }
                   else
                       log.error("IMPOSSIBLE---------------------------- 
refObjs[i]  ["+refObjs[i] +"] is not in cached when it should");
  @@ -81,6 +85,27 @@
                                    int[] referencedObjsStartIndex,
                                    int[] referencedObjsEndIndex
                                    ) {
  +        add(urlKey, method, byteContent,
  +                Url,
  +                refObjs,
  +                refObjsUrls,
  +                referencedObjsStartIndex,
  +                referencedObjsEndIndex,
  +                EsiConst.DEFAULT_EXPIRATION,
  +                (new Date()).getTime() + EsiConst.DEFAULT_EXPIRATION,
  +                EsiConst.DEFAULT_DELAY );
  +    }
  +
  +    public synchronized void add(String urlKey, HttpMethod method, byte[] 
byteContent,
  +                                 String Url,
  +                                 String[] refObjs,
  +                                 String[] refObjsUrls,
  +                                 int[] referencedObjsStartIndex,
  +                                 int[] referencedObjsEndIndex,
  +                                 long expirationInSecs,
  +                                 long expirationDateInSecs,
  +                                 long maxRemovalDelayInSecs
  +    ) {
   
           String byteContentHash = getMD5Hash(byteContent);
           UrlCacheObject newUrlObj = null;
  @@ -94,6 +119,9 @@
               newUrlObj.setReferencedObjsUrls(refObjsUrls);
               newUrlObj.setReferencedObjsStartIndex(referencedObjsStartIndex);
               newUrlObj.setReferencedObjsEndIndex(referencedObjsEndIndex);
  +            newUrlObj.setExpirationDelayInSecs(expirationInSecs);
  +            newUrlObj.setExpirationDateInSecs(expirationDateInSecs);
  +            newUrlObj.setExpirationDateInSecs(maxRemovalDelayInSecs);
               updateReferenceCount(refObjs);
               newUrlObj.incUpdateCount();
               log.debug("Updated in cache UrlCacheObject : " + newUrlObj);
  @@ -105,7 +133,10 @@
                       refObjs,
                       refObjsUrls,
                       referencedObjsStartIndex,
  -                    referencedObjsEndIndex);
  +                    referencedObjsEndIndex,
  +                    expirationInSecs,
  +                    expirationDateInSecs,
  +                    maxRemovalDelayInSecs);
               updateReferenceCount(refObjs);
               hashCache.put(urlKey,newUrlObj);
               log.debug("Added in cache UrlCacheObject : " + newUrlObj);
  @@ -128,23 +159,37 @@
           }
       }
   
  -    public boolean contains(String urlKey) {
  +    public boolean contains(String urlKey ) {
   
           UrlCacheObject urlObj = (UrlCacheObject) hashCache.get(urlKey);
   
           if ( urlObj!=null ) {
  -           //sanity check: Shouldn't have to do this check, only for debug
  -            if (contentCache.containsKey(urlObj.getContentHash())) {
  +            //Has this fragment expired?
  +            long now = (new Date()).getTime();
  +            if (urlObj.getExpirationDateInSecs() < now ) {
  +
  +                //might still be valid depending on maxRemovalDelay
  +                if (urlObj.getExpirationDateInSecs() + 
urlObj.getMaxRemovalDelayInSecs()   < now ) {
  +                    //the object is stale so fetch it in background but 
continue serving this version
  +                    //TODO: FETCH THIS OBJECT IN BACKGROUND
  +                }
  +                else {
  +                    log.debug("Request/Hash Cache MISS: request ["+urlKey 
+"] - Object has expired : 
expirationDateInSecs["+urlObj.expirationDateInSecs+"]");
  +                    return false;
  +                }
  +            }
   
  +            //sanity check: Shouldn't have to do this check, only for debug
  +            if (contentCache.containsKey(urlObj.getContentHash())) {
                   //Check that all referenced objects are also valid
                   String[] refObjs = urlObj.getReferencedObjs();
                   if (refObjs!=null)
  -                for (int i=0; i < refObjs.length ; i++) {
  -                    if (!contains(refObjs[i])) {
  -                        log.debug("Request/Hash Cache Miss: request 
["+urlKey +"] due to Cache Miss on referenced object ["+refObjs[i]+"]");
  -                        return false;
  +                    for (int i=0; i < refObjs.length ; i++) {
  +                        if (!contains(refObjs[i])) {
  +                            log.debug("Request/Hash Cache Miss: request 
["+urlKey +"] due to Cache Miss on referenced object ["+refObjs[i]+"]");
  +                            return false;
  +                        }
                       }
  -                }
   
                   log.debug("Request/Hash Cache Hit: request ["+urlKey +"] 
already in cache");
                   urlObj.incHitCount();                   //SHOULD REALLY BE 
CALLED from code we know for sure is doing a user cache access
  @@ -176,49 +221,49 @@
   
       public void remove(String urlKey) {
           if ( hashCache.containsKey(urlKey) ) { //this check shouldn't be 
necessary since we should've called contains beforehand
  -                    UrlCacheObject urlObj = (UrlCacheObject) 
hashCache.get(urlKey);
  -                    remove(urlObj, urlKey);
  +            UrlCacheObject urlObj = (UrlCacheObject) hashCache.get(urlKey);
  +            remove(urlObj, urlKey);
           } else
               log.error("IMPOSSIBLE----------------------------");
       }
   
       public void remove(UrlCacheObject urlObj, String urlKey) {
   
  -            ContentCacheObject contentObj = (ContentCacheObject) 
contentCache.get(urlObj.getContentHash());
  -
  -            //if this is the last request URL pointing to it, so remove hash 
and content Hash entries
  -            if (contentObj.decReferenceCount()==1) {
  -                log.debug("Removing unreferenced ["+contentObj+"]");
  -                contentCache.remove(urlObj.getContentHash());
  -            } else if (contentObj.getReferenceCount()<1) {
  -                log.error("IMPOSSIBLE----------------------------");
  -            }
  +        ContentCacheObject contentObj = (ContentCacheObject) 
contentCache.get(urlObj.getContentHash());
   
  -            //Remove all referenced objects (only if referenceCount is 0)
  -                String[] refUrlKeys = urlObj.getReferencedObjs();
  -                if (refUrlKeys !=null)
  -                for (int i=0; i < refUrlKeys.length ; i++) {
  -
  -                    String refUrlKey = refUrlKeys[i];
  -
  -                    if (contains(refUrlKey)) {//shouldn't have to do this
  -                        UrlCacheObject refUrlObj = (UrlCacheObject) 
hashCache.get(refUrlKey);
  -                        refUrlObj.decReferenceCount();
  -                        //this object is not referenced by anyone else, so 
delete it
  -                        if (refUrlObj.getReferenceCount()==0) {
  -                            log.debug("detected orphaned 
refUrlKey["+refUrlKey+"] so deleting it.");
  -                            remove(refUrlObj, refUrlKey);
  -                        }
  -                        if (refUrlObj.getReferenceCount()<0) { //shouldn't 
have to do this
  -                            
log.error("IMPOSSIBLE---------------------------- refUrlKey["+refUrlKey+"] has 
a negative reference count ["+refUrlObj.getReferenceCount()+"]");
  -                        }
  +        //if this is the last request URL pointing to it, so remove hash and 
content Hash entries
  +        if (contentObj.decReferenceCount()==1) {
  +            log.debug("Removing unreferenced ["+contentObj+"]");
  +            contentCache.remove(urlObj.getContentHash());
  +        } else if (contentObj.getReferenceCount()<1) {
  +            log.error("IMPOSSIBLE----------------------------");
  +        }
   
  +        //Remove all referenced objects (only if referenceCount is 0)
  +        String[] refUrlKeys = urlObj.getReferencedObjs();
  +        if (refUrlKeys !=null)
  +            for (int i=0; i < refUrlKeys.length ; i++) {
  +
  +                String refUrlKey = refUrlKeys[i];
  +
  +                if (contains(refUrlKey)) {//shouldn't have to do this
  +                    UrlCacheObject refUrlObj = (UrlCacheObject) 
hashCache.get(refUrlKey);
  +                    refUrlObj.decReferenceCount();
  +                    //this object is not referenced by anyone else, so 
delete it
  +                    if (refUrlObj.getReferenceCount()==0) {
  +                        log.debug("detected orphaned 
refUrlKey["+refUrlKey+"] so deleting it.");
  +                        remove(refUrlObj, refUrlKey);
  +                    }
  +                    if (refUrlObj.getReferenceCount()<0) { //shouldn't have 
to do this
  +                        log.error("IMPOSSIBLE---------------------------- 
refUrlKey["+refUrlKey+"] has a negative reference count 
["+refUrlObj.getReferenceCount()+"]");
                       }
  -                    else log.error("IMPOSSIBLE---------------------------- 
urlKey["+urlKey+"] references an object which does exist ["+refUrlKey+"]");
  -             }
   
  -            log.debug("Removing ["+urlObj+"]");
  -            hashCache.remove(urlKey);
  +                }
  +                else log.error("IMPOSSIBLE---------------------------- 
urlKey["+urlKey+"] references an object which does exist ["+refUrlKey+"]");
  +            }
  +
  +        log.debug("Removing ["+urlObj+"]");
  +        hashCache.remove(urlKey);
   
       }
   
  
  
  
  Index: GetThread.java
  ===================================================================
  RCS file: /home/cvs/repository/esi_server/src/org/jahia/esi/GetThread.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- GetThread.java    19 Oct 2005 17:34:21 -0000      1.1
  +++ GetThread.java    25 Oct 2005 12:32:19 -0000      1.2
  @@ -3,6 +3,7 @@
   import org.apache.commons.httpclient.HttpClient;
   import org.apache.commons.httpclient.URI;
   import org.apache.commons.httpclient.URIException;
  +import org.apache.commons.httpclient.Header;
   import org.apache.commons.httpclient.methods.GetMethod;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -20,6 +21,7 @@
   import javax.servlet.http.HttpServletRequest;
   import java.util.Vector;
   import java.util.Enumeration;
  +import java.util.Date;
   import java.io.InputStream;
   import java.io.ByteArrayOutputStream;
   
  @@ -46,6 +48,13 @@
       private String urlToServer;
       private String clientRequestUrl;
   
  +    long expirationDateInSecs = (new Date()).getTime();
  +    long expirationInSecs = EsiConst.DEFAULT_EXPIRATION;
  +    long maxRemovalDelayInSecs = EsiConst.DEFAULT_DELAY;
  +    boolean isContentEsi10 = false; //process standard ESI tags
  +    boolean isContentEsiInline10 = false; //process <esi:inline> tags
  +    boolean isContentEsiInv10 = false; //process <esi:invalidate> tags
  +
       static int CACHEABLE_CONTENT_MAX_SIZE_BYTES = 100000;
   
       public GetThread(HttpClient httpClient,
  @@ -152,9 +161,11 @@
               methodToServer.releaseConnection();
               log.debug(id + " - connection released");
   
  -            //ResponseHandlerBase.printRequestHeaders(methodToServer);
  -            //ResponseHandlerBase.printResponseHeaders(methodToServer);
  -        }
  +           ResponseHandlerBase.printRequestHeaders(methodToServer);
  +           ResponseHandlerBase.printResponseHeaders(methodToServer);
  +
  +           parserEsiResponseHeaders();
  +       }
   
           //******************** CHECK CONTENT TYPE ************************
           //***********************************************
  @@ -164,11 +175,11 @@
               contentLength = Integer.parseInt(contentLengthStr);
           } catch (Exception ex) {
               if (bytes==null)
  -                log.error("content bytes is NULL so cannot set content 
length. Ignoring file ");
  +                log.error(id + "content bytes is NULL so cannot set content 
length. Ignoring file ");
               else {
                   contentLength = bytes.length;
  -                log.debug(" NO VALID CONTENT LENGTH on 
["+methodToServer.getResponseHeader("Content-Length")+"]  
urlToServer:"+this.urlToServer +" ex: "+ex);
  -                log.debug(" reverting to content length got from connection 
: " + bytes.length);
  +                log.debug(id + " NO VALID CONTENT LENGTH on 
["+methodToServer.getResponseHeader("Content-Length")+"]  
urlToServer:"+this.urlToServer +" ex: "+ex);
  +                log.debug(id + " reverting to content length got from 
connection : " + bytes.length);
               }
           }
   
  @@ -176,7 +187,7 @@
           try {
               contentType = 
methodToServer.getResponseHeader("Content-type").getValue().toLowerCase();
           } catch (Exception ex) {
  -            log.debug(" NO VALID CONTENT TYPE on 
["+methodToServer.getResponseHeader("Content-type")+"]   
urlToServer:"+this.urlToServer +" ex: "+ex);
  +            log.debug(id + " NO VALID CONTENT TYPE on 
["+methodToServer.getResponseHeader("Content-type")+"]   
urlToServer:"+this.urlToServer +" ex: "+ex);
           }
           //***********************************************
   
  @@ -190,7 +201,9 @@
   
               String urlKey = 
CacheAdminstrator.getInstance().generateEntryKey("GET" , clientRequestUrl 
);//urlToServer);
   
  -            fragmentCache.add ( urlKey  , this.methodToServer , bytes , 
this.clientRequestUrl   , null, null, null ,null);
  +            fragmentCache.add ( urlKey  , this.methodToServer , bytes , 
this.clientRequestUrl   ,
  +                    null, null, null ,null); //will set default expirations 
for the moment
  +
               //if (contentLength !=-1 && 
contentLength<CACHEABLE_CONTENT_MAX_SIZE_BYTES )  {
               // TODO: revert to Cacheless Passthrough for content which is 
over the threshold size
               //}
  @@ -275,7 +288,7 @@
                                   tagCacheKey,
                                   tagUrlObj, //TODO: will be NULL MOST OF THE 
TIME
                                   null //because this is an internal demand 
and there is no clientRequestUrl
  -                        );
  +                                );
                           threads.add(thread);
                           thread.start();
                       }
  @@ -291,7 +304,7 @@
                       thread.join();
   
                   } catch (InterruptedException ex) {
  -                    log.error("THREAD WAS INTERRUPTED !!!!!!!!!!!!!!!!!!!!");
  +                    log.error(id + "THREAD WAS INTERRUPTED 
!!!!!!!!!!!!!!!!!!!!");
                       //TODO: deal with error
                   }
               }
  @@ -321,14 +334,14 @@
   
                   byte[] cachedByteContent = 
tagCacheObject.getContentCacheObject().getByteContent();
   
  -                log.debug("replacing node : "+esiTag.toHtml()+" with cached 
content of length ["+cachedByteContent.length+"]");
  +                log.debug(id + "replacing node : "+esiTag.toHtml()+" with 
cached content of length ["+cachedByteContent.length+"]");
   
                   esiTag.setTagName ("WAS:ESIINCLUDECLASS");
                   esiTag.setEndTag(new EsiIncludeTag());
                   TextNode fragContentTextNode = new TextNode (new 
String(cachedByteContent));
                   NodeList children = new NodeList (fragContentTextNode);
                   esiTag.setChildren (children);
  -                log.debug("New node content : "+esiTag.toHtml());
  +                log.debug(id + "New node content : "+esiTag.toHtml());
   
                   refObjs[pos] = new String(tagCacheKey);
                   refObjsUrls[pos] = new String(src);
  @@ -345,29 +358,29 @@
               while (commentTagsEnum.hasMoreElements()) {
                   EsiCommentTag esiCommentTag = (EsiCommentTag) 
commentTagsEnum.nextElement();
   
  -                log.debug("clearing esi:comment node : 
"+esiCommentTag.toHtml()+" ");
  +                log.debug(id + "clearing esi:comment node : 
"+esiCommentTag.toHtml()+" ");
   
                   esiCommentTag.setTagName ("WAS:ESICOMMENTCLASS");
                   esiCommentTag.setEndTag(new EsiCommentTag());
                   TextNode blankContentTextNode = new TextNode (new 
String(""));
                   NodeList children = new NodeList (blankContentTextNode);
                   esiCommentTag.setChildren (children);
  -                log.debug("New node content : "+esiCommentTag.toHtml());
  +                log.debug(id + "New node content : "+esiCommentTag.toHtml());
               }
   
               StringBuffer finalContents = new StringBuffer();
   
               //Generate final output
               for (NodeIterator e = list.elements (); e.hasMoreNodes (); ) {
  -                /*if (log.isDebugEnabled())
  -                    log.debug ( "Final Output : " + e.nextNode ().toHtml()); 
*/
  +                /*log.debug ( "Final Output : " + e.nextNode ().toHtml()); 
//can't do this line and one below it*/
                   finalContents.append(e.nextNode ().toHtml());
               }
   
               fragmentCache.add ( urlKey  , methodToServer , 
finalContents.toString().getBytes()
                       , methodToServer.getURI().toString(),
                       refObjs, refObjsUrls,
  -                    referencedObjsStartIndex ,referencedObjsEndIndex );
  +                    referencedObjsStartIndex ,referencedObjsEndIndex,
  +                    this.expirationInSecs, this.expirationDateInSecs, 
this.maxRemovalDelayInSecs );
   
           } catch (Exception e) {
               log.error(id + " - Main Thread ERROR : " + e);
  @@ -377,4 +390,82 @@
   
       }
   
  +    public void parserEsiResponseHeaders() {
  +
  +        Header controlHeader = 
methodToServer.getResponseHeader(EsiConst.SURROGATE_CONTROL_HEADER); //If there 
are multiple headers with the same name, there values will be combined with the 
',' separator
  +        if (controlHeader == null)
  +            return;
  +
  +        String control =  controlHeader.getValue();
  +
  +        String[] ctrlParts = control.split (",");
  +        for (int i=0; i < ctrlParts.length; i++) {
  +
  +            int ind = ctrlParts[i].indexOf("content=");
  +
  +            //Parse NO-STORE -----------
  +            if (ctrlParts[i].indexOf(EsiConst.NO_STORE)>-1 ||
  +                ctrlParts[i].indexOf(EsiConst.NO_STORE_REMOTE)>-1  ) {
  +                //TODO: shouldn't have to do assignment since these are the 
default values anyway, but do it anyway for good measure
  +                expirationInSecs = 0;
  +                expirationDateInSecs = (new Date()).getTime();
  +                log.debug(id + " No-Store detected ");
  +                continue;
  +            }
  +
  +
  +            //Parse CONTENT -----------
  +            if (ind > -1 ) {
  +                if ( ctrlParts[i].indexOf(EsiConst.CONTENT_ESI_10) > -1 )
  +                      isContentEsi10 = true;
  +
  +                if ( ctrlParts[i].indexOf(EsiConst.ESI_INLINE_10) > -1 )
  +                      isContentEsiInline10 = true;
  +
  +                if ( ctrlParts[i].indexOf(EsiConst.ESI_INV_10) > -1 )
  +                      isContentEsiInv10 = true;
  +
  +                continue;
  +            }
  +
  +            //Parse MAX-AGE ------------
  +            ind = ctrlParts[i].indexOf("max-age=");
  +            if (ind > -1 ) {
  +                //TODO: support the targetting of directives at individual 
ESI servers e.g. Surrogate-Control: max-age=60;abc, max-age=300
  +                String maxAge = ctrlParts[i].substring( "max-age=".length(), 
ctrlParts[i].length());
  +
  +                int plusPos = maxAge.indexOf("+");
  +                plusPos = (plusPos==-1)?maxAge.length():plusPos;//in case we 
have no optional + e.g. "max-age=30" versus "max-age=30+10"
  +
  +
  +                try {
  +                    expirationInSecs = Integer.parseInt( maxAge.substring(0, 
plusPos) );
  +                    expirationDateInSecs = (new Date()).getTime() + 
expirationInSecs; //new Date( (new Date()).getTime() + expirationInSecs );
  +                    log.debug(id + " expirationInSecs 
["+expirationInSecs+"]");
  +                    log.debug(id + " expirationDateInSecs 
["+expirationDateInSecs+"]");
  +                } catch (NumberFormatException ex) {
  +                    //maybe it's set to Infinity?
  +                    if 
(ctrlParts[i].indexOf(EsiConst.INFINITY_EXPIRATION_MARKER) > -1) {
  +                         expirationInSecs = Long.MAX_VALUE; //equivalent to 
infinity
  +                         expirationDateInSecs = expirationInSecs; //new 
Date(expirationInSecs));
  +                    }
  +                    else
  +                        log.error(id + "Badly formatted ESI expiration 
header in response from server. Bad value is : ["+maxAge+"] . Reverting to 
default value : ["+expirationInSecs+"].  ex:"+ex);
  +                }
  +
  +                try {
  +                    maxRemovalDelayInSecs = Integer.parseInt( 
maxAge.substring(plusPos+1, maxAge.length() ) );
  +                    log.debug(id + " maxRemovalDelayInSecs 
["+maxRemovalDelayInSecs+"]");
  +                } catch (NumberFormatException ex) {
  +                    log.error(id + "Badly formatted ESI maxRemovalDelay 
header in response from server. Bad value is : ["+maxAge+"]. Reverting to 
default value : ["+maxRemovalDelayInSecs+"].  ex:"+ex);
  +                }
  +
  +                continue;
  +            }
  +
  +        }
  +
  +
  +    }
  +
   }
  
  
  
  Index: Log4jInitServlet.java
  ===================================================================
  RCS file: 
/home/cvs/repository/esi_server/src/org/jahia/esi/Log4jInitServlet.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Log4jInitServlet.java     19 Oct 2005 17:34:21 -0000      1.2
  +++ Log4jInitServlet.java     25 Oct 2005 12:32:19 -0000      1.3
  @@ -26,7 +26,7 @@
   import java.util.Enumeration;
   import org.apache.log4j.Logger;
   import org.apache.log4j.LogManager;
  -import net.sf.j2ep.testParser;
  +
   
   /**
    * <p>Title: Log4J initialization servlet</p>
  
  
  
  Index: UrlCacheObject.java
  ===================================================================
  RCS file: 
/home/cvs/repository/esi_server/src/org/jahia/esi/UrlCacheObject.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- UrlCacheObject.java       19 Oct 2005 17:34:21 -0000      1.4
  +++ UrlCacheObject.java       25 Oct 2005 12:32:19 -0000      1.5
  @@ -27,7 +27,56 @@
       protected int[] referencedObjsEndIndex; //end offset position of 
referencing Tag in current object
       protected String[] referencedObjsUrls; //referenced object's URLs
       int referenceCount = 0;
  +    long expirationDelayInSecs; //expiration delay set in max-age
  +    long expirationDateInSecs;  //actual date/time at which this object will 
expire
  +    long maxRemovalDelayInSecs;  //optional freshness delay which specifies 
an additional period of time the stale object can be served, before it must be 
refetched
   
  +    public UrlCacheObject(String contentHash, HttpMethod method, String Url,
  +                          String[] referencedObjs,
  +                          String[] referencedObjsUrls,
  +                          int[] referencedObjsStartIndex, int[] 
referencedObjsEndIndex,
  +                          long expirationInSecs,
  +                          long expirationDateInSecs,
  +                          long maxRemovalDelayInSecs) {
  +
  +
  +        this.referencedObjsUrls = referencedObjsUrls;
  +        this.Url = Url;
  +        this.contentHash = contentHash;
  +        this.method = method;
  +        this.referencedObjs = referencedObjs;
  +        this.referencedObjsStartIndex = referencedObjsStartIndex;
  +        this.referencedObjsEndIndex = referencedObjsEndIndex;
  +        this.expirationDelayInSecs = expirationInSecs;
  +        this.expirationDateInSecs = expirationDateInSecs;
  +        this.maxRemovalDelayInSecs = maxRemovalDelayInSecs;
  +        
  +        this.creationDate = new Date();
  +    }
  +
  +    public long getMaxRemovalDelayInSecs() {
  +        return maxRemovalDelayInSecs;
  +    }
  +
  +    public void setMaxRemovalDelayInSecs(long maxRemovalDelayInSecs) {
  +        this.maxRemovalDelayInSecs = maxRemovalDelayInSecs;
  +    }
  +
  +    public long getExpirationDelayInSecs() {
  +        return expirationDelayInSecs;
  +    }
  +
  +    public void setExpirationDelayInSecs(long expirationDelayInSecs) {
  +        this.expirationDelayInSecs = expirationDelayInSecs;
  +    }
  +
  +    public long getExpirationDateInSecs() {
  +        return expirationDateInSecs;
  +    }
  +
  +    public void setExpirationDateInSecs(long expirationDateInSecs) {
  +        this.expirationDateInSecs = expirationDateInSecs;
  +    }
   
       public String[] getReferencedObjsUrls() {
           return referencedObjsUrls;
  @@ -97,22 +146,6 @@
       }
   
   
  -    public UrlCacheObject(String contentHash, HttpMethod method, String Url,
  -                          String[] referencedObjs,
  -                          String[] referencedObjsUrls,
  -                          int[] referencedObjsStartIndex, int[] 
referencedObjsEndIndex) {
  -
  -        this.referencedObjsUrls = referencedObjsUrls;
  -        this.Url = Url;
  -        this.contentHash = contentHash;
  -        this.method = method;
  -        this.referencedObjs = referencedObjs;
  -        this.referencedObjsStartIndex = referencedObjsStartIndex;
  -        this.referencedObjsEndIndex = referencedObjsEndIndex;
  -
  -        this.creationDate = new Date();
  -    }
  -
       public HttpMethod getMethod() {
           return method;
       }
  @@ -176,6 +209,8 @@
                   ", referencedObjsEndIndex=" + referencedObjsEndIndex +
                   ", referencedObjsUrls=" + (referencedObjsUrls == null ? null 
: Arrays.asList(referencedObjsUrls)) +
                   ", referenceCount=" + referenceCount +
  +                ", expirationDelayInSecs=" + expirationDelayInSecs +
  +                ", expirationDateInSecs=" + expirationDateInSecs +
                   "}";
       }
   }
  
  
  
  Index: Utils.java
  ===================================================================
  RCS file: /home/cvs/repository/esi_server/src/org/jahia/esi/Utils.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Utils.java        19 Oct 2005 17:34:21 -0000      1.1
  +++ Utils.java        25 Oct 2005 12:32:19 -0000      1.2
  @@ -27,7 +27,7 @@
       private static final transient Log log = LogFactory.getLog(Utils.class);
   
   
  -    public static DownloadObject downloadUrl (HttpMethod method)   {
  +   /* public static DownloadObject downloadUrl (HttpMethod method)   {
   
           byte[] bytes = null;
   
  @@ -57,7 +57,7 @@
           DownloadObject dw = new DownloadObject(method, bytes);
   
           return dw;
  -    }
  +    } */
   
        public static GetMethod copyMethod ( HttpMethod method)  {
           try {
  

Reply via email to