]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpProto.c
NetworkPkg: HttpDxe response/cancel issue fix
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpProto.c
index 9b3c774ae21d53feb2987b6e53f8d33617d881b4..486b20304f5274be71b35026c09c3f715438914b 100644 (file)
@@ -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
@@ -815,6 +835,11 @@ HttpCleanProtocol (
   \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
@@ -1541,6 +1566,7 @@ 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
+  @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
@@ -1550,7 +1576,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
@@ -1599,9 +1626,18 @@ HttpTcpReceiveHeader (
         return Status;\r
       }\r
       \r
-      while (!HttpInstance->IsRxDone) {\r
-       Tcp4->Poll (Tcp4);\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
@@ -1660,9 +1696,18 @@ HttpTcpReceiveHeader (
         return Status;\r
       }\r
       \r
-      while (!HttpInstance->IsRxDone) {\r
-       Tcp6->Poll (Tcp6);\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
@@ -1738,7 +1783,6 @@ HttpTcpReceiveBody (
   Tcp6 = HttpInstance->Tcp6;\r
   Rx4Token       = NULL;\r
   Rx6Token       = NULL;\r
-\r
   \r
   if (HttpInstance->LocalAddressIsIPv6) {\r
     ASSERT (Tcp6 != NULL);\r
@@ -1758,7 +1802,6 @@ 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
@@ -1798,45 +1841,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