classification
Title: http.client.HTTPConnection tunneling is broken
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.5, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: orsenthil Nosy List: Cybjit, barry, benjamin.peterson, cameron, dstufft, ethan.furman, larry, ned.deily, nikratio, orsenthil, python-dev, vadmium
Priority: release blocker Keywords: patch

Created on 2010-01-25 04:34 by cameron, last changed 2014-05-19 21:59 by orsenthil. This issue is now closed.

Files
File name Uploaded Description Edit
issue7776_rev1.patch nikratio, 2014-01-08 04:10 Patch, revision 1
issue7776_rev2.patch nikratio, 2014-01-08 04:43 Patch, revision 2
issue7776_rev3.patch nikratio, 2014-01-12 18:22 Patch, revision 3
issue7776_rev4.patch nikratio, 2014-01-18 04:12 Patch, revision 4 review
issue7776_rev5.patch nikratio, 2014-01-27 05:18 review
issue7776_rev6.patch nikratio, 2014-01-28 04:59
issue7776_r7_Py3.4.diff nikratio, 2014-04-13 19:10
issue7776_r7_Py3.5.diff nikratio, 2014-04-13 19:10
7776-2.7.patch orsenthil, 2014-05-17 00:41
Messages (43)
msg98264 - (view) Author: Cameron Simpson (cameron) Date: 2010-01-25 04:33
I'm trying to do HTTPS via a proxy in Python 2.6.4 (which is supposed to incorporate this fix from issue 1424152).

While trying to debug this starting from the suds library I've been reading httplib.py and urllib2.py to figure out what's going wrong
and found myself around line 687 of httplib.py at the _tunnel()
function.

_tunnel() is broken because _set_hostport() has side effects.

_tunnel() starts with:
  self._set_hostport(self._tunnel_host, self._tunnel_port)
to arrange that the subsequent connection is made to the proxy
host and port, and that is in itself ok.

However, _set_hostport() sets the .host and .port attributes in
the HTTPConnection object.

The next action _tunnel() takes is to send the CONNECT HTTP command,
filling in the endpoint host and port from self.host and self.port.
But these values have been overwritten by the preceeding _set_hostport()
call, and so we ask the proxy to connect to itself.

It seems to me that _tunnel() should be grabbing the original host and port before calling _set_hostport(), thus:

  ohost, oport = self.host, self.port
  self._set_hostport(self._tunnel_host, self._tunnel_port)
  self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (ohost, oport))

In fact the situation seems even worse: _tunnel() calls send(), send() calls connect(), and connect() calls _tunnel() in an infinite regress.
- Cameron Simpson
msg98266 - (view) Author: Cameron Simpson (cameron) Date: 2010-01-25 05:46
Amendment: regarding the infinite regress, it looks like there will not be a recursion if the caller leaps straight to the .connect() method. However, if they do that then the call to _tunnel() from within connect() will happen _after_ the socket is made directly to the origin host, not via the proxy. So the behaviour seems incorrect then also; it looks very much like _tunnel() must always be called before the real socket connection is established, and .connect() calls _tunnel() afterwards, not before.
msg98268 - (view) Author: Cameron Simpson (cameron) Date: 2010-01-25 06:57
It's looking like I have my idea of .host versus ._tunnel_host swapped. I think things are still buggy, but my interpretation of the bug is wrong or misleading.

I gather that after _set_tunnel(), .host is the proxy host and that ._tunnel_host is the original target host.

I'll follow up here in a bit when I've better characterised the problem.
I think I'm letting urllib2's complicated state stuff confuse me too...
msg98311 - (view) Author: Cameron Simpson (cameron) Date: 2010-01-26 02:24
Well, I've established a few things:
  - I'm mischaracterised this issue
  - httplib's _set_tunnel() is really meant to be called from
    urllib2, because using it directly with httplib is totally
    counter intuitive
  - a bare urllib2 setup fails with its own bug

To the first item: _tunnel() feels really fragile with that recursion issue, though it doesn't recurse called from urllib2.

For the second, here's my test script using httplib:

  H = httplib.HTTPSConnection("localhost", 3128)
  print H
  H._set_tunnel("localhost", 443)
  H.request("GET", "/boguspath")
  os.system("lsof -p %d | grep IPv4" % (os.getpid(),))
  R = H.getresponse()
  print R.status, R.reason

As you can see, one builds the HTTPSConnection object with the proxy's details instead of those of the target URL, and then put the target URL details in with _set_tunnel(). Am I alone in find this strange?

For the third, my test code is this:

  U = urllib2.Request('https://localhost/boguspath')
  U.set_proxy('localhost:3128', 'https')
  f = urllib2.urlopen(R)
  print f.read()

which fails like this:

  Traceback (most recent call last):
    File "thttp.py", line 15, in <module>
      f = urllib2.urlopen(R)
    File "/opt/python-2.6.4/lib/python2.6/urllib2.py", line 131, in urlopen
      return _opener.open(url, data, timeout)
    File "/opt/python-2.6.4/lib/python2.6/urllib2.py", line 395, in open
      protocol = req.get_type()
  AttributeError: HTTPResponse instance has no attribute 'get_type'

The line numbers are slightly off because I've got some debugging statements in there.

Finally, I flat out do not understand urllib2's set_proxy() method:
  
    def set_proxy(self, host, type):
        if self.type == 'https' and not self._tunnel_host:
            self._tunnel_host = self.host
        else:
            self.type = type
            self.__r_host = self.__original
        self.host = host

When my code calls set_proxy, self.type is None. Now, I had naively expected the first branch to be the only branch. Could someone explain what's happening here, and what is meant to happen?

I'm thinking that this bug may turn into a doc fix instead of a behaviour fix, but I'm finding it surprisingly hard to know how urllib2 is supposed to be used.
msg98312 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-01-26 03:08
As you noticed, the _set_tunnel method is a private method not intended to be used directly. Its being used by urllib2 when https through proxy is required.
urllib2 works like this, it reads HTTPS_PROXY environment variable (in turn includes HTTPSProxyHandler and HTTPSProxyAuthenticationHandler) and then try to do a urlopen on an https:// url or a request object through the tunnel doing a  CONNECT instead of a GET.

How do think the docs can be improved? If you have any suggestions please upload a patch. 
Thanks.
msg98401 - (view) Author: Cameron Simpson (cameron) Date: 2010-01-27 03:06
Well, following your description I've backed out my urllib2 test case to this:

  f = urllib2.urlopen('https://localhost/boguspath')
  os.system("lsof -p %d | grep IPv4" % (os.getpid(),))
  f = urllib2.urlopen(R)
  print f.read()

and it happily runs HTTPS through the proxy if I set the https_proxy envvar. So it's all well and good for the "just do what the environment suggests" use case.

However, my older test:

  U = urllib2.Request('https://localhost/boguspath')
  U.set_proxy('localhost:3128', 'https')
  f = urllib2.urlopen(R)
  print f.read()

still blows up with:

  File "/opt/python-2.6.4/lib/python2.6/urllib2.py", line 381, in open
    protocol = req.get_type()
  AttributeError: HTTPResponse instance has no attribute 'get_type'

Now, this is the use case for "I have a custom proxy setup for this activity".

It seems a little dd that "req" above is an HTTPResponse instead of a Request, and that my be why there's no .ettype() method available.

I also see nothing obviously wrong with my set_proxy() call above based on the docs for the .set_proxy() method, though obviously it fails.

I think what may be needed is a small expansion of the section in the Examples are on proxies. There's an description of the use of the *_proxy envvars there (and not elsewhere, which seems wrong) and an example of providing a proxy Handler. An addition example with a functioning use of a bare .set_proxy() might help.
msg190052 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2013-05-26 03:29
Cameron could you provide a patch for this?
msg207658 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-08 03:42
Ok, this is a bit of a mess.

Issue #11448 contains a patch for the documentation. But the functionality itself is still not working.

With the (I believe) intended usage, we have:

>>> import http.client
>>> conn = http.client.HTTPSConnection("localhost",8080)
>>> conn.set_tunnel("www.python.org")
>>> conn.request("HEAD","/index.html")

What happens then is this:

- request() calls _send_request(), which calls _put_request()
- _put_request() generates a "Host: localhost:8080" header
- _send_request() calls sendheaders(), calls _send_output()
- _send_output() calls send(), which calls connect()
- connect() connects to localhost:8080 and calls _tunnel()
- _tunnel() sets self.host to www.python.org and establishes the tunnel, but the Host: header has already been generated, and the proxy host name and port is now lost
- The request is send with a wrong Host header
- When calling close() and connect(), connect will now try to connect directly to www.python.org, but attempt to use it as a proxy to tunnel to itself.
msg207661 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-08 04:10
I have attached a patch that should fix the issue.
msg207663 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-08 04:43
New patch revision, this time includes unit tests.
msg207976 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-12 18:22
I've updated the patch again to fix a problem with HTTPSConnection.
msg208382 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-18 04:12
Rebased patch on current tip.
msg209382 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-01-27 03:35
A few comments
- Your docstring for set_tunnel claims the method sends CONNECT when it in fact doesn't touch the network at all.
- Instead of 3 parallel arrays for tunnel information, it would be better to have a TunnelInfo class to contain host/port/headers (perhaps a namedtuple?).
msg209397 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-27 05:18
Thanks for the review! I've attached an updated patch.

An update to the set_tunnel library documentation is being discussed in issue 11448. I'm not sure how to best handle the overlap. Maybe the best way is to first deal with issue 11448, and then add the changes resulting from this issue?
msg209494 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-28 01:03
Hmm. I think I found another problem... please wait for another patch revision.
msg209500 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-01-28 04:59
Ok, I've attached yet another patch revision. 

This revision is less complex, because it gets rid of the ability to set up chains of tunnels. The only reason that I put that in was to preserve backward compatibility -- but upon reviewing the old implementation again, I found out that this actually did not work in the past either.
msg216031 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-04-13 19:10
Refreshed patch.
msg216046 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-04-14 01:45
I am reviewing this patch right now and you will see my action soon. It is completely and I am reviewing to validating the technical details/fix. Thanks for patch, Nikolaus.
msg216100 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-04-14 15:40
I verified the patch and this indeed corrects a nasty bug in sending a wrong header when doing it a lower level HTTPSConnection to proxy and set_tunnel (bad term) to the end host..I was worried as why we did not observe this earlier and it seems to me that the advertised way to do HTTPS CONNECT is via Proxy Handler or urllib.request and when doing it via a ProxyHandler, these wierdly named action (set_tunnel) happen underneath, but the skip_hosts bit is set as we got headers from the higher level method. and the host header is carried transparently to the tunnel connection request and thus we escaped this. 

The patch fixes the problem and cleans up a bit. Thanks for that , Nikolaus.

This code (http/client.py) will require more attention beyond this bug too.
msg216114 - (view) Author: Roundup Robot (python-dev) Date: 2014-04-14 17:10
New changeset 39ee3286d187 by Senthil Kumaran in branch '3.4':
Issue #7776: Fix ``Host:'' header and reconnection when using http.client.HTTPConnection.set_tunnel().
http://hg.python.org/cpython/rev/39ee3286d187

New changeset 2c9af09ba7b8 by Senthil Kumaran in branch 'default':
merge from 3.4
http://hg.python.org/cpython/rev/2c9af09ba7b8
msg216117 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-04-14 17:14
This is fixed in 3.4 and 3.5 (finally). I will port it to 2.7 as well.
msg218197 - (view) Author: (Cybjit) Date: 2014-05-09 21:02
I get errors when using pip with a proxy in 3.4.1rc1 on Windows, that does not happen on 3.4.0.
I tracked it down to this change to client.py.
OK with client.py from fd2c69cedb25, but not with client.py from 39ee3286d187.

C:\Python34\Scripts>set HTTP_PROXY=http://openwrt.lan:8888

C:\Python34\Scripts>set HTTPS_PROXY=http://openwrt.lan:8888

C:\Python34\Scripts>pip -v install simplejson
Downloading/unpacking simplejson
  Could not fetch URL https://pypi.python.org/simple/simplejson/: connection err
or: hostname 'openwrt.lan' doesn't match either of '*.c.ssl.fastly.net', 'c.ssl.
fastly.net', '*.target.com', '*.vhx.tv', '*.snappytv.com', '*.atlassian.net', 'p
laces.hoteltonight.com', 'secure.lessthan3.com', '*.atlassian.com', 'a.sellpoint
.net', 'cdn.upthere.com', '*.tissuu.com', '*.issuu.com', '*.kekofan.com', '*.pyt
hon.org', '*.theverge.com', '*.sbnation.com', '*.polygon.com', '*.twobrightlight
s.com', '*.2brightlights.info', '*.vox.com', 'staging-cdn.upthere.com', '*.zeebo
x.com', '*.beamly.com', '*.aticpan.org', 'stream.svc.7digital.net', 'stream-test
.svc.7digital.net', '*.articulate.com', 's.t.st', 'vid.thestreet.com', '*.planet
-labs.com', '*.url2png.com', 'turn.com', 'www.turn.com', 'rivergathering.org', '
social.icfglobal2014-europe.org', '*.innogamescdn.com', '*.pathable.com', '*.sta
ging.pathable.com', '*.kickstarter.com', 'sparkingchange.org', 'www.swedavia.se'
, 'www.swedavia.com', 'js-agent.newrelic.com', '*.fastly-streams.com', 'cdn.bran
disty.com', 'fastly.hightailcdn.com', '*.fl.yelpcdn.com', '*.feedmagnet.com', 'a
pi.contentbody.com', '*.acquia.com', '*.swarmapp.com', '*.lonny.com', '*.stylebi
stro.com', '*.zimbio.com', '*.pypa.io', 'pypa.io', 'static.qbranch.se', '*.krxd.
net', '*.room.co', '*.metrological.com', 'room.co', 'www.ibmserviceengage.com',
'my.ibmserviceengage.com', 'cdn.evbuc.com', 'cdn.adagility.com'
  Will skip URL https://pypi.python.org/simple/simplejson/ when looking for down
load links for simplejson
msg218204 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-05-09 22:23
On 05/09/2014 02:02 PM, Cybjit wrote:
> C:\Python34\Scripts>pip -v install simplejson
> Downloading/unpacking simplejson
>   Could not fetch URL https://pypi.python.org/simple/simplejson/: connection err
> or: hostname 'openwrt.lan' doesn't match either of '*.c.ssl.fastly.net', 'c.ssl.

This looks as if pip tries to match the hostname in the certificate from
pypi.python.org against the hostname of the local proxy. Looking at the
code, I don't see why it would do that though. HTTPSConnection.connect
definitely tries to match against the final hostname.

Is pip maybe doing its own certificate check, and relying on
HTTPSConnection.host to contain the final hostname rather than the proxy?
msg218212 - (view) Author: (Cybjit) Date: 2014-05-10 07:45
On 2014-05-10 00:23, nikratio wrote:
> Is pip maybe doing its own certificate check, and relying on
> HTTPSConnection.host to contain the final hostname rather than the proxy?

I think the culprit might be here https://github.com/pypa/pip/blob/1.5.4/pip/_vendor/requests/packages/urllib3/connection.py#L172
msg218286 - (view) Author: Nikolaus Rath (nikratio) * Date: 2014-05-11 19:02
Cybjit <report@bugs.python.org> writes:
> Cybjit added the comment:
>
> On 2014-05-10 00:23, nikratio wrote:
>> Is pip maybe doing its own certificate check, and relying on
>> HTTPSConnection.host to contain the final hostname rather than the proxy?
>
> I think the culprit might be here
> https://github.com/pypa/pip/blob/1.5.4/pip/_vendor/requests/packages/urllib3/connection.py#L172

Yes, that's the problem. I guess that nicely demonstrates why using
inheritance as an API is not a good idea.

I guess we nevertheless need to repair/work around this in Python 3.4?
Unfortunately pip explicitly relies on _set_tunnel() to set self.host =
self._tunnel_host. So we would need to change _set_tunnel() to save the
original attribute somewhere, change the other methods to use the saved
attribute in favor of the real one, and have connect() restore it (so
that we can reconnect). This still would not allow pip to reconnect
(because it overwrites the connect method), but then reconnecting a
tunneled connection with pip did not work before either. Still, rather
ugly.

Alternatively, maybe we could also do nothing, because if pip is
depending on undocumented semantics of a private method (_set_tunnel),
they have to live with the consequences?

Thinking about this, I think we should just revert the entire patch for
3.4, but keep it in for 3.5. That gives the pip folks enough time to fix
their code. Fixing the issue in 3.4 is probably not that crucial (after
all, it existed since about 2.6.3).

Best,
Nikolaus

-- 
GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

             »Time flies like an arrow, fruit flies like a Banana.«
msg218294 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2014-05-11 20:07
Should this be a release blocker regression for 3.4.1?
msg218295 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-05-11 20:27
dstufft, what do you think?
msg218297 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-11 20:32
Let me raise the issue with urllib3 and see if maybe we can get a quick turn around and just fix it for real.
msg218299 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-11 21:14
This is going to break existing versions of urllib3 (and thus requests and thus pip) when using verified TLS + a proxy, however future versions can work around it and a fix is being looked at right now. Once it's fixed there it can propagate to requests and then to pip.

Urllib3 issue is here https://github.com/shazow/urllib3/issues/385

As far as what CPython should do. I personally don't think 3.4.1 should go out with this broken. That'll mean either getting a new pip out with the fix and bump the bundled version in CPython or revert this patch and wait till 3.5 (or 3.4.2 if you don't want to hold up 3.4.1).
msg218355 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-12 19:10
Just an update, the issue is fixed in urllib3 and that has been pulled into requests. Requests is currently prepping to release a new version which I'll pull into pip and issue a pip 1.5.6 release which can be pulled into CPython which should fix this.
msg218685 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-05-17 00:41
I am glad that issues with 3rdparty libs which dependent on the previous wrong behavior has been resolved.

As indicated previously, I think, it makes sense to have this in 2.7 as well. I created a patch and tested it 2.7 and it is all good. I plan to commit it before the next 2.7 update (which should be tomorrow).
msg218688 - (view) Author: Roundup Robot (python-dev) Date: 2014-05-17 01:52
New changeset 568041fd8090 by Senthil Kumaran in branch '2.7':
Backport Fix for Issue #7776: Fix ``Host:'' header and reconnection when using http.client.HTTPConnection.set_tunnel().
http://hg.python.org/cpython/rev/568041fd8090
msg218689 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-05-17 01:53
This is fixed in 2.7 as well here (changeset 568041fd8090). 

We shall close this ticket after @dstufft pulls in the updated pip for 3.4

Thanks!
msg218691 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-17 02:05
Requests has been released and I've pulled it into the pip tree. I'll be releasing tonight probably, or maybe tomorrow.
msg218692 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-05-17 02:06
I tag 3.4.1 final in less than 24 hours.  I really would prefer that the embedded pip not contain such, uh, fresh software.  But let's try it and hope for the best.
msg218693 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-17 02:09
Well you're the RM Larry :) I'll do whatever you think is best. I would greatly prefer it if the pip shipped with CPython 3.4.1 wasn't broken with proxies. I think the choices are

1) Ship it with the new pip, I can give a delta of the differences if that is helpful.
2) Roll back the patch that broke the behavior
3) Ship with broken pip + proxy behavior

Whichever you think is the better option is fine with me.
msg218694 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-05-17 02:42
Yeah, I'd like to see the diff.
msg218695 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-17 02:53
I just released pip 1.5.6.

The ensurepip package currently has 1.5.4 inside of it. 1.5.5 has been out for 2 weeks or so and there haven't been any reported regressions.

The only difference between 1.5.5 and 1.5.6 is that requests has been upgraded.

Here's the changelog items for 1.5.5 and 1.5.6: https://github.com/pypa/pip/blob/master/CHANGES.txt#L1-L20

Here's the diff from 1.5.5 to 1.5.6: https://github.com/pypa/pip/compare/1.5.5...1.5.6
Here's the diff from 1.5.4 to 1.5.6: https://github.com/pypa/pip/compare/1.5.4...1.5.6

If you want me to update the bundled ensurepip let me know what branch I should do it on. I'm going to go ahead and do it for 3.5 though.
msg218696 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-17 03:07
Just FYI, I upgraded setuptools and pip in 3.5:

http://hg.python.org/cpython/rev/acb5cc616052
http://hg.python.org/cpython/rev/308ff6a5ce67

If you decide to go that way dunno if you can just cherry pick or not.
msg218698 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-05-17 04:34
I prefer we update the ensurepip in 3.4.1  
That will be helpful too since 3.5 has the fix.
msg218724 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-05-18 00:26
@larry

Is there anything else I need to do?
msg218728 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2014-05-18 01:40
@dstufft - should you commit it in 3.4 branch (since the change is already in 3.5) and then wait for larry's approval or rejection?
msg218729 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-05-18 02:59
Okay, this has my blessing to be merged for 3.4.1.
History
Date User Action Args
2014-05-19 21:59:33orsenthilsetversions: + Python 2.7
2014-05-18 02:59:18larrysetstatus: open -> closed
2014-05-18 02:59:08larrysetmessages: + msg218729
2014-05-18 01:40:13orsenthilsetmessages: + msg218728
2014-05-18 00:26:14dstufftsetmessages: + msg218724
2014-05-18 00:22:19benjamin.petersonsetversions: - Python 2.7
2014-05-17 04:34:59orsenthilsetmessages: + msg218698
2014-05-17 03:07:04dstufftsetmessages: + msg218696
2014-05-17 02:53:11dstufftsetmessages: + msg218695
2014-05-17 02:42:11larrysetmessages: + msg218694
2014-05-17 02:09:05dstufftsetmessages: + msg218693
2014-05-17 02:06:44larrysetmessages: + msg218692
2014-05-17 02:05:43dstufftsetmessages: + msg218691
2014-05-17 01:53:59orsenthilsetpriority: high -> release blocker

messages: + msg218689
versions: + Python 2.7
2014-05-17 01:52:00python-devsetmessages: + msg218688
2014-05-17 00:41:49orsenthilsetpriority: release blocker -> high
files: + 7776-2.7.patch
messages: + msg218685
2014-05-12 19:10:47dstufftsetmessages: + msg218355
2014-05-12 19:06:13barrysetnosy: + barry
2014-05-11 21:14:27dstufftsetmessages: + msg218299
2014-05-11 20:32:46dstufftsetmessages: + msg218297
2014-05-11 20:27:03larrysetnosy: + dstufft
messages: + msg218295
2014-05-11 20:07:48ned.deilysetpriority: normal -> release blocker
nosy: + larry, ned.deily
messages: + msg218294

2014-05-11 19:02:35nikratiosetmessages: + msg218286
2014-05-10 07:45:43Cybjitsetmessages: + msg218212
2014-05-09 22:23:16nikratiosetmessages: + msg218204
2014-05-09 21:02:16Cybjitsetnosy: + Cybjit
messages: + msg218197
2014-04-14 18:12:21orsenthilsetstage: test needed -> resolved
resolution: fixed
versions: + Python 3.5, - Python 2.7, Python 3.3
2014-04-14 17:14:23orsenthilsetmessages: + msg216117
2014-04-14 17:10:27python-devsetnosy: + python-dev
messages: + msg216114
2014-04-14 15:40:56orsenthilsetmessages: + msg216100
2014-04-14 01:45:52orsenthilsetmessages: + msg216046
2014-04-13 19:10:51nikratiosetfiles: + issue7776_r7_Py3.5.diff
2014-04-13 19:10:37nikratiosetfiles: + issue7776_r7_Py3.4.diff

messages: + msg216031
2014-03-19 04:56:56vadmiumsetnosy: + vadmium
2014-02-03 15:35:18BreamoreBoysetnosy: - BreamoreBoy
2014-01-28 04:59:20nikratiosetfiles: + issue7776_rev6.patch

messages: + msg209500
2014-01-28 01:03:58nikratiosetmessages: + msg209494
2014-01-27 05:18:04nikratiosetfiles: + issue7776_rev5.patch

messages: + msg209397
2014-01-27 03:35:30benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg209382
2014-01-18 04:37:03terry.reedysetversions: - Python 2.6, Python 3.1, Python 3.2, Python 3.5
2014-01-18 04:12:36nikratiosetfiles: + issue7776_rev4.patch

messages: + msg208382
2014-01-18 02:46:49ethan.furmansetnosy: + ethan.furman
2014-01-12 18:22:02nikratiosetfiles: + issue7776_rev3.patch

messages: + msg207976
2014-01-08 04:53:18brian.curtinsetnosy: - brian.curtin
2014-01-08 04:43:10nikratiosetfiles: + issue7776_rev2.patch

messages: + msg207663
2014-01-08 04:10:12nikratiosetfiles: + issue7776_rev1.patch
keywords: + patch
messages: + msg207661
2014-01-08 03:42:46nikratiosetversions: + Python 3.3, Python 3.4, Python 3.5
nosy: + nikratio
title: httplib.py: ._tunnel() broken -> http.client.HTTPConnection tunneling is broken
messages: + msg207658

2013-05-26 03:29:24BreamoreBoysetnosy: + BreamoreBoy
messages: + msg190052
2010-01-27 03:06:57cameronsetmessages: + msg98401
2010-01-26 03:08:36orsenthilsetmessages: + msg98312
2010-01-26 02:24:06cameronsetmessages: + msg98311
2010-01-25 06:57:44cameronsetmessages: + msg98268
2010-01-25 06:22:17orsenthilsetassignee: orsenthil

nosy: + orsenthil
2010-01-25 05:46:37cameronsetmessages: + msg98266
2010-01-25 04:57:07brian.curtinsetpriority: normal
nosy: + brian.curtin
versions: + Python 3.1, Python 2.7, Python 3.2

stage: test needed
2010-01-25 04:34:00cameroncreate