File Source: PageServlet.java

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   *  contributor license agreements.  The ASF licenses this file to You
     4   * under the Apache License, Version 2.0 (the "License"); you may not
     5   * use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.  For additional information regarding
    15   * copyright in this work, please see the NOTICE file in the top level
    16   * directory of this distribution.
    17   */
    18  
    19  package org.apache.roller.weblogger.ui.rendering.servlets;
    20  
    21  import java.io.IOException;
    22  import java.util.Date;
    23  import java.util.HashMap;
    24  import java.util.Map;
    25  import java.util.regex.Pattern;
    26  import javax.servlet.ServletConfig;
    27  import javax.servlet.ServletException;
    28  import javax.servlet.http.HttpServlet;
    29  import javax.servlet.http.HttpServletRequest;
    30  import javax.servlet.http.HttpServletResponse;
    31  import javax.servlet.jsp.JspFactory;
    32  import javax.servlet.jsp.PageContext;
    33  import org.apache.commons.lang.StringUtils;
    34  import org.apache.commons.logging.Log;
    35  import org.apache.commons.logging.LogFactory;
    36  import org.apache.roller.weblogger.WebloggerException;
    37  import org.apache.roller.weblogger.business.HitCountQueue;
    38  import org.apache.roller.weblogger.business.referrers.IncomingReferrer;
    39  import org.apache.roller.weblogger.business.referrers.ReferrerQueueManager;
    40  import org.apache.roller.weblogger.config.WebloggerConfig;
    41  import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
    42  import org.apache.roller.weblogger.business.WebloggerFactory;
    43  import org.apache.roller.weblogger.business.WeblogManager;
    44  import org.apache.roller.weblogger.pojos.StaticThemeTemplate;
    45  import org.apache.roller.weblogger.pojos.ThemeTemplate;
    46  import org.apache.roller.weblogger.pojos.WeblogEntry;
    47  import org.apache.roller.weblogger.pojos.Weblog;
    48  import org.apache.roller.weblogger.ui.core.RollerContext;
    49  import org.apache.roller.weblogger.ui.rendering.util.InvalidRequestException;
    50  import org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest;
    51  import org.apache.roller.weblogger.util.cache.CachedContent;
    52  import org.apache.roller.weblogger.ui.rendering.Renderer;
    53  import org.apache.roller.weblogger.ui.rendering.RendererManager;
    54  import org.apache.roller.weblogger.ui.rendering.model.ModelLoader;
    55  import org.apache.roller.weblogger.ui.rendering.util.cache.SiteWideCache;
    56  import org.apache.roller.weblogger.ui.rendering.util.WeblogEntryCommentForm;
    57  import org.apache.roller.weblogger.ui.rendering.util.cache.WeblogPageCache;
    58  import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
    59  import org.apache.roller.weblogger.util.BlacklistChecker;
    60  
    61  
    62  /**
    63   * Provides access to weblog pages.
    64   */
         /* 
    P/P   *  Method: void org.apache.roller.weblogger.ui.rendering.servlets.PageServlet()
          * 
          *  Postconditions:
          *    this.excludeOwnerPages == 0
          *    this.processReferrers == 1
          *    this.siteWideCache == null
          *    this.weblogPageCache == null
          */
    65  public class PageServlet extends HttpServlet {
    66  
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.rendering.servlets.PageServlet__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              *    robotPattern == null
              */
    67      private static Log log = LogFactory.getLog(PageServlet.class);
    68      // for referrer processing
    69      private boolean processReferrers = true;
    70      private static Pattern robotPattern = null;
    71      // for caching
    72      private boolean excludeOwnerPages = false;
    73      private WeblogPageCache weblogPageCache = null;
    74      private SiteWideCache siteWideCache = null;
    75  
    76      /**
    77       * Init method for this servlet
    78       */
    79      public void init(ServletConfig servletConfig) throws ServletException {
    80  
                 /* 
    P/P           *  Method: void init(ServletConfig)
                  * 
                  *  Preconditions:
                  *    log != null
                  * 
                  *  Postconditions:
                  *    possibly_updated(robotPattern)
                  *    init'ed(this.excludeOwnerPages)
                  *    init'ed(this.processReferrers)
                  *    init'ed(this.siteWideCache)
                  *    init'ed(this.weblogPageCache)
                  * 
                  *  Test Vectors:
                  *    java.lang.String:length(...)@100: {0}, {1..232-1}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getProperty(...)@99: Addr_Set{null}, Inverse{null}
                  */
    81          super.init(servletConfig);
    82  
    83          log.info("Initializing PageServlet");
    84  
    85          this.excludeOwnerPages = WebloggerConfig.getBooleanProperty("cache.excludeOwnerEditPages");
    86  
    87          // get a reference to the weblog page cache
    88          this.weblogPageCache = WeblogPageCache.getInstance();
    89  
    90          // get a reference to the site wide cache
    91          this.siteWideCache = SiteWideCache.getInstance();
    92  
    93          // see if built-in referrer processing is enabled
    94          this.processReferrers = WebloggerConfig.getBooleanProperty("referrers.processing.enabled");
    95  
    96          log.info("Referrer processing enabled = " + this.processReferrers);
    97  
    98          // check for possible robot pattern
    99          String robotPatternStr = WebloggerConfig.getProperty("referrer.robotCheck.userAgentPattern");
   100          if (robotPatternStr != null && robotPatternStr.length() > 0) {
   101              // Parse the pattern, and store the compiled form.
   102              try {
   103                  robotPattern = Pattern.compile(robotPatternStr);
   104              } catch (Exception e) {
   105                  // Most likely a PatternSyntaxException; log and continue as if it is not set.
   106                  log.error("Error parsing referrer.robotCheck.userAgentPattern value '" + robotPatternStr + "'.  Robots will not be filtered. ", e);
   107              }
   108          }
   109      }
   110  
   111      /**
   112       * Handle GET requests for weblog pages.
   113       */
   114      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   115  
                 /* 
    P/P           *  Method: void doGet(HttpServletRequest, HttpServletResponse)
                  * 
                  *  Preconditions:
                  *    log != null
                  *    init'ed(this.processReferrers)
                  *    (soft) org/apache/roller/weblogger/ui/core/RollerContext.servletContext != null
                  *    (soft) org/apache/roller/weblogger/ui/rendering/RendererManager.rendererFactories != null
                  *    (soft) org/apache/roller/weblogger/ui/rendering/model/ModelLoader.log != null
                  *    (soft) org/apache/roller/weblogger/util/Blacklist.mLogger != null
                  *    (soft) org/apache/roller/weblogger/util/cache/CachedContent.log != null
                  *    (soft) request != null
                  *    (soft) response != null
                  *    (soft) init'ed(robotPattern)
                  *    ...
                  * 
                  *  Presumptions:
                  *    cachedContent.content@190 != null
                  *    cachedContent.content@192 != null
                  *    getContent(...).length@190 <= 232-1
                  *    getContent(...).length@192 <= 232-1
                  *    getContent(...).length@446 <= 232-1
                  *    ...
                  * 
                  *  Test Vectors:
                  *    this.excludeOwnerPages: {0}, {1}
                  *    this.processReferrers: {0}, {1}
                  *    java.lang.String:equals(...)@233: {0}, {1}
                  *    java.lang.String:equals(...)@247: {0}, {1}
                  *    java.lang.String:startsWith(...)@312: {1}, {0}
                  *    java.util.Date:before(...)@316: {0}, {1}
                  *    java.util.List:size(...)@325: {-231..0}, {1..232-1}
                  *    javax.servlet.ServletContext:getMimeType(...)@365: Addr_Set{null}, Inverse{null}
                  *    javax.servlet.http.HttpServletRequest:getAttribute(...)@186: Inverse{null}, Addr_Set{null}
                  *    javax.servlet.http.HttpServletRequest:getAttribute(...)@391: Addr_Set{null}, Inverse{null}
                  *    ...
                  */
   116          log.debug("Entering");
   117  
   118          // do referrer processing, if it's enabled
   119          // NOTE: this *must* be done first because it triggers a hibernate flush
   120          // which will close the active session and cause lazy init exceptions otherwise
   121          if (this.processReferrers) {
   122              boolean spam = this.processReferrer(request);
   123              if (spam) {
   124                  log.debug("spammer, giving 'em a 403");
   125                  if (!response.isCommitted()) {
   126                      response.reset();
   127                  }
   128                  response.sendError(HttpServletResponse.SC_FORBIDDEN);
   129                  return;
   130              }
   131          }
   132  
   133  
   134          Weblog weblog = null;
   135          boolean isSiteWide = false;
   136  
   137          WeblogPageRequest pageRequest = null;
   138          try {
   139              pageRequest = new WeblogPageRequest(request);
   140  
   141              weblog = pageRequest.getWeblog();
   142              if (weblog == null) {
   143                  throw new WebloggerException("unable to lookup weblog: " + pageRequest.getWeblogHandle());
   144              }
   145  
   146              // is this the site-wide weblog?
   147              isSiteWide = WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest.getWeblogHandle());
   148          } catch (Exception e) {
   149              // some kind of error parsing the request or looking up weblog
   150              log.debug("error creating page request", e);
   151              response.sendError(HttpServletResponse.SC_NOT_FOUND);
   152              return;
   153          }
   154  
   155  
   156          // determine the lastModified date for this content
   157          long lastModified = System.currentTimeMillis();
   158          if (isSiteWide) {
   159              lastModified = siteWideCache.getLastModified().getTime();
   160          } else if (weblog.getLastModified() != null) {
   161              lastModified = weblog.getLastModified().getTime();
   162          }
   163  
   164          // 304 Not Modified handling.
   165          // We skip this for logged in users to avoid the scenerio where a user
   166          // views their weblog, logs in, then gets a 304 without the 'edit' links
   167          if (!pageRequest.isLoggedIn()) {
   168              if (ModDateHeaderUtil.respondIfNotModified(request, response, lastModified)) {
   169                  return;
   170              } else {
   171                  // set last-modified date
   172                  ModDateHeaderUtil.setLastModifiedHeader(response, lastModified);
   173              }
   174          }
   175  
   176  
   177          // generate cache key
   178          String cacheKey = null;
   179          if (isSiteWide) {
   180              cacheKey = siteWideCache.generateKey(pageRequest);
   181          } else {
   182              cacheKey = weblogPageCache.generateKey(pageRequest);
   183          }
   184  
   185          // cached content checking
   186          if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) && request.getAttribute("skipCache") == null) {
   187  
   188              CachedContent cachedContent = null;
   189              if (isSiteWide) {
   190                  cachedContent = (CachedContent) siteWideCache.get(cacheKey);
   191              } else {
   192                  cachedContent = (CachedContent) weblogPageCache.get(cacheKey, lastModified);
   193              }
   194  
   195              if (cachedContent != null) {
   196                  log.debug("HIT " + cacheKey);
   197  
   198                  // allow for hit counting
   199                  if (!isSiteWide) {
   200                      this.processHit(weblog, request.getRequestURL().toString(), request.getHeader("referer"));
   201                  }
   202  
   203                  response.setContentLength(cachedContent.getContent().length);
   204                  response.setContentType(cachedContent.getContentType());
   205                  response.getOutputStream().write(cachedContent.getContent());
   206                  return;
   207              } else {
   208                  log.debug("MISS " + cacheKey);
   209              }
   210          }
   211  
   212          log.debug("Looking for template to use for rendering");
   213  
   214          // figure out what template to use
   215          ThemeTemplate page = null;
   216  
   217          // If this is a popup request, then deal with it specially
   218          // TODO: do we really need to keep supporting this?
   219          if (request.getParameter("popup") != null) {
   220              try {
   221                  // Does user have a popupcomments page?
   222                  page = weblog.getTheme().getTemplateByName("_popupcomments");
   223              } catch (Exception e) {
   224                  // ignored ... considered page not found
   225              }
   226  
   227              // User doesn't have one so return the default
   228              if (page == null) {
   229                  page = new StaticThemeTemplate("templates/weblog/popupcomments.vm", "velocity");
   230              }
   231  
   232              // If request specified the page, then go with that
   233          } else if ("page".equals(pageRequest.getContext())) {
   234              page = pageRequest.getWeblogPage();
   235  
   236              // if we don't have this page then 404, we don't let
   237              // this one fall through to the default template
   238              if (page == null) {
   239                  if (!response.isCommitted()) {
   240                      response.reset();
   241                  }
   242                  response.sendError(HttpServletResponse.SC_NOT_FOUND);
   243                  return;
   244              }
   245  
   246              // If request specified tags section index, then look for custom template
   247          } else if ("tags".equals(pageRequest.getContext()) && pageRequest.getTags() == null) {
   248              try {
   249                  page = weblog.getTheme().getTemplateByAction(ThemeTemplate.ACTION_TAGSINDEX);
   250              } catch (Exception e) {
   251                  log.error("Error getting weblog page for action 'tagsIndex'", e);
   252              }
   253  
   254              // if we don't have a custom tags page then 404, we don't let
   255              // this one fall through to the default template
   256              if (page == null) {
   257                  if (!response.isCommitted()) {
   258                      response.reset();
   259                  }
   260                  response.sendError(HttpServletResponse.SC_NOT_FOUND);
   261                  return;
   262              }
   263  
   264              // If this is a permalink then look for a permalink template
   265          } else if (pageRequest.getWeblogAnchor() != null) {
   266              try {
   267                  page = weblog.getTheme().getTemplateByAction(ThemeTemplate.ACTION_PERMALINK);
   268              } catch (Exception e) {
   269                  log.error("Error getting weblog page for action 'permalink'", e);
   270              }
   271          }
   272  
   273          // if we haven't found a page yet then try our default page
   274          if (page == null) {
   275              try {
   276                  page = weblog.getTheme().getDefaultTemplate();
   277              } catch (Exception e) {
   278                  log.error("Error getting default page for weblog = " + weblog.getHandle(), e);
   279              }
   280          }
   281  
   282          // Still no page?  Then that is a 404
   283          if (page == null) {
   284              if (!response.isCommitted()) {
   285                  response.reset();
   286              }
   287              response.sendError(HttpServletResponse.SC_NOT_FOUND);
   288              return;
   289          }
   290  
   291          log.debug("page found, dealing with it");
   292  
   293          // validation.  make sure that request input makes sense.
   294          boolean invalid = false;
   295          if (pageRequest.getWeblogPageName() != null && page.isHidden()) {
   296              invalid = true;
   297          }
   298          if (pageRequest.getLocale() != null) {
   299  
   300              // locale view only allowed if weblog has enabled it
   301              if (!pageRequest.getWeblog().isEnableMultiLang()) {
   302                  invalid = true;
   303              }
   304          }
   305          if (pageRequest.getWeblogAnchor() != null) {
   306  
   307              // permalink specified.
   308              // entry must exist, be published before current time, and locale must match
   309              WeblogEntry entry = pageRequest.getWeblogEntry();
   310              if (entry == null) {
   311                  invalid = true;
   312              } else if (pageRequest.getLocale() != null && !entry.getLocale().startsWith(pageRequest.getLocale())) {
   313                  invalid = true;
   314              } else if (!entry.isPublished()) {
   315                  invalid = true;
   316              } else if (new Date().before(entry.getPubTime())) {
   317                  invalid = true;
   318              }
   319          } else if (pageRequest.getWeblogCategoryName() != null) {
   320  
   321              // category specified.  category must exist.
   322              if (pageRequest.getWeblogCategory() == null) {
   323                  invalid = true;
   324              }
   325          } else if (pageRequest.getTags() != null && pageRequest.getTags().size() > 0) {
   326  
   327              try {
   328                  // tags specified.  make sure they exist.
   329                  WeblogManager wmgr = WebloggerFactory.getWeblogger().getWeblogManager();
   330                  invalid = !wmgr.getTagComboExists(pageRequest.getTags(), (isSiteWide) ? null : weblog);
   331              } catch (WebloggerException ex) {
   332                  invalid = true;
   333              }
   334          }
   335  
   336  
   337          if (invalid) {
   338              log.debug("page failed validation, bailing out");
   339              if (!response.isCommitted()) {
   340                  response.reset();
   341              }
   342              response.sendError(HttpServletResponse.SC_NOT_FOUND);
   343              return;
   344          }
   345  
   346  
   347          // do we need to force a specific locale for the request?
   348          if (pageRequest.getLocale() == null && !weblog.isShowAllLangs()) {
   349              pageRequest.setLocale(weblog.getLocale());
   350          }
   351  
   352  
   353          // allow for hit counting
   354          if (!isSiteWide) {
   355              this.processHit(weblog, request.getRequestURL().toString(), request.getHeader("referer"));
   356          }
   357  
   358  
   359          // looks like we need to render content
   360          // set the content type
+  361          String contentType = "text/html; charset=utf-8";
   362          if (StringUtils.isNotEmpty(page.getOutputContentType())) {
   363              contentType = page.getOutputContentType() + "; charset=utf-8";
   364          } else {
   365              String mimeType = RollerContext.getServletContext().getMimeType(page.getLink());
   366              if (mimeType != null) {
   367                  // we found a match ... set the content type
   368                  contentType = mimeType + "; charset=utf-8";
   369              } else {
   370                  contentType = "text/html; charset=utf-8";
   371              }
   372          }
   373  
   374          HashMap model = new HashMap();
   375          try {
   376              PageContext pageContext = JspFactory.getDefaultFactory().getPageContext(this, request, response, "", false, 8192, true);
   377  
   378              // special hack for menu tag
   379              request.setAttribute("pageRequest", pageRequest);
   380  
   381              // populate the rendering model
   382              Map initData = new HashMap();
   383              initData.put("requestParameters", request.getParameterMap());
   384              initData.put("parsedRequest", pageRequest);
   385              initData.put("pageContext", pageContext);
   386  
   387              // define url strategy
   388              initData.put("urlStrategy", WebloggerFactory.getWeblogger().getUrlStrategy());
   389  
   390              // if this was a comment posting, check for comment form
   391              WeblogEntryCommentForm commentForm = (WeblogEntryCommentForm) request.getAttribute("commentForm");
   392              if (commentForm != null) {
   393                  initData.put("commentForm", commentForm);
   394              }
   395  
   396              // Load models for pages
   397              String pageModels = WebloggerConfig.getProperty("rendering.pageModels");
   398              ModelLoader.loadModels(pageModels, model, initData, true);
   399  
   400              // Load special models for site-wide blog
   401              if (WebloggerRuntimeConfig.isSiteWideWeblog(weblog.getHandle())) {
   402                  String siteModels = WebloggerConfig.getProperty("rendering.siteModels");
   403                  ModelLoader.loadModels(siteModels, model, initData, true);
   404              }
   405  
   406              // Load weblog custom models
   407              ModelLoader.loadCustomModels(weblog, model, initData);
   408  
   409              // ick, gotta load pre-3.0 model stuff as well :(
   410              ModelLoader.loadOldModels(model, request, response, pageContext, pageRequest, WebloggerFactory.getWeblogger().getUrlStrategy());
   411          } catch (WebloggerException ex) {
   412              log.error("Error loading model objects for page", ex);
   413  
   414              if (!response.isCommitted()) {
   415                  response.reset();
   416              }
   417              response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
   418              return;
   419          }
   420  
   421  
   422          // lookup Renderer we are going to use
   423          Renderer renderer = null;
   424          try {
   425              log.debug("Looking up renderer");
   426              renderer = RendererManager.getRenderer(page);
   427          } catch (Exception e) {
   428              // nobody wants to render my content :(
   429              log.error("Couldn't find renderer for page " + page.getId(), e);
   430  
   431              if (!response.isCommitted()) {
   432                  response.reset();
   433              }
   434              response.sendError(HttpServletResponse.SC_NOT_FOUND);
   435              return;
   436          }
   437  
   438          // render content.  use size of about 24K for a standard page
   439          CachedContent rendererOutput = new CachedContent(24567, contentType);
   440          try {
   441              log.debug("Doing rendering");
   442              renderer.render(model, rendererOutput.getCachedWriter());
   443  
   444              // flush rendered output and close
   445              rendererOutput.flush();
   446              rendererOutput.close();
   447          } catch (Exception e) {
   448              // bummer, error during rendering
   449              log.error("Error during rendering for page " + page.getId(), e);
   450  
   451              if (!response.isCommitted()) {
   452                  response.reset();
   453              }
   454              response.sendError(HttpServletResponse.SC_NOT_FOUND);
   455              return;
   456          }
   457  
   458  
   459          // post rendering process
   460          // flush rendered content to response
   461          log.debug("Flushing response output");
   462          response.setContentType(contentType);
+  463          response.setContentLength(rendererOutput.getContent().length);
   464          response.getOutputStream().write(rendererOutput.getContent());
   465  
   466          // cache rendered content.  only cache if user is not logged in?
   467          if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) && request.getAttribute("skipCache") == null) {
   468              log.debug("PUT " + cacheKey);
   469  
   470              // put it in the right cache
   471              if (isSiteWide) {
   472                  siteWideCache.put(cacheKey, rendererOutput);
   473              } else {
   474                  weblogPageCache.put(cacheKey, rendererOutput);
   475              }
   476          } else {
   477              log.debug("SKIPPED " + cacheKey);
   478          }
   479  
   480          log.debug("Exiting");
   481      }
   482  
   483      /**
   484       * Handle POST requests.
   485       *
   486       * We have this here because the comment servlet actually forwards some of
   487       * its requests on to us to render some pages with cusom messaging.  We
   488       * may want to revisit this approach in the future and see if we can do
   489       * this in a different way, but for now this is the easy way.
   490       */
   491      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   492  
   493          // make sure caching is disabled
                 /* 
    P/P           *  Method: void doPost(HttpServletRequest, HttpServletResponse)
                  * 
                  *  Preconditions:
                  *    request != null
                  */
   494          request.setAttribute("skipCache", "true");
   495  
   496          // handle just like a GET request
   497          this.doGet(request, response);
   498      }
   499  
   500      /**
   501       * Notify the hit tracker that it has an incoming page hit.
   502       */
   503      private void processHit(Weblog weblog, String url, String referrer) {
   504  
                 /* 
    P/P           *  Method: void processHit(Weblog, String, String)
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.business.HitCountQueue:getInstance(...)@505 != null
                  */
   505          HitCountQueue counter = HitCountQueue.getInstance();
   506          counter.processHit(weblog, url, referrer);
   507      }
   508  
   509      /**
   510       * Process the incoming request to extract referrer info and pass it on
   511       * to the referrer processing queue for tracking.
   512       *
   513       * @returns true if referrer was spam, false otherwise
   514       */
   515      private boolean processReferrer(HttpServletRequest request) {
   516  
                 /* 
    P/P           *  Method: bool processReferrer(HttpServletRequest)
                  * 
                  *  Preconditions:
                  *    log != null
                  *    request != null
                  *    (soft) org/apache/roller/weblogger/util/Blacklist.mLogger != null
                  *    (soft) init'ed(robotPattern)
                  * 
                  *  Presumptions:
                  *    java.util.regex.Pattern:matcher(...)@538 != null
                  *    javax.servlet.http.HttpServletRequest:getRequestURL(...)@545 != null
                  *    org.apache.roller.weblogger.business.Weblogger:getReferrerQueueManager(...)@605 != null
                  *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@605 != null
                  *    org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest:getWeblog(...)@586 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    robotPattern: Addr_Set{null}, Inverse{null}
                  *    java.lang.String:indexOf(...)@556: {-1}, {-231..-2, 0..232-1}
                  *    java.lang.String:indexOf(...)@578: {-231..-2, 0..232-1}, {-1}
                  *    java.lang.String:length(...)@538: {0}, {1..232-1}
                  *    java.lang.String:matches(...)@584: {0}, {1}
                  *    java.lang.String:startsWith(...)@567: {0}, {1}
                  *    java.lang.String:startsWith(...)@573: {1}, {0}
                  *    java.util.regex.Matcher:matches(...)@538: {0}, {1}
                  *    javax.servlet.http.HttpServletRequest:getHeader(...)@537: Addr_Set{null}, Inverse{null}
                  *    javax.servlet.http.HttpServletRequest:getHeader(...)@544: Addr_Set{null}, Inverse{null}
                  *    ...
                  */
   517          log.debug("processing referrer for " + request.getRequestURI());
   518  
   519          // bleh!  because ref processing does a flush it will close
   520          // our hibernate session and cause lazy init exceptions on
   521          // objects we have fetched, so we need to use a separate
   522          // page request object for this
   523          WeblogPageRequest pageRequest;
   524          try {
   525              pageRequest = new WeblogPageRequest(request);
   526          } catch (InvalidRequestException ex) {
   527              return false;
   528          }
   529  
   530          // if this came from site-wide frontpage then skip it
   531          if (WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest.getWeblogHandle())) {
   532              return false;
   533          }
   534  
   535          // if this came from a robot then don't process it
   536          if (robotPattern != null) {
   537              String userAgent = request.getHeader("User-Agent");
   538              if (userAgent != null && userAgent.length() > 0 && robotPattern.matcher(userAgent).matches()) {
   539                  log.debug("skipping referrer from robot");
   540                  return false;
   541              }
   542          }
   543  
   544          String referrerUrl = request.getHeader("Referer");
   545          StringBuffer reqsb = request.getRequestURL();
   546          if (request.getQueryString() != null) {
   547              reqsb.append("?");
   548              reqsb.append(request.getQueryString());
   549          }
   550          String requestUrl = reqsb.toString();
   551  
   552          log.debug("referrer = " + referrerUrl);
   553  
   554          // if this came from persons own blog then don't process it
   555          String selfSiteFragment = "/" + pageRequest.getWeblogHandle();
   556          if (referrerUrl != null && referrerUrl.indexOf(selfSiteFragment) != -1) {
   557              log.debug("skipping referrer from own blog");
   558              return false;
   559          }
   560  
   561          // validate the referrer
+  562          if (pageRequest != null && pageRequest.getWeblogHandle() != null) {
   563  
   564              // Base page URLs, with and without www.
   565              String basePageUrlWWW = WebloggerRuntimeConfig.getAbsoluteContextURL() + "/" + pageRequest.getWeblogHandle();
   566              String basePageUrl = basePageUrlWWW;
   567              if (basePageUrlWWW.startsWith("http://www.")) {
   568                  // chop off the http://www.
   569                  basePageUrl = "http://" + basePageUrlWWW.substring(11);
   570              }
   571  
   572              // ignore referrers coming from users own blog
   573              if (referrerUrl == null || (!referrerUrl.startsWith(basePageUrl) && !referrerUrl.startsWith(basePageUrlWWW))) {
   574  
   575                  // validate the referrer
   576                  if (referrerUrl != null) {
   577                      // treat editor referral as direct
   578                      int lastSlash = requestUrl.indexOf("/", 8);
   579                      if (lastSlash == -1) {
   580                          lastSlash = requestUrl.length();
   581                      }
   582                      String requestSite = requestUrl.substring(0, lastSlash);
   583  
   584                      if (referrerUrl.matches(requestSite + ".*\\.rol.*")) {
   585                          referrerUrl = null;
   586                      } else if (BlacklistChecker.checkReferrer(pageRequest.getWeblog(), referrerUrl)) {
   587                          return true;
   588                      }
   589                  }
   590              } else {
   591                  log.debug("Ignoring referer = " + referrerUrl);
   592                  return false;
   593              }
   594          }
   595  
   596          // referrer is valid, lets record it
   597          try {
   598              IncomingReferrer referrer = new IncomingReferrer();
   599              referrer.setReferrerUrl(referrerUrl);
   600              referrer.setRequestUrl(requestUrl);
   601              referrer.setWeblogHandle(pageRequest.getWeblogHandle());
   602              referrer.setWeblogAnchor(pageRequest.getWeblogAnchor());
   603              referrer.setWeblogDateString(pageRequest.getWeblogDate());
   604  
   605              ReferrerQueueManager refQueue = WebloggerFactory.getWeblogger().getReferrerQueueManager();
   606              refQueue.processReferrer(referrer);
   607          } catch (Exception e) {
   608              log.error("Error processing referrer", e);
   609          }
   610  
   611          return false;
   612      }
   613  }








SofCheck Inspector Build Version : 2.18479
PageServlet.java 2009-Jan-02 14:24:58
PageServlet.class 2009-Sep-04 03:12:45