@@ -59,7 +59,12 @@ const GodotFetch = {
5959 } ) ;
6060 obj . status = response . status ;
6161 obj . response = response ;
62- obj . reader = response . body . getReader ( ) ;
62+ // `body` can be null per spec (for example, in cases where the request method is HEAD).
63+ // As of the time of writing, Chromium (127.0.6533.72) does not follow the spec but Firefox (131.0.3) does.
64+ // See godotengine/godot#76825 for more information.
65+ // See Chromium revert (of the change to follow the spec):
66+ // https://chromium.googlesource.com/chromium/src/+/135354b7bdb554cd03c913af7c90aceead03c4d4
67+ obj . reader = response . body ?. getReader ( ) ;
6368 obj . chunked = chunked ;
6469 } ,
6570
@@ -121,6 +126,10 @@ const GodotFetch = {
121126 }
122127 obj . reading = true ;
123128 obj . reader . read ( ) . then ( GodotFetch . onread . bind ( null , id ) ) . catch ( GodotFetch . onerror . bind ( null , id ) ) ;
129+ } else if ( obj . reader == null && obj . response . body == null ) {
130+ // Emulate a stream closure to maintain the request lifecycle.
131+ obj . reading = true ;
132+ GodotFetch . onread ( id , { value : undefined , done : true } ) ;
124133 }
125134 } ,
126135 } ,
@@ -159,7 +168,10 @@ const GodotFetch = {
159168 if ( ! obj . response ) {
160169 return 0 ;
161170 }
162- if ( obj . reader ) {
171+ // If the reader is nullish, but there is no body, and the request is not marked as done,
172+ // the same status should be returned as though the request is currently being read
173+ // so that the proper lifecycle closure can be handled in `read()`.
174+ if ( obj . reader || ( obj . response . body == null && ! obj . done ) ) {
163175 return 1 ;
164176 }
165177 if ( obj . done ) {
0 commit comments