masperro / httplib2

Automatically exported from code.google.com/p/httplib2
0 stars 0 forks source link

Http.request hangs when reattempting a POST/PUT w/ file-object as body after a http401 challenge #151

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. h = Http()
   h.add_credentials(user_name, user_pass)
   f = open(file, "r")
   # Pass the file-handle as the body param in the request method
   h.request("url", "POST", body = f, headers...)
   # Server replies to first POST with a 401
   # httplib2 reattempts, but fails to POST/PUT the file
   # It stalls after it has sent the headers in the reattempt

What is the expected output? What do you see instead?

A successfully completed POST or PUT with the file uploaded after 
authenticating with the server.

What happens is that the second attempt (after the 401 challenge) stalls when 
it is about to add in the body. I would guess this is due to the library not 
seeking back to the beginning of the file again (f.seek(0)) on 2nd attempt.

What I see via wireshark: (POSTing a random logging.conf file as an example)

 POST /col-uri/961c7785-a2a9-4555-b8eb-c5a0985244f6 HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
Content-Length: 329
content-disposition: attachment; filename=sword2_logging.conf
in-progress: true
user-agent: Python-httplib2/$Rev$
packaging: http://purl.org/net/sword/package/Binary
content-md5: 26c9465bba767c61d8e6be703718e425
content-type: text/plain

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=basicFormatting

[logger_root]
level=INFO
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=basicFormatting
args=(sys.stdout,)

[formatter_basicFormatting]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="SSS"
Transfer-Encoding: chunked
Date: Tue, 31 May 2011 04:34:51 GMT
Server: CherryPy/3.1.2 WSGI Server

4
None
0

POST /col-uri/961c7785-a2a9-4555-b8eb-c5a0985244f6 HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
Content-Length: 329
content-disposition: attachment; filename=sword2_logging.conf
in-progress: true
user-agent: Python-httplib2/$Rev$
packaging: http://purl.org/net/sword/package/Binary
content-md5: 26c9465bba767c61d8e6be703718e425
content-type: text/plain
authorization: Basic c3dvcmQ6c3dvcmQ=

[*STALLS AT THIS POINT* - remote server times out with a http 408 error]
===================================

If I pass the payload as a bytestring rather than a file-like object, the POST 
works fine. Eg as follows - pcap w/ wireshark:

========================================

POST /col-uri/961c7785-a2a9-4555-b8eb-c5a0985244f6 HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
Content-Length: 30
content_length: 30
content-disposition: attachment; filename=readme.txt
in-progress: true
content-md5: b5c151529e88bd3c993346efa1a6bad7
packaging: http://purl.org/net/sword/package/Binary
user-agent: Python-httplib2/$Rev$
content-type: text/plain

Payload is just a load of text

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="SSS"
Transfer-Encoding: chunked
Date: Tue, 31 May 2011 04:28:42 GMT
Server: CherryPy/3.1.2 WSGI Server

4
None
0

POST /col-uri/961c7785-a2a9-4555-b8eb-c5a0985244f6 HTTP/1.1
Host: localhost:8080
Accept-Encoding: identity
Content-Length: 30
content_length: 30
content-disposition: attachment; filename=readme.txt
in-progress: true
content-md5: b5c151529e88bd3c993346efa1a6bad7
packaging: http://purl.org/net/sword/package/Binary
user-agent: Python-httplib2/$Rev$
content-type: text/plain
authorization: Basic c3dvcmQ6c3dvcmQ=

Payload is just a load of text

HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry
Location: 
http://localhost:8080/edit-uri/961c7785-a2a9-4555-b8eb-c5a0985244f6/8b17eb5a-b50
8-4fa8-86a0-61b86aa26364
Transfer-Encoding: chunked
Date: Tue, 31 May 2011 04:28:42 GMT
Server: CherryPy/3.1.2 WSGI Server

8c0
<entry xmlns:dcterms="http://purl.org/dc/terms/" 
xmlns:sword="http://purl.org/net/sword/terms/" 
xmlns="http://www.w3.org/2005/Atom">
  <title>SWORD Deposit</title>
  <id>tag:container@sss/961c7785-a2a9-4555-b8eb-c5a0985244f6/8b17eb5a-b508-4fa8-86a0-61b86aa26364</id>
  <updated>2011-05-31T05:28:42Z</updated>
  <author> ...... etc

========================================

What version of the product are you using? On what operating system?

$ sudo easy_install -U httplib2
[sudo] password for ben: 
Searching for httplib2
Reading http://pypi.python.org/simple/httplib2/
Reading http://code.google.com/p/httplib2/
Reading http://bitworking.org/projects/httplib2/
Best match: httplib2 0.6.0
Processing httplib2-0.6.0-py2.6.egg
httplib2 0.6.0 is already the active version in easy-install.pth

Using /usr/local/lib/python2.6/dist-packages/httplib2-0.6.0-py2.6.egg
Processing dependencies for httplib2
Finished processing dependencies for httplib2

easy_install tells me it is 0.6.0, but the httplib2.__version__ string has (a 
bug?) a '$Rev$' string, suggesting a CVS/related error on making the release.

Please provide any additional information below.

Linux, recent kernel, using Httplib2 to perform Atom/APP style communications.

Original issue reported on code.google.com by bost...@gmail.com on 31 May 2011 at 4:38

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
In fact, if you add the following code to line 1195 of httplib2/__init__.py -> 
http://code.google.com/p/httplib2/source/browse/python2/httplib2/__init__.py#119
5 it should fix the problem:

    for authorization in self._auth_from_challenge(host, request_uri, headers, response, content):

        # ADDED CODE
        if hasattr(body, seek):
            body.seek(0)
        # END

        authorization.request(method, request_uri, headers, body)
        (response, content) = self._conn_request(conn, request_uri, method, body, headers, )
        if response.status != 401:
            self.authorizations.append(authorization)
            authorization.response(response, body)
            break

Original comment by bost...@gmail.com on 10 Jun 2011 at 2:14

GoogleCodeExporter commented 8 years ago
body must always be a string, it has never supported a file handle.

Original comment by joe.gregorio@gmail.com on 13 Jun 2011 at 5:13