sneako / finch

Elixir HTTP client, focused on performance
MIT License
1.26k stars 118 forks source link

Split trailers from headers #242

Closed wojtekmach closed 1 year ago

wojtekmach commented 1 year ago

Ref https://github.com/wojtekmach/req/issues/230#issue-1869352131

I couldn't write an integration test for http2 given Plug has no support for trailers and it is not easy to write a fake server.

I verified it manually:

$ openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
$ cat main.go
package main

import (
  "log"
  "net/http"
)

func main() {
  srv := &http.Server{Addr: ":8080", Handler: http.HandlerFunc(handle)}
  log.Printf("Serving on https://0.0.0.0:8080")
  log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key"))
}

func handle(w http.ResponseWriter, r *http.Request) {
  log.Printf("Got connection: %s", r.Proto)
  w.Header().Set("trailer", "x-foo")
  w.Write([]byte("Hello"))
  w.Header().Set("x-foo", "bar")
}
$ cat run.exs
{:ok, _} =
  Finch.start_link(
    name: MyFinch,
    pools: %{
      default: [
        protocol: :http2,
        conn_opts: [
          transport_opts: [verify: :verify_none]
        ]
      ]
    }
  )

req = Finch.build(:get, "https://localhost:8080")
IO.inspect(Finch.request(req, MyFinch))
$ go run main.go
$ mix run run.exs
{:ok,
 %Finch.Response{
   status: 200,
   body: "Hello",
   headers: [
     {"trailer", "x-foo"},
     {"content-type", "text/plain; charset=utf-8"},
     {"content-length", "5"},
     {"date", "Tue, 29 Aug 2023 09:37:39 GMT"}
   ],
   trailers: [{"x-foo", "bar"}]
 }}