Skip to content

Commit

Permalink
Return connection: close when doing http over streams
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoPolo committed Apr 3, 2024
1 parent 86a6720 commit 5c0f551
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
10 changes: 9 additions & 1 deletion p2p/http/libp2phttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func (h *Host) Serve() error {
h.httpTransport.listenAddrs = append(h.httpTransport.listenAddrs, h.StreamHost.Addrs()...)

go func() {
errCh <- http.Serve(listener, h.ServeMux)
errCh <- http.Serve(listener, connectionCloseHeaderMiddleware(h.ServeMux))
}()
}

Expand Down Expand Up @@ -816,3 +816,11 @@ func (h *Host) RemovePeerMetadata(server peer.ID) {
}
h.peerMetadata.Remove(server)
}

func connectionCloseHeaderMiddleware(next http.Handler) http.Handler {
// Sets connection: close. It's preferable to not reuse streams for HTTP.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Connection", "close")
next.ServeHTTP(w, r)
})
}
36 changes: 36 additions & 0 deletions p2p/http/libp2phttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,42 @@ func TestHTTPOverStreams(t *testing.T) {
require.Equal(t, "hello", string(body))
}

func TestHTTPOverStreamsReturnsConnectionClose(t *testing.T) {
serverHost, err := libp2p.New(
libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"),
)
require.NoError(t, err)

httpHost := libp2phttp.Host{StreamHost: serverHost}

httpHost.SetHTTPHandlerAtPath("/hello", "/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
}))

// Start server
go httpHost.Serve()
defer httpHost.Close()

// Start client
clientHost, err := libp2p.New(libp2p.NoListenAddrs)
require.NoError(t, err)
clientHost.Connect(context.Background(), peer.AddrInfo{
ID: serverHost.ID(),
Addrs: serverHost.Addrs(),
})

s, err := clientHost.NewStream(context.Background(), serverHost.ID(), libp2phttp.ProtocolIDForMultistreamSelect)
require.NoError(t, err)
_, err = s.Write([]byte("GET / HTTP/1.1\r\nHost: \r\n\r\n"))
require.NoError(t, err)

out := make([]byte, 1024)
n, err := s.Read(out)
require.NoError(t, err)

require.Contains(t, strings.ToLower(string(out[:n])), "connection: close")
}

func TestRoundTrippers(t *testing.T) {
serverHost, err := libp2p.New(
libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"),
Expand Down

0 comments on commit 5c0f551

Please sign in to comment.