Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into swift
Browse files Browse the repository at this point in the history
  • Loading branch information
brianquinlan committed Aug 28, 2024
2 parents addd926 + dfeecf0 commit 697b35a
Show file tree
Hide file tree
Showing 36 changed files with 803 additions and 109 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/health.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Health
on:
pull_request:
branches: [ master ]
types: [opened, synchronize, reopened, labeled, unlabeled]

jobs:
health:
uses: dart-lang/ecosystem/.github/workflows/health.yaml@main
with:
ignore_license: "**.g.dart"
sdk: dev
permissions:
pull-requests: write
17 changes: 17 additions & 0 deletions .github/workflows/post_summaries.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Comment on the pull request

on:
# Trigger this workflow after the Health workflow completes. This workflow will have permissions to
# do things like create comments on the PR, even if the original workflow couldn't.
workflow_run:
workflows:
- Health
- Publish
types:
- completed

jobs:
upload:
uses: dart-lang/ecosystem/.github/workflows/post_summaries.yaml@main
permissions:
pull-requests: write
2 changes: 2 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
publish:
if: ${{ github.repository_owner == 'dart-lang' }}
uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
with:
write-comments: false
permissions:
id-token: write # Required for authentication using OIDC
pull-requests: write # Required for writing the pull request note
5 changes: 5 additions & 0 deletions pkgs/cronet_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.3.3-wip

* Throw `ClientException` if `CronetClient.send` runs out of Java heap while
allocating memory for the request body.

## 1.3.2

* Upgrade `package:jni` to 0.10.1 and `package:jnigen` to 0.10.0 to fix method
Expand Down
16 changes: 15 additions & 1 deletion pkgs/cronet_http/lib/src/cronet_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,22 @@ class CronetClient extends BaseClient {
headers.forEach((k, v) => builder.addHeader(k.toJString(), v.toJString()));

if (body.isNotEmpty) {
final JByteBuffer data;
try {
data = body.toJByteBuffer();
} on JniException catch (e) {
// There are no unit tests for this code. You can verify this behavior
// manually by incrementally increasing the amount of body data in
// `CronetClient.post` until you get this exception.
if (e.message.contains('java.lang.OutOfMemoryError:')) {
throw ClientException(
'Not enough memory for request body: ${e.message}', request.url);
}
rethrow;
}

builder.setUploadDataProvider(
jb.UploadDataProviders.create2(body.toJByteBuffer()), _executor);
jb.UploadDataProviders.create2(data), _executor);
}
builder.build().start();
return responseCompleter.future;
Expand Down
2 changes: 1 addition & 1 deletion pkgs/cronet_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cronet_http
version: 1.3.2
version: 1.3.3-wip
description: >-
An Android Flutter plugin that provides access to the Cronet HTTP client.
repository: https://github.com/dart-lang/http/tree/master/pkgs/cronet_http
Expand Down
2 changes: 2 additions & 0 deletions pkgs/cupertino_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## 1.5.2-wip

## 1.5.1

* Allow `1000` as a `code` argument in `CupertinoWebSocket.close`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ Pod::Spec.new do |s|
# paths, so Classes contains a forwarder C file that relatively imports
# `../src/*` so that the C sources can be shared among all target platforms.
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'FlutterMacOS'
s.source_files = 'cupertino_http/Sources/cupertino_http/**/*'
s.ios.dependency 'Flutter'
s.osx.dependency 'FlutterMacOS'
s.ios.deployment_target = '12.0'
s.osx.deployment_target = '10.14'
s.requires_arc = []

s.platform = :osx, '10.14'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.swift_version = '5.0'
end
29 changes: 0 additions & 29 deletions pkgs/cupertino_http/ios/cupertino_http.podspec

This file was deleted.

10 changes: 8 additions & 2 deletions pkgs/cupertino_http/lib/src/cupertino_web_socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class ConnectionException extends WebSocketException {
/// A [WebSocket] implemented using the
/// [NSURLSessionWebSocketTask API](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask).
///
/// NOTE: the [WebSocket] interface is currently experimental and may change in
/// the future.
/// > [!NOTE]
/// > The [WebSocket] interface is currently experimental and may change in the
/// > future.
///
/// ```dart
/// import 'package:cupertino_http/cupertino_http.dart';
Expand All @@ -47,6 +48,11 @@ class ConnectionException extends WebSocketException {
/// });
/// }
/// ```
///
/// > [!TIP]
/// > [`AdapterWebSocketChannel`](https://pub.dev/documentation/web_socket_channel/latest/adapter_web_socket_channel/AdapterWebSocketChannel-class.html)
/// > can be used to adapt a [CupertinoWebSocket] into a
/// > [`WebSocketChannel`](https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html).
class CupertinoWebSocket implements WebSocket {
/// Create a new WebSocket connection using the
/// [NSURLSessionWebSocketTask API](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask).
Expand Down
4 changes: 3 additions & 1 deletion pkgs/cupertino_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cupertino_http
version: 1.5.1
version: 1.5.2-wip
description: >-
A macOS/iOS Flutter plugin that provides access to the Foundation URL
Loading System.
Expand Down Expand Up @@ -27,5 +27,7 @@ flutter:
platforms:
ios:
ffiPlugin: true
sharedDarwinSource: true
macos:
ffiPlugin: true
sharedDarwinSource: true
4 changes: 4 additions & 0 deletions pkgs/http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.2.3-wip

* Fixed unintended HTML tags in doc comments.

## 1.2.2

* Require package `web: '>=0.5.0 <2.0.0'`.
Expand Down
30 changes: 15 additions & 15 deletions pkgs/http/lib/http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ Future<Response> get(Uri url, {Map<String, String>? headers}) =>

/// Sends an HTTP POST request with the given headers and body to the given URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>] or
/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
/// used as the body of the request. The content-type of the request will
/// [body] sets the body of the request. It can be a `String`, a `List<int>` or
/// a `Map<String, String>`. If it's a `String`, it's encoded using [encoding]
/// and used as the body of the request. The content-type of the request will
/// default to "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand All @@ -73,15 +73,15 @@ Future<Response> post(Uri url,

/// Sends an HTTP PUT request with the given headers and body to the given URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>] or
/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
/// used as the body of the request. The content-type of the request will
/// [body] sets the body of the request. It can be a `String`, a `List<int>` or
/// a `Map<String, String>`. If it's a `String`, it's encoded using [encoding]
/// and used as the body of the request. The content-type of the request will
/// default to "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand All @@ -97,15 +97,15 @@ Future<Response> put(Uri url,
/// Sends an HTTP PATCH request with the given headers and body to the given
/// URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>] or
/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
/// used as the body of the request. The content-type of the request will
/// [body] sets the body of the request. It can be a `String`, a `List<int>` or
/// a `Map<String, String>`. If it's a `String`, it's encoded using [encoding]
/// and used as the body of the request. The content-type of the request will
/// default to "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand Down
11 changes: 6 additions & 5 deletions pkgs/http/lib/src/base_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ var _headerSplitter = RegExp(r'[ \t]*,[ \t]*');
///
/// Set-Cookie strings can contain commas. In particular, the following
/// productions defined in RFC-6265, section 4.1.1:
/// - <sane-cookie-date> e.g. "Expires=Sun, 06 Nov 1994 08:49:37 GMT"
/// - <path-value> e.g. "Path=somepath,"
/// - <extension-av> e.g. "AnyString,Really,"
/// - `<sane-cookie-date>` e.g. "Expires=Sun, 06 Nov 1994 08:49:37 GMT"
/// - `<path-value>` e.g. "Path=somepath,"
/// - `<extension-av>` e.g. "AnyString,Really,"
///
/// Some values are ambiguous e.g.
/// "Set-Cookie: lang=en; Path=/foo/"
Expand All @@ -128,8 +128,9 @@ var _headerSplitter = RegExp(r'[ \t]*,[ \t]*');
/// "Set-Cookie: lang=en; Path=/foo/,SID=x23"
/// would both be result in `response.headers` => "lang=en; Path=/foo/,SID=x23"
///
/// The idea behind this regex is that ",<valid token>=" is more likely to
/// start a new <cookie-pair> then be part of <path-value> or <extension-av>.
/// The idea behind this regex is that `,<valid token>=` is more likely to
/// start a new `<cookie-pair>` than be part of `<path-value>` or
/// `<extension-av>`.
///
/// See https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
var _setCookieSplitter = RegExp(r'[ \t]*,[ \t]*(?=[' + _tokenChars + r']+=)');
Expand Down
28 changes: 14 additions & 14 deletions pkgs/http/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ abstract interface class Client {
/// Sends an HTTP POST request with the given headers and body to the given
/// URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>]
/// or a [Map<String, String>].
/// [body] sets the body of the request. It can be a `String`, a `List<int>`
/// or a `Map<String, String>`.
///
/// If [body] is a String, it's encoded using [encoding] and used as the body
/// of the request. The content-type of the request will default to
/// If [body] is a `String`, it's encoded using [encoding] and used as the
/// body of the request. The content-type of the request will default to
/// "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand All @@ -77,15 +77,15 @@ abstract interface class Client {
/// Sends an HTTP PUT request with the given headers and body to the given
/// URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>]
/// or a [Map<String, String>]. If it's a String, it's encoded using
/// [body] sets the body of the request. It can be a `String`, a `List<int>`
/// or a `Map<String, String>`. If it's a `String`, it's encoded using
/// [encoding] and used as the body of the request. The content-type of the
/// request will default to "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand All @@ -98,15 +98,15 @@ abstract interface class Client {
/// Sends an HTTP PATCH request with the given headers and body to the given
/// URL.
///
/// [body] sets the body of the request. It can be a [String], a [List<int>]
/// or a [Map<String, String>]. If it's a String, it's encoded using
/// [body] sets the body of the request. It can be a `String`, a `List<int>`
/// or a `Map<String, String>`. If it's a `String`, it's encoded using
/// [encoding] and used as the body of the request. The content-type of the
/// request will default to "text/plain".
///
/// If [body] is a List, it's used as a list of bytes for the body of the
/// If [body] is a `List`, it's used as a list of bytes for the body of the
/// request.
///
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// If [body] is a `Map`, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
///
Expand Down
2 changes: 1 addition & 1 deletion pkgs/http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: http
version: 1.2.2
version: 1.2.3-wip
description: A composable, multi-platform, Future-based API for HTTP requests.
repository: https://github.com/dart-lang/http/tree/master/pkgs/http

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'package:stream_channel/stream_channel.dart';
/// On Startup:
/// - send port
/// On Request Received:
/// - send headers as Map<String, List<String>>
/// - send headers as `Map<String, List<String>>`
/// When Receive Anything:
/// - exit
void hybridMain(StreamChannel<Object?> channel) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,27 @@ void hybridMain(StreamChannel<Object?> channel) async {
server = (await HttpServer.bind('localhost', 0))
..listen((request) async {
request.response.headers.set('Access-Control-Allow-Origin', '*');
request.response
..contentLength = 0
..statusCode = HttpStatus.ok;

if (request.method == 'OPTIONS') {
// Handle a CORS preflight request:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
request.response.headers
..set('Access-Control-Allow-Methods', '*')
..set('Access-Control-Allow-Headers', '*');
await request.response.close();
} else {
final headers = <String, List<String>>{};
request.headers.forEach((field, value) {
headers[field] = value;
});
final body =
await const Utf8Decoder().bind(request).fold('', (x, y) => '$x$y');
channel.sink.add((headers, body));
await request.response.close();
channel.sink.add([headers, body]);
}
unawaited(request.response.close());
});

channel.sink.add(server.port);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ void testMultipartRequests(Client client,
request.files.add(MultipartFile.fromString('file1', 'Hello World'));

await client.send(request);
final (headers, body) =
await httpServerQueue.next as (Map<String, List<String>>, String);
final serverRequest = await httpServerQueue.next as List;
final headers = (serverRequest[0] as Map).cast<String, List<Object?>>();
final body = serverRequest[1] as String;
expect(headers['content-length']!.single, '${request.contentLength}');
expect(headers['content-type']!.single,
startsWith('multipart/form-data; boundary='));
Expand Down
Loading

0 comments on commit 697b35a

Please sign in to comment.