Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Add ENABLE_PUSH flag in the Upgrade HTTP2-Settings header #311

Merged
merged 5 commits into from
Feb 24, 2017

Conversation

hkwi
Copy link
Contributor

@hkwi hkwi commented Feb 23, 2017

Push flag required for the case the initial upgrade request triggered server push. This PR is a relaxed version of #310 , which was more strict on server push I/O timing.
Test send/recv timing was fixed, because connection state machine does not get corrupted during h2c upgrade migration.

hkwi added 2 commits February 23, 2017 11:19
Push flag required for the case the initial upgrade request triggered server push.
Some tests requires synchronization to let the connection
state machine working.
Copy link
Member

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this seems reasonable, but there are some changes in the tests I don't understand. Notes are inline.

frame.data = data
if end_stream:
frame.flags.add('END_STREAM')
self.frames.append(frame)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move these helpers out to a common mixin class now that we're using them in more than one place?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it.

self.http101 + b''.join([frame.serialize()
for frame in self.frames])
)
self.conn.request('GET', '/')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should do any asserting that the Upgrade header is present?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrading process itself is tested at test_http11.py, and IMHO, we would focus on client side view here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's fair enough.

# Send the headers for the response. This response has no body.
f = build_headers_frame(
[(':status', '200'), ('content-length', '0')]
)
f.flags.add('END_STREAM')
f.stream_id = 1
sock.sendall(f.serialize())

# Wait for the message from the main thread.
send_event.wait()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this get moved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to wait here only when the client side are going to get the response. Another option is add send_event.wait() here, and add get_response(), send_event.set() in client side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So historically the reason for these waits has been to ensure that we don't close sockets in a way that leads to unexpected socket behaviour on some platforms. If we don't need to remove them I'd be inclined to leave them in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@@ -1078,8 +1126,6 @@ def socket_handler(listener):
d.data = b'1234567890' * 2
d.flags.add('END_STREAM')
sock.send(d.serialize())

send_event.wait(5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to wait here when we close the socket. Another option is add send_event.wait() and sock.close() here, and send_event.set() in client side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this really answered what the reason was for removing this. Was it causing a problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not causing problem. I removed just because I thought it was not necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for this stuff that's not really a great attitude. Specifically, these are intended to delay socket shutdown to the point where the socket is no longer in use, as some interactions can cause exceptions to be raised if EOF is received too early.

introduced FrameEncoderMixin helper class.
fix waits for not displaying unwanted EOF errors.
@@ -1107,6 +1114,7 @@ def test_response_version(self):


class TestHTTP20Adapter(object):

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did all these blank lines get added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... that's autopep8. I'd revert those.

Copy link
Member

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, cool, getting closer. One more question inline.

client_preface = b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'
timeout = time.time() + 5
got = b''
while len(got) < len(client_preface) and time.time() < timeout:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the logic behind this timeout here? The socket doesn't actually have the timeout applied to it, so it could time out indefinitely.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's a bug. I used timeout for local testing.

Copy link
Member

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, this looks good to me. Thanks for doing all this work @hkwi! ✨

@Lukasa Lukasa merged commit 04f3266 into python-hyper:development Feb 24, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants