1- # $Id: client.py,v 1.98 2003-02-26 04:08:04 richard Exp $
1+ # $Id: client.py,v 1.99 2003-02-26 04:51:41 richard Exp $
22
33__doc__ = """
44WWW request handler (also used in the stand-alone server).
55"""
66
77import os , os .path , cgi , StringIO , urlparse , re , traceback , mimetypes , urllib
88import binascii , Cookie , time , random , MimeWriter , smtplib , socket , quopri
9+ import stat , rfc822
910
1011from roundup import roundupdb , date , hyperdb , password
1112from roundup .i18n import _
@@ -22,6 +23,8 @@ class NotFound(HTTPException):
2223 pass
2324class Redirect (HTTPException ):
2425 pass
26+ class NotModified (HTTPException ):
27+ pass
2528
2629# XXX actually _use_ FormError
2730class FormError (ValueError ):
@@ -235,7 +238,12 @@ def inner_main(self):
235238 except SendFile , designator :
236239 self .serve_file (designator )
237240 except SendStaticFile , file :
238- self .serve_static_file (str (file ))
241+ try :
242+ self .serve_static_file (str (file ))
243+ except NotModified :
244+ # send the 304 response
245+ self .request .send_response (304 )
246+ self .request .end_headers ()
239247 except Unauthorised , message :
240248 self .classname = None
241249 self .template = ''
@@ -422,11 +430,26 @@ def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')):
422430 self .write (file .get (nodeid , 'content' ))
423431
424432 def serve_static_file (self , file ):
433+ # see if there's an if-modified-since...
434+ ims = self .request .headers .getheader ('if-modified-since' )
435+ # cgi will put the header in the env var
436+ if not ims and self .env .has_key ('HTTP_IF_MODIFIED_SINCE' ):
437+ ims = self .env ['HTTP_IF_MODIFIED_SINCE' ]
438+ filename = os .path .join (self .instance .config .TEMPLATES , file )
439+ lmt = os .stat (filename )[stat .ST_MTIME ]
440+ if ims :
441+ ims = rfc822 .parsedate (ims )[:6 ]
442+ lmtt = time .gmtime (lmt )[:6 ]
443+ if lmtt <= ims :
444+ raise NotModified
445+
425446 # we just want to serve up the file named
426447 mt = mimetypes .guess_type (str (file ))[0 ]
448+ if not mt :
449+ mt = 'text/plain'
427450 self .additional_headers ['Content-Type' ] = mt
428- self .write ( open ( os . path . join ( self . instance . config . TEMPLATES ,
429- file ) ).read ())
451+ self .additional_headers [ 'Last-Modifed' ] = rfc822 . formatdate ( lmt )
452+ self . write ( open ( filename ).read ())
430453
431454 def renderContext (self ):
432455 ''' Return a PageTemplate for the named page
0 commit comments