Esempio n. 1
0
            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);
            }
Esempio n. 2
0
            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);
            }