@@ -2233,25 +2233,25 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
2233
2233
func (sc * serverConn ) newWriterAndRequest (st * stream , f * MetaHeadersFrame ) (* responseWriter , * http.Request , error ) {
2234
2234
sc .serveG .check ()
2235
2235
2236
- rp := requestParam {
2237
- method : f .PseudoValue ("method" ),
2238
- scheme : f .PseudoValue ("scheme" ),
2239
- authority : f .PseudoValue ("authority" ),
2240
- path : f .PseudoValue ("path" ),
2241
- protocol : f .PseudoValue ("protocol" ),
2236
+ rp := httpcommon. ServerRequestParam {
2237
+ Method : f .PseudoValue ("method" ),
2238
+ Scheme : f .PseudoValue ("scheme" ),
2239
+ Authority : f .PseudoValue ("authority" ),
2240
+ Path : f .PseudoValue ("path" ),
2241
+ Protocol : f .PseudoValue ("protocol" ),
2242
2242
}
2243
2243
2244
2244
// extended connect is disabled, so we should not see :protocol
2245
- if disableExtendedConnectProtocol && rp .protocol != "" {
2245
+ if disableExtendedConnectProtocol && rp .Protocol != "" {
2246
2246
return nil , nil , sc .countError ("bad_connect" , streamError (f .StreamID , ErrCodeProtocol ))
2247
2247
}
2248
2248
2249
- isConnect := rp .method == "CONNECT"
2249
+ isConnect := rp .Method == "CONNECT"
2250
2250
if isConnect {
2251
- if rp .protocol == "" && (rp .path != "" || rp .scheme != "" || rp .authority == "" ) {
2251
+ if rp .Protocol == "" && (rp .Path != "" || rp .Scheme != "" || rp .Authority == "" ) {
2252
2252
return nil , nil , sc .countError ("bad_connect" , streamError (f .StreamID , ErrCodeProtocol ))
2253
2253
}
2254
- } else if rp .method == "" || rp .path == "" || (rp .scheme != "https" && rp .scheme != "http" ) {
2254
+ } else if rp .Method == "" || rp .Path == "" || (rp .Scheme != "https" && rp .Scheme != "http" ) {
2255
2255
// See 8.1.2.6 Malformed Requests and Responses:
2256
2256
//
2257
2257
// Malformed requests or responses that are detected
@@ -2265,15 +2265,16 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
2265
2265
return nil , nil , sc .countError ("bad_path_method" , streamError (f .StreamID , ErrCodeProtocol ))
2266
2266
}
2267
2267
2268
- rp .header = make (http.Header )
2268
+ header := make (http.Header )
2269
+ rp .Header = header
2269
2270
for _ , hf := range f .RegularFields () {
2270
- rp . header .Add (sc .canonicalHeader (hf .Name ), hf .Value )
2271
+ header .Add (sc .canonicalHeader (hf .Name ), hf .Value )
2271
2272
}
2272
- if rp .authority == "" {
2273
- rp .authority = rp . header .Get ("Host" )
2273
+ if rp .Authority == "" {
2274
+ rp .Authority = header .Get ("Host" )
2274
2275
}
2275
- if rp .protocol != "" {
2276
- rp . header .Set (":protocol" , rp .protocol )
2276
+ if rp .Protocol != "" {
2277
+ header .Set (":protocol" , rp .Protocol )
2277
2278
}
2278
2279
2279
2280
rw , req , err := sc .newWriterAndRequestNoBody (st , rp )
@@ -2282,7 +2283,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
2282
2283
}
2283
2284
bodyOpen := ! f .StreamEnded ()
2284
2285
if bodyOpen {
2285
- if vv , ok := rp .header ["Content-Length" ]; ok {
2286
+ if vv , ok := rp .Header ["Content-Length" ]; ok {
2286
2287
if cl , err := strconv .ParseUint (vv [0 ], 10 , 63 ); err == nil {
2287
2288
req .ContentLength = int64 (cl )
2288
2289
} else {
@@ -2298,84 +2299,38 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
2298
2299
return rw , req , nil
2299
2300
}
2300
2301
2301
- type requestParam struct {
2302
- method string
2303
- scheme , authority , path string
2304
- protocol string
2305
- header http.Header
2306
- }
2307
-
2308
- func (sc * serverConn ) newWriterAndRequestNoBody (st * stream , rp requestParam ) (* responseWriter , * http.Request , error ) {
2302
+ func (sc * serverConn ) newWriterAndRequestNoBody (st * stream , rp httpcommon.ServerRequestParam ) (* responseWriter , * http.Request , error ) {
2309
2303
sc .serveG .check ()
2310
2304
2311
2305
var tlsState * tls.ConnectionState // nil if not scheme https
2312
- if rp .scheme == "https" {
2306
+ if rp .Scheme == "https" {
2313
2307
tlsState = sc .tlsState
2314
2308
}
2315
2309
2316
- needsContinue := httpguts .HeaderValuesContainsToken (rp .header ["Expect" ], "100-continue" )
2317
- if needsContinue {
2318
- rp .header .Del ("Expect" )
2319
- }
2320
- // Merge Cookie headers into one "; "-delimited value.
2321
- if cookies := rp .header ["Cookie" ]; len (cookies ) > 1 {
2322
- rp .header .Set ("Cookie" , strings .Join (cookies , "; " ))
2323
- }
2324
-
2325
- // Setup Trailers
2326
- var trailer http.Header
2327
- for _ , v := range rp .header ["Trailer" ] {
2328
- for _ , key := range strings .Split (v , "," ) {
2329
- key = http .CanonicalHeaderKey (textproto .TrimString (key ))
2330
- switch key {
2331
- case "Transfer-Encoding" , "Trailer" , "Content-Length" :
2332
- // Bogus. (copy of http1 rules)
2333
- // Ignore.
2334
- default :
2335
- if trailer == nil {
2336
- trailer = make (http.Header )
2337
- }
2338
- trailer [key ] = nil
2339
- }
2340
- }
2341
- }
2342
- delete (rp .header , "Trailer" )
2343
-
2344
- var url_ * url.URL
2345
- var requestURI string
2346
- if rp .method == "CONNECT" && rp .protocol == "" {
2347
- url_ = & url.URL {Host : rp .authority }
2348
- requestURI = rp .authority // mimic HTTP/1 server behavior
2349
- } else {
2350
- var err error
2351
- url_ , err = url .ParseRequestURI (rp .path )
2352
- if err != nil {
2353
- return nil , nil , sc .countError ("bad_path" , streamError (st .id , ErrCodeProtocol ))
2354
- }
2355
- requestURI = rp .path
2310
+ res := httpcommon .NewServerRequest (rp )
2311
+ if res .InvalidReason != "" {
2312
+ return nil , nil , sc .countError (res .InvalidReason , streamError (st .id , ErrCodeProtocol ))
2356
2313
}
2357
2314
2358
2315
body := & requestBody {
2359
2316
conn : sc ,
2360
2317
stream : st ,
2361
- needsContinue : needsContinue ,
2318
+ needsContinue : res . NeedsContinue ,
2362
2319
}
2363
- req := & http.Request {
2364
- Method : rp .method ,
2365
- URL : url_ ,
2320
+ req := ( & http.Request {
2321
+ Method : rp .Method ,
2322
+ URL : res . URL ,
2366
2323
RemoteAddr : sc .remoteAddrStr ,
2367
- Header : rp .header ,
2368
- RequestURI : requestURI ,
2324
+ Header : rp .Header ,
2325
+ RequestURI : res . RequestURI ,
2369
2326
Proto : "HTTP/2.0" ,
2370
2327
ProtoMajor : 2 ,
2371
2328
ProtoMinor : 0 ,
2372
2329
TLS : tlsState ,
2373
- Host : rp .authority ,
2330
+ Host : rp .Authority ,
2374
2331
Body : body ,
2375
- Trailer : trailer ,
2376
- }
2377
- req = req .WithContext (st .ctx )
2378
-
2332
+ Trailer : res .Trailer ,
2333
+ }).WithContext (st .ctx )
2379
2334
rw := sc .newResponseWriter (st , req )
2380
2335
return rw , req , nil
2381
2336
}
@@ -3270,12 +3225,12 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
3270
3225
// we start in "half closed (remote)" for simplicity.
3271
3226
// See further comments at the definition of stateHalfClosedRemote.
3272
3227
promised := sc .newStream (promisedID , msg .parent .id , stateHalfClosedRemote )
3273
- rw , req , err := sc .newWriterAndRequestNoBody (promised , requestParam {
3274
- method : msg .method ,
3275
- scheme : msg .url .Scheme ,
3276
- authority : msg .url .Host ,
3277
- path : msg .url .RequestURI (),
3278
- header : cloneHeader (msg .header ), // clone since handler runs concurrently with writing the PUSH_PROMISE
3228
+ rw , req , err := sc .newWriterAndRequestNoBody (promised , httpcommon. ServerRequestParam {
3229
+ Method : msg .method ,
3230
+ Scheme : msg .url .Scheme ,
3231
+ Authority : msg .url .Host ,
3232
+ Path : msg .url .RequestURI (),
3233
+ Header : cloneHeader (msg .header ), // clone since handler runs concurrently with writing the PUSH_PROMISE
3279
3234
})
3280
3235
if err != nil {
3281
3236
// Should not happen, since we've already validated msg.url.
0 commit comments