/** @file\r
Implementation of EFI_HTTP_PROTOCOL protocol interfaces.\r
\r
- Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.\r
@param[out] HttpConfigData Point to buffer for operational parameters of this\r
- HTTP instance.\r
+ HTTP instance. It is the responsibility of the caller\r
+ to allocate the memory for HttpConfigData and\r
+ HttpConfigData->AccessPoint.IPv6Node/IPv4Node. In fact,\r
+ it is recommended to allocate sufficient memory to record\r
+ IPv6Node since it is big enough for all possibilities.\r
\r
@retval EFI_SUCCESS Operation succeeded.\r
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
This is NULL.\r
HttpConfigData is NULL.\r
- HttpInstance->LocalAddressIsIPv6 is FALSE and\r
- HttpConfigData->IPv4Node is NULL.\r
- HttpInstance->LocalAddressIsIPv6 is TRUE and\r
- HttpConfigData->IPv6Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv4Node or\r
+ HttpConfigData->AccessPoint.IPv6Node is NULL.\r
@retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.\r
\r
**/\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
- if ((HttpInstance->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
- (!HttpInstance->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)) {\r
+ if ((HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
+ (HttpConfigData->AccessPoint.IPv4Node == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
This is NULL.\r
HttpConfigData->LocalAddressIsIPv6 is FALSE and\r
- HttpConfigData->IPv4Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv4Node is NULL.\r
HttpConfigData->LocalAddressIsIPv6 is TRUE and\r
- HttpConfigData->IPv6Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv6Node is NULL.\r
@retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling\r
Configure() with NULL to reset it.\r
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
EfiHttpConfigure (\r
IN EFI_HTTP_PROTOCOL *This,\r
IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL\r
- ) \r
+ )\r
{\r
HTTP_PROTOCOL *HttpInstance;\r
EFI_STATUS Status;\r
- \r
+\r
//\r
// Check input parameters.\r
//\r
if (This == NULL ||\r
- (HttpConfigData != NULL && \r
+ (HttpConfigData != NULL &&\r
((HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
(!HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)))) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL && HttpInstance->Service != NULL);\r
+ ASSERT (HttpInstance->Service != NULL);\r
\r
if (HttpConfigData != NULL) {\r
\r
HttpInstance->HttpVersion = HttpConfigData->HttpVersion;\r
HttpInstance->TimeOutMillisec = HttpConfigData->TimeOutMillisec;\r
HttpInstance->LocalAddressIsIPv6 = HttpConfigData->LocalAddressIsIPv6;\r
- \r
- if (HttpConfigData->LocalAddressIsIPv6) { \r
+\r
+ if (HttpConfigData->LocalAddressIsIPv6) {\r
CopyMem (\r
&HttpInstance->Ipv6Node,\r
HttpConfigData->AccessPoint.IPv6Node,\r
sizeof (HttpInstance->IPv4Node)\r
);\r
}\r
- \r
+\r
//\r
// Creat Tcp child\r
//\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
HttpInstance->State = HTTP_STATE_HTTP_CONFIGED;\r
return EFI_SUCCESS;\r
\r
return EFI_SUCCESS;\r
}\r
}\r
- \r
+\r
\r
/**\r
The Request() function queues an HTTP request to this HTTP instance.\r
Request = HttpMsg->Data.Request;\r
\r
//\r
- // Only support GET, HEAD, PATCH, PUT and POST method in current implementation.\r
+ // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation.\r
//\r
if ((Request != NULL) && (Request->Method != HttpMethodGet) &&\r
- (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodPut) && \r
- (Request->Method != HttpMethodPost) && (Request->Method != HttpMethodPatch)) {\r
+ (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) &&\r
+ (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) &&\r
+ (Request->Method != HttpMethodPatch)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
//\r
// Capture the method into HttpInstance.\r
//\r
// Request would be NULL only for PUT/POST/PATCH operation (in the current implementation)\r
//\r
- if ((HttpInstance->Method != HttpMethodPut) && \r
- (HttpInstance->Method != HttpMethodPost) && \r
+ if ((HttpInstance->Method != HttpMethodPut) &&\r
+ (HttpInstance->Method != HttpMethodPost) &&\r
(HttpInstance->Method != HttpMethodPatch)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);\r
\r
//\r
- // From the information in Url, the HTTP instance will \r
+ // From the information in Url, the HTTP instance will\r
// be able to determine whether to use http or https.\r
//\r
HttpInstance->UseHttps = IsHttpsUrl (Url);\r
// HTTP is disabled, return directly if the URI is not HTTPS.\r
//\r
if (!PcdGetBool (PcdAllowHttpConnections) && !(HttpInstance->UseHttps)) {\r
- \r
+\r
DEBUG ((EFI_D_ERROR, "EfiHttpRequest: HTTP is disabled.\n"));\r
\r
return EFI_ACCESS_DENIED;\r
goto Error1;\r
}\r
\r
- HostName = NULL;\r
- Status = HttpUrlGetHostName (Url, UrlParser, &HostName);\r
+ Status = HttpUrlGetHostName (Url, UrlParser, &HostName);\r
if (EFI_ERROR (Status)) {\r
- goto Error1;\r
+ goto Error1;\r
+ }\r
+\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ HostNameSize = AsciiStrSize (HostName);\r
+\r
+ if (HostNameSize > 2 && HostName[0] == '[' && HostName[HostNameSize - 2] == ']') {\r
+ //\r
+ // HostName format is expressed as IPv6, so, remove '[' and ']'.\r
+ //\r
+ HostNameSize -= 2;\r
+ CopyMem (HostName, HostName + 1, HostNameSize - 1);\r
+ HostName[HostNameSize - 1] = '\0';\r
+ }\r
}\r
\r
Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);\r
ReConfigure = FALSE;\r
} else {\r
if ((HttpInstance->RemotePort == RemotePort) &&\r
- (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) && \r
- (!HttpInstance->UseHttps || (HttpInstance->UseHttps && \r
- !TlsConfigure && \r
+ (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&\r
+ (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&\r
+ !TlsConfigure &&\r
HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) {\r
//\r
// Host Name and port number of the request URL are the same with previous call to Request().\r
\r
FreePool (HostName);\r
\r
+ HttpUrlFreeParser (UrlParser);\r
+\r
//\r
// Queue the HTTP token and return.\r
//\r
}\r
}\r
}\r
- } \r
+ }\r
\r
if (Configure) {\r
//\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Error1;\r
}\r
- \r
+\r
AsciiStrToUnicodeStrS (HostName, HostNameStr, HostNameSize);\r
if (!HttpInstance->LocalAddressIsIPv6) {\r
Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);\r
} else {\r
Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr);\r
}\r
- \r
+\r
FreePool (HostNameStr);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Error: Could not retrieve the host address from DNS server.\n"));\r
goto Error1;\r
}\r
}\r
if (EFI_ERROR (Status)) {\r
goto Error1;\r
}\r
- \r
+\r
TlsCloseTxRxEvent (HttpInstance);\r
}\r
- \r
+\r
HttpCloseConnection (HttpInstance);\r
EfiHttpCancel (This, NULL);\r
}\r
if (Request != NULL) {\r
Wrap->TcpWrap.Method = Request->Method;\r
}\r
- \r
+\r
Status = HttpInitSession (\r
- HttpInstance, \r
- Wrap, \r
- Configure || ReConfigure, \r
+ HttpInstance,\r
+ Wrap,\r
+ Configure || ReConfigure,\r
TlsConfigure\r
);\r
if (EFI_ERROR (Status)) {\r
\r
if (!Configure && !ReConfigure && !TlsConfigure) {\r
//\r
- // For the new HTTP token, create TX TCP token events. \r
+ // For the new HTTP token, create TX TCP token events.\r
//\r
Status = HttpCreateTcpTxEvent (Wrap);\r
if (EFI_ERROR (Status)) {\r
goto Error1;\r
}\r
}\r
- \r
+\r
//\r
// Create request message.\r
//\r
goto Error3;\r
}\r
\r
- ASSERT (RequestMsg != NULL);\r
-\r
//\r
// Every request we insert a TxToken and a response call would remove the TxToken.\r
// In cases of PUT/POST/PATCH, after an initial request-response pair, we would do a\r
RequestMsgSize\r
);\r
if (EFI_ERROR (Status)) {\r
- goto Error5; \r
+ goto Error5;\r
}\r
\r
DispatchDpc ();\r
- \r
+\r
if (HostName != NULL) {\r
FreePool (HostName);\r
}\r
- \r
+\r
+ if (UrlParser != NULL) {\r
+ HttpUrlFreeParser (UrlParser);\r
+ }\r
+\r
return EFI_SUCCESS;\r
\r
Error5:\r
Error4:\r
if (RequestMsg != NULL) {\r
FreePool (RequestMsg);\r
- } \r
+ }\r
\r
Error3:\r
if (HttpInstance->UseHttps) {\r
\r
Error2:\r
HttpCloseConnection (HttpInstance);\r
- \r
+\r
HttpCloseTcpConnCloseEvent (HttpInstance);\r
if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {\r
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
if (Wrap != NULL) {\r
FreePool (Wrap);\r
}\r
- if (UrlParser!= NULL) {\r
+ if (UrlParser != NULL) {\r
HttpUrlFreeParser (UrlParser);\r
}\r
\r
return Status;\r
- \r
+\r
}\r
\r
/**\r
- Cancel a user's Token. \r
- \r
+ Cancel a user's Token.\r
+\r
@param[in] Map The HTTP instance's token queue.\r
@param[in] Item Object container for one HTTP token and token's wrap.\r
@param[in] Context The user's token to cancel.\r
Wrap = (HTTP_TOKEN_WRAP *) Item->Value;\r
ASSERT (Wrap != NULL);\r
HttpInstance = Wrap->HttpInstance;\r
- \r
+\r
if (!HttpInstance->LocalAddressIsIPv6) {\r
if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
//\r
return EFI_ABORTED;\r
}\r
\r
- return EFI_SUCCESS; \r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
cancelled.\r
\r
@retval EFI_SUCCESS The token is cancelled.\r
- @retval EFI_NOT_FOUND The asynchronous request or response token is not found. \r
+ @retval EFI_NOT_FOUND The asynchronous request or response token is not found.\r
@retval Others Other error as indicated.\r
\r
**/\r
if (Token != NULL) {\r
if (Status == EFI_ABORTED) {\r
return EFI_SUCCESS;\r
- } \r
+ }\r
} else {\r
return Status;\r
}\r
HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);\r
}\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r
IN VOID *Context\r
)\r
{\r
+ HTTP_CALLBACK_DATA *CallbackData;\r
HTTP_TOKEN_WRAP *Wrap;\r
UINTN BodyLength;\r
CHAR8 *Body;\r
return EFI_SUCCESS;\r
}\r
\r
- Wrap = (HTTP_TOKEN_WRAP *) Context;\r
- Body = Wrap->HttpToken->Message->Body;\r
- BodyLength = Wrap->HttpToken->Message->BodyLength;\r
+ CallbackData = (HTTP_CALLBACK_DATA *) Context;\r
+\r
+ Wrap = (HTTP_TOKEN_WRAP *) (CallbackData->Wrap);\r
+ Body = CallbackData->ParseData;\r
+ BodyLength = CallbackData->ParseDataLength;\r
+\r
if (Data < Body + BodyLength) {\r
Wrap->HttpInstance->NextMsg = Data;\r
} else {\r
Wrap->HttpInstance->NextMsg = NULL;\r
}\r
- \r
-\r
- //\r
- // Free Tx4Token or Tx6Token since already received corrsponding HTTP response.\r
- //\r
- FreePool (Wrap);\r
\r
return EFI_SUCCESS;\r
}\r
\r
@retval EFI_SUCCESS Allocation succeeded.\r
@retval EFI_OUT_OF_RESOURCES Failed to complete the opration due to lack of resources.\r
- @retval EFI_NOT_READY Can't find a corresponding Tx4Token/Tx6Token or \r
+ @retval EFI_NOT_READY Can't find a corresponding Tx4Token/Tx6Token or\r
the EFI_HTTP_UTILITIES_PROTOCOL is not available.\r
\r
**/\r
if (Wrap == NULL || Wrap->HttpInstance == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- \r
+\r
HttpInstance = Wrap->HttpInstance;\r
Token = Wrap->HttpToken;\r
HttpMsg = Token->Message;\r
ValueInItem = NULL;\r
Fragment.Len = 0;\r
Fragment.Bulk = NULL;\r
- \r
+\r
if (HttpMsg->Data.Response != NULL) {\r
//\r
// Check whether we have cached header from previous call.\r
//\r
// Check whether we cached the whole HTTP headers.\r
//\r
- EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR); \r
- } \r
+ EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR);\r
+ }\r
\r
HttpInstance->EndofHeader = &EndofHeader;\r
HttpInstance->HttpHeaders = &HttpHeaders;\r
HttpMsg->HeaderCount,\r
HttpMsg->Headers,\r
HttpBodyParserCallback,\r
- (VOID *) ValueInItem,\r
+ (VOID *) (&HttpInstance->CallbackData),\r
&HttpInstance->MsgParser\r
);\r
if (EFI_ERROR (Status)) {\r
// Check whether we received a complete HTTP message.\r
//\r
if (HttpInstance->CacheBody != NULL) {\r
+ //\r
+ // Record the CallbackData data.\r
+ //\r
+ HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+ HttpInstance->CallbackData.ParseData = (VOID *) HttpInstance->CacheBody;\r
+ HttpInstance->CallbackData.ParseDataLength = HttpInstance->CacheLen;\r
+\r
+ //\r
+ // Parse message with CallbackData data.\r
+ //\r
Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody);\r
if (EFI_ERROR (Status)) {\r
goto Error2;\r
}\r
+ }\r
\r
- if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
- //\r
- // Free the MsgParse since we already have a full HTTP message.\r
- //\r
- HttpFreeMsgParser (HttpInstance->MsgParser);\r
- HttpInstance->MsgParser = NULL;\r
- }\r
+ if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
+ //\r
+ // Free the MsgParse since we already have a full HTTP message.\r
+ //\r
+ HttpFreeMsgParser (HttpInstance->MsgParser);\r
+ HttpInstance->MsgParser = NULL;\r
}\r
}\r
\r
//\r
// We have a cached HTTP message which includes a part of HTTP header of next message.\r
//\r
- BodyLen = HttpInstance->NextMsg - (HttpInstance->CacheBody + HttpInstance->CacheOffset); \r
+ BodyLen = HttpInstance->NextMsg - (HttpInstance->CacheBody + HttpInstance->CacheOffset);\r
} else {\r
BodyLen = HttpInstance->CacheLen - HttpInstance->CacheOffset;\r
}\r
//\r
Status = EFI_SUCCESS;\r
goto Exit;\r
- } \r
+ }\r
\r
if (BodyLen == 0 && HttpInstance->MsgParser == NULL) {\r
//\r
//\r
HttpMsg->BodyLength = 0;\r
Status = EFI_SUCCESS;\r
- goto Exit; \r
- } \r
+ goto Exit;\r
+ }\r
}\r
\r
ASSERT (HttpInstance->MsgParser != NULL);\r
if (EFI_ERROR (Status)) {\r
goto Error2;\r
}\r
- \r
+\r
} else {\r
if (HttpInstance->TimeoutEvent == NULL) {\r
//\r
if (EFI_ERROR (Status)) {\r
goto Error2;\r
}\r
- \r
+\r
Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);\r
\r
gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
goto Error2;\r
}\r
\r
//\r
- // Check whether we receive a complete HTTP message.\r
+ // Process the received the body packet.\r
+ //\r
+ HttpMsg->BodyLength = MIN ((UINTN) Fragment.Len, HttpMsg->BodyLength);\r
+\r
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
+\r
+ //\r
+ // Record the CallbackData data.\r
+ //\r
+ HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+ HttpInstance->CallbackData.ParseData = HttpMsg->Body;\r
+ HttpInstance->CallbackData.ParseDataLength = HttpMsg->BodyLength;\r
+\r
+ //\r
+ // Parse Body with CallbackData data.\r
//\r
Status = HttpParseMessageBody (\r
HttpInstance->MsgParser,\r
- (UINTN) Fragment.Len,\r
- (CHAR8 *) Fragment.Bulk\r
+ HttpMsg->BodyLength,\r
+ HttpMsg->Body\r
);\r
if (EFI_ERROR (Status)) {\r
goto Error2;\r
}\r
\r
//\r
- // We receive part of header of next HTTP msg.\r
+ // Check whether there is the next message header in the HttpMsg->Body.\r
//\r
if (HttpInstance->NextMsg != NULL) {\r
- HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength);\r
- CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
- \r
- HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
- if (HttpInstance->CacheLen != 0) {\r
- if (HttpInstance->CacheBody != NULL) {\r
- FreePool (HttpInstance->CacheBody);\r
- }\r
- \r
- HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
- if (HttpInstance->CacheBody == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Error2;\r
- }\r
- \r
- CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
- HttpInstance->CacheOffset = 0;\r
+ HttpMsg->BodyLength = HttpInstance->NextMsg - (CHAR8 *) HttpMsg->Body;\r
+ }\r
\r
- HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength));\r
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
+ if (HttpInstance->CacheLen != 0) {\r
+ if (HttpInstance->CacheBody != NULL) {\r
+ FreePool (HttpInstance->CacheBody);\r
+ }\r
+\r
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
+ if (HttpInstance->CacheBody == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Error2;\r
}\r
- } else {\r
- HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);\r
- CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
- HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
- if (HttpInstance->CacheLen != 0) {\r
- if (HttpInstance->CacheBody != NULL) {\r
- FreePool (HttpInstance->CacheBody);\r
- }\r
- \r
- HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
- if (HttpInstance->CacheBody == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Error2;\r
- }\r
\r
- CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
- HttpInstance->CacheOffset = 0;\r
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
+ HttpInstance->CacheOffset = 0;\r
+ if (HttpInstance->NextMsg != NULL) {\r
+ HttpInstance->NextMsg = HttpInstance->CacheBody;\r
}\r
}\r
\r
} else {\r
FreePool (Wrap);\r
}\r
- \r
+\r
if (HttpHeaders != NULL) {\r
FreePool (HttpHeaders);\r
HttpHeaders = NULL;\r
\r
gBS->SignalEvent (Token->Event);\r
\r
- return Status; \r
+ return Status;\r
\r
}\r
\r
if (HttpMsg == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- \r
+\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r
// Check whether the token already existed.\r
//\r
if (EFI_ERROR (NetMapIterate (&HttpInstance->RxTokens, HttpTokenExist, Token))) {\r
- return EFI_ACCESS_DENIED; \r
+ return EFI_ACCESS_DENIED;\r
}\r
\r
Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));\r
Wrap->HttpToken = Token;\r
\r
//\r
- // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to \r
- // receive the https response. A special TlsRxToken is used for receiving TLS \r
+ // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to\r
+ // receive the https response. A special TlsRxToken is used for receiving TLS\r
// related messages. It should be a blocking response.\r
//\r
if (!HttpInstance->UseHttps) {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
}\r
FreePool (Wrap);\r
- } \r
+ }\r
\r
- return Status; \r
+ return Status;\r
}\r
\r
/**\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r
}\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
if (HttpInstance->Tcp6 == NULL) {\r
return EFI_NOT_STARTED;\r
}\r
Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
}\r
- \r
+\r
DispatchDpc ();\r
- \r
+\r
return Status;\r
}\r