Rewritten HTTPServer to use size_t for data lengths.
This commit is contained in:
parent
0d916a3e2f
commit
1795cca552
@ -20,7 +20,7 @@ cEnvelopeParser::cEnvelopeParser(cCallbacks & a_Callbacks) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cEnvelopeParser::Parse(const char * a_Data, int a_Size)
|
size_t cEnvelopeParser::Parse(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
if (!m_IsInHeaders)
|
if (!m_IsInHeaders)
|
||||||
{
|
{
|
||||||
@ -55,7 +55,7 @@ int cEnvelopeParser::Parse(const char * a_Data, int a_Size)
|
|||||||
{
|
{
|
||||||
// An error has occurred
|
// An error has occurred
|
||||||
m_IsInHeaders = false;
|
m_IsInHeaders = false;
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
Last = idxCRLF + 2;
|
Last = idxCRLF + 2;
|
||||||
idxCRLF = m_IncomingData.find("\r\n", idxCRLF + 2);
|
idxCRLF = m_IncomingData.find("\r\n", idxCRLF + 2);
|
||||||
|
@ -19,7 +19,9 @@ public:
|
|||||||
class cCallbacks
|
class cCallbacks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Called when a full header line is parsed
|
virtual ~cCallbacks() {}
|
||||||
|
|
||||||
|
/** Called when a full header line is parsed */
|
||||||
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0;
|
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
@ -27,40 +29,41 @@ public:
|
|||||||
cEnvelopeParser(cCallbacks & a_Callbacks);
|
cEnvelopeParser(cCallbacks & a_Callbacks);
|
||||||
|
|
||||||
/** Parses the incoming data.
|
/** Parses the incoming data.
|
||||||
Returns the number of bytes consumed from the input. The bytes not consumed are not part of the envelope header
|
Returns the number of bytes consumed from the input. The bytes not consumed are not part of the envelope header.
|
||||||
|
Returns AString::npos on error
|
||||||
*/
|
*/
|
||||||
int Parse(const char * a_Data, int a_Size);
|
size_t Parse(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/// Makes the parser forget everything parsed so far, so that it can be reused for parsing another datastream
|
/** Makes the parser forget everything parsed so far, so that it can be reused for parsing another datastream */
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
/// Returns true if more input is expected for the envelope header
|
/** Returns true if more input is expected for the envelope header */
|
||||||
bool IsInHeaders(void) const { return m_IsInHeaders; }
|
bool IsInHeaders(void) const { return m_IsInHeaders; }
|
||||||
|
|
||||||
/// Sets the IsInHeaders flag; used by cMultipartParser to simplify the parser initial conditions
|
/** Sets the IsInHeaders flag; used by cMultipartParser to simplify the parser initial conditions */
|
||||||
void SetIsInHeaders(bool a_IsInHeaders) { m_IsInHeaders = a_IsInHeaders; }
|
void SetIsInHeaders(bool a_IsInHeaders) { m_IsInHeaders = a_IsInHeaders; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Callbacks to call for the various events
|
/** Callbacks to call for the various events */
|
||||||
cCallbacks & m_Callbacks;
|
cCallbacks & m_Callbacks;
|
||||||
|
|
||||||
/// Set to true while the parser is still parsing the envelope headers. Once set to true, the parser will not consume any more data.
|
/** Set to true while the parser is still parsing the envelope headers. Once set to true, the parser will not consume any more data. */
|
||||||
bool m_IsInHeaders;
|
bool m_IsInHeaders;
|
||||||
|
|
||||||
/// Buffer for the incoming data until it is parsed
|
/** Buffer for the incoming data until it is parsed */
|
||||||
AString m_IncomingData;
|
AString m_IncomingData;
|
||||||
|
|
||||||
/// Holds the last parsed key; used for line-wrapped values
|
/** Holds the last parsed key; used for line-wrapped values */
|
||||||
AString m_LastKey;
|
AString m_LastKey;
|
||||||
|
|
||||||
/// Holds the last parsed value; used for line-wrapped values
|
/** Holds the last parsed value; used for line-wrapped values */
|
||||||
AString m_LastValue;
|
AString m_LastValue;
|
||||||
|
|
||||||
|
|
||||||
/// Notifies the callback of the key/value stored in m_LastKey/m_LastValue, then erases them
|
/** Notifies the callback of the key/value stored in m_LastKey/m_LastValue, then erases them */
|
||||||
void NotifyLast(void);
|
void NotifyLast(void);
|
||||||
|
|
||||||
/// Parses one line of header data. Returns true if successful
|
/** Parses one line of header data. Returns true if successful */
|
||||||
bool ParseLine(const char * a_Data, size_t a_Size);
|
bool ParseLine(const char * a_Data, size_t a_Size);
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ void cHTTPConnection::Send(const cHTTPResponse & a_Response)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cHTTPConnection::Send(const void * a_Data, int a_Size)
|
void cHTTPConnection::Send(const void * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
ASSERT(m_State == wcsSendingResp);
|
ASSERT(m_State == wcsSendingResp);
|
||||||
AppendPrintf(m_OutgoingData, "%x\r\n", a_Size);
|
AppendPrintf(m_OutgoingData, "%x\r\n", a_Size);
|
||||||
@ -155,8 +155,8 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size)
|
|||||||
m_CurrentRequest = new cHTTPRequest;
|
m_CurrentRequest = new cHTTPRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BytesConsumed = m_CurrentRequest->ParseHeaders(a_Data, a_Size);
|
size_t BytesConsumed = m_CurrentRequest->ParseHeaders(a_Data, a_Size);
|
||||||
if (BytesConsumed < 0)
|
if (BytesConsumed == AString::npos)
|
||||||
{
|
{
|
||||||
delete m_CurrentRequest;
|
delete m_CurrentRequest;
|
||||||
m_CurrentRequest = NULL;
|
m_CurrentRequest = NULL;
|
||||||
@ -174,16 +174,16 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size)
|
|||||||
m_State = wcsRecvBody;
|
m_State = wcsRecvBody;
|
||||||
m_HTTPServer.NewRequest(*this, *m_CurrentRequest);
|
m_HTTPServer.NewRequest(*this, *m_CurrentRequest);
|
||||||
m_CurrentRequestBodyRemaining = m_CurrentRequest->GetContentLength();
|
m_CurrentRequestBodyRemaining = m_CurrentRequest->GetContentLength();
|
||||||
if (m_CurrentRequestBodyRemaining < 0)
|
if (m_CurrentRequestBodyRemaining == AString::npos)
|
||||||
{
|
{
|
||||||
// The body length was not specified in the request, assume zero
|
// The body length was not specified in the request, assume zero
|
||||||
m_CurrentRequestBodyRemaining = 0;
|
m_CurrentRequestBodyRemaining = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the rest of the incoming data into the request body:
|
// Process the rest of the incoming data into the request body:
|
||||||
if (a_Size > BytesConsumed)
|
if (a_Size > (int)BytesConsumed)
|
||||||
{
|
{
|
||||||
DataReceived(a_Data + BytesConsumed, a_Size - BytesConsumed);
|
DataReceived(a_Data + BytesConsumed, a_Size - (int)BytesConsumed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -197,7 +197,7 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size)
|
|||||||
ASSERT(m_CurrentRequest != NULL);
|
ASSERT(m_CurrentRequest != NULL);
|
||||||
if (m_CurrentRequestBodyRemaining > 0)
|
if (m_CurrentRequestBodyRemaining > 0)
|
||||||
{
|
{
|
||||||
int BytesToConsume = std::min(m_CurrentRequestBodyRemaining, a_Size);
|
size_t BytesToConsume = std::min(m_CurrentRequestBodyRemaining, (size_t)a_Size);
|
||||||
m_HTTPServer.RequestBody(*this, *m_CurrentRequest, a_Data, BytesToConsume);
|
m_HTTPServer.RequestBody(*this, *m_CurrentRequest, a_Data, BytesToConsume);
|
||||||
m_CurrentRequestBodyRemaining -= BytesToConsume;
|
m_CurrentRequestBodyRemaining -= BytesToConsume;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ public:
|
|||||||
void Send(const cHTTPResponse & a_Response);
|
void Send(const cHTTPResponse & a_Response);
|
||||||
|
|
||||||
/** Sends the data as the response (may be called multiple times) */
|
/** Sends the data as the response (may be called multiple times) */
|
||||||
void Send(const void * a_Data, int a_Size);
|
void Send(const void * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/** Sends the data as the response (may be called multiple times) */
|
/** Sends the data as the response (may be called multiple times) */
|
||||||
void Send(const AString & a_Data) { Send(a_Data.data(), a_Data.size()); }
|
void Send(const AString & a_Data) { Send(a_Data.data(), a_Data.size()); }
|
||||||
@ -87,7 +87,7 @@ protected:
|
|||||||
|
|
||||||
/** Number of bytes that remain to read for the complete body of the message to be received.
|
/** Number of bytes that remain to read for the complete body of the message to be received.
|
||||||
Valid only in wcsRecvBody */
|
Valid only in wcsRecvBody */
|
||||||
int m_CurrentRequestBodyRemaining;
|
size_t m_CurrentRequestBodyRemaining;
|
||||||
|
|
||||||
|
|
||||||
// cSocketThreads::cCallback overrides:
|
// cSocketThreads::cCallback overrides:
|
||||||
|
@ -243,7 +243,7 @@ void cHTTPFormParser::OnPartHeader(const AString & a_Key, const AString & a_Valu
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cHTTPFormParser::OnPartData(const char * a_Data, int a_Size)
|
void cHTTPFormParser::OnPartData(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
if (m_CurrentPartName.empty())
|
if (m_CurrentPartName.empty())
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0;
|
virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0;
|
||||||
|
|
||||||
/// Called when more file data has come for the current file in the form data
|
/// Called when more file data has come for the current file in the form data
|
||||||
virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, int a_Size) = 0;
|
virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) = 0;
|
||||||
|
|
||||||
/// Called when the current file part has ended in the form data
|
/// Called when the current file part has ended in the form data
|
||||||
virtual void OnFileEnd(cHTTPFormParser & a_Parser) = 0;
|
virtual void OnFileEnd(cHTTPFormParser & a_Parser) = 0;
|
||||||
@ -103,7 +103,7 @@ protected:
|
|||||||
// cMultipartParser::cCallbacks overrides:
|
// cMultipartParser::cCallbacks overrides:
|
||||||
virtual void OnPartStart (void) override;
|
virtual void OnPartStart (void) override;
|
||||||
virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) override;
|
virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) override;
|
||||||
virtual void OnPartData (const char * a_Data, int a_Size) override;
|
virtual void OnPartData (const char * a_Data, size_t a_Size) override;
|
||||||
virtual void OnPartEnd (void) override;
|
virtual void OnPartEnd (void) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
cHTTPMessage::cHTTPMessage(eKind a_Kind) :
|
cHTTPMessage::cHTTPMessage(eKind a_Kind) :
|
||||||
m_Kind(a_Kind),
|
m_Kind(a_Kind),
|
||||||
m_ContentLength(-1)
|
m_ContentLength(AString::npos)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,23 +81,23 @@ cHTTPRequest::cHTTPRequest(void) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cHTTPRequest::ParseHeaders(const char * a_Data, int a_Size)
|
size_t cHTTPRequest::ParseHeaders(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
if (!m_IsValid)
|
if (!m_IsValid)
|
||||||
{
|
{
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Method.empty())
|
if (m_Method.empty())
|
||||||
{
|
{
|
||||||
// The first line hasn't been processed yet
|
// The first line hasn't been processed yet
|
||||||
int res = ParseRequestLine(a_Data, a_Size);
|
size_t res = ParseRequestLine(a_Data, a_Size);
|
||||||
if ((res < 0) || (res == a_Size))
|
if ((res == AString::npos) || (res == a_Size))
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
int res2 = m_EnvelopeParser.Parse(a_Data + res, a_Size - res);
|
size_t res2 = m_EnvelopeParser.Parse(a_Data + res, a_Size - res);
|
||||||
if (res2 < 0)
|
if (res2 == AString::npos)
|
||||||
{
|
{
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return res2;
|
return res2;
|
||||||
@ -107,8 +107,8 @@ int cHTTPRequest::ParseHeaders(const char * a_Data, int a_Size)
|
|||||||
|
|
||||||
if (m_EnvelopeParser.IsInHeaders())
|
if (m_EnvelopeParser.IsInHeaders())
|
||||||
{
|
{
|
||||||
int res = m_EnvelopeParser.Parse(a_Data, a_Size);
|
size_t res = m_EnvelopeParser.Parse(a_Data, a_Size);
|
||||||
if (res < 0)
|
if (res == AString::npos)
|
||||||
{
|
{
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ AString cHTTPRequest::GetBareURL(void) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size)
|
size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
m_IncomingHeaderData.append(a_Data, a_Size);
|
m_IncomingHeaderData.append(a_Data, a_Size);
|
||||||
size_t IdxEnd = m_IncomingHeaderData.size();
|
size_t IdxEnd = m_IncomingHeaderData.size();
|
||||||
@ -158,7 +158,7 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size)
|
|||||||
if (LineStart >= IdxEnd)
|
if (LineStart >= IdxEnd)
|
||||||
{
|
{
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NumSpaces = 0;
|
int NumSpaces = 0;
|
||||||
@ -186,7 +186,7 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size)
|
|||||||
{
|
{
|
||||||
// Too many spaces in the request
|
// Too many spaces in the request
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumSpaces += 1;
|
NumSpaces += 1;
|
||||||
@ -198,13 +198,13 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size)
|
|||||||
{
|
{
|
||||||
// LF too early, without a CR, without two preceeding spaces or too soon after the second space
|
// LF too early, without a CR, without two preceeding spaces or too soon after the second space
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
// Check that there's HTTP/version at the end
|
// Check that there's HTTP/version at the end
|
||||||
if (strncmp(a_Data + URLEnd + 1, "HTTP/1.", 7) != 0)
|
if (strncmp(a_Data + URLEnd + 1, "HTTP/1.", 7) != 0)
|
||||||
{
|
{
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return -1;
|
return AString::npos;
|
||||||
}
|
}
|
||||||
m_Method = m_IncomingHeaderData.substr(LineStart, MethodEnd - LineStart);
|
m_Method = m_IncomingHeaderData.substr(LineStart, MethodEnd - LineStart);
|
||||||
m_URL = m_IncomingHeaderData.substr(MethodEnd + 1, URLEnd - MethodEnd - 1);
|
m_URL = m_IncomingHeaderData.substr(MethodEnd + 1, URLEnd - MethodEnd - 1);
|
||||||
|
@ -42,7 +42,7 @@ public:
|
|||||||
void SetContentLength(int a_ContentLength) { m_ContentLength = a_ContentLength; }
|
void SetContentLength(int a_ContentLength) { m_ContentLength = a_ContentLength; }
|
||||||
|
|
||||||
const AString & GetContentType (void) const { return m_ContentType; }
|
const AString & GetContentType (void) const { return m_ContentType; }
|
||||||
int GetContentLength(void) const { return m_ContentLength; }
|
size_t GetContentLength(void) const { return m_ContentLength; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<AString, AString> cNameValueMap;
|
typedef std::map<AString, AString> cNameValueMap;
|
||||||
@ -54,8 +54,10 @@ protected:
|
|||||||
/** Type of the content; parsed by AddHeader(), set directly by SetContentLength() */
|
/** Type of the content; parsed by AddHeader(), set directly by SetContentLength() */
|
||||||
AString m_ContentType;
|
AString m_ContentType;
|
||||||
|
|
||||||
/** Length of the content that is to be received. -1 when the object is created, parsed by AddHeader() or set directly by SetContentLength() */
|
/** Length of the content that is to be received.
|
||||||
int m_ContentLength;
|
AString::npos when the object is created.
|
||||||
|
Parsed by AddHeader() or set directly by SetContentLength() */
|
||||||
|
size_t m_ContentLength;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
@ -72,9 +74,9 @@ public:
|
|||||||
cHTTPRequest(void);
|
cHTTPRequest(void);
|
||||||
|
|
||||||
/** Parses the request line and then headers from the received data.
|
/** Parses the request line and then headers from the received data.
|
||||||
Returns the number of bytes consumed or a negative number for error
|
Returns the number of bytes consumed or AString::npos number for error
|
||||||
*/
|
*/
|
||||||
int ParseHeaders(const char * a_Data, int a_Size);
|
size_t ParseHeaders(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/** Returns true if the request did contain a Content-Length header */
|
/** Returns true if the request did contain a Content-Length header */
|
||||||
bool HasReceivedContentLength(void) const { return (m_ContentLength >= 0); }
|
bool HasReceivedContentLength(void) const { return (m_ContentLength >= 0); }
|
||||||
@ -145,7 +147,7 @@ protected:
|
|||||||
/** Parses the incoming data for the first line (RequestLine)
|
/** Parses the incoming data for the first line (RequestLine)
|
||||||
Returns the number of bytes consumed, or -1 for an error
|
Returns the number of bytes consumed, or -1 for an error
|
||||||
*/
|
*/
|
||||||
int ParseRequestLine(const char * a_Data, int a_Size);
|
size_t ParseRequestLine(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
// cEnvelopeParser::cCallbacks overrides:
|
// cEnvelopeParser::cCallbacks overrides:
|
||||||
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override;
|
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override;
|
||||||
|
@ -38,7 +38,7 @@ class cDebugCallbacks :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override
|
virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Connection);
|
UNUSED(a_Connection);
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ class cDebugCallbacks :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, int a_Size) override
|
virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) override
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ void cHTTPServer::NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Re
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size)
|
void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
m_Callbacks->OnRequestBody(a_Connection, a_Request, a_Data, a_Size);
|
m_Callbacks->OnRequestBody(a_Connection, a_Request, a_Data, a_Size);
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0;
|
virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0;
|
||||||
|
|
||||||
/// Called when another part of request body has arrived.
|
/** Called when another part of request body has arrived.
|
||||||
virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) = 0;
|
May be called multiple times for a single request. */
|
||||||
|
virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) = 0;
|
||||||
|
|
||||||
/// Called when the request body has been fully received in previous calls to OnRequestBody()
|
/// Called when the request body has been fully received in previous calls to OnRequestBody()
|
||||||
virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0;
|
virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0;
|
||||||
@ -90,8 +91,9 @@ protected:
|
|||||||
/// Called by cHTTPConnection when it finishes parsing the request header
|
/// Called by cHTTPConnection when it finishes parsing the request header
|
||||||
void NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
void NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
||||||
|
|
||||||
/// Called by cHTTPConenction when it receives more data for the request body
|
/** Called by cHTTPConenction when it receives more data for the request body.
|
||||||
void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size);
|
May be called multiple times for a single request. */
|
||||||
|
void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/// Called by cHTTPConnection when it detects that the request has finished (all of its body has been received)
|
/// Called by cHTTPConnection when it detects that the request has finished (all of its body has been received)
|
||||||
void RequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
void RequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
||||||
|
@ -97,8 +97,6 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a
|
|||||||
m_EnvelopeParser(*this),
|
m_EnvelopeParser(*this),
|
||||||
m_HasHadData(false)
|
m_HasHadData(false)
|
||||||
{
|
{
|
||||||
static AString s_Multipart = "multipart/";
|
|
||||||
|
|
||||||
// Check that the content type is multipart:
|
// Check that the content type is multipart:
|
||||||
AString ContentType(a_ContentType);
|
AString ContentType(a_ContentType);
|
||||||
if (strncmp(ContentType.c_str(), "multipart/", 10) != 0)
|
if (strncmp(ContentType.c_str(), "multipart/", 10) != 0)
|
||||||
@ -146,7 +144,7 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cMultipartParser::Parse(const char * a_Data, int a_Size)
|
void cMultipartParser::Parse(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
// Skip parsing if invalid
|
// Skip parsing if invalid
|
||||||
if (!m_IsValid)
|
if (!m_IsValid)
|
||||||
@ -160,8 +158,8 @@ void cMultipartParser::Parse(const char * a_Data, int a_Size)
|
|||||||
{
|
{
|
||||||
if (m_EnvelopeParser.IsInHeaders())
|
if (m_EnvelopeParser.IsInHeaders())
|
||||||
{
|
{
|
||||||
int BytesConsumed = m_EnvelopeParser.Parse(m_IncomingData.data(), m_IncomingData.size());
|
size_t BytesConsumed = m_EnvelopeParser.Parse(m_IncomingData.data(), m_IncomingData.size());
|
||||||
if (BytesConsumed < 0)
|
if (BytesConsumed == AString::npos)
|
||||||
{
|
{
|
||||||
m_IsValid = false;
|
m_IsValid = false;
|
||||||
return;
|
return;
|
||||||
|
@ -22,50 +22,52 @@ public:
|
|||||||
class cCallbacks
|
class cCallbacks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Called when a new part starts
|
virtual ~cCallbacks() {}
|
||||||
|
|
||||||
|
/** Called when a new part starts */
|
||||||
virtual void OnPartStart(void) = 0;
|
virtual void OnPartStart(void) = 0;
|
||||||
|
|
||||||
/// Called when a complete header line is received for a part
|
/** Called when a complete header line is received for a part */
|
||||||
virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) = 0;
|
virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) = 0;
|
||||||
|
|
||||||
/// Called when body for a part is received
|
/** Called when body for a part is received */
|
||||||
virtual void OnPartData(const char * a_Data, int a_Size) = 0;
|
virtual void OnPartData(const char * a_Data, size_t a_Size) = 0;
|
||||||
|
|
||||||
/// Called when the current part ends
|
/** Called when the current part ends */
|
||||||
virtual void OnPartEnd(void) = 0;
|
virtual void OnPartEnd(void) = 0;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/// Creates the parser, expects to find the boundary in a_ContentType
|
/** Creates the parser, expects to find the boundary in a_ContentType */
|
||||||
cMultipartParser(const AString & a_ContentType, cCallbacks & a_Callbacks);
|
cMultipartParser(const AString & a_ContentType, cCallbacks & a_Callbacks);
|
||||||
|
|
||||||
/// Parses more incoming data
|
/** Parses more incoming data */
|
||||||
void Parse(const char * a_Data, int a_Size);
|
void Parse(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// The callbacks to call for various parsing events
|
/** The callbacks to call for various parsing events */
|
||||||
cCallbacks & m_Callbacks;
|
cCallbacks & m_Callbacks;
|
||||||
|
|
||||||
/// True if the data parsed so far is valid; if false, further parsing is skipped
|
/** True if the data parsed so far is valid; if false, further parsing is skipped */
|
||||||
bool m_IsValid;
|
bool m_IsValid;
|
||||||
|
|
||||||
/// Parser for each part's envelope
|
/** Parser for each part's envelope */
|
||||||
cEnvelopeParser m_EnvelopeParser;
|
cEnvelopeParser m_EnvelopeParser;
|
||||||
|
|
||||||
/// Buffer for the incoming data until it is parsed
|
/** Buffer for the incoming data until it is parsed */
|
||||||
AString m_IncomingData;
|
AString m_IncomingData;
|
||||||
|
|
||||||
/// The boundary, excluding both the initial "--" and the terminating CRLF
|
/** The boundary, excluding both the initial "--" and the terminating CRLF */
|
||||||
AString m_Boundary;
|
AString m_Boundary;
|
||||||
|
|
||||||
/// Set to true if some data for the current part has already been signalized to m_Callbacks. Used for proper CRLF inserting.
|
/** Set to true if some data for the current part has already been signalized to m_Callbacks. Used for proper CRLF inserting. */
|
||||||
bool m_HasHadData;
|
bool m_HasHadData;
|
||||||
|
|
||||||
|
|
||||||
/// Parse one line of incoming data. The CRLF has already been stripped from a_Data / a_Size
|
/** Parse one line of incoming data. The CRLF has already been stripped from a_Data / a_Size */
|
||||||
void ParseLine(const char * a_Data, int a_Size);
|
void ParseLine(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/// Parse one line of incoming data in the headers section of a part. The CRLF has already been stripped from a_Data / a_Size
|
/** Parse one line of incoming data in the headers section of a part. The CRLF has already been stripped from a_Data / a_Size */
|
||||||
void ParseHeaderLine(const char * a_Data, int a_Size);
|
void ParseHeaderLine(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
// cEnvelopeParser overrides:
|
// cEnvelopeParser overrides:
|
||||||
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override;
|
virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override;
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
// Now try parsing char-by-char, to debug transitions across datachunk boundaries:
|
// Now try parsing char-by-char, to debug transitions across datachunk boundaries:
|
||||||
cNameValueParser Parser2;
|
cNameValueParser Parser2;
|
||||||
for (int i = 0; i < sizeof(Data) - 1; i++)
|
for (size_t i = 0; i < sizeof(Data) - 1; i++)
|
||||||
{
|
{
|
||||||
Parser2.Parse(Data + i, 1);
|
Parser2.Parse(Data + i, 1);
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ cNameValueParser::cNameValueParser(bool a_AllowsKeyOnly) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cNameValueParser::cNameValueParser(const char * a_Data, int a_Size, bool a_AllowsKeyOnly) :
|
cNameValueParser::cNameValueParser(const char * a_Data, size_t a_Size, bool a_AllowsKeyOnly) :
|
||||||
m_State(psKeySpace),
|
m_State(psKeySpace),
|
||||||
m_AllowsKeyOnly(a_AllowsKeyOnly)
|
m_AllowsKeyOnly(a_AllowsKeyOnly)
|
||||||
{
|
{
|
||||||
@ -93,12 +93,12 @@ cNameValueParser::cNameValueParser(const char * a_Data, int a_Size, bool a_Allow
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cNameValueParser::Parse(const char * a_Data, int a_Size)
|
void cNameValueParser::Parse(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong!
|
ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong!
|
||||||
|
|
||||||
int Last = 0;
|
int Last = 0;
|
||||||
for (int i = 0; i < a_Size;)
|
for (size_t i = 0; i < a_Size;)
|
||||||
{
|
{
|
||||||
switch (m_State)
|
switch (m_State)
|
||||||
{
|
{
|
||||||
|
@ -21,10 +21,10 @@ public:
|
|||||||
cNameValueParser(bool a_AllowsKeyOnly = true);
|
cNameValueParser(bool a_AllowsKeyOnly = true);
|
||||||
|
|
||||||
/// Creates an empty parser, then parses the data given. Doesn't call Finish(), so more data can be parsed later
|
/// Creates an empty parser, then parses the data given. Doesn't call Finish(), so more data can be parsed later
|
||||||
cNameValueParser(const char * a_Data, int a_Size, bool a_AllowsKeyOnly = true);
|
cNameValueParser(const char * a_Data, size_t a_Size, bool a_AllowsKeyOnly = true);
|
||||||
|
|
||||||
/// Parses the data given
|
/// Parses the data given
|
||||||
void Parse(const char * a_Data, int a_Size);
|
void Parse(const char * a_Data, size_t a_Size);
|
||||||
|
|
||||||
/// Notifies the parser that no more data will be coming. Returns true if the parser state is valid
|
/// Notifies the parser that no more data will be coming. Returns true if the parser state is valid
|
||||||
bool Finish(void);
|
bool Finish(void);
|
||||||
|
@ -490,7 +490,7 @@ void cWebAdmin::OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size)
|
void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
UNUSED(a_Connection);
|
UNUSED(a_Connection);
|
||||||
cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
|
cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
|
||||||
@ -537,7 +537,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest &
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cWebAdmin::cWebadminRequestData
|
// cWebAdmin::cWebadminRequestData
|
||||||
|
|
||||||
void cWebAdmin::cWebadminRequestData::OnBody(const char * a_Data, int a_Size)
|
void cWebAdmin::cWebadminRequestData::OnBody(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
m_Form.Parse(a_Data, a_Size);
|
m_Form.Parse(a_Data, a_Size);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ protected:
|
|||||||
virtual ~cRequestData() {} // Force a virtual destructor in all descendants
|
virtual ~cRequestData() {} // Force a virtual destructor in all descendants
|
||||||
|
|
||||||
/** Called when a new chunk of body data is received */
|
/** Called when a new chunk of body data is received */
|
||||||
virtual void OnBody(const char * a_Data, int a_Size) = 0;
|
virtual void OnBody(const char * a_Data, size_t a_Size) = 0;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/** The body handler for requests in the "/webadmin" and "/~webadmin" paths */
|
/** The body handler for requests in the "/webadmin" and "/~webadmin" paths */
|
||||||
@ -169,14 +169,14 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cRequestData overrides:
|
// cRequestData overrides:
|
||||||
virtual void OnBody(const char * a_Data, int a_Size) override;
|
virtual void OnBody(const char * a_Data, size_t a_Size) override;
|
||||||
|
|
||||||
// cHTTPFormParser::cCallbacks overrides. Files are ignored:
|
// cHTTPFormParser::cCallbacks overrides. Files are ignored:
|
||||||
virtual void OnFileStart(cHTTPFormParser &, const AString & a_FileName) override
|
virtual void OnFileStart(cHTTPFormParser &, const AString & a_FileName) override
|
||||||
{
|
{
|
||||||
UNUSED(a_FileName);
|
UNUSED(a_FileName);
|
||||||
}
|
}
|
||||||
virtual void OnFileData(cHTTPFormParser &, const char * a_Data, int a_Size) override
|
virtual void OnFileData(cHTTPFormParser &, const char * a_Data, size_t a_Size) override
|
||||||
{
|
{
|
||||||
UNUSED(a_Data);
|
UNUSED(a_Data);
|
||||||
UNUSED(a_Size);
|
UNUSED(a_Size);
|
||||||
@ -216,7 +216,7 @@ protected:
|
|||||||
|
|
||||||
// cHTTPServer::cCallbacks overrides:
|
// cHTTPServer::cCallbacks overrides:
|
||||||
virtual void OnRequestBegun (cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override;
|
virtual void OnRequestBegun (cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override;
|
||||||
virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override;
|
virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override;
|
||||||
virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override;
|
virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override;
|
||||||
} ; // tolua_export
|
} ; // tolua_export
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user