11package fasthttpadaptor
22
33import (
4+ "bytes"
5+ "errors"
6+ "io"
47 "net/http"
8+ "net/url"
59 "testing"
610
711 "github.com/valyala/fasthttp"
@@ -27,3 +31,251 @@ func BenchmarkConvertRequest(b *testing.B) {
2731 _ = ConvertRequest (ctx , & httpReq , true )
2832 }
2933}
34+
35+ func BenchmarkConvertNetHttpRequestToFastHttpRequest (b * testing.B ) {
36+ var httpReq http.Request = http.Request {
37+ Method : "GET" ,
38+ RequestURI : "/test" ,
39+ Host : "test" ,
40+ Header : http.Header {
41+ "X" : []string {"test" },
42+ "Y" : []string {"test" },
43+ },
44+ }
45+
46+ ctx := & fasthttp.RequestCtx {}
47+
48+ b .ResetTimer ()
49+ for i := 0 ; i < b .N ; i ++ {
50+ _ = ConvertNetHttpRequestToFastHttpRequest (& httpReq , ctx )
51+ }
52+ }
53+
54+ // errReader is a reader that always returns an error.
55+ type errReader struct {}
56+
57+ func (errReader ) Read ([]byte ) (int , error ) {
58+ return 0 , errors .New ("read error" )
59+ }
60+
61+ func TestConvertNetHttpRequestToFastHttpRequest (t * testing.T ) {
62+ t .Parallel ()
63+
64+ t .Run ("basic conversion" , func (t * testing.T ) {
65+ t .Parallel ()
66+ httpReq := & http.Request {
67+ Method : "POST" ,
68+ RequestURI : "/test/path?query=1" ,
69+ Proto : "HTTP/1.1" ,
70+ Host : "example.com" ,
71+ Header : http.Header {},
72+ }
73+
74+ ctx := & fasthttp.RequestCtx {}
75+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
76+ if err != nil {
77+ t .Fatalf ("unexpected error: %v" , err )
78+ }
79+
80+ if string (ctx .Method ()) != "POST" {
81+ t .Errorf ("expected method POST, got %s" , ctx .Method ())
82+ }
83+ if string (ctx .RequestURI ()) != "/test/path?query=1" {
84+ t .Errorf ("expected URI /test/path?query=1, got %s" , ctx .RequestURI ())
85+ }
86+ if string (ctx .Request .Header .Protocol ()) != "HTTP/1.1" {
87+ t .Errorf ("expected protocol HTTP/1.1, got %s" , ctx .Request .Header .Protocol ())
88+ }
89+ if string (ctx .Host ()) != "example.com" {
90+ t .Errorf ("expected host example.com, got %s" , ctx .Host ())
91+ }
92+ })
93+
94+ t .Run ("URL fallback when RequestURI is empty" , func (t * testing.T ) {
95+ t .Parallel ()
96+ httpReq := & http.Request {
97+ Method : "GET" ,
98+ RequestURI : "" ,
99+ URL : & url.URL {
100+ Path : "/fallback/path" ,
101+ RawQuery : "foo=bar" ,
102+ },
103+ Proto : "HTTP/1.1" ,
104+ Host : "fallback.com" ,
105+ Header : http.Header {},
106+ }
107+
108+ ctx := & fasthttp.RequestCtx {}
109+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
110+ if err != nil {
111+ t .Fatalf ("unexpected error: %v" , err )
112+ }
113+
114+ if string (ctx .RequestURI ()) != "/fallback/path?foo=bar" {
115+ t .Errorf ("expected URI /fallback/path?foo=bar, got %s" , ctx .RequestURI ())
116+ }
117+ })
118+
119+ t .Run ("single header" , func (t * testing.T ) {
120+ t .Parallel ()
121+ httpReq := & http.Request {
122+ Method : "GET" ,
123+ RequestURI : "/" ,
124+ Proto : "HTTP/1.1" ,
125+ Host : "example.com" ,
126+ Header : http.Header {
127+ "X-Custom-Header" : []string {"custom-value" },
128+ },
129+ }
130+
131+ ctx := & fasthttp.RequestCtx {}
132+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
133+ if err != nil {
134+ t .Fatalf ("unexpected error: %v" , err )
135+ }
136+
137+ if string (ctx .Request .Header .Peek ("X-Custom-Header" )) != "custom-value" {
138+ t .Errorf ("expected header value custom-value, got %s" , ctx .Request .Header .Peek ("X-Custom-Header" ))
139+ }
140+ })
141+
142+ t .Run ("multiple header values" , func (t * testing.T ) {
143+ t .Parallel ()
144+ httpReq := & http.Request {
145+ Method : "GET" ,
146+ RequestURI : "/" ,
147+ Proto : "HTTP/1.1" ,
148+ Host : "example.com" ,
149+ Header : http.Header {
150+ "Accept" : []string {"text/html" , "application/json" , "text/plain" },
151+ },
152+ }
153+
154+ ctx := & fasthttp.RequestCtx {}
155+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
156+ if err != nil {
157+ t .Fatalf ("unexpected error: %v" , err )
158+ }
159+
160+ // Check all header values are present
161+ var values []string
162+ ctx .Request .Header .VisitAll (func (key , value []byte ) {
163+ if string (key ) == "Accept" {
164+ values = append (values , string (value ))
165+ }
166+ })
167+
168+ if len (values ) != 3 {
169+ t .Errorf ("expected 3 Accept header values, got %d" , len (values ))
170+ }
171+ })
172+
173+ t .Run ("request body" , func (t * testing.T ) {
174+ t .Parallel ()
175+ bodyContent := []byte ("test body content" )
176+ httpReq := & http.Request {
177+ Method : "POST" ,
178+ RequestURI : "/" ,
179+ Proto : "HTTP/1.1" ,
180+ Host : "example.com" ,
181+ Header : http.Header {},
182+ Body : io .NopCloser (bytes .NewReader (bodyContent )),
183+ }
184+
185+ ctx := & fasthttp.RequestCtx {}
186+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
187+ if err != nil {
188+ t .Fatalf ("unexpected error: %v" , err )
189+ }
190+
191+ if ! bytes .Equal (ctx .Request .Body (), bodyContent ) {
192+ t .Errorf ("expected body %q, got %q" , bodyContent , ctx .Request .Body ())
193+ }
194+ })
195+
196+ t .Run ("nil body" , func (t * testing.T ) {
197+ t .Parallel ()
198+ httpReq := & http.Request {
199+ Method : "GET" ,
200+ RequestURI : "/" ,
201+ Proto : "HTTP/1.1" ,
202+ Host : "example.com" ,
203+ Header : http.Header {},
204+ Body : nil ,
205+ }
206+
207+ ctx := & fasthttp.RequestCtx {}
208+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
209+ if err != nil {
210+ t .Fatalf ("unexpected error: %v" , err )
211+ }
212+
213+ if len (ctx .Request .Body ()) != 0 {
214+ t .Errorf ("expected empty body, got %q" , ctx .Request .Body ())
215+ }
216+ })
217+
218+ t .Run ("remote address with port" , func (t * testing.T ) {
219+ t .Parallel ()
220+ httpReq := & http.Request {
221+ Method : "GET" ,
222+ RequestURI : "/" ,
223+ Proto : "HTTP/1.1" ,
224+ Host : "example.com" ,
225+ Header : http.Header {},
226+ RemoteAddr : "192.168.1.100:8080" ,
227+ }
228+
229+ ctx := & fasthttp.RequestCtx {}
230+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
231+ if err != nil {
232+ t .Fatalf ("unexpected error: %v" , err )
233+ }
234+
235+ remoteAddr := ctx .RemoteAddr ().String ()
236+ if remoteAddr != "192.168.1.100:8080" {
237+ t .Errorf ("expected remote addr 192.168.1.100:8080, got %s" , remoteAddr )
238+ }
239+ })
240+
241+ t .Run ("remote address without port" , func (t * testing.T ) {
242+ t .Parallel ()
243+ httpReq := & http.Request {
244+ Method : "GET" ,
245+ RequestURI : "/" ,
246+ Proto : "HTTP/1.1" ,
247+ Host : "example.com" ,
248+ Header : http.Header {},
249+ RemoteAddr : "192.168.1.100" ,
250+ }
251+
252+ ctx := & fasthttp.RequestCtx {}
253+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
254+ if err != nil {
255+ t .Fatalf ("unexpected error: %v" , err )
256+ }
257+
258+ remoteAddr := ctx .RemoteAddr ().String ()
259+ if remoteAddr != "192.168.1.100:0" {
260+ t .Errorf ("expected remote addr 192.168.1.100:0, got %s" , remoteAddr )
261+ }
262+ })
263+
264+ t .Run ("body read error" , func (t * testing.T ) {
265+ t .Parallel ()
266+ httpReq := & http.Request {
267+ Method : "POST" ,
268+ RequestURI : "/" ,
269+ Proto : "HTTP/1.1" ,
270+ Host : "example.com" ,
271+ Header : http.Header {},
272+ Body : io .NopCloser (errReader {}),
273+ }
274+
275+ ctx := & fasthttp.RequestCtx {}
276+ err := ConvertNetHttpRequestToFastHttpRequest (httpReq , ctx )
277+ if err == nil {
278+ t .Fatal ("expected error, got nil" )
279+ }
280+ })
281+ }
0 commit comments