示例#1
0
文件: proxy.py 项目: akeprojecta/pywb
    def handle_cert_install(self, env):
        if env['pywb.proxy_req_uri'] in ('/', '/index.html', '/index.html'):
            available = (self.ca is not None)

            if self.proxy_cert_dl_view:
                return (self.proxy_cert_dl_view.
                         render_response(available=available,
                                         pem_path=self.CERT_DL_PEM,
                                         p12_path=self.CERT_DL_P12))

        elif env['pywb.proxy_req_uri'] == self.CERT_DL_PEM:
            if not self.ca:
                return None

            buff = ''
            with open(self.ca.ca_file, 'rb') as fh:
                buff = fh.read()

            content_type = 'application/x-x509-ca-cert'

            return WbResponse.text_response(buff,
                                            content_type=content_type)

        elif env['pywb.proxy_req_uri'] == self.CERT_DL_P12:
            if not self.ca:
                return None

            buff = self.ca.get_root_PKCS12()

            content_type = 'application/x-pkcs12'

            return WbResponse.text_response(buff,
                                            content_type=content_type)
示例#2
0
    def handle_cert_install(self, env):
        if env['pywb.proxy_req_uri'] in ('/', '/index.html', '/index.html'):
            available = (self.ca is not None)

            if self.proxy_cert_dl_view:
                return (self.proxy_cert_dl_view.render_response(
                    available=available,
                    pem_path=self.CERT_DL_PEM,
                    p12_path=self.CERT_DL_P12))

        elif env['pywb.proxy_req_uri'] == self.CERT_DL_PEM:
            if not self.ca:
                return None

            buff = ''
            with open(self.ca.ca_file) as fh:
                buff = fh.read()

            content_type = 'application/x-x509-ca-cert'

            return WbResponse.text_response(buff, content_type=content_type)

        elif env['pywb.proxy_req_uri'] == self.CERT_DL_P12:
            if not self.ca:
                return None

            buff = self.ca.get_root_PKCS12()

            content_type = 'application/x-pkcs12'

            return WbResponse.text_response(buff, content_type=content_type)
示例#3
0
 def render_home_page(self):
     # render the homepage!
     if self.home_view:
         return self.home_view.render_response(routes = self.routes)
     else:
         # default home page template
         text = '\n'.join(map(str, self.routes))
         return WbResponse.text_response(text)
示例#4
0
 def render_home_page(self, env):
     # render the homepage!
     if self.home_view:
         return self.home_view.render_response(env=env, routes=self.routes)
     else:
         # default home page template
         text = '\n'.join(map(str, self.routes))
         return WbResponse.text_response(text)
示例#5
0
    def make_redir_response(self, url, headers=None):
        if not headers:
            headers = []

        if self.extra_headers:
            for name, value in self.extra_headers.iteritems():
                headers.append((name, value))

        return WbResponse.redir_response(url, headers=headers)
示例#6
0
    def make_redir_response(self, url, headers=None):
        if not headers:
            headers = []

        if self.extra_headers:
            for name, value in self.extra_headers.iteritems():
                headers.append((name, value))

        return WbResponse.redir_response(url, headers=headers)
示例#7
0
    def __call__(self, env, routes):
        referrer = env.get('HTTP_REFERER')

        # ensure there is a referrer
        if referrer is None:
            return None

        # get referrer path name
        ref_split = urlparse.urlsplit(referrer)

        # ensure referrer starts with one of allowed hosts
        if not any (referrer.startswith(i) for i in self.match_prefixs):
            if ref_split.netloc != env.get('HTTP_HOST'):
                return None

        path = ref_split.path

        app_path = env['SCRIPT_NAME']

        if app_path:
            # must start with current app name, if not root
            if not path.startswith(app_path):
                 return None

            path = path[len(app_path):]


        for route in routes:
            ref_request = route.parse_request(env, False, request_uri = path)
            if ref_request:
                break

        # must have matched one of the routes
        if not ref_request:
            return None

        # must have a rewriter
        if not ref_request.urlrewriter:
            return None

        rewriter = ref_request.urlrewriter

        rel_request_uri = env['REL_REQUEST_URI']

        timestamp_path = '/' + rewriter.wburl.timestamp + '/'

        # check if timestamp is already part of the path
        if rel_request_uri.startswith(timestamp_path):
            # remove timestamp but leave / to make host relative url
            # 2013/path.html -> /path.html
            rel_request_uri = rel_request_uri[len(timestamp_path) - 1:]

        final_url = urlparse.urlunsplit((ref_split.scheme, ref_split.netloc, rewriter.rewrite(rel_request_uri), '', ''))

        return WbResponse.redir_response(final_url)
示例#8
0
    def select_coll_response(self, env):
        proxy_msg = 'Basic realm="{0}"'.format(self.auth_msg)

        headers = [('Content-Type', 'text/plain'),
                   ('Proxy-Authenticate', proxy_msg)]

        status_headers = StatusAndHeaders('407 Proxy Authentication', headers)

        value = self.auth_msg

        return WbResponse(status_headers, value=[value])
示例#9
0
    def handle_exception(self, env, exc, print_trace):
        error_view = None

        if hasattr(self.wb_router, "error_view"):
            error_view = self.wb_router.error_view

        if hasattr(exc, "status"):
            status = exc.status()
        else:
            status = "500 Internal Server Error"

        if hasattr(exc, "url"):
            err_url = exc.url
        else:
            err_url = None

        err_msg = exc.message

        if print_trace:
            import traceback

            err_details = traceback.format_exc(exc)
            print err_details
        else:
            logging.info(err_msg)
            err_details = None

        if error_view:
            if err_url and isinstance(err_url, str):
                err_url = err_url.decode("utf-8", "ignore")
            if err_msg and isinstance(err_msg, str):
                err_msg = err_msg.decode("utf-8", "ignore")

            return error_view.render_response(
                exc_type=type(exc).__name__,
                err_msg=err_msg,
                err_details=err_details,
                status=status,
                env=env,
                err_url=err_url,
            )
        else:
            msg = status + " Error: "
            if err_msg:
                msg += err_msg

            msg = msg.encode("utf-8", "ignore")
            return WbResponse.text_response(msg, status=status)
示例#10
0
文件: proxy.py 项目: phillipsm/pywb
    def make_pac_response(self, env):
        server_hostport = env['SERVER_NAME'] + ':' + env['SERVER_PORT']

        buff = 'function FindProxyForURL (url, host) {\n'

        direct_cond ='    if (shExpMatch(host, "{0}")) {{ return "DIRECT"; }}\n'

        for hostpath in self.hostpaths:
            parts = urlparse.urlsplit(hostpath).netloc.split(':')
            buff += direct_cond.format(parts[0])

        buff += direct_cond.format(env['SERVER_NAME'])

        #buff += '\n    return "PROXY {0}";\n}}\n'.format(self.hostpaths[0])
        buff += '\n    return "PROXY {0}";\n}}\n'.format(server_hostport)

        return WbResponse.text_response(buff, content_type = 'application/x-ns-proxy-autoconfig')
示例#11
0
    def handle_exception(self, env, exc, print_trace):
        error_view = None

        if hasattr(self.wb_router, 'error_view'):
            error_view = self.wb_router.error_view

        if hasattr(exc, 'status'):
            status = exc.status()
        else:
            status = '400 Bad Request'

        if hasattr(exc, 'url'):
            err_url = exc.url
        else:
            err_url = None

        err_msg = exc.message

        if print_trace:
            import traceback
            err_details = traceback.format_exc(exc)
            print err_details
        else:
            logging.info(err_msg)
            err_details = None

        if error_view:
            if err_url and isinstance(err_url, str):
                err_url = err_url.decode('utf-8', 'ignore')
            if err_msg and isinstance(err_msg, str):
                err_msg = err_msg.decode('utf-8', 'ignore')

            return error_view.render_response(exc_type=type(exc).__name__,
                                              err_msg=err_msg,
                                              err_details=err_details,
                                              status=status,
                                              env=env,
                                              err_url=err_url)
        else:
            msg = status + ' Error: '
            if err_msg:
                msg += err_msg

            msg = msg.encode('utf-8', 'ignore')
            return WbResponse.text_response(msg,
                                            status=status)
示例#12
0
    def handle_exception(self, env, exc, print_trace):
        error_view = None

        if hasattr(self.wb_router, 'error_view'):
            error_view = self.wb_router.error_view

        if hasattr(exc, 'status'):
            status = exc.status()
        else:
            status = '500 Internal Server Error'

        if hasattr(exc, 'url'):
            err_url = exc.url
        else:
            err_url = None

        err_msg = exc.message

        if print_trace:
            import traceback
            err_details = traceback.format_exc(exc)
            print err_details
        else:
            logging.info(err_msg)
            err_details = None

        if error_view:
            if err_url and isinstance(err_url, str):
                err_url = err_url.decode('utf-8', 'ignore')
            if err_msg and isinstance(err_msg, str):
                err_msg = err_msg.decode('utf-8', 'ignore')

            return error_view.render_response(exc_type=type(exc).__name__,
                                              err_msg=err_msg,
                                              err_details=err_details,
                                              status=status,
                                              env=env,
                                              err_url=err_url)
        else:
            msg = status + ' Error: '
            if err_msg:
                msg += err_msg

            msg = msg.encode('utf-8', 'ignore')
            return WbResponse.text_response(msg, status=status)
示例#13
0
文件: wbapp.py 项目: phillipsm/pywb
def handle_exception(env, error_view, exc, print_trace):
    if hasattr(exc, 'status'):
        status = exc.status()
    else:
        status = '400 Bad Request'

    if print_trace:
        import traceback
        err_details = traceback.format_exc(exc)
        print err_details
    else:
        logging.info(str(exc))
        err_details = None

    if error_view:
        import traceback
        return error_view.render_response(err_msg = str(exc), err_details = err_details, status = status)
    else:
        return WbResponse.text_response(status + ' Error: ' + str(exc), status = status)
示例#14
0
    def __call__(self, wbrequest):
        full_path = self.static_path + wbrequest.wb_url_str

        try:
            if full_path.startswith(".") or full_path.startswith("file://"):
                data = open(full_path, "rb")
            else:
                data = pkgutil.get_data(self.pkg, full_path)

            if "wsgi.file_wrapper" in wbrequest.env:
                reader = wbrequest.env["wsgi.file_wrapper"](data)
            else:
                reader = iter(lambda: data.read(), "")

            content_type, _ = mimetypes.guess_type(full_path)

            return WbResponse.text_stream(data, content_type=content_type)

        except IOError:
            raise NotFoundException("Static File Not Found: " + wbrequest.wb_url_str)
示例#15
0
    def __call__(self, wbrequest):
        if wbrequest.referrer is None:
            return None

        if not any (wbrequest.referrer.startswith(i) for i in self.match_prefixs):
            return None

        try:
            ref_split = urlparse.urlsplit(wbrequest.referrer)

            path = ref_split.path
            script_name = wbrequest.env['SCRIPT_NAME']

            if not path.startswith(script_name):
                return None

            ref_path = path[len(script_name) + 1:].split('/', 1)

            # No match on any exception
            try:
                rewriter = UrlRewriter(ref_path[1], script_name + '/' + ref_path[0] + '/')
            except Exception:
                return None

            rel_request_uri = wbrequest.request_uri[1:]

            #ref_wb_url = archiveurl('/' + ref_path[1])
            #ref_wb_url.url = urlparse.urljoin(ref_wb_url.url, wbrequest.request_uri[1:])
            #ref_wb_url.url = ref_wb_url.url.replace('../', '')

            #final_url = urlparse.urlunsplit((ref_split.scheme, ref_split.netloc, ref_path[0] + str(ref_wb_url), '', ''))
            final_url = urlparse.urlunsplit((ref_split.scheme, ref_split.netloc, rewriter.rewrite(rel_request_uri), '', ''))

        except Exception as e:
            raise e

        return WbResponse.redir_response(final_url)
示例#16
0
 def render_search_page(self, wbrequest):
     if self.search_view:
         return self.search_view.render_response(wbrequest=wbrequest)
     else:
         return WbResponse.text_response("No Lookup Url Specified")
示例#17
0
 def handle_magic_page(self, env):
     coll, ts = self.get_proxy_coll_ts(env)
     ip = self._get_ip(env)
     res = json.dumps({'ip': ip, 'coll': coll, 'ts': ts})
     return WbResponse.text_response(res, content_type='application/json')
示例#18
0
    def __call__(self, env, the_router):
        referrer = env.get('HTTP_REFERER')

        routes = the_router.routes

        # ensure there is a referrer
        if referrer is None:
            return None

        # get referrer path name
        ref_split = urlparse.urlsplit(referrer)

        # require that referrer starts with current Host, if any
        curr_host = env.get('HTTP_HOST')
        if curr_host and curr_host != ref_split.netloc:
            return None

        path = ref_split.path

        app_path = env.get('SCRIPT_NAME', '')

        if app_path:
            # must start with current app name, if not root
            if not path.startswith(app_path):
                return None

            path = path[len(app_path):]

        ref_route = None
        ref_request = None

        for route in routes:
            matcher, coll = route.is_handling(path)
            if matcher:
                ref_request = the_router.parse_request(route, env,
                                                       matcher, coll, path)
                ref_route = route
                break

        # must have matched one of the routes with a urlrewriter
        if not ref_request or not ref_request.urlrewriter:
            return None

        rewriter = ref_request.urlrewriter

        rel_request_uri = env['REL_REQUEST_URI']

        timestamp_path = '/' + rewriter.wburl.timestamp + '/'

        # check if timestamp is already part of the path
        if rel_request_uri.startswith(timestamp_path):
            # remove timestamp but leave / to make host relative url
            # 2013/path.html -> /path.html
            rel_request_uri = rel_request_uri[len(timestamp_path) - 1:]

        rewritten_url = rewriter.rewrite(rel_request_uri)

        # if post, can't redirect as that would lost the post data
        # (can't use 307 because FF will show confirmation warning)
        if ref_request.method == 'POST':
            new_wb_url = WbUrl(rewritten_url[len(rewriter.prefix):])
            ref_request.wb_url.url = new_wb_url.url
            return ref_route.handler(ref_request)

        final_url = urlparse.urlunsplit((ref_split.scheme,
                                         ref_split.netloc,
                                         rewritten_url,
                                         '',
                                         ''))

        return WbResponse.redir_response(final_url, status='302 Temp Redirect')
示例#19
0
文件: proxy.py 项目: akeprojecta/pywb
    def handle_connect(self, env):
        sock = self.get_request_socket(env)
        if not sock:
            return WbResponse.text_response('HTTPS Proxy Not Supported',
                                            '405 HTTPS Proxy Not Supported')

        sock.send('HTTP/1.0 200 Connection Established\r\n')
        sock.send('Server: pywb proxy\r\n')
        sock.send('\r\n')

        hostname, port = env['REL_REQUEST_URI'].split(':')

        if not self.use_wildcard:
            _, certfile = self.ca.get_cert_for_host(hostname)
        else:
            certfile = self.ca.get_wildcard_cert(hostname)

        try:
            ssl_sock = ssl.wrap_socket(sock,
                                       server_side=True,
                                       certfile=certfile,
                                       #ciphers="ALL",
                                       suppress_ragged_eofs=False,
                                       ssl_version=ssl.PROTOCOL_SSLv23
                                       )
            env['pywb.proxy_ssl_sock'] = ssl_sock

            buffreader = BufferedReader(ssl_sock, block_size=self.BLOCK_SIZE)

            statusline = buffreader.readline().rstrip()

        except Exception as se:
            raise BadRequestException(se.message)

        statusparts = statusline.split(' ')

        if len(statusparts) < 3:
            raise BadRequestException('Invalid Proxy Request: ' + statusline)

        env['REQUEST_METHOD'] = statusparts[0]
        env['REL_REQUEST_URI'] = ('https://' +
                                  env['REL_REQUEST_URI'].replace(':443', '') +
                                  statusparts[1])

        env['SERVER_PROTOCOL'] = statusparts[2].strip()

        env['pywb.proxy_scheme'] = 'https'

        env['pywb.proxy_host'] = hostname
        env['pywb.proxy_port'] = port
        env['pywb.proxy_req_uri'] = statusparts[1]

        queryparts = env['REL_REQUEST_URI'].split('?', 1)
        env['PATH_INFO'] = queryparts[0]
        env['QUERY_STRING'] = queryparts[1] if len(queryparts) > 1 else ''

        while True:
            line = buffreader.readline()
            if line:
                line = line.rstrip()

            if not line:
                break

            parts = line.split(':', 1)
            if len(parts) < 2:
                continue

            name = parts[0].strip()
            value = parts[1].strip()

            name = name.replace('-', '_').upper()

            if name not in ('CONTENT_LENGTH', 'CONTENT_TYPE'):
                name = 'HTTP_' + name

            env[name] = value

        remain = buffreader.rem_length()
        if remain > 0:
            remainder = buffreader.read(self.BLOCK_SIZE)
            env['wsgi.input'] = BufferedReader(ssl_sock,
                                               block_size=self.BLOCK_SIZE,
                                               starting_data=remainder)
示例#20
0
 def __call__(self, wbrequest):
     return WbResponse.text_response(str(wbrequest))
示例#21
0
 def render_home_page(self, env):
     if self.home_view:
         return self.home_view.render_response(env=env, routes=self.routes)
     else:
         return WbResponse.text_response('No Home Page')
示例#22
0
    def __call__(self, env, the_router):
        referrer = env.get('HTTP_REFERER')

        routes = the_router.routes

        # ensure there is a referrer
        if referrer is None:
            return None

        # get referrer path name
        ref_split = urlparse.urlsplit(referrer)

        # require that referrer starts with current Host, if any
        curr_host = env.get('HTTP_HOST')
        if curr_host and curr_host != ref_split.netloc:
            return None

        path = ref_split.path

        app_path = env.get('SCRIPT_NAME', '')

        if app_path:
            # must start with current app name, if not root
            if not path.startswith(app_path):
                return None

            path = path[len(app_path):]

        ref_route = None
        ref_request = None

        for route in routes:
            matcher, coll = route.is_handling(path)
            if matcher:
                ref_request = the_router.parse_request(route, env,
                                                       matcher, coll, path)
                ref_route = route
                break

        # must have matched one of the routes with a urlrewriter
        if not ref_request or not ref_request.urlrewriter:
            return None

        rewriter = ref_request.urlrewriter

        rel_request_uri = env['REL_REQUEST_URI']

        timestamp_path = '/' + rewriter.wburl.timestamp + '/'

        # check if timestamp is already part of the path
        if rel_request_uri.startswith(timestamp_path):
            # remove timestamp but leave / to make host relative url
            # 2013/path.html -> /path.html
            rel_request_uri = rel_request_uri[len(timestamp_path) - 1:]

        rewritten_url = rewriter.rewrite(rel_request_uri)

        # if post, can't redirect as that would lost the post data
        # (can't use 307 because FF will show confirmation warning)
        if ref_request.method == 'POST':
            new_wb_url = WbUrl(rewritten_url[len(rewriter.prefix):])
            ref_request.wb_url.url = new_wb_url.url
            return ref_route.handler(ref_request)

        final_url = urlparse.urlunsplit((ref_split.scheme,
                                         ref_split.netloc,
                                         rewritten_url,
                                         '',
                                         ''))

        return WbResponse.redir_response(final_url, status='302 Temp Redirect')
示例#23
0
    def handle_connect(self, env):
        sock = self.get_request_socket(env)
        if not sock:
            return WbResponse.text_response('HTTPS Proxy Not Supported',
                                            '405 HTTPS Proxy Not Supported')

        sock.send('HTTP/1.0 200 Connection Established\r\n')
        sock.send('Server: pywb proxy\r\n')
        sock.send('\r\n')

        hostname, port = env['REL_REQUEST_URI'].split(':')

        if not self.use_wildcard:
            _, certfile = self.ca.get_cert_for_host(hostname)
        else:
            certfile = self.ca.get_wildcard_cert(hostname)

        try:
            ssl_sock = ssl.wrap_socket(
                sock,
                server_side=True,
                certfile=certfile,
                #ciphers="ALL",
                suppress_ragged_eofs=False,
                ssl_version=ssl.PROTOCOL_SSLv23)
            env['pywb.proxy_ssl_sock'] = ssl_sock

            buffreader = BufferedReader(ssl_sock, block_size=self.BLOCK_SIZE)

            statusline = buffreader.readline().rstrip()

        except Exception as se:
            raise BadRequestException(se.message)

        statusparts = statusline.split(' ')

        if len(statusparts) < 3:
            raise BadRequestException('Invalid Proxy Request: ' + statusline)

        env['REQUEST_METHOD'] = statusparts[0]
        env['REL_REQUEST_URI'] = ('https://' +
                                  env['REL_REQUEST_URI'].replace(':443', '') +
                                  statusparts[1])

        env['SERVER_PROTOCOL'] = statusparts[2].strip()

        env['pywb.proxy_scheme'] = 'https'

        env['pywb.proxy_host'] = hostname
        env['pywb.proxy_port'] = port
        env['pywb.proxy_req_uri'] = statusparts[1]

        queryparts = env['REL_REQUEST_URI'].split('?', 1)
        env['PATH_INFO'] = queryparts[0]
        env['QUERY_STRING'] = queryparts[1] if len(queryparts) > 1 else ''

        while True:
            line = buffreader.readline()
            if line:
                line = line.rstrip()

            if not line:
                break

            parts = line.split(':', 1)
            if len(parts) < 2:
                continue

            name = parts[0].strip()
            value = parts[1].strip()

            name = name.replace('-', '_').upper()

            if not name in ('CONTENT_LENGTH', 'CONTENT_TYPE'):
                name = 'HTTP_' + name

            env[name] = value

        remain = buffreader.rem_length()
        if remain > 0:
            remainder = buffreader.read(self.BLOCK_SIZE)
            env['wsgi.input'] = BufferedReader(ssl_sock,
                                               block_size=self.BLOCK_SIZE,
                                               starting_data=remainder)