mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-23 22:52:25 +01:00
- dispatching: cleanup wbrequestresponse, move tests to a seperate file - wbrequest: store both rel_prefix and host_prefix, with wb_prefix either full or rel path as needed, so that full and relative paths are both available in wbrequest - create WbUrlHandler to differentiate handlers which support WbUrl (timestamp[mod]/url) semantic vs other request handlers.
154 lines
4.1 KiB
Python
154 lines
4.1 KiB
Python
from pywb.utils.statusandheaders import StatusAndHeaders
|
|
import pprint
|
|
|
|
|
|
#=================================================================
|
|
class WbRequest:
|
|
"""
|
|
Represents the main pywb request object.
|
|
|
|
Contains various info from wsgi env, add additional info
|
|
about the request, such as coll, relative prefix,
|
|
host prefix, absolute prefix.
|
|
|
|
If a wburl and url rewriter classes are specified, the class
|
|
also contains the url rewriter.
|
|
|
|
"""
|
|
@staticmethod
|
|
def make_host_prefix(env):
|
|
try:
|
|
host = env.get('HTTP_HOST')
|
|
if not host:
|
|
host = env['SERVER_NAME'] + ':' + env['SERVER_PORT']
|
|
|
|
return env['wsgi.url_scheme'] + '://' + host
|
|
except KeyError:
|
|
return ''
|
|
|
|
|
|
def __init__(self, env,
|
|
request_uri=None,
|
|
rel_prefix='',
|
|
wb_url_str='/',
|
|
coll='',
|
|
host_prefix='',
|
|
use_abs_prefix=False,
|
|
wburl_class=None,
|
|
urlrewriter_class=None,
|
|
is_proxy=False):
|
|
|
|
self.env = env
|
|
|
|
self.request_uri = request_uri if request_uri else env.get('REL_REQUEST_URI')
|
|
|
|
self.coll = coll
|
|
|
|
if not host_prefix:
|
|
host_prefix = self.make_host_prefix(env)
|
|
|
|
self.host_prefix = host_prefix
|
|
self.rel_prefix = rel_prefix
|
|
|
|
if use_abs_prefix:
|
|
self.wb_prefix = host_prefix + rel_prefix
|
|
else:
|
|
self.wb_prefix = rel_prefix
|
|
|
|
|
|
if not wb_url_str:
|
|
wb_url_str = '/'
|
|
|
|
self.wb_url_str = wb_url_str
|
|
|
|
# wb_url present and not root page
|
|
if wb_url_str != '/' and wburl_class:
|
|
self.wb_url = wburl_class(wb_url_str)
|
|
self.urlrewriter = urlrewriter_class(self.wb_url, self.wb_prefix)
|
|
else:
|
|
# no wb_url, just store blank wb_url
|
|
self.wb_url = None
|
|
self.urlrewriter = None
|
|
|
|
self.referrer = env.get('HTTP_REFERER')
|
|
|
|
self.is_ajax = self._is_ajax()
|
|
|
|
self.query_filter = []
|
|
|
|
self.is_proxy = is_proxy
|
|
|
|
self.custom_params = {}
|
|
|
|
# PERF
|
|
env['X_PERF'] = {}
|
|
|
|
|
|
def _is_ajax(self):
|
|
value = self.env.get('HTTP_X_REQUESTED_WITH')
|
|
if not value:
|
|
return False
|
|
|
|
if value.lower() == 'xmlhttprequest':
|
|
return True
|
|
|
|
if self.referrer and ('ajaxpipe' in self.env.get('QUERY_STRING')):
|
|
return True
|
|
return False
|
|
|
|
|
|
def __repr__(self):
|
|
varlist = vars(self)
|
|
varstr = pprint.pformat(varlist)
|
|
return varstr
|
|
|
|
|
|
#=================================================================
|
|
class WbResponse:
|
|
"""
|
|
Represnts a pywb wsgi response object.
|
|
|
|
Holds a status_headers object and a response iter, to be
|
|
returned to wsgi container.
|
|
"""
|
|
def __init__(self, status_headers, value = []):
|
|
self.status_headers = status_headers
|
|
self.body = value
|
|
|
|
@staticmethod
|
|
def text_stream(text, status = '200 OK', content_type = 'text/plain'):
|
|
return WbResponse(StatusAndHeaders(status, [('Content-Type', content_type)]), value = text)
|
|
|
|
@staticmethod
|
|
def text_response(text, status = '200 OK', content_type = 'text/plain'):
|
|
return WbResponse(StatusAndHeaders(status, [('Content-Type', content_type)]), value = [text])
|
|
|
|
@staticmethod
|
|
def redir_response(location, status = '302 Redirect'):
|
|
return WbResponse(StatusAndHeaders(status, [('Location', location)]))
|
|
|
|
|
|
def __call__(self, env, start_response):
|
|
|
|
# PERF
|
|
perfstats = env.get('X_PERF')
|
|
if perfstats:
|
|
self.status_headers.headers.append(('X-Archive-Perf-Stats', str(perfstats)))
|
|
|
|
|
|
start_response(self.status_headers.statusline, self.status_headers.headers)
|
|
|
|
if env['REQUEST_METHOD'] == 'HEAD':
|
|
if hasattr(self.body, 'close'):
|
|
self.body.close()
|
|
return []
|
|
|
|
if hasattr(self.body, '__iter__'):
|
|
return self.body
|
|
else:
|
|
return [str(self.body)]
|
|
|
|
|
|
def __repr__(self):
|
|
return str(vars(self))
|