]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpProto.c
NetworkPkg: Convert source file to DOS format
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpProto.c
index 06f3bb686061c8c62310fe99dc07c8b07dfd31cf..d7fe271168fe29b41eb9dbb154fdf2719371b510 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 - 2017, 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
@@ -148,21 +148,41 @@ HttpTcpReceiveNotifyDpc (
   \r
   if (UsingIpv6) {\r
     gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\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
+    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
@@ -234,8 +254,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
@@ -412,15 +433,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
@@ -440,7 +461,6 @@ HttpCreateTcpTxEvent (
     TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
     TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
     \r
-    \r
   }\r
   \r
   return EFI_SUCCESS;\r
@@ -622,7 +642,7 @@ HttpInitProtocol (
     //\r
     Status = NetLibCreateServiceChild (\r
                HttpInstance->Service->ControllerHandle,\r
-               HttpInstance->Service->ImageHandle,\r
+               HttpInstance->Service->Ip4DriverBindingHandle,\r
                &gEfiTcp4ServiceBindingProtocolGuid,\r
                &HttpInstance->Tcp4ChildHandle\r
                );\r
@@ -635,7 +655,7 @@ 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
@@ -648,7 +668,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 +680,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 +693,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,7 +706,7 @@ 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
@@ -699,7 +719,7 @@ 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
@@ -712,7 +732,7 @@ HttpInitProtocol (
                     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
@@ -736,20 +756,20 @@ ON_ERROR:
     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
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip4DriverBindingHandle,\r
       &gEfiTcp4ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp4ChildHandle\r
       );\r
@@ -759,7 +779,7 @@ ON_ERROR:
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }\r
@@ -768,20 +788,20 @@ ON_ERROR:
     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
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip6DriverBindingHandle,\r
       &gEfiTcp6ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp6ChildHandle\r
       );\r
@@ -791,7 +811,7 @@ ON_ERROR:
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp6ChildHandle,\r
            &gEfiTcp6ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip6DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }\r
@@ -844,24 +864,31 @@ HttpCleanProtocol (
   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
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip4DriverBindingHandle,\r
       &gEfiTcp4ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp4ChildHandle\r
       );\r
@@ -871,7 +898,7 @@ HttpCleanProtocol (
     gBS->CloseProtocol (\r
            HttpInstance->Service->Tcp4ChildHandle,\r
            &gEfiTcp4ProtocolGuid,\r
-           HttpInstance->Service->ImageHandle,\r
+           HttpInstance->Service->Ip4DriverBindingHandle,\r
            HttpInstance->Handle\r
            );\r
   }  \r
@@ -880,20 +907,20 @@ HttpCleanProtocol (
     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
     NetLibDestroyServiceChild (\r
       HttpInstance->Service->ControllerHandle,\r
-      HttpInstance->Service->ImageHandle,\r
+      HttpInstance->Service->Ip6DriverBindingHandle,\r
       &gEfiTcp6ServiceBindingProtocolGuid,\r
       HttpInstance->Tcp6ChildHandle\r
       );\r
@@ -903,11 +930,12 @@ HttpCleanProtocol (
     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
@@ -1165,7 +1193,8 @@ HttpConfigureTcp6 (
 }\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
@@ -1206,11 +1235,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
@@ -1251,30 +1327,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
@@ -1318,7 +1452,7 @@ HttpInitTcp (
 }\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
@@ -1342,14 +1476,66 @@ HttpTransmitTcp (
   EFI_TCP4_PROTOCOL             *Tcp4;\r
   EFI_TCP6_IO_TOKEN             *Tx6Token;\r
   EFI_TCP6_PROTOCOL             *Tcp6;\r
+  UINT8                         *Buffer;  \r
+  UINTN                         BufferSize;\r
+  NET_FRAGMENT                  TempFragment;\r
+\r
+  Status                = EFI_SUCCESS;\r
+  Buffer                = NULL;\r
+  TempFragment.Len      = 0;\r
+  TempFragment.Bulk     = NULL;\r
+\r
+  //\r
+  // Need to encrypt data.\r
+  //\r
+  if (HttpInstance->UseHttps) {\r
+    //\r
+    // Build BufferOut data\r
+    //\r
+    BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;\r
+    Buffer     = AllocateZeroPool (BufferSize);\r
+    if (Buffer == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      return Status;\r
+    }\r
+    ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData;\r
+    ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
+    ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
+    ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);\r
+    CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);\r
+    \r
+    //\r
+    // Encrypt Packet.\r
+    //\r
+    Status = TlsProcessMessage (\r
+               HttpInstance, \r
+               Buffer, \r
+               BufferSize, \r
+               EfiTlsEncrypt, \r
+               &TempFragment\r
+               );\r
+    \r
+    FreePool (Buffer);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
   \r
-  if (!HttpInstance->LocalAddressIsIPv6) {     \r
+  if (!HttpInstance->LocalAddressIsIPv6) {\r
     Tcp4 = HttpInstance->Tcp4;\r
     Tx4Token = &Wrap->TcpWrap.Tx4Token;\r
+\r
+    if (HttpInstance->UseHttps) {\r
+      Tx4Token->Packet.TxData->DataLength = TempFragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.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->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
     Wrap->TcpWrap.IsTxDone = FALSE;\r
@@ -1362,10 +1548,17 @@ HttpTransmitTcp (
   } 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
+    \r
+    if (HttpInstance->UseHttps) {\r
+      Tx6Token->Packet.TxData->DataLength = TempFragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.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
@@ -1376,7 +1569,6 @@ HttpTransmitTcp (
     }\r
   }\r
   \r
-\r
   return Status;\r
 }\r
 \r
@@ -1446,7 +1638,7 @@ HttpTcpNotReady (
 }\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
@@ -1469,8 +1661,11 @@ HttpTcpTransmit (
   EFI_STATUS                Status;\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
     return EFI_SUCCESS;\r
@@ -1479,12 +1674,13 @@ 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
@@ -1497,10 +1693,12 @@ HttpTcpTransmit (
                  );\r
   FreePool (Url);\r
 \r
-  if (EFI_ERROR (Status)){\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
@@ -1568,6 +1766,7 @@ HttpTcpReceiveHeader (
   CHAR8                         **EndofHeader;\r
   CHAR8                         **HttpHeaders;\r
   CHAR8                         *Buffer;\r
+  NET_FRAGMENT                  Fragment;\r
 \r
   ASSERT (HttpInstance != NULL);\r
 \r
@@ -1578,6 +1777,8 @@ HttpTcpReceiveHeader (
   Buffer      = NULL;\r
   Rx4Token    = NULL;\r
   Rx6Token    = NULL;\r
+  Fragment.Len  = 0;\r
+  Fragment.Bulk = NULL;\r
   \r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     ASSERT (Tcp6 != NULL);\r
@@ -1585,144 +1786,219 @@ HttpTcpReceiveHeader (
     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
+  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 && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
-        Tcp4->Poll (Tcp4);\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
-      if (!HttpInstance->IsRxDone) {\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
       //\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
-    }\r
-    FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\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
   } 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
     // 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
-      }\r
-      \r
-      while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
-        Tcp6->Poll (Tcp6);\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
-      if (!HttpInstance->IsRxDone) {\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
       //\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
+      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); \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
+\r
+    if (Fragment.Bulk != NULL) {\r
+      FreePool (Fragment.Bulk);\r
+      Fragment.Bulk = NULL;\r
     }\r
-    FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
-    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;    \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
@@ -1732,7 +2008,6 @@ HttpTcpReceiveHeader (
 \r
   @param[in]  Wrap               The HTTP token's wrap data.\r
   @param[in]  HttpMsg            The HTTP message data.\r
-  @param[in]  Timeout            The time to wait for receiving the body packet.\r
 \r
   @retval EFI_SUCCESS            The HTTP body is received.                          \r
   @retval Others                 Other error as indicated.\r
@@ -1741,8 +2016,7 @@ HttpTcpReceiveHeader (
 EFI_STATUS\r
 HttpTcpReceiveBody (\r
   IN  HTTP_TOKEN_WRAP       *Wrap,\r
-  IN  EFI_HTTP_MESSAGE      *HttpMsg,\r
-  IN  EFI_EVENT             Timeout\r
+  IN  EFI_HTTP_MESSAGE      *HttpMsg\r
   )\r
 {\r
   EFI_STATUS                Status;\r
@@ -1766,8 +2040,8 @@ HttpTcpReceiveBody (
   \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
@@ -1776,21 +2050,10 @@ HttpTcpReceiveBody (
       DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
       return Status;\r
     }\r
-\r
-    while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
-      Tcp6->Poll (Tcp6);\r
-    }\r
-\r
-    if (!Wrap->TcpWrap.IsRxDone) {\r
-      gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
-      Rx6Token->CompletionToken.Status = EFI_TIMEOUT;\r
-      Wrap->HttpToken->Status = Rx6Token->CompletionToken.Status;\r
-      gBS->SignalEvent (Wrap->HttpToken->Event);\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
     Rx4Token->CompletionToken.Status = EFI_NOT_READY;\r
@@ -1799,17 +2062,6 @@ HttpTcpReceiveBody (
       DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
       return Status;\r
     }\r
-\r
-    while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
-      Tcp4->Poll (Tcp4);\r
-    }\r
-\r
-    if (!Wrap->TcpWrap.IsRxDone) {\r
-      gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
-      Rx4Token->CompletionToken.Status = EFI_TIMEOUT;\r
-      Wrap->HttpToken->Status = Rx4Token->CompletionToken.Status;\r
-      gBS->SignalEvent (Wrap->HttpToken->Event);\r
-    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1837,45 +2089,45 @@ HttpTcpTokenCleanup (
   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
     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
-    FreePool (Wrap);\r
 \r
-    if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {\r
-      gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);\r
-      HttpInstance->Rx6Token.CompletionToken.Event = NULL;\r
-    }\r
+    FreePool (Wrap);\r
 \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
     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
   } 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
+    if (Rx4Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+      Rx4Token->CompletionToken.Event = NULL;\r
     }\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
+    Rx4Token = &HttpInstance->Rx4Token;\r
+\r
+    if (Rx4Token->CompletionToken.Event != NULL) {\r
+      gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+      Rx4Token->CompletionToken.Event = NULL;\r
     }\r
     \r
-    Rx4Token = &HttpInstance->Rx4Token;\r
+    \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