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

add HTTP version to connection and responses #296

Merged
merged 2 commits into from Dec 7, 2016

Conversation

nateprewitt
Copy link
Member

This should address #285.

The tests aren't passing right now because we still have an outstanding bug (#291) in hyper until a new version of h2 is released. Other than the b'connection' header failures though, everything seems to be working.

@nateprewitt
Copy link
Member Author

Actually it looks like TestImportPython2.test_cannot_import_python_2 is failing too because it raises an AttributeError rather than an ImportError.

This seems unrelated to this patch though. I can dig a bit if you don't immediately know what's causing that @Lukasa.

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.

This generally seems fine! I'll try to chase the test stuff up tomorrow.

@@ -102,6 +104,9 @@ def __init__(self, host, port=None, secure=None, window_manager=None,
else:
self.host, self.port = host, port

# HTTP Version of the connection
self.version = HTTPVersion.http20
Copy link
Member

Choose a reason for hiding this comment

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

Given that these are static and don't change, let's set these on the class object rather than do this at initialisation time.

def test_response_version(self):
r = HTTP20Response(HTTPHeaderMap([(':status', '200')]), None)
assert r.version is HTTPVersion.http20

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 also get a few tests for the abstract HTTPConnection object passing this through?

@nateprewitt
Copy link
Member Author

A couple quick questions on the abstract tests. I'm currently unable to come up with a way to test HTTP and TLS upgrades without live network IO to something like http2bin.org. I could mock the connections like the other tests but that kind of defeats the point.

The second question I have is more of an oddity. I've written what is a successful test when run with py.test and as a separate python file, but in tox it repeatedly fails to perform the TLS upgrade. wrap_socket never changes the proto from None.

from hyper.common.connection import HTTPConnection
from hyper.common.util import HTTPVersion

c = HTTPConnection('www.http2bin.org', 443)
assert c.version is HTTPVersion.http11
c.request('GET', '/')
assert c.version is HTTPVersion.http20

c = HTTPConnection('www.http2bin.org', 80)
assert c.version is HTTPVersion.http11
c.request('GET', '/')
c.get_response()
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: test the response version here too.

@Lukasa
Copy link
Member

Lukasa commented Dec 2, 2016

I'm currently unable to come up with a way to test HTTP and TLS upgrades without live network IO to something like http2bin.org. I could mock the connections like the other tests but that kind of defeats the point.

I don't think I follow this. Other parts of the test suite have found a way to do it, it should be possible for your code to do that. In this case, you just need to lie about the connection setup, which ought not to be too difficult.

I've written what is a successful test when run with py.test and as a separate python file, but in tox it repeatedly fails to perform the TLS upgrade. wrap_socket never changes the proto from None.

Are you running the same Python version in both cases? Same dependencies? Almost certainly you're using a Python that has a too-old ssl library or OpenSSL in tox, so there is no negotiation.

@Lukasa
Copy link
Member

Lukasa commented Dec 2, 2016

Ok, the master branch should have its tests fixed up.

@nateprewitt
Copy link
Member Author

I don't think I follow this. Other parts of the test suite have found a way to do it, it should be possible for your code to do that. In this case, you just need to lie about the connection setup, which ought not to be too difficult.

Sorry, I should have been clearer. The other parts of the library are mocking out a custom Connection object in order to do this. In that case, I'm simply creating a DummySocket that has an attr "version" and then testing the dummy socket still has a version after upgrades. That kind of test never actually touches the underlying HTTP11Connection or HTTP20Connection so it doesn't prove anything useful. It will always pass regardless of changes to the actual connection classes.

Are you running the same Python version in both cases? Same dependencies? Almost certainly you're using a Python that has a too-old ssl library or OpenSSL in tox, so there is no negotiation.

That was the first thing I had checked but couldn't find anything immediately. The weird thing is it will run fine locally in a fresh virtualenv, but fails in tox and Travis. I'll try to do a deeper dig to figure out what my base environment has that doesn't seem to be in Travis.

@Lukasa
Copy link
Member

Lukasa commented Dec 2, 2016

Hrm. Can you do it in the socket-level style by actually creating a TLS connection? If not, we may need to use some mocks to achieve what we need.

@nateprewitt
Copy link
Member Author

Yeah, I'll do some tinkering this afternoon and try to devise a way to initiate the upgrades with the actual objects but no external IO.

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 looks good, except for the fact that one of the tests is super-wacky and I don't really understand what it was trying to do.

b'Server: socket-level-server\r\n'
b'Content-Length: 0\r\n'
b'Connection: upgrade\r\n',
b'Upgrade: TLS/1.0, HTTP/2.0'
Copy link
Member

Choose a reason for hiding this comment

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

Uh...what is this? This test doesn't make any sense at all, and frankly suggests that the upgrade code in hyper is broken. =P

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, this one was a test based off of a bad reading of the RFC 2817. I had a question on it yesterday that I was going to ask here but solved it and forgot to remove the code.

@nateprewitt
Copy link
Member Author

@Lukasa, okay, sorry that took so long. I got the test working by monkeypatching wrap_socket. Things should be ready for an actual look now.

@nateprewitt
Copy link
Member Author

As an aside, is there a reason the tests are configured to pass despite failures, as long as there's 100% test coverage?

I hit this with a couple test attempts that were failing but the build wasn't explicitly telling me until I dug into the logs of "successful" builds. It looks like all of the NGHTTP2 builds have been failing to import nghttp2 (TestUtilities.test_nghttp2_installs_correctly) for at least the last few months too.

@Lukasa
Copy link
Member

Lukasa commented Dec 7, 2016

There is not, I think it's just a misconfiguration of Travis. I seem to recall that I had the same problem in the hpack library, which I fixed in python-hyper/hpack#60. This included removing the nghttp2 support (which hasn't worked for a while, and which I didn't have the resources to investigate).

I recommend opening a PR to do both of those things if you have the bandwidth to do it. =)

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.

Small notes, but I think it'd be good if we tackled the bad reporting of tests first. =)

sock.sendall(f.serialize())

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

Choose a reason for hiding this comment

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

This needs to be wait, not set.

@Lukasa
Copy link
Member

Lukasa commented Dec 7, 2016

Nevermind, I'm tackling it myself in #298.

@nateprewitt
Copy link
Member Author

Alright, things should be set once the tests finish.

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.

Looks good to me, thanks @nateprewitt!

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.

None yet

2 participants