dart-lang / http2

A HTTP/2 implementation for dart.

Home Page:https://pub.dev/packages/http2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for half-open connections

sigurdm opened this issue · comments

A tcp-socket can be closed in one direction (the client can close one direction after it is done sending the request, and still listen for more response).
We should support this in package:http2.

Currently this program:

import 'dart:io';
import 'dart:async';
import 'dart:isolate';
import 'package:http2/http2.dart';

client(port) async {
  Socket s = await Socket.connect('localhost', port);
  final ctc = ClientTransportConnection.viaSocket(s);
  final cts = ctc.makeRequest([Header.ascii("a", "b")]);
  
  cts.incomingMessages.listen(print);
  await Future.delayed(Duration(seconds: 2));
  print("closing client socket outgoing");
  s.close();
}

spawnClient(port) async {
  await Isolate.spawn(client, port);
}

main() async {
  ServerSocket ss = await ServerSocket.bind('localhost', 0);
  spawnClient(ss.port);
  Socket s = await ss.first;
  ServerTransportStream ts;
  print("Listening");
  new ServerTransportConnection.viaSocket(s).incomingStreams.listen((stream) {
    print("got stream");
    ts = stream;
  }, onDone: () {
    print("done");
    ts.sendHeaders([Header.ascii("foo", "bar")]);
  });
}

prints:

Listening
got stream
closing client socket
Unhandled exception:
Bad state: StreamSink is bound to a stream
#0      _StreamSinkImpl.close (dart:io/io_sink.dart:218:7)
#1      _Socket.close (dart:io/runtime/binsocket_patch.dart:1627:27)
#2      client (file:///usr/local/google/home/sigurdm/projects/blah/bin/http2sample.dart:14:5)
<asynchronous suspension>
#3      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:292:17)
#4      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
done
Unhandled exception:
Bad state: Cannot add event after closing
#0      _StreamController.add (dart:async/stream_controller.dart:585:24)
#1      _StreamSinkWrapper.add (dart:async/stream_controller.dart:858:13)
#2      TransportStream.sendHeaders (package:http2/transport.dart:145:10)
#3      main.<anonymous closure> (file:///usr/local/google/home/sigurdm/projects/blah/bin/http2sample.dart:32:8)
#4      _RootZone.runGuarded (dart:async/zone.dart:1302:10)
#5      _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:389:13)
#6      _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:399:15)