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