Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use HTTPHeaderDict in request #679

Merged
merged 4 commits into from Jul 21, 2015

Conversation

sigmavirus24
Copy link
Contributor

Supersedes #633

shazow and others added 2 commits May 28, 2015 11:25
Fix dict(HTTPHeaderDict(other_dict)) and deal with changes in how we
implement the HTTPHeaderDict as a MutableMapping subclass instead of
as a dict subclass.
@sigmavirus24
Copy link
Contributor Author

This might not be perfect, but it at least passes the test_collections tests. And it's late here =P

@sigmavirus24
Copy link
Contributor Author

Tests are failing because there isn't that tests the get method directly of the HTTPHeaderDict.

yield val[0], ', '.join(val[1:])

def items(self):
return list(self.iteritems())

viewitems = items
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Forgot to delete this. We don't need it.

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 18, 2015

Broadly LGTM.

@shazow
Copy link
Member

shazow commented Jul 18, 2015

Mmmm yea this is a smaller change than I thought we'd need. If you can make the remaining test(s) pass, I'm all for it. :)

@shazow
Copy link
Member

shazow commented Jul 18, 2015

Btw, 🍮.

Now when we send data with the HTTPHeaderDict we will use the original
casing, e.g., if we create an instance with

    {'COOkie': 'value'}

Then

    dict(HTTPHeaderDict({'COOkie': 'value'})) == {'COOkie': 'value'}

So we should expect that the returned headers preserve the capitalization
that was provided to the HeaderDict.
@sigmavirus24
Copy link
Contributor Author

So the tests should pass now. The thing that I'm uncertain about is this test. I can definitely see that dict(HTTPHeaderDict(baz='quuz')) == {'baz': 'quuz'} but something else is turning that into {'Baz': 'quuz'}. I haven't investigated it yet.

@shazow
Copy link
Member

shazow commented Jul 18, 2015

Hm wonder if it's our dummyserver and/or httplib mangling headers on some versions.

@sigmavirus24
Copy link
Contributor Author

Hm wonder if it's our dummyserver and/or httplib mangling headers on some versions.

It's more bizarre because this test was passing before we fixed the round-trip behaviour. =/

@sigmavirus24
Copy link
Contributor Author

If I debug into the request methods, I get to

(Pdb) p kw['headers']
{'Accept': '*/*', 'baz': 'quux', 'Host': 'localhost:52261'}

On L276 in urllib3/poolmanager.py

@sigmavirus24
Copy link
Contributor Author

If I go further, it's still the right case in connectionpool.py. I don't have much time to go further though. Sorry. =(

@sigmavirus24
Copy link
Contributor Author

For anyone else looking to follow the same rabbit hole.

  1. Add import pdb; pdb.set_trace() (or ipdb if that's your thing) to test/with_dummyserver/test_proxy_poolmanager.py at L238.
  2. tox -e py27 -- -s test.with_dummyserver.test_proxy_poolmanager (or py34 or whatever)
  3. Start stepping into functions that make the request.

@Lukasa Lukasa added this to the v1.11 milestone Jul 19, 2015
@shazow shazow mentioned this pull request Jul 19, 2015
2 tasks
@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 19, 2015

So this isn't in httplib: the header is emitted in the case it was provided to httplib. Current money is on the dummyserver doing that.

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 19, 2015

Definitely the dummy server. From tcpdump:

GET http://localhost:62953/headers HTTP/1.1
Accept-Encoding: identity
Accept: */*
Host: localhost:62953
baz: quux
foo: bar

HTTP/1.1 200 OK
Etag: "feb15a7ce2766d24cf20cf1633197fc5d8a59281"
Date: Sun, 19 Jul 2015 10:22:50 GMT
Content-Length: 146
Server: TornadoServer/4.1
Content-Type: text/html; charset=UTF-8,text/plain

{"Accept": "*/*", "Content-Length": "0", "Foo": "bar", "Connection": "close", "Host": "localhost:62953", "Accept-Encoding": "gzip", "Baz": "quux"}

We definitely emitted headers in lowercase, they were definitely reflected to us in upper-case.

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 19, 2015

Note also that the dummyserver inserts some headers we didn't send (Connection: close) and mangles one we did send (Accept-Encoding: gzip).

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 19, 2015

Ok, so had a quick chat with @shazow and I think that test should just be rethought. We can't effectively test that case is preserved when we round-trip via the dummy server, so let's just not.

I can see a case for wanting a test that ensures that case is preserved that includes httplib, but if we're going to do that we should do it as a socket-level test where we can confirm that the bytes-on-the-wire are really what we think they are.

@sigmavirus24
Copy link
Contributor Author

So b49490d has a socketlevel test for this.

@shazow
Copy link
Member

shazow commented Jul 21, 2015

Yay 🍮!

Are we good to go? Shall I merge and ship v1.11?

@sigmavirus24
Copy link
Contributor Author

That's Cory's call.

Sent from my Android device with K-9 Mail. Please excuse my brevity.

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Jul 21, 2015

Let's rock-and-roll. :shipit:

shazow added a commit that referenced this pull request Jul 21, 2015
@shazow shazow merged commit a76eb3b into urllib3:master Jul 21, 2015
shazow added a commit that referenced this pull request Jul 21, 2015
@mmedvede
Copy link

mmedvede commented Aug 5, 2015

This causes OpenStack devstack-gate tests to fail on Fedora 21 (but not on Ubuntu). There are interactions between many python packages during the test, so I am not yet certain if it is urlib's fault, but if I use the commit previous to the merge of this pull request, tempest tests pass.

@Lukasa
Copy link
Sponsor Contributor

Lukasa commented Aug 5, 2015

@mmedvede Can we get more information, e.g. a link to a Launchpad bug?

@sigmavirus24
Copy link
Contributor Author

@Lukasa it appears they're tracking it in https://bugs.launchpad.net/glance/+bug/1476770. The original bug was because the gate is not operating as it is supposed to (and I suspect the same is happening on Fedora). The gate should always be installing requests from pip instead of using system packages but they're not so when they install urllib3 1.11.0, it installs over the system urllib3 that was installed. I maintain that this is fundamentally a problem with the gate. Note that instead of fixing the gate, they released a new version of oslo.vmware (the only library to use urllib3 in openstack directly) with a cap to exclude 1.11.0. This is not a problem or a bug in urllib3.

@mmedvede
Copy link

mmedvede commented Aug 6, 2015

@sigmavirus24 I was not aware of the bug, thanks. It is exactly what was happening to our third-party Fedora 21 gate (IBM PowerKVM CI) before I disabled the urllib3 1.11 install. I assume that Ubuntu installs newer system python-requests, so when urllib3 1.11 is installed on top, the gate doesn't break. The weird thing is that both Ubuntu and Fedora gates show requests 2.7.0 installed. I have confirmed that doing 'pip install --upgrade --force-reinstall requests' fixes Fedora 21 in my scenario, even though requests would still show as being 2.7.0.

@Lukasa Thanks for quick response. Not urllib3 problem.

@sigmavirus24
Copy link
Contributor Author

@mmedvede check where requests 2.7.0 is installed from. You'll see that it's installed from the system packages and that is not what the gate is supposed to do. Anyway, further discussion should happen on LaunchPad, not here.

@tfmorris
Copy link

This change requires all requests-cache caches be deleted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants