Skip to content

Commit 9381f18

Browse files
authored
fix(dart_frog): revert Expando perf optimization (#1908)
1 parent 713e801 commit 9381f18

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

packages/dart_frog/lib/src/request.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class Request {
110110

111111
Request._(this._request);
112112

113-
final shelf.Request _request;
113+
shelf.Request _request;
114114

115115
/// Connection information for the associated HTTP request.
116116
HttpConnectionInfo get connectionInfo {
@@ -146,12 +146,16 @@ class Request {
146146

147147
/// Returns a [Future] containing the body as a [String].
148148
Future<String> body() async {
149-
final bodyFromCache = _requestBodyCache[_request];
150-
if (bodyFromCache != null) return bodyFromCache;
149+
const requestBodyKey = 'dart_frog.request.body';
150+
final bodyFromContext =
151+
_request.context[requestBodyKey] as Completer<String>?;
152+
if (bodyFromContext != null) return bodyFromContext.future;
151153

152154
final completer = Completer<String>();
153155
try {
154-
_requestBodyCache[_request] = completer.future;
156+
_request = _request.change(
157+
context: {..._request.context, requestBodyKey: completer},
158+
);
155159
completer.complete(await _request.readAsString());
156160
} catch (error, stackTrace) {
157161
completer.completeError(error, stackTrace);
@@ -180,5 +184,3 @@ class Request {
180184
return Request._(_request.change(headers: headers, path: path, body: body));
181185
}
182186
}
183-
184-
final _requestBodyCache = Expando<Future<String>>('dart_frog.request.body');

packages/dart_frog/test/src/serve_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,40 @@ void main() {
2727
await server.close();
2828
});
2929

30+
test('can read request.body across middleware:handler gap', () async {
31+
Middleware middleware() {
32+
return (handler) {
33+
return (context) async {
34+
await context.request.body(); // Read #1
35+
return handler(context);
36+
};
37+
};
38+
}
39+
40+
Handler handler() {
41+
return (context) async {
42+
await context.request.body(); // Read #2
43+
return Response();
44+
};
45+
}
46+
47+
const address = 'localhost';
48+
const port = 3002;
49+
final pipeline = const Pipeline().addMiddleware(middleware());
50+
final router = Router()..mount('/', handler());
51+
final server = await serve(
52+
pipeline.addHandler(router.call),
53+
address,
54+
port,
55+
);
56+
final client = HttpClient();
57+
final request = await client.getUrl(Uri.parse('http://$address:$port'));
58+
final response = await request.close();
59+
expect(response.statusCode, equals(HttpStatus.ok));
60+
client.close();
61+
await server.close();
62+
});
63+
3064
test('exposes connectionInfo on the incoming request', () async {
3165
late HttpConnectionInfo connectionInfo;
3266
final server = await serve(

0 commit comments

Comments
 (0)