public override DataFrame Read() { DataFrame frame = null; try { if (_chunks == null || !_chunks.MoveNext()) { if (_isTransparent) { _chunks = BaseHttpDataAdapter.ReadFrames(null, _reader).GetEnumerator(); } else { _currentHeader = HttpParser.ReadResponseHeader(_reader, _layer._config.ResponseStrictParsing, _logger); HttpRequestHeader request = null; lock (_requests) { if (_requests.Count > 0) { // If we have a queued request then dequeue and set head response request = _requests.Dequeue(); } } lock (_requestStream) { if (request == null) { try { _requestStream.Position = 0; request = HttpParser.ReadRequestHeader(new DataReader(_requestStream), false, _logger); } catch (EndOfStreamException) { // Ignore end of stream, might just mean we sent garbage to the server which we can't parse } } _requestStream.SetLength(0); } if (request != null) { _currentHeader.SetHeadRequest(request.IsHead); _currentHeader.SetConnectRequest(request.IsConnect); if (_currentHeader.Is100Continue) { // If a 100 status response then requeue the request lock (_requests) { HttpRequestHeader[] headers = _requests.ToArray(); _requests.Clear(); // Unlikely that another request will come as client is probably waiting for 100 status, but might as well be sure _requests.Enqueue(request); foreach (HttpRequestHeader head in headers) { _requests.Enqueue(head); } } } } if (_currentHeader.IsUpgradeResponse) { _layer._upgrading = true; _isTransparent = true; } _chunks = _currentHeader.ReadFrames(CreateConfig(_currentHeader, request)).GetEnumerator(); } if (!_chunks.MoveNext()) { throw new EndOfStreamException(); } } frame = _chunks.Current; } catch (EndOfStreamException) { frame = null; } return(frame); }
public override DataFrame Read() { DataFrame frame = null; try { if (_chunks == null || !_chunks.MoveNext()) { char firstChar = _reader.ReadChar(); // Check whether we need to upgrade the connection to raw data, could even at this point actually implement // TLS upgrade (and put back the HTTP parser on top?) if (_isTransparent) { // If transparent send the first chunk along and don't increment enumerator _chunks = BaseHttpDataAdapter.ReadFrames(new DataFrame(new byte[] { (byte)firstChar }), _reader).GetEnumerator(); } else { _currentHeader = HttpParser.ReadRequestHeader(_reader, _layer._config.RequestStrictParsing, _logger, new char[] { firstChar }); if (_currentHeader.Version.IsVersion11 && _layer._config.Handle100Continue) { bool sendResponse = false; int i = 0; while (i < _currentHeader.Headers.Count) { KeyDataPair <string> header = _currentHeader.Headers[i]; // Remove expect headers if (header.Name.Equals("Expect", StringComparison.OrdinalIgnoreCase) && header.Value.Equals("100-continue", StringComparison.OrdinalIgnoreCase)) { _currentHeader.Headers.RemoveAt(i); sendResponse = true; } else { i++; } } if (sendResponse) { _adapter.Write(new DataFrame("HTTP/1.1 100 Continue\r\n\r\n")); } } _chunks = _currentHeader.ReadFrames(CreateConfig(_currentHeader)).GetEnumerator(); } // Increment to next chunk if (!_chunks.MoveNext()) { throw new EndOfStreamException(); } } frame = _chunks.Current; } catch (EndOfStreamException) { frame = null; } return(frame); }