nameof(HeaderNames.Origin), "server.example.com")] // no authority public async Task WebTransportHandshake_IncorrectHeadersRejects(long error, string targetErrorMessage, params string[] headers) { _serviceContext.ServerOptions.EnableWebTransportAndH3Datagrams = true; await Http3Api.InitializeConnectionAsync(_noopApplication); var controlStream = await Http3Api.CreateControlStream(); var controlStream2 = await Http3Api.GetInboundControlStream(); var settings = new Http3PeerSettings() { EnableWebTransport = 1, H3Datagram = 1, }; await controlStream.SendSettingsAsync(settings.GetNonProtocolDefaults()); var response1 = await controlStream2.ExpectSettingsAsync(); await Http3Api.ServerReceivedSettingsReader.ReadAsync().DefaultTimeout(); Assert.Equal(1, response1[(long)Http3SettingType.EnableWebTransport]); var headersConnectFrame = new List <KeyValuePair <string, string> >(); for (var i = 0; i < headers.Length; i += 2) { headersConnectFrame.Add(new KeyValuePair <string, string>(GetHeaderFromName(headers[i]), headers[i + 1])); } var requestStream = await Http3Api.CreateRequestStream(headersConnectFrame); await requestStream.WaitForStreamErrorAsync((Http3ErrorCode)error, AssertExpectedErrorMessages, GetCoreStringFromName(targetErrorMessage)); }
public static async ValueTask <WebTransportSession> GenerateSession(Http3InMemory inMemory, TaskCompletionSource exitSessionTcs) { var appCompletedTcs = new TaskCompletionSource <IWebTransportSession>(TaskCreationOptions.RunContinuationsAsynchronously); await inMemory.InitializeConnectionAsync(async context => { var webTransportFeature = context.Features.GetRequiredFeature <IHttpWebTransportFeature>(); #pragma warning disable CA2252 // This API requires opting into preview features try { var session = await webTransportFeature.AcceptAsync(CancellationToken.None).DefaultTimeout(); appCompletedTcs.SetResult(session); } catch (TimeoutException exception) { appCompletedTcs.SetException(exception); } #pragma warning restore CA2252 // wait for the test to tell us to kill the application await exitSessionTcs.Task; }); var controlStream = await inMemory.CreateControlStream(); var controlStream2 = await inMemory.GetInboundControlStream(); var settings = new Http3PeerSettings() { EnableWebTransport = 1, H3Datagram = 1, }; await controlStream.SendSettingsAsync(settings.GetNonProtocolDefaults()); var response1 = await controlStream2.ExpectSettingsAsync(); await inMemory.ServerReceivedSettingsReader.ReadAsync().DefaultTimeout(); var requestStream = await inMemory.CreateRequestStream(new[] { new KeyValuePair <string, string>(InternalHeaderNames.Method, "CONNECT"), new KeyValuePair <string, string>(InternalHeaderNames.Protocol, "webtransport"), new KeyValuePair <string, string>(InternalHeaderNames.Scheme, "http"), new KeyValuePair <string, string>(InternalHeaderNames.Path, "/"), new KeyValuePair <string, string>(InternalHeaderNames.Authority, "server.example.com"), new KeyValuePair <string, string>(HeaderNames.Origin, "server.example.com"), new KeyValuePair <string, string>(WebTransportSession.CurrentSuppportedVersion, "1") }); return((WebTransportSession)await appCompletedTcs.Task); }
public async Task WriteSettings_NoSettingsWrittenWithProtocolDefault() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = CreateFrameWriter(pipe); var settings = new Http3PeerSettings(); await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); var payload = await pipe.Reader.ReadForLengthAsync(2); Assert.Equal(new byte[] { 0x04, 0x00 }, payload.ToArray()); }
public Http3StreamContext( string connectionId, HttpProtocols protocols, ConnectionContext connectionContext, ServiceContext serviceContext, IFeatureCollection connectionFeatures, MemoryPool <byte> memoryPool, IPEndPoint?localEndPoint, IPEndPoint?remoteEndPoint, IDuplexPipe transport, ConnectionContext streamContext, Http3PeerSettings settings) : base(connectionId, protocols, connectionContext, serviceContext, connectionFeatures, memoryPool, localEndPoint, remoteEndPoint, transport) { StreamContext = streamContext; ServerSettings = settings; }
public async Task WriteSettings_TwoSettingsWritten() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = CreateFrameWriter(pipe); var settings = new Http3PeerSettings(); settings.HeaderTableSize = 1234; settings.MaxRequestHeaderFieldSize = 567890; await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); // variable length ints make it so the results isn't know without knowing the values var payload = await pipe.Reader.ReadForLengthAsync(10); Assert.Equal(new byte[] { 0x04, 0x08, 0x01, 0x44, 0xD2, 0x06, 0x80, 0x08, 0xAA, 0x52 }, payload.ToArray()); }
public async Task WriteSettings_OneSettingsWrittenWithKestrelDefaults() { var pipe = new Pipe(new PipeOptions(_dirtyMemoryPool, PipeScheduler.Inline, PipeScheduler.Inline)); var frameWriter = CreateFrameWriter(pipe); var limits = new Http3Limits(); var settings = new Http3PeerSettings(); settings.HeaderTableSize = (uint)limits.HeaderTableSize; settings.MaxRequestHeaderFieldSize = (uint)limits.MaxRequestHeaderFieldSize; await frameWriter.WriteSettingsAsync(settings.GetNonProtocolDefaults()); // variable length ints make it so the results isn't know without knowing the values var payload = await pipe.Reader.ReadForLengthAsync(5); Assert.Equal(new byte[] { 0x04, 0x03, 0x06, 0x60, 0x00 }, payload.ToArray()); }
public async Task WebTransportHandshake_ClientToServerPasses() { _serviceContext.ServerOptions.EnableWebTransportAndH3Datagrams = true; await Http3Api.InitializeConnectionAsync(_noopApplication); var controlStream = await Http3Api.CreateControlStream(); var controlStream2 = await Http3Api.GetInboundControlStream(); var settings = new Http3PeerSettings() { EnableWebTransport = 1, H3Datagram = 1, }; await controlStream.SendSettingsAsync(settings.GetNonProtocolDefaults()); var response1 = await controlStream2.ExpectSettingsAsync(); await Http3Api.ServerReceivedSettingsReader.ReadAsync().DefaultTimeout(); Assert.Equal(1, response1[(long)Http3SettingType.EnableWebTransport]); var requestStream = await Http3Api.CreateRequestStream(); var headersConnectFrame = new[] { new KeyValuePair <string, string>(HeaderNames.Method, "CONNECT"), new KeyValuePair <string, string>(HeaderNames.Protocol, "webtransport"), new KeyValuePair <string, string>(HeaderNames.Scheme, "http"), new KeyValuePair <string, string>(HeaderNames.Path, "/"), new KeyValuePair <string, string>(HeaderNames.Authority, "server.example.com"), new KeyValuePair <string, string>(HeaderNames.Origin, "server.example.com") }; await requestStream.SendHeadersAsync(headersConnectFrame); var response2 = await requestStream.ExpectHeadersAsync(); Assert.Equal((int)HttpStatusCode.OK, Convert.ToInt32(response2[HeaderNames.Status], null)); await requestStream.OnDisposedTask.DefaultTimeout(); }
public Http3StreamContext( string connectionId, HttpProtocols protocols, AltSvcHeader?altSvcHeader, BaseConnectionContext connectionContext, ServiceContext serviceContext, IFeatureCollection connectionFeatures, MemoryPool <byte> memoryPool, IPEndPoint?localEndPoint, IPEndPoint?remoteEndPoint, IHttp3StreamLifetimeHandler streamLifetimeHandler, ConnectionContext streamContext, Http3PeerSettings clientPeerSettings, Http3PeerSettings serverPeerSettings) : base(connectionId, protocols, altSvcHeader, connectionContext, serviceContext, connectionFeatures, memoryPool, localEndPoint, remoteEndPoint) { StreamLifetimeHandler = streamLifetimeHandler; StreamContext = streamContext; ClientPeerSettings = clientPeerSettings; ServerPeerSettings = serverPeerSettings; }
public Http3ControlStream(Http3StreamContext context) { var httpLimits = context.ServiceContext.ServerOptions.Limits; _context = context; _serverPeerSettings = context.ServerPeerSettings; _streamIdFeature = context.ConnectionFeatures.GetRequiredFeature <IStreamIdFeature>(); _errorCodeFeature = context.ConnectionFeatures.GetRequiredFeature <IProtocolErrorCodeFeature>(); _headerType = -1; _frameWriter = new Http3FrameWriter( context.StreamContext, context.TimeoutControl, httpLimits.MinResponseDataRate, context.MemoryPool, context.ServiceContext.Log, _streamIdFeature, context.ClientPeerSettings, this); _frameWriter.Reset(context.Transport.Output, context.ConnectionId); }
public async Task WebTransportHandshake_ClientToServerPasses() { _serviceContext.ServerOptions.EnableWebTransportAndH3Datagrams = true; var appCompletedTcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); await Http3Api.InitializeConnectionAsync(async context => { var success = true; var webTransportFeature = context.Features.GetRequiredFeature <IHttpWebTransportFeature>(); success &= webTransportFeature.IsWebTransportRequest; #pragma warning disable CA2252 // This API requires opting into preview features try { var session = await webTransportFeature.AcceptAsync(CancellationToken.None).DefaultTimeout(); // todo session is null here success &= session is not null; appCompletedTcs.SetResult(success); } catch (TimeoutException) { appCompletedTcs.SetResult(false); } #pragma warning restore CA2252 }); var controlStream = await Http3Api.CreateControlStream(); var controlStream2 = await Http3Api.GetInboundControlStream(); var settings = new Http3PeerSettings() { EnableWebTransport = 1, H3Datagram = 1, }; await controlStream.SendSettingsAsync(settings.GetNonProtocolDefaults()); var response1 = await controlStream2.ExpectSettingsAsync(); await Http3Api.ServerReceivedSettingsReader.ReadAsync().DefaultTimeout(); Assert.Equal(1, response1[(long)Http3SettingType.EnableWebTransport]); var requestStream = await Http3Api.CreateRequestStream(new[] { new KeyValuePair <string, string>(InternalHeaderNames.Method, "CONNECT"), new KeyValuePair <string, string>(InternalHeaderNames.Protocol, "webtransport"), new KeyValuePair <string, string>(InternalHeaderNames.Scheme, "http"), new KeyValuePair <string, string>(InternalHeaderNames.Path, "/"), new KeyValuePair <string, string>(InternalHeaderNames.Authority, "server.example.com"), new KeyValuePair <string, string>(HeaderNames.Origin, "server.example.com"), new KeyValuePair <string, string>(WebTransportSession.CurrentSuppportedVersion, "1") }); var response2 = await requestStream.ExpectHeadersAsync(); Assert.Equal((int)HttpStatusCode.OK, Convert.ToInt32(response2[InternalHeaderNames.Status], null)); await requestStream.OnDisposedTask.DefaultTimeout(); Assert.True(await appCompletedTcs.Task); }