]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpImpl.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpImpl.c
index f70e116f38d7e78f7bfc131c343b26aa4bc622bc..d64cd9e965c0d890ea5ddc2e1b2f96e73a3c0924 100644 (file)
@@ -1,16 +1,10 @@
 /** @file\r
   Implementation of EFI_HTTP_PROTOCOL protocol interfaces.\r
 \r
-  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2021, 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
@@ -51,11 +45,11 @@ EFI_HTTP_PROTOCOL  mEfiHttpTemplate = {
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpGetModeData (\r
-  IN  EFI_HTTP_PROTOCOL         *This,\r
-  OUT EFI_HTTP_CONFIG_DATA      *HttpConfigData\r
+  IN  EFI_HTTP_PROTOCOL     *This,\r
+  OUT EFI_HTTP_CONFIG_DATA  *HttpConfigData\r
   )\r
 {\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
+  HTTP_PROTOCOL  *HttpInstance;\r
 \r
   //\r
   // Check input parameters.\r
@@ -67,7 +61,8 @@ EfiHttpGetModeData (
   HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
 \r
   if ((HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
-      (HttpConfigData->AccessPoint.IPv4Node == NULL)) {\r
+      (HttpConfigData->AccessPoint.IPv4Node == NULL))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -84,7 +79,7 @@ EfiHttpGetModeData (
       HttpConfigData->AccessPoint.IPv6Node,\r
       &HttpInstance->Ipv6Node,\r
       sizeof (HttpInstance->Ipv6Node)\r
-    );\r
+      );\r
   } else {\r
     CopyMem (\r
       HttpConfigData->AccessPoint.IPv4Node,\r
@@ -130,20 +125,21 @@ EfiHttpGetModeData (
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpConfigure (\r
-  IN  EFI_HTTP_PROTOCOL         *This,\r
-  IN  EFI_HTTP_CONFIG_DATA      *HttpConfigData OPTIONAL\r
+  IN  EFI_HTTP_PROTOCOL     *This,\r
+  IN  EFI_HTTP_CONFIG_DATA  *HttpConfigData OPTIONAL\r
   )\r
 {\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
-  EFI_STATUS                    Status;\r
+  HTTP_PROTOCOL  *HttpInstance;\r
+  EFI_STATUS     Status;\r
 \r
   //\r
   // Check input parameters.\r
   //\r
-  if (This == NULL ||\r
-      (HttpConfigData != NULL &&\r
-       ((HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
-        (!HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)))) {\r
+  if ((This == NULL) ||\r
+      ((HttpConfigData != NULL) &&\r
+       ((HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv6Node == NULL)) ||\r
+        (!HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv4Node == NULL)))))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -151,7 +147,6 @@ EfiHttpConfigure (
   ASSERT (HttpInstance->Service != NULL);\r
 \r
   if (HttpConfigData != NULL) {\r
-\r
     if (HttpConfigData->HttpVersion >= HttpVersionUnsupported) {\r
       return EFI_UNSUPPORTED;\r
     }\r
@@ -191,10 +186,9 @@ EfiHttpConfigure (
 \r
     HttpInstance->State = HTTP_STATE_HTTP_CONFIGED;\r
     return EFI_SUCCESS;\r
-\r
   } else {\r
     //\r
-    // Reset all the resources related to HttpInsance.\r
+    // Reset all the resources related to HttpInstance.\r
     //\r
     HttpCleanProtocol (HttpInstance);\r
     HttpInstance->State = HTTP_STATE_UNCONFIGED;\r
@@ -202,7 +196,6 @@ EfiHttpConfigure (
   }\r
 }\r
 \r
-\r
 /**\r
   The Request() function queues an HTTP request to this HTTP instance.\r
 \r
@@ -232,41 +225,41 @@ EfiHttpConfigure (
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpRequest (\r
-  IN  EFI_HTTP_PROTOCOL         *This,\r
-  IN  EFI_HTTP_TOKEN            *Token\r
+  IN  EFI_HTTP_PROTOCOL  *This,\r
+  IN  EFI_HTTP_TOKEN     *Token\r
   )\r
 {\r
-  EFI_HTTP_MESSAGE              *HttpMsg;\r
-  EFI_HTTP_REQUEST_DATA         *Request;\r
-  VOID                          *UrlParser;\r
-  EFI_STATUS                    Status;\r
-  CHAR8                         *HostName;\r
-  UINTN                         HostNameSize;\r
-  UINT16                        RemotePort;\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
-  BOOLEAN                       Configure;\r
-  BOOLEAN                       ReConfigure;\r
-  BOOLEAN                       TlsConfigure;\r
-  CHAR8                         *RequestMsg;\r
-  CHAR8                         *Url;\r
-  UINTN                         UrlLen;\r
-  CHAR16                        *HostNameStr;\r
-  HTTP_TOKEN_WRAP               *Wrap;\r
-  CHAR8                         *FileUrl;\r
-  UINTN                         RequestMsgSize;\r
-  EFI_HANDLE                    ImageHandle;\r
+  EFI_HTTP_MESSAGE       *HttpMsg;\r
+  EFI_HTTP_REQUEST_DATA  *Request;\r
+  VOID                   *UrlParser;\r
+  EFI_STATUS             Status;\r
+  CHAR8                  *HostName;\r
+  UINTN                  HostNameSize;\r
+  UINT16                 RemotePort;\r
+  HTTP_PROTOCOL          *HttpInstance;\r
+  BOOLEAN                Configure;\r
+  BOOLEAN                ReConfigure;\r
+  BOOLEAN                TlsConfigure;\r
+  CHAR8                  *RequestMsg;\r
+  CHAR8                  *Url;\r
+  UINTN                  UrlLen;\r
+  CHAR16                 *HostNameStr;\r
+  HTTP_TOKEN_WRAP        *Wrap;\r
+  CHAR8                  *FileUrl;\r
+  UINTN                  RequestMsgSize;\r
+  EFI_HANDLE             ImageHandle;\r
 \r
   //\r
   // Initializations\r
   //\r
-  Url = NULL;\r
-  UrlParser = NULL;\r
-  RemotePort = 0;\r
-  HostName = NULL;\r
-  RequestMsg = NULL;\r
-  HostNameStr = NULL;\r
-  Wrap = NULL;\r
-  FileUrl = NULL;\r
+  Url          = NULL;\r
+  UrlParser    = NULL;\r
+  RemotePort   = 0;\r
+  HostName     = NULL;\r
+  RequestMsg   = NULL;\r
+  HostNameStr  = NULL;\r
+  Wrap         = NULL;\r
+  FileUrl      = NULL;\r
   TlsConfigure = FALSE;\r
 \r
   if ((This == NULL) || (Token == NULL)) {\r
@@ -286,7 +279,8 @@ EfiHttpRequest (
   if ((Request != NULL) && (Request->Method != HttpMethodGet) &&\r
       (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) &&\r
       (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) &&\r
-      (Request->Method != HttpMethodPatch)) {\r
+      (Request->Method != HttpMethodPatch))\r
+  {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -309,7 +303,8 @@ EfiHttpRequest (
     //\r
     if ((HttpInstance->Method != HttpMethodPut) &&\r
         (HttpInstance->Method != HttpMethodPost) &&\r
-        (HttpInstance->Method != HttpMethodPatch)) {\r
+        (HttpInstance->Method != HttpMethodPatch))\r
+    {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
@@ -323,7 +318,7 @@ EfiHttpRequest (
     //\r
     // We need to have the Message Body for sending the HTTP message across in these cases.\r
     //\r
-    if (HttpMsg->Body == NULL || HttpMsg->BodyLength == 0) {\r
+    if ((HttpMsg->Body == NULL) || (HttpMsg->BodyLength == 0)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
@@ -343,18 +338,18 @@ EfiHttpRequest (
     //\r
     // Parse the URI of the remote host.\r
     //\r
-    Url = HttpInstance->Url;\r
+    Url    = HttpInstance->Url;\r
     UrlLen = StrLen (Request->Url) + 1;\r
     if (UrlLen > HTTP_URL_BUFFER_LEN) {\r
       Url = AllocateZeroPool (UrlLen);\r
       if (Url == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
+\r
       FreePool (HttpInstance->Url);\r
       HttpInstance->Url = Url;\r
     }\r
 \r
-\r
     UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);\r
 \r
     //\r
@@ -367,8 +362,7 @@ EfiHttpRequest (
     // HTTP is disabled, return directly if the URI is not HTTPS.\r
     //\r
     if (!PcdGetBool (PcdAllowHttpConnections) && !(HttpInstance->UseHttps)) {\r
-\r
-      DEBUG ((EFI_D_ERROR, "EfiHttpRequest: HTTP is disabled.\n"));\r
+      DEBUG ((DEBUG_ERROR, "EfiHttpRequest: HTTP is disabled.\n"));\r
 \r
       return EFI_ACCESS_DENIED;\r
     }\r
@@ -376,7 +370,7 @@ EfiHttpRequest (
     //\r
     // Check whether we need to create Tls child and open the TLS protocol.\r
     //\r
-    if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {\r
+    if (HttpInstance->UseHttps && (HttpInstance->TlsChildHandle == NULL)) {\r
       //\r
       // Use TlsSb to create Tls child and open the TLS protocol.\r
       //\r
@@ -400,15 +394,27 @@ EfiHttpRequest (
     }\r
 \r
     UrlParser = NULL;\r
-    Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);\r
+    Status    = HttpParseUrl (Url, (UINT32)AsciiStrLen (Url), FALSE, &UrlParser);\r
     if (EFI_ERROR (Status)) {\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
@@ -419,6 +425,7 @@ EfiHttpRequest (
         RemotePort = HTTP_DEFAULT_PORT;\r
       }\r
     }\r
+\r
     //\r
     // If Configure is TRUE, it indicates the first time to call Request();\r
     // If ReConfigure is TRUE, it indicates the request URL is not same\r
@@ -437,7 +444,8 @@ EfiHttpRequest (
           (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&\r
           (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&\r
                                        !TlsConfigure &&\r
-                                       HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) {\r
+                                       (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))\r
+      {\r
         //\r
         // Host Name and port number of the request URL are the same with previous call to Request().\r
         // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring.\r
@@ -509,7 +517,7 @@ EfiHttpRequest (
 \r
     if (EFI_ERROR (Status)) {\r
       HostNameSize = AsciiStrSize (HostName);\r
-      HostNameStr = AllocateZeroPool (HostNameSize * sizeof (CHAR16));\r
+      HostNameStr  = AllocateZeroPool (HostNameSize * sizeof (CHAR16));\r
       if (HostNameStr == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Error1;\r
@@ -522,9 +530,11 @@ EfiHttpRequest (
         Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr);\r
       }\r
 \r
+      HttpNotify (HttpEventDns, Status);\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
+        DEBUG ((DEBUG_ERROR, "Error: Could not retrieve the host address from DNS server.\n"));\r
         goto Error1;\r
       }\r
     }\r
@@ -535,7 +545,7 @@ EfiHttpRequest (
     ASSERT (HttpInstance->RemoteHost == NULL);\r
     HttpInstance->RemotePort = RemotePort;\r
     HttpInstance->RemoteHost = HostName;\r
-    HostName = NULL;\r
+    HostName                 = NULL;\r
   }\r
 \r
   if (ReConfigure) {\r
@@ -570,8 +580,8 @@ EfiHttpRequest (
     goto Error1;\r
   }\r
 \r
-  Wrap->HttpToken      = Token;\r
-  Wrap->HttpInstance   = HttpInstance;\r
+  Wrap->HttpToken    = Token;\r
+  Wrap->HttpInstance = HttpInstance;\r
   if (Request != NULL) {\r
     Wrap->TcpWrap.Method = Request->Method;\r
   }\r
@@ -582,6 +592,7 @@ EfiHttpRequest (
              Configure || ReConfigure,\r
              TlsConfigure\r
              );\r
+  HttpNotify (HttpEventInitSession, Status);\r
   if (EFI_ERROR (Status)) {\r
     goto Error2;\r
   }\r
@@ -600,13 +611,14 @@ EfiHttpRequest (
   // Create request message.\r
   //\r
   FileUrl = Url;\r
-  if (Url != NULL && *FileUrl != '/') {\r
+  if ((Url != NULL) && (*FileUrl != '/')) {\r
     //\r
     // Convert the absolute-URI to the absolute-path\r
     //\r
     while (*FileUrl != ':') {\r
       FileUrl++;\r
     }\r
+\r
     if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) {\r
       FileUrl += 3;\r
       while (*FileUrl != '/') {\r
@@ -620,7 +632,7 @@ EfiHttpRequest (
 \r
   Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);\r
 \r
-  if (EFI_ERROR (Status) || NULL == RequestMsg) {\r
+  if (EFI_ERROR (Status) || (NULL == RequestMsg)) {\r
     goto Error3;\r
   }\r
 \r
@@ -643,7 +655,7 @@ EfiHttpRequest (
   Status = HttpTransmitTcp (\r
              HttpInstance,\r
              Wrap,\r
-             (UINT8*) RequestMsg,\r
+             (UINT8 *)RequestMsg,\r
              RequestMsgSize\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -690,6 +702,7 @@ Error2:
     gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
     Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;\r
   }\r
+\r
   if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) {\r
     gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);\r
     Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL;\r
@@ -699,15 +712,16 @@ Error1:
   if (HostName != NULL) {\r
     FreePool (HostName);\r
   }\r
+\r
   if (Wrap != NULL) {\r
     FreePool (Wrap);\r
   }\r
+\r
   if (UrlParser != NULL) {\r
     HttpUrlFreeParser (UrlParser);\r
   }\r
 \r
   return Status;\r
-\r
 }\r
 \r
 /**\r
@@ -724,16 +738,16 @@ Error1:
 EFI_STATUS\r
 EFIAPI\r
 HttpCancelTokens (\r
-  IN NET_MAP                *Map,\r
-  IN NET_MAP_ITEM           *Item,\r
-  IN VOID                   *Context\r
+  IN NET_MAP       *Map,\r
+  IN NET_MAP_ITEM  *Item,\r
+  IN VOID          *Context\r
   )\r
 {\r
-  EFI_HTTP_TOKEN            *Token;\r
-  HTTP_TOKEN_WRAP           *Wrap;\r
-  HTTP_PROTOCOL             *HttpInstance;\r
+  EFI_HTTP_TOKEN   *Token;\r
+  HTTP_TOKEN_WRAP  *Wrap;\r
+  HTTP_PROTOCOL    *HttpInstance;\r
 \r
-  Token = (EFI_HTTP_TOKEN *) Context;\r
+  Token = (EFI_HTTP_TOKEN *)Context;\r
 \r
   //\r
   // Return EFI_SUCCESS to check the next item in the map if\r
@@ -743,14 +757,14 @@ HttpCancelTokens (
     return EFI_SUCCESS;\r
   }\r
 \r
-  Wrap = (HTTP_TOKEN_WRAP *) Item->Value;\r
+  Wrap = (HTTP_TOKEN_WRAP *)Item->Value;\r
   ASSERT (Wrap != NULL);\r
   HttpInstance = Wrap->HttpInstance;\r
 \r
   if (!HttpInstance->LocalAddressIsIPv6) {\r
     if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
       //\r
-      // Cancle the Token before close its Event.\r
+      // Cancel the Token before close its Event.\r
       //\r
       HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &Wrap->TcpWrap.Rx4Token.CompletionToken);\r
 \r
@@ -762,7 +776,7 @@ HttpCancelTokens (
   } else {\r
     if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
       //\r
-      // Cancle the Token before close its Event.\r
+      // Cancel the Token before close its Event.\r
       //\r
       HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &Wrap->TcpWrap.Rx6Token.CompletionToken);\r
 \r
@@ -800,11 +814,11 @@ HttpCancelTokens (
 **/\r
 EFI_STATUS\r
 HttpCancel (\r
-  IN  HTTP_PROTOCOL             *HttpInstance,\r
-  IN  EFI_HTTP_TOKEN            *Token\r
+  IN  HTTP_PROTOCOL   *HttpInstance,\r
+  IN  EFI_HTTP_TOKEN  *Token\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
+  EFI_STATUS  Status;\r
 \r
   //\r
   // First check the tokens queued by EfiHttpRequest().\r
@@ -847,7 +861,6 @@ HttpCancel (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Abort an asynchronous HTTP request or response token.\r
 \r
@@ -873,11 +886,11 @@ HttpCancel (
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpCancel (\r
-  IN  EFI_HTTP_PROTOCOL         *This,\r
-  IN  EFI_HTTP_TOKEN            *Token\r
+  IN  EFI_HTTP_PROTOCOL  *This,\r
+  IN  EFI_HTTP_TOKEN     *Token\r
   )\r
 {\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
+  HTTP_PROTOCOL  *HttpInstance;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -890,7 +903,6 @@ EfiHttpCancel (
   }\r
 \r
   return HttpCancel (HttpInstance, Token);\r
-\r
 }\r
 \r
 /**\r
@@ -910,39 +922,37 @@ EfiHttpCancel (
 EFI_STATUS\r
 EFIAPI\r
 HttpBodyParserCallback (\r
-  IN HTTP_BODY_PARSE_EVENT      EventType,\r
-  IN CHAR8                      *Data,\r
-  IN UINTN                      Length,\r
-  IN VOID                       *Context\r
+  IN HTTP_BODY_PARSE_EVENT  EventType,\r
+  IN CHAR8                  *Data,\r
+  IN UINTN                  Length,\r
+  IN VOID                   *Context\r
   )\r
 {\r
-  HTTP_TOKEN_WRAP               *Wrap;\r
-  UINTN                         BodyLength;\r
-  CHAR8                         *Body;\r
+  HTTP_CALLBACK_DATA  *CallbackData;\r
+  HTTP_TOKEN_WRAP     *Wrap;\r
+  UINTN               BodyLength;\r
+  CHAR8               *Body;\r
 \r
   if (EventType != BodyParseEventOnComplete) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Data == NULL || Length != 0 || Context == NULL) {\r
+  if ((Data == NULL) || (Length != 0) || (Context == NULL)) {\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
@@ -952,41 +962,42 @@ HttpBodyParserCallback (
   @param[in]  Wrap                Pointer to HTTP token's wrap data.\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_OUT_OF_RESOURCES    Failed to complete the operation due to lack of resources.\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
 EFI_STATUS\r
 HttpResponseWorker (\r
-  IN  HTTP_TOKEN_WRAP           *Wrap\r
+  IN  HTTP_TOKEN_WRAP  *Wrap\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_HTTP_MESSAGE              *HttpMsg;\r
-  CHAR8                         *EndofHeader;\r
-  CHAR8                         *HttpHeaders;\r
-  UINTN                         SizeofHeaders;\r
-  UINTN                         BufferSize;\r
-  UINTN                         StatusCode;\r
-  CHAR8                         *Tmp;\r
-  CHAR8                         *HeaderTmp;\r
-  CHAR8                         *StatusCodeStr;\r
-  UINTN                         BodyLen;\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
-  EFI_HTTP_TOKEN                *Token;\r
-  NET_MAP_ITEM                  *Item;\r
-  HTTP_TOKEN_WRAP               *ValueInItem;\r
-  UINTN                         HdrLen;\r
-  NET_FRAGMENT                  Fragment;\r
-\r
-  if (Wrap == NULL || Wrap->HttpInstance == NULL) {\r
+  EFI_STATUS        Status;\r
+  EFI_HTTP_MESSAGE  *HttpMsg;\r
+  CHAR8             *EndofHeader;\r
+  CHAR8             *HttpHeaders;\r
+  UINTN             SizeofHeaders;\r
+  UINTN             BufferSize;\r
+  UINTN             StatusCode;\r
+  CHAR8             *Tmp;\r
+  CHAR8             *HeaderTmp;\r
+  CHAR8             *StatusCodeStr;\r
+  UINTN             BodyLen;\r
+  HTTP_PROTOCOL     *HttpInstance;\r
+  EFI_HTTP_TOKEN    *Token;\r
+  NET_MAP_ITEM      *Item;\r
+  HTTP_TOKEN_WRAP   *ValueInItem;\r
+  UINTN             HdrLen;\r
+  NET_FRAGMENT      Fragment;\r
+  UINT32            TimeoutValue;\r
+\r
+  if ((Wrap == NULL) || (Wrap->HttpInstance == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   HttpInstance = Wrap->HttpInstance;\r
-  Token = Wrap->HttpToken;\r
-  HttpMsg = Token->Message;\r
+  Token        = Wrap->HttpToken;\r
+  HttpMsg      = Token->Message;\r
 \r
   HttpInstance->EndofHeader = NULL;\r
   HttpInstance->HttpHeaders = NULL;\r
@@ -1007,7 +1018,7 @@ HttpResponseWorker (
       //\r
       // The data is stored at [NextMsg, CacheBody + CacheLen].\r
       //\r
-      HdrLen = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg;\r
+      HdrLen      = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg;\r
       HttpHeaders = AllocateZeroPool (HdrLen);\r
       if (HttpHeaders == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
@@ -1019,8 +1030,8 @@ HttpResponseWorker (
       HttpInstance->CacheBody   = NULL;\r
       HttpInstance->NextMsg     = NULL;\r
       HttpInstance->CacheOffset = 0;\r
-      SizeofHeaders = HdrLen;\r
-      BufferSize = HttpInstance->CacheLen;\r
+      SizeofHeaders             = HdrLen;\r
+      BufferSize                = HttpInstance->CacheLen;\r
 \r
       //\r
       // Check whether we cached the whole HTTP headers.\r
@@ -1031,7 +1042,6 @@ HttpResponseWorker (
     HttpInstance->EndofHeader = &EndofHeader;\r
     HttpInstance->HttpHeaders = &HttpHeaders;\r
 \r
-\r
     if (HttpInstance->TimeoutEvent == NULL) {\r
       //\r
       // Create TimeoutEvent for response\r
@@ -1048,10 +1058,15 @@ HttpResponseWorker (
       }\r
     }\r
 \r
+    //\r
+    // Get HTTP timeout value\r
+    //\r
+    TimeoutValue = PcdGet32 (PcdHttpIoTimeout);\r
+\r
     //\r
     // Start the timer, and wait Timeout seconds to receive the header packet.\r
     //\r
-    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);\r
+    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS);\r
     if (EFI_ERROR (Status)) {\r
       goto Error;\r
     }\r
@@ -1119,9 +1134,9 @@ HttpResponseWorker (
     }\r
 \r
     HttpMsg->Data.Response->StatusCode = HttpMappingToStatusCode (StatusCode);\r
-    HttpInstance->StatusCode = StatusCode;\r
+    HttpInstance->StatusCode           = StatusCode;\r
 \r
-    Status = EFI_NOT_READY;\r
+    Status      = EFI_NOT_READY;\r
     ValueInItem = NULL;\r
 \r
     //\r
@@ -1132,8 +1147,8 @@ HttpResponseWorker (
     // Hence, check that case before doing a NetMapRemoveHead.\r
     //\r
     if (!NetMapIsEmpty (&HttpInstance->TxTokens)) {\r
-      NetMapRemoveHead (&HttpInstance->TxTokens, (VOID**) &ValueInItem);\r
-      if (ValueInItem == NULL)  {\r
+      NetMapRemoveHead (&HttpInstance->TxTokens, (VOID **)&ValueInItem);\r
+      if (ValueInItem == NULL) {\r
         goto Error;\r
       }\r
 \r
@@ -1181,7 +1196,6 @@ HttpResponseWorker (
       FreePool (HttpHeaders);\r
       HttpHeaders = NULL;\r
 \r
-\r
       //\r
       // Init message-body parser by header information.\r
       //\r
@@ -1191,7 +1205,7 @@ HttpResponseWorker (
                  HttpMsg->HeaderCount,\r
                  HttpMsg->Headers,\r
                  HttpBodyParserCallback,\r
-                 (VOID *) ValueInItem,\r
+                 (VOID *)(&HttpInstance->CallbackData),\r
                  &HttpInstance->MsgParser\r
                  );\r
       if (EFI_ERROR (Status)) {\r
@@ -1202,18 +1216,28 @@ HttpResponseWorker (
       // 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
@@ -1257,7 +1281,7 @@ HttpResponseWorker (
         //\r
         CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, BodyLen);\r
         HttpInstance->CacheOffset = BodyLen + HttpInstance->CacheOffset;\r
-        HttpMsg->BodyLength = BodyLen;\r
+        HttpMsg->BodyLength       = BodyLen;\r
 \r
         if (HttpInstance->NextMsg == NULL) {\r
           //\r
@@ -1269,19 +1293,20 @@ HttpResponseWorker (
           HttpInstance->CacheOffset = 0;\r
         }\r
       }\r
+\r
       //\r
-      // Return since we aready received required data.\r
+      // Return since we already received required data.\r
       //\r
       Status = EFI_SUCCESS;\r
       goto Exit;\r
     }\r
 \r
-    if (BodyLen == 0 && HttpInstance->MsgParser == NULL) {\r
+    if ((BodyLen == 0) && (HttpInstance->MsgParser == NULL)) {\r
       //\r
       // We received a complete HTTP message, and we don't have more data to return to caller.\r
       //\r
       HttpMsg->BodyLength = 0;\r
-      Status = EFI_SUCCESS;\r
+      Status              = EFI_SUCCESS;\r
       goto Exit;\r
     }\r
   }\r
@@ -1297,7 +1322,6 @@ HttpResponseWorker (
     if (EFI_ERROR (Status)) {\r
       goto Error2;\r
     }\r
-\r
   } else {\r
     if (HttpInstance->TimeoutEvent == NULL) {\r
       //\r
@@ -1315,10 +1339,15 @@ HttpResponseWorker (
       }\r
     }\r
 \r
+    //\r
+    // Get HTTP timeout value\r
+    //\r
+    TimeoutValue = PcdGet32 (PcdHttpIoTimeout);\r
+\r
     //\r
     // Start the timer, and wait Timeout seconds to receive the body packet.\r
     //\r
-    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);\r
+    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS);\r
     if (EFI_ERROR (Status)) {\r
       goto Error2;\r
     }\r
@@ -1332,12 +1361,26 @@ HttpResponseWorker (
     }\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
@@ -1352,46 +1395,28 @@ HttpResponseWorker (
     }\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
-    } 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
+      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
@@ -1468,10 +1493,8 @@ Error:
   gBS->SignalEvent (Token->Event);\r
 \r
   return Status;\r
-\r
 }\r
 \r
-\r
 /**\r
   The Response() function queues an HTTP response to this HTTP instance, similar to\r
   Receive() function in the EFI TCP driver. When the HTTP response is received successfully,\r
@@ -1522,14 +1545,14 @@ Error:
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpResponse (\r
-  IN  EFI_HTTP_PROTOCOL         *This,\r
-  IN  EFI_HTTP_TOKEN            *Token\r
+  IN  EFI_HTTP_PROTOCOL  *This,\r
+  IN  EFI_HTTP_TOKEN     *Token\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_HTTP_MESSAGE              *HttpMsg;\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
-  HTTP_TOKEN_WRAP               *Wrap;\r
+  EFI_STATUS        Status;\r
+  EFI_HTTP_MESSAGE  *HttpMsg;\r
+  HTTP_PROTOCOL     *HttpInstance;\r
+  HTTP_TOKEN_WRAP   *Wrap;\r
 \r
   if ((This == NULL) || (Token == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1596,6 +1619,7 @@ Error:
     if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
       gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
     }\r
+\r
     FreePool (Wrap);\r
   }\r
 \r
@@ -1625,11 +1649,11 @@ Error:
 EFI_STATUS\r
 EFIAPI\r
 EfiHttpPoll (\r
-  IN  EFI_HTTP_PROTOCOL         *This\r
+  IN  EFI_HTTP_PROTOCOL  *This\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  HTTP_PROTOCOL                 *HttpInstance;\r
+  EFI_STATUS     Status;\r
+  HTTP_PROTOCOL  *HttpInstance;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1645,11 +1669,13 @@ EfiHttpPoll (
     if (HttpInstance->Tcp6 == NULL) {\r
       return EFI_NOT_STARTED;\r
     }\r
+\r
     Status = HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
   } else {\r
     if (HttpInstance->Tcp4 == NULL) {\r
       return EFI_NOT_STARTED;\r
     }\r
+\r
     Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
   }\r
 \r