mirror of https://github.com/acidanthera/audk.git
NetworkPkg/HttpDxe: Fix the bug when parsing HTTP(S) message body.
*v2: Resolve the conflict commit. *v3: Fixed the failure if BodyLength in HTTP token is less than the received size of HTTPS message. HttpBodyParserCallback function is to parse the HTTP(S) message body so as to confirm whether there is the next message header. But it doesn't record the parsing message data/length correctly. This patch is refine the parsing logic so as to fix the potential failure. Cc: Ye Ting <ting.ye@intel.com> Cc: Fu Siyuan <siyuan.fu@intel.com> Cc: Gary Lin <glin@suse.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Tested-by: Gary Lin <glin@suse.com>
This commit is contained in:
parent
c6a14de3ef
commit
895b87e380
|
@ -916,6 +916,7 @@ HttpBodyParserCallback (
|
|||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
HTTP_CALLBACK_DATA *CallbackData;
|
||||
HTTP_TOKEN_WRAP *Wrap;
|
||||
UINTN BodyLength;
|
||||
CHAR8 *Body;
|
||||
|
@ -928,21 +929,18 @@ HttpBodyParserCallback (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Wrap = (HTTP_TOKEN_WRAP *) Context;
|
||||
Body = Wrap->HttpToken->Message->Body;
|
||||
BodyLength = Wrap->HttpToken->Message->BodyLength;
|
||||
CallbackData = (HTTP_CALLBACK_DATA *) Context;
|
||||
|
||||
Wrap = (HTTP_TOKEN_WRAP *) (CallbackData->Wrap);
|
||||
Body = CallbackData->ParseData;
|
||||
BodyLength = CallbackData->ParseDataLength;
|
||||
|
||||
if (Data < Body + BodyLength) {
|
||||
Wrap->HttpInstance->NextMsg = Data;
|
||||
} else {
|
||||
Wrap->HttpInstance->NextMsg = NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Free Tx4Token or Tx6Token since already received corrsponding HTTP response.
|
||||
//
|
||||
FreePool (Wrap);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1191,7 +1189,7 @@ HttpResponseWorker (
|
|||
HttpMsg->HeaderCount,
|
||||
HttpMsg->Headers,
|
||||
HttpBodyParserCallback,
|
||||
(VOID *) ValueInItem,
|
||||
(VOID *) (&HttpInstance->CallbackData),
|
||||
&HttpInstance->MsgParser
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -1202,18 +1200,28 @@ HttpResponseWorker (
|
|||
// Check whether we received a complete HTTP message.
|
||||
//
|
||||
if (HttpInstance->CacheBody != NULL) {
|
||||
//
|
||||
// Record the CallbackData data.
|
||||
//
|
||||
HttpInstance->CallbackData.Wrap = (VOID *) Wrap;
|
||||
HttpInstance->CallbackData.ParseData = (VOID *) HttpInstance->CacheBody;
|
||||
HttpInstance->CallbackData.ParseDataLength = HttpInstance->CacheLen;
|
||||
|
||||
//
|
||||
// Parse message with CallbackData data.
|
||||
//
|
||||
Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error2;
|
||||
}
|
||||
}
|
||||
|
||||
if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
|
||||
//
|
||||
// Free the MsgParse since we already have a full HTTP message.
|
||||
//
|
||||
HttpFreeMsgParser (HttpInstance->MsgParser);
|
||||
HttpInstance->MsgParser = NULL;
|
||||
}
|
||||
if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
|
||||
//
|
||||
// Free the MsgParse since we already have a full HTTP message.
|
||||
//
|
||||
HttpFreeMsgParser (HttpInstance->MsgParser);
|
||||
HttpInstance->MsgParser = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1332,12 +1340,26 @@ HttpResponseWorker (
|
|||
}
|
||||
|
||||
//
|
||||
// Check whether we receive a complete HTTP message.
|
||||
// Process the received the body packet.
|
||||
//
|
||||
HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
|
||||
|
||||
CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
|
||||
|
||||
//
|
||||
// Record the CallbackData data.
|
||||
//
|
||||
HttpInstance->CallbackData.Wrap = (VOID *) Wrap;
|
||||
HttpInstance->CallbackData.ParseData = HttpMsg->Body;
|
||||
HttpInstance->CallbackData.ParseDataLength = HttpMsg->BodyLength;
|
||||
|
||||
//
|
||||
// Parse Body with CallbackData data.
|
||||
//
|
||||
Status = HttpParseMessageBody (
|
||||
HttpInstance->MsgParser,
|
||||
(UINTN) Fragment.Len,
|
||||
(CHAR8 *) Fragment.Bulk
|
||||
HttpMsg->BodyLength,
|
||||
HttpMsg->Body
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error2;
|
||||
|
@ -1352,46 +1374,28 @@ HttpResponseWorker (
|
|||
}
|
||||
|
||||
//
|
||||
// We receive part of header of next HTTP msg.
|
||||
// Check whether there is the next message header in the HttpMsg->Body.
|
||||
//
|
||||
if (HttpInstance->NextMsg != NULL) {
|
||||
HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength);
|
||||
CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
|
||||
HttpMsg->BodyLength = HttpInstance->NextMsg - (CHAR8 *) HttpMsg->Body;
|
||||
}
|
||||
|
||||
HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
|
||||
if (HttpInstance->CacheLen != 0) {
|
||||
if (HttpInstance->CacheBody != NULL) {
|
||||
FreePool (HttpInstance->CacheBody);
|
||||
}
|
||||
|
||||
HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
|
||||
if (HttpInstance->CacheBody == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error2;
|
||||
}
|
||||
|
||||
CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
|
||||
HttpInstance->CacheOffset = 0;
|
||||
|
||||
HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength));
|
||||
HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
|
||||
if (HttpInstance->CacheLen != 0) {
|
||||
if (HttpInstance->CacheBody != NULL) {
|
||||
FreePool (HttpInstance->CacheBody);
|
||||
}
|
||||
} else {
|
||||
HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
|
||||
CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
|
||||
HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
|
||||
if (HttpInstance->CacheLen != 0) {
|
||||
if (HttpInstance->CacheBody != NULL) {
|
||||
FreePool (HttpInstance->CacheBody);
|
||||
}
|
||||
|
||||
HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
|
||||
if (HttpInstance->CacheBody == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error2;
|
||||
}
|
||||
HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
|
||||
if (HttpInstance->CacheBody == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error2;
|
||||
}
|
||||
|
||||
CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
|
||||
HttpInstance->CacheOffset = 0;
|
||||
CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
|
||||
HttpInstance->CacheOffset = 0;
|
||||
if (HttpInstance->NextMsg != NULL) {
|
||||
HttpInstance->NextMsg = HttpInstance->CacheBody;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -197,6 +197,16 @@ HttpTcpReceiveNotifyDpc (
|
|||
Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;
|
||||
}
|
||||
|
||||
//
|
||||
// Record the CallbackData data.
|
||||
//
|
||||
HttpInstance->CallbackData.Wrap = (VOID *) Wrap;
|
||||
HttpInstance->CallbackData.ParseData = Wrap->HttpToken->Message->Body;
|
||||
HttpInstance->CallbackData.ParseDataLength = Length;
|
||||
|
||||
//
|
||||
// Parse Body with CallbackData data.
|
||||
//
|
||||
Status = HttpParseMessageBody (
|
||||
HttpInstance->MsgParser,
|
||||
Length,
|
||||
|
|
|
@ -91,6 +91,15 @@ typedef struct {
|
|||
EFI_TLS_SESSION_STATE SessionState;
|
||||
} TLS_CONFIG_DATA;
|
||||
|
||||
//
|
||||
// Callback data for HTTP_PARSER_CALLBACK()
|
||||
//
|
||||
typedef struct {
|
||||
UINTN ParseDataLength;
|
||||
VOID *ParseData;
|
||||
VOID *Wrap;
|
||||
} HTTP_CALLBACK_DATA;
|
||||
|
||||
typedef struct _HTTP_PROTOCOL {
|
||||
UINT32 Signature;
|
||||
EFI_HTTP_PROTOCOL Http;
|
||||
|
@ -149,6 +158,7 @@ typedef struct _HTTP_PROTOCOL {
|
|||
// HTTP message-body parser.
|
||||
//
|
||||
VOID *MsgParser;
|
||||
HTTP_CALLBACK_DATA CallbackData;
|
||||
|
||||
EFI_HTTP_VERSION HttpVersion;
|
||||
UINT32 TimeOutMillisec;
|
||||
|
|
Loading…
Reference in New Issue