public async Task ContinuationsWithoutHeadersShouldLeadToGoAway() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); Func <IStream, bool> listener = (s) => true; var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener); var hEncoder = new Encoder(); await inPipe.WriteContinuation(hEncoder, 1u, DefaultGetHeaders, true); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0); await outPipe.AssertStreamEnd(); }
public async Task ContinuationFrameHeadersShouldBeAddedToTotalHeaders( int[] nrHeadersInFrame) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); IStream stream = null; IEnumerable <HeaderField> receivedHeaders = null; SemaphoreSlim handlerDone = new SemaphoreSlim(0); Func <IStream, bool> listener = (s) => { stream = s; Task.Run(async() => { receivedHeaders = await s.ReadHeadersAsync(); handlerDone.Release(); }); return(true); }; var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener); var hEncoder = new Encoder(); var totalHeaders = DefaultGetHeaders; var isContinuation = false; var toSkip = 0; var isEndOfHeaders = false; for (var frameNr = 0; frameNr <= nrHeadersInFrame.Length; frameNr++) { var headersToSend = totalHeaders.Skip(toSkip); if (frameNr != nrHeadersInFrame.Length) { var toSend = nrHeadersInFrame[frameNr]; headersToSend = headersToSend.Take(toSend); toSkip += toSend; } else { // send remaining headers isEndOfHeaders = true; } if (!isContinuation) { await inPipe.WriteHeaders( hEncoder, 1, false, headersToSend, isEndOfHeaders); isContinuation = true; } else { await inPipe.WriteContinuation( hEncoder, 1, headersToSend, isEndOfHeaders); } } var handlerCompleted = await handlerDone.WaitAsync( ReadableStreamTestExtensions.ReadTimeout); Assert.True(handlerCompleted, "Expected stream handler to complete"); Assert.True( totalHeaders.SequenceEqual(receivedHeaders), "Expected to receive all sent headers"); }
public async Task MaxHeaderListSizeViolationsShouldBeDetected( uint maxHeaderListSize, int headersInFirstFrame, int headersInContFrame, bool shouldError) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); Func <IStream, bool> listener = (s) => true; var settings = Settings.Default; settings.MaxHeaderListSize = maxHeaderListSize; var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener, localSettings : settings, huffmanStrategy : HuffmanStrategy.Never); var hEncoder = new Encoder(); var headers = new List <HeaderField>(); // Add the default headers // These take 123 bytes in store and 3 bytes in transmission headers.AddRange(new HeaderField[] { new HeaderField { Name = ":method", Value = "GET" }, new HeaderField { Name = ":path", Value = "/" }, new HeaderField { Name = ":scheme", Value = "http" }, }); var currentHeadersLength = headers .Select(hf => hf.Name.Length + hf.Value.Length + 32) .Sum(); // Create a header which takes 34 bytes in store and 5 bytes in transmission var extraHeader = new HeaderField { Name = "a", Value = "b", Sensitive = true }; while (currentHeadersLength < headersInFirstFrame) { headers.Add(extraHeader); currentHeadersLength += 1 + 1 + 32; } await inPipe.WriteHeaders( hEncoder, 1, false, headers, headersInContFrame == 0); if (headersInContFrame != 0) { headers.Clear(); currentHeadersLength = 0; while (currentHeadersLength < headersInContFrame) { headers.Add(extraHeader); currentHeadersLength += 1 + 1 + 32; } await inPipe.WriteContinuation( hEncoder, 1, headers, true); } if (shouldError) { // TODO: The spec says actually the remote should answer with // an HTTP431 error - but that happens on another layer await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u); await outPipe.AssertStreamEnd(); } else { await inPipe.WritePing(new byte[8], false); await outPipe.ReadAndDiscardPong(); } }