diff --git a/microstack/ILibWebClient.c b/microstack/ILibWebClient.c
index 4c649b0..12f3337 100644
--- a/microstack/ILibWebClient.c
+++ b/microstack/ILibWebClient.c
@@ -538,7 +538,10 @@ void ILibWebClient_TimerInterruptSink(void *object)
{
UNREFERENCED_PARAMETER( object );
}
-
+int ILibWebClient_IsFinHeader(ILibWebClient_StateObject wcdo)
+{
+ return(((ILibWebClientDataObject*)wcdo)->FinHeader);
+}
void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo)
{
ILibWebClient_RequestToken rt = NULL;
@@ -1485,7 +1488,7 @@ void ILibWebClient_OnWebSocketData(ILibAsyncSocket_SocketModule socketModule, ch
// Function Pointer that triggers when a connection is interrupted
// User data that can be set/received
// Flag to tell the underlying socket to pause reading data
-void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffer, int *p_beginPointer, int endPointer, void (**InterruptPtr)(void *socketModule, void *user), void **user, int *PAUSE)
+ILibWebClient_DataResults ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffer, int *p_beginPointer, int endPointer, void (**InterruptPtr)(void *socketModule, void *user), void **user, int *PAUSE)
{
struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)(*user);
struct ILibWebRequest *wr;
@@ -1502,8 +1505,8 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
//char *tempPath;
//unsigned short tempPort;
- if (wcdo == NULL || wcdo->RequestQueue == NULL) return;
- if (wcdo->IsWebSocket != 0 && wcdo->Server == 0) { ILibWebClient_OnWebSocketData(socketModule, buffer, p_beginPointer, endPointer, InterruptPtr, user, PAUSE); return; }
+ if (wcdo == NULL || wcdo->RequestQueue == NULL) return(ILibWebClient_DataResults_OK);
+ if (wcdo->IsWebSocket != 0 && wcdo->Server == 0) { ILibWebClient_OnWebSocketData(socketModule, buffer, p_beginPointer, endPointer, InterruptPtr, user, PAUSE); return(ILibWebClient_DataResults_OK); }
if (wcdo->Server == 0)
{
@@ -1525,7 +1528,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
// of the time, it means the remote endpoint is sending invalid packets.
//
*p_beginPointer = endPointer;
- return;
+ return(ILibWebClient_DataResults_OK);
}
if (wcdo->FinHeader == 0)
{
@@ -1589,6 +1592,11 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
}
if (wcdo->header != NULL)
{
+ if (wcdo->header->Directive == NULL && wcdo->header->StatusCode != -1 && wcdo->Server != 0)
+ {
+ return(ILibWebClient_DataResults_InvalidRequest); // We're a server, but we received a Response Packet...
+ }
+
//
// Check to see if this has an absolute path. Might be able to convert it
// for easier processing
@@ -1654,6 +1662,11 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
wcdo->WaitForClose = 0;
phfn->FieldData[phfn->FieldDataLength] = '\0';
wcdo->BytesLeft = atoi(phfn->FieldData);
+ if (wcdo->BytesLeft < 0)
+ {
+ wcdo->BytesLeft = 0;
+ return(ILibWebClient_DataResults_InvalidContentLength);
+ }
}
phfn = phfn->NextField;
}
@@ -1680,7 +1693,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
int zro = 0;
if (wr->OnResponse != NULL) { wr->OnResponse(wcdo, 0, wcdo->header, NULL, &zro, 0, ILibWebClient_ReceiveStatus_Connection_Established, wr->user1, wr->user2, &(wcdo->PAUSE)); }
*p_beginPointer += wcdo->HeaderLength;
- return;
+ return(ILibWebClient_DataResults_OK);
}
else if (wcdo->header->StatusCode == 101 && wr->requestToken->WebSocketKey != NULL)
{
@@ -1700,14 +1713,14 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
if (wr->OnResponse != NULL) { wr->OnResponse(wcdo, 0, wcdo->header, NULL, &zro, 0, ILibWebClient_ReceiveStatus_Connection_Established, wr->user1, wr->user2, &(wcdo->PAUSE)); }
*p_beginPointer += hdrLen;
- return;
+ return(ILibWebClient_DataResults_OK);
}
else
{
// WebSocket Handshake Error... Unrecoverable, Abort connection
ILibWebClient_Disconnect(wcdo);
ILibWebClient_DestroyWebClientDataObject(wcdo); // We are destroying here, because WebSockets have independent WCDO objects
- return;
+ return(ILibWebClient_DataResults_OK);
}
}
if (wr->streamedState == NULL)
@@ -1897,14 +1910,14 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
// VIOLATION of the http specification.
//
*p_beginPointer = i + 4;
- return;
+ return(ILibWebClient_DataResults_OK);
}
if (socketModule != NULL && ILibAsyncSocket_IsFree(socketModule)!=0)
{
//
// The user closed the socket, so just return
//
- return;
+ return(ILibWebClient_DataResults_OK);
}
}
@@ -2011,6 +2024,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
//
*PAUSE = wcdo->PAUSE;
}
+ return(ILibWebClient_DataResults_OK);
}
//
@@ -2506,7 +2520,7 @@ ILibWebClient_RequestManager ILibCreateWebClient(int PoolSize, void *Chain)
RetVal->socks[i] = ILibCreateAsyncSocketModule(
Chain,
INITIAL_BUFFER_SIZE,
- &ILibWebClient_OnData,
+ (ILibAsyncSocket_OnData)&ILibWebClient_OnData,
&ILibWebClient_OnConnect,
&ILibWebClient_OnDisconnectSink,
&ILibWebClient_OnSendOKSink);
diff --git a/microstack/ILibWebClient.h b/microstack/ILibWebClient.h
index 8b4aa41..a7b7fc1 100644
--- a/microstack/ILibWebClient.h
+++ b/microstack/ILibWebClient.h
@@ -172,11 +172,18 @@ typedef int(*ILibWebClient_OnHttpsConnection)(ILibWebClient_RequestToken sender,
extern const int ILibMemory_WebClient_RequestToken_CONTAINERSIZE;
+typedef enum ILibWebClient_DataResults
+{
+ ILibWebClient_DataResults_OK = 0,
+ ILibWebClient_DataResults_InvalidRequest = 400,
+ ILibWebClient_DataResults_InvalidContentLength = 4001
+}ILibWebClient_DataResults;
+
ILibWebClient_RequestManager ILibCreateWebClient(int PoolSize, void *Chain);
ILibWebClient_StateObject ILibCreateWebClientEx(ILibWebClient_OnResponse OnResponse, ILibAsyncSocket_SocketModule socketModule, void *user1, void *user2);
void ILibWebClient_OnBufferReAllocate(ILibAsyncSocket_SocketModule token, void *user, ptrdiff_t offSet);
-void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule,char* buffer,int *p_beginPointer, int endPointer,ILibAsyncSocket_OnInterrupt *InterruptPtr, void **user, int *PAUSE);
+ILibWebClient_DataResults ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule,char* buffer,int *p_beginPointer, int endPointer,ILibAsyncSocket_OnInterrupt *InterruptPtr, void **user, int *PAUSE);
void ILibDestroyWebClient(void *object);
void ILibWebClient_DestroyWebClientDataObject(ILibWebClient_StateObject token);
@@ -240,6 +247,7 @@ void ILibWebClient_Pause(ILibWebClient_StateObject wcdo);
void ILibWebClient_Disconnect(ILibWebClient_StateObject wcdo);
void ILibWebClient_CancelRequest(ILibWebClient_RequestToken RequestToken);
void ILibWebClient_ResetUserObjects(ILibWebClient_StateObject webstate, void *user1, void *user2);
+int ILibWebClient_IsFinHeader(ILibWebClient_StateObject wcdo);
ILibWebClient_RequestToken ILibWebClient_GetRequestToken_FromStateObject(ILibWebClient_StateObject WebStateObject);
ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token);
void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok);
diff --git a/microstack/ILibWebServer.c b/microstack/ILibWebServer.c
index 1aad620..3db717d 100644
--- a/microstack/ILibWebServer.c
+++ b/microstack/ILibWebServer.c
@@ -760,7 +760,29 @@ void ILibWebServer_OnReceive(void *AsyncServerSocketModule, void *ConnectionToke
if (ILibWebServer_Session_GetSystemData(ws)->WebSocket_Request == NULL)
{
// Normal HTTP Processing Rules
- ILibWebClient_OnData(ConnectionToken, buffer, p_beginPointer, endPointer, NULL, &(ILibWebServer_Session_GetSystemData(ws)->WebClientDataObject), PAUSE);
+ ILibWebClient_DataResults r;
+ int pbp = *p_beginPointer;
+ switch ((r = ILibWebClient_OnData(ConnectionToken, buffer, p_beginPointer, endPointer, NULL, &(ILibWebServer_Session_GetSystemData(ws)->WebClientDataObject), PAUSE)))
+ {
+ case ILibWebClient_DataResults_OK:
+ if (*p_beginPointer == pbp && (endPointer - pbp >= 4096) && ILibWebClient_IsFinHeader(ILibWebServer_Session_GetSystemData(ws)->WebClientDataObject) == 0)
+ {
+ // The headers is > 4k
+ ILibWebServer_Session_GetSystemData(ws)->CloseOverrideFlag = 1; // This will force close the socket when done
+ ILibWebServer_Send_Raw(ws, "HTTP/1.1 431 Header size too big\r\nConnection: close\r\n\r\n", 55, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_Done);
+ }
+ break;
+ case ILibWebClient_DataResults_InvalidRequest:
+ ILibWebServer_Session_GetSystemData(ws)->CloseOverrideFlag = 1; // This will force close the socket when done
+ ILibWebServer_Send_Raw(ws, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n", 47, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_Done);
+ break;
+ case ILibWebClient_DataResults_InvalidContentLength:
+ ILibWebServer_Session_GetSystemData(ws)->CloseOverrideFlag = 1; // This will force close the socket when done
+ ILibWebServer_Send_Raw(ws, "HTTP/1.1 400 Invalid content length\r\nConnection: close\r\n\r\n", 58, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_Done);
+ break;
+ default:
+ break;
+ }
}
else
{
@@ -801,7 +823,18 @@ enum ILibWebServer_Status ILibWebServer_RequestAnswered(struct ILibWebServer_Ses
ILibRemoteLogging_printf(ILibChainGetLogger(session->Reserved_Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_Microstack_Web, ILibRemoteLogging_Flags_VerbosityLevel_1, "WebSession[%p] (Request Answered)", (void*)session);
- if (hdr == NULL) return ILibWebServer_ALL_DATA_SENT;
+ if (hdr == NULL)
+ {
+ if (ILibWebServer_Session_GetSystemData(session)->CloseOverrideFlag != 0)
+ {
+ ILibLifeTime_Add(((struct ILibWebServer_StateModule*)session->Parent)->LifeTime, ILibWebServer_Session_GetSystemData(session)->ConnectionToken, 0, &ILibAsyncSocket_Disconnect, NULL);
+ return(ILibWebServer_SEND_RESULTED_IN_DISCONNECT);
+ }
+ else
+ {
+ return ILibWebServer_ALL_DATA_SENT;
+ }
+ }
//
// Virtual Directory State Object