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
Closed

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

bradfitz opened this issue Apr 10, 2014 · 5 comments
Milestone

Comments

@bradfitz
Copy link
Contributor

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
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
Copy link
Contributor Author

wking added a commit to ipfs/kubo that referenced this issue Jun 24, 2015
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/kubo that referenced this issue Jun 24, 2015
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/kubo that referenced this issue Jun 24, 2015
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/kubo that referenced this issue Jun 24, 2015
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
Copy link

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

@bradfitz
Copy link
Contributor Author

@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
Copy link

@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.
Projects
None yet
Development

No branches or pull requests

4 participants