static async Task Main(string[] args) { PreparedHeaderSet preparedHeaders = new PreparedHeaderSetBuilder() .AddHeader("User-Agent", "NetworkToolkit") .AddHeader("Accept", "text/html") .Build(); await using ConnectionFactory connectionFactory = new SocketConnectionFactory(); await using Connection connection = await connectionFactory.ConnectAsync(new DnsEndPoint ("microsoft.com", 80)); await using HttpConnection httpConnection = new Http1Connection(connection, HttpPrimitiveVersion.Version11); int requestCounter = 0; await SingleRequest(); await SingleRequest(); async Task SingleRequest() { await using ValueHttpRequest request = (await httpConnection.CreateNewRequestAsync(HttpPrimitiveVersion.Version11, HttpVersionPolicy.RequestVersionExact)).Value; request.ConfigureRequest(contentLength: 0, hasTrailingHeaders: false); request.WriteRequest(HttpMethod.Get, new Uri("http://microsoft.com")); request.WriteHeader(preparedHeaders); request.WriteHeader("X-Example-RequestNo", requestCounter++.ToString()); await request.CompleteRequestAsync(); await request.DrainAsync(); } }
protected internal override async ValueTask DisposeAsync(int version, CancellationToken cancellationToken) { if (_owningConnection is PooledHttpConnection owningConnection) { ThrowIfDisposed(version); PooledHttp1Connection pooledConnection = (PooledHttp1Connection)((Http1Request)_request.Request).Connection; bool disposeConnection = false; try { await _request.DrainAsync(owningConnection.MaximumDrainBytes, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { disposeConnection = true; } await _request.DisposeAsync(cancellationToken).ConfigureAwait(false); _owningConnection = null; owningConnection.PushCachedRequest(this); if (!disposeConnection && !pooledConnection.IsExpired(Environment.TickCount64, owningConnection.PooledConnectionLifetimeLimit, owningConnection.PooledConnectionIdleLimit)) { owningConnection.PushHttp1Connection(pooledConnection); } else { await pooledConnection.DisposeAsync(cancellationToken).ConfigureAwait(false); } } }
protected internal override async ValueTask DisposeAsync(int version, CancellationToken cancellationToken) { if (_owningConnection is PooledHttpConnection owningConnection) { ThrowIfDisposed(version); PooledHttp1Connection pooledConnection = (PooledHttp1Connection)((Http1Request)_request.Request).Connection; bool disposeConnection = false; try { await _request.DrainAsync(owningConnection.MaximumDrainBytes, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { disposeConnection = true; } await _request.DisposeAsync(cancellationToken).ConfigureAwait(false); _owningConnection = null; bool owningConnectionDisposed = owningConnection._disposed; disposeConnection = disposeConnection || owningConnectionDisposed || pooledConnection.Status != HttpConnectionStatus.Open || pooledConnection.IsExpired(Environment.TickCount64, owningConnection.PooledConnectionLifetimeLimit, owningConnection.PooledConnectionIdleLimit); if (!owningConnectionDisposed) { owningConnection.PushCachedRequestToTail(this); } if (!disposeConnection) { owningConnection.PushHttp1ConnectionToTail(pooledConnection); if (owningConnection._disposed) { // If the owning connection was disposed between last checking, the connection // will be pushed to freelist with noone else to dispose it. // Re-dispose the owning connection to clear out the freelist. await owningConnection.DisposeAsync(cancellationToken).ConfigureAwait(false); } } else { await pooledConnection.DisposeAsync(cancellationToken).ConfigureAwait(false); } } }
internal async Task RunSingleStreamTest(Func <ValueHttpRequest, Uri, Task> clientFunc, Func <HttpTestStream, Task> serverFunc, int?millisecondsTimeout = null) { await RunMultiStreamTest( async (client, serverUri) => { ValueHttpRequest?optionalRequest = await client.CreateNewRequestAsync(Version, HttpVersionPolicy.RequestVersionExact).ConfigureAwait(false); Assert.NotNull(optionalRequest); ValueHttpRequest request = optionalRequest.Value; await using (request.ConfigureAwait(false)) { await clientFunc(request, serverUri).ConfigureAwait(false); await request.DrainAsync().ConfigureAwait(false); } }, async server => { HttpTestStream request = await server.AcceptStreamAsync().ConfigureAwait(false); await using (request.ConfigureAwait(false)) { await serverFunc(request).ConfigureAwait(false); } }, millisecondsTimeout).ConfigureAwait(false); }
internal override async Task RunSingleStreamTest(Func <ValueHttpRequest, Uri, Task> clientFunc, Func <HttpTestStream, Task> serverFunc, int?millisecondsTimeout = null) { ConnectionFactory connectionFactory = CreateConnectionFactory(); await using (connectionFactory.ConfigureAwait(false)) { var server = new Http1TestServer(await connectionFactory.ListenAsync().ConfigureAwait(false)); await using (server.ConfigureAwait(false)) { var uriBuilder = new UriBuilder { Scheme = Uri.UriSchemeHttp, Path = "/" }; switch (server.EndPoint) { case DnsEndPoint dnsEp: uriBuilder.Host = dnsEp.Host; uriBuilder.Port = dnsEp.Port; break; case IPEndPoint ipEp: uriBuilder.Host = ipEp.Address.ToString(); uriBuilder.Port = ipEp.Port; break; default: uriBuilder.Host = "localhost"; uriBuilder.Port = 80; break; } Uri serverUri = uriBuilder.Uri; await RunClientServer(RunClientAsync, RunServerAsync, millisecondsTimeout).ConfigureAwait(false); async Task RunClientAsync() { HttpConnection connection = new Http1Connection(await connectionFactory.ConnectAsync(server.EndPoint !).ConfigureAwait(false)); await using (connection.ConfigureAwait(false)) { ValueHttpRequest?optionalRequest = await connection.CreateNewRequestAsync(HttpPrimitiveVersion.Version11, HttpVersionPolicy.RequestVersionExact).ConfigureAwait(false); Assert.NotNull(optionalRequest); ValueHttpRequest request = optionalRequest.Value; await using (request.ConfigureAwait(false)) { await clientFunc(request, serverUri).ConfigureAwait(false); await request.DrainAsync().ConfigureAwait(false); } } } async Task RunServerAsync() { HttpTestConnection connection = await server.AcceptAsync().ConfigureAwait(false); await using (connection.ConfigureAwait(false)) { HttpTestStream request = await connection.AcceptStreamAsync().ConfigureAwait(false); await using (request.ConfigureAwait(false)) { await serverFunc(request).ConfigureAwait(false); } } } } } }