public async Task <Frame> ReadFrameAsync(TimeSpan timeout) { // Prep the timeout cancellation token. CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout); // First read the frame headers, which should tell us how long the rest of the frame is. byte[] headerBytes = new byte[Frame.FrameHeaderLength]; int totalReadBytes = 0; while (totalReadBytes < Frame.FrameHeaderLength) { int readBytes = await _connectionStream.ReadAsync(headerBytes, totalReadBytes, Frame.FrameHeaderLength - totalReadBytes, timeoutCts.Token).ConfigureAwait(false); totalReadBytes += readBytes; if (readBytes == 0) { throw new Exception("Connection stream closed while attempting to read frame header."); } } Frame header = Frame.ReadFrom(headerBytes); // Read the data segment of the frame, if it is present. byte[] data = new byte[header.Length]; totalReadBytes = 0; while (totalReadBytes < header.Length) { int readBytes = await _connectionStream.ReadAsync(data, totalReadBytes, header.Length - totalReadBytes, timeoutCts.Token).ConfigureAwait(false); totalReadBytes += readBytes; if (readBytes == 0) { throw new Exception("Connection stream closed while attempting to read frame body."); } } // Construct the correct frame type and return it. switch (header.Type) { case FrameType.Data: return(DataFrame.ReadFrom(header, data)); case FrameType.Headers: return(HeadersFrame.ReadFrom(header, data)); case FrameType.Priority: return(PriorityFrame.ReadFrom(header, data)); case FrameType.RstStream: return(RstStreamFrame.ReadFrom(header, data)); case FrameType.Ping: return(PingFrame.ReadFrom(header, data)); default: return(header); } }
public async Task SendDefaultResponseAsync(int streamId) { byte[] headers = new byte[] { 0x88 }; // Encoding for ":status: 200" HeadersFrame headersFrame = new HeadersFrame(headers, FrameFlags.EndHeaders | FrameFlags.EndStream, 0, 0, 0, streamId); await WriteFrameAsync(headersFrame).ConfigureAwait(false); }
public async Task <Frame> ReadFrameAsync(TimeSpan timeout) { // Prep the timeout cancellation token. CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout); // First read the frame headers, which should tell us how long the rest of the frame is. byte[] headerBytes = new byte[Frame.FrameHeaderLength]; if (!await FillBufferAsync(headerBytes, timeoutCts.Token).ConfigureAwait(false)) { return(null); } Frame header = Frame.ReadFrom(headerBytes); // Read the data segment of the frame, if it is present. byte[] data = new byte[header.Length]; if (header.Length > 0 && !await FillBufferAsync(data, timeoutCts.Token).ConfigureAwait(false)) { throw new Exception("Connection stream closed while attempting to read frame body."); } if (_ignoreSettingsAck && header.Type == FrameType.Settings && header.Flags == FrameFlags.Ack) { _ignoreSettingsAck = false; return(await ReadFrameAsync(timeout)); } if (_ignoreWindowUpdates && header.Type == FrameType.WindowUpdate) { return(await ReadFrameAsync(timeout)); } // Construct the correct frame type and return it. switch (header.Type) { case FrameType.Data: return(DataFrame.ReadFrom(header, data)); case FrameType.Headers: return(HeadersFrame.ReadFrom(header, data)); case FrameType.Priority: return(PriorityFrame.ReadFrom(header, data)); case FrameType.RstStream: return(RstStreamFrame.ReadFrom(header, data)); case FrameType.Ping: return(PingFrame.ReadFrom(header, data)); case FrameType.GoAway: return(GoAwayFrame.ReadFrom(header, data)); default: return(header); } }
public async Task <int> ReadRequestHeaderAsync(bool expectEndOfStream = true) { HeadersFrame frame = await ReadRequestHeaderFrameAsync(expectEndOfStream); return(frame.StreamId); }
public async Task <Frame> ReadFrameAsync(CancellationToken cancellationToken) { // First read the frame headers, which should tell us how long the rest of the frame is. byte[] headerBytes = new byte[Frame.FrameHeaderLength]; try { if (!await FillBufferAsync(headerBytes, cancellationToken).ConfigureAwait(false)) { return(null); } } catch (IOException) { // eat errors when client aborts connection and return null. return(null); } Frame header = Frame.ReadFrom(headerBytes); // Read the data segment of the frame, if it is present. byte[] data = new byte[header.Length]; if (header.Length > 0 && !await FillBufferAsync(data, cancellationToken).ConfigureAwait(false)) { throw new Exception("Connection stream closed while attempting to read frame body."); } if (_ignoredSettingsAckPromise != null && header.Type == FrameType.Settings && header.Flags == FrameFlags.Ack) { _ignoredSettingsAckPromise.TrySetResult(true); _ignoredSettingsAckPromise = null; return(await ReadFrameAsync(cancellationToken).ConfigureAwait(false)); } if (_ignoreWindowUpdates && header.Type == FrameType.WindowUpdate) { return(await ReadFrameAsync(cancellationToken).ConfigureAwait(false)); } if (header.Type == FrameType.Ping && _transparentPingResponse) { PingFrame pingFrame = PingFrame.ReadFrom(header, data); bool processed = await TryProcessExpectedPingFrameAsync(pingFrame); return(processed ? await ReadFrameAsync(cancellationToken).ConfigureAwait(false) : pingFrame); } // Construct the correct frame type and return it. switch (header.Type) { case FrameType.Settings: return(SettingsFrame.ReadFrom(header, data)); case FrameType.Data: return(DataFrame.ReadFrom(header, data)); case FrameType.Headers: return(HeadersFrame.ReadFrom(header, data)); case FrameType.Priority: return(PriorityFrame.ReadFrom(header, data)); case FrameType.RstStream: return(RstStreamFrame.ReadFrom(header, data)); case FrameType.Ping: return(PingFrame.ReadFrom(header, data)); case FrameType.GoAway: return(GoAwayFrame.ReadFrom(header, data)); case FrameType.Continuation: return(ContinuationFrame.ReadFrom(header, data)); case FrameType.WindowUpdate: return(WindowUpdateFrame.ReadFrom(header, data)); default: return(header); } }
public async Task <int> ReadRequestHeaderAsync() { HeadersFrame frame = await ReadRequestHeaderFrameAsync(); return(frame.StreamId); }