Re: HTTP2 and SPDY
Date: Thu, 30 Jan 2014 21:24:06 +0900
On Thu, Jan 30, 2014 at 8:50 AM, Daniel Stenberg <daniel_at_haxx.se> wrote:
> On Wed, 29 Jan 2014, Tatsuhiro Tsujikawa wrote:
> Feel free to raise the issue at nghttp2 project page.
> Good to see you here Tatsuhiro, thanks for helping out!
> I added more code to libcurl to actually slowly start to receive http2
> frames but I end up with nghttp2_session_recv() failing for the moment. I
> filed https://github.com/tatsuhiro-t/nghttp2/issues/24 as I would really
> like some help from the lib to point out what the problem is!
> Additionally, I get one invalid frame it says. I will clearly need to add
> more debugging ability to libcurl for this so that --trace etc works for
> the http2 data as well!
> My test output with code from git shows this:
> <= Recv header, 21 bytes (0x15)
> 0000: 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 Connection: Upgr
> 0010: 61 64 65 0d 0a ade..
> <= Recv header, 28 bytes (0x1c)
> 0000: 55 70 67 72 61 64 65 3a 20 48 54 54 50 2d 64 72 Upgrade: HTTP-dr
> 0010: 61 66 74 2d 30 39 2f 32 2e 30 0d 0a aft-09/2.0..
> == Info: Received 101
> == Info: We have switched to HTTP2
> == Info: on_invalid_frame_recv() was called, error_code = 1
> == Info: Got ':status:200'
> == Info: Got 'accept-ranges:bytes'
> == Info: Got 'age:0'
> == Info: Got 'content-length:10478'
> == Info: Got 'content-type:text/html'
> == Info: Got 'date:Wed, 29 Jan 2014 23:47:24 GMT'
> == Info: Got 'etag:"52daab5b-28ee"'
> == Info: Got 'last-modified:Sat, 18 Jan 2014 16:27:07 GMT'
> == Info: Got 'server:nginx/1.4.1 (Ubuntu)'
> == Info: Got 'x-varnish:2029056218'
> == Info: Got 'via:1.1 varnish, 1.1 nghttpx'
> == Info: on_frame_recv() was called with header 1
> == Info: Failed receiving HTTP2 data
> == Info: nghttp2_session_recv() returned -902
> == Info: STATE: PERFORM => DONE handle 0x14e4498; line 1582 (connection #0)
> == Info: Connection #0 to host 188.8.131.52 left intact
This mixed result is caused by the bug in nghttp2 and the missing
in libcurl code.
The invalid_frame_recv callback should not be called in this situation, but
due to the bug,
the client code recognizes the response from the server as "request" and
processed as such, but
because stream ID is odd, the library detects that it is not valid and
invoked invalid_frame_recv callback. Anyway, the fix is easy so I'll do
that soon after this email.
For the libcurl part, there is more thing for client to do after 101
In HTTP2 spec, client has to send 24 bytes magic string and SETTINGS frame
as client connection header.
This 24 bytes byte string is defined as NGHTTP2_CLIENT_CONNECTION_HEADER in
Client should first push this off to the socket. Usually,
nghttp2_submit_settings() is used to send
SETTINGS frame. But the HTTP upgrade is treated specially and has the
nghttp2_session_upgrade(). Client should call this function with the same
SETTINGS payload sent
in HTTP2-Settings header field (but the form before base64-encoded). This
function opens stream ID=1, which is considered to be sent as the first
HTTP/1 request and queues SETTINGS frame to transmission queue in
I think the -902 error, which is NGHTTP2_ERR_CALLBACK_FAILURE, is triggered
because callback function
return it when it gets EOF from the remote peer.
As discussed in https://github.com/tatsuhiro-t/nghttp2/issues/13, I've
implemented the ability to stop processing
bytes when application requested so. To use this feature, application must
use nghttp2_session_mem_recv() instead of nghttp2_session_recv().
nghttp2_session_mem_recv() does not use recv_callback function and takes
the buffer pointer and its byte length directly. So, current libcurl code
can be a bit simplified with 1 less callback.
List admin: http://cool.haxx.se/list/listinfo/curl-library
Received on 2014-01-30