This library provides an http/2 interface on top of a bidirectional stream of bytes.

The client and server sides can be created via ClientTransportStream and ServerTransportStream respectively. Both sides can be configured via settings (see ClientSettings and ServerSettings). The settings will be communicated to the remote peer (if necessary) and will be valid during the entire lifetime of the connection.

A http/2 transport allows a client to open a bidirectional stream (see ClientTransportConnection.makeRequest) and a server can open (or push) a unidirectional stream to the client via ServerTransportStream.push.

In both cases (unidirectional and bidirectional stream), one can send headers and data to the other side (via HeadersStreamMessage and DataStreamMessage). These messages are ordered and will arrive in the same order as they were sent (data messages may be split up into multiple smaller chunks or might be combined).

In the most common case, each direction will send a HeadersStreamMessage and zero or more DataStreamMessages.

Establishing a bidirectional stream of bytes to a server is up to the user of this library and can for example be done via dart:ios secure socket implementation (using a SecurityContext and including 'h2' in the list of protocols used during ALPN).

Here is a simple example on how to connect to a http/2 capable server and requesting a resource:

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:http2/transport.dart';

main() async {
  var uri = Uri.parse("https://www.google.com/");

  var socket = await connect(uri);
  var transport = new ClientTransportConnection.viaSocket(socket);

  var headers = [
    new Header.ascii(':method', 'GET'),
    new Header.ascii(':path', uri.path),
    new Header.ascii(':scheme', uri.scheme),
    new Header.ascii(':authority', uri.host),
  ];

  var stream = transport.makeRequest(headers, endStream: true);
  await for (var message in stream.incomingMessages) {
    if (message is HeadersStreamMessage) {
      for (var header in message.headers) {
        print('${UTF8.decode(header.name)}: ${UTF8.decode(header.value)}');
      }
    } else if (message is DataStreamMessage) {
      // Use [message.bytes] (but respect 'content-encoding' header)
    }
  }
  await transport.finish();
}

Future<Socket> connect(Uri uri) async {
  bool useSSL = uri.scheme == 'https';
  if (useSSL) {
    var secureSocket = await SecureSocket.connect(
        uri.host, uri.port, supportedProtocols: ['h2']);
    if (secureSocket.selectedProtocol != 'h2') {
      throw new Exception(
          "Failed to negogiate http/2 via alpn. Maybe server "
          "doesn't support http/2.");
    }
    return secureSocket;
  } else {
    return await Socket.connect(uri.host, uri.port);
  }
}

Classes

ClientSettings

Settings for a TransportConnection a client can make.

ClientTransportConnection

ClientTransportStream

DataStreamMessage

Represents a data message which can be sent over a HTTP/2 stream.

A HTTP/2 header.

HeadersStreamMessage

Represents a headers message which can be sent over a HTTP/2 stream.

ServerSettings

Settings for a TransportConnection a server can make.

ServerTransportConnection

ServerTransportStream

Settings

Settings for a TransportConnection.

StreamMessage

Represents a message which can be sent over a HTTP/2 stream.

TransportConnection

Represents a HTTP/2 connection.

TransportStream

Represents a HTTP/2 stream.

TransportStreamPush

Represents a remote stream push.

Exceptions / Errors

StreamTransportException

An exception thrown when a HTTP/2 connection error occured.

TransportConnectionException

An exception thrown when a HTTP/2 connection error occurred.

TransportException

An exception thrown by the HTTP/2 implementation.