Closed c0b closed 7 years ago
from Chrome DevTool:
the actual need behind this is I want some application level debugging for http2, from https://golang.org/pkg/net/http/httptrace/ it's good to have a WroteHeaders
hook point, but that only answered a question of when all headers are written, it's when my callback is called, but its signature is WroteHeaders func()
it didn't answer a question of what headers are written? I want a copy of what's going on to the wire;
from the (cc *http2ClientConn) RoundTrip
function we can see there is a local var hdrs
have a hold of all written headers in []byte
format, I guess it's hpack compressed already,
can I request WroteHeaders signature changed to be called with all uncompressed headers?
https://golang.org/src/net/http/h2_bundle.go #L5496
5496 hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
https://github.com/golang/net/blob/master/http2/transport.go#L754-L772
// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
// sent by writeRequestBody below, along with any Trailers,
// again in form HEADERS{1}, CONTINUATION{0,})
hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
if err != nil {
cc.mu.Unlock()
return nil, err
}
cs := cc.newStream()
cs.req = req
cs.trace = requestTrace(req)
cs.requestedGzip = requestedGzip
bodyWriter := cc.t.getBodyWriterState(cs, body)
cs.on100 = bodyWriter.on100
cc.wmu.Lock()
endStream := !hasBody && !hasTrailers
werr := cc.writeHeaders(cs.ID, endStream, hdrs)
For questions about Go, see https://golang.org/wiki/Questions.
As the docs say:
HTTP/2 requests are dumped in HTTP/1.x form, not in their original binary representations.
Dumping in binary would be unreadable and useless.
If you want to see how the sausage is made, see https://godoc.org/golang.org/x/net/http2.
why is this closed so early? @bradfitz
I didn't ask to dump the binary, but a better text format more close to what's seen in Chrome DevTool:
like
:authority: http2bin.org
:method: GET
:path: /get
:scheme: https
accept-encoding: gzip
user-agent: ...
[request body]
:status: 200
server: h2o/2.0.4
date: ...
content-type: ...
[response body]
this is not only a question, but something deserve to be improved in code
of course I have read that; but the problem I pointed out is the current http2 code didn't give application level an inspect interface to know what headers are written into the wire; this is a feature request
The Chrome text format is almost as arbitrary as any http2-binary-to-text format, including Go's format, which is at least consistent with Go's http1 format.
If you want a certain format, you're free to implement one. I don't think more formats are a good idea for the standard library. It's too little value for too much overlap.
I'd prefer this be implemented outside the Go libraries as an opt-in mechanism people can use when they want to match Chrome.
We already provide GODEBUG=http2debug=2 when you want to see exactly what's happening.
the GODEBUG=http2debug=2
is not enough because I have read this part of code it's just setting internal variables and print to log with extra information, in fixed format like I have shown above; but in a user friendly application design, I need to show the detail http2 interaction in different format, could be in a GUI, or saved in key=value pairs in Database for lookup later, from Application design level, need better and flexible interfaces
https://github.com/golang/net/blob/master/http2/http2.go#L42-L52
I have found the httptrace
package could be a good starting point, but it's also very limited, I can register a WroteHeaders
callback to be notified when the headers are actually wrote, at that moment with this interface I can only do is to record a timestamp; but what are the headers written?
WroteRequest
is called with WroteRequestInfo
looks like a little better,
https://golang.org/pkg/net/http/httptrace/
// WroteHeaders is called after the Transport has written
// the request headers.
WroteHeaders func()
// WroteRequest is called with the result of writing the
// request and any body.
WroteRequest func(WroteRequestInfo)
if httputil
is not agreed to change to show http2 traffic in different way, that is fine, I would like to do differentiation in Application level; then a different issue can be opened for this as a feature request? because currently many fields on http2ClientConn struct are lower cased (private); this library users won't be able to access, those can be changed to public (not good), or this library could design with proper API to expose such information when users want
Let me point you some different API design in different pro language / libraries: @bradfitz
nghttp2 in C; notice in their tutorial client program, users can register a on_header_callback
function, this function's signature shows it will get name, value
pairs in the order headers are received
http://nghttp2.org/documentation/tutorial-client.html
http://nghttp2.org/documentation/nghttp2_session_callbacks_set_on_header_callback.html
nodejs' http2 in core; users are freely to listen events like 'begin-headers'
, 'header'
(for each name, value pair on the order they are received), 'headers-complete'
, 'stream-close'
, ... many of them; because this code is utilizing nghttp2 as underlayer and is just a thin wrapper
https://github.com/nodejs/http2/blob/master/doc/http2-implementation-notes.md#event-header
Current Golang http2 code doesn't have any of these features; I have read the doc and most of the Go code under net/http2 https://godoc.org/golang.org/x/net/http2 https://github.com/golang/net/tree/master/http2
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?1.7.4
What operating system and processor architecture are you using (
go env
)?Linux amd64
What did you do?
If possible, provide a recipe for reproducing the error. A complete runnable program is good. A link on play.golang.org is best.
A simple http2 client program, make get request to https://http2bin.org/get
use DumpResponse / DumpRequestOut (from net/http/httputil/) to print the Request & Response,
What did you expect to see?
http2 headers for request & response should be different with http1, should be all lower cases, in Chrome DevTool like other command line tools it's commonly shown as:
What did you see instead?
========
BTW, set
GODEBUG=http2debug=2
get following debugging logs: