cosmetics on http server

master
UbitUmarov 2020-07-24 17:12:38 +01:00
parent e0aff5e640
commit d9a680703f
2 changed files with 106 additions and 87 deletions

View File

@ -364,20 +364,18 @@ namespace OSHttpServer
continue; continue;
m_ReceiveBytesLeft += bytesRead; m_ReceiveBytesLeft += bytesRead;
if (m_ReceiveBytesLeft > m_ReceiveBuffer.Length)
throw new BadRequestException("HTTP header Too large: " + m_ReceiveBytesLeft);
int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft); int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft);
if (m_stream == null) if (m_stream == null)
return; // "Connection: Close" in effect. return; // "Connection: Close" in effect.
// try again to see if we can parse another message (check parser to see if it is looking for a new message) while (offset != 0)
int nextOffset;
int nextBytesleft = m_ReceiveBytesLeft - offset;
while (offset != 0 && nextBytesleft > 0)
{ {
nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft); int nextBytesleft = m_ReceiveBytesLeft - offset;
if(nextBytesleft <= 0)
break;
int nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft);
if (m_stream == null) if (m_stream == null)
return; // "Connection: Close" in effect. return; // "Connection: Close" in effect.
@ -386,7 +384,6 @@ namespace OSHttpServer
break; break;
offset = nextOffset; offset = nextOffset;
nextBytesleft = m_ReceiveBytesLeft - offset;
} }
// copy unused bytes to the beginning of the array // copy unused bytes to the beginning of the array

View File

@ -224,21 +224,24 @@ namespace OSHttpServer.Parser
m_log.Write(this, LogPrio.Warning, "HTTP Request is too large."); m_log.Write(this, LogPrio.Warning, "HTTP Request is too large.");
throw new BadRequestException("Too large request line."); throw new BadRequestException("Too large request line.");
} }
if (char.IsLetterOrDigit(ch) && startPos == -1) if (startPos == -1)
{
if(char.IsLetterOrDigit(ch))
startPos = currentPos; startPos = currentPos;
if (startPos == -1 && (ch != '\r' || nextCh != '\n')) else if (ch != '\r' || nextCh != '\n')
{ {
m_log.Write(this, LogPrio.Warning, "Request line is not found."); m_log.Write(this, LogPrio.Warning, "Request line is not found.");
throw new BadRequestException("Invalid request line."); throw new BadRequestException("Invalid request line.");
} }
if (startPos != -1 && (ch == '\r' || ch == '\n')) }
else if(ch == '\r' || ch == '\n')
{ {
int size = GetLineBreakSize(buffer, currentPos); int size = GetLineBreakSize(buffer, currentPos);
OnFirstLine(Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos)); OnFirstLine(Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos));
CurrentState = CurrentState + 1;
currentPos += size - 1; currentPos += size - 1;
handledBytes = currentPos + size - 1; handledBytes = currentPos;
startPos = -1; startPos = -1;
CurrentState = RequestParserState.HeaderName;
} }
break; break;
case RequestParserState.HeaderName: case RequestParserState.HeaderName:
@ -273,19 +276,20 @@ namespace OSHttpServer.Parser
} }
m_curHeaderName = Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos); m_curHeaderName = Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
handledBytes = currentPos + 1; handledBytes = currentPos + 1;
startPos = -1; startPos = handledBytes;
CurrentState = CurrentState + 1;
if (ch == ':') if (ch == ':')
CurrentState = CurrentState + 1; CurrentState = RequestParserState.Between;
else
CurrentState = RequestParserState.AfterName;
} }
else if (startPos == -1)
startPos = currentPos;
else if (!char.IsLetterOrDigit(ch) && ch != '-') else if (!char.IsLetterOrDigit(ch) && ch != '-')
{ {
m_log.Write(this, LogPrio.Warning, "Invalid character in header name on line " + currentLine); m_log.Write(this, LogPrio.Warning, "Invalid character in header name on line " + currentLine);
throw new BadRequestException("Invalid character in header name on line " + currentLine); throw new BadRequestException("Invalid character in header name on line " + currentLine);
} }
if (startPos != -1 && currentPos - startPos > 200) if (startPos == -1)
startPos = currentPos;
else if (currentPos - startPos > 200)
{ {
m_log.Write(this, LogPrio.Warning, "Invalid header name on line " + currentLine); m_log.Write(this, LogPrio.Warning, "Invalid header name on line " + currentLine);
throw new BadRequestException("Invalid header name on line " + currentLine); throw new BadRequestException("Invalid header name on line " + currentLine);
@ -295,40 +299,54 @@ namespace OSHttpServer.Parser
if (ch == ':') if (ch == ':')
{ {
handledBytes = currentPos + 1; handledBytes = currentPos + 1;
CurrentState = CurrentState + 1; startPos = currentPos;
CurrentState = RequestParserState.Between;
}
else if(currentPos - startPos > 256)
{
m_log.Write(this, LogPrio.Warning, "missing header aftername ':' " + currentLine);
throw new BadRequestException("missing header aftername ':' " + currentLine);
} }
break; break;
case RequestParserState.Between: case RequestParserState.Between:
{ {
if (ch == ' ' || ch == '\t') if (ch == ' ' || ch == '\t')
continue; {
if (currentPos - startPos > 256)
{
m_log.Write(this, LogPrio.Warning, "header value too far" + currentLine);
throw new BadRequestException("header value too far" + currentLine);
}
}
else
{
int newLineSize = GetLineBreakSize(buffer, currentPos); int newLineSize = GetLineBreakSize(buffer, currentPos);
if (newLineSize > 0 && currentPos + newLineSize < endOfBufferPos && if (newLineSize > 0 && currentPos + newLineSize < endOfBufferPos &&
char.IsWhiteSpace((char)buffer[currentPos + newLineSize])) char.IsWhiteSpace((char)buffer[currentPos + newLineSize]))
{ {
++currentPos; if (currentPos - startPos > 256)
continue; {
m_log.Write(this, LogPrio.Warning, "header value too" + currentLine);
throw new BadRequestException("header value too far" + currentLine);
} }
++currentPos;
}
else
{
startPos = currentPos; startPos = currentPos;
CurrentState = CurrentState + 1;
handledBytes = currentPos; handledBytes = currentPos;
continue; CurrentState = RequestParserState.HeaderValue;
}
}
break;
} }
case RequestParserState.HeaderValue: case RequestParserState.HeaderValue:
{ {
if (ch != '\r' && ch != '\n') if (ch == '\r' || ch == '\n')
continue; {
int newLineSize = GetLineBreakSize(buffer, currentPos);
if (startPos == -1)
continue; // allow new lines before start of value
if (m_curHeaderName == string.Empty) if (m_curHeaderName == string.Empty)
throw new BadRequestException("Missing header on line " + currentLine); throw new BadRequestException("Missing header on line " + currentLine);
if (startPos == -1)
{
m_log.Write(this, LogPrio.Warning, "Missing header value for '" + m_curHeaderName);
throw new BadRequestException("Missing header value for '" + m_curHeaderName);
}
if (currentPos - startPos > 8190) if (currentPos - startPos > 8190)
{ {
m_log.Write(this, LogPrio.Warning, "Too large header value on line " + currentLine); m_log.Write(this, LogPrio.Warning, "Too large header value on line " + currentLine);
@ -337,20 +355,21 @@ namespace OSHttpServer.Parser
// Header fields can be extended over multiple lines by preceding each extra line with at // Header fields can be extended over multiple lines by preceding each extra line with at
// least one SP or HT. // least one SP or HT.
int newLineSize = GetLineBreakSize(buffer, currentPos);
if (endOfBufferPos > currentPos + newLineSize if (endOfBufferPos > currentPos + newLineSize
&& (buffer[currentPos + newLineSize] == ' ' || buffer[currentPos + newLineSize] == '\t')) && (buffer[currentPos + newLineSize] == ' ' || buffer[currentPos + newLineSize] == '\t'))
{ {
if (startPos != -1) if (startPos != -1)
m_curHeaderValue = Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos); m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
m_log.Write(this, LogPrio.Trace, "Header value is on multiple lines."); m_log.Write(this, LogPrio.Trace, "Header value is on multiple lines.");
CurrentState = RequestParserState.Between; CurrentState = RequestParserState.Between;
startPos = -1;
currentPos += newLineSize - 1; currentPos += newLineSize - 1;
handledBytes = currentPos + newLineSize - 1; startPos = currentPos;
continue; handledBytes = currentPos;
} }
else
{
m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos); m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
m_log.Write(this, LogPrio.Trace, "Header [" + m_curHeaderName + ": " + m_curHeaderValue + "]"); m_log.Write(this, LogPrio.Trace, "Header [" + m_curHeaderName + ": " + m_curHeaderValue + "]");
OnHeader(m_curHeaderName, m_curHeaderValue); OnHeader(m_curHeaderName, m_curHeaderValue);
@ -359,14 +378,15 @@ namespace OSHttpServer.Parser
CurrentState = RequestParserState.HeaderName; CurrentState = RequestParserState.HeaderName;
m_curHeaderValue = string.Empty; m_curHeaderValue = string.Empty;
m_curHeaderName = string.Empty; m_curHeaderName = string.Empty;
++currentPos; currentPos += newLineSize - 1;
handledBytes = currentPos + 1; handledBytes = currentPos;
// Check if we got a colon so we can cut header name, or crlf for end of header. // Check if we got a colon so we can cut header name, or crlf for end of header.
bool canContinue = false; bool canContinue = false;
for (int j = currentPos; j < endOfBufferPos; ++j) for (int j = currentPos; j < endOfBufferPos; ++j)
{ {
if (buffer[j] != ':' && buffer[j] != '\r' && buffer[j] != '\n') continue; if (buffer[j] != ':' && buffer[j] != '\r' && buffer[j] != '\n')
continue;
canContinue = true; canContinue = true;
break; break;
} }
@ -376,6 +396,8 @@ namespace OSHttpServer.Parser
return currentPos + 1; return currentPos + 1;
} }
} }
}
}
break; break;
} }
} }