MdeModulePkg:DxeHttpLib: Add checks in HttpGenRequestMessage API

HttpGenRequestMessage assumes that HTTP message would always
contain a request-line, headers and an optional message body.
However, subsequent to a HTTP PUT/POST request, HTTP requests
would contain just the message body. This patch supports
creation of such request messages with additional checks.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hegde, Nagaraj P <nagaraj-p.hegde@hpe.com>
Reviewed-By: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
This commit is contained in:
Nagaraj Hegde
2016-05-05 14:59:03 +08:00
committed by Fu Siyuan
parent 0c986eafae
commit 09991304c9

View File

@ -1681,61 +1681,92 @@ HttpGenRequestMessage (
HttpUtilitiesProtocol = NULL; HttpUtilitiesProtocol = NULL;
// //
// Locate the HTTP_UTILITIES protocol. // 1. If we have a Request, we cannot have a NULL Url
// 2. If we have a Request, HeaderCount can not be non-zero
// 3. If we do not have a Request, HeaderCount should be zero
// 4. If we do not have Request and Headers, we need at least a message-body
// //
Status = gBS->LocateProtocol ( if ((Message->Data.Request != NULL && Url == NULL) ||
&gEfiHttpUtilitiesProtocolGuid, (Message->Data.Request != NULL && Message->HeaderCount == 0) ||
NULL, (Message->Data.Request == NULL && Message->HeaderCount != 0) ||
(VOID **)&HttpUtilitiesProtocol (Message->Data.Request == NULL && Message->HeaderCount == 0 && Message->BodyLength == 0)) {
); return EFI_INVALID_PARAMETER;
}
if (EFI_ERROR (Status)) { if (Message->HeaderCount != 0) {
DEBUG ((DEBUG_ERROR,"Failed to locate Http Utilities protocol. Status = %r.\n", Status)); //
return Status; // Locate the HTTP_UTILITIES protocol.
//
Status = gBS->LocateProtocol (
&gEfiHttpUtilitiesProtocolGuid,
NULL,
(VOID **)&HttpUtilitiesProtocol
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,"Failed to locate Http Utilities protocol. Status = %r.\n", Status));
return Status;
}
//
// Build AppendList to send into HttpUtilitiesBuild
//
AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));
if (AppendList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
for(Index = 0; Index < Message->HeaderCount; Index++){
AppendList[Index] = &Message->Headers[Index];
}
//
// Build raw HTTP Headers
//
Status = HttpUtilitiesProtocol->Build (
HttpUtilitiesProtocol,
0,
NULL,
0,
NULL,
Message->HeaderCount,
AppendList,
&HttpHdrSize,
&HttpHdr
);
if (AppendList != NULL) {
FreePool (AppendList);
}
if (EFI_ERROR (Status) || HttpHdr == NULL){
return Status;
}
} }
// //
// Build AppendList to send into HttpUtilitiesBuild // If we have headers to be sent, account for it.
// //
AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount)); if (Message->HeaderCount != 0) {
if (AppendList == NULL) { MsgSize = HttpHdrSize;
return EFI_OUT_OF_RESOURCES;
}
for(Index = 0; Index < Message->HeaderCount; Index++){
AppendList[Index] = &Message->Headers[Index];
} }
// //
// Build raw HTTP Headers // If we have a request line, account for the fields.
// //
Status = HttpUtilitiesProtocol->Build ( if (Message->Data.Request != NULL) {
HttpUtilitiesProtocol, MsgSize += HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (HTTP_VERSION_CRLF_STR) + AsciiStrLen (Url);
0,
NULL,
0,
NULL,
Message->HeaderCount,
AppendList,
&HttpHdrSize,
&HttpHdr
);
if (AppendList != NULL) {
FreePool (AppendList);
} }
if (EFI_ERROR (Status) || HttpHdr == NULL){
return Status;
}
// //
// Calculate HTTP message length. // If we have a message body to be sent, account for it.
// //
MsgSize = Message->BodyLength + HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (Url) + MsgSize += Message->BodyLength;
AsciiStrLen (HTTP_VERSION_CRLF_STR) + HttpHdrSize;
//
// memory for the string that needs to be sent to TCP
//
*RequestMsg = AllocateZeroPool (MsgSize); *RequestMsg = AllocateZeroPool (MsgSize);
if (*RequestMsg == NULL) { if (*RequestMsg == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
@ -1746,61 +1777,65 @@ HttpGenRequestMessage (
// //
// Construct header request // Construct header request
// //
switch (Message->Data.Request->Method) { if (Message->Data.Request != NULL) {
case HttpMethodGet: switch (Message->Data.Request->Method) {
StrLength = sizeof (HTTP_METHOD_GET) - 1; case HttpMethodGet:
CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength); StrLength = sizeof (HTTP_METHOD_GET) - 1;
CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodPut:
StrLength = sizeof (HTTP_METHOD_PUT) - 1;
CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodPatch:
StrLength = sizeof (HTTP_METHOD_PATCH) - 1;
CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodPost:
StrLength = sizeof (HTTP_METHOD_POST) - 1;
CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodHead:
StrLength = sizeof (HTTP_METHOD_HEAD) - 1;
CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodDelete:
StrLength = sizeof (HTTP_METHOD_DELETE) - 1;
CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
RequestPtr += StrLength;
break;
default:
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
StrLength = AsciiStrLen(EMPTY_SPACE);
CopyMem (RequestPtr, EMPTY_SPACE, StrLength);
RequestPtr += StrLength; RequestPtr += StrLength;
break;
case HttpMethodPut: StrLength = AsciiStrLen (Url);
StrLength = sizeof (HTTP_METHOD_PUT) - 1; CopyMem (RequestPtr, Url, StrLength);
CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength);
RequestPtr += StrLength; RequestPtr += StrLength;
break;
case HttpMethodPatch: StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;
StrLength = sizeof (HTTP_METHOD_PATCH) - 1; CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);
CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength);
RequestPtr += StrLength; RequestPtr += StrLength;
break;
case HttpMethodPost: if (HttpHdr != NULL) {
StrLength = sizeof (HTTP_METHOD_POST) - 1; //
CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength); // Construct header
RequestPtr += StrLength; //
break; CopyMem (RequestPtr, HttpHdr, HttpHdrSize);
case HttpMethodHead: RequestPtr += HttpHdrSize;
StrLength = sizeof (HTTP_METHOD_HEAD) - 1; }
CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);
RequestPtr += StrLength;
break;
case HttpMethodDelete:
StrLength = sizeof (HTTP_METHOD_DELETE) - 1;
CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
RequestPtr += StrLength;
break;
default:
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
goto Exit;
} }
StrLength = AsciiStrLen(EMPTY_SPACE);
CopyMem (RequestPtr, EMPTY_SPACE, StrLength);
RequestPtr += StrLength;
StrLength = AsciiStrLen (Url);
CopyMem (RequestPtr, Url, StrLength);
RequestPtr += StrLength;
StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;
CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);
RequestPtr += StrLength;
//
// Construct header
//
CopyMem (RequestPtr, HttpHdr, HttpHdrSize);
RequestPtr += HttpHdrSize;
// //
// Construct body // Construct body
// //