예제 #1
0
        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);
                    }
                }
            }
예제 #4
0
        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);
        }
예제 #5
0
        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);
                            }
                        }
                    }
                }
            }
        }