Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: no way for Server to set Trailer headers #7759

Closed
bradfitz opened this Issue Apr 10, 2014 · 5 comments

Comments

Projects
None yet
4 participants
@bradfitz
Copy link
Member

bradfitz commented Apr 10, 2014

There's no way for Server handlers to set Trailer headers.

From a test I just wrote, with a work-around and TODO for Go 1.4:

        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                w.Header().Set("Connection", "close")
                w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
                w.Header().Add("Trailer", "Server-Trailer-C")

                var decl []string
                for k := range r.Trailer {
                        decl = append(decl, k)
                }
                sort.Strings(decl)

                slurp, err := ioutil.ReadAll(r.Body)
                if err != nil {
                        t.Errorf("Server reading request body: %v", err)
                }
                if string(slurp) != "foo" {
                        t.Errorf("Server read request body %q; want foo", slurp)
                }
                if r.Trailer == nil {
                        io.WriteString(w, "nil Trailer")
                } else {
                        fmt.Fprintf(w, "decl: %v, vals: %s, %s",
                                decl,
                                r.Trailer.Get("Client-Trailer-A"),
                                r.Trailer.Get("Client-Trailer-B"))
                }

                // TODO: There's no way yet for the server to set trailers
                // without hijacking, so do that for now, just to test the client.
                // Later, in Go 1.4, it should be be implicit that any mutations
                // to w.Header() after the initial write are the trailers to be
                // sent, if and only if they were previously declared with
                // w.Header().Set("Trailer", ..keys..)
                w.(Flusher).Flush()
                conn, buf, _ := w.(Hijacker).Hijack()
                t := Header{}
                t.Set("Server-Trailer-A", "valuea")
                t.Set("Server-Trailer-C", "valuec") // skipping B
                buf.WriteString("0\r\n")            // eof
                t.Write(buf)
                buf.WriteString("\r\n") // end of trailers
                buf.Flush()
                conn.Close()
@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Sep 16, 2014

Comment 1:

Probably too late.

Labels changed: added release-go1.5, removed release-go1.4.

@bradfitz bradfitz self-assigned this Sep 16, 2014

@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014

@bradfitz bradfitz removed the release-go1.5 label Dec 16, 2014

@bradfitz

This comment has been minimized.

Copy link
Member Author

bradfitz commented Dec 30, 2014

@bradfitz bradfitz closed this in 4b96409 Dec 30, 2014

wking added a commit to ipfs/go-ipfs that referenced this issue Jun 24, 2015

commands/http/handler: Write a trailer with any error messages
For streaming responses (e.g. 'ipfs add -r /path/to/root/directory'),
we may hit errors later on in the stream, after we've already written
the initial 200 response and started in on the streaming body
(e.g. /path/to/root/directory/a/b/c is an unsupported file type).  We
should check for that sort of error, and set a trailer [1] if there
were any errors.  Unfortunately, it's a bit awkward to set these
headers in Go 1.4 and earlier [2], but [2] does have a workaround for
Go 1.4 (it's not clear if the workaround is compatible with Go 1.3).

[1]: http://tools.ietf.org/html/rfc2616#section-14.40
[2]: golang/go#7759

License: MIT
Signed-off-by: W. Trevor King <wking@tremily.us>

wking added a commit to ipfs/go-ipfs that referenced this issue Jun 24, 2015

commands/http/handler: Write a trailer with any error messages
For streaming responses (e.g. 'ipfs add -r /path/to/root/directory'),
we may hit errors later on in the stream, after we've already written
the initial 200 response and started in on the streaming body
(e.g. /path/to/root/directory/a/b/c is an unsupported file type).  We
should check for that sort of error, and set a trailer [1] if there
were any errors.  Unfortunately, it's a bit awkward to set these
headers in Go 1.4 and earlier [2], but [2] does have a workaround for
Go 1.4 (it's not clear if the workaround is compatible with Go 1.3).

[1]: http://tools.ietf.org/html/rfc2616#section-14.40
[2]: golang/go#7759

License: MIT
Signed-off-by: W. Trevor King <wking@tremily.us>

wking added a commit to ipfs/go-ipfs that referenced this issue Jun 24, 2015

commands/http/handler: Write a trailer with any error messages
For streaming responses (e.g. 'ipfs add -r /path/to/root/directory'),
we may hit errors later on in the stream, after we've already written
the initial 200 response and started in on the streaming body
(e.g. /path/to/root/directory/a/b/c is an unsupported file type).  We
should check for that sort of error, and set a trailer [1] if there
were any errors.  Unfortunately, it's a bit awkward to set these
headers in Go 1.4 and earlier [2], but [2] does have a workaround for
Go 1.4 (it's not clear if the workaround is compatible with Go 1.3).

[1]: http://tools.ietf.org/html/rfc2616#section-14.40
[2]: golang/go#7759

License: MIT
Signed-off-by: W. Trevor King <wking@tremily.us>

wking added a commit to ipfs/go-ipfs that referenced this issue Jun 24, 2015

commands/http/handler: Write a trailer with any error messages
For streaming responses (e.g. 'ipfs add -r /path/to/root/directory'),
we may hit errors later on in the stream, after we've already written
the initial 200 response and started in on the streaming body
(e.g. /path/to/root/directory/a/b/c is an unsupported file type).  We
should check for that sort of error, and set a trailer [1] if there
were any errors.  Unfortunately, it's a bit awkward to set these
headers in Go 1.4 and earlier [2], but [2] does have a workaround for
Go 1.4 (it's not clear if the workaround is compatible with Go 1.3).

[1]: http://tools.ietf.org/html/rfc2616#section-14.40
[2]: golang/go#7759

License: MIT
Signed-off-by: W. Trevor King <wking@tremily.us>
@drcrallen

This comment has been minimized.

Copy link

drcrallen commented Aug 30, 2015

Does this mean the example at http://golang.org/pkg/net/http/#example_ResponseWriter_trailers does not actually work?

@bradfitz

This comment has been minimized.

Copy link
Member Author

bradfitz commented Aug 30, 2015

@drcrallen, what gives you that impression? See the most recent comment. https://go-review.googlesource.com/2157 added support. It's in Go 1.5.

@drcrallen

This comment has been minimized.

Copy link

drcrallen commented Aug 30, 2015

@bradfitz Misreading of docs on my part. Found out I have 1.4.2 installed but was using tutorials from prior URL, which are built for go1.5 (in the page footer which I missed). My bad

@golang golang locked and limited conversation to collaborators Sep 4, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.