/** @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
\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
// 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
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
TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
\r
- \r
}\r
\r
return EFI_SUCCESS;\r
//\r
Status = NetLibCreateServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
&gEfiTcp4ServiceBindingProtocolGuid,\r
&HttpInstance->Tcp4ChildHandle\r
);\r
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
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
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
//\r
Status = NetLibCreateServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
&HttpInstance->Tcp6ChildHandle\r
);\r
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
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
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
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
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
}\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
HttpInstance->Tcp6ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
}\r
NetMapClean (&HttpInstance->TxTokens);\r
NetMapClean (&HttpInstance->RxTokens);\r
\r
+ if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) {\r
+ //\r
+ // Destroy the TLS instance. \r
+ //\r
+ HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
+ }\r
+\r
if (HttpInstance->Tcp4ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
&gEfiTcp4ServiceBindingProtocolGuid,\r
HttpInstance->Tcp4ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
} \r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
HttpInstance->Tcp6ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
}\r
- \r
+\r
+ TlsCloseTxRxEvent (HttpInstance); \r
}\r
\r
/**\r
}\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
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
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
}\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
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
} 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
}\r
}\r
\r
-\r
return Status;\r
}\r
\r
}\r
\r
/**\r
- Transmit the HTTP mssage by processing the associated HTTP token.\r
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.\r
\r
@param[in] Map The container of Tx4Token or Tx6Token.\r
@param[in] Item Current item to check against.\r
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
//\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
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
CHAR8 **EndofHeader;\r
CHAR8 **HttpHeaders;\r
CHAR8 *Buffer;\r
+ NET_FRAGMENT Fragment;\r
\r
ASSERT (HttpInstance != NULL);\r
\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
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
\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
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
\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
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
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
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