changeset 15:5a2a8201bb6f

make moin friendlier to proxies, thanks to ASF imported from: moin--main--1.5--patch-16
author Thomas Waldmann <tw@waldmann-edv.de>
date Fri, 23 Sep 2005 20:02:07 +0000
parents c8a7e012ebeb
children 9c868ac2ccc6
files MoinMoin/Page.py MoinMoin/action/rss_rc.py MoinMoin/i18n/__init__.py MoinMoin/multiconfig.py MoinMoin/request.py MoinMoin/server/standalone.py MoinMoin/util/datetime.py MoinMoin/wikiaction.py
diffstat 8 files changed, 56 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/Page.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/Page.py	Fri Sep 23 20:02:07 2005 +0000
@@ -11,6 +11,7 @@
 from MoinMoin import config, caching, user, util, wikiutil
 from MoinMoin.logfile import eventlog
 from MoinMoin.util import filesys, web
+from MoinMoin.util.datetime import formathttpdate
 
 class Page:
     """Page - Manage an (immutable) page associated with a WikiName.
@@ -1090,8 +1091,24 @@
         page_exists = self.exists()
         if not content_only:
             # send the document leader
+
+            # need to inform caches that content changes
+            # based on cookie (even if we aren't sending one now)
+            request.setHttpHeader("Vary: Cookie")
+
+            # use "nocache" headers if we're using a method that
+            # is not simply "display", or if a user is logged in
+            # (which triggers personalisation features)
+
             if page_exists:
-                request.http_headers()
+                if not request.cacheable or request.user.valid:
+                    request.http_headers(request.nocache)
+                else:
+                    # use the correct last-modified value from the on-disk file
+                    # to ensure cacheability where supported
+                    request.http_headers(["Last-Modified: " +
+                         formathttpdate(os.path.getmtime(self._text_filename()))])
+
             else:
                 request.http_headers(['Status: 404 NOTFOUND'])
                 request.setResponseCode(404)
--- a/MoinMoin/action/rss_rc.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/action/rss_rc.py	Fri Sep 23 20:02:07 2005 +0000
@@ -7,9 +7,10 @@
 
     @license: GNU GPL, see COPYING for details.
 """
-import StringIO, re, os
+import StringIO, re, os, time
 from MoinMoin import wikixml, config, wikiutil, util
 from MoinMoin.logfile import editlog
+from MoinMoin.util.datetime import formathttpdate
 from MoinMoin.Page import Page
 from MoinMoin.wikixml.util import RssGenerator
 
@@ -59,6 +60,7 @@
     logdata = []
     counter = 0
     pages = {}
+    lastmod = 0
     for line in log.reverse():
         if not request.user.may.read(line.pagename):
             continue
@@ -69,6 +71,10 @@
         line.time = util.datetime.tmtuple(wikiutil.version2timestamp(line.ed_time_usecs)) # UTC
         logdata.append(line)
         pages[line.pagename] = None
+
+        if not lastmod:
+            lastmod = wikiutil.version2timestamp(line.ed_time_usecs)
+
         counter += 1
         if counter >= max_items:
             break
@@ -197,8 +203,20 @@
     # end SAX stream
     handler.endDocument()
 
+    # generate an Expires header, using whatever setting the admin
+    # defined for suggested cache lifetime of the RecentChanges RSS doc
+    expires = formathttpdate(time.time() + cfg.rss_cache)
+
+    httpheaders = ["Content-Type: text/xml; charset=%s" % config.charset,
+                        "Expires: "+expires]
+
+    # use a correct Last-Modified header, set to whatever the mod date
+    # on the most recent page was; if there were no mods, don't send one
+    if lastmod:
+        httpheaders.append("Last-Modified: "+formathttpdate(lastmod))
+
     # send the generated XML document
-    request.http_headers(["Content-Type: text/xml; charset=%s" % config.charset] + request.nocache)
+    request.http_headers(httpheaders)
     request.write(out.getvalue())
     request.finish()
     request.no_closing_html_code = 1
--- a/MoinMoin/i18n/__init__.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/i18n/__init__.py	Fri Sep 23 20:02:07 2005 +0000
@@ -199,6 +199,8 @@
     available = wikiLanguages()
     for lang in browserLanguages(request):
         if available.has_key(lang):
+            if request.http_accept_language:
+                request.setHttpHeader('Vary: Accept-Language')
             return lang
     
     # Or return the wiki default language...
--- a/MoinMoin/multiconfig.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/multiconfig.py	Fri Sep 23 20:02:07 2005 +0000
@@ -263,6 +263,7 @@
         'up':          ("%(q_page_parent_page)s", _("Up"), "up"),
         }
     refresh = None # (minimum_delay, type), e.g.: (2, 'internal')
+    rss_cache = 60 # suggested caching time for RecentChanges RSS, in seconds
     shared_intermap = None # can be string or list of strings (filenames)
     show_hosts = 1
     show_section_numbers = 0
--- a/MoinMoin/request.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/request.py	Fri Sep 23 20:02:07 2005 +0000
@@ -90,6 +90,7 @@
               
         self.sent_headers = 0
         self.user_headers = []
+        self.cacheable = 0 # may this output get cached by http proxies/caches?
         self.page = None
         self._dicts = None
         
--- a/MoinMoin/server/standalone.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/server/standalone.py	Fri Sep 23 20:02:07 2005 +0000
@@ -37,12 +37,12 @@
 # Imports
 import os, sys, time, urllib, socket, errno, shutil
 import BaseHTTPServer, SimpleHTTPServer, SocketServer
-from email.Utils import formatdate
 
 # MoinMoin imports
 from MoinMoin import version
 from MoinMoin.server import Config, switchUID
 from MoinMoin.request import RequestStandAlone
+from MoinMoin.util.datetime import formathttpdate
 
 # Server globals
 httpd = None
@@ -371,7 +371,7 @@
         if self.expires:
             now = time.time()
             expires = now + self.expires
-            self.send_header('Expires', formatdate(expires))
+            self.send_header('Expires', formathttpdate(expires))
         SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)
         
     def copyfile(self, source, outputfile):
--- a/MoinMoin/util/datetime.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/util/datetime.py	Fri Sep 23 20:02:07 2005 +0000
@@ -8,7 +8,8 @@
 
 # we guarantee that time is always imported!
 import time
-
+import re
+from email.Utils import formatdate
 
 def tmtuple(tmsecs=None):
     """ Return a time tuple.
@@ -20,3 +21,12 @@
         tmsecs = 0                # 0 initially, so reset it to 0.
     return time.gmtime(tmsecs or time.time())
 
+def formathttpdate(tmsecs=None):
+    """ Return a HTTP date/time stamp as defined in
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 .
+    """
+    stamp = formatdate(tmsecs, False)
+    # replace non-standard "-0000" at end with http-mandated "GMT"
+    stamp = re.match('^(.*) [\-\+]0000$', stamp).group(1) + " GMT"
+    return stamp
+
--- a/MoinMoin/wikiaction.py	Fri Sep 23 19:27:45 2005 +0000
+++ b/MoinMoin/wikiaction.py	Fri Sep 23 20:02:07 2005 +0000
@@ -465,6 +465,7 @@
             rev = 0
         Page(request, pagename, rev=rev).send_page(request, count_hit=1)
     else:
+        request.cacheable = 1
         Page(request, pagename).send_page(request, count_hit=1)