Skip to content

Commit 49d237b

Browse files
gnoffztanner
authored andcommitted
[Flight][Reply] Close Response after creating root chunk (facebook#27634)
creating the root after closing the response can lead to a promise that never rejects. This is not intended use of the decodeReply API but if pathalogical cases where you pass a raw FormData into this fucntion with no zero chunk it can hang forever. This reordering causes a connection error instead --------- Co-authored-by: Zack Tanner <[email protected]>
1 parent 25bf50b commit 49d237b

File tree

8 files changed

+24
-7
lines changed

8 files changed

+24
-7
lines changed

packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ function decodeReply<T>(
162162
body = form;
163163
}
164164
const response = createResponse(moduleBasePath, '', body);
165+
const root = getRoot<T>(response);
165166
close(response);
166-
return getRoot(response);
167+
return root;
167168
}
168169

169170
export {

packages/react-server-dom-turbopack/src/ReactFlightDOMServerBrowser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ function decodeReply<T>(
9393
body = form;
9494
}
9595
const response = createResponse(turbopackMap, '', body);
96+
const root = getRoot<T>(response);
9697
close(response);
97-
return getRoot(response);
98+
return root;
9899
}
99100

100101
export {renderToReadableStream, decodeReply, decodeAction};

packages/react-server-dom-turbopack/src/ReactFlightDOMServerEdge.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ function decodeReply<T>(
9393
body = form;
9494
}
9595
const response = createResponse(turbopackMap, '', body);
96+
const root = getRoot<T>(response);
9697
close(response);
97-
return getRoot(response);
98+
return root;
9899
}
99100

100101
export {renderToReadableStream, decodeReply, decodeAction};

packages/react-server-dom-turbopack/src/ReactFlightDOMServerNode.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,9 @@ function decodeReply<T>(
158158
body = form;
159159
}
160160
const response = createResponse(turbopackMap, '', body);
161+
const root = getRoot<T>(response);
161162
close(response);
162-
return getRoot(response);
163+
return root;
163164
}
164165

165166
export {

packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ function decodeReply<T>(
100100
body = form;
101101
}
102102
const response = createResponse(webpackMap, '', body);
103+
const root = getRoot<T>(response);
103104
close(response);
104-
return getRoot(response);
105+
return root;
105106
}
106107

107108
export {renderToReadableStream, decodeReply, decodeAction, decodeFormState};

packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ function decodeReply<T>(
100100
body = form;
101101
}
102102
const response = createResponse(webpackMap, '', body);
103+
const root = getRoot<T>(response);
103104
close(response);
104-
return getRoot(response);
105+
return root;
105106
}
106107

107108
export {renderToReadableStream, decodeReply, decodeAction, decodeFormState};

packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ function decodeReply<T>(
181181
body = form;
182182
}
183183
const response = createResponse(webpackMap, '', body);
184+
const root = getRoot<T>(response);
184185
close(response);
185-
return getRoot(response);
186+
return root;
186187
}
187188

188189
export {

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,14 @@ describe('ReactFlightDOMReply', () => {
231231
expect(s2.has('hi')).toBe(true);
232232
expect(s2).toEqual(s);
233233
});
234+
235+
it('does not hang indefinitely when calling decodeReply with FormData', async () => {
236+
let error;
237+
try {
238+
await ReactServerDOMServer.decodeReply(new FormData(), webpackServerMap);
239+
} catch (e) {
240+
error = e;
241+
}
242+
expect(error.message).toBe('Connection closed.');
243+
});
234244
});

0 commit comments

Comments
 (0)