-
Notifications
You must be signed in to change notification settings - Fork 193
Implement draft 10 of the http2 spec #34
Changes from all commits
87a8149
0b75307
7a42e05
228362f
da4e207
c750a32
79ef23e
5ce4ecd
2d2490a
ce43c6d
2c5e53a
2da1ba5
4a0cd6c
b72a3c4
c2e9280
5d5d61c
6030a38
32572a6
575a856
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
omit = | ||
hyper/compat.py | ||
hyper/httplib_compat.py | ||
hyper/ssl_compat.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
build/ | ||
env/ | ||
dist/ | ||
*.egg-info/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,6 +140,11 @@ def listlen(list): | |
# Append the data to the buffer. | ||
data.append(frame.data) | ||
|
||
# Increase the window size. Only do this if the data frame contains | ||
# actual data. | ||
size = len(frame.data) + frame.total_padding | ||
increment = self._in_window_manager._handle_frame(size) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any reason this got moved? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I ignored it for streams quite deliberately, because it seemed unnecessary (the stream is about to be closed so who cares what the flow control window is doing?). I don't hugely mind though, and it shouldn't hurt. |
||
# If that was the last frame, we're done here. | ||
if 'END_STREAM' in frame.flags: | ||
self.state = ( | ||
|
@@ -148,9 +153,6 @@ def listlen(list): | |
) | ||
break | ||
|
||
# Increase the window size. Only do this if the data frame contains | ||
# actual data. | ||
increment = self._in_window_manager._handle_frame(len(frame.data)) | ||
if increment: | ||
w = WindowUpdateFrame(self.stream_id) | ||
w.window_increment = increment | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,75 +5,57 @@ | |
|
||
Contains the TLS/SSL logic for use in hyper. | ||
""" | ||
import ssl | ||
import os.path as path | ||
|
||
from ..compat import is_py3 | ||
from ..compat import ignore_missing, ssl | ||
|
||
|
||
# Right now we support draft 9. | ||
SUPPORTED_PROTOCOLS = ['http/1.1', 'HTTP-draft-09/2.0'] | ||
NPN_PROTOCOL = 'h2-10' | ||
SUPPORTED_NPN_PROTOCOLS = ['http/1.1', NPN_PROTOCOL] | ||
|
||
|
||
# We have a singleton SSLContext object. There's no reason to be creating one | ||
# per connection. We're using v23 right now until someone gives me a reason not | ||
# to. | ||
# per connection. | ||
_context = None | ||
|
||
# Exposed here so it can be monkey-patched in integration tests. | ||
_verify_mode = ssl.CERT_REQUIRED | ||
|
||
|
||
# Work out where our certificates are. | ||
cert_loc = path.join(path.dirname(__file__), '..', 'certs.pem') | ||
|
||
def wrap_socket(sock, server_hostname): | ||
""" | ||
A vastly simplified SSL wrapping function. We'll probably extend this to | ||
do more things later. | ||
""" | ||
global _context | ||
|
||
if is_py3: # pragma: no cover | ||
def wrap_socket(socket, server_hostname): | ||
""" | ||
A vastly simplified SSL wrapping function. We'll probably extend this to | ||
do more things later. | ||
""" | ||
global _context | ||
|
||
if _context is None: # pragma: no cover | ||
_context = _init_context() | ||
|
||
if ssl.HAS_SNI: | ||
return _context.wrap_socket(socket, server_hostname=server_hostname) | ||
if _context is None: # pragma: no cover | ||
_context = _init_context() | ||
|
||
wrapped = _context.wrap_socket(socket) # pragma: no cover | ||
assert wrapped.selected_npn_protocol() == 'HTTP-draft-09/2.0' | ||
return wrapped | ||
else: # pragma: no cover | ||
def wrap_socket(socket, server_hostname): | ||
return ssl.wrap_socket(socket, ssl_version=ssl.PROTOCOL_SSLv23, | ||
ca_certs=cert_loc, cert_reqs=_verify_mode) | ||
# the spec requires SNI support | ||
ssl_sock = _context.wrap_socket(sock, server_hostname=server_hostname) | ||
# Setting SSLContext.check_hostname to True only verifies that the | ||
# post-handshake servername matches that of the certificate. We also need to | ||
# check that it matches the requested one. | ||
ssl.match_hostname(ssl_sock.getpeercert(), server_hostname) | ||
with ignore_missing(): | ||
assert ssl_sock.selected_npn_protocol() == NPN_PROTOCOL | ||
return ssl_sock | ||
|
||
|
||
def _init_context(): # pragma: no cover | ||
def _init_context(): | ||
""" | ||
Creates the singleton SSLContext we use. | ||
""" | ||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | ||
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) | ||
context.set_default_verify_paths() | ||
context.load_verify_locations(cafile=cert_loc) | ||
context.verify_mode = _verify_mode | ||
|
||
try: | ||
context.set_npn_protocols(SUPPORTED_PROTOCOLS) | ||
except (AttributeError, NotImplementedError): # pragma: no cover | ||
pass | ||
context.verify_mode = ssl.CERT_REQUIRED | ||
context.check_hostname = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth examining what Requests does here. =) |
||
|
||
# We do our best to do better security | ||
try: | ||
context.options |= ssl.OP_NO_SSLv2 | ||
except AttributeError: # pragma: no cover | ||
pass | ||
with ignore_missing(): | ||
context.set_npn_protocols(SUPPORTED_NPN_PROTOCOLS) | ||
|
||
try: | ||
context.options |= ssl.OP_NO_COMPRESSION | ||
except AttributeError: # pragma: no cover | ||
pass | ||
# required by the spec | ||
context.options |= ssl.OP_NO_COMPRESSION | ||
|
||
return context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the comment? =)