Make numerous improvements

- Python static hello world now 1.8mb
- Python static fully loaded now 10mb
- Python HTTPS client now uses MbedTLS
- Python REPL now completes import stmts
- Increase stack size for Python for now
- Begin synthesizing posixpath and ntpath
- Restore Python \N{UNICODE NAME} support
- Restore Python NFKD symbol normalization
- Add optimized code path for Intel SHA-NI
- Get more Python unit tests passing faster
- Get Python help() pagination working on NT
- Python hashlib now supports MbedTLS PBKDF2
- Make memcpy/memmove/memcmp/bcmp/etc. faster
- Add Mersenne Twister and Vigna to LIBC_RAND
- Provide privileged __printf() for error code
- Fix zipos opendir() so that it reports ENOTDIR
- Add basic chmod() implementation for Windows NT
- Add Cosmo's best functions to Python cosmo module
- Pin function trace indent depth to that of caller
- Show memory diagram on invalid access in MODE=dbg
- Differentiate stack overflow on crash in MODE=dbg
- Add stb_truetype and tools for analyzing font files
- Upgrade to UNICODE 13 and reduce its binary footprint
- COMPILE.COM now logs resource usage of build commands
- Start implementing basic poll() support on bare metal
- Set getauxval(AT_EXECFN) to GetModuleFileName() on NT
- Add descriptions to strerror() in non-TINY build modes
- Add COUNTBRANCH() macro to help with micro-optimizations
- Make error / backtrace / asan / memory code more unbreakable
- Add fast perfect C implementation of μ-Law and a-Law audio codecs
- Make strtol() functions consistent with other libc implementations
- Improve Linenoise implementation (see also github.com/jart/bestline)
- COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
Justine Tunney 2021-09-27 22:58:51 -07:00
parent fa7b4f5bd1
commit 39bf41f4eb
806 changed files with 77494 additions and 63859 deletions

View file

@ -8,37 +8,37 @@ may legally make another request or fetch the response for a particular
request. This diagram details these state transitions:
(null)
|
| HTTPConnection()
v
HTTPConnection()
Idle
|
| putrequest()
v
putrequest()
Request-started
|
| ( putheader() )* endheaders()
v
( putheader() )* endheaders()
Request-sent
|\_____________________________
| | getresponse() raises
| response = getresponse() | ConnectionError
v v
getresponse() raises
response = getresponse() ConnectionError
Unread-response Idle
[Response-headers-read]
|\____________________
| |
| response.read() | putrequest()
v v
response.read() putrequest()
Idle Req-started-unread-response
______/|
/ |
response.read() | | ( putheader() )* endheaders()
v v
response.read() ( putheader() )* endheaders()
Request-started Req-sent-unread-response
|
| response.read()
v
response.read()
Request-sent
This diagram presents the following rules:
@ -59,7 +59,7 @@ Note: this enforcement is applied by the HTTPConnection class. The
the server will NOT be closing the connection.
Logical State __state __response
------------- ------- ----------
Idle _CS_IDLE None
Request-started _CS_REQ_STARTED None
Request-sent _CS_REQ_SENT None
@ -74,6 +74,7 @@ import http
import io
import os
import re
import tls
import socket
import collections
from urllib.parse import urlsplit
@ -81,7 +82,7 @@ from encodings import idna, iso8859_1
# HTTPMessage, parse_headers(), and the HTTP status code constants are
# intentionally omitted for simplicity
__all__ = ["HTTPResponse", "HTTPConnection",
__all__ = ["HTTPResponse", "HTTPConnection", "HTTPSConnection",
"HTTPException", "NotConnected", "UnknownProtocol",
"UnknownTransferEncoding", "UnimplementedFileMode",
"IncompleteRead", "InvalidURL", "ImproperConnectionState",
@ -256,7 +257,11 @@ class HTTPResponse(io.BufferedIOBase):
# happen if a self.fp.read() is done (without a size) whether
# self.fp is buffered or not. So, no self.fp.read() by
# clients unless they know what they are doing.
self.fp = sock.makefile("rb")
if type(sock) is tls.TLS:
self.fp = io.BufferedReader(socket.SocketIO(sock, "r"),
io.DEFAULT_BUFFER_SIZE)
else:
self.fp = sock.makefile("rb")
self.debuglevel = debuglevel
self._method = method
@ -967,7 +972,10 @@ class HTTPConnection:
sock = self.sock
if sock:
self.sock = None
sock.close() # close it manually... there may be other refs
try:
sock.close() # close it manually... there may be other refs
except OSError:
pass # TODO(jart): deal with https fd ownership
finally:
response = self.__response
if response:
@ -1400,66 +1408,32 @@ class HTTPConnection:
response.close()
raise
try:
import ssl
except ImportError:
pass
else:
class HTTPSConnection(HTTPConnection):
"This class allows communication via SSL."
default_port = HTTPS_PORT
class HTTPSConnection(HTTPConnection):
"This class allows communication via SSL."
# XXX Should key_file and cert_file be deprecated in favour of context?
default_port = HTTPS_PORT
def __init__(self, host, port=None, key_file=None, cert_file=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, *, context=None,
check_hostname=None):
super(HTTPSConnection, self).__init__(host, port, timeout,
source_address)
if (key_file is not None or cert_file is not None or
check_hostname is not None):
import warnings
warnings.warn("key_file, cert_file and check_hostname are "
"deprecated, use a custom context instead.",
DeprecationWarning, 2)
self.key_file = key_file
self.cert_file = cert_file
if context is None:
context = ssl._create_default_https_context()
will_verify = context.verify_mode != ssl.CERT_NONE
if check_hostname is None:
check_hostname = context.check_hostname
if check_hostname and not will_verify:
raise ValueError("check_hostname needs a SSL context with "
"either CERT_OPTIONAL or CERT_REQUIRED")
if key_file or cert_file:
context.load_cert_chain(cert_file, key_file)
self._context = context
self._check_hostname = check_hostname
def __init__(self, host, port=None, key_file=None, cert_file=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, *, context=None,
check_hostname=None):
super(HTTPSConnection, self).__init__(host, port, timeout,
source_address)
self._check_hostname = check_hostname
if context is not None:
raise ValueError('context parameter not supported yet')
if key_file is not None:
raise ValueError('key_file parameter not supported yet')
if cert_file is not None:
raise ValueError('cert_file parameter not supported yet')
def connect(self):
"Connect to a host on a given (SSL) port."
def connect(self):
"Connect to a host on a given (SSL) port."
super().connect()
self.sock = tls.newclient(self.sock.fileno(), self.host, self.sock)
self.sock.handshake()
super().connect()
if self._tunnel_host:
server_hostname = self._tunnel_host
else:
server_hostname = self.host
self.sock = self._context.wrap_socket(self.sock,
server_hostname=server_hostname)
if not self._context.check_hostname and self._check_hostname:
try:
ssl.match_hostname(self.sock.getpeercert(), server_hostname)
except Exception:
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
raise
__all__.append("HTTPSConnection")
class HTTPException(Exception):
# Subclasses that define an __init__ must call Exception.__init__