Windows: Use 32-bit distribution of python

This commit is contained in:
James Taylor
2018-09-14 19:32:27 -07:00
parent 6ca20ff701
commit 4212164e91
166 changed files with 175548 additions and 44620 deletions

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2005-2009, eventlet contributors
# Copyright (c) 2009-2015, gevent contributors
# Copyright (c) 2009-2018, gevent contributors
"""
A pure-Python, gevent-friendly WSGI server.
@@ -9,6 +9,8 @@ created for each request. The server can be customized to use
different subclasses of :class:`WSGIHandler`.
"""
from __future__ import absolute_import
# FIXME: Can we refactor to make smallor?
# pylint:disable=too-many-lines
@@ -517,20 +519,20 @@ class WSGIHandler(object):
if len(words) == 3:
self.command, self.path, self.request_version = words
if not self._check_http_version():
raise _InvalidClientRequest('Invalid http version: %r', raw_requestline)
raise _InvalidClientRequest('Invalid http version: %r' % (raw_requestline,))
elif len(words) == 2:
self.command, self.path = words
if self.command != "GET":
raise _InvalidClientRequest('Expected GET method: %r', raw_requestline)
raise _InvalidClientRequest('Expected GET method: %r' % (raw_requestline,))
self.request_version = "HTTP/0.9"
# QQQ I'm pretty sure we can drop support for HTTP/0.9
else:
raise _InvalidClientRequest('Invalid HTTP method: %r', raw_requestline)
raise _InvalidClientRequest('Invalid HTTP method: %r' % (raw_requestline,))
self.headers = self.MessageClass(self.rfile, 0)
if self.headers.status:
raise _InvalidClientRequest('Invalid headers status: %r', self.headers.status)
raise _InvalidClientRequest('Invalid headers status: %r' % (self.headers.status,))
if self.headers.get("transfer-encoding", "").lower() == "chunked":
try:
@@ -542,7 +544,7 @@ class WSGIHandler(object):
if content_length is not None:
content_length = int(content_length)
if content_length < 0:
raise _InvalidClientRequest('Invalid Content-Length: %r', content_length)
raise _InvalidClientRequest('Invalid Content-Length: %r' % (content_length,))
if content_length and self.command in ('HEAD', ):
raise _InvalidClientRequest('Unexpected Content-Length')
@@ -706,7 +708,9 @@ class WSGIHandler(object):
raise
self.response_length += len(data)
def _write(self, data):
def _write(self, data,
_PY34_EXACTLY=(sys.version_info[:2] == (3, 4)),
_bytearray=bytearray):
if not data:
# The application/middleware are allowed to yield
# empty bytestrings.
@@ -714,14 +718,25 @@ class WSGIHandler(object):
if self.response_use_chunked:
## Write the chunked encoding
header = ("%x\r\n" % len(data)).encode('ascii')
# socket.sendall will slice these small strings, as [0:],
# but that's special cased to return the original string.
# They're small enough we probably expect them to go down to the network
# buffers in one go anyway.
self._sendall(header)
self._sendall(data)
self._sendall(b'\r\n') # trailer
# header
if _PY34_EXACTLY:
# This is the only version we support that doesn't
# allow % to be used with bytes. Passing a bytestring
# directly in to bytearray() is faster than passing a
# (unicode) str with encoding, which naturally is faster still
# than encoding first. Interestingly, byte formatting on Python 3
# is faster than str formatting.
header_str = '%x\r\n' % len(data)
towrite = _bytearray(header_str, 'ascii')
else:
header_str = b'%x\r\n' % len(data)
towrite = _bytearray(header_str)
# data
towrite += data
# trailer
towrite += b'\r\n'
self._sendall(towrite)
else:
self._sendall(data)
@@ -741,21 +756,20 @@ class WSGIHandler(object):
self._write_with_headers(data)
def _write_with_headers(self, data):
towrite = bytearray()
self.headers_sent = True
self.finalize_headers()
# self.response_headers and self.status are already in latin-1, as encoded by self.start_response
towrite.extend(b'HTTP/1.1 ')
towrite.extend(self.status)
towrite.extend(b'\r\n')
towrite = bytearray(b'HTTP/1.1 ')
towrite += self.status
towrite += b'\r\n'
for header, value in self.response_headers:
towrite.extend(header)
towrite.extend(b': ')
towrite.extend(value)
towrite.extend(b"\r\n")
towrite += header
towrite += b': '
towrite += value
towrite += b"\r\n"
towrite.extend(b'\r\n')
towrite += b'\r\n'
self._sendall(towrite)
# No need to copy the data into towrite; we may make an extra syscall
# but the copy time could be substantial too, and it reduces the chances
@@ -788,7 +802,7 @@ class WSGIHandler(object):
# "Servers should check for errors in the headers at the time
# start_response is called, so that an error can be raised
# while the application is still running." Here, we check the encoding.
# This aids debugging: headers especially are generated programatically
# This aids debugging: headers especially are generated programmatically
# and an encoding error in a loop or list comprehension yields an opaque
# UnicodeError without any clue which header was wrong.
# Note that this results in copying the header list at this point, not modifying it,
@@ -899,8 +913,8 @@ class WSGIHandler(object):
# Trigger the flush of the headers.
self.write(b'')
if self.response_use_chunked:
self.socket.sendall(b'0\r\n\r\n')
self.response_length += 5
self._sendall(b'0\r\n\r\n')
def run_application(self):
assert self.result is None
@@ -921,7 +935,33 @@ class WSGIHandler(object):
close = None
self.result = None
#: These errors are silently ignored by :meth:`handle_one_response` to avoid producing
#: excess log entries on normal operating conditions. They indicate
#: a remote client has disconnected and there is little or nothing
#: this process can be expected to do about it. You may change this
#: value in a subclass.
#:
#: The default value includes :data:`errno.EPIPE` and :data:`errno.ECONNRESET`.
#: On Windows this also includes :data:`errno.WSAECONNABORTED`.
#:
#: This is a provisional API, subject to change. See :pr:`377`, :pr:`999`
#: and :issue:`136`.
#:
#: .. versionadded:: 1.3
ignored_socket_errors = (errno.EPIPE, errno.ECONNRESET)
try:
ignored_socket_errors += (errno.WSAECONNABORTED,)
except AttributeError:
pass # Not windows
def handle_one_response(self):
"""
Invoke the application to produce one response.
This is called by :meth:`handle_one_request` after all the
state for the request has been established. It is responsible
for error handling.
"""
self.time_start = time.time()
self.status = None
self.headers_sent = False
@@ -946,12 +986,8 @@ class WSGIHandler(object):
except _InvalidClientInput:
self._send_error_response_if_possible(400)
except socket.error as ex:
if ex.args[0] in (errno.EPIPE, errno.ECONNRESET):
# Broken pipe, connection reset by peer.
# Swallow these silently to avoid spewing
# useless info on normal operating conditions,
# bloating logfiles. See https://github.com/gevent/gevent/pull/377
# and https://github.com/gevent/gevent/issues/136.
if ex.args[0] in self.ignored_socket_errors:
# See description of self.ignored_socket_errors.
if not PY3:
sys.exc_clear()
self.close_connection = True