From e1beabaa259fa0b71fb05d59dda8f2fe9843a8a1 Mon Sep 17 00:00:00 2001 From: Alex James Date: Wed, 16 Aug 2023 16:22:52 +0100 Subject: [PATCH 1/6] Add response status code test --- .../lib/http_client_conformance_tests.dart | 1 + .../lib/src/response_status_line_server.dart | 36 +++++++++++++++++++ .../src/response_status_line_server_vm.dart | 12 +++++++ .../src/response_status_line_server_web.dart | 10 ++++++ .../lib/src/response_status_line_tests.dart | 33 +++++++++++++++++ pkgs/java_http/test/java_client_test.dart | 1 + 6 files changed, 93 insertions(+) create mode 100644 pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart create mode 100644 pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart create mode 100644 pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart create mode 100644 pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart diff --git a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart index 3500bf8df2..5a0a7c1df6 100644 --- a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart @@ -29,6 +29,7 @@ export 'src/request_headers_tests.dart' show testRequestHeaders; export 'src/response_body_streamed_test.dart' show testResponseBodyStreamed; export 'src/response_body_tests.dart' show testResponseBody; export 'src/response_headers_tests.dart' show testResponseHeaders; +export 'src/response_status_line_tests.dart' show testResponseStatusLine; export 'src/server_errors_test.dart' show testServerErrors; /// Runs the entire test suite against the given [Client]. diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart new file mode 100644 index 0000000000..9b6c570840 --- /dev/null +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:io'; + +import 'package:stream_channel/stream_channel.dart'; + +/// Starts an HTTP server that returns custom headers. +/// +/// Channel protocol: +/// On Startup: +/// - send port +/// On Request Received: +/// - load response header map from channel +/// - exit +void hybridMain(StreamChannel channel) async { + late HttpServer server; + + server = (await HttpServer.bind('localhost', 0)) + ..listen((request) async { + await request.drain(); + final socket = await request.response.detachSocket(writeHeaders: false); + + socket.writeAll([ + 'HTTP/1.1 OK', + 'Content-Length: 0', + '', // Add \r\n at the end of this header section. + ], '\r\n'); + await socket.close(); + unawaited(server.close()); + }); + + channel.sink.add(server.port); +} diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart new file mode 100644 index 0000000000..ff2ea84f02 --- /dev/null +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart @@ -0,0 +1,12 @@ +// Generated by generate_server_wrappers.dart. Do not edit. + +import 'package:stream_channel/stream_channel.dart'; + +import 'response_status_line_server.dart'; + +/// Starts the redirect test HTTP server in the same process. +Future> startServer() async { + final controller = StreamChannelController(sync: true); + hybridMain(controller.foreign); + return controller.local; +} diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart new file mode 100644 index 0000000000..f1ebbcbd3a --- /dev/null +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart @@ -0,0 +1,10 @@ +// Generated by generate_server_wrappers.dart. Do not edit. + +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +/// Starts the redirect test HTTP server out-of-process. +Future> startServer() async => spawnHybridUri(Uri( + scheme: 'package', + path: + 'http_client_conformance_tests/src/response_status_line_server.dart')); diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart new file mode 100644 index 0000000000..b3f1ec13dc --- /dev/null +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async/async.dart'; +import 'package:http/http.dart'; +import 'package:stream_channel/stream_channel.dart'; +import 'package:test/test.dart'; + +import 'response_status_line_server_vm.dart' + if (dart.library.html) 'response_status_line_server_web.dart'; + +/// Tests that the [Client] correctly processes response headers. +void testResponseStatusLine(Client client) async { + group('response status line', () { + late String host; + late StreamChannel httpServerChannel; + late StreamQueue httpServerQueue; + + setUp(() async { + httpServerChannel = await startServer(); + httpServerQueue = StreamQueue(httpServerChannel.stream); + host = 'localhost:${await httpServerQueue.next}'; + }); + + test('without status code', () async { + await expectLater( + client.get(Uri.http(host, '')), + throwsA(isA()), + ); + }); + }); +} diff --git a/pkgs/java_http/test/java_client_test.dart b/pkgs/java_http/test/java_client_test.dart index 5ad0120099..ee355dc662 100644 --- a/pkgs/java_http/test/java_client_test.dart +++ b/pkgs/java_http/test/java_client_test.dart @@ -11,6 +11,7 @@ void main() { testIsolate(JavaClient.new); testResponseBody(JavaClient(), canStreamResponseBody: false); testResponseHeaders(JavaClient()); + testResponseStatusLine(JavaClient()); testRequestBody(JavaClient()); testRequestHeaders(JavaClient()); testMultipleClients(JavaClient.new); From 73cf408e3071c40a1131b6d3eb88089fcfcddd65 Mon Sep 17 00:00:00 2001 From: Alex James Date: Mon, 21 Aug 2023 16:24:17 +0100 Subject: [PATCH 2/6] Add response status line tests to testAll --- .../lib/http_client_conformance_tests.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart index 5a0a7c1df6..3d003193e9 100644 --- a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart @@ -15,6 +15,7 @@ import 'src/request_headers_tests.dart'; import 'src/response_body_streamed_test.dart'; import 'src/response_body_tests.dart'; import 'src/response_headers_tests.dart'; +import 'src/response_status_line_tests.dart'; import 'src/server_errors_test.dart'; export 'src/close_tests.dart' show testClose; @@ -65,6 +66,7 @@ void testAll(Client Function() clientFactory, canStreamResponseBody: canStreamResponseBody); testRequestHeaders(clientFactory()); testResponseHeaders(clientFactory()); + testResponseStatusLine(clientFactory()); testRedirect(clientFactory(), redirectAlwaysAllowed: redirectAlwaysAllowed); testServerErrors(clientFactory()); testCompressedResponseBody(clientFactory()); From 4d14d9470cf60699e5d0e1c4665ef9cb6d12821d Mon Sep 17 00:00:00 2001 From: Alex James Date: Thu, 24 Aug 2023 21:29:52 +0100 Subject: [PATCH 3/6] Update copyright date --- .../lib/src/response_status_line_server.dart | 2 +- .../lib/src/response_status_line_tests.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart index 9b6c570840..2f5e44eae8 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart index b3f1ec13dc..e1bcdb46a3 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. From cf2ed369254956ec28315b1741192c6c6b453559 Mon Sep 17 00:00:00 2001 From: Alex James Date: Thu, 24 Aug 2023 21:34:41 +0100 Subject: [PATCH 4/6] Update comments --- .../lib/src/response_status_line_server.dart | 3 +-- .../lib/src/response_status_line_tests.dart | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart index 2f5e44eae8..ba81d048c7 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart @@ -7,13 +7,12 @@ import 'dart:io'; import 'package:stream_channel/stream_channel.dart'; -/// Starts an HTTP server that returns custom headers. +/// Starts an HTTP server that returns a custom status line. /// /// Channel protocol: /// On Startup: /// - send port /// On Request Received: -/// - load response header map from channel /// - exit void hybridMain(StreamChannel channel) async { late HttpServer server; diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart index e1bcdb46a3..6e88e8608b 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart @@ -10,7 +10,7 @@ import 'package:test/test.dart'; import 'response_status_line_server_vm.dart' if (dart.library.html) 'response_status_line_server_web.dart'; -/// Tests that the [Client] correctly processes response headers. +/// Tests that the [Client] correctly processes the response status line. void testResponseStatusLine(Client client) async { group('response status line', () { late String host; From ea8ccdf7c1428d790a17b69f7b11e126b242adc4 Mon Sep 17 00:00:00 2001 From: Alex James Date: Thu, 24 Aug 2023 21:39:16 +0100 Subject: [PATCH 5/6] Let each test have its own response status line --- .../lib/src/response_status_line_server.dart | 17 ++++++++++++----- .../lib/src/response_status_line_tests.dart | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart index ba81d048c7..66d44889a1 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; /// Starts an HTTP server that returns a custom status line. @@ -13,20 +14,26 @@ import 'package:stream_channel/stream_channel.dart'; /// On Startup: /// - send port /// On Request Received: +/// - load response status line from channel /// - exit void hybridMain(StreamChannel channel) async { late HttpServer server; + final clientQueue = StreamQueue(channel.stream); server = (await HttpServer.bind('localhost', 0)) ..listen((request) async { await request.drain(); final socket = await request.response.detachSocket(writeHeaders: false); - socket.writeAll([ - 'HTTP/1.1 OK', - 'Content-Length: 0', - '', // Add \r\n at the end of this header section. - ], '\r\n'); + final statusLine = (await clientQueue.next) as String; + socket.writeAll( + [ + statusLine, + 'Content-Length: 0', + '\r\n', // Add \r\n at the end of this header section. + ], + '\r\n', // Separate each field by \r\n. + ); await socket.close(); unawaited(server.close()); }); diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart index 6e88e8608b..895d4fe3fc 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart @@ -24,6 +24,7 @@ void testResponseStatusLine(Client client) async { }); test('without status code', () async { + httpServerChannel.sink.add('HTTP/1.1 OK'); await expectLater( client.get(Uri.http(host, '')), throwsA(isA()), From bea93bcb636bf97918c4bfa345eff931e24c2ff2 Mon Sep 17 00:00:00 2001 From: Alex James Date: Sat, 26 Aug 2023 00:38:41 +0100 Subject: [PATCH 6/6] Skip the 'without status code' test --- .../lib/src/response_status_line_tests.dart | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart index 895d4fe3fc..922236ccc1 100644 --- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart +++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart @@ -23,12 +23,17 @@ void testResponseStatusLine(Client client) async { host = 'localhost:${await httpServerQueue.next}'; }); - test('without status code', () async { - httpServerChannel.sink.add('HTTP/1.1 OK'); - await expectLater( - client.get(Uri.http(host, '')), - throwsA(isA()), - ); - }); + test( + 'without status code', + () async { + httpServerChannel.sink.add('HTTP/1.1 OK'); + await expectLater( + client.get(Uri.http(host, '')), + throwsA(isA()), + ); + }, + skip: + 'Enable after https://github.com/dart-lang/http/issues/1013 is fixed', + ); }); }