github.com/mikelsr/quic-go@v0.36.1-0.20230701132136-1d9415b66898/http3/request_writer_test.go (about) 1 package http3 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 8 mockquic "github.com/mikelsr/quic-go/internal/mocks/quic" 9 "github.com/mikelsr/quic-go/internal/utils" 10 11 "github.com/golang/mock/gomock" 12 "github.com/quic-go/qpack" 13 14 . "github.com/onsi/ginkgo/v2" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Request Writer", func() { 19 var ( 20 rw *requestWriter 21 str *mockquic.MockStream 22 strBuf *bytes.Buffer 23 ) 24 25 decode := func(str io.Reader) map[string]string { 26 frame, err := parseNextFrame(str, nil) 27 ExpectWithOffset(1, err).ToNot(HaveOccurred()) 28 ExpectWithOffset(1, frame).To(BeAssignableToTypeOf(&headersFrame{})) 29 headersFrame := frame.(*headersFrame) 30 data := make([]byte, headersFrame.Length) 31 _, err = io.ReadFull(str, data) 32 ExpectWithOffset(1, err).ToNot(HaveOccurred()) 33 decoder := qpack.NewDecoder(nil) 34 hfs, err := decoder.DecodeFull(data) 35 ExpectWithOffset(1, err).ToNot(HaveOccurred()) 36 values := make(map[string]string) 37 for _, hf := range hfs { 38 values[hf.Name] = hf.Value 39 } 40 return values 41 } 42 43 BeforeEach(func() { 44 rw = newRequestWriter(utils.DefaultLogger) 45 strBuf = &bytes.Buffer{} 46 str = mockquic.NewMockStream(mockCtrl) 47 str.EXPECT().Write(gomock.Any()).DoAndReturn(strBuf.Write).AnyTimes() 48 }) 49 50 It("writes a GET request", func() { 51 req, err := http.NewRequest(http.MethodGet, "https://quic.clemente.io/index.html?foo=bar", nil) 52 Expect(err).ToNot(HaveOccurred()) 53 Expect(rw.WriteRequestHeader(str, req, false)).To(Succeed()) 54 headerFields := decode(strBuf) 55 Expect(headerFields).To(HaveKeyWithValue(":authority", "quic.clemente.io")) 56 Expect(headerFields).To(HaveKeyWithValue(":method", "GET")) 57 Expect(headerFields).To(HaveKeyWithValue(":path", "/index.html?foo=bar")) 58 Expect(headerFields).To(HaveKeyWithValue(":scheme", "https")) 59 Expect(headerFields).ToNot(HaveKey("accept-encoding")) 60 }) 61 62 It("sends cookies", func() { 63 req, err := http.NewRequest(http.MethodGet, "https://quic.clemente.io/", nil) 64 Expect(err).ToNot(HaveOccurred()) 65 cookie1 := &http.Cookie{ 66 Name: "Cookie #1", 67 Value: "Value #1", 68 } 69 cookie2 := &http.Cookie{ 70 Name: "Cookie #2", 71 Value: "Value #2", 72 } 73 req.AddCookie(cookie1) 74 req.AddCookie(cookie2) 75 Expect(rw.WriteRequestHeader(str, req, false)).To(Succeed()) 76 headerFields := decode(strBuf) 77 Expect(headerFields).To(HaveKeyWithValue("cookie", `Cookie #1="Value #1"; Cookie #2="Value #2"`)) 78 }) 79 80 It("adds the header for gzip support", func() { 81 req, err := http.NewRequest(http.MethodGet, "https://quic.clemente.io/", nil) 82 Expect(err).ToNot(HaveOccurred()) 83 Expect(rw.WriteRequestHeader(str, req, true)).To(Succeed()) 84 headerFields := decode(strBuf) 85 Expect(headerFields).To(HaveKeyWithValue("accept-encoding", "gzip")) 86 }) 87 88 It("writes a CONNECT request", func() { 89 req, err := http.NewRequest(http.MethodConnect, "https://quic.clemente.io/", nil) 90 Expect(err).ToNot(HaveOccurred()) 91 Expect(rw.WriteRequestHeader(str, req, false)).To(Succeed()) 92 headerFields := decode(strBuf) 93 Expect(headerFields).To(HaveKeyWithValue(":method", "CONNECT")) 94 Expect(headerFields).To(HaveKeyWithValue(":authority", "quic.clemente.io")) 95 Expect(headerFields).ToNot(HaveKey(":path")) 96 Expect(headerFields).ToNot(HaveKey(":scheme")) 97 Expect(headerFields).ToNot(HaveKey(":protocol")) 98 }) 99 100 It("writes an Extended CONNECT request", func() { 101 req, err := http.NewRequest(http.MethodConnect, "https://quic.clemente.io/foobar", nil) 102 Expect(err).ToNot(HaveOccurred()) 103 req.Proto = "webtransport" 104 Expect(rw.WriteRequestHeader(str, req, false)).To(Succeed()) 105 headerFields := decode(strBuf) 106 Expect(headerFields).To(HaveKeyWithValue(":authority", "quic.clemente.io")) 107 Expect(headerFields).To(HaveKeyWithValue(":method", "CONNECT")) 108 Expect(headerFields).To(HaveKeyWithValue(":path", "/foobar")) 109 Expect(headerFields).To(HaveKeyWithValue(":scheme", "https")) 110 Expect(headerFields).To(HaveKeyWithValue(":protocol", "webtransport")) 111 }) 112 })