-
-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1172 from CastagnaIT/http2
Migration to HTTP/2 network protocol
- Loading branch information
Showing
148 changed files
with
49,576 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ coverage: | |
comment: false | ||
ignore: | ||
- tests/ | ||
- packages/ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .core import contents, where | ||
|
||
__version__ = "2021.05.30" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import argparse | ||
|
||
from certifi import contents, where | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument("-c", "--contents", action="store_true") | ||
args = parser.parse_args() | ||
|
||
if args.contents: | ||
print(contents()) | ||
else: | ||
print(where()) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
certifi.py | ||
~~~~~~~~~~ | ||
This module returns the installation location of cacert.pem or its contents. | ||
""" | ||
import os | ||
|
||
try: | ||
from importlib.resources import path as get_path, read_text | ||
|
||
_CACERT_CTX = None | ||
_CACERT_PATH = None | ||
|
||
def where(): | ||
# This is slightly terrible, but we want to delay extracting the file | ||
# in cases where we're inside of a zipimport situation until someone | ||
# actually calls where(), but we don't want to re-extract the file | ||
# on every call of where(), so we'll do it once then store it in a | ||
# global variable. | ||
global _CACERT_CTX | ||
global _CACERT_PATH | ||
if _CACERT_PATH is None: | ||
# This is slightly janky, the importlib.resources API wants you to | ||
# manage the cleanup of this file, so it doesn't actually return a | ||
# path, it returns a context manager that will give you the path | ||
# when you enter it and will do any cleanup when you leave it. In | ||
# the common case of not needing a temporary file, it will just | ||
# return the file system location and the __exit__() is a no-op. | ||
# | ||
# We also have to hold onto the actual context manager, because | ||
# it will do the cleanup whenever it gets garbage collected, so | ||
# we will also store that at the global level as well. | ||
_CACERT_CTX = get_path("certifi", "cacert.pem") | ||
_CACERT_PATH = str(_CACERT_CTX.__enter__()) | ||
|
||
return _CACERT_PATH | ||
|
||
|
||
except ImportError: | ||
# This fallback will work for Python versions prior to 3.7 that lack the | ||
# importlib.resources module but relies on the existing `where` function | ||
# so won't address issues with environments like PyOxidizer that don't set | ||
# __file__ on modules. | ||
def read_text(_module, _path, encoding="ascii"): | ||
with open(where(), "r", encoding=encoding) as data: | ||
return data.read() | ||
|
||
# If we don't have importlib.resources, then we will just do the old logic | ||
# of assuming we're on the filesystem and munge the path directly. | ||
def where(): | ||
f = os.path.dirname(__file__) | ||
|
||
return os.path.join(f, "cacert.pem") | ||
|
||
|
||
def contents(): | ||
return read_text("certifi", "cacert.pem", encoding="ascii") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), | ||
# containing no networking code at all, loosely modelled on hyper-h2's generic | ||
# implementation of HTTP/2 (and in particular the h2.connection.H2Connection | ||
# class). There's still a bunch of subtle details you need to get right if you | ||
# want to make this actually useful, because it doesn't implement all the | ||
# semantics to check that what you're asking to write to the wire is sensible, | ||
# but at least it gets you out of dealing with the wire itself. | ||
|
||
from ._connection import * | ||
from ._events import * | ||
from ._state import * | ||
from ._util import LocalProtocolError, ProtocolError, RemoteProtocolError | ||
from ._version import __version__ | ||
|
||
PRODUCT_ID = "python-h11/" + __version__ | ||
|
||
|
||
__all__ = ["ProtocolError", "LocalProtocolError", "RemoteProtocolError"] | ||
__all__ += _events.__all__ | ||
__all__ += _connection.__all__ | ||
__all__ += _state.__all__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# We use native strings for all the re patterns, to take advantage of string | ||
# formatting, and then convert to bytestrings when compiling the final re | ||
# objects. | ||
|
||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace | ||
# OWS = *( SP / HTAB ) | ||
# ; optional whitespace | ||
OWS = r"[ \t]*" | ||
|
||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators | ||
# token = 1*tchar | ||
# | ||
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" | ||
# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" | ||
# / DIGIT / ALPHA | ||
# ; any VCHAR, except delimiters | ||
token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" | ||
|
||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields | ||
# field-name = token | ||
field_name = token | ||
|
||
# The standard says: | ||
# | ||
# field-value = *( field-content / obs-fold ) | ||
# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] | ||
# field-vchar = VCHAR / obs-text | ||
# obs-fold = CRLF 1*( SP / HTAB ) | ||
# ; obsolete line folding | ||
# ; see Section 3.2.4 | ||
# | ||
# https://tools.ietf.org/html/rfc5234#appendix-B.1 | ||
# | ||
# VCHAR = %x21-7E | ||
# ; visible (printing) characters | ||
# | ||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string | ||
# obs-text = %x80-FF | ||
# | ||
# However, the standard definition of field-content is WRONG! It disallows | ||
# fields containing a single visible character surrounded by whitespace, | ||
# e.g. "foo a bar". | ||
# | ||
# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 | ||
# | ||
# So our definition of field_content attempts to fix it up... | ||
# | ||
# Also, we allow lots of control characters, because apparently people assume | ||
# that they're legal in practice (e.g., google analytics makes cookies with | ||
# \x01 in them!): | ||
# https://github.com/python-hyper/h11/issues/57 | ||
# We still don't allow NUL or whitespace, because those are often treated as | ||
# meta-characters and letting them through can lead to nasty issues like SSRF. | ||
vchar = r"[\x21-\x7e]" | ||
vchar_or_obs_text = r"[^\x00\s]" | ||
field_vchar = vchar_or_obs_text | ||
field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) | ||
|
||
# We handle obs-fold at a different level, and our fixed-up field_content | ||
# already grows to swallow the whole value, so ? instead of * | ||
field_value = r"({field_content})?".format(**globals()) | ||
|
||
# header-field = field-name ":" OWS field-value OWS | ||
header_field = ( | ||
r"(?P<field_name>{field_name})" | ||
r":" | ||
r"{OWS}" | ||
r"(?P<field_value>{field_value})" | ||
r"{OWS}".format(**globals()) | ||
) | ||
|
||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line | ||
# | ||
# request-line = method SP request-target SP HTTP-version CRLF | ||
# method = token | ||
# HTTP-version = HTTP-name "/" DIGIT "." DIGIT | ||
# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive | ||
# | ||
# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full | ||
# URL, host+port (for connect), or even "*", but in any case we are guaranteed | ||
# that it contists of the visible printing characters. | ||
method = token | ||
request_target = r"{vchar}+".format(**globals()) | ||
http_version = r"HTTP/(?P<http_version>[0-9]\.[0-9])" | ||
request_line = ( | ||
r"(?P<method>{method})" | ||
r" " | ||
r"(?P<target>{request_target})" | ||
r" " | ||
r"{http_version}".format(**globals()) | ||
) | ||
|
||
# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line | ||
# | ||
# status-line = HTTP-version SP status-code SP reason-phrase CRLF | ||
# status-code = 3DIGIT | ||
# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) | ||
status_code = r"[0-9]{3}" | ||
reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) | ||
status_line = ( | ||
r"{http_version}" | ||
r" " | ||
r"(?P<status_code>{status_code})" | ||
# However, there are apparently a few too many servers out there that just | ||
# leave out the reason phrase: | ||
# https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 | ||
# https://github.com/seanmonstar/httparse/issues/29 | ||
# so make it optional. ?: is a non-capturing group. | ||
r"(?: (?P<reason>{reason_phrase}))?".format(**globals()) | ||
) | ||
|
||
HEXDIG = r"[0-9A-Fa-f]" | ||
# Actually | ||
# | ||
# chunk-size = 1*HEXDIG | ||
# | ||
# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 | ||
chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) | ||
# Actually | ||
# | ||
# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) | ||
# | ||
# but we aren't parsing the things so we don't really care. | ||
chunk_ext = r";.*" | ||
chunk_header = ( | ||
r"(?P<chunk_size>{chunk_size})" | ||
r"(?P<chunk_ext>{chunk_ext})?" | ||
r"\r\n".format(**globals()) | ||
) |
Oops, something went wrong.