def _do_redirect(response, exc=None): request = response.request # done with current response url = response.headers.get("location") # Handle redirection without scheme (see: RFC 1808 Section 4) if url.startswith("//"): parsed_rurl = urlparse(request.full_url) url = "%s:%s" % (parsed_rurl.scheme, url) # Facilitate non-RFC2616-compliant 'location' headers # (e.g. '/path/to/resource' instead of # 'http://domain.tld/path/to/resource') if not urlparse(url).netloc: url = urljoin( request.full_url, # Compliant with RFC3986, we percent # encode the url. requote_uri(url), ) history = request.history if history and len(history) >= request.max_redirects: response.request_again = TooManyRedirects(response) else: params = request.inp_params.copy() params["history"] = copy(history) if history else [] params["history"].append(response) if response.status_code == 303: method = "GET" params.pop("data", None) params.pop("files", None) else: method = request.method response.request_again = request_again(method, url, params)
def _do_redirect(response): request = response.request client = request.client # done with current response url = response.headers.get('location') # Handle redirection without scheme (see: RFC 1808 Section 4) if url.startswith('//'): parsed_rurl = urlparse(request.full_url) url = '%s:%s' % (parsed_rurl.scheme, url) # Facilitate non-RFC2616-compliant 'location' headers # (e.g. '/path/to/resource' instead of # 'http://domain.tld/path/to/resource') if not urlparse(url).netloc: url = urljoin(request.full_url, # Compliant with RFC3986, we percent # encode the url. requote_uri(url)) history = response._history if history and len(history) >= request.max_redirects: raise TooManyRedirects(response) # if response.status_code == 303: params = request.inp_params.copy() method = 'GET' params.pop('data', None) params.pop('files', None) return client.again(response, method, url, params, True) else: return client.again(response, url=url, history=True)
def _do_redirect(response, exc=None): request = response.request # done with current response url = response.headers.get('location') # Handle redirection without scheme (see: RFC 1808 Section 4) if url.startswith('//'): parsed_rurl = urlparse(request.full_url) url = '%s:%s' % (parsed_rurl.scheme, url) # Facilitate non-RFC2616-compliant 'location' headers # (e.g. '/path/to/resource' instead of # 'http://domain.tld/path/to/resource') if not urlparse(url).netloc: url = urljoin( request.full_url, # Compliant with RFC3986, we percent # encode the url. requote_uri(url)) history = request.history if history and len(history) >= request.max_redirects: response.request_again = TooManyRedirects(response) else: params = request.inp_params.copy() params['history'] = copy(history) if history else [] params['history'].append(response) if response.status_code == 303: method = 'GET' params.pop('data', None) params.pop('files', None) else: method = request.method response.request_again = request_again(method, url, params)
def same_origin(url1, url2): """ Checks if two URLs are 'same-origin' """ p1, p2 = urlparse(url1), urlparse(url2) try: return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port) except ValueError: return False
def test_wsgi_environ(path='/', method=None, headers=None, extra=None, secure=False, loop=None): '''An function to create a WSGI environment dictionary for testing. :param url: the resource in the ``PATH_INFO``. :param method: the ``REQUEST_METHOD``. :param headers: optional request headers :params secure: a secure connection? :param extra: additional dictionary of parameters to add. :return: a valid WSGI environ dictionary. ''' parser = http_parser(kind=0) method = (method or 'GET').upper() path = iri_to_uri(path) data = '%s %s HTTP/1.1\r\n\r\n' % (method, path) data = data.encode('latin1') parser.execute(data, len(data)) request_headers = Headers(headers, kind='client') # Add Host if not available parsed = urlparse(path) if parsed.netloc and 'host' not in request_headers: request_headers['host'] = parsed.netloc # headers = Headers() stream = StreamReader(request_headers, parser) extra = extra or {} extra['pulsar.connection'] = FakeConnection(loop=loop) return wsgi_environ(stream, ('127.0.0.1', 8060), '777.777.777.777:8080', headers, https=secure, extra=extra)
def test_wsgi_environ(path=None, method=None, headers=None, extra=None, secure=False, loop=None, body=None): '''An function to create a WSGI environment dictionary for testing. :param url: the resource in the ``PATH_INFO``. :param method: the ``REQUEST_METHOD``. :param headers: optional request headers :params secure: a secure connection? :param extra: additional dictionary of parameters to add. :return: a valid WSGI environ dictionary. ''' parser = http_parser(kind=0) method = (method or 'GET').upper() path = iri_to_uri(path or '/') request_headers = Headers(headers, kind='client') # Add Host if not available parsed = urlparse(path) if 'host' not in request_headers: if not parsed.netloc: path = '%s%s' % ('https://:443' if secure else 'http://:80', path) else: request_headers['host'] = parsed.netloc # data = '%s %s HTTP/1.1\r\n\r\n' % (method, path) data = data.encode('latin1') parser.execute(data, len(data)) # headers = Headers() stream = StreamReader(request_headers, parser) stream.buffer = body or b'' stream.on_message_complete.set_result(None) extra = extra or {} return wsgi_environ(stream, ('127.0.0.1', 8060), '777.777.777.777:8080', headers, https=secure, extra=extra)
def test_wsgi_environ(path=None, method=None, headers=None, extra=None, secure=False, loop=None, body=None): """An function to create a WSGI environment dictionary for testing. :param url: the resource in the ``PATH_INFO``. :param method: the ``REQUEST_METHOD``. :param headers: optional request headers :params secure: a secure connection? :param extra: additional dictionary of parameters to add. :return: a valid WSGI environ dictionary. """ parser = http_parser(kind=0) method = (method or "GET").upper() path = iri_to_uri(path or "/") request_headers = Headers(headers, kind="client") # Add Host if not available parsed = urlparse(path) if "host" not in request_headers: if not parsed.netloc: path = "%s%s" % ("https://:443" if secure else "http://:80", path) else: request_headers["host"] = parsed.netloc # data = "%s %s HTTP/1.1\r\n\r\n" % (method, path) data = data.encode("latin1") parser.execute(data, len(data)) # stream = io.BytesIO(body or b"") return wsgi_environ( stream, parser, request_headers, ("127.0.0.1", 8060), "255.0.1.2:8080", Headers(), https=secure, extra=extra )
def __test_tunnel_request_object(self): http = self.client() response = yield http.get(self.httpbin()).on_finished request = response.request tunnel = request._tunnel self.assertEqual(tunnel.request, request) self.assertNotEqual(tunnel.parser, request.parser) self.assertEqual(tunnel.full_url, self.proxy_uri) self.assertEqual(tunnel.headers['host'], urlparse(self.uri).netloc)
def set_proxy(self, request): if request.scheme in self.proxy_info: hostonly = request.host no_proxy = [n for n in self.proxy_info.get('no', '').split(',') if n] if not any(map(hostonly.endswith, no_proxy)): url = self.proxy_info[request.scheme] p = urlparse(url) if not p.scheme: raise ValueError('Could not understand proxy %s' % url) request.set_proxy(p.scheme, p.netloc)
def router_href(app, route): url = '/'.join(_angular_route(route)) if url: url = '/%s' % url if route.is_leaf else '/%s/' % url else: url = '/' site_url = app.config['SITE_URL'] if site_url: p = urlparse(site_url + url) return p.path else: return url
def on_html_document(self, app, request, doc): favicon = app.config['FAVICON'] if favicon: parsed = urlparse(favicon) if not parsed.scheme and not parsed.netloc: site_url = app.config['SITE_URL'] media = app.config['MEDIA_URL'] if not favicon.startswith(media): favicon = remove_double_slash('%s%s' % (media, favicon)) if site_url: favicon = '%s%s' % (site_url, favicon) doc.head.links.append(favicon, rel="icon", type='image/x-icon')
def post_request(self, call, response): if response.status_code == 302 and call.name == 'authorization': url = urlparse(response.headers['location']) query = parse_qs(url.query) cont = query.get('cont') if cont: return self.request(call, cont[0], chain_to_response=response) else: state = query.get('state') #if state != response.request.data['state']: # raise PermissionDenied('state mismatch') code = url.query['code'][0] return self.token(code=code, chain_to_response=response) return response
def __init__(self, path=None, nargs=0, allowed_params=None, required_params=None, callback=None, method=None, append=None, doc=None, **http_params): self.path = path or '' self.scheme = urlparse(path).scheme self.nargs = nargs self.append = append self.required_params = required_params or [] self.doc = doc self.callback = callback self.http_params = http_params self.method = (method or 'get').upper() if self.required_params and not allowed_params: allowed_params = dict(((p, None) for p in self.required_params)) self.allowed_params = allowed_params or {}
def encode(self, method, uri): '''Called by the client to encode Authentication header.''' if not self.username or not self.password: return o = self.options qop = o.get('qop') realm = o.get('realm') nonce = o['nonce'] entdig = None p_parsed = urlparse(uri) path = p_parsed.path if p_parsed.query: path += '?' + p_parsed.query KD = lambda s, d: self.hex("%s:%s" % (s, d)) ha1 = self.ha1(realm, self.password) ha2 = self.ha2(qop, method, path) if qop == 'auth': if nonce == self.last_nonce: self.nonce_count += 1 else: self.nonce_count = 1 ncvalue = '%08x' % self.nonce_count s = str(self.nonce_count).encode('utf-8') s += nonce.encode('utf-8') s += time.ctime().encode('utf-8') s += os.urandom(8) cnonce = sha1(s).hexdigest()[:16] noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, ha2) respdig = KD(ha1, noncebit) elif qop is None: respdig = KD(ha1, "%s:%s" % (nonce, ha2)) else: # XXX handle auth-int. return base = 'username="******", realm="%s", nonce="%s", uri="%s", ' \ 'response="%s"' % (self.username, realm, nonce, path, respdig) opaque = o.get('opaque') if opaque: base += ', opaque="%s"' % opaque if entdig: base += ', digest="%s"' % entdig base += ', algorithm="%s"' % self.algorithm if qop: base += ', qop=%s, nc=%s, cnonce="%s"' % (qop, ncvalue, cnonce) return 'Digest %s' % (base)
def wsgi_environ(stream, address, client_address, headers, server_software=None, https=False, extra=None): protocol = stream.protocol() parser = stream.parser request_headers = stream.headers raw_uri = parser.get_url() request_uri = urlparse(raw_uri) # # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.2 # If Request-URI is an absoluteURI, the host is part of the Request-URI. # Any Host header field value in the request MUST be ignored if request_uri.scheme: url_scheme = request_uri.scheme host = request_uri.netloc else: url_scheme = 'https' if https else 'http' host = None # environ = { "wsgi.input": stream, "wsgi.errors": sys.stderr, "wsgi.version": (1, 0), "wsgi.run_once": False, "wsgi.multithread": False, "wsgi.multiprocess": False, "SERVER_SOFTWARE": server_software or pulsar.SERVER_SOFTWARE, "REQUEST_METHOD": native_str(parser.get_method()), "QUERY_STRING": parser.get_query_string(), "RAW_URI": raw_uri, "SERVER_PROTOCOL": protocol, "CONTENT_TYPE": '' } forward = client_address script_name = os.environ.get("SCRIPT_NAME", "") for header, value in request_headers: header = header.lower() if header in HOP_HEADERS: headers[header] = value if header == 'x-forwarded-for': forward = value elif header == "x-forwarded-protocol" and value == "ssl": url_scheme = "https" elif header == "x-forwarded-ssl" and value == "on": url_scheme = "https" elif header == "host" and not host: host = value elif header == "script_name": script_name = value elif header == "content-type": environ['CONTENT_TYPE'] = value continue elif header == "content-length": environ['CONTENT_LENGTH'] = value continue key = 'HTTP_' + header.upper().replace('-', '_') environ[key] = value environ['wsgi.url_scheme'] = url_scheme if url_scheme == 'https': environ['HTTPS'] = 'on' if is_string(forward): # we only took the last one # http://en.wikipedia.org/wiki/X-Forwarded-For if forward.find(",") >= 0: forward = forward.rsplit(",", 1)[1].strip() remote = forward.split(":") if len(remote) < 2: remote.append('80') else: remote = forward environ['REMOTE_ADDR'] = remote[0] environ['REMOTE_PORT'] = str(remote[1]) if not host and protocol == 'HTTP/1.0': host = format_address(address) if host: host = host_and_port_default(url_scheme, host) environ['SERVER_NAME'] = socket.getfqdn(host[0]) environ['SERVER_PORT'] = host[1] path_info = request_uri.path if path_info is not None: if script_name: path_info = path_info.split(script_name, 1)[1] environ['PATH_INFO'] = unquote(path_info) environ['SCRIPT_NAME'] = script_name if extra: environ.update(extra) return environ
def __test_connect(self): http = self.client() p = urlparse(self.uri) response = yield http.connect(p.netloc) self.assertEqual(response.status_code, 405) self.assertEqual(response._request.method, 'CONNECT')
def _set_full_url(self, url): self._scheme, self._netloc, self.path, self.params,\ self.query, self.fragment = urlparse(url) if not self._netloc and self.method == 'CONNECT': self._scheme, self._netloc, self.path, self.params,\ self.query, self.fragment = urlparse('http://%s' % url)
def wsgi_environ( stream, parser, request_headers, address, client_address, headers, server_software=None, https=False, extra=None ): """Build the WSGI Environment dictionary :param stream: a wsgi stream object :param parser: pulsar HTTP parser :param request_headers: headers of request :param address: server address :param client_address: client address :param headers: container for response headers """ protocol = http_protocol(parser) raw_uri = parser.get_url() request_uri = urlparse(raw_uri) # # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.2 # If Request-URI is an absoluteURI, the host is part of the Request-URI. # Any Host header field value in the request MUST be ignored if request_uri.scheme: url_scheme = request_uri.scheme host = request_uri.netloc else: url_scheme = "https" if https else "http" host = None # environ = { "wsgi.input": stream, "wsgi.errors": sys.stderr, "wsgi.version": (1, 0), "wsgi.run_once": False, "wsgi.multithread": False, "wsgi.multiprocess": False, "SERVER_SOFTWARE": server_software or pulsar.SERVER_SOFTWARE, "REQUEST_METHOD": native_str(parser.get_method()), "QUERY_STRING": parser.get_query_string(), "RAW_URI": raw_uri, "SERVER_PROTOCOL": protocol, "CONTENT_TYPE": "", } forward = client_address script_name = os.environ.get("SCRIPT_NAME", "") for header, value in request_headers: header = header.lower() if header in HOP_HEADERS: headers[header] = value if header == "x-forwarded-for": forward = value elif header == "x-forwarded-protocol" and value == "ssl": url_scheme = "https" elif header == "x-forwarded-ssl" and value == "on": url_scheme = "https" elif header == "host" and not host: host = value elif header == "script_name": script_name = value elif header == "content-type": environ["CONTENT_TYPE"] = value continue elif header == "content-length": environ["CONTENT_LENGTH"] = value continue key = "HTTP_" + header.upper().replace("-", "_") environ[key] = value environ["wsgi.url_scheme"] = url_scheme if url_scheme == "https": environ["HTTPS"] = "on" if isinstance(forward, str): # we only took the last one # http://en.wikipedia.org/wiki/X-Forwarded-For if forward.find(",") >= 0: forward = forward.rsplit(",", 1)[1].strip() remote = forward.split(":") if len(remote) < 2: remote.append("80") else: remote = forward environ["REMOTE_ADDR"] = remote[0] environ["REMOTE_PORT"] = str(remote[1]) if not host and protocol == "HTTP/1.0": host = format_address(address) if host: h = host_and_port_default(url_scheme, host) environ["SERVER_NAME"] = socket.getfqdn(h[0]) if h[0] else "0.0.0.0" environ["SERVER_PORT"] = h[1] path_info = request_uri.path if path_info is not None: if script_name: path_info = path_info.split(script_name, 1)[1] environ["PATH_INFO"] = unquote(path_info) environ["SCRIPT_NAME"] = script_name if extra: environ.update(extra) return environ
def wsgi_environ(stream, address, client_address, headers, server_software=None, https=False, extra=None): protocol = stream.protocol() parser = stream.parser request_headers = stream.headers raw_uri = parser.get_url() request_uri = urlparse(raw_uri) # # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.2 # If Request-URI is an absoluteURI, the host is part of the Request-URI. # Any Host header field value in the request MUST be ignored if request_uri.scheme: url_scheme = request_uri.scheme host = request_uri.netloc else: url_scheme = 'https' if https else 'http' host = None # environ = {"wsgi.input": stream, "wsgi.errors": sys.stderr, "wsgi.version": (1, 0), "wsgi.run_once": False, "wsgi.multithread": False, "wsgi.multiprocess": False, "SERVER_SOFTWARE": server_software or pulsar.SERVER_SOFTWARE, "REQUEST_METHOD": native_str(parser.get_method()), "QUERY_STRING": parser.get_query_string(), "RAW_URI": raw_uri, "SERVER_PROTOCOL": protocol, "CONTENT_TYPE": ''} forward = client_address script_name = os.environ.get("SCRIPT_NAME", "") for header, value in request_headers: header = header.lower() if header in HOP_HEADERS: headers[header] = value if header == 'x-forwarded-for': forward = value elif header == "x-forwarded-protocol" and value == "ssl": url_scheme = "https" elif header == "x-forwarded-ssl" and value == "on": url_scheme = "https" elif header == "host" and not host: host = value elif header == "script_name": script_name = value elif header == "content-type": environ['CONTENT_TYPE'] = value continue elif header == "content-length": environ['CONTENT_LENGTH'] = value continue key = 'HTTP_' + header.upper().replace('-', '_') environ[key] = value environ['wsgi.url_scheme'] = url_scheme if url_scheme == 'https': environ['HTTPS'] = 'on' if is_string(forward): # we only took the last one # http://en.wikipedia.org/wiki/X-Forwarded-For if forward.find(",") >= 0: forward = forward.rsplit(",", 1)[1].strip() remote = forward.split(":") if len(remote) < 2: remote.append('80') else: remote = forward environ['REMOTE_ADDR'] = remote[0] environ['REMOTE_PORT'] = str(remote[1]) if not host and protocol == 'HTTP/1.0': host = format_address(address) if host: host = host_and_port_default(url_scheme, host) environ['SERVER_NAME'] = socket.getfqdn(host[0]) environ['SERVER_PORT'] = host[1] path_info = parser.get_path() if path_info is not None: if script_name: path_info = path_info.split(script_name, 1)[1] environ['PATH_INFO'] = unquote(path_info) environ['SCRIPT_NAME'] = script_name if extra: environ.update(extra) return environ
def __test_connect(self): http = self.client() p = urlparse(self.uri) response = yield from http.connect(p.netloc) self.assertEqual(response.status_code, 405) self.assertEqual(response._request.method, 'CONNECT')
def test_url_handling(self): target = '/\N{SNOWMAN}' request = self.request(path=target) path = urlparse(request.path).path self.assertEqual(path, target)
def full_url(self, url): self._scheme, self._netloc, self.path, self.params,\ self.query, self.fragment = urlparse(url) if not self._netloc and self.method == 'CONNECT': self._scheme, self._netloc, self.path, self.params,\ self.query, self.fragment = urlparse('http://%s' % url)