def encode_environ(self, environ): # I don't want to totally overwrite things in the current # environment, so we copy: for name in ['QUERY_STRING', 'SCRIPT_NAME', 'PATH_INFO']: if name not in environ: environ[name] = '' orig_environ = environ environ = environ.copy() environ['wsgiproxy.orig_environ'] = orig_environ if self.secret_file is not None: secret = get_secret(self.secret_file) sign_request(environ) for key in environ.keys(): if key.startswith('HTTP_X_WSGIPROXY'): # Conflicting header... del environ[key] for key, dest in self.header_map.items(): environ['HTTP_%s' % dest] = environ[key] for prefix, keys, encoder in [ ('STR', self.string_keys, self.str_encode), ('UNICODE', self.unicode_keys, self.unicode_encode), ('JSON', self.json_keys, self.json_encode), ('PICKLE', self.pickle_keys, self.pickle_encode) ]: for count, key in enumerate(keys): if key not in environ: continue key = 'HTTP_X_WSGIPROXY_%s_%s' % (prefix, count) environ[key] = '%s %s' % (urllib.quote(key), encoder(environ[key])) environ['HTTP_X_WSGIPROXY_VERSION'] = protocol_version return environ
def encode_environ(self, environ): # I don't want to totally overwrite things in the current # environment, so we copy: for name in ['QUERY_STRING', 'SCRIPT_NAME', 'PATH_INFO']: if name not in environ: environ[name] = '' orig_environ = environ environ = environ.copy() environ['wsgiproxy.orig_environ'] = orig_environ if self.secret_file is not None: secret = get_secret(self.secret_file) sign_request(environ) for key in environ.keys(): if key.startswith('HTTP_X_WSGIPROXY'): # Conflicting header... del environ[key] for key, dest in self.header_map.items(): environ['HTTP_%s' % dest] = environ[key] for prefix, keys, encoder in [ ('STR', self.string_keys, self.str_encode), ('UNICODE', self.unicode_keys, self.unicode_encode), ('JSON', self.json_keys, self.json_encode), ('PICKLE', self.pickle_keys, self.pickle_encode)]: for count, key in enumerate(keys): if key not in environ: continue new_key = 'HTTP_X_WSGIPROXY_%s_%s' % (prefix, count) environ[new_key] = '%s %s' % ( urllib.quote(key), encoder(environ[key])) environ['HTTP_X_WSGIPROXY_VERSION'] = protocol_version return environ
def _fixup_environ(self, environ, start_response): # @@: 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 self.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 _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