]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpProto.c
MdePkg/SmmMemLib: Check for untested memory in GCD
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpProto.c
index 579b9e46627070e26ab1f990df973c36f573e4f8..94f89f5665846049c0aafbf471d18463d186d84e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Miscellaneous routines for HttpDxe driver.\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "HttpDriver.h"\r
 \r
 /**\r
-  The common notify function used in HTTP driver. \r
+  The common notify function used in HTTP driver.\r
 \r
   @param[in]  Event   The event signaled.\r
   @param[in]  Context The context.\r
@@ -54,10 +54,10 @@ HttpTcpTransmitNotifyDpc (
   if (Context == NULL) {\r
     return ;\r
   }\r
-  \r
+\r
   Wrap         = (HTTP_TOKEN_WRAP *) Context;\r
   HttpInstance = Wrap->HttpInstance;\r
-  \r
+\r
   if (!HttpInstance->LocalAddressIsIPv6) {\r
       Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;\r
       gBS->SignalEvent (Wrap->HttpToken->Event);\r
@@ -72,11 +72,11 @@ HttpTcpTransmitNotifyDpc (
       if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {\r
         gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
       }\r
-      \r
+\r
   } else {\r
     Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;\r
     gBS->SignalEvent (Wrap->HttpToken->Event);\r
-    \r
+\r
     //\r
     // Free resources.\r
     //\r
@@ -86,7 +86,7 @@ HttpTcpTransmitNotifyDpc (
 \r
     if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {\r
       gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);\r
-    }   \r
+    }\r
   }\r
 \r
 \r
@@ -145,24 +145,44 @@ HttpTcpReceiveNotifyDpc (
   Wrap = (HTTP_TOKEN_WRAP *) Context;\r
   HttpInstance = Wrap->HttpInstance;\r
   UsingIpv6    = HttpInstance->LocalAddressIsIPv6;\r
-  \r
+\r
   if (UsingIpv6) {\r
     gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
-    \r
+    Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;\r
+\r
     if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {\r
+      DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));\r
       Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
       gBS->SignalEvent (Wrap->HttpToken->Event);\r
+\r
+      Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
+      if (Item != NULL) {\r
+        NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
+      }\r
+\r
       FreePool (Wrap);\r
+      Wrap = NULL;\r
+\r
       return ;\r
     }\r
 \r
   } else {\r
     gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
-    \r
+    Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;\r
+\r
     if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {\r
+      DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));\r
       Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
       gBS->SignalEvent (Wrap->HttpToken->Event);\r
+\r
+      Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
+      if (Item != NULL) {\r
+        NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
+      }\r
+\r
       FreePool (Wrap);\r
+      Wrap = NULL;\r
+\r
       return ;\r
     }\r
   }\r
@@ -177,6 +197,16 @@ HttpTcpReceiveNotifyDpc (
     Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;\r
   }\r
 \r
+  //\r
+  // Record the CallbackData data.\r
+  //\r
+  HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+  HttpInstance->CallbackData.ParseData = Wrap->HttpToken->Message->Body;\r
+  HttpInstance->CallbackData.ParseDataLength = Length;\r
+\r
+  //\r
+  // Parse Body with CallbackData data.\r
+  //\r
   Status = HttpParseMessageBody (\r
              HttpInstance->MsgParser,\r
              Length,\r
@@ -200,7 +230,7 @@ HttpTcpReceiveNotifyDpc (
   // We receive part of header of next HTTP msg.\r
   //\r
   if (HttpInstance->NextMsg != NULL) {\r
-    Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg - \r
+    Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg -\r
                                            (CHAR8 *) Wrap->HttpToken->Message->Body;\r
     HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength;\r
     if (HttpInstance->CacheLen != 0) {\r
@@ -226,7 +256,7 @@ HttpTcpReceiveNotifyDpc (
   } else {\r
     Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
   }\r
-  \r
+\r
 \r
   gBS->SignalEvent (Wrap->HttpToken->Event);\r
 \r
@@ -234,8 +264,9 @@ HttpTcpReceiveNotifyDpc (
   // Check pending RxTokens and receive the HTTP message.\r
   //\r
   NetMapIterate (&Wrap->HttpInstance->RxTokens, HttpTcpReceive, NULL);\r
-  \r
+\r
   FreePool (Wrap);\r
+  Wrap = NULL;\r
 }\r
 \r
 /**\r
@@ -302,7 +333,7 @@ HttpCreateTcpConnCloseEvent (
     if (EFI_ERROR (Status)) {\r
       goto ERROR;\r
     }\r
-    \r
+\r
   } else {\r
     //\r
     // Create events for variuos asynchronous operations.\r
@@ -332,7 +363,7 @@ HttpCreateTcpConnCloseEvent (
       goto ERROR;\r
     }\r
   }\r
-     \r
+\r
   return EFI_SUCCESS;\r
 \r
 ERROR:\r
@@ -380,7 +411,7 @@ HttpCloseTcpConnCloseEvent (
       HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;\r
     }\r
   }\r
-  \r
+\r
 }\r
 \r
 /**\r
@@ -412,15 +443,15 @@ HttpCreateTcpTxEvent (
                     Wrap,\r
                     &TcpWrap->Tx4Token.CompletionToken.Event\r
                     );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-    \r
-      TcpWrap->Tx4Data.Push = TRUE;\r
-      TcpWrap->Tx4Data.Urgent = FALSE;\r
-      TcpWrap->Tx4Data.FragmentCount = 1;\r
-      TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;\r
-      TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    TcpWrap->Tx4Data.Push = TRUE;\r
+    TcpWrap->Tx4Data.Urgent = FALSE;\r
+    TcpWrap->Tx4Data.FragmentCount = 1;\r
+    TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;\r
+    TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;\r
 \r
   } else {\r
     Status = gBS->CreateEvent (\r
@@ -439,10 +470,9 @@ HttpCreateTcpTxEvent (
     TcpWrap->Tx6Data.FragmentCount  = 1;\r
     TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
     TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
-    \r
-    \r
+\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -473,7 +503,7 @@ HttpCreateTcpRxEventForHeader (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-    \r
+\r
     HttpInstance->Rx4Data.FragmentCount = 1;\r
     HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data;\r
     HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
@@ -493,7 +523,7 @@ HttpCreateTcpRxEventForHeader (
     HttpInstance->Rx6Data.FragmentCount  =1;\r
     HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data;\r
     HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
-    \r
+\r
   }\r
 \r
 \r
@@ -511,7 +541,7 @@ HttpCreateTcpRxEventForHeader (
 **/\r
 EFI_STATUS\r
 HttpCreateTcpRxEvent (\r
-  IN  HTTP_TOKEN_WRAP      *Wrap \r
+  IN  HTTP_TOKEN_WRAP      *Wrap\r
   )\r
 {\r
   EFI_STATUS               Status;\r
@@ -531,7 +561,7 @@ HttpCreateTcpRxEvent (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-    \r
+\r
     TcpWrap->Rx4Data.FragmentCount = 1;\r
     TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data;\r
     TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
@@ -543,7 +573,7 @@ HttpCreateTcpRxEvent (
                     HttpTcpReceiveNotify,\r
                     Wrap,\r
                     &TcpWrap->Rx6Token.CompletionToken.Event\r
-                    );  \r
+                    );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -552,7 +582,7 @@ HttpCreateTcpRxEvent (
     TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data;\r
     TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -560,7 +590,7 @@ HttpCreateTcpRxEvent (
   Close Events for Tcp Receive Tokens for HTTP body and HTTP header.\r
 \r
   @param[in]  Wrap               Pointer to HTTP token's wrap data.\r
-  \r
+\r
 **/\r
 VOID\r
 HttpCloseTcpRxEvent (\r
@@ -571,7 +601,7 @@ HttpCloseTcpRxEvent (
 \r
   ASSERT (Wrap != NULL);\r
   HttpInstance   = Wrap->HttpInstance;\r
-  \r
+\r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
       gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
@@ -585,7 +615,7 @@ HttpCloseTcpRxEvent (
     if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
       gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
     }\r
-    \r
+\r
     if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
       gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
       HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
@@ -599,7 +629,7 @@ HttpCloseTcpRxEvent (
   @param[in, out]  HttpInstance         Pointer to HTTP_PROTOCOL structure.\r
   @param[in]       IpVersion            Indicate us TCP4 protocol or TCP6 protocol.\r
 \r
-  @retval EFI_SUCCESS       HTTP_PROTOCOL structure is initialized successfully.                                          \r
+  @retval EFI_SUCCESS       HTTP_PROTOCOL structure is initialized successfully.\r
   @retval Others            Other error as indicated.\r
 \r
 **/\r
@@ -612,17 +642,17 @@ HttpInitProtocol (
   EFI_STATUS                     Status;\r
   VOID                           *Interface;\r
   BOOLEAN                        UsingIpv6;\r
-  \r
+\r
   ASSERT (HttpInstance != NULL);\r
   UsingIpv6 = IpVersion;\r
-  \r
+\r
   if (!UsingIpv6) {\r
     //\r
     // Create TCP4 child.\r
     //\r
     Status = NetLibCreateServiceChild (\r
                HttpInstance->Service->ControllerHandle,\r
-               HttpInstance->Service->ImageHandle,\r
+               HttpInstance->Service->Ip4DriverBindingHandle,\r
                &gEfiTcp4ServiceBindingProtocolGuid,\r
                &HttpInstance->Tcp4ChildHandle\r
                );\r
@@ -635,11 +665,11 @@ HttpInitProtocol (
                     HttpInstance->Tcp4ChildHandle,\r
                     &gEfiTcp4ProtocolGuid,\r
                     (VOID **) &Interface,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip4DriverBindingHandle,\r
                     HttpInstance->Service->ControllerHandle,\r
                     EFI_OPEN_PROTOCOL_BY_DRIVER\r
                     );\r
-                    \r
+\r
     if (EFI_ERROR (Status)) {\r
       goto ON_ERROR;\r
     }\r
@@ -648,7 +678,7 @@ HttpInitProtocol (
                     HttpInstance->Tcp4ChildHandle,\r
                     &gEfiTcp4ProtocolGuid,\r
                     (VOID **) &HttpInstance->Tcp4,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip4DriverBindingHandle,\r
                     HttpInstance->Handle,\r
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
@@ -660,7 +690,7 @@ HttpInitProtocol (
                     HttpInstance->Service->Tcp4ChildHandle,\r
                     &gEfiTcp4ProtocolGuid,\r
                     (VOID **) &Interface,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip4DriverBindingHandle,\r
                     HttpInstance->Handle,\r
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
@@ -673,7 +703,7 @@ HttpInitProtocol (
     //\r
     Status = NetLibCreateServiceChild (\r
                HttpInstance->Service->ControllerHandle,\r
-               HttpInstance->Service->ImageHandle,\r
+               HttpInstance->Service->Ip6DriverBindingHandle,\r
                &gEfiTcp6ServiceBindingProtocolGuid,\r
                &HttpInstance->Tcp6ChildHandle\r
                );\r
@@ -686,11 +716,11 @@ HttpInitProtocol (
                     HttpInstance->Tcp6ChildHandle,\r
                     &gEfiTcp6ProtocolGuid,\r
                     (VOID **) &Interface,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip6DriverBindingHandle,\r
                     HttpInstance->Service->ControllerHandle,\r
                     EFI_OPEN_PROTOCOL_BY_DRIVER\r
                     );\r
-    \r
+\r
     if (EFI_ERROR (Status)) {\r
       goto ON_ERROR;\r
     }\r
@@ -699,20 +729,20 @@ HttpInitProtocol (
                     HttpInstance->Tcp6ChildHandle,\r
                     &gEfiTcp6ProtocolGuid,\r
                     (VOID **) &HttpInstance->Tcp6,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip6DriverBindingHandle,\r
                     HttpInstance->Handle,\r
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
-    \r
+\r
     if (EFI_ERROR(Status)) {\r
       goto ON_ERROR;\r
-    }      \r
+    }\r
 \r
     Status = gBS->OpenProtocol (\r
                     HttpInstance->Service->Tcp6ChildHandle,\r
                     &gEfiTcp6ProtocolGuid,\r
                     (VOID **) &Interface,\r
-                    HttpInstance->Service->ImageHandle,\r
+                    HttpInstance->Service->Ip6DriverBindingHandle,\r
                     HttpInstance->Handle,\r
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
@@ -721,7 +751,7 @@ HttpInitProtocol (
       goto ON_ERROR;\r
     }\r
   }\r
-  \r
+\r
   HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);\r
   if (HttpInstance->Url == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
@@ -731,73 +761,73 @@ HttpInitProtocol (
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
-  \r
+\r
   if (HttpInstance->Tcp4ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Service->ControllerHandle\r
            );\r
 \r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
-           );    \r
-    \r
+           );\r
+\r
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip4DriverBindingHandle,\r
       &gEfiTcp4ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp4ChildHandle\r
       );\r
   }\r
-  \r
+\r
   if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }\r
-  \r
+\r
   if (HttpInstance->Tcp6ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Service->ControllerHandle\r
            );\r
 \r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
-    \r
+\r
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip6DriverBindingHandle,\r
       &gEfiTcp6ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp6ChildHandle\r
       );\r
   }\r
-  \r
+\r
   if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }\r
 \r
   return EFI_UNSUPPORTED;\r
-  \r
+\r
 }\r
 \r
 /**\r
@@ -812,9 +842,14 @@ HttpCleanProtocol (
   )\r
 {\r
   HttpCloseConnection (HttpInstance);\r
-  \r
+\r
   HttpCloseTcpConnCloseEvent (HttpInstance);\r
 \r
+  if (HttpInstance->TimeoutEvent != NULL) {\r
+    gBS->CloseEvent (HttpInstance->TimeoutEvent);\r
+    HttpInstance->TimeoutEvent = NULL;\r
+  }\r
+\r
   if (HttpInstance->CacheBody != NULL) {\r
     FreePool (HttpInstance->CacheBody);\r
     HttpInstance->CacheBody = NULL;\r
@@ -830,33 +865,40 @@ HttpCleanProtocol (
     HttpFreeMsgParser (HttpInstance->MsgParser);\r
     HttpInstance->MsgParser = NULL;\r
   }\r
-  \r
+\r
   if (HttpInstance->Url != NULL) {\r
     FreePool (HttpInstance->Url);\r
     HttpInstance->Url = NULL;\r
   }\r
-  \r
+\r
   NetMapClean (&HttpInstance->TxTokens);\r
   NetMapClean (&HttpInstance->RxTokens);\r
 \r
+  if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) {\r
+    //\r
+    // Destroy the TLS instance.\r
+    //\r
+    HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
+  }\r
+\r
   if (HttpInstance->Tcp4ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Service->ControllerHandle\r
            );\r
 \r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
-    \r
+\r
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip4DriverBindingHandle,\r
       &gEfiTcp4ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp4ChildHandle\r
       );\r
@@ -866,43 +908,44 @@ HttpCleanProtocol (
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
-  }  \r
+  }\r
 \r
   if (HttpInstance->Tcp6ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Service->ControllerHandle\r
            );\r
 \r
     gBS->CloseProtocol (\r
            HttpInstance->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
-    \r
+\r
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip6DriverBindingHandle,\r
       &gEfiTcp6ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp6ChildHandle\r
       );\r
   }\r
-  \r
+\r
   if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }\r
-  \r
+\r
+  TlsCloseTxRxEvent (HttpInstance);\r
 }\r
 \r
 /**\r
@@ -932,13 +975,13 @@ HttpCreateConnection (
       DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));\r
       return Status;\r
     }\r
-    \r
+\r
     while (!HttpInstance->IsTcp4ConnDone) {\r
       HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
     }\r
-    \r
+\r
     Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;\r
-    \r
+\r
   } else {\r
     HttpInstance->IsTcp6ConnDone = FALSE;\r
     HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
@@ -952,9 +995,9 @@ HttpCreateConnection (
       HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
     }\r
 \r
-    Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;   \r
+    Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;\r
   }\r
-  \r
+\r
   if (!EFI_ERROR (Status)) {\r
     HttpInstance->State = HTTP_STATE_TCP_CONNECTED;\r
   }\r
@@ -991,7 +1034,7 @@ HttpCloseConnection (
       while (!HttpInstance->IsTcp6CloseDone) {\r
         HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
       }\r
-      \r
+\r
     } else {\r
       HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;\r
       HttpInstance->IsTcp4CloseDone             = FALSE;\r
@@ -1037,7 +1080,7 @@ HttpConfigureTcp4 (
 \r
   Tcp4CfgData = &HttpInstance->Tcp4CfgData;\r
   ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));\r
-  \r
+\r
   Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT;\r
   Tcp4CfgData->TimeToLive    = HTTP_TTL_DEAULT;\r
   Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option;\r
@@ -1048,7 +1091,7 @@ HttpConfigureTcp4 (
     IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress);\r
     IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);\r
   }\r
-  \r
+\r
   Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort;\r
   Tcp4AP->RemotePort  = HttpInstance->RemotePort;\r
   Tcp4AP->ActiveFlag  = TRUE;\r
@@ -1108,16 +1151,16 @@ HttpConfigureTcp6 (
   EFI_TCP6_CONFIG_DATA     *Tcp6CfgData;\r
   EFI_TCP6_ACCESS_POINT    *Tcp6Ap;\r
   EFI_TCP6_OPTION          *Tcp6Option;\r
-  \r
+\r
   ASSERT (HttpInstance != NULL);\r
-  \r
+\r
   Tcp6CfgData = &HttpInstance->Tcp6CfgData;\r
   ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA));\r
 \r
   Tcp6CfgData->TrafficClass  = 0;\r
   Tcp6CfgData->HopLimit      = 255;\r
   Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option;\r
-  \r
+\r
   Tcp6Ap  = &Tcp6CfgData->AccessPoint;\r
   Tcp6Ap->ActiveFlag  = TRUE;\r
   Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;\r
@@ -1142,7 +1185,7 @@ HttpConfigureTcp6 (
     DEBUG ((EFI_D_ERROR, "HttpConfigureTcp6 - %r\n", Status));\r
     return Status;\r
   }\r
-  \r
+\r
   Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -1156,11 +1199,12 @@ HttpConfigureTcp6 (
   HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
 \r
   return EFI_SUCCESS;\r
\r
+\r
 }\r
 \r
 /**\r
-  Check existing TCP connection, if in error state, recover TCP4 connection.\r
+  Check existing TCP connection, if in error state, recover TCP4 connection. Then,\r
+  connect one TLS session if required.\r
 \r
   @param[in]  HttpInstance       The HTTP instance private data.\r
 \r
@@ -1183,8 +1227,8 @@ HttpConnectTcp4 (
   }\r
 \r
   Status = HttpInstance->Tcp4->GetModeData(\r
-                                 HttpInstance->Tcp4, \r
-                                 &Tcp4State, \r
+                                 HttpInstance->Tcp4,\r
+                                 &Tcp4State,\r
                                  NULL,\r
                                  NULL,\r
                                  NULL,\r
@@ -1201,11 +1245,58 @@ HttpConnectTcp4 (
     HttpCloseConnection(HttpInstance);\r
   }\r
 \r
-  return HttpCreateConnection (HttpInstance);\r
+  Status = HttpCreateConnection (HttpInstance);\r
+  if (EFI_ERROR(Status)){\r
+    DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Tls session connection.\r
+  //\r
+  if (HttpInstance->UseHttps) {\r
+    if (HttpInstance->TimeoutEvent == NULL) {\r
+      //\r
+      // Create TimeoutEvent for TLS connection.\r
+      //\r
+      Status = gBS->CreateEvent (\r
+                      EVT_TIMER,\r
+                      TPL_CALLBACK,\r
+                      NULL,\r
+                      NULL,\r
+                      &HttpInstance->TimeoutEvent\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        TlsCloseTxRxEvent (HttpInstance);\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Start the timer, and wait Timeout seconds for connection.\r
+    //\r
+    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);\r
+    if (EFI_ERROR (Status)) {\r
+      TlsCloseTxRxEvent (HttpInstance);\r
+      return Status;\r
+    }\r
+\r
+    Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
+\r
+    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      TlsCloseTxRxEvent (HttpInstance);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
-  Check existing TCP connection, if in error state, recover TCP6 connection.\r
+  Check existing TCP connection, if in error state, recover TCP6 connection. Then,\r
+  connect one TLS session if required.\r
 \r
   @param[in]  HttpInstance       The HTTP instance private data.\r
 \r
@@ -1234,7 +1325,7 @@ HttpConnectTcp6 (
                                  NULL,\r
                                  NULL\r
                                  );\r
-  \r
+\r
   if (EFI_ERROR(Status)){\r
      DEBUG ((EFI_D_ERROR, "Tcp6 GetModeData fail - %x\n", Status));\r
      return Status;\r
@@ -1246,30 +1337,88 @@ HttpConnectTcp6 (
     HttpCloseConnection(HttpInstance);\r
   }\r
 \r
-  return HttpCreateConnection (HttpInstance);\r
+  Status = HttpCreateConnection (HttpInstance);\r
+  if (EFI_ERROR(Status)){\r
+    DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Tls session connection.\r
+  //\r
+  if (HttpInstance->UseHttps) {\r
+    if (HttpInstance->TimeoutEvent == NULL) {\r
+      //\r
+      // Create TimeoutEvent for TLS connection.\r
+      //\r
+      Status = gBS->CreateEvent (\r
+                      EVT_TIMER,\r
+                      TPL_CALLBACK,\r
+                      NULL,\r
+                      NULL,\r
+                      &HttpInstance->TimeoutEvent\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        TlsCloseTxRxEvent (HttpInstance);\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Start the timer, and wait Timeout seconds for connection.\r
+    //\r
+    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);\r
+    if (EFI_ERROR (Status)) {\r
+      TlsCloseTxRxEvent (HttpInstance);\r
+      return Status;\r
+    }\r
+\r
+    Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
+\r
+    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      TlsCloseTxRxEvent (HttpInstance);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
-  Initialize TCP related data.\r
+  Initialize Http session.\r
 \r
   @param[in]  HttpInstance       The HTTP instance private data.\r
   @param[in]  Wrap               The HTTP token's wrap data.\r
-  @param[in]  Configure          The Flag indicates whether the first time to initialize Tcp.\r
+  @param[in]  Configure          The Flag indicates whether need to initialize session.\r
+  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls session.\r
 \r
-  @retval EFI_SUCCESS            The initialization of TCP instance is done. \r
+  @retval EFI_SUCCESS            The initialization of session is done.\r
   @retval Others                 Other error as indicated.\r
 \r
 **/\r
 EFI_STATUS\r
-HttpInitTcp (\r
+HttpInitSession (\r
   IN  HTTP_PROTOCOL    *HttpInstance,\r
   IN  HTTP_TOKEN_WRAP  *Wrap,\r
-  IN  BOOLEAN          Configure\r
+  IN  BOOLEAN          Configure,\r
+  IN  BOOLEAN          TlsConfigure\r
   )\r
 {\r
   EFI_STATUS           Status;\r
   ASSERT (HttpInstance != NULL);\r
 \r
+  //\r
+  // Configure Tls session.\r
+  //\r
+  if (TlsConfigure) {\r
+    Status = TlsConfigureSession (HttpInstance);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
   if (!HttpInstance->LocalAddressIsIPv6) {\r
     //\r
     // Configure TCP instance.\r
@@ -1307,13 +1456,13 @@ HttpInitTcp (
       return Status;\r
     }\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
-  \r
+\r
 }\r
 \r
 /**\r
-  Send the HTTP message through TCP4 or TCP6.\r
+  Send the HTTP or HTTPS message through TCP4 or TCP6.\r
 \r
   @param[in]  HttpInstance       The HTTP instance private data.\r
   @param[in]  Wrap               The HTTP token's wrap data.\r
@@ -1337,143 +1486,153 @@ HttpTransmitTcp (
   EFI_TCP4_PROTOCOL             *Tcp4;\r
   EFI_TCP6_IO_TOKEN             *Tx6Token;\r
   EFI_TCP6_PROTOCOL             *Tcp6;\r
-  \r
-  if (!HttpInstance->LocalAddressIsIPv6) {     \r
+  UINT8                         *TlsRecord;\r
+  UINT16                        PayloadSize;\r
+  NET_FRAGMENT                  TempFragment;\r
+  NET_FRAGMENT                  Fragment;\r
+  UINTN                         RecordCount;\r
+  UINTN                         RemainingLen;\r
+\r
+  Status                = EFI_SUCCESS;\r
+  TlsRecord             = NULL;\r
+  PayloadSize           = 0;\r
+  TempFragment.Len      = 0;\r
+  TempFragment.Bulk     = NULL;\r
+  Fragment.Len          = 0;\r
+  Fragment.Bulk         = NULL;\r
+  RecordCount           = 0;\r
+  RemainingLen          = 0;\r
+\r
+  //\r
+  // Need to encrypt data.\r
+  //\r
+  if (HttpInstance->UseHttps) {\r
+    //\r
+    // Allocate enough buffer for each TLS plaintext records.\r
+    //\r
+    TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
+    if (TlsRecord == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Allocate enough buffer for all TLS ciphertext records.\r
+    //\r
+    RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1;\r
+    Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));\r
+    if (Fragment.Bulk == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    //\r
+    // Encrypt each TLS plaintext records.\r
+    //\r
+    RemainingLen = TxStringLen;\r
+    while (RemainingLen != 0) {\r
+      PayloadSize = (UINT16) MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen);\r
+\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->ContentType = TlsContentTypeApplicationData;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
+      ((TLS_RECORD_HEADER *) TlsRecord)->Length = PayloadSize;\r
+\r
+      CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize);\r
+\r
+      Status = TlsProcessMessage (\r
+                 HttpInstance,\r
+                 TlsRecord,\r
+                 TLS_RECORD_HEADER_LENGTH + PayloadSize,\r
+                 EfiTlsEncrypt,\r
+                 &TempFragment\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_ERROR;\r
+      }\r
+\r
+      //\r
+      // Record the processed/encrypted Packet.\r
+      //\r
+      CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len);\r
+      Fragment.Len += TempFragment.Len;\r
+\r
+      FreePool (TempFragment.Bulk);\r
+      TempFragment.Len  = 0;\r
+      TempFragment.Bulk = NULL;\r
+\r
+      RemainingLen -= (UINTN) PayloadSize;\r
+      ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
+    }\r
+\r
+    FreePool (TlsRecord);\r
+    TlsRecord = NULL;\r
+  }\r
+\r
+  if (!HttpInstance->LocalAddressIsIPv6) {\r
     Tcp4 = HttpInstance->Tcp4;\r
     Tx4Token = &Wrap->TcpWrap.Tx4Token;\r
-    \r
-    Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
-    Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
-    Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
-    Tx4Token->CompletionToken.Status = EFI_NOT_READY;  \r
-    \r
+\r
+    if (HttpInstance->UseHttps) {\r
+      Tx4Token->Packet.TxData->DataLength = Fragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
+    } else {\r
+      Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
+    }\r
+\r
+    Tx4Token->CompletionToken.Status = EFI_NOT_READY;\r
+\r
     Wrap->TcpWrap.IsTxDone = FALSE;\r
     Status  = Tcp4->Transmit (Tcp4, Tx4Token);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
-      return Status;\r
+      goto ON_ERROR;\r
     }\r
 \r
   } else {\r
     Tcp6 = HttpInstance->Tcp6;\r
     Tx6Token = &Wrap->TcpWrap.Tx6Token;\r
 \r
-    Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
-    Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
-    Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
+    if (HttpInstance->UseHttps) {\r
+      Tx6Token->Packet.TxData->DataLength = Fragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
+    } else {\r
+      Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
+    }\r
+\r
     Tx6Token->CompletionToken.Status = EFI_NOT_READY;\r
 \r
     Wrap->TcpWrap.IsTxDone = FALSE;\r
     Status = Tcp6->Transmit (Tcp6, Tx6Token);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
-      return Status;\r
+      goto ON_ERROR;\r
     }\r
   }\r
-  \r
 \r
   return Status;\r
-}\r
 \r
-/**\r
-  Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined \r
-  in UEFI 2.5 specification.\r
-\r
-  @param[in]  StatusCode         The status code value in HTTP message.\r
+ON_ERROR:\r
 \r
-  @return                        Value defined in EFI_HTTP_STATUS_CODE .\r
+  if (HttpInstance->UseHttps) {\r
+    if (TlsRecord != NULL) {\r
+      FreePool (TlsRecord);\r
+      TlsRecord = NULL;\r
+    }\r
 \r
-**/\r
-EFI_HTTP_STATUS_CODE\r
-HttpMappingToStatusCode (\r
-  IN UINTN                  StatusCode\r
-  )  \r
-{\r
-  switch (StatusCode) {\r
-  case 100:\r
-    return HTTP_STATUS_100_CONTINUE;\r
-  case 101:\r
-    return HTTP_STATUS_101_SWITCHING_PROTOCOLS;\r
-  case 200:\r
-    return HTTP_STATUS_200_OK;\r
-  case 201:\r
-    return HTTP_STATUS_201_CREATED;\r
-  case 202:\r
-    return HTTP_STATUS_202_ACCEPTED;\r
-  case 203:\r
-    return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION;\r
-  case 204:\r
-    return HTTP_STATUS_204_NO_CONTENT;\r
-  case 205:\r
-    return HTTP_STATUS_205_RESET_CONTENT;\r
-  case 206:\r
-    return HTTP_STATUS_206_PARTIAL_CONTENT;\r
-  case 300:\r
-    return HTTP_STATUS_300_MULTIPLE_CHIOCES;\r
-  case 301:\r
-    return HTTP_STATUS_301_MOVED_PERMANENTLY;\r
-  case 302:\r
-    return HTTP_STATUS_302_FOUND;\r
-  case 303:\r
-    return HTTP_STATUS_303_SEE_OTHER;\r
-  case 304:\r
-    return HTTP_STATUS_304_NOT_MODIFIED;\r
-  case 305:\r
-    return HTTP_STATUS_305_USE_PROXY;\r
-  case 307:\r
-    return HTTP_STATUS_307_TEMPORARY_REDIRECT;\r
-  case 400:\r
-    return HTTP_STATUS_400_BAD_REQUEST;\r
-  case 401:\r
-    return HTTP_STATUS_401_UNAUTHORIZED;\r
-  case 402:\r
-    return HTTP_STATUS_402_PAYMENT_REQUIRED;\r
-  case 403:\r
-    return HTTP_STATUS_403_FORBIDDEN;\r
-  case 404:\r
-    return HTTP_STATUS_404_NOT_FOUND;\r
-  case 405:\r
-    return HTTP_STATUS_405_METHOD_NOT_ALLOWED;\r
-  case 406:\r
-    return HTTP_STATUS_406_NOT_ACCEPTABLE;\r
-  case 407:\r
-    return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED;\r
-  case 408:\r
-    return HTTP_STATUS_408_REQUEST_TIME_OUT;\r
-  case 409:\r
-    return HTTP_STATUS_409_CONFLICT;\r
-  case 410:\r
-    return HTTP_STATUS_410_GONE;\r
-  case 411:\r
-    return HTTP_STATUS_411_LENGTH_REQUIRED;\r
-  case 412:\r
-    return HTTP_STATUS_412_PRECONDITION_FAILED;\r
-  case 413:\r
-    return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE;\r
-  case 414:\r
-    return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE;\r
-  case 415:\r
-    return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE;\r
-  case 416:\r
-    return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;\r
-  case 417:\r
-    return HTTP_STATUS_417_EXPECTATION_FAILED;\r
-  case 500:\r
-    return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;\r
-  case 501:\r
-    return HTTP_STATUS_501_NOT_IMPLEMENTED;\r
-  case 502:\r
-    return HTTP_STATUS_502_BAD_GATEWAY;\r
-  case 503:\r
-    return HTTP_STATUS_503_SERVICE_UNAVAILABLE;\r
-  case 504:\r
-    return HTTP_STATUS_504_GATEWAY_TIME_OUT;\r
-  case 505:\r
-    return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED;\r
-\r
-  default:\r
-    return HTTP_STATUS_UNSUPPORTED_STATUS;\r
+    if (Fragment.Bulk != NULL) {\r
+      FreePool (Fragment.Bulk);\r
+      Fragment.Bulk = NULL;\r
+    }\r
   }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -1537,12 +1696,12 @@ HttpTcpNotReady (
   if (!ValueInItem->TcpWrap.IsTxDone) {\r
     return EFI_NOT_READY;\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Transmit the HTTP mssage by processing the associated HTTP token.\r
+  Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.\r
 \r
   @param[in]  Map                The container of Tx4Token or Tx6Token.\r
   @param[in]  Item               Current item to check against.\r
@@ -1563,8 +1722,12 @@ HttpTcpTransmit (
 {\r
   HTTP_TOKEN_WRAP           *ValueInItem;\r
   EFI_STATUS                Status;\r
-  CHAR8                     *RequestStr;\r
+  CHAR8                     *RequestMsg;\r
   CHAR8                     *Url;\r
+  UINTN                     UrlSize;\r
+  UINTN                     RequestMsgSize;\r
+\r
+  RequestMsg = NULL;\r
 \r
   ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value;\r
   if (ValueInItem->TcpWrap.IsTxDone) {\r
@@ -1574,36 +1737,41 @@ HttpTcpTransmit (
   //\r
   // Parse the URI of the remote host.\r
   //\r
-  Url = AllocatePool (StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1);\r
+  UrlSize = StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1;\r
+  Url = AllocatePool (UrlSize);\r
   if (Url == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  UnicodeStrToAsciiStr (ValueInItem->HttpToken->Message->Data.Request->Url, Url);\r
+  UnicodeStrToAsciiStrS (ValueInItem->HttpToken->Message->Data.Request->Url, Url, UrlSize);\r
 \r
   //\r
   // Create request message.\r
   //\r
-  RequestStr = HttpGenRequestString (\r
-                 ValueInItem->HttpInstance,\r
+  Status = HttpGenRequestMessage (\r
                  ValueInItem->HttpToken->Message,\r
-                 Url\r
+                 Url,\r
+                 &RequestMsg,\r
+                 &RequestMsgSize\r
                  );\r
   FreePool (Url);\r
-  if (RequestStr == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+\r
+  if (EFI_ERROR (Status) || NULL == RequestMsg){\r
+    return Status;\r
   }\r
 \r
+  ASSERT (RequestMsg != NULL);\r
+\r
   //\r
   // Transmit the request message.\r
   //\r
   Status = HttpTransmitTcp (\r
              ValueInItem->HttpInstance,\r
              ValueInItem,\r
-             (UINT8*) RequestStr,\r
-             AsciiStrLen (RequestStr)\r
+             (UINT8*) RequestMsg,\r
+             RequestMsgSize\r
              );\r
-  FreePool (RequestStr);\r
+  FreePool (RequestMsg);\r
   return Status;\r
 }\r
 \r
@@ -1639,8 +1807,9 @@ HttpTcpReceive (
   @param[in]       HttpInstance     The HTTP instance private data.\r
   @param[in, out]  SizeofHeaders    The HTTP header length.\r
   @param[in, out]  BufferSize       The size of buffer to cacahe the header message.\r
-  \r
-  @retval EFI_SUCCESS               The HTTP header is received.                          \r
+  @param[in]       Timeout          The time to wait for receiving the header packet.\r
+\r
+  @retval EFI_SUCCESS               The HTTP header is received.\r
   @retval Others                    Other errors as indicated.\r
 \r
 **/\r
@@ -1648,7 +1817,8 @@ EFI_STATUS
 HttpTcpReceiveHeader (\r
   IN  HTTP_PROTOCOL         *HttpInstance,\r
   IN  OUT UINTN             *SizeofHeaders,\r
-  IN  OUT UINTN             *BufferSize\r
+  IN  OUT UINTN             *BufferSize,\r
+  IN  EFI_EVENT             Timeout\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
@@ -1659,6 +1829,7 @@ HttpTcpReceiveHeader (
   CHAR8                         **EndofHeader;\r
   CHAR8                         **HttpHeaders;\r
   CHAR8                         *Buffer;\r
+  NET_FRAGMENT                  Fragment;\r
 \r
   ASSERT (HttpInstance != NULL);\r
 \r
@@ -1669,141 +1840,228 @@ HttpTcpReceiveHeader (
   Buffer      = NULL;\r
   Rx4Token    = NULL;\r
   Rx6Token    = NULL;\r
-  \r
+  Fragment.Len  = 0;\r
+  Fragment.Bulk = NULL;\r
+\r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     ASSERT (Tcp6 != NULL);\r
   } else {\r
     ASSERT (Tcp4 != NULL);\r
   }\r
 \r
-  if (!HttpInstance->LocalAddressIsIPv6) {\r
-    Rx4Token = &HttpInstance->Rx4Token;\r
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
-    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
+  if (!HttpInstance->UseHttps) {\r
+    Status = HttpCreateTcpRxEventForHeader (HttpInstance);\r
+    if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-  \r
+  }\r
+\r
+  if (!HttpInstance->LocalAddressIsIPv6) {\r
+    if (!HttpInstance->UseHttps) {\r
+      Rx4Token = &HttpInstance->Rx4Token;\r
+      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
+      if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        return Status;\r
+      }\r
+    }\r
+\r
     //\r
     // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
     //\r
-    while (*EndofHeader == NULL) {   \r
-      HttpInstance->IsRxDone = FALSE;\r
-      Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
-      Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
-      Status = Tcp4->Receive (Tcp4, Rx4Token);\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
-        return Status;\r
-      }\r
-      \r
-      while (!HttpInstance->IsRxDone) {\r
-       Tcp4->Poll (Tcp4);\r
-      }    \r
-  \r
-      Status = Rx4Token->CompletionToken.Status;\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
+    while (*EndofHeader == NULL) {\r
+      if (!HttpInstance->UseHttps) {\r
+        HttpInstance->IsRxDone = FALSE;\r
+        Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
+        Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
+        Status = Tcp4->Receive (Tcp4, Rx4Token);\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
+          return Status;\r
+        }\r
+\r
+        while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+          Tcp4->Poll (Tcp4);\r
+        }\r
+\r
+        if (!HttpInstance->IsRxDone) {\r
+          //\r
+          // Cancle the Token before close its Event.\r
+          //\r
+          Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);\r
+          gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+          Rx4Token->CompletionToken.Status = EFI_TIMEOUT;\r
+        }\r
+\r
+        Status = Rx4Token->CompletionToken.Status;\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        Fragment.Len  = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
+        Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
+      } else {\r
+        if (Fragment.Bulk != NULL) {\r
+          FreePool (Fragment.Bulk);\r
+          Fragment.Bulk = NULL;\r
+        }\r
+\r
+        Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
+          return Status;\r
+        }\r
       }\r
-  \r
+\r
       //\r
       // Append the response string.\r
       //\r
-      *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
+      *BufferSize = *SizeofHeaders + Fragment.Len;\r
       Buffer      = AllocateZeroPool (*BufferSize);\r
       if (Buffer == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         return Status;\r
       }\r
-  \r
+\r
       if (*HttpHeaders != NULL) {\r
-        CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));\r
+        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
         FreePool (*HttpHeaders);\r
       }\r
-  \r
+\r
       CopyMem (\r
-        Buffer + (*SizeofHeaders),\r
-        Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,\r
-        Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength\r
+        Buffer + *SizeofHeaders,\r
+        Fragment.Bulk,\r
+        Fragment.Len\r
         );\r
-      *HttpHeaders    = Buffer;\r
-      *SizeofHeaders  = *BufferSize;\r
-  \r
+      *HttpHeaders   = Buffer;\r
+      *SizeofHeaders = *BufferSize;\r
+\r
       //\r
       // Check whether we received end of HTTP headers.\r
       //\r
-      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); \r
+      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);\r
+    };\r
+\r
+    //\r
+    // Free the buffer.\r
+    //\r
+    if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
+      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
+      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+      Fragment.Bulk = NULL;\r
+    }\r
+\r
+    if (Fragment.Bulk != NULL) {\r
+      FreePool (Fragment.Bulk);\r
+      Fragment.Bulk = NULL;\r
     }\r
-    FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
-    \r
   } else {\r
-    Rx6Token = &HttpInstance->Rx6Token;\r
-    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
-    if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      return Status;\r
+    if (!HttpInstance->UseHttps) {\r
+      Rx6Token = &HttpInstance->Rx6Token;\r
+      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);\r
+      if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        return Status;\r
+      }\r
     }\r
-  \r
+\r
     //\r
     // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
     //\r
-    while (*EndofHeader == NULL) {   \r
-      HttpInstance->IsRxDone = FALSE;\r
-      Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
-      Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
-      Status = Tcp6->Receive (Tcp6, Rx6Token);\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
-        return Status;\r
+    while (*EndofHeader == NULL) {\r
+      if (!HttpInstance->UseHttps) {\r
+        HttpInstance->IsRxDone = FALSE;\r
+        Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;\r
+        Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;\r
+        Status = Tcp6->Receive (Tcp6, Rx6Token);\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
+          return Status;\r
+        }\r
+\r
+        while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+          Tcp6->Poll (Tcp6);\r
+        }\r
+\r
+        if (!HttpInstance->IsRxDone) {\r
+          //\r
+          // Cancle the Token before close its Event.\r
+          //\r
+          Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);\r
+          gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+          Rx6Token->CompletionToken.Status = EFI_TIMEOUT;\r
+        }\r
+\r
+        Status = Rx6Token->CompletionToken.Status;\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        Fragment.Len  = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
+        Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
+      } else {\r
+        if (Fragment.Bulk != NULL) {\r
+          FreePool (Fragment.Bulk);\r
+          Fragment.Bulk = NULL;\r
+        }\r
+\r
+        Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
+          return Status;\r
+        }\r
       }\r
-      \r
-      while (!HttpInstance->IsRxDone) {\r
-       Tcp6->Poll (Tcp6);\r
-      }    \r
-  \r
-      Status = Rx6Token->CompletionToken.Status;\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-  \r
+\r
       //\r
       // Append the response string.\r
       //\r
-      *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
+      *BufferSize = *SizeofHeaders + Fragment.Len;\r
       Buffer      = AllocateZeroPool (*BufferSize);\r
       if (Buffer == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         return Status;\r
       }\r
-  \r
+\r
       if (*HttpHeaders != NULL) {\r
-        CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));\r
+        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
         FreePool (*HttpHeaders);\r
       }\r
-  \r
+\r
       CopyMem (\r
-        Buffer + (*SizeofHeaders),\r
-        Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,\r
-        Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength\r
+        Buffer + *SizeofHeaders,\r
+        Fragment.Bulk,\r
+        Fragment.Len\r
         );\r
-      *HttpHeaders     = Buffer;\r
-      *SizeofHeaders  = *BufferSize;\r
-  \r
+      *HttpHeaders   = Buffer;\r
+      *SizeofHeaders = *BufferSize;\r
+\r
       //\r
       // Check whether we received end of HTTP headers.\r
       //\r
       *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);\r
-  \r
+    };\r
+\r
+    //\r
+    // Free the buffer.\r
+    //\r
+    if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
+      FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
+      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+      Fragment.Bulk = NULL;\r
     }\r
-    FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;    \r
-  }     \r
+\r
+    if (Fragment.Bulk != NULL) {\r
+      FreePool (Fragment.Bulk);\r
+      Fragment.Bulk = NULL;\r
+    }\r
+  }\r
 \r
   //\r
   // Skip the CRLF after the HTTP headers.\r
   //\r
-  *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);  \r
+  *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);\r
+\r
+  *SizeofHeaders = *EndofHeader - *HttpHeaders;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1814,7 +2072,7 @@ HttpTcpReceiveHeader (
   @param[in]  Wrap               The HTTP token's wrap data.\r
   @param[in]  HttpMsg            The HTTP message data.\r
 \r
-  @retval EFI_SUCCESS            The HTTP body is received.                          \r
+  @retval EFI_SUCCESS            The HTTP body is received.\r
   @retval Others                 Other error as indicated.\r
 \r
 **/\r
@@ -1830,24 +2088,23 @@ HttpTcpReceiveBody (
   EFI_TCP6_IO_TOKEN         *Rx6Token;\r
   EFI_TCP4_PROTOCOL         *Tcp4;\r
   EFI_TCP4_IO_TOKEN         *Rx4Token;\r
-  \r
+\r
   HttpInstance   = Wrap->HttpInstance;\r
   Tcp4 = HttpInstance->Tcp4;\r
   Tcp6 = HttpInstance->Tcp6;\r
   Rx4Token       = NULL;\r
   Rx6Token       = NULL;\r
 \r
-  \r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     ASSERT (Tcp6 != NULL);\r
   } else {\r
     ASSERT (Tcp4 != NULL);\r
   }\r
-  \r
+\r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
-    Rx6Token ->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
-    Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength;\r
+    Rx6Token ->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
+    Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
     Rx6Token ->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
     Rx6Token->CompletionToken.Status = EFI_NOT_READY;\r
 \r
@@ -1856,13 +2113,12 @@ HttpTcpReceiveBody (
       DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
       return Status;\r
     }\r
-      \r
   } else {\r
     Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
-    Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength;\r
+    Rx4Token->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
+    Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
     Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
-    \r
+\r
     Rx4Token->CompletionToken.Status = EFI_NOT_READY;\r
     Status = Tcp4->Receive (Tcp4, Rx4Token);\r
     if (EFI_ERROR (Status)) {\r
@@ -1879,13 +2135,13 @@ HttpTcpReceiveBody (
   Clean up Tcp Tokens while the Tcp transmission error occurs.\r
 \r
   @param[in]  Wrap               Pointer to HTTP token's wrap data.\r
-  \r
+\r
 **/\r
 VOID\r
 HttpTcpTokenCleanup (\r
   IN  HTTP_TOKEN_WRAP      *Wrap\r
   )\r
-{ \r
+{\r
   HTTP_PROTOCOL            *HttpInstance;\r
   EFI_TCP4_IO_TOKEN        *Rx4Token;\r
   EFI_TCP6_IO_TOKEN        *Rx6Token;\r
@@ -1894,207 +2150,51 @@ HttpTcpTokenCleanup (
   HttpInstance   = Wrap->HttpInstance;\r
   Rx4Token       = NULL;\r
   Rx6Token       = NULL;\r
-  \r
-  if (HttpInstance->LocalAddressIsIPv6) {\r
-    if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
-      gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
-    }\r
 \r
+  if (HttpInstance->LocalAddressIsIPv6) {\r
     Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
-    if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
-      FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+\r
+    if (Rx6Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+      Rx6Token->CompletionToken.Event = NULL;\r
     }\r
+\r
     FreePool (Wrap);\r
 \r
-    if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {\r
-      gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);\r
-      HttpInstance->Rx6Token.CompletionToken.Event = NULL;\r
+    Rx6Token = &HttpInstance->Rx6Token;\r
+\r
+    if (Rx6Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+      Rx6Token->CompletionToken.Event = NULL;\r
     }\r
 \r
-    Rx6Token = &HttpInstance->Rx6Token;\r
     if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
       FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
       Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
     }\r
-    \r
+\r
   } else {\r
-    if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
-      gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
-    }\r
     Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
-    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
-      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
-    }\r
-    FreePool (Wrap);\r
 \r
-    if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
-      gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
-      HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
-    }\r
-    \r
-    Rx4Token = &HttpInstance->Rx4Token;\r
-    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
-      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+    if (Rx4Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+      Rx4Token->CompletionToken.Event = NULL;\r
     }\r
-  }\r
-\r
-}\r
-\r
-/**\r
-  Generate HTTP request string.\r
-\r
-  @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.\r
-  @param[in]  Message            Pointer to storage containing HTTP message data.\r
-  @param[in]  Url                The URL of a remote host.\r
 \r
-  @return     Pointer to the created HTTP request string.\r
-  @return     NULL if any error occured.\r
-\r
-**/\r
-CHAR8 *\r
-HttpGenRequestString (\r
-  IN  HTTP_PROTOCOL        *HttpInstance,\r
-  IN  EFI_HTTP_MESSAGE     *Message,\r
-  IN  CHAR8                *Url\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  UINTN                       StrLength;\r
-  UINT8                       *Request;\r
-  UINT8                       *RequestPtr;\r
-  UINTN                       HttpHdrSize;\r
-  UINTN                       MsgSize;\r
-  BOOLEAN                     Success;\r
-  VOID                        *HttpHdr;\r
-  EFI_HTTP_HEADER             **AppendList; \r
-  UINTN                       Index;\r
-  \r
-  ASSERT (HttpInstance != NULL);\r
-  ASSERT (Message != NULL);\r
-\r
-  DEBUG ((EFI_D_ERROR, "HttpMethod - %x\n", Message->Data.Request->Method));\r
-\r
-  Request = NULL;\r
-  Success = FALSE;\r
-  HttpHdr = NULL;\r
-  AppendList = NULL;\r
-\r
-  //\r
-  // Build AppendList\r
-  //\r
-  AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));\r
-  if (AppendList == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  for(Index = 0; Index < Message->HeaderCount; Index++){\r
-    AppendList[Index] = &Message->Headers[Index];\r
-  }\r
-\r
-  //\r
-  // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available.\r
-  //\r
-  if (mHttpUtilities == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Build raw unformatted HTTP headers.\r
-  //\r
-  Status = mHttpUtilities->Build (\r
-                             mHttpUtilities,\r
-                             0,\r
-                             NULL,\r
-                             0,\r
-                             NULL,\r
-                             Message->HeaderCount,\r
-                             AppendList,\r
-                             &HttpHdrSize,\r
-                             &HttpHdr\r
-                             );\r
-  FreePool (AppendList);\r
-  if (EFI_ERROR (Status) || HttpHdr == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Calculate HTTP message length.\r
-  //\r
-  MsgSize = Message->BodyLength + HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (Url) +\r
-            AsciiStrLen (HTTP_VERSION_CRLF_STR) + HttpHdrSize;\r
-  Request = AllocateZeroPool (MsgSize);\r
-  if (Request == NULL) {\r
-    goto Exit;\r
-  }  \r
-\r
-  RequestPtr = Request;\r
-  //\r
-  // Construct header request\r
-  //\r
-  switch (Message->Data.Request->Method) {\r
-  case HttpMethodGet:\r
-    StrLength = sizeof (HTTP_METHOD_GET) - 1;\r
-    CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);\r
-    RequestPtr += StrLength;\r
-    break;\r
-  case HttpMethodHead:\r
-    StrLength = sizeof (HTTP_METHOD_HEAD) - 1;\r
-    CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);\r
-    RequestPtr += StrLength;\r
-    break;\r
-  default:\r
-    ASSERT (FALSE);\r
-    goto Exit;\r
-  }\r
-\r
-  StrLength = AsciiStrLen(" ");\r
-  CopyMem (RequestPtr, " ", StrLength);\r
-  RequestPtr += StrLength;\r
-\r
-  StrLength = AsciiStrLen (Url);\r
-  CopyMem (RequestPtr, Url, StrLength);\r
-  RequestPtr += StrLength;\r
-\r
-  StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;\r
-  CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);\r
-  RequestPtr += StrLength;\r
-\r
-  //\r
-  // Construct header\r
-  //\r
-  CopyMem (RequestPtr, HttpHdr, HttpHdrSize);\r
-  RequestPtr += HttpHdrSize;\r
-\r
-  //\r
-  // Construct body\r
-  //\r
-  if (Message->Body != NULL) {\r
-    CopyMem (RequestPtr, Message->Body, Message->BodyLength);\r
-    RequestPtr += Message->BodyLength;\r
-  }\r
+    FreePool (Wrap);\r
 \r
-  //\r
-  // Done\r
-  //\r
-  *RequestPtr = 0;\r
-  Success     = TRUE;\r
-  \r
-Exit:\r
+    Rx4Token = &HttpInstance->Rx4Token;\r
 \r
-  if (!Success) {\r
-    if (Request != NULL) {\r
-      FreePool (Request);\r
+    if (Rx4Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+      Rx4Token->CompletionToken.Event = NULL;\r
     }\r
 \r
-    Request = NULL;\r
-  }\r
 \r
-  if (HttpHdr != NULL) {\r
-    FreePool (HttpHdr);\r
+    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
+      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
+      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+    }\r
   }\r
 \r
-  return (CHAR8*) Request;\r
 }\r