forked from quic-go/quic-go
implement a basic QUIC RoundTripper
This commit is contained in:
@@ -41,6 +41,8 @@ type Client struct {
|
|||||||
responses map[protocol.StreamID]chan *http.Response
|
responses map[protocol.StreamID]chan *http.Response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ h2quicClient = &Client{}
|
||||||
|
|
||||||
// NewClient creates a new client
|
// NewClient creates a new client
|
||||||
func NewClient(hostname string) (*Client, error) {
|
func NewClient(hostname string) (*Client, error) {
|
||||||
c := &Client{
|
c := &Client{
|
||||||
|
|||||||
49
h2quic/roundtrip.go
Normal file
49
h2quic/roundtrip.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package h2quic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type h2quicClient interface {
|
||||||
|
Do(*http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuicRoundTripper implements the http.RoundTripper interface
|
||||||
|
type QuicRoundTripper struct {
|
||||||
|
mutex sync.Mutex
|
||||||
|
|
||||||
|
clients map[string]h2quicClient
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ http.RoundTripper = &QuicRoundTripper{}
|
||||||
|
|
||||||
|
// RoundTrip does a round trip
|
||||||
|
func (r *QuicRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
hostname := authorityAddr("https", hostnameFromRequest(req))
|
||||||
|
client, err := r.getClient(hostname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return client.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QuicRoundTripper) getClient(hostname string) (h2quicClient, error) {
|
||||||
|
r.mutex.Lock()
|
||||||
|
defer r.mutex.Unlock()
|
||||||
|
|
||||||
|
if r.clients == nil {
|
||||||
|
r.clients = make(map[string]h2quicClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, ok := r.clients[hostname]
|
||||||
|
if !ok {
|
||||||
|
var err error
|
||||||
|
client, err = NewClient(hostname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.clients[hostname] = client
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
36
h2quic/roundtrip_test.go
Normal file
36
h2quic/roundtrip_test.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package h2quic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockQuicRoundTripper struct{}
|
||||||
|
|
||||||
|
func (m *mockQuicRoundTripper) Do(req *http.Request) (*http.Response, error) {
|
||||||
|
return &http.Response{Request: req}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("RoundTripper", func() {
|
||||||
|
var (
|
||||||
|
rt *QuicRoundTripper
|
||||||
|
req1 *http.Request
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
rt = &QuicRoundTripper{}
|
||||||
|
var err error
|
||||||
|
req1, err = http.NewRequest("GET", "https://www.example.org/file1.html", nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("reuses existing clients", func() {
|
||||||
|
rt.clients = make(map[string]h2quicClient)
|
||||||
|
rt.clients["www.example.org:443"] = &mockQuicRoundTripper{}
|
||||||
|
rsp, _ := rt.RoundTrip(req1)
|
||||||
|
Expect(rsp.Request).To(Equal(req1))
|
||||||
|
Expect(rt.clients).To(HaveLen(1))
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user