1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:http2/http2.dart';
void main() async { var uri = Uri.parse('https://cn.bing.com/search?q=http2'); var transport = await connectTunnel('127.0.0.1', 8888, uri.host); var headers = [ Header.ascii(':method', 'GET'), Header.ascii(':path', uri.hasQuery ? uri.path + '?' + uri.query : uri.path), Header.ascii(':scheme', uri.scheme), Header.ascii(':authority', uri.host), ]; var stream = transport.makeRequest(headers, endStream: true); var bodyStream = StreamController<List<int>>(); utf8.decoder.bind(bodyStream.stream).listen((body) { print(body); }); await for (var message in stream.incomingMessages) { if (message is HeadersStreamMessage) { for (var header in message.headers) { var name = utf8.decode(header.name); var value = utf8.decode(header.value); print('Header: $name: $value'); } } else if (message is DataStreamMessage) { bodyStream.add(message.bytes); if (message.endStream) { bodyStream.close(); } } } if (!bodyStream.isClosed) { await bodyStream.close(); } await transport.finish(); }
Future<ClientTransportConnection> connectTunnel(String proxyHost, int proxyPort, String targetHost, [int targetPort = 443]) async { var proxy = await Socket.connect(proxyHost, proxyPort, timeout: const Duration(seconds: 1)); const CRLF = "\r\n"; proxy.write("CONNECT $targetHost:$targetPort HTTP/1.1"); proxy.write(CRLF); proxy.write("Host: $targetHost:$targetPort"); proxy.write(CRLF); proxy.write(CRLF); var completer = Completer<bool>.sync(); var sub = proxy.listen((event) { var response = ascii.decode(event); var lines = response.split(CRLF); var statusLine = lines.first; if (statusLine.startsWith("HTTP/1.1 200")) { completer.complete(); } else { completer.completeError(statusLine); } }, onError: completer.completeError); await completer.future; await sub.pause();
var socket = await SecureSocket.secure(proxy, host: targetHost, supportedProtocols: const ["h2"]); return ClientTransportConnection.viaSocket(socket); }
|