def _fixup_configured(self, environ): path_info = environ['PATH_INFO'] script_name = environ['SCRIPT_NAME'] if self.prefix is not None: environ['SCRIPT_NAME'] = self.prefix elif self.pop_prefix is not None: if self.pop_prefix == path_info: path_info = '' script_name = script_name + self.pop_prefix elif path_info.startswith(self.pop_prefix + '/'): path_info = path_info[len(self.pop_prefix):] script_name = script_name + self.pop_prefix else: exc = httpexceptions.HTTPBadRequest( "It was expected that all requests would start with " "the path %r, but I got a request with %r" % (self.pop_prefix, path_info)) raise exc if self.scheme is not None: environ['wsgi.url_scheme'] = self.scheme if self.host is not None: domain, port = self.host.split(':', 1) environ['HTTP_HOST'] = self.host environ['SERVER_NAME'] = domain environ['SERVER_PORT'] = port if self.port is not None: environ['SERVER_PORT'] = self.port if self.domain is None: host = environ['HTTP_HOST'].split(':', 1) + ':' + self.port environ['HTTP_HOST'] = host if self.domain is not None: host = self.domain + ':' + environ['SERVER_PORT'] environ['HTTP_HOST'] = host environ['SERVER_NAME'] = self.domain
def __call__(self, environ, start_response): if (self.allowed_request_methods and environ['REQUEST_METHOD'].lower() not in self.allowed_request_methods): return httpexceptions.HTTPBadRequest("Disallowed")(environ, start_response) if self.scheme == 'http': ConnClass = httplib.HTTPConnection elif self.scheme == 'https': ConnClass = httplib.HTTPSConnection else: raise ValueError("Unknown scheme for %r: %r" % (self.address, self.scheme)) conn = ConnClass(self.host) headers = {} for key, value in environ.items(): if key.startswith('HTTP_'): key = key[5:].lower().replace('_', '-') if key == 'host' or key in self.suppress_http_headers: continue headers[key] = value headers['host'] = self.host if 'REMOTE_ADDR' in environ: headers['x-forwarded-for'] = environ['REMOTE_ADDR'] if environ.get('CONTENT_TYPE'): headers['content-type'] = environ['CONTENT_TYPE'] if environ.get('CONTENT_LENGTH'): headers['content-length'] = environ['CONTENT_LENGTH'] length = int(environ['CONTENT_LENGTH']) body = environ['wsgi.input'].read(length) else: body = '' path_info = urllib.quote(environ['PATH_INFO']) if self.path: request_path = path_info if request_path[0] == '/': request_path = request_path[1:] path = urlparse.urljoin(self.path, request_path) else: path = path_info if environ.get('QUERY_STRING'): path += '?' + environ['QUERY_STRING'] conn.request(environ['REQUEST_METHOD'], path, body, headers) res = conn.getresponse() headers_out = parse_headers(res.msg) status = '%s %s' % (res.status, res.reason) start_response(status, headers_out) # @@: Default? length = res.getheader('content-length') if length is not None: body = res.read(int(length)) else: body = res.read() conn.close() return [body]
def _fixup_environ(self, environ): # @@: Obviously better errors here: if 'HTTP_X_WSGIPROXY_VERSION' in environ: version = environ.pop('HTTP_X_WSGIPROXY_VERSION') assert version == protocol_version secure = False if self.secret_file is not None: secret = get_secret(self.secret_file) # @@: Should catch error: check_request(environ, secret) secure = True if self.trust_ips: ip = environ.get('REMOTE_ADDR') if ip in trust_ips: # @@: Should allow ranges and whatnot: secure = True if 'HTTP_X_FORWARDED_SERVER' in environ: environ['HTTP_HOST'] = environ.pop('HTTP_X_FORWARDED_SERVER') if 'HTTP_X_FORWARDED_SCHEME' in environ: environ['wsgi.url_scheme'] = environ.pop('HTTP_X_FORWARDED_SCHEME') if 'HTTP_X_FORWARDED_FOR' in environ: environ['REMOTE_ADDR'] = environ.pop('HTTP_X_FORWARDED_FOR') script_name = environ.get('SCRIPT_NAME', '') path_info = environ.get('PATH_INFO', '') if 'HTTP_X_TRAVERSAL_PATH' in environ: traversal_path = environ['HTTP_X_TRAVERSAL_PATH'].rstrip('/') if traversal_path == path_info: path_info = '' elif not path_info.startswith(traversal_path + '/'): exc = httpexceptions.HTTPBadRequest( "The header X-Traversal-Path gives the value %r but " "the path is %r (it should start with " "X-Traversal-Path)" % (traversal_path, path_info)) return exc(environ, start_response) else: path_info = path_info[len(traversal_path):] if 'HTTP_X_SCRIPT_NAME' in environ: add_script_name = environ.pop('HTTP_X_SCRIPT_NAME').rstrip('/') if not add_script_name.startswith('/'): exc = httpexceptions.HTTPBadRequest( "The header X-Script-Name gives %r which does not " "start with /" % add_script_name) return exc(environ, start_response) script_name = add_script_name + script_name environ['SCRIPT_NAME'] = script_name environ['PATH_INFO'] = path_info for header, key in [('HTTP_HOST', 'HTTP_HOST'), ('SCRIPT_NAME', 'SCRIPT_NAME'), ('PATH_INFO', 'PATH_INFO'), ('QUERY_STRING', 'QUERY_STRING'), ('WSGI_URL_SCHEME', 'wsgi.url_scheme')]: header = 'HTTP_X_WSGIPROXY_%s' % header if header in environ: environ[key] = environ.pop(header) for prefix, decoder, is_secure in [ ('STR', self.str_decode, True), ('UNICODE', self.unicode_decode, True), ('JSON', self.json_decode, True), ('PICKLE', self.pickle_decode, False) ]: expect = 'HTTP_X_WSGIPROXY_%s' % prefix for key in environ: if key.startswith(expect): if not is_secure and not secure: # Better error again! assert 0 key_name, value = environ[key].split(None, 1) key_name = urllib.unquote(key_name) value = decoder(value) environ[key_name] = value
def __call__(self, environ, start_response): if (self.allowed_request_methods and environ['REQUEST_METHOD'].lower() not in self.allowed_request_methods): return httpexceptions.HTTPBadRequest("Disallowed")(environ, start_response) #if self.scheme == 'http': # ConnClass = httplib.HTTPConnection #elif self.scheme == 'https': # ConnClass = httplib.HTTPSConnection #else: # raise ValueError( # "Unknown scheme for %r: %r" % (self.address, self.scheme)) #conn = ConnClass(self.host) headers = {} for key, value in environ.items(): if key.startswith('HTTP_'): key = key[5:].lower().replace('_', '-') if key == 'host' or key in self.suppress_http_headers: continue headers[key] = value headers['host'] = self.host if 'REMOTE_ADDR' in environ: headers['x-forwarded-for'] = environ['REMOTE_ADDR'] if environ.get('CONTENT_TYPE'): headers['content-type'] = environ['CONTENT_TYPE'] if environ.get('CONTENT_LENGTH'): if environ['CONTENT_LENGTH'] == '-1': # This is a special case, where the content length is basically undetermined body = environ['wsgi.input'].read(-1) headers['content-length'] = str(len(body)) else: headers['content-length'] = environ['CONTENT_LENGTH'] length = int(environ['CONTENT_LENGTH']) body = environ['wsgi.input'].read(length) else: body = '' # x-forward-scheme was breaking in the proxy when https://bisque-site/ was fetch engine_service/_service over http # The address was always coming back as https://bisque-engine/_services # This code removes any mention of the forwards which seems to be the correct thing/ for k in headers.keys(): if k.startswith('x-forwarded'): del headers[k] #log.debug('environ: %s', str(environ)) path_info = urllib.quote(environ['PATH_INFO']) if self.path: request_path = path_info if request_path and request_path[0] == '/': request_path = request_path[1:] path = urlparse.urljoin(self.path, request_path) else: path = path_info if environ.get('QUERY_STRING'): path += '?' + environ['QUERY_STRING'] url = "%s://%s%s" % (self.scheme, self.host, path) log.debug('method: %s, url: %s', environ['REQUEST_METHOD'], url) log.debug('headers: %s', headers) #log.debug('environ: %s', environ) #log.debug('body: %s', body) try: res = requests.request(method=environ['REQUEST_METHOD'], url=url, data=body, headers=headers, stream=False, verify=False, allow_redirects=True) log.debug("Proxy response: %s with: %s", str(res), res.headers) #log.debug ("Proxy response content: %s", res.content) #log.debug ("Proxy response text: %s", res.text) #log.debug ("Proxy response history: %s", res.history) #log.debug ("Proxy response request headers: %s", res.request.headers) status = '%s %s' % (res.status_code, res.reason) headers_out = dict( (k, res.headers[k]) for k in res.headers if k.lower() not in self.suppress_http_headers_out) start_response(status, list(headers_out.items())) return [res.content] except Exception: log.exception('Failed') start_response("502", []) return ['Bad Gateway']
def __call__(self, environ, start_response): if (self.allowed_request_methods and environ['REQUEST_METHOD' ].lower() not in self.allowed_request_methods): disallowedRequest = httpexceptions.HTTPBadRequest("Disallowed") return disallowedRequest(environ, start_response) if not self.__environSessionKeyName: sslCtx = None else: session = environ.get(self.__environSessionKeyName) if session is None: msg = "No session in environ" http500Error = httpexceptions.HTTPInternalServerError(msg) return http500Error(environ, start_response) sslCtx = session[self.__ctxSessionKeyName] if self.scheme == 'http': conn = httplib.HTTPConnection(self.host) elif self.scheme == 'https': conn = HTTPSConnection(self.host, ssl_context=sslCtx) else: raise ValueError( "Unknown scheme for %r: %r" % (self.address, self.scheme)) headers = {} for key, value in environ.items(): if key.startswith('HTTP_'): key = key[5:].lower().replace('_', '-') if key == 'host' or key in self.suppress_http_headers: continue headers[key] = value headers['host'] = self.host if 'REMOTE_ADDR' in environ: headers['x-forwarded-for'] = environ['REMOTE_ADDR'] if environ.get('CONTENT_TYPE'): headers['content-type'] = environ['CONTENT_TYPE'] if environ.get('CONTENT_LENGTH'): if environ['CONTENT_LENGTH'] != '-1': headers['content-length'] = environ['CONTENT_LENGTH'] path_info = urllib.quote(environ['PATH_INFO']) if self.path: request_path = path_info if request_path and request_path[0] == '/': request_path = request_path[1:] path = urljoin(self.path, request_path) else: path = path_info if environ.get('QUERY_STRING'): path += '?' + environ['QUERY_STRING'] conn.request(environ['REQUEST_METHOD'], path, environ['wsgi.input'], headers) res = conn.getresponse() conn.close() # Handle a security redirect - if not handled it returns None and the # original response is returned redirectRes = self._handleSecuredRedirect(res, sslCtx) if redirectRes is None: _res = res else: _res = redirectRes headers_out = parse_headers(_res.msg) status = '%s %s' % (_res.status, _res.reason) start_response(status, headers_out) length = int(_res.getheader('content-length', '-1')) response = FileObjResponseIterator(_res.fp, file_size=length) return response