etwist/request.py
brancholdstable
changeset 8746 88c71ad83d47
parent 8316 d5b1b75805dd
child 8752 e19f4bba89cd
equal deleted inserted replaced
8507:0c111b232927 8746:88c71ad83d47
    25 
    25 
    26 from cubicweb.web import DirectResponse
    26 from cubicweb.web import DirectResponse
    27 from cubicweb.web.request import CubicWebRequestBase
    27 from cubicweb.web.request import CubicWebRequestBase
    28 from cubicweb.web.httpcache import GMTOFFSET
    28 from cubicweb.web.httpcache import GMTOFFSET
    29 from cubicweb.web.http_headers import Headers
    29 from cubicweb.web.http_headers import Headers
    30 from cubicweb.etwist.http import not_modified_response
       
    31 
    30 
    32 
    31 
    33 class CubicWebTwistedRequestAdapter(CubicWebRequestBase):
    32 class CubicWebTwistedRequestAdapter(CubicWebRequestBase):
    34     def __init__(self, req, vreg, https, base_url):
    33     def __init__(self, req, vreg, https):
    35         self._twreq = req
    34         self._twreq = req
    36         self._base_url = base_url
    35         super(CubicWebTwistedRequestAdapter, self).__init__(
    37         super(CubicWebTwistedRequestAdapter, self).__init__(vreg, https, req.args)
    36             vreg, https, req.args, headers=req.received_headers)
    38         for key, (name, stream) in req.files.iteritems():
    37         for key, (name, stream) in req.files.iteritems():
    39             if name is None:
    38             if name is None:
    40                 self.form[key] = (name, stream)
    39                 self.form[key] = (name, stream)
    41             else:
    40             else:
    42                 self.form[key] = (unicode(name, self.encoding), stream)
    41                 self.form[key] = (unicode(name, self.encoding), stream)
    43         # XXX can't we keep received_headers?
       
    44         self._headers_in = Headers()
       
    45         for k, v in req.received_headers.iteritems():
       
    46             self._headers_in.addRawHeader(k, v)
       
    47 
       
    48     def base_url(self):
       
    49         """return the root url of the instance"""
       
    50         return self._base_url
       
    51 
    42 
    52     def http_method(self):
    43     def http_method(self):
    53         """returns 'POST', 'GET', 'HEAD', etc."""
    44         """returns 'POST', 'GET', 'HEAD', etc."""
    54         return self._twreq.method
    45         return self._twreq.method
    55 
    46 
    63         """
    54         """
    64         path = self._twreq.uri[1:] # remove the root '/'
    55         path = self._twreq.uri[1:] # remove the root '/'
    65         if not includeparams:
    56         if not includeparams:
    66             path = path.split('?', 1)[0]
    57             path = path.split('?', 1)[0]
    67         return path
    58         return path
    68 
       
    69     def get_header(self, header, default=None, raw=True):
       
    70         """return the value associated with the given input header, raise
       
    71         KeyError if the header is not set
       
    72         """
       
    73         if raw:
       
    74             return self._headers_in.getRawHeaders(header, [default])[0]
       
    75         return self._headers_in.getHeader(header, default)
       
    76 
       
    77     def _validate_cache(self):
       
    78         """raise a `DirectResponse` exception if a cached page along the way
       
    79         exists and is still usable
       
    80         """
       
    81         if self.get_header('Cache-Control') in ('max-age=0', 'no-cache'):
       
    82             # Expires header seems to be required by IE7
       
    83             self.add_header('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
       
    84             return
       
    85         # when using both 'Last-Modified' and 'ETag' response headers
       
    86         # (i.e. using respectively If-Modified-Since and If-None-Match request
       
    87         # headers, see
       
    88         # http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 for
       
    89         # reference
       
    90         last_modified = self.headers_out.getHeader('last-modified')
       
    91         if last_modified is not None:
       
    92             status = self._twreq.setLastModified(last_modified)
       
    93             if status != http.CACHED:
       
    94                 return
       
    95         etag = self.headers_out.getRawHeaders('etag')
       
    96         if etag is not None:
       
    97             status = self._twreq.setETag(etag[0])
       
    98             if status == http.CACHED:
       
    99                 response = not_modified_response(self._twreq, self._headers_in)
       
   100                 raise DirectResponse(response)
       
   101         # Expires header seems to be required by IE7
       
   102         self.add_header('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
       
   103 
       
   104     def header_accept_language(self):
       
   105         """returns an ordered list of preferred languages"""
       
   106         acceptedlangs = self.get_header('Accept-Language', raw=False) or {}
       
   107         for lang, _ in sorted(acceptedlangs.iteritems(), key=lambda x: x[1],
       
   108                               reverse=True):
       
   109             lang = lang.split('-')[0]
       
   110             yield lang
       
   111 
       
   112     def header_if_modified_since(self):
       
   113         """If the HTTP header If-modified-since is set, return the equivalent
       
   114         date time value (GMT), else return None
       
   115         """
       
   116         mtime = self.get_header('If-modified-since', raw=False)
       
   117         if mtime:
       
   118             # :/ twisted is returned a localized time stamp
       
   119             return datetime.fromtimestamp(mtime) + GMTOFFSET
       
   120         return None