summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/HTTPServer/HTTPConnection.cpp26
-rw-r--r--source/HTTPServer/HTTPConnection.h3
-rw-r--r--source/HTTPServer/HTTPMessage.cpp16
-rw-r--r--source/HTTPServer/HTTPMessage.h3
-rw-r--r--source/HTTPServer/HTTPServer.cpp11
-rw-r--r--source/HTTPServer/HTTPServer.h5
6 files changed, 51 insertions, 13 deletions
diff --git a/source/HTTPServer/HTTPConnection.cpp b/source/HTTPServer/HTTPConnection.cpp
index f7318c6ae..59fe8f878 100644
--- a/source/HTTPServer/HTTPConnection.cpp
+++ b/source/HTTPServer/HTTPConnection.cpp
@@ -25,6 +25,7 @@ cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) :
void cHTTPConnection::SendStatusAndReason(int a_StatusCode, const AString & a_Response)
{
AppendPrintf(m_OutgoingData, "%d %s\r\n\r\n", a_StatusCode, a_Response.c_str());
+ m_HTTPServer.NotifyConnectionWrite(*this);
}
@@ -36,6 +37,7 @@ void cHTTPConnection::Send(const cHTTPResponse & a_Response)
ASSERT(m_State = wcsRecvIdle);
a_Response.AppendToData(m_OutgoingData);
m_State = wcsSendingResp;
+ m_HTTPServer.NotifyConnectionWrite(*this);
}
@@ -47,6 +49,8 @@ void cHTTPConnection::Send(const void * a_Data, int a_Size)
ASSERT(m_State == wcsSendingResp);
AppendPrintf(m_OutgoingData, "%x\r\n", a_Size);
m_OutgoingData.append((const char *)a_Data, a_Size);
+ m_OutgoingData.append("\r\n");
+ m_HTTPServer.NotifyConnectionWrite(*this);
}
@@ -56,8 +60,9 @@ void cHTTPConnection::Send(const void * a_Data, int a_Size)
void cHTTPConnection::FinishResponse(void)
{
ASSERT(m_State == wcsSendingResp);
- m_OutgoingData.append("0\r\n");
+ m_OutgoingData.append("0\r\n\r\n");
m_State = wcsRecvHeaders;
+ m_HTTPServer.NotifyConnectionWrite(*this);
}
@@ -95,12 +100,19 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size)
}
m_State = wcsRecvBody;
m_HTTPServer.NewRequest(*this, *m_CurrentRequest);
+ m_CurrentRequestBodyRemaining = m_CurrentRequest->GetContentLength();
// Process the rest of the incoming data into the request body:
if (m_IncomingHeaderData.size() > idxEnd + 4)
{
m_IncomingHeaderData.erase(0, idxEnd + 4);
DataReceived(m_IncomingHeaderData.c_str(), m_IncomingHeaderData.size());
+ m_IncomingHeaderData.clear();
+ }
+ else
+ {
+ m_IncomingHeaderData.clear();
+ DataReceived("", 0); // If the request has zero body length, let it be processed right-away
}
break;
}
@@ -108,7 +120,17 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size)
case wcsRecvBody:
{
ASSERT(m_CurrentRequest != NULL);
- // TODO: Receive the body, and the next request (If HTTP/1.1 keepalive)
+ if (m_CurrentRequestBodyRemaining > 0)
+ {
+ int BytesToConsume = std::min(m_CurrentRequestBodyRemaining, a_Size);
+ m_HTTPServer.RequestBody(*this, *m_CurrentRequest, a_Data, BytesToConsume);
+ m_CurrentRequestBodyRemaining -= BytesToConsume;
+ }
+ if (m_CurrentRequestBodyRemaining == 0)
+ {
+ m_HTTPServer.RequestFinished(*this, *m_CurrentRequest);
+ m_State = wcsRecvIdle;
+ }
break;
}
diff --git a/source/HTTPServer/HTTPConnection.h b/source/HTTPServer/HTTPConnection.h
index e2df5de46..d8ecdf1d9 100644
--- a/source/HTTPServer/HTTPConnection.h
+++ b/source/HTTPServer/HTTPConnection.h
@@ -72,6 +72,9 @@ protected:
/// The request being currently received (valid only between having parsed the headers and finishing receiving the body)
cHTTPRequest * m_CurrentRequest;
+
+ /// Number of bytes that remain to read for the complete body of the message to be received. Valid only in wcsRecvBody
+ int m_CurrentRequestBodyRemaining;
// cSocketThreads::cCallback overrides:
diff --git a/source/HTTPServer/HTTPMessage.cpp b/source/HTTPServer/HTTPMessage.cpp
index b784cb941..b2e21c712 100644
--- a/source/HTTPServer/HTTPMessage.cpp
+++ b/source/HTTPServer/HTTPMessage.cpp
@@ -88,7 +88,11 @@ bool cHTTPRequest::ParseHeaders(const char * a_IncomingData, size_t a_IdxEnd)
End -= Next;
}
- return HasReceivedContentLength();
+ if (!HasReceivedContentLength())
+ {
+ SetContentLength(0);
+ }
+ return true;
}
@@ -125,12 +129,12 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_IdxEnd)
{
case 0:
{
- m_Method.assign(a_Data, Last, i - Last - 1);
+ m_Method.assign(a_Data, Last, i - Last);
break;
}
case 1:
{
- m_URL.assign(a_Data, Last, i - Last - 1);
+ m_URL.assign(a_Data, Last, i - Last);
break;
}
default:
@@ -145,7 +149,7 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_IdxEnd)
}
case '\n':
{
- if ((i == 0) || (a_Data[i] != '\r') || (NumSpaces != 2) || (i < Last + 7))
+ if ((i == 0) || (a_Data[i - 1] != '\r') || (NumSpaces != 2) || (i < Last + 7))
{
// LF too early, without a CR, without two preceeding spaces or too soon after the second space
return AString::npos;
@@ -155,7 +159,7 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_IdxEnd)
{
return AString::npos;
}
- return i;
+ return i + 1;
}
} // switch (a_Data[i])
} // for i - a_Data[]
@@ -263,7 +267,7 @@ cHTTPResponse::cHTTPResponse(void) :
void cHTTPResponse::AppendToData(AString & a_DataStream) const
{
- a_DataStream.append("200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: ");
+ a_DataStream.append("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: ");
a_DataStream.append(m_ContentType);
a_DataStream.append("\r\n");
for (cNameValueMap::const_iterator itr = m_Headers.begin(), end = m_Headers.end(); itr != end; ++itr)
diff --git a/source/HTTPServer/HTTPMessage.h b/source/HTTPServer/HTTPMessage.h
index a3c4f96d1..fc7b621fe 100644
--- a/source/HTTPServer/HTTPMessage.h
+++ b/source/HTTPServer/HTTPMessage.h
@@ -78,9 +78,6 @@ protected:
/// Full URL of the request
AString m_URL;
- /// Number of bytes that remain to read for the complete body of the message to be received
- int m_BodyRemaining;
-
/** Parses the RequestLine out of a_Data, up to index a_IdxEnd
Returns the index to the next line, or npos if invalid request
*/
diff --git a/source/HTTPServer/HTTPServer.cpp b/source/HTTPServer/HTTPServer.cpp
index 980cad14f..d518df10d 100644
--- a/source/HTTPServer/HTTPServer.cpp
+++ b/source/HTTPServer/HTTPServer.cpp
@@ -94,6 +94,15 @@ void cHTTPServer::CloseConnection(cHTTPConnection & a_Connection)
+void cHTTPServer::NotifyConnectionWrite(cHTTPConnection & a_Connection)
+{
+ m_SocketThreads.NotifyWrite(&a_Connection);
+}
+
+
+
+
+
void cHTTPServer::NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request)
{
// TODO
@@ -103,7 +112,7 @@ void cHTTPServer::NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Re
-void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request)
+void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size)
{
// TODO
}
diff --git a/source/HTTPServer/HTTPServer.h b/source/HTTPServer/HTTPServer.h
index fd4782267..2d0acc386 100644
--- a/source/HTTPServer/HTTPServer.h
+++ b/source/HTTPServer/HTTPServer.h
@@ -55,11 +55,14 @@ protected:
/// Called by cHTTPConnection to close the connection (presumably due to an error)
void CloseConnection(cHTTPConnection & a_Connection);
+ /// Called by cHTTPConnection to notify SocketThreads that there's data to be sent for the connection
+ void NotifyConnectionWrite(cHTTPConnection & a_Connection);
+
/// Called by cHTTPConnection when it finishes parsing the request header
void NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
/// Called by cHTTPConenction when it receives more data for the request body
- void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
+ void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size);
/// 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);