RE: Publication date

"Marc Cardle" <[email protected]>
Newsgroups gmane.comp.cms.jahia.template
Message-ID <[email protected]>
Ghislain,

 

Thanks for your contribution! This code will be particularly useful for
people running Jahia 4.0 and 4.1 (with or without a front-end Apache
server). In Jahia 5.0, we are developing an ESI-enabled webcache server
which supports more advanced caching features. It will replace, and be more
efficient, than a front-end Apache server.

 

In the meantime, why not go even further with your code and use the
If-Not-Modified HTTP header? If Jahia detects such a header in the request
and the cache entry is old enough, it will quit processing the page and
return an HTTP 304 Not-Modified header (
http://www.checkupdown.com/status/E304.html ). 

 

The best place to add this functionality would be in the
org.jahia.operations.valves.CacheReadValve class. I have written a
(untested) mockup of the necessary changes below which you are welcome to
try. Check for the BEGIN: NEW CODE tagged section. Again, you’d need to
recompile the CacheReadValve class and place it in the appropriate package
directory in your webapps/jahia/WEB-INF/classes directory.

 

    public void invoke (Object context, ValveContext valveContext)
        throws PipelineException {
        ProcessingContext processingContext = (ProcessingContext) context;
        // first order of business is to do all cache processing, in order
to
        // minimize what we have to do.
        if (processingContext.settings().lookupBoolean(SettingsBean.
                                               OUTPUT_CACHE_ACTIVATED)) {
            /** we only do HTML content caching if it is a core engine call
             *  and if the HTTP method is GET. We might extend on this later
             *  on but for the sake of simplicity of implementation we
             *  restrict it for now. We might be interested in doing more
             *  work here in order to cache more often.
             */
            HtmlCache htmlCache = null;
            try {
                // Get the HTML cache instance
                htmlCache =
ServicesRegistry.getInstance().getCacheService().getHtmlCacheInstance();
            } catch (JahiaInitializationException ex) {
                throw new PipelineException(ex);
            }
            // extract the workflow state out of the parameters bean
            int workflowState = processingContext.getEntryLoadRequest().
                                getWorkflowState();
            // Get the language code
            String curLanguageCode =
LanguageCodeConverters.localeToLanguageTag(
                processingContext.getLocale());
            if ( ("core".equals(processingContext.getEngine())) &&
                (processingContext.getHttpMethod() ==
ProcessingContext.GET_METHOD) &&
 
(ProcessingContext.CACHE_ON.equals(processingContext.getCacheStatus()))
                ) {
                // logger.debug("Requested page is : " +
jParams.getObjectKey() );
 
                GroupCacheKey entryKey = htmlCache.computeEntryKey(
                    Integer.toString(processingContext.getPageID()),
                    processingContext.getUser().getUsername(),
                    curLanguageCode,
                    workflowState,
                    processingContext.getUserAgent());
 
                CacheEntry cacheEntry = htmlCache.getCacheEntry(entryKey);
 
                if (cacheEntry != null) {
//                            logger.debug ("Found HTML page in
cache!!!!!!!!!!!!!!!!!!");
                    HtmlCacheEntry htmlEntry = (HtmlCacheEntry) cacheEntry.
                                               getObject();
                    String htmlContent = htmlEntry.getContentBody();
 
                    if (!cacheEntry.getOperationMode().equals(
                        processingContext.getOperationMode())) {
                        logger.debug("Cache entry mode is NOT equal to
current mode, flushing page entry and generating page...");
                        htmlCache.remove(entryKey);
 
                    } else {
                        if (htmlContent != null) {
                            logger.debug(
                                "Found content in cache, writing directly
bypassing processing...");
                            HttpServletResponse realResp =
((ParamBean)processingContext).
                                getRealResponse();
                            String contentType = htmlEntry.getContentType();
 
                            //---------------------  BEGIN: NEW CODE
---------------------------
                            //return an HTTP 304 Not modified if cache entry
hasn't been changed since last request
                            HttpServletRequest realReq =
((ParamBean)processingContext).
                                getRealRequest();
                            long modSinceHeader =
realReq.getDateHeader("If-Modified-Since");
                            if (modSinceHeader !=-1) {
                                Date modSinceHeaderDate = new
Date(modSinceHeader);
                                Date cacheLastMod =
htmlEntry.getContentTimestamp();
                                if (
cacheLastMod.before(modSinceHeaderDate)) {
                                    realResp.setStatus(304);
                                    return;
                                }
                            }
                            //---------------------  END: NEW CODE
---------------------------
 
 
                            if (contentType != null) {
                                realResp.setContentType(contentType);
                                logger.debug("Sending content type : [" +
                                             contentType + "]");
                            }
                            try {
                                ServletOutputStream outputStream = realResp.
                                    getOutputStream();
                                OutputStreamWriter streamWriter = new
                                    OutputStreamWriter(outputStream);
                                if (contentType != null) {
                                    int charsetPos =
contentType.toLowerCase().
                                        indexOf("charset=");
                                    if (charsetPos != -1) {
                                        String encoding =
contentType.substring(
                                            charsetPos +
"charset=".length()).
                                            toUpperCase();
                                        logger.debug(
                                            "Using streamWriter with
encoding : " +
                                            encoding);
                                        streamWriter = new
                                            OutputStreamWriter(outputStream,
                                            encoding);
                                    }
                                }
                                streamWriter.write(htmlContent, 0,
                                    htmlContent.length());
                                streamWriter.flush();
                            } catch (java.io.IOException ioe) {
                                logger.error(
                                    "Error writing cache output, IOException
generated error",
                                    ioe);
                                JahiaException outputException = new
                                    JahiaException(
                                    "OperationsManager.handleOperations",
                                    "Error writing cache content to writer",
                                    JahiaException.SECURITY_ERROR,
                                    JahiaException.ERROR_SEVERITY, ioe);
                                throw new
PipelineException(outputException);
                            }
                            return; // exit handling here !
                        }
                    }
                } else {
                    logger.debug(
                        "!!!!!! Could not find HTML page in
cache!!!!!!!!!!!!!!!!!!");
                }
            }
 
            if (
(ProcessingContext.CACHE_OFFONCE.equals(processingContext.getCacheStatus()))
||
 
(ProcessingContext.CACHE_BYPASS.equals(processingContext.getCacheStatus()))
||
 
(ProcessingContext.CACHE_ONLYUPDATE.equals(processingContext.getCacheStatus(
)))
                ) {
                // if we have a mode that is only temporary, all the
                // urls will be generated to have the cache active
                // by default.
 
processingContext.setCacheStatus(ProcessingContext.CACHE_ON);
            }
        } else {
            logger.debug("Output cache not activated.");
        }
        valveContext.invokeNext(context);
    }

 

 

Kind Regards,

 

Marc

 

 

 

  _____  

From: ghislain.cussonneau [mailto:[email protected]] 
Sent: 12 December 2005 15:53
To: template_list
Subject: RE: Publication date

 

Ok !

 

I've done that and everything goes well ! For your interest, the following
codes are the solution I've use (in order templates adding code / patch on
jahia / apache conf).

 

I've put the new HtmlCacheEntry in webapps/jahia/WEB-INF/classes directory,
modify the jahia.properties to add the property "readonlyserver" and restart
the server.

 

TEMPLATES

 

Here is the code I had in header.inc (after the include of declarations.inc)
:

<%
// Definition des headers en fonction des droits des utilisateurs
// Si on est en anonyme ou que le serveur est utilisé en lecture uniquement
--> utilisation du cache Apache
if (!jData.gui().isLogged() || bIsReadonlyServer)
{
  int iCacheMaxExpire = 24*3600; // 24 heures max pour cache Apache
  // Get the language code
  String curLanguageCode =
LanguageCodeConverters.localeToLanguageTag(jParams.getLocale());
  // Extract the workflow state out of the parameters bean
  int workflowState = jParams.getEntryLoadRequest().getWorkflowState();
  // Get the HTML cache instance
  HtmlCache htmlCache = CacheFactory.getHtmlCache();
  // Get the CacheEntry
  String entryKey =
htmlCache.computeEntryKey(Integer.toString(jParams.getPageID()),
  jParams.getUser().getUsername(), curLanguageCode, workflowState,
jParams.getUserAgent());
  Date dLastModifiedCacheDate = new Date();
  try {
    CacheEntry cacheEntry = (CacheEntry)htmlCache.getCacheEntry(entryKey);
    HtmlCacheEntry htmlEntry = (HtmlCacheEntry) cacheEntry.getObject();
    dLastModifiedCacheDate.setTime(htmlEntry.getContentTimestamp());
  } catch(Exception e) {}
  Date dExpires = new Date();
  dExpires.setTime(dLastModifiedCacheDate.getTime() + iCacheMaxExpire);
  logger.debug("Header Expires = " + getDateAsRFC822String(dExpires));
  logger.debug("Header Last-Modified = " +
getDateAsRFC822String(dLastModifiedCacheDate));
  logger.debug("Header Cache-Control = " + "max-age=" + iCacheMaxExpire + ",
must-revalidate");
  response.addHeader("Expires", getDateAsRFC822String(dExpires));
  response.addHeader("Last-Modified",
getDateAsRFC822String(dLastModifiedCacheDate));
  response.addHeader("Cache-Control", "max-age=" + iCacheMaxExpire + ",
must-revalidate");
}
// Autrement --> pas de cache Apache
else 
{
  Date dExpiresAbsolute = new Date();
  dExpiresAbsolute.setTime(dExpiresAbsolute.getTime() + 24*3600);
  logger.debug("Header Cache-Control = no-cache");
  logger.debug("Header Pragma = No-Cache");
  logger.debug("Header ExpiresAbsolute = " +
getDateAsRFC822String(dExpiresAbsolute));
  logger.debug("Header Expires = -1");
  response.addHeader("Cache-Control", "no-cache");
  response.addHeader("Pragma", "No-Cache");
  response.addHeader("ExpiresAbsolute",
getDateAsRFC822String(dExpiresAbsolute));
  response.addHeader("Expires", "-1");
}
%>

Here is the code I had in declarations.inc :

 

private static PropertiesManager properties = new
PropertiesManager(Jahia.getJahiaPropertiesFileName ());
private boolean bIsReadonlyServer =
"true".equals(properties.getProperty("readonlyserver"));


public static SimpleDateFormat RFC822DATEFORMAT = new
SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
public static String getDateAsRFC822String(Date date)
{
  return RFC822DATEFORMAT.format(date);
}

 

PATCH JAHIA 4.0.6

 

Here is my personnal org.jahia.services.cache.HtmlCacheEntry (in red the
code I've had) :

 

public class HtmlCacheEntry implements Serializable {

 

    /** the HTML body content. */
    private String contentBody = "";

 

    /** the HTML content type. */
    private String contentType = "";

 

    /** the date of HTMLCacheEntry creation / update **/
    private long contentTimestamp = -1;


    public HtmlCacheEntry (String contentBody) {
        init (contentBody, null, new Date().getTime());
    }


    public HtmlCacheEntry (String contentBody, String contentType) {
        init (contentBody, contentType, new Date().getTime());
    }

 

    private void init (String contentBody, String contentType, long
contentTimestamp) {
        if (contentBody != null)
            this.contentBody = contentBody;

        if (contentType != null)
            this.contentType = contentType;
        
        this.contentTimestamp = contentTimestamp;
        
    }


    final public String getContentType() {
        return contentType;
    }


    final public void setContentType (String contentType) {
        this.contentType = contentType;
        this.contentTimestamp = new Date().getTime();
    }


    final public String getContentBody() {
        return contentBody;
    }


    final public void setContentBody (String contentBody) {
        this.contentBody = contentBody;
        this.contentTimestamp = new Date().getTime();
    }

   final public long getContentTimestamp() {
       return contentTimestamp;
   }

}

Then in Apache, I've had a new virtual site declaration for my site

 

<VirtualHost *:80>

  ServerName www.mysite.mydomain.fr

  # Logging access
  CustomLog "|/apache/2.0.54/bin/rotatelogs
/apache/logs/jahiaconsult_access_mysitekey_log.%Y-%m-%d-%H_%M_%S.log 86400"
common

  # Redirections
  Redirect /index.html
http://www.mysite.mydomain.fr/jahia/Jahia/site/mysitekey
  DocumentRoot /apache/2.0.54/htdocs

  RewriteEngine On

  RewriteRule /favicon.ico - [F]
  RewriteRule (.*)/op(.*)$
http://www.mysite.mydomain.edit.fr/jahia/Jahia/engineName/login/site/mysitek
ey
  RewriteRule ^/jahia/administration(.*)$
http://www.mysite.mydomain.edit.fr/jahia/administration

  ProxyPass /jahia/Jahia/op !
  ProxyPass /jahia/Jahia/site/mysitekey/op !
  ProxyPass /jahia/administration !
  ProxyPass /jahia http://www.mysite.mydomain.fr:9080/jahia
  ProxyPassReverse /jahia http://www.mysite.mydomain.fr:9080/jahia

  # Gestion du Cache
  CacheRoot "/apache/2.0.54/proxy/www.mysite.mydomain.fr"
  CacheSize 50000
  CacheEnable disk /
  CacheGcInterval 0.25
  CacheMaxExpire 180
  CacheLastModifiedFactor 0.1
  CacheDefaultExpire 0.25
  CacheDirLength 2
  CacheDirLevels 3

  # Expire - by request
  ExpiresActive On
  ExpiresByType image/gif A86400
  ExpiresByType image/png A86400
  ExpiresByType image/jpeg A86400
  ExpiresByType text/css A86400

</VirtualHost>

 

Regards for your Help.

 

Ghislain CUSSONNEAU

DIRR/DPIL/CIS

CAP 44, Rue Marcel Sembat

44000 Nantes

02 51 84 48 80

 

 

Accédez au courrier électronique de La Poste : www.laposte.net ;

Jusqu'au 25 décembre, participez au grand jeu du Calendrier de l'Avent et

 gagnez tous les jours de nombreux lots, + de 300 cadeaux en jeu !
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.