Hi,
We were trying to implement a reverse proxy using fasthttp library and we noticed that the client does not support reading HTTP trailers from the response.
Sample backend application
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", hello)
fmt.Println("listening...")
err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
if err != nil {
panic(err)
}
}
func hello(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Trailer", "AtEnd1, AtEnd2")
w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
w.WriteHeader(http.StatusOK)
w.Header().Set("AtEnd1", "value 1")
io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\r\n")
w.Header().Set("AtEnd2", "value 2")
}
fasthttp client
package main
import (
"fmt"
"github.com/valyala/fasthttp"
)
func main() {
req := fasthttp.AcquireRequest()
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseRequest(req)
defer fasthttp.ReleaseResponse(resp)
req.SetHost("localhost:9090")
req.Header.SetMethod("GET")
err := fasthttp.Do(req, resp)
if err != nil {
fmt.Printf("Error making HTTP request: %s\n", err.Error())
}
fmt.Printf("Response %#v", resp)
}
Is this feature anywhere in the roadmap for the project?
Regards
Shash && Edwin (@flawedmatrix)
Hello @valyala
Would you take a PR to add support for HTTP trailers?
Yes we would take PR to add support for trailers.
@shashwathi @erikdubbelboer
I saw somewhere that is not possible to write to response more than once.
You wrote the response status, than you can not write to response anymore.
I will search where I saw this.
Here is the part of spec:
type ResponseWriter interface {
// Header returns the header map that will be sent by
// WriteHeader. The Header map also is the mechanism with which
// Handlers can set HTTP trailers.
//
// Changing the header map after a call to WriteHeader (or
// Write) has no effect unless the modified headers are
// trailers.
//
// There are two ways to set Trailers. The preferred way is to
// predeclare in the headers which trailers you will later
// send by setting the "Trailer" header to the names of the
// trailer keys which will come later. In this case, those
// keys of the Header map are treated as if they were
// trailers. See the example. The second way, for trailer
// keys not known to the Handler until after the first Write,
// is to prefix the Header map keys with the TrailerPrefix
// constant value. See TrailerPrefix.
//
// To suppress automatic response headers (such as "Date"), set
// their value to nil.
Header() Header
I think this issue can be closed, because this is like golang works and was designed.
@rof20004 your links are all about net/http. fasthttp is an alternative ground-up implementation incompatible with net/http. we're interested in HTTP RFCs and can do things in ways that differ from net/http
We could also very easily implement this with a Trailer header like net/http. If anyone needs this please let me know and I'll fix it.
@erikdubbelboer we would appreciate having trailer headers to indicate errors in a streaming response
Most helpful comment
We could also very easily implement this with a
Trailerheader likenet/http. If anyone needs this please let me know and I'll fix it.