Esempio n. 1
0
        public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
        {
            newStep = null;

            int read = byteBuf.ReadToOrRollback(
                HttpHeaderConstants.CR,
                HttpHeaderConstants.LF,
                state.SecWebSocketKey /* output */,
                0 /* startIndex */,
                state.SecWebSocketKey.Length /* len */
                );

            if (read < 0)
            {
                return;
            }

            // Если буфер смог дочитать до CRLF, значит в нем точно есть еще как минимум 2 байта CRLF.
            // Читаем их, чтобы сдвинуть.
            byteBuf.ReadByte();
            byteBuf.ReadByte();

            state.SecWebSocketKeyHeaderValueMatched = true;
            state.SecWebSocketKeyLen = read;

            newStep = _crLfStep;
        }
Esempio n. 2
0
        private HttpMatchState CreateState()
        {
            // TODO:
            var state = new HttpMatchState();

            state.SecWebSocketKey = new byte[92];

            return(state);
        }
        public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
        {
            newStep = null;

            int skipped = byteBuf.SkipTo(
                HttpHeaderConstants.CR /* stopByte1 */,
                HttpHeaderConstants.LF /* stopByte2 */,
                true /* include */
                );

            // Если пропустить не удается (результат -1, т.е. буфер прерывается до окончания чтения),
            // то остаемся в этом же состоянии. Может при следующем входе удастся продолжить.
            if (skipped < 0)
            {
                return;
            }

            newStep = _crLfStep;
        }
Esempio n. 4
0
        public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
        {
            newStep = null;

            // Далее как минимум должны следовать либо 2 байта CRLF, либо следующий заголовок со значением,
            // где тоже должно быть гораздо больше байт, с учетом того,
            // что название и значение разделено 2 байтами ": ".
            if (byteBuf.ReadableBytes() < 2)
            {
                return;
            }

            // Читаем следующие 2 байта.
            byte nextByte1 = byteBuf.ReadByte();
            byte nextByte2 = byteBuf.ReadByte();

            // Если CRLF - значит это второй CRLF, который по стандарту означает начало тела HTTP.
            // Но в нашем случае, тело нас не интересует, мы прочитали заголовки.
            if (nextByte1 == HttpHeaderConstants.CR && nextByte2 == HttpHeaderConstants.LF)
            {
                newStep = _finishStep;
                return;
            }

            // TODO: нормальные исключения
            if (nextByte1 == HttpHeaderConstants.CR && nextByte2 != HttpHeaderConstants.LF)
            {
                throw new Exception();
            }

            if (nextByte1 != HttpHeaderConstants.CR && nextByte2 == HttpHeaderConstants.LF)
            {
                throw new Exception();
            }

            // Если далее идут не CRLF, значит идет следующий заголовок.
            // Возвращаем чтение буфера на 2 байта обратно.
            byteBuf.Back(2);

            newStep = _httpHeaderNameMatchStep;
        }
 public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
 {
     newStep = _skipToCrLfStep;
 }
        public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
        {
            newStep = null;

            bool colonAndWhitespace = false;
            bool crlf          = false;
            bool allNotMatched = false;

            while (byteBuf.ReadableBytes() > 0)
            {
                if (!_firstByte)
                {
                    _firstByte = true;

                    _connectionHeaderMatched          = true;
                    _upgradeHeaderMatched             = true;
                    _secWebSocketVersionHeaderMatched = true;
                    _secWebSocketKeyHeaderMatched     = true;
                }

                byte nextByte = byteBuf.ReadByte();

                #region ": "

                if (nextByte == HttpHeaderConstants.Whitespace)
                {
                    if (_lastByteIsColon)
                    {
                        colonAndWhitespace = true;
                        break;
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                if (nextByte == HttpHeaderConstants.Colon)
                {
                    _lastByteIsColon = true;
                    continue;
                }
                else
                {
                    _lastByteIsColon   = false;
                    colonAndWhitespace = false;
                }

                #endregion

                #region CRLF

                if (nextByte == HttpHeaderConstants.LF)
                {
                    if (_lastByteIsCR)
                    {
                        crlf = true;
                        break;
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                if (nextByte == HttpHeaderConstants.CR)
                {
                    _lastByteIsCR = true;
                    continue;
                }
                else
                {
                    _lastByteIsCR = false;
                    crlf          = false;
                }

                #endregion

                #region Headers matching

                if (!_skipConnectionHeader)
                {
                    _connectionHeaderMatched &=
                        ConnectionHeaderLen > _index &&
                        (nextByte == HttpHeaderConstants.ConnectionLower[_index] ||
                         nextByte == HttpHeaderConstants.ConnectionUpper[_index]);
                    if (!_connectionHeaderMatched)
                    {
                        _skipConnectionHeader = true;
                    }
                }

                if (!_skipUpgradeHeader)
                {
                    _upgradeHeaderMatched &=
                        UpgradeHeaderLen > _index &&
                        (nextByte == HttpHeaderConstants.UpgradeLower[_index] ||
                         nextByte == HttpHeaderConstants.UpgradeUpper[_index]);
                    if (!_upgradeHeaderMatched)
                    {
                        _skipUpgradeHeader = true;
                    }
                }

                if (!_skipSecWebSocketVersionHeader)
                {
                    _secWebSocketVersionHeaderMatched &=
                        SecWebSocketVersionHeaderLen > _index &&
                        (nextByte == HttpHeaderConstants.SecWebsocketVersionLower[_index] ||
                         nextByte == HttpHeaderConstants.SecWebsocketVersionUpper[_index]);
                    if (!_secWebSocketVersionHeaderMatched)
                    {
                        _skipSecWebSocketVersionHeader = true;
                    }
                }

                if (!_skipSecWebSocketKeyHeader)
                {
                    _secWebSocketKeyHeaderMatched &=
                        SecWebSocketKeyHeaderLen > _index &&
                        (nextByte == HttpHeaderConstants.SecWebsocketKeyLower[_index] ||
                         nextByte == HttpHeaderConstants.SecWebsocketKeyUpper[_index]);
                    if (!_secWebSocketKeyHeaderMatched)
                    {
                        _skipSecWebSocketKeyHeader = true;
                    }
                }

                #endregion

                allNotMatched =
                    !_connectionHeaderMatched &&
                    !_upgradeHeaderMatched &&
                    !_secWebSocketVersionHeaderMatched &&
                    !_secWebSocketKeyHeaderMatched;
                if (allNotMatched)
                {
                    break;
                }

                _index++;
            }

            if (crlf)
            {
                throw new Exception();
            }

            if (allNotMatched)
            {
                newStep = _skipToCrLfMatchStep;
                return;
            }

            if (colonAndWhitespace)
            {
                if (_connectionHeaderMatched)
                {
                    state.ConnectionHeaderMatched = true;
                    newStep = _connectionHeaderValueMatchStep;
                }
                else if (_upgradeHeaderMatched)
                {
                    state.UpgradeHeaderMatched = true;
                    newStep = _upgradeHeaderValueMatchStep;
                }
                else if (_secWebSocketVersionHeaderMatched)
                {
                    state.SecWebSocketVersionHeaderMatched = true;
                    newStep = _secWebSocketVersionHeaderValueMatchStep;
                }
                else if (_secWebSocketKeyHeaderMatched)
                {
                    state.SecWebSocketKeyHeaderMatched = true;
                    newStep = _secWebSocketKeyHeaderValueMatchStep;
                }
                else
                {
                    newStep = _skipToCrLfMatchStep;
                }
            }
        }
        public void Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
        {
            newStep = null;

            bool crlf       = false;
            bool matched    = false;
            bool notMatched = false;

            while (byteBuf.ReadableBytes() > 0)
            {
                if (!_firstByte)
                {
                    _firstByte                    = true;
                    _index                        = 0;
                    _headerValueMatched           = true;
                    _headerValueMatchedCurrent    = false;
                    _skipToNextCommaAndWhitespace = false;
                }

                byte nextByte = byteBuf.ReadByte();

                #region CRLF

                if (nextByte == HttpHeaderConstants.LF)
                {
                    if (_lastByteIsCR)
                    {
                        crlf = true;
                        _skipToNextCommaAndWhitespace = false;
                        break;
                    }

                    throw new Exception();
                }
                if (nextByte == HttpHeaderConstants.CR)
                {
                    _lastByteIsCR = true;
                    continue;
                }

                _lastByteIsCR = false;

                #endregion

                if (nextByte == HttpHeaderConstants.Comma || nextByte == HttpHeaderConstants.Whitespace)
                {
                    if (_headerValueMatchedCurrent)
                    {
                        matched = true;
                        _skipToNextCommaAndWhitespace = false;
                        break;
                    }

                    _firstByte = false;
                    continue;
                }

                if (!_skipToNextCommaAndWhitespace)
                {
                    _headerValueMatched &=
                        _headerValueLen > _index &&
                        (nextByte == _headerValueLower[_index] ||
                         nextByte == _headerValueUpper[_index]);
                    if (!_headerValueMatched)
                    {
                        _headerValueMatchedCurrent    = false;
                        _skipToNextCommaAndWhitespace = true;
                    }
                    else
                    {
                        if (_index == _headerValueLen - 1)
                        {
                            _headerValueMatchedCurrent = true;
                        }
                    }
                }

                _index++;
            }

            matched |= crlf && _headerValueMatchedCurrent;

            if (!matched && !_headerValueMatched && !_skipToNextCommaAndWhitespace)
            {
                notMatched = true;
            }

            if (matched)
            {
                Matched(crlf, ref state, out newStep);
            }

            if (notMatched)
            {
                NotMatched(crlf, ref state, out newStep);
            }
        }
 abstract protected void NotMatched(bool crLf, ref HttpMatchState state, out IHttpMatchStep newStep);
Esempio n. 9
0
        public HttpMatcher()
        {
            var httpHeaderNameMatchStep                 = new HttpHeaderNameMatchStep();
            var skipToCrLfStep                          = new HttpSkipToCrLfStep();
            var connectionHeaderValueMatchStep          = new HttpConnectionHeaderValueMatchStep();
            var upgradeHeaderValueMatchStep             = new HttpUpgradeHeaderValueMatchStep();
            var secWebSocketVersionHeaderValueMatchStep = new HttpSecWebSocketVersionHeaderValueMatchStep();
            var secWebSocketKeyHeaderValueMatchStep     = new HttpSecWebSocketKeyHeaderValueMatchStep();
            var crLfStep = new HttpCrLfStep();

            _httpHeaderNameMatchStep                 = httpHeaderNameMatchStep;
            _skipToCrLfStep                          = skipToCrLfStep;
            _connectionHeaderValueMatchStep          = connectionHeaderValueMatchStep;
            _upgradeHeaderValueMatchStep             = upgradeHeaderValueMatchStep;
            _secWebSocketVersionHeaderValueMatchStep = secWebSocketVersionHeaderValueMatchStep;
            _secWebSocketKeyHeaderValueMatchStep     = secWebSocketKeyHeaderValueMatchStep;
            _crLfStep   = crLfStep;
            _finishStep = this;

            httpHeaderNameMatchStep.Init(
                _skipToCrLfStep,
                _connectionHeaderValueMatchStep,
                _upgradeHeaderValueMatchStep,
                _secWebSocketVersionHeaderValueMatchStep,
                _secWebSocketKeyHeaderValueMatchStep
                );

            skipToCrLfStep.Init(
                _crLfStep
                );

            connectionHeaderValueMatchStep.Init(
                _crLfStep,
                _skipToCrLfStep,
                _finishStep
                );

            upgradeHeaderValueMatchStep.Init(
                _crLfStep,
                _skipToCrLfStep,
                _finishStep
                );

            secWebSocketVersionHeaderValueMatchStep.Init(
                _crLfStep,
                _skipToCrLfStep,
                _finishStep
                );

            secWebSocketKeyHeaderValueMatchStep.Init(
                _crLfStep
                );

            crLfStep.Init(
                _finishStep,
                _httpHeaderNameMatchStep
                );

            _state = CreateState();

            _currentStep = _skipToCrLfStep;
        }
Esempio n. 10
0
 void IHttpMatchStep.Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep)
 {
     newStep = null;
 }