Skip to content

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

Closed
@bradfitz

Description

@bradfitz
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()

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions