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; }
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; }
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);
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; }
void IHttpMatchStep.Match(ByteBuf byteBuf, ref HttpMatchState state, out IHttpMatchStep newStep) { newStep = null; }