[issue28539] httplib/http.client HTTPConnection._get_hostport() regression

2016-10-26 Thread Charles Stephens

New submission from Charles Stephens:

Back through the mists of time, there was a change to strip square brackets 
IPv6 address host literals in HTTPConnection._get_hostport():

https://hg.python.org/cpython/diff/433606e9546c/Lib/httplib.py

However, the code mixed tabs and spaces and was "corected" by:

https://hg.python.org/cpython/diff/9e2b94a3b5dc/Lib/httplib.py

However, the intent was changed in the second diff and brackets won't be 
stripped.  This causes problems when IPv6 address URL's are used with the 
requests package:

In [1]: import httplib

In [2]: con = httplib.HTTPConnection('[fe80::26a9:37ff:fe00:f764%eth0]', 15482)

In [3]: con.request("GET", "/api/api-version")
---
gaierror  Traceback (most recent call last)
 in ()
> 1 con.request("GET", "/api/api-version")

/usr/lib/python2.7/httplib.pyc in request(self, method, url, body, headers)
977 def request(self, method, url, body=None, headers={}):
978 """Send a complete request to the server."""
--> 979 self._send_request(method, url, body, headers)
980 
981 def _set_content_length(self, body):

/usr/lib/python2.7/httplib.pyc in _send_request(self, method, url, body, 
headers)
   1011 for hdr, value in headers.iteritems():
   1012 self.putheader(hdr, value)
-> 1013 self.endheaders(body)
   1014 
   1015 def getresponse(self, buffering=False):

/usr/lib/python2.7/httplib.pyc in endheaders(self, message_body)
973 else:
974 raise CannotSendHeader()
--> 975 self._send_output(message_body)
976 
977 def request(self, method, url, body=None, headers={}):

/usr/lib/python2.7/httplib.pyc in _send_output(self, message_body)
833 msg += message_body
834 message_body = None
--> 835 self.send(msg)
836 if message_body is not None:
837 #message_body was not a string (i.e. it is a file) and

/usr/lib/python2.7/httplib.pyc in send(self, data)
795 if self.sock is None:
796 if self.auto_open:
--> 797 self.connect()
798 else:
799 raise NotConnected()

/usr/lib/python2.7/httplib.pyc in connect(self)
776 """Connect to the host and port specified in __init__."""
777 self.sock = socket.create_connection((self.host,self.port),
--> 778  self.timeout, 
self.source_address)
779 
780 if self._tunnel_host:

/usr/lib/python2.7/socket.pyc in create_connection(address, timeout, 
source_address)
551 host, port = address
552 err = None
--> 553 for res in getaddrinfo(host, port, 0, SOCK_STREAM):
554 af, socktype, proto, canonname, sa = res
555 sock = None

gaierror: [Errno -2] Name or service not known

--
components: Library (Lib)
files: get_hostport.diff
keywords: patch
messages: 279509
nosy: cfs-pure
priority: normal
severity: normal
status: open
title: httplib/http.client HTTPConnection._get_hostport() regression
versions: Python 2.7, Python 3.3, Python 3.4, Python 3.5, Python 3.6, Python 3.7
Added file: http://bugs.python.org/file45233/get_hostport.diff

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

Er, that is HTTPConnection._set_hostport() not _get_hostport()

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Changes by Charles Stephens :


--
title: httplib/http.client HTTPConnection._get_hostport() regression -> 
httplib/http.client HTTPConnection._set_hostport() regression

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

I misapplied the term 'regression'.  My intent was to describe how original 
author's change revision 433606e9546c was refactored to make it perform 
incorrectly.

Without the scope specifier, the outcome is the same when HTTPConnection is 
instantiated.  When both the host and port arguments are specified, the square 
brackets are not stripped and are stored in the host attribute.  When the port 
number is part of the host argument and the port argument is None, the host 
attribute does not include the square brackets.  Examples:

Python 2.7.10 (default, Jul 30 2016, 18:31:42) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import httplib
>>> con1 = httplib.HTTPConnection('[fe80::26a9:37ff:fe00:f764]', 15482)
>>> con1.host, con1.port
('[fe80::26a9:37ff:fe00:f764]', 15482)
>>> con2 = httplib.HTTPConnection('[fe80::26a9:37ff:fe00:f764]:15482')
>>> con2.host, con2.port
('fe80::26a9:37ff:fe00:f764', 15482)

Compare with IPv4 behavior:

>>> con3 = httplib.HTTPConnection('127.0.0.1', 15482)
>>> con3.host, con3.port
('127.0.0.1', 15482)
>>> con4 = httplib.HTTPConnection('127.0.0.1:15482')
>>> con4.host, con4.port
('127.0.0.1', 15482)

Calls to con1.request() will fail in socket.py because getaddrinfo will choke 
on the square brackets.  Which makes sense since HTTPConnection.host is passed 
on down the stack as-is until it reaches create_connection() in socket.py.

Moving the indent of that if block up one level makes con1 identical to con2.

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

Example with patch applied:

Python 2.7.6 (default, Oct 26 2016, 20:33:50) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import httplib
>>> con1 = httplib.HTTPConnection('[fe80::26a9:37ff:fe00:f764]', 15482)
>>> con1.host, con1.port
('fe80::26a9:37ff:fe00:f764', 15482)

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

Our internal use case is happening through requests via urllib3 for parsing.

Essentially requests is taking the URL, passing it to urllib3 for parsing.  
urllib3 is returning a namedtuple of type Url which includes a host and port 
property which is being fed to httplib.  Essentially:

>>> import urllib3
>>> import httplib
>>> orig_url = 'http://[2620:125:9014:3240:14:240:128:0]:8080/api/python'
>>> u1 = urllib3.util.parse_url(orig_url)
>>> u1
Url(scheme='http', auth=None, host='[2620:125:9014:3240:14:240:128:0]', 
port=8080, path='/api/python', query=None, fragment=None)
>>> c1 = httplib.HTTPConnection(u1.host, port=u1.port)
>>> c1.host, c1.port
('[2620:125:9014:3240:14:240:128:0]', 8080)
>>> c1.request('GET', '/api/json')
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python2.7/httplib.py", line 979, in request
self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 1013, in _send_request
self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 975, in endheaders
self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 835, in _send_output
self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 797, in send
self.connect()
  File "/usr/lib/python2.7/httplib.py", line 778, in connect
self.timeout, self.source_address)
  File "/usr/lib/python2.7/socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno -2] Name or service not known

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

Not when passing it to getaddrinfo().

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28539] httplib/http.client HTTPConnection._set_hostport() regression

2016-10-26 Thread Charles Stephens

Charles Stephens added the comment:

Yes, I'm working on patching urllib3 to preprocess the host argument to 
HTTPConnection.  However, it makes sense to strip square brackets regardless.

--

___
Python tracker 
<http://bugs.python.org/issue28539>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com