/** @file\r
Miscellaneous routines for HttpDxe driver.\r
\r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2015 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
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#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
}\r
\r
/**\r
- The notify function associated with TxToken for Tcp4->Transmit().\r
+ The notify function associated with Tx4Token for Tcp4->Transmit() or Tx6Token for Tcp6->Transmit().\r
\r
@param[in] Context The context.\r
\r
)\r
{\r
HTTP_TOKEN_WRAP *Wrap;\r
+ HTTP_PROTOCOL *HttpInstance;\r
\r
if (Context == NULL) {\r
return ;\r
}\r
\r
- Wrap = (HTTP_TOKEN_WRAP *) Context;\r
- Wrap->HttpToken->Status = Wrap->TcpWrap.TxToken.CompletionToken.Status;\r
- gBS->SignalEvent (Wrap->HttpToken->Event);\r
+ Wrap = (HTTP_TOKEN_WRAP *) Context;\r
+ HttpInstance = Wrap->HttpInstance;\r
\r
- //\r
- // Free resources.\r
- //\r
- if (Wrap->TcpWrap.TxToken.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {\r
- FreePool (Wrap->TcpWrap.TxToken.Packet.TxData->FragmentTable[0].FragmentBuffer);\r
- }\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;\r
+ gBS->SignalEvent (Wrap->HttpToken->Event);\r
+\r
+ //\r
+ // Free resources.\r
+ //\r
+ if (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {\r
+ FreePool (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer);\r
+ }\r
+\r
+ if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
+ }\r
+\r
+ } else {\r
+ Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;\r
+ gBS->SignalEvent (Wrap->HttpToken->Event);\r
+\r
+ //\r
+ // Free resources.\r
+ //\r
+ if (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {\r
+ FreePool (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer);\r
+ }\r
\r
- if (Wrap->TcpWrap.TxToken.CompletionToken.Event != NULL) {\r
- gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event);\r
+ if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);\r
+ }\r
}\r
\r
+\r
Wrap->TcpWrap.IsTxDone = TRUE;\r
\r
//\r
QueueDpc (TPL_CALLBACK, HttpTcpTransmitNotifyDpc, Context);\r
}\r
\r
-\r
/**\r
- The notify function associated with RxToken for Tcp4->Receive ().\r
+ The notify function associated with Rx4Token for Tcp4->Receive () or Rx6Token for Tcp6->Receive().\r
\r
@param[in] Context The context.\r
\r
UINTN Length;\r
EFI_STATUS Status;\r
HTTP_PROTOCOL *HttpInstance;\r
+ BOOLEAN UsingIpv6;\r
\r
if (Context == NULL) {\r
return ;\r
}\r
\r
Wrap = (HTTP_TOKEN_WRAP *) Context;\r
- gBS->CloseEvent (Wrap->TcpWrap.RxToken.CompletionToken.Event);\r
- if (EFI_ERROR (Wrap->TcpWrap.RxToken.CompletionToken.Status)) {\r
- return ;\r
- }\r
-\r
HttpInstance = Wrap->HttpInstance;\r
+ UsingIpv6 = HttpInstance->LocalAddressIsIPv6;\r
+\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
\r
//\r
// Check whether we receive a complete HTTP message.\r
//\r
ASSERT (HttpInstance->MsgParser != NULL);\r
+ if (UsingIpv6) {\r
+ Length = (UINTN) Wrap->TcpWrap.Rx6Data.FragmentTable[0].FragmentLength;\r
+ } else {\r
+ 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
- Length = (UINTN) Wrap->TcpWrap.RxData.FragmentTable[0].FragmentLength;\r
+ //\r
+ // Parse Body with CallbackData data.\r
+ //\r
Status = HttpParseMessageBody (\r
HttpInstance->MsgParser,\r
Length,\r
// 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
\r
\r
Wrap->TcpWrap.IsRxDone = TRUE;\r
- Wrap->HttpToken->Status = Wrap->TcpWrap.RxToken.CompletionToken.Status;\r
+ if (UsingIpv6) {\r
+ Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
+ } else {\r
+ Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
+ }\r
+\r
\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
\r
// 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
QueueDpc (TPL_CALLBACK, HttpTcpReceiveNotifyDpc, Context);\r
}\r
\r
-\r
/**\r
- Create events for the TCP4 connection token and TCP4 close token.\r
+ Create events for the TCP connection token and TCP close token.\r
\r
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
\r
\r
**/\r
EFI_STATUS\r
-HttpCreateTcp4ConnCloseEvent (\r
+HttpCreateTcpConnCloseEvent (\r
IN HTTP_PROTOCOL *HttpInstance\r
)\r
{\r
EFI_STATUS Status;\r
+\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ //\r
+ // Create events for variuos asynchronous operations.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpCommonNotify,\r
+ &HttpInstance->IsTcp4ConnDone,\r
+ &HttpInstance->Tcp4ConnToken.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ //\r
+ // Initialize Tcp4CloseToken\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpCommonNotify,\r
+ &HttpInstance->IsTcp4CloseDone,\r
+ &HttpInstance->Tcp4CloseToken.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR;\r
+ }\r
+\r
+ } else {\r
//\r
// Create events for variuos asynchronous operations.\r
//\r
EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r
HttpCommonNotify,\r
- &HttpInstance->IsConnDone,\r
- &HttpInstance->ConnToken.CompletionToken.Event\r
+ &HttpInstance->IsTcp6ConnDone,\r
+ &HttpInstance->Tcp6ConnToken.CompletionToken.Event\r
);\r
if (EFI_ERROR (Status)) {\r
goto ERROR;\r
}\r
\r
//\r
- // Initialize CloseToken\r
+ // Initialize Tcp6CloseToken\r
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r
HttpCommonNotify,\r
- &HttpInstance->IsCloseDone,\r
- &HttpInstance->CloseToken.CompletionToken.Event\r
+ &HttpInstance->IsTcp6CloseDone,\r
+ &HttpInstance->Tcp6CloseToken.CompletionToken.Event\r
);\r
if (EFI_ERROR (Status)) {\r
goto ERROR;\r
}\r
+ }\r
\r
- \r
return EFI_SUCCESS;\r
\r
ERROR:\r
//\r
// Error handling\r
//\r
- HttpCloseTcp4ConnCloseEvent (HttpInstance);\r
+ HttpCloseTcpConnCloseEvent (HttpInstance);\r
\r
return Status;\r
}\r
\r
\r
/**\r
- Close events in the TCP4 connection token and TCP4 close token.\r
+ Close events in the TCP connection token and TCP close token.\r
\r
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
\r
**/\r
VOID\r
-HttpCloseTcp4ConnCloseEvent (\r
+HttpCloseTcpConnCloseEvent (\r
IN HTTP_PROTOCOL *HttpInstance\r
)\r
{\r
ASSERT (HttpInstance != NULL);\r
\r
- if (NULL != HttpInstance->ConnToken.CompletionToken.Event) {\r
- gBS->CloseEvent (HttpInstance->ConnToken.CompletionToken.Event);\r
- HttpInstance->ConnToken.CompletionToken.Event = NULL;\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ if (NULL != HttpInstance->Tcp6ConnToken.CompletionToken.Event) {\r
+ gBS->CloseEvent (HttpInstance->Tcp6ConnToken.CompletionToken.Event);\r
+ HttpInstance->Tcp6ConnToken.CompletionToken.Event = NULL;\r
+ }\r
+\r
+ if (NULL != HttpInstance->Tcp6CloseToken.CompletionToken.Event) {\r
+ gBS->CloseEvent(HttpInstance->Tcp6CloseToken.CompletionToken.Event);\r
+ HttpInstance->Tcp6CloseToken.CompletionToken.Event = NULL;\r
+ }\r
+\r
+ } else {\r
+ if (NULL != HttpInstance->Tcp4ConnToken.CompletionToken.Event) {\r
+ gBS->CloseEvent (HttpInstance->Tcp4ConnToken.CompletionToken.Event);\r
+ HttpInstance->Tcp4ConnToken.CompletionToken.Event = NULL;\r
+ }\r
+\r
+ if (NULL != HttpInstance->Tcp4CloseToken.CompletionToken.Event) {\r
+ gBS->CloseEvent(HttpInstance->Tcp4CloseToken.CompletionToken.Event);\r
+ HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;\r
+ }\r
}\r
\r
- if (NULL != HttpInstance->CloseToken.CompletionToken.Event) {\r
- gBS->CloseEvent(HttpInstance->CloseToken.CompletionToken.Event);\r
- HttpInstance->CloseToken.CompletionToken.Event = NULL;\r
- } \r
}\r
\r
/**\r
- Create event for the TCP4 transmit token.\r
+ Create event for the TCP transmit token.\r
\r
@param[in] Wrap Point to HTTP token's wrap data.\r
\r
\r
**/\r
EFI_STATUS\r
-HttpCreateTcp4TxEvent (\r
+HttpCreateTcpTxEvent (\r
IN HTTP_TOKEN_WRAP *Wrap\r
)\r
{\r
HttpInstance = Wrap->HttpInstance;\r
TcpWrap = &Wrap->TcpWrap;\r
\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- HttpTcpTransmitNotify,\r
- Wrap,\r
- &TcpWrap->TxToken.CompletionToken.Event\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpTcpTransmitNotify,\r
+ 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
+\r
+ } else {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpTcpTransmitNotify,\r
+ Wrap,\r
+ &TcpWrap->Tx6Token.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ TcpWrap->Tx6Data.Push = TRUE;\r
+ TcpWrap->Tx6Data.Urgent = FALSE;\r
+ TcpWrap->Tx6Data.FragmentCount = 1;\r
+ TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
+ TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
\r
- TcpWrap->TxData.Push = TRUE;\r
- TcpWrap->TxData.Urgent = FALSE;\r
- TcpWrap->TxData.FragmentCount = 1;\r
- TcpWrap->TxToken.Packet.TxData = &Wrap->TcpWrap.TxData;\r
- TcpWrap->TxToken.CompletionToken.Status = EFI_NOT_READY;\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
- Create event for the TCP4 receive token which is used to receive HTTP header.\r
+ Create event for the TCP receive token which is used to receive HTTP header.\r
\r
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
\r
\r
**/\r
EFI_STATUS\r
-HttpCreateTcp4RxEventForHeader (\r
+HttpCreateTcpRxEventForHeader (\r
IN HTTP_PROTOCOL *HttpInstance\r
)\r
{\r
EFI_STATUS Status;\r
\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpCommonNotify,\r
+ &HttpInstance->IsRxDone,\r
+ &HttpInstance->Rx4Token.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ HttpInstance->Rx4Data.FragmentCount = 1;\r
+ HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data;\r
+ HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
+\r
+ } else {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpCommonNotify,\r
+ &HttpInstance->IsRxDone,\r
+ &HttpInstance->Rx6Token.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ HttpInstance->Rx6Data.FragmentCount =1;\r
+ HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data;\r
+ HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- HttpCommonNotify,\r
- &HttpInstance->IsRxDone,\r
- &HttpInstance->RxToken.CompletionToken.Event\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
}\r
\r
- HttpInstance->RxData.FragmentCount = 1;\r
- HttpInstance->RxToken.Packet.RxData = &HttpInstance->RxData;\r
- HttpInstance->RxToken.CompletionToken.Status = EFI_NOT_READY;\r
\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
- Create event for the TCP4 receive token which is used to receive HTTP body.\r
+ Create event for the TCP receive token which is used to receive HTTP body.\r
\r
@param[in] Wrap Point to HTTP token's wrap data.\r
\r
\r
**/\r
EFI_STATUS\r
-HttpCreateTcp4RxEvent (\r
- IN HTTP_TOKEN_WRAP *Wrap \r
+HttpCreateTcpRxEvent (\r
+ IN HTTP_TOKEN_WRAP *Wrap\r
)\r
{\r
EFI_STATUS Status;\r
\r
HttpInstance = Wrap->HttpInstance;\r
TcpWrap = &Wrap->TcpWrap;\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpTcpReceiveNotify,\r
+ Wrap,\r
+ &TcpWrap->Rx4Token.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- HttpTcpReceiveNotify,\r
- Wrap,\r
- &TcpWrap->RxToken.CompletionToken.Event\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ TcpWrap->Rx4Data.FragmentCount = 1;\r
+ TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data;\r
+ TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
+\r
+ } else {\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ HttpTcpReceiveNotify,\r
+ Wrap,\r
+ &TcpWrap->Rx6Token.CompletionToken.Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- TcpWrap->RxData.FragmentCount = 1;\r
- TcpWrap->RxToken.Packet.RxData = &Wrap->TcpWrap.RxData;\r
- TcpWrap->RxToken.CompletionToken.Status = EFI_NOT_READY;\r
+ TcpWrap->Rx6Data.FragmentCount = 1;\r
+ TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data;\r
+ TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ 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
+VOID\r
+HttpCloseTcpRxEvent (\r
+ IN HTTP_TOKEN_WRAP *Wrap\r
+ )\r
+{\r
+ HTTP_PROTOCOL *HttpInstance;\r
+\r
+ ASSERT (Wrap != NULL);\r
+ HttpInstance = Wrap->HttpInstance;\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->Rx6Token.CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);\r
+ HttpInstance->Rx6Token.CompletionToken.Event = NULL;\r
+ }\r
+ } else {\r
+ if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
+ }\r
+\r
+ if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
+ HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Intiialize the HTTP_PROTOCOL structure to the unconfigured state.\r
\r
- @param[in] HttpSb The HTTP service private instance.\r
@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
EFI_STATUS\r
HttpInitProtocol (\r
- IN HTTP_SERVICE *HttpSb,\r
- IN OUT HTTP_PROTOCOL *HttpInstance\r
+ IN OUT HTTP_PROTOCOL *HttpInstance,\r
+ IN BOOLEAN IpVersion\r
)\r
{\r
EFI_STATUS Status;\r
VOID *Interface;\r
+ BOOLEAN UsingIpv6;\r
\r
- ASSERT ((HttpSb != NULL) && (HttpInstance != NULL));\r
+ ASSERT (HttpInstance != NULL);\r
+ UsingIpv6 = IpVersion;\r
\r
- HttpInstance->Signature = HTTP_PROTOCOL_SIGNATURE;\r
- CopyMem (&HttpInstance->Http, &mEfiHttpTemplate, sizeof (HttpInstance->Http));\r
- HttpInstance->Service = HttpSb;\r
+ if (!UsingIpv6) {\r
+ //\r
+ // Create TCP4 child.\r
+ //\r
+ Status = NetLibCreateServiceChild (\r
+ HttpInstance->Service->ControllerHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ &gEfiTcp4ServiceBindingProtocolGuid,\r
+ &HttpInstance->Tcp4ChildHandle\r
+ );\r
\r
- //\r
- // Create TCP child.\r
- //\r
- Status = NetLibCreateServiceChild (\r
- HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- &HttpInstance->TcpChildHandle\r
- );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
\r
- if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
- }\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Tcp4ChildHandle,\r
+ &gEfiTcp4ProtocolGuid,\r
+ (VOID **) &Interface,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ HttpInstance->Service->ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
\r
- Status = gBS->OpenProtocol (\r
- HttpInstance->TcpChildHandle,\r
- &gEfiTcp4ProtocolGuid,\r
- (VOID **) &Interface,\r
- HttpInstance->Service->ImageHandle,\r
- HttpInstance->Service->ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- \r
- if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
- }\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
\r
- Status = gBS->OpenProtocol (\r
- HttpInstance->TcpChildHandle,\r
- &gEfiTcp4ProtocolGuid,\r
- (VOID **) &HttpInstance->Tcp4,\r
- HttpInstance->Service->ImageHandle,\r
- HttpInstance->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR(Status)) {\r
- goto ON_ERROR;\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Tcp4ChildHandle,\r
+ &gEfiTcp4ProtocolGuid,\r
+ (VOID **) &HttpInstance->Tcp4,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ HttpInstance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Service->Tcp4ChildHandle,\r
+ &gEfiTcp4ProtocolGuid,\r
+ (VOID **) &Interface,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ HttpInstance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+ } else {\r
+ //\r
+ // Create TCP6 Child.\r
+ //\r
+ Status = NetLibCreateServiceChild (\r
+ HttpInstance->Service->ControllerHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ &gEfiTcp6ServiceBindingProtocolGuid,\r
+ &HttpInstance->Tcp6ChildHandle\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ (VOID **) &Interface,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Service->ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ (VOID **) &HttpInstance->Tcp6,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ HttpInstance->Service->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ (VOID **) &Interface,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ goto ON_ERROR;\r
+ }\r
}\r
\r
HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);\r
goto ON_ERROR;\r
}\r
\r
- NetMapInit (&HttpInstance->TxTokens);\r
- NetMapInit (&HttpInstance->RxTokens);\r
-\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
- \r
- if (HttpInstance->TcpChildHandle != NULL) {\r
+\r
+ if (HttpInstance->Tcp4ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
- HttpInstance->TcpChildHandle,\r
+ HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
- HttpInstance->TcpChildHandle,\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->TcpChildHandle\r
+ HttpInstance->Tcp4ChildHandle\r
);\r
}\r
\r
- return Status;\r
- \r
+ if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Service->Tcp4ChildHandle,\r
+ &gEfiTcp4ProtocolGuid,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+ }\r
+\r
+ if (HttpInstance->Tcp6ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Service->ControllerHandle\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+\r
+ NetLibDestroyServiceChild (\r
+ HttpInstance->Service->ControllerHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ &gEfiTcp6ServiceBindingProtocolGuid,\r
+ HttpInstance->Tcp6ChildHandle\r
+ );\r
+ }\r
+\r
+ if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Service->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+ }\r
+\r
+ return EFI_UNSUPPORTED;\r
+\r
}\r
\r
/**\r
)\r
{\r
HttpCloseConnection (HttpInstance);\r
- \r
- HttpCloseTcp4ConnCloseEvent (HttpInstance);\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
NetMapClean (&HttpInstance->TxTokens);\r
NetMapClean (&HttpInstance->RxTokens);\r
\r
- if (HttpInstance->TcpChildHandle != NULL) {\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->TcpChildHandle,\r
+ HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
- HttpInstance->TcpChildHandle,\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->TcpChildHandle\r
+ HttpInstance->Tcp4ChildHandle\r
);\r
}\r
-}\r
-\r
-/**\r
- Establish TCP connection with HTTP server.\r
\r
- @param[in] HttpInstance The HTTP instance private data.\r
+ if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Service->Tcp4ChildHandle,\r
+ &gEfiTcp4ProtocolGuid,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+ }\r
\r
- @retval EFI_SUCCESS The TCP connection is established.\r
- @retval Others Other error as indicated.\r
+ if (HttpInstance->Tcp6ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Service->ControllerHandle\r
+ );\r
\r
-**/\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+\r
+ NetLibDestroyServiceChild (\r
+ HttpInstance->Service->ControllerHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ &gEfiTcp6ServiceBindingProtocolGuid,\r
+ HttpInstance->Tcp6ChildHandle\r
+ );\r
+ }\r
+\r
+ if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ HttpInstance->Service->Tcp6ChildHandle,\r
+ &gEfiTcp6ProtocolGuid,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
+ HttpInstance->Handle\r
+ );\r
+ }\r
+\r
+ TlsCloseTxRxEvent (HttpInstance);\r
+}\r
+\r
+/**\r
+ Establish TCP connection with HTTP server.\r
+\r
+ @param[in] HttpInstance The HTTP instance private data.\r
+\r
+ @retval EFI_SUCCESS The TCP connection is established.\r
+ @retval Others Other error as indicated.\r
+\r
+**/\r
EFI_STATUS\r
HttpCreateConnection (\r
IN HTTP_PROTOCOL *HttpInstance\r
{\r
EFI_STATUS Status;\r
\r
- //\r
- // Create events for variuos asynchronous operations.\r
- //\r
- HttpInstance->IsConnDone = FALSE;\r
-\r
//\r
// Connect to Http server\r
//\r
- HttpInstance->ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
- Status = HttpInstance->Tcp4->Connect (HttpInstance->Tcp4, &HttpInstance->ConnToken);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));\r
- return Status;\r
- }\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ HttpInstance->IsTcp4ConnDone = FALSE;\r
+ HttpInstance->Tcp4ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
+ Status = HttpInstance->Tcp4->Connect (HttpInstance->Tcp4, &HttpInstance->Tcp4ConnToken);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));\r
+ return Status;\r
+ }\r
\r
- while (!HttpInstance->IsConnDone) {\r
- HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
- }\r
+ while (!HttpInstance->IsTcp4ConnDone) {\r
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
+ }\r
\r
- Status = HttpInstance->ConnToken.CompletionToken.Status;\r
+ Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;\r
+\r
+ } else {\r
+ HttpInstance->IsTcp6ConnDone = FALSE;\r
+ HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
+ Status = HttpInstance->Tcp6->Connect (HttpInstance->Tcp6, &HttpInstance->Tcp6ConnToken);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp6->Connect() = %r\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ while(!HttpInstance->IsTcp6ConnDone) {\r
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
+ }\r
+\r
+ Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;\r
+ }\r
\r
if (!EFI_ERROR (Status)) {\r
HttpInstance->State = HTTP_STATE_TCP_CONNECTED;\r
EFI_STATUS Status;\r
\r
if (HttpInstance->State == HTTP_STATE_TCP_CONNECTED) {\r
- HttpInstance->CloseToken.AbortOnClose = TRUE;\r
- HttpInstance->IsCloseDone = FALSE;\r
- \r
- Status = HttpInstance->Tcp4->Close (HttpInstance->Tcp4, &HttpInstance->CloseToken);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
\r
- while (!HttpInstance->IsCloseDone) {\r
- HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ HttpInstance->Tcp6CloseToken.AbortOnClose = TRUE;\r
+ HttpInstance->IsTcp6CloseDone = FALSE;\r
+ Status = HttpInstance->Tcp6->Close (HttpInstance->Tcp6, &HttpInstance->Tcp6CloseToken);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (!HttpInstance->IsTcp6CloseDone) {\r
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
+ }\r
+\r
+ } else {\r
+ HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;\r
+ HttpInstance->IsTcp4CloseDone = FALSE;\r
+ Status = HttpInstance->Tcp4->Close (HttpInstance->Tcp4, &HttpInstance->Tcp4CloseToken);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ while (!HttpInstance->IsTcp4CloseDone) {\r
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
+ }\r
}\r
+\r
}\r
\r
HttpInstance->State = HTTP_STATE_TCP_CLOSED;\r
EFI_TCP4_CONFIG_DATA *Tcp4CfgData;\r
EFI_TCP4_ACCESS_POINT *Tcp4AP;\r
EFI_TCP4_OPTION *Tcp4Option;\r
- HTTP_TCP_TOKEN_WRAP *TcpWrap;\r
\r
ASSERT (HttpInstance != NULL);\r
- TcpWrap = &Wrap->TcpWrap;\r
\r
\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
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
return Status;\r
}\r
\r
- Status = HttpCreateTcp4ConnCloseEvent (HttpInstance);\r
+ Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = HttpCreateTcpTxEvent (Wrap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Configure TCP6 protocol child.\r
+\r
+ @param[in] HttpInstance The HTTP instance private data.\r
+ @param[in] Wrap The HTTP token's wrap data.\r
+\r
+ @retval EFI_SUCCESS The TCP6 protocol child is configured.\r
+ @retval Others Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpConfigureTcp6 (\r
+ IN HTTP_PROTOCOL *HttpInstance,\r
+ IN HTTP_TOKEN_WRAP *Wrap\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TCP6_CONFIG_DATA *Tcp6CfgData;\r
+ EFI_TCP6_ACCESS_POINT *Tcp6Ap;\r
+ EFI_TCP6_OPTION *Tcp6Option;\r
+\r
+ ASSERT (HttpInstance != NULL);\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
+ Tcp6Ap = &Tcp6CfgData->AccessPoint;\r
+ Tcp6Ap->ActiveFlag = TRUE;\r
+ Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;\r
+ Tcp6Ap->RemotePort = HttpInstance->RemotePort;\r
+ IP6_COPY_ADDRESS (&Tcp6Ap->StationAddress, &HttpInstance->Ipv6Node.LocalAddress);\r
+ IP6_COPY_ADDRESS (&Tcp6Ap->RemoteAddress , &HttpInstance->RemoteIpv6Addr);\r
+\r
+ Tcp6Option = Tcp6CfgData->ControlOption;\r
+ Tcp6Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
+ Tcp6Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT;\r
+ Tcp6Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG;\r
+ Tcp6Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;\r
+ Tcp6Option->DataRetries = HTTP_DATA_RETRIES;\r
+ Tcp6Option->FinTimeout = HTTP_FIN_TIMEOUT;\r
+ Tcp6Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES;\r
+ Tcp6Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME;\r
+ Tcp6Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;\r
+ Tcp6Option->EnableNagle = TRUE;\r
+\r
+ Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, Tcp6CfgData);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "HttpConfigureTcp6 - %r\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- Status = HttpCreateTcp4TxEvent (Wrap);\r
+ Status = HttpCreateTcpTxEvent (Wrap);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
\r
return EFI_SUCCESS;\r
+\r
}\r
\r
/**\r
- Check existing TCP connection, if in error state, receover 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
EFI_TCP4_CONNECTION_STATE Tcp4State;\r
\r
\r
- if (HttpInstance->State != HTTP_STATE_TCP_CONFIGED || HttpInstance->Tcp4 == NULL) {\r
+ if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED || HttpInstance->Tcp4 == NULL) {\r
return EFI_NOT_READY;\r
}\r
\r
Status = HttpInstance->Tcp4->GetModeData(\r
- HttpInstance->Tcp4, \r
- &Tcp4State, \r
+ HttpInstance->Tcp4,\r
+ &Tcp4State,\r
NULL,\r
NULL,\r
NULL,\r
return Status;\r
}\r
\r
- if (Tcp4State > Tcp4StateEstablished) {\r
+ if (Tcp4State == Tcp4StateEstablished) {\r
+ return EFI_SUCCESS;\r
+ } else if (Tcp4State > Tcp4StateEstablished ) {\r
HttpCloseConnection(HttpInstance);\r
- } \r
+ }\r
+\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. Then,\r
+ connect one TLS session if required.\r
+\r
+ @param[in] HttpInstance The HTTP instance private data.\r
+\r
+ @retval EFI_SUCCESS The TCP connection is established.\r
+ @retval EFI_NOT_READY TCP6 protocol child is not created or configured.\r
+ @retval Others Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpConnectTcp6 (\r
+ IN HTTP_PROTOCOL *HttpInstance\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TCP6_CONNECTION_STATE Tcp6State;\r
+\r
+ if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED || HttpInstance->Tcp6 == NULL) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ Status = HttpInstance->Tcp6->GetModeData (\r
+ HttpInstance->Tcp6,\r
+ &Tcp6State,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR(Status)){\r
+ DEBUG ((EFI_D_ERROR, "Tcp6 GetModeData fail - %x\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ if (Tcp6State == Tcp6StateEstablished) {\r
+ return EFI_SUCCESS;\r
+ } else if (Tcp6State > Tcp6StateEstablished ) {\r
+ HttpCloseConnection(HttpInstance);\r
+ }\r
+\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 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 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 session is done.\r
+ @retval Others Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpInitSession (\r
+ IN HTTP_PROTOCOL *HttpInstance,\r
+ IN HTTP_TOKEN_WRAP *Wrap,\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
+ //\r
+ if (Configure) {\r
+ Status = HttpConfigureTcp4 (HttpInstance, Wrap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Connect TCP.\r
+ //\r
+ Status = HttpConnectTcp4 (HttpInstance);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ } else {\r
+ //\r
+ // Configure TCP instance.\r
+ //\r
+ if (Configure) {\r
+ Status = HttpConfigureTcp6 (HttpInstance, Wrap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Connect TCP.\r
+ //\r
+ Status = HttpConnectTcp6 (HttpInstance);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
\r
- return HttpCreateConnection (HttpInstance);\r
}\r
\r
/**\r
- Send the HTTP message through TCP4.\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
\r
**/\r
EFI_STATUS\r
-HttpTransmitTcp4 (\r
+HttpTransmitTcp (\r
IN HTTP_PROTOCOL *HttpInstance,\r
IN HTTP_TOKEN_WRAP *Wrap,\r
IN UINT8 *TxString,\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_TCP4_IO_TOKEN *TxToken;\r
+ EFI_TCP4_IO_TOKEN *Tx4Token;\r
EFI_TCP4_PROTOCOL *Tcp4;\r
- \r
- Tcp4 = HttpInstance->Tcp4;\r
- TxToken = &Wrap->TcpWrap.TxToken;\r
+ EFI_TCP6_IO_TOKEN *Tx6Token;\r
+ EFI_TCP6_PROTOCOL *Tcp6;\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
- TxToken->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
- TxToken->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
- TxToken->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
- TxToken->CompletionToken.Status = EFI_NOT_READY; \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
- Wrap->TcpWrap.IsTxDone = FALSE;\r
- Status = Tcp4->Transmit (Tcp4, TxToken);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
- return Status;\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
- return Status;\r
-}\r
+ if (!HttpInstance->LocalAddressIsIPv6) {\r
+ Tcp4 = HttpInstance->Tcp4;\r
+ Tx4Token = &Wrap->TcpWrap.Tx4Token;\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
-/**\r
- Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined \r
- in UEFI 2.5 specification.\r
+ Tx4Token->CompletionToken.Status = EFI_NOT_READY;\r
\r
- @param[in] StatusCode The status code value in HTTP message.\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
+ goto ON_ERROR;\r
+ }\r
+\r
+ } else {\r
+ Tcp6 = HttpInstance->Tcp6;\r
+ Tx6Token = &Wrap->TcpWrap.Tx6Token;\r
+\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
- @return Value defined in EFI_HTTP_STATUS_CODE .\r
+ Tx6Token->CompletionToken.Status = EFI_NOT_READY;\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
+ 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
+ goto ON_ERROR;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+\r
+ON_ERROR:\r
+\r
+ if (HttpInstance->UseHttps) {\r
+ if (TlsRecord != NULL) {\r
+ FreePool (TlsRecord);\r
+ TlsRecord = NULL;\r
+ }\r
+\r
+ if (Fragment.Bulk != NULL) {\r
+ FreePool (Fragment.Bulk);\r
+ Fragment.Bulk = NULL;\r
+ }\r
}\r
+\r
+ return Status;\r
}\r
\r
/**\r
Check whether the user's token or event has already\r
- been enqueue on HTTP TxToken or RxToken list.\r
+ been enqueue on HTTP Tx or Rx Token list.\r
\r
@param[in] Map The container of either user's transmit or receive\r
token.\r
}\r
\r
/**\r
- Check whether the HTTP message associated with TxToken is already sent out.\r
+ Check whether the HTTP message associated with Tx4Token or Tx6Token is already sent out.\r
\r
- @param[in] Map The container of TxToken.\r
+ @param[in] Map The container of Tx4Token or Tx6Token.\r
@param[in] Item Current item to check against.\r
@param[in] Context The Token to check againist.\r
\r
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 TxToken.\r
+ @param[in] Map The container of Tx4Token or Tx6Token.\r
@param[in] Item Current item to check against.\r
@param[in] Context The Token to check againist.\r
\r
{\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
//\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 = HttpTransmitTcp4 (\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
/**\r
Receive the HTTP response by processing the associated HTTP token.\r
\r
- @param[in] Map The container of RxToken.\r
+ @param[in] Map The container of Rx4Token or Rx6Token.\r
@param[in] Item Current item to check against.\r
@param[in] Context The Token to check againist.\r
\r
}\r
\r
/**\r
- Generate HTTP request string.\r
+ Receive the HTTP header by processing the associated HTTP token.\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
+ @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
- @return Pointer to the created HTTP request string.\r
- @return NULL if any error occured.\r
+ @retval EFI_SUCCESS The HTTP header is received.\r
+ @retval Others Other errors as indicated.\r
\r
**/\r
-CHAR8 *\r
-HttpGenRequestString (\r
- IN HTTP_PROTOCOL *HttpInstance,\r
- IN EFI_HTTP_MESSAGE *Message,\r
- IN CHAR8 *Url\r
+EFI_STATUS\r
+HttpTcpReceiveHeader (\r
+ IN HTTP_PROTOCOL *HttpInstance,\r
+ IN OUT UINTN *SizeofHeaders,\r
+ IN OUT UINTN *BufferSize,\r
+ IN EFI_EVENT Timeout\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
+ EFI_STATUS Status;\r
+ EFI_TCP4_IO_TOKEN *Rx4Token;\r
+ EFI_TCP4_PROTOCOL *Tcp4;\r
+ EFI_TCP6_IO_TOKEN *Rx6Token;\r
+ EFI_TCP6_PROTOCOL *Tcp6;\r
+ CHAR8 **EndofHeader;\r
+ CHAR8 **HttpHeaders;\r
+ CHAR8 *Buffer;\r
+ NET_FRAGMENT Fragment;\r
\r
- DEBUG ((EFI_D_ERROR, "HttpMethod - %x\n", Message->Data.Request->Method));\r
+ ASSERT (HttpInstance != NULL);\r
\r
- Request = NULL;\r
- Success = FALSE;\r
- HttpHdr = NULL;\r
- AppendList = NULL;\r
+ EndofHeader = HttpInstance->EndofHeader;\r
+ HttpHeaders = HttpInstance->HttpHeaders;\r
+ Tcp4 = HttpInstance->Tcp4;\r
+ Tcp6 = HttpInstance->Tcp6;\r
+ 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
+ } else {\r
+ ASSERT (Tcp4 != NULL);\r
+ }\r
\r
- //\r
- // Build AppendList\r
- //\r
- AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));\r
- if (AppendList == NULL) {\r
- return NULL;\r
+ if (!HttpInstance->UseHttps) {\r
+ Status = HttpCreateTcpRxEventForHeader (HttpInstance);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
}\r
\r
- for(Index = 0; Index < Message->HeaderCount; Index++){\r
- AppendList[Index] = &Message->Headers[Index];\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
+ 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
+ // Append the response string along with a Null-terminator.\r
+ //\r
+ *BufferSize = *SizeofHeaders + Fragment.Len;\r
+ Buffer = AllocatePool (*BufferSize + 1);\r
+ if (Buffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ return Status;\r
+ }\r
+\r
+ if (*HttpHeaders != NULL) {\r
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
+ FreePool (*HttpHeaders);\r
+ }\r
+\r
+ CopyMem (\r
+ Buffer + *SizeofHeaders,\r
+ Fragment.Bulk,\r
+ Fragment.Len\r
+ );\r
+ *(Buffer + *BufferSize) = '\0';\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
+ // 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
+ 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
+ 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
+ //\r
+ // Append the response string along with a Null-terminator.\r
+ //\r
+ *BufferSize = *SizeofHeaders + Fragment.Len;\r
+ Buffer = AllocatePool (*BufferSize + 1);\r
+ if (Buffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ return Status;\r
+ }\r
+\r
+ if (*HttpHeaders != NULL) {\r
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);\r
+ FreePool (*HttpHeaders);\r
+ }\r
+\r
+ CopyMem (\r
+ Buffer + *SizeofHeaders,\r
+ Fragment.Bulk,\r
+ Fragment.Len\r
+ );\r
+ *(Buffer + *BufferSize) = '\0';\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
+ // 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
}\r
\r
//\r
- // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available.\r
+ // Skip the CRLF after the HTTP headers.\r
//\r
- if (mHttpUtilities == NULL) {\r
- return NULL;\r
+ *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);\r
+\r
+ *SizeofHeaders = *EndofHeader - *HttpHeaders;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Receive the HTTP body by processing the associated HTTP token.\r
+\r
+ @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 Others Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpTcpReceiveBody (\r
+ IN HTTP_TOKEN_WRAP *Wrap,\r
+ IN EFI_HTTP_MESSAGE *HttpMsg\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HTTP_PROTOCOL *HttpInstance;\r
+ EFI_TCP6_PROTOCOL *Tcp6;\r
+ EFI_TCP6_IO_TOKEN *Rx6Token;\r
+ EFI_TCP4_PROTOCOL *Tcp4;\r
+ EFI_TCP4_IO_TOKEN *Rx4Token;\r
+\r
+ HttpInstance = Wrap->HttpInstance;\r
+ Tcp4 = HttpInstance->Tcp4;\r
+ Tcp6 = HttpInstance->Tcp6;\r
+ Rx4Token = NULL;\r
+ Rx6Token = NULL;\r
+\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ ASSERT (Tcp6 != NULL);\r
+ } else {\r
+ ASSERT (Tcp4 != 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
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ Rx6Token = &Wrap->TcpWrap.Rx6Token;\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
+ 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
+ } else {\r
+ Rx4Token = &Wrap->TcpWrap.Rx4Token;\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
+ 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
\r
- //\r
- // Calculate HTTP message length.\r
- //\r
- MsgSize = Message->BodyLength + HTTP_MAXIMUM_METHOD_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_GET_STR) - 1;\r
- CopyMem (RequestPtr, HTTP_GET_STR, StrLength);\r
- RequestPtr += StrLength;\r
- break;\r
- case HttpMethodHead:\r
- StrLength = sizeof (HTTP_HEAD_STR) - 1;\r
- CopyMem (RequestPtr, HTTP_HEAD_STR, StrLength);\r
- RequestPtr += StrLength;\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- goto Exit;\r
- }\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
+ return EFI_SUCCESS;\r
\r
- //\r
- // Construct header\r
- //\r
- CopyMem (RequestPtr, HttpHdr, HttpHdrSize);\r
- RequestPtr += HttpHdrSize;\r
+}\r
\r
- //\r
- // Construct body\r
- //\r
- if (Message->Body != NULL) {\r
- CopyMem (RequestPtr, Message->Body, Message->BodyLength);\r
- RequestPtr += Message->BodyLength;\r
- }\r
+/**\r
+ Clean up Tcp Tokens while the Tcp transmission error occurs.\r
\r
- //\r
- // Done\r
- //\r
- *RequestPtr = 0;\r
- Success = TRUE;\r
- \r
-Exit:\r
+ @param[in] Wrap Pointer to HTTP token's wrap data.\r
\r
- if (!Success) {\r
- if (Request != NULL) {\r
- FreePool (Request);\r
+**/\r
+VOID\r
+HttpTcpTokenCleanup (\r
+ IN HTTP_TOKEN_WRAP *Wrap\r
+ )\r
+{\r
+ HTTP_PROTOCOL *HttpInstance;\r
+ EFI_TCP4_IO_TOKEN *Rx4Token;\r
+ EFI_TCP6_IO_TOKEN *Rx6Token;\r
+\r
+ ASSERT (Wrap != NULL);\r
+ HttpInstance = Wrap->HttpInstance;\r
+ Rx4Token = NULL;\r
+ Rx6Token = NULL;\r
+\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
+\r
+ if (Rx6Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+ Rx6Token->CompletionToken.Event = NULL;\r
}\r
\r
- Request = 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
+ Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
+\r
+ if (Rx4Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+ Rx4Token->CompletionToken.Event = NULL;\r
+ }\r
\r
- if (HttpHdr != NULL) {\r
- FreePool (HttpHdr);\r
+ FreePool (Wrap);\r
+\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
+\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