Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
instance_id: An optional str containing the instance_id of the instance to
service this request. If unset, the request will be dispatched
according to the host header and relative_url and, if applicable, the
load-balancing for the module and version.
fake_login: A bool indicating whether login checks should be bypassed,
i.e. "login: required" should be ignored for this request.
Returns:
A request_info.ResponseTuple containing the response information for the
HTTP request.
"""
if module_name:
_module = self._get_module_with_soft_routing(module_name, version)
inst = _module.get_instance(instance_id) if instance_id else None
else:
headers_dict = wsgiref.headers.Headers(headers)
_module, inst = self._resolve_target(
headers_dict['Host'], urlparse.urlsplit(relative_url).path)
if inst:
try:
port = _module.get_instance_port(inst.instance_id)
except request_info.NotSupportedWithAutoScalingError:
port = _module.balanced_port
else:
port = _module.balanced_port
environ = _module.build_request_environ(method, relative_url, headers, body,
source_ip, port,
fake_login=fake_login)
start_response = start_response_utils.CapturingStartResponse()
response = self._handle_request(environ,
start_response,
_module,
def wrapped_start_response(status, response_headers, exc_info=None):
response_headers.append(('Server',
http_runtime_constants.SERVER_SOFTWARE))
if should_log_request:
headers = wsgiref.headers.Headers(response_headers)
status_code = int(status.split(' ', 1)[0])
content_length = int(headers.get('Content-Length', 0))
# TODO: Remove after the Files API is really gone.
if (self._filesapi_warning_message is not None
and self._request_data.was_filesapi_used(request_id)):
logging.warning(self._filesapi_warning_message)
self._insert_log_message(self._filesapi_warning_message,
2, request_id)
logservice.end_request(request_id, status_code, content_length)
if any(resource.startswith(prefix) for prefix in _QUIETER_RESOURCES):
level = logging.DEBUG
else:
level = logging.INFO
logging.log(level, '%(module_name)s: '
'"%(method)s %(resource)s %(http_version)s" '
'%(status)d %(content_length)s',
def __init__(self, env):
""" Constructor for the Request wrapper class. Parses the HTTP headers
and sets request attributes.
@param env: wsgi environ dict
@type env: dict
"""
self.env = env.copy()
self.body = env.get('wsgi.input', None)
self.headers = wsgiref.headers.Headers([])
for k,v in env.items():
if 'HTTP' in k:
key = k.replace('HTTP_', '').lower().replace('_', '-')
self.headers[key] = v
self.method = env['REQUEST_METHOD']
self.server_protocol = env['SERVER_PROTOCOL']
self.protocol = tuple(map(int, self.server_protocol[5:].split('.')))
self.headers['Content-length'] = env.get('CONTENT_LENGTH', 0)
if not self.headers['Content-length']:
del self.headers['Content-length']
else:
self.headers['Content-length'] = int(self.headers['Content-length'])
def package_response(self, outIO, environ, start_response, headers = []):
newheaders = headers
headers = [('Content-type', 'application/octet-stream')] # my understanding of spec. If unknown = binary
headersIface = Headers(headers)
for header in newheaders:
headersIface[header[0]] = '; '.join(header[1:])
retobj = outIO
if hasattr(outIO,'fileno') and 'wsgi.file_wrapper' in environ:
outIO.seek(0)
retobj = environ['wsgi.file_wrapper']( outIO, self.bufsize )
# TODO: I think this does not work well on NWSGI 2.0. Talk to Jeff about this for 3.0
elif hasattr(outIO,'read'):
outIO.seek(0)
retobj = iter( lambda: outIO.read(self.bufsize), '' )
start_response("200 OK", headers)
return retobj
def finish_header(self):
self.file = BytesIO()
self.headers = Headers(self.headerlist)
cdis = self.headers.get('Content-Disposition', '')
ctype = self.headers.get('Content-Type', '')
if not cdis:
raise MultipartError('Content-Disposition header is missing.')
self.disposition, self.options = parse_options_header(cdis)
self.name = self.options.get('name')
self.filename = self.options.get('filename')
self.content_type, options = parse_options_header(ctype)
self.charset = options.get('charset') or self.charset
self.content_length = int(self.headers.get('Content-Length', '-1'))
except httplib.HTTPException as e:
# The runtime process has written a bad HTTP response. For example,
# a Go runtime process may have crashed in app-specific code.
yield self._respond_with_error(
'the runtime process gave a bad HTTP response: %s' % e,
start_response)
return
# Ensures that we avoid merging repeat headers into a single header,
# allowing use of multiple Set-Cookie headers.
headers = []
for name in response.msg:
for value in response.msg.getheaders(name):
headers.append((name, value))
response_headers = wsgiref.headers.Headers(headers)
if self._error_handler_file and (
http_runtime_constants.ERROR_CODE_HEADER in response_headers):
try:
with open(self._error_handler_file) as f:
content = f.read()
except IOError:
content = 'Failed to load error handler'
logging.exception('failed to load error file: %s',
self._error_handler_file)
start_response('500 Internal Server Error',
[('Content-Type', 'text/html'),
('Content-Length', str(len(content)))])
yield content
return
del response_headers[http_runtime_constants.ERROR_CODE_HEADER]
if self.headers_sent:
# Re-raise original exception if headers sent
# because this violates WSGI specification.
raise
finally:
exc_info = None
elif self.header_set:
raise AssertionError("Headers already set!")
if PY3K and not isinstance(status, str):
self.status = str(status, 'ISO-8859-1')
else:
self.status = status
# Make sure headers are bytes objects
try:
self.header_set = Headers(response_headers)
except UnicodeDecodeError:
self.error = ('500 Internal Server Error',
'HTTP Headers should be bytes')
self.err_log.error('Received HTTP Headers from client that contain'
' invalid characters for Latin-1 encoding.')
return self.write_warning
def key_error(response, key):
result = 'KeyError: "%s" not found' % key
status = '404 Not Found'
response_headers = Headers([])
response_headers.add_header('Content-Type', 'text/plain'),
response_headers.add_header('Content-Length', str(len(result)))
response.start_response(status, response_headers.items())
return [result]
try:
file_like, _mimetype, _size, _file_name = self._get_path_contents(_p)
except:
return self.canned_handlers(environ, start_response, '404')
# TODO: wire up the time to commit. Until then, there will be no caching
# on web client. Ugh!
mtime = time.time()
etag, last_modified = str(mtime), email.utils.formatdate(mtime)
headers = [
('Content-type', 'text/plain')
,('Date', email.utils.formatdate(time.time()))
,('Last-Modified', last_modified)
,('ETag', etag)
]
headersIface = Headers(headers)
if_modified = environ.get('HTTP_IF_MODIFIED_SINCE')
if if_modified and (email.utils.parsedate(if_modified) >= email.utils.parsedate(last_modified)):
return self.canned_handlers(environ, start_response, 'not_modified', headers)
if_none = environ.get('HTTP_IF_NONE_MATCH')
if if_none and (if_none == '*' or etag in if_none):
return self.canned_handlers(environ, start_response, 'not_modified', headers)
if _size != None:
headersIface['Content-Length'] = str(_size)
headersIface['Content-Type'] = _mimetype
if _file_name:
# See:
# RFC5987
# http://greenbytes.de/tech/webdav/rfc5987.html
# Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)
# http://datatracker.ietf.org/doc/draft-ietf-httpbis-content-disp/?include_text=1
source_ip: The source ip address for the request.
server_name: An optional str containing the server name to service this
request. If unset, the request will be dispatched to the default
server.
version: An optional str containing the version to service this request.
If unset, the request will be dispatched to the default version.
instance_id: An optional str containing the instance_id of the instance to
service this request. If unset, the request will be dispatched to
according to the load-balancing for the server and version.
Returns:
A request_info.ResponseTuple containing the response information for the
HTTP request.
"""
try:
header_dict = wsgiref.headers.Headers(headers)
connection_host = header_dict.get('host')
connection = http.client.HTTPConnection(connection_host)
connection.putrequest(
method, relative_url,
skip_host='host' in header_dict,
skip_accept_encoding='accept-encoding' in header_dict)
for header_key, header_value in headers:
connection.putheader(header_key, header_value)
connection.endheaders()
connection.send(body)
response = connection.getresponse()
response.read()