Skip to content

Commit 5e2281e

Browse files
authored
Merge pull request #1318 from dart-lang/merge-http2-package
Merge `package:http2`
2 parents 92d317a + e6f2fb5 commit 5e2281e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+11204
-0
lines changed

.github/ISSUE_TEMPLATE/http2.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: "package:http2"
3+
about: "Create a bug or file a feature request against package:http2."
4+
labels: "package:http2"
5+
---

.github/labeler.yml

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
- changed-files:
1717
- any-glob-to-any-file: 'pkgs/http/**'
1818

19+
'package:http2':
20+
- changed-files:
21+
- any-glob-to-any-file: 'pkgs/http2/**'
22+
1923
'package:http_parser':
2024
- changed-files:
2125
- any-glob-to-any-file: 'pkgs/http_parser/**'

.github/workflows/http2.yaml

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: package:http2
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- '.github/workflows/http2.yaml'
9+
- 'pkgs/http2/**'
10+
pull_request:
11+
paths:
12+
- '.github/workflows/http2.yaml'
13+
- 'pkgs/http2/**'
14+
schedule:
15+
- cron: "0 0 * * 0"
16+
17+
defaults:
18+
run:
19+
working-directory: pkgs/http2/
20+
21+
env:
22+
PUB_ENVIRONMENT: bot.github
23+
24+
jobs:
25+
# Check code formatting and static analysis on a single OS (linux)
26+
# against Dart dev.
27+
analyze:
28+
runs-on: ubuntu-latest
29+
strategy:
30+
fail-fast: false
31+
matrix:
32+
sdk: [dev]
33+
steps:
34+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
35+
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
36+
with:
37+
sdk: ${{ matrix.sdk }}
38+
- id: install
39+
name: Install dependencies
40+
run: dart pub get
41+
- name: Check formatting
42+
run: dart format --output=none --set-exit-if-changed .
43+
if: always() && steps.install.outcome == 'success'
44+
- name: Analyze code
45+
run: dart analyze --fatal-infos
46+
if: always() && steps.install.outcome == 'success'
47+
48+
# Run tests on a matrix consisting of two dimensions:
49+
# 1. OS: ubuntu-latest, (macos-latest, windows-latest)
50+
# 2. release channel: dev
51+
test:
52+
needs: analyze
53+
runs-on: ${{ matrix.os }}
54+
strategy:
55+
fail-fast: false
56+
matrix:
57+
# Add macos-latest and/or windows-latest if relevant for this package.
58+
os: [ubuntu-latest]
59+
sdk: [3.2, dev]
60+
steps:
61+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
62+
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
63+
with:
64+
sdk: ${{ matrix.sdk }}
65+
- id: install
66+
name: Install dependencies
67+
run: dart pub get
68+
- name: Run VM tests
69+
run: dart test --platform vm
70+
if: always() && steps.install.outcome == 'success'

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and the browser.
1414
| [cupertino_http](pkgs/cupertino_http/) | A macOS/iOS Flutter plugin that provides access to the [Foundation URL Loading System](https://developer.apple.com/documentation/foundation/url_loading_system). | [![pub package](https://img.shields.io/pub/v/cupertino_http.svg)](https://pub.dev/packages/cupertino_http) |
1515
| [flutter_http_example](pkgs/flutter_http_example/) | An Flutter app that demonstrates how to configure and use `package:http`. ||
1616
| [http](pkgs/http/) | A composable, multi-platform, Future-based API for HTTP requests. | [![pub package](https://img.shields.io/pub/v/http.svg)](https://pub.dev/packages/http) |
17+
| [http2](pkgs/http2/) | A HTTP/2 implementation in Dart. | [![pub package](https://img.shields.io/pub/v/http2.svg)](https://pub.dev/packages/http2) |
1718
| [http_client_conformance_tests](pkgs/http_client_conformance_tests/) | A library that tests whether implementations of package:http's `Client` class behave as expected. | |
1819
| [http_parser](pkgs/http_parser/) | A platform-independent package for parsing and serializing HTTP formats. | [![pub package](https://img.shields.io/pub/v/http_parser.svg)](https://pub.dev/packages/http_parser) |
1920
| [http_profile](pkgs/http_profile/) | A library used by HTTP client authors to integrate with the DevTools Network View. | [![pub package](https://img.shields.io/pub/v/http_profile.svg)](https://pub.dev/packages/http_profile) |

pkgs/http2/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Don’t commit the following directories created by pub.
2+
.dart_tool
3+
.packages
4+
pubspec.lock

pkgs/http2/.test_config

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"test_package": {
3+
"platforms" : ["vm"]
4+
}
5+
}

pkgs/http2/AUTHORS

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Below is a list of people and organizations that have contributed
2+
# to the project. Names should be added to the list like so:
3+
#
4+
# Name/Organization <email address>
5+
6+
Google Inc. <*@google.com>
7+
8+
Alexandre Ardhuin <[email protected]>

pkgs/http2/CHANGELOG.md

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
## 2.3.1
2+
3+
- Require Dart 3.2
4+
- Add topics to `pubspec.yaml`
5+
- Move to `dart-lang/http` monorepo.
6+
7+
## 2.3.0
8+
9+
- Only send updates on frames and pings being received when there are listeners, as to not fill up memory.
10+
11+
## 2.2.0
12+
13+
- Transform headers to lowercase.
14+
- Expose pings to connection to enable the KEEPALIVE feature for gRPC.
15+
16+
## 2.1.0
17+
18+
- Require Dart `3.0.0`
19+
- Require Dart `2.17.0`.
20+
- Send `WINDOW_UPDATE` frames for the connection to account for data being sent on closed streams until the `RST_STREAM` has been processed.
21+
22+
## 2.0.1
23+
24+
- Simplify the implementation of `MultiProtocolHttpServer.close`.
25+
- Require Dart `2.15.0`.
26+
27+
## 2.0.0
28+
29+
* Migrate to null safety.
30+
31+
## 1.0.1
32+
33+
* Add `TransportConnection.onInitialPeerSettingsReceived` which fires when
34+
initial SETTINGS frame is received from the peer.
35+
36+
## 1.0.0
37+
38+
* Graduate package to 1.0.
39+
* `package:http2/http2.dart` now reexports `package:http2/transport.dart`.
40+
41+
## 0.1.9
42+
43+
* Discard messages incoming after stream cancellation.
44+
45+
## 0.1.8+2
46+
47+
* On connection termination, try to dispatch existing messages, thereby avoiding
48+
terminating existing streams.
49+
50+
* Fix `ClientTransportConnection.isOpen` to return `false` if we have exhausted
51+
the number of max-concurrent-streams.
52+
53+
## 0.1.8+1
54+
55+
* Switch all uppercase constants from `dart:convert` to lowercase.
56+
57+
## 0.1.8
58+
59+
* More changes required for making tests pass under Dart 2.0 runtime.
60+
* Modify sdk constraint to require '>=2.0.0-dev.40.0'.
61+
62+
## 0.1.7
63+
64+
* Fixes for Dart 2.0.
65+
66+
## 0.1.6
67+
68+
* Strong mode fixes and other cleanup.
69+
70+
## 0.1.5
71+
72+
* Removed use of new `Function` syntax, since it isn't fully supported in Dart
73+
1.24.
74+
75+
## 0.1.4
76+
77+
* Added an `onActiveStateChanged` callback to `Connection`, which is invoked when
78+
the connection changes state from idle to active or from active to idle. This
79+
can be used to implement an idle connection timeout.
80+
81+
## 0.1.3
82+
83+
* Fixed a bug where a closed window would not open correctly due to an increase
84+
in initial window size.
85+
86+
## 0.1.2
87+
88+
* The endStream bit is now set on the requested frame, instead of on an empty
89+
data frame following it.
90+
* Added an `onTerminated` hook that is called when a TransportStream receives
91+
a RST_STREAM frame.
92+
93+
## 0.1.1+2
94+
95+
* Add errorCode to exception toString message.
96+
97+
## 0.1.1+1
98+
99+
* Fixing a performance issue in case the underlying socket is not writeable
100+
* Allow clients of MultiProtocolHttpServer to supply [http.ServerSettings]
101+
* Allow the draft version 'h2-14' in the ALPN protocol negogiation.
102+
103+
## 0.1.1
104+
105+
* Adding support for MultiProtocolHttpServer in the
106+
`package:http2/multiprotocol_server.dart` library
107+
108+
## 0.1.0
109+
110+
* First version of a HTTP/2 transport implementation in the
111+
`package:http2/transport.dart` library
112+
113+
## 0.0.1
114+
115+
- Initial version

pkgs/http2/LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright 2015, the Dart project authors.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above
10+
copyright notice, this list of conditions and the following
11+
disclaimer in the documentation and/or other materials provided
12+
with the distribution.
13+
* Neither the name of Google LLC nor the names of its
14+
contributors may be used to endorse or promote products derived
15+
from this software without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pkgs/http2/README.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
[![pub package](https://img.shields.io/pub/v/http2.svg)](https://pub.dev/packages/http2)
2+
[![package publisher](https://img.shields.io/pub/publisher/http2.svg)](https://pub.dev/packages/http2/publisher)
3+
4+
This library provides an http/2 interface on top of a bidirectional stream of bytes.
5+
6+
## Usage
7+
8+
Here is a minimal example of connecting to a http/2 capable server, requesting
9+
a resource and iterating over the response.
10+
11+
```dart
12+
import 'dart:convert';
13+
import 'dart:io';
14+
15+
import 'package:http2/http2.dart';
16+
17+
Future<void> main() async {
18+
final uri = Uri.parse('https://www.google.com/');
19+
20+
final transport = ClientTransportConnection.viaSocket(
21+
await SecureSocket.connect(
22+
uri.host,
23+
uri.port,
24+
supportedProtocols: ['h2'],
25+
),
26+
);
27+
28+
final stream = transport.makeRequest(
29+
[
30+
Header.ascii(':method', 'GET'),
31+
Header.ascii(':path', uri.path),
32+
Header.ascii(':scheme', uri.scheme),
33+
Header.ascii(':authority', uri.host),
34+
],
35+
endStream: true,
36+
);
37+
38+
await for (var message in stream.incomingMessages) {
39+
if (message is HeadersStreamMessage) {
40+
for (var header in message.headers) {
41+
final name = utf8.decode(header.name);
42+
final value = utf8.decode(header.value);
43+
print('Header: $name: $value');
44+
}
45+
} else if (message is DataStreamMessage) {
46+
// Use [message.bytes] (but respect 'content-encoding' header)
47+
}
48+
}
49+
await transport.finish();
50+
}
51+
```
52+
53+
An example with better error handling is available [here][example].
54+
55+
See the [API docs][api] for more details.

pkgs/http2/analysis_options.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# https://dart.dev/tools/analysis#the-analysis-options-file
2+
include: package:dart_flutter_team_lints/analysis_options.yaml
3+
4+
analyzer:
5+
language:
6+
strict-casts: true
7+
errors:
8+
# Disabled as there are several dozen violations.
9+
constant_identifier_names: ignore

pkgs/http2/dart_test.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tags:
2+
flaky: # Tests that should be run as a separate job on Travis
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:convert';
7+
import 'dart:io';
8+
9+
import 'package:http2/transport.dart';
10+
11+
void main(List<String> args) async {
12+
if (args.length != 1) {
13+
print('Usage: dart display_headers.dart <HTTPS_URI>');
14+
exit(1);
15+
}
16+
17+
var uriArg = args[0];
18+
19+
if (!uriArg.startsWith('https://')) {
20+
print('URI must start with https://');
21+
exit(1);
22+
}
23+
24+
var uri = Uri.parse(uriArg);
25+
26+
var socket = await connect(uri);
27+
28+
// The default client settings will disable server pushes. We
29+
// therefore do not need to deal with [stream.peerPushes].
30+
var transport = ClientTransportConnection.viaSocket(socket);
31+
32+
var headers = [
33+
Header.ascii(':method', 'GET'),
34+
Header.ascii(':path', uri.path),
35+
Header.ascii(':scheme', uri.scheme),
36+
Header.ascii(':authority', uri.host),
37+
];
38+
39+
var stream = transport.makeRequest(headers, endStream: true);
40+
await for (var message in stream.incomingMessages) {
41+
if (message is HeadersStreamMessage) {
42+
for (var header in message.headers) {
43+
var name = utf8.decode(header.name);
44+
var value = utf8.decode(header.value);
45+
print('$name: $value');
46+
}
47+
} else if (message is DataStreamMessage) {
48+
// Use [message.bytes] (but respect 'content-encoding' header)
49+
}
50+
}
51+
await transport.finish();
52+
}
53+
54+
Future<Socket> connect(Uri uri) async {
55+
var useSSL = uri.scheme == 'https';
56+
if (useSSL) {
57+
var secureSocket = await SecureSocket.connect(uri.host, uri.port,
58+
supportedProtocols: ['h2']);
59+
if (secureSocket.selectedProtocol != 'h2') {
60+
throw Exception('Failed to negogiate http/2 via alpn. Maybe server '
61+
"doesn't support http/2.");
62+
}
63+
return secureSocket;
64+
} else {
65+
return await Socket.connect(uri.host, uri.port);
66+
}
67+
}

0 commit comments

Comments
 (0)