httpie / httpie-http2

(DEPRECATED) Experimental HTTP/2 plugin for HTTPie
https://httpie.org
Other
68 stars 4 forks source link

AttributeError: 'HTTP20Response' object has no attribute '_original_response' #1

Closed t2y closed 9 years ago

t2y commented 9 years ago

I tried to connect to google, but I got AttributeError.

(httpie)$ http --debug https://www.google.com
HTTPie 1.0.0-dev
HTTPie data: /Users/t2y/.httpie
Requests 2.5.1
Pygments 2.0.2
Python 3.4.2 (default, Nov 23 2014, 23:10:23) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] darwin

>>> requests.request({'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': OrderedDict(),
 'files': DataDict(),
 'headers': {'User-Agent': b'HTTPie/1.0.0-dev'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://www.google.com',
 'verify': True})

Traceback (most recent call last):
  File "/Users/t2y/.virtualenvs/httpie/bin/http", line 9, in <module>
    load_entry_point('httpie==1.0.0-dev', 'console_scripts', 'http')()
  File "/Users/t2y/work/external-repo/python/httpie/httpie/core.py", line 142, in main
    write(**write_kwargs)
  File "/Users/t2y/work/external-repo/python/httpie/httpie/output/streams.py", line 35, in write
    for chunk in stream:
  File "/Users/t2y/work/external-repo/python/httpie/httpie/output/streams.py", line 152, in __iter__
    yield self.get_headers()
  File "/Users/t2y/work/external-repo/python/httpie/httpie/output/streams.py", line 235, in get_headers
    self.msg.headers).encode(self.output_encoding)
  File "/Users/t2y/work/external-repo/python/httpie/httpie/models.py", line 54, in headers
    original = self._orig.raw._original_response
AttributeError: 'HTTP20Response' object has no attribute '_original_response'
Lukasa commented 9 years ago

Suspect this bug is actually on my end, because I fake out the raw response. I'm open to extending hyper to providing what's needed here.

jkbrzt commented 9 years ago

@t2y I see, there needs to be some more work done. Will look into that.

@Lukasa HTTPie expects a Requests Response. If it's not too much trouble, then making the response compatible would probably be the best solution for now.

Lukasa commented 9 years ago

We do build one, but this exception is being thrown from introspecting into the raw response, which means you really need that to be compatible with urllib3. =) Should be do-able.

Lukasa commented 9 years ago

So, that chunk of code makes some strong assumptions about the shape of the raw response object. Specifically, it assumes the following:

I can make that work.

Lukasa commented 9 years ago

Actually, the one problem is version, which clearly doesn't allow me to return 20. =D

jkbrzt commented 9 years ago

@Lukasa Now it will :wink:

Lukasa commented 9 years ago

Hurrah! And in return, the httpie branch of hyper now contains code that hacks around to get through this section of code. Feel free to test against it!

I very quietly released 0.1.1 of hyper about an hour ago, but I'm not publicising it until we can successfully make a HTTP/2 request through this. =D This is exciting, so I'll keep pushing releases until it works.

jkbrzt commented 9 years ago

@Lukasa Yea, it's not very clean but It was written only with Requests in mind. I think HTTPie should eventually expose those wrapper models and allow plugins to overwrite them (I'll be looking into the plugin API soon).

jkbrzt commented 9 years ago

@Lukasa Great, will test the httpie branch

Lukasa commented 9 years ago

Nothing wrong with that, it's hyper's job to conform as closely to what urllib3 provides as it can. =)

Lukasa commented 9 years ago

Ok, so nghttp2 doesn't like the request we're sending. Something about the headers, so it tears the stream down. I'll look at that next.

Lukasa commented 9 years ago

Alright, it doesn't like the connection header. Time to check whether it's invalid or whether nghttp2 is getting a bit aggressive. Suspect the former.

Lukasa commented 9 years ago

As always, nghttp2.org is doing the right thing here. I need to update hyper to strip the Connection header if it's provided to us.

Lukasa commented 9 years ago

Tracking that issue in Lukasa/hyper#83.

jkbrzt commented 9 years ago

@Lukasa good catch

Lukasa commented 9 years ago

Alright! With the change set I just pushed to the httpie branch, I now get this:

(env)cory@corymbp:hyper/ % ./env/bin/http --debug https://www.nghttp2.org/httpbin/get
HTTPie 1.0.0-dev
HTTPie data: /Users/cory/.httpie
Requests 2.5.1
Pygments 2.0.2
Python 3.4.2 (default, Oct 26 2014, 21:10:15) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] darwin

>>> requests.request({'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': OrderedDict(),
 'files': DataDict(),
 'headers': {'User-Agent': b'HTTPie/1.0.0-dev'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://www.nghttp2.org/httpbin/get',
 'verify': True})

HTTP/2.0 200 
access-control-allow-credentials: true
access-control-allow-origin: *
content-length: 271
content-type: application/json
date: Sat, 07 Feb 2015 11:27:15 GMT
server: nghttpx nghttp2/0.7.4-DEV
strict-transport-security: max-age=31536000
via: 1.1 nghttpx

{
    "args": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "close",
        "Host": "httpbin",
        "User-Agent": "HTTPie/1.0.0-dev",
        "Via": "2.0 nghttpx"
    },
    "origin": "81.156.148.41",
    "url": "https://httpbin/get"
}
Lukasa commented 9 years ago

Google is working too:

(env)cory@corymbp:hyper/ % ./env/bin/http --debug https://www.google.com/      
HTTPie 1.0.0-dev
HTTPie data: /Users/cory/.httpie
Requests 2.5.1
Pygments 2.0.2
Python 3.4.2 (default, Oct 26 2014, 21:10:15) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] darwin

>>> requests.request({'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': OrderedDict(),
 'files': DataDict(),
 'headers': {'User-Agent': b'HTTPie/1.0.0-dev'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://www.google.com/',
 'verify': True})

HTTP/2.0 302 
alternate-protocol: 443:quic,p=0.02
cache-control: private
content-length: 262
content-type: text/html; charset=UTF-8
date: Sat, 07 Feb 2015 11:29:39 GMT
location: https://www.google.co.uk/?gfe_rd=cr&ei=I_fVVKukEJKK4AbH54DQBw
server: GFE/2.0

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.co.uk/?gfe_rd=cr&amp;ei=I_fVVKukEJKK4AbH54DQBw">here</A>.
</BODY></HTML>
Lukasa commented 9 years ago

I'll push another hyper release, and then @jakubroztocil you can close this bug down.

jkbrzt commented 9 years ago

It's working for me after running:

$ pip install -U git+git://github.com/Lukasa/hyper.git@httpie

screen shot 2015-02-07 at 12 38 44

:sparkles:

jkbrzt commented 9 years ago

@Lukasa Awesome work :+1:

Lukasa commented 9 years ago

=D This is exciting stuff, definitely gave me a second wind on this project.

Once I push a release with this fix (currently getting 502s from the cheeseshop) I'll take another look at Python 2.7, because I think I can support Python 2.7.9 now.

jkbrzt commented 9 years ago

I guess the request HTTP version should now be also taken dynamically from the request:

https://github.com/jakubroztocil/httpie/blob/9682f955b5808585429e5cf64a6096ceac445999/httpie/models.py#L98-98

$ http -v  https://nghttp2.org/
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: nghttp2.org
User-Agent: HTTPie/1.0.0-dev
HTTP/2.0 200
accept-ranges: bytes
content-length: 26030
content-type: text/html
date: Sat, 07 Feb 2015 11:47:30 GMT
etag: "54c4fc4d-65ae"
last-modified: Sun, 25 Jan 2015 14:23:09 GMT
server: nghttpx nghttp2/0.7.4-DEV
strict-transport-security: max-age=31536000
via: 1.1 nghttpx
Lukasa commented 9 years ago

Heh, probably, yes. Note also that strictly it's not HTTP/2.0, it's just HTTP/2: the minor version number is gone.

jkbrzt commented 9 years ago

Is that true only for the version included in the request, or for responses as well?

Lukasa commented 9 years ago

For both.

I've released these changes as hyper v0.1.2, available now from your local PyPI.

Lukasa commented 9 years ago

And while I'm updating, I just pushed v0.2.0 to PyPI, which adds support for Python 2.7.9!

jkbrzt commented 9 years ago

@Lukasa I'm struggling to find a way to detect the HTTP version used for a request. Any idea?

jkbrzt commented 9 years ago

Fixed and released!