@@ -25,9 +25,6 @@ pub struct RequestInit {
2525 signal : Option < JsObject > ,
2626}
2727
28- #[ derive( Clone , Copy ) ]
29- struct HasBody ;
30-
3128impl RequestInit {
3229 /// Takes the abort signal from the options, if present.
3330 pub fn take_signal ( & mut self ) -> Option < JsObject > {
@@ -45,13 +42,15 @@ impl RequestInit {
4542 ) -> JsResult < HttpRequest < Vec < u8 > > > {
4643 let mut builder = HttpRequest :: builder ( ) ;
4744 let mut is_get_or_head_method = true ;
48- let mut has_inherited_body = false ;
49- let mut request_body = Vec :: new ( ) ;
45+ let mut inherited_is_get_or_head_method = true ;
46+ let mut inherited_body = None ;
47+ let mut request_body: Option < Vec < u8 > > = None ;
5048 if let Some ( r) = request {
5149 let ( parts, body) = r. into_parts ( ) ;
5250 is_get_or_head_method = matches ! ( parts. method, http:: Method :: GET | http:: Method :: HEAD ) ;
51+ inherited_is_get_or_head_method = is_get_or_head_method;
5352 // https://fetch.spec.whatwg.org/#dom-request - "Let inputBody be input's request's body if input is a Request object; otherwise null."
54- has_inherited_body = parts . extensions . get :: < HasBody > ( ) . is_some ( ) || ! body. is_empty ( ) ;
53+ inherited_body = Some ( body) ;
5554 builder = builder
5655 . method ( parts. method )
5756 . uri ( parts. uri )
@@ -60,7 +59,6 @@ impl RequestInit {
6059 for ( key, value) in & parts. headers {
6160 builder = builder. header ( key, value) ;
6261 }
63- request_body = body;
6462 }
6563
6664 if let Some ( headers) = self . headers . take ( ) {
@@ -78,8 +76,16 @@ impl RequestInit {
7876 builder = builder. method ( method. as_str ( ) ) ;
7977 }
8078
81- // https://fetch.spec.whatwg.org/#dom-request - "If either init["body"] exists and is non-null or inputBody is non-null, and request's method is GET or HEAD, then throw a TypeError."
82- if is_get_or_head_method && ( self . body . is_some ( ) || has_inherited_body) {
79+ // Fetch Standard §5.4 Request constructor:
80+ // If either init["body"] exists and is non-null or inputBody is non-null,
81+ // and request's method is GET or HEAD, then throw a TypeError.
82+ // https://fetch.spec.whatwg.org/#dom-request
83+ if is_get_or_head_method
84+ && ( self . body . is_some ( )
85+ || inherited_body
86+ . as_ref ( )
87+ . is_some_and ( |body| !body. is_empty ( ) || !inherited_is_get_or_head_method) )
88+ {
8389 return Err ( js_error ! ( TypeError : "Request with GET/HEAD method cannot have body." ) ) ;
8490 }
8591
@@ -89,20 +95,19 @@ impl RequestInit {
8995 let body = body. to_std_string ( ) . map_err (
9096 |_| js_error ! ( TypeError : "Request constructor: body is not a valid string" ) ,
9197 ) ?;
92- request_body = body. into_bytes ( ) ;
98+ request_body = Some ( body. into_bytes ( ) ) ;
9399 } else {
94100 return Err (
95101 js_error ! ( TypeError : "Request constructor: body is not a supported type" ) ,
96102 ) ;
97103 }
104+ } else if let Some ( body) = inherited_body {
105+ request_body = Some ( body) ;
98106 }
99107
100- let mut request = builder
101- . body ( request_body)
108+ let request = builder
109+ . body ( request_body. unwrap_or_default ( ) )
102110 . map_err ( |_| js_error ! ( Error : "Cannot construct request" ) ) ?;
103- if self . body . is_some ( ) || has_inherited_body {
104- request. extensions_mut ( ) . insert ( HasBody ) ;
105- }
106111 Ok ( request)
107112 }
108113}
0 commit comments