147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** @file 247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Implementation of EFI_HTTP_PROTOCOL protocol interfaces. 347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 5c5a693cea60823e0a3df5a3e92604e4e8936c84aSamer El-Haj-Mahmoud (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> 647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This program and the accompanying materials 847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting are licensed and made available under the terms and conditions of the BSD License 947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting which accompanies this distribution. The full text of the license may be found at 1047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting http://opensource.org/licenses/bsd-license.php. 1147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 1247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 1547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 1647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 1747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting#include "HttpDriver.h" 1847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 1947f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_HTTP_PROTOCOL mEfiHttpTemplate = { 2047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpGetModeData, 2147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpConfigure, 2247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpRequest, 2347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpCancel, 2447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpResponse, 2547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpPoll 2647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting}; 2747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 2847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 2947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Returns the operational parameters for the current HTTP child instance. 3047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 3147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The GetModeData() function is used to read the current mode data (operational 3247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting parameters) for this HTTP protocol instance. 3347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 3447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 3547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[out] HttpConfigData Point to buffer for operational parameters of this 3647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP instance. 3747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 3847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Operation succeeded. 3947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: 4047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This is NULL. 4147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData is NULL. 4247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->AccessPoint is NULL. 431b96428d92c01383dc437717db679f57cf70d980Zhang Lubo @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. 4447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_STARTED The HTTP instance is not configured. 4547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 4647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 4747f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 4847f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 4947f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpGetModeData ( 5047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This, 5147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting OUT EFI_HTTP_CONFIG_DATA *HttpConfigData 5247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 5347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 5447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 55b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo EFI_HTTPv4_ACCESS_POINT *Http4AccessPoint; 56b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo EFI_HTTPv6_ACCESS_POINT *Http6AccessPoint; 5747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 5847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((This == NULL) || (HttpConfigData == NULL)) { 5947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 6047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 6147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 6247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 6347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL); 64b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 6547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) { 6647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_STARTED; 6747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 6847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 6947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->HttpVersion = HttpInstance->HttpVersion; 7047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->TimeOutMillisec = HttpInstance->TimeOutMillisec; 7147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->LocalAddressIsIPv6 = HttpInstance->LocalAddressIsIPv6; 7247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 73b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (HttpInstance->LocalAddressIsIPv6) { 74b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Http6AccessPoint = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT)); 751b96428d92c01383dc437717db679f57cf70d980Zhang Lubo if (Http6AccessPoint == NULL) { 761b96428d92c01383dc437717db679f57cf70d980Zhang Lubo return EFI_OUT_OF_RESOURCES; 771b96428d92c01383dc437717db679f57cf70d980Zhang Lubo } 78b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo CopyMem ( 79b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Http6AccessPoint, 80b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo &HttpInstance->Ipv6Node, 81b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo sizeof (HttpInstance->Ipv6Node) 8247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ); 83b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpConfigData->AccessPoint.IPv6Node = Http6AccessPoint; 84b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } else { 85b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Http4AccessPoint = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT)); 861b96428d92c01383dc437717db679f57cf70d980Zhang Lubo if (Http4AccessPoint == NULL) { 871b96428d92c01383dc437717db679f57cf70d980Zhang Lubo return EFI_OUT_OF_RESOURCES; 881b96428d92c01383dc437717db679f57cf70d980Zhang Lubo } 89b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo CopyMem ( 90b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Http4AccessPoint, 91b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo &HttpInstance->IPv4Node, 92b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo sizeof (HttpInstance->IPv4Node) 93b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo ); 94b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpConfigData->AccessPoint.IPv4Node = Http4AccessPoint; 95b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 9647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 9747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 9847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 9947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 10047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 10147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Initialize or brutally reset the operational parameters for this EFI HTTP instance. 10247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 10347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The Configure() function does the following: 10447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring 10547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting timeout, local address, port, etc. 10647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active 10747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting connections with remote hosts, canceling all asynchronous tokens, and flush request 10847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting and response buffers without informing the appropriate hosts. 10947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 11047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Except for GetModeData() and Configure(), No other EFI HTTP function can be executed 11147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting by this instance until the Configure() function is executed and returns successfully. 11247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 11347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 11447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] HttpConfigData Pointer to the configure data to configure the instance. 11547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 11647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Operation succeeded. 11747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: 11847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This is NULL. 11947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->LocalAddressIsIPv6 is FALSE and 12047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->IPv4Node is NULL. 12147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->LocalAddressIsIPv6 is TRUE and 12247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->IPv6Node is NULL. 12347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling 12447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Configure() with NULL to reset it. 12547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. 12647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when 12747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting executing Configure(). 12847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_UNSUPPORTED One or more options in HttpConfigData are not supported 12947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting in the implementation. 13047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 13147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 13247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 13347f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpConfigure ( 13447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This, 13547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_CONFIG_DATA *HttpConfigData 13647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 13747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 13847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 13947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_STATUS Status; 140b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 141b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 142b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // Check input parameters. 143b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 144b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (This == NULL || 145b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo (HttpConfigData != NULL && ((HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) || 146b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo (!HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)))) { 14747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 14847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 14947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 15047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 15147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL && HttpInstance->Service != NULL); 15247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 15347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpConfigData != NULL) { 154b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 15547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 15647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Now configure this HTTP instance. 15747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 15847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->State != HTTP_STATE_UNCONFIGED) { 15947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_ALREADY_STARTED; 16047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 16147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 16247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->HttpVersion = HttpConfigData->HttpVersion; 16347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->TimeOutMillisec = HttpConfigData->TimeOutMillisec; 16447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->LocalAddressIsIPv6 = HttpConfigData->LocalAddressIsIPv6; 165b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 166b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (HttpConfigData->LocalAddressIsIPv6) { 167b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo CopyMem ( 168b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo &HttpInstance->Ipv6Node, 169b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpConfigData->AccessPoint.IPv6Node, 170b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo sizeof (HttpInstance->Ipv6Node) 171b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo ); 17247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 17347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem ( 17447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting &HttpInstance->IPv4Node, 17547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpConfigData->AccessPoint.IPv4Node, 17647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting sizeof (HttpInstance->IPv4Node) 17747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ); 17847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 179b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 180b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // Creat Tcp child 181b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 182b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpInitProtocol (HttpInstance, HttpInstance->LocalAddressIsIPv6); 183b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (EFI_ERROR (Status)) { 184b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo return Status; 185b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 186b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 187b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->State = HTTP_STATE_HTTP_CONFIGED; 188b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo return EFI_SUCCESS; 18947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 19047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 191b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 192b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // Reset all the resources related to HttpInsance. 193b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // 194b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpCleanProtocol (HttpInstance); 195b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->State = HTTP_STATE_UNCONFIGED; 196b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo return EFI_SUCCESS; 19747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 19847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 19947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 20047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 20147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 20247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The Request() function queues an HTTP request to this HTTP instance. 20347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 20447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent 20547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting successfully, or if there is an error, Status in token will be updated and Event will 20647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting be signaled. 20747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 20847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 20947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Token Pointer to storage containing HTTP request token. 21047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 21147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Outgoing data was processed. 21247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. 21347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. 21447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. 21547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. 21647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_UNSUPPORTED The HTTP method is not supported in current 21747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting implementation. 21847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: 21947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This is NULL. 22047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message is NULL. 22147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->Body is not NULL, 22247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->BodyLength is non-zero, and 22347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->Data is NULL, but a previous call to 22447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Request()has not been completed successfully. 22547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 22647f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 22747f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 22847f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpRequest ( 22947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This, 23047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_TOKEN *Token 23147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 23247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 23347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_MESSAGE *HttpMsg; 23447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_REQUEST_DATA *Request; 23547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting VOID *UrlParser; 23647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_STATUS Status; 23747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *HostName; 23847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINT16 RemotePort; 23947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 24047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BOOLEAN Configure; 24147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BOOLEAN ReConfigure; 24247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *RequestStr; 24347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *Url; 24451b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan UINTN UrlLen; 24547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR16 *HostNameStr; 24647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_TOKEN_WRAP *Wrap; 247b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin CHAR8 *FileUrl; 248b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin 24947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((This == NULL) || (Token == NULL)) { 25047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 25147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 25247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 25347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg = Token->Message; 25447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((HttpMsg == NULL) || (HttpMsg->Headers == NULL)) { 25547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 25647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 25747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 25847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 25947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Current implementation does not support POST/PUT method. 26047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // If future version supports these two methods, Request could be NULL for a special case that to send large amounts 26147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // of data. For this case, the implementation need check whether previous call to Request() has been completed or not. 26247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 26347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 26447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Request = HttpMsg->Data.Request; 26547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((Request == NULL) || (Request->Url == NULL)) { 26647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 26747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 26847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 26947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 27047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Only support GET and HEAD method in current implementation. 27147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 27247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead)) { 27347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_UNSUPPORTED; 27447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 27547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 27647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 27747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL); 27847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 27947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) { 28047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_STARTED; 28147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 28247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 28347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 28447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether the token already existed. 28547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 28647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) { 28747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_ACCESS_DENIED; 28847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 28947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 29047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HostName = NULL; 29147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = NULL; 29247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HostNameStr = NULL; 29347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 29447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 29547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Parse the URI of the remote host. 29647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 2977ef0690f7c116e8760b5556e8c91d5902deee255Fu Siyuan Url = HttpInstance->Url; 29851b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan UrlLen = StrLen (Request->Url) + 1; 29951b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan if (UrlLen > HTTP_URL_BUFFER_LEN) { 30051b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan Url = AllocateZeroPool (UrlLen); 30151b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan if (Url == NULL) { 30251b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan return EFI_OUT_OF_RESOURCES; 30351b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan } 30451b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan FreePool (HttpInstance->Url); 30551b0450e002431b7cb902220c513ddaf589f3600Fu Siyuan HttpInstance->Url = Url; 306b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 307b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 30847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 30947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UnicodeStrToAsciiStr (Request->Url, Url); 31047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UrlParser = NULL; 31147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser); 31247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 31347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 31447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 31547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 31647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting RequestStr = NULL; 31747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HostName = NULL; 31847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = HttpUrlGetHostName (Url, UrlParser, &HostName); 31947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 32047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 32147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 32247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 32347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = HttpUrlGetPort (Url, UrlParser, &RemotePort); 32447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 32547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting RemotePort = HTTP_DEFAULT_PORT; 32647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 327a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo // 328a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo // If Configure is TRUE, it indicates the first time to call Request(); 329a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo // If ReConfigure is TRUE, it indicates the request URL is not same 330a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo // with the previous call to Request(); 331a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo // 33247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Configure = TRUE; 33347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ReConfigure = TRUE; 33447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 335a8706acb0ee847c1521bd8db71c144fd24480e0bFu Siyuan if (HttpInstance->RemoteHost == NULL) { 33647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 33747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Request() is called the first time. 33847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 33947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ReConfigure = FALSE; 34047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 34147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((HttpInstance->RemotePort == RemotePort) && 34247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) { 34347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 34447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Host Name and port number of the request URL are the same with previous call to Request(). 34547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether previous TCP packet sent out. 34647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 34747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) { 34847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 34947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Wrap the HTTP token in HTTP_TOKEN_WRAP 35047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 35147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); 35247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Wrap == NULL) { 35347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 35447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 35547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 35647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 35747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpToken = Token; 35847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpInstance = HttpInstance; 35947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 360b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpCreateTcpTxEvent (Wrap); 36147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 36247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 36347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 36447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 36547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); 36647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 36747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 36847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 36947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 37047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->TcpWrap.Method = Request->Method; 37147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 37247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HostName); 37347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 37447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 37547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Queue the HTTP token and return. 37647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 37747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 37847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 37947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 38047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Use existing TCP instance to transmit the packet. 38147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 38247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Configure = FALSE; 38347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ReConfigure = FALSE; 38447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 38547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 38647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 38747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Need close existing TCP instance and create a new TCP instance for data transmit. 38847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 38947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->RemoteHost != NULL) { 39047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpInstance->RemoteHost); 39147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->RemoteHost = NULL; 392a8706acb0ee847c1521bd8db71c144fd24480e0bFu Siyuan HttpInstance->RemotePort = 0; 39347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 39447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 39547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 39647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 39747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Configure) { 39847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 399b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // Parse Url for IPv4 or IPv6 address, if failed, perform DNS resolution. 40047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 401b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (!HttpInstance->LocalAddressIsIPv6) { 402b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr); 403b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } else { 404ac4588532d17a2f3cac3e7dde7c85ed59dab319bZhang Lubo Status = HttpUrlGetIp6 (Url, UrlParser, &HttpInstance->RemoteIpv6Addr); 405b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 406b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 40747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 408b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16)); 40947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HostNameStr == NULL) { 41047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 41147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 41247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 413b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 41447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting AsciiStrToUnicodeStr (HostName, HostNameStr); 415b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (!HttpInstance->LocalAddressIsIPv6) { 416b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr); 417b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } else { 418b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr); 419b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 420b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 42147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HostNameStr); 42247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 42347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 42447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 42547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 42647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 427b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 42847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 42947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Save the RemotePort and RemoteHost. 43047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 43147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance->RemoteHost == NULL); 43247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->RemotePort = RemotePort; 43347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->RemoteHost = HostName; 43447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HostName = NULL; 43547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 43647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 43747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (ReConfigure) { 43847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 43947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // The request URL is different from previous calls to Request(), close existing TCP instance. 44047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 441a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo if (!HttpInstance->LocalAddressIsIPv6) { 442a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo ASSERT (HttpInstance->Tcp4 != NULL); 443a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo } else { 444a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo ASSERT (HttpInstance->Tcp6 != NULL); 445a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo } 44647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpCloseConnection (HttpInstance); 44747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpCancel (This, NULL); 44847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 44947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 45047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 45147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Wrap the HTTP token in HTTP_TOKEN_WRAP 45247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 45347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); 45447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Wrap == NULL) { 45547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 45647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 45747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 45847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 45947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpToken = Token; 46047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpInstance = HttpInstance; 46147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->TcpWrap.Method = Request->Method; 46247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 463a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo Status = HttpInitTcp (HttpInstance, Wrap, Configure); 464a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo if (EFI_ERROR (Status)) { 465a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo goto Error2; 466a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo } 467b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 468a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo if (!Configure) { 46947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 47047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // For the new HTTP token, create TX TCP token events. 47147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 472b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpCreateTcpTxEvent (Wrap); 47347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 47447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error1; 47547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 47647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 477a2e619821a791de5cd65cd2c757de0a8aa7f138cZhang Lubo 47847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 47947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Create request message. 48047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 481b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin FileUrl = Url; 482b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin if (*FileUrl != '/') { 483b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin // 484b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin // Convert the absolute-URI to the absolute-path 485b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin // 486b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin while (*FileUrl != ':') { 487b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin FileUrl++; 488b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin } 489b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) { 490b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin FileUrl += 3; 491b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin while (*FileUrl != '/') { 492b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin FileUrl++; 493b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin } 494b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin } else { 495b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin Status = EFI_INVALID_PARAMETER; 496b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin goto Error3; 497b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin } 498b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin } 499b199d9418820b873d0e05190fe5dc947a6f72b14Gary Ching-Pang Lin RequestStr = HttpGenRequestString (HttpInstance, HttpMsg, FileUrl); 50047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (RequestStr == NULL) { 50147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 50247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error3; 50347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 50447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 50547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); 50647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 50747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error4; 50847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 50947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 51047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 51147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Transmit the request message. 51247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 513b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpTransmitTcp ( 51447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance, 51547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap, 51647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting (UINT8*) RequestStr, 51747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting AsciiStrLen (RequestStr) 51847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ); 51947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 52047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error5; 52147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 52247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 52349c9f74cc1bd967ea042bcfc948c849207fa71bfFu Siyuan DispatchDpc (); 524b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 525cdf8c32ec169db14d4824c659159e2b6b6bed540Nagaraj Hegde if (HostName != NULL) { 526cdf8c32ec169db14d4824c659159e2b6b6bed540Nagaraj Hegde FreePool (HostName); 527cdf8c32ec169db14d4824c659159e2b6b6bed540Nagaraj Hegde } 528b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 52947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 53047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 53147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError5: 53247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NetMapRemoveTail (&HttpInstance->TxTokens, NULL); 53347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 53447f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError4: 53547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (RequestStr != NULL) { 53647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (RequestStr); 53747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 53847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 53947f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError3: 54047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpCloseConnection (HttpInstance); 54147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 54247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError2: 543b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpCloseTcpConnCloseEvent (HttpInstance); 544b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) { 545b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event); 546b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL; 547b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 548b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) { 549b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event); 550b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL; 55147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 55247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 55347f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError1: 554b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 55547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HostName != NULL) { 55647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HostName); 55747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 55847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Wrap != NULL) { 55947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (Wrap); 56047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 56147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (UrlParser!= NULL) { 56247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpUrlFreeParser (UrlParser); 56347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 56447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 56547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 56647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 56747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 56847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 56947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 570b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Cancel a user's Token. 57147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 57247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Map The HTTP instance's token queue. 57347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Item Object container for one HTTP token and token's wrap. 57447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Context The user's token to cancel. 57547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 57647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Continue to check the next Item. 57747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_ABORTED The user's Token (Token != NULL) is cancelled. 57847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 57947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 58047f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 58147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 58247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingHttpCancelTokens ( 58347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN NET_MAP *Map, 58447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN NET_MAP_ITEM *Item, 58547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN VOID *Context 58647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 58747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 58847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 58947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_TOKEN *Token; 59047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_TOKEN_WRAP *Wrap; 591b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HTTP_PROTOCOL *HttpInstance; 59247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 59347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token = (EFI_HTTP_TOKEN *) Context; 59447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 59547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 59647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Return EFI_SUCCESS to check the next item in the map if 59747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // this one doesn't match. 59847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 59947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((Token != NULL) && (Token != Item->Key)) { 60047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 60147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 60247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 60347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = (HTTP_TOKEN_WRAP *) Item->Value; 60447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (Wrap != NULL); 605b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance = Wrap->HttpInstance; 60647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 60747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 60847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Free resources. 60947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 61047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NetMapRemoveItem (Map, Item, NULL); 61147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 612b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (!HttpInstance->LocalAddressIsIPv6) { 613b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) { 614b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event); 615b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 616b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 617b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) { 618b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event); 619b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 620b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 621b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx4Token.Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) { 622b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo FreePool (Wrap->TcpWrap.Rx4Token.Packet.RxData->FragmentTable[0].FragmentBuffer); 623b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 62447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 625b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } else { 626b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) { 627b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event); 628b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 629b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 630b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) { 631b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event); 632b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 63347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 634b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx6Token.Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) { 635b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo FreePool (Wrap->TcpWrap.Rx6Token.Packet.RxData->FragmentTable[0].FragmentBuffer); 636b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 63747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 63847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 639b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 64047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (Wrap); 64147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 64247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 64347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // If only one item is to be cancel, return EFI_ABORTED to stop 64447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // iterating the map any more. 64547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 64647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Token != NULL) { 64747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_ABORTED; 64847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 64947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 65047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 65147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 65247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 65347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 65447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Cancel the user's receive/transmit request. It is the worker function of 65547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EfiHttpCancel API. If a matching token is found, it will call HttpCancelTokens to cancel the 65647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting token. 65747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 65847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. 65947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Token The token to cancel. If NULL, all token will be 66047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting cancelled. 66147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 66247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS The token is cancelled. 66347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_FOUND The asynchronous request or response token is not found. 66447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval Others Other error as indicated. 66547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 66647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 66747f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 66847f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingHttpCancel ( 66947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN HTTP_PROTOCOL *HttpInstance, 67047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_TOKEN *Token 67147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 67247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 67347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_STATUS Status; 67447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 67547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 67647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // First check the tokens queued by EfiHttpRequest(). 67747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 67847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = NetMapIterate (&HttpInstance->TxTokens, HttpCancelTokens, Token); 67947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 68047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Token != NULL) { 68147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Status == EFI_ABORTED) { 68247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 68347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 68447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 68547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 68647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 68747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 68847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 68947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 69047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Then check the tokens queued by EfiHttpResponse(). 69147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 69247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token); 69347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 69447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Token != NULL) { 69547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Status == EFI_ABORTED) { 69647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 69747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 69847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_FOUND; 69947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 70047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 70147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 70247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 70347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 70447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 70547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 70647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 70747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 70847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 70947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 71047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Abort an asynchronous HTTP request or response token. 71147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 71247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The Cancel() function aborts a pending HTTP request or response transaction. If 71347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token is not NULL and the token is in transmit or receive queues when it is being 71447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will 71547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting be signaled. If the token is not in one of the queues, which usually means that the 71647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL, 71747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting all asynchronous tokens issued by Request() or Response() will be aborted. 71847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 71947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 72047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Token Point to storage containing HTTP request or response 72147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting token. 72247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 72347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Request and Response queues are successfully flushed. 72447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER This is NULL. 72547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_STARTED This instance hasn't been configured. 72647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, 72747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BOOTP, RARP, etc.) hasn't finished yet. 72847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_FOUND The asynchronous request or response token is not 72947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting found. 73047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_UNSUPPORTED The implementation does not support this function. 73147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 73247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 73347f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 73447f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 73547f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpCancel ( 73647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This, 73747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_TOKEN *Token 73847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 73947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 74047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 74147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 74247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (This == NULL) { 74347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 74447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 74547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 74647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 74747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL); 74847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 74947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) { 75047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_STARTED; 75147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 75247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 75347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return HttpCancel (HttpInstance, Token); 75447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 75547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 75647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 75747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 75847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting A callback function to intercept events during message parser. 75947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 76047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This function will be invoked during HttpParseMessageBody() with various events type. An error 76147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return status of the callback function will cause the HttpParseMessageBody() aborted. 76247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 76347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] EventType Event type of this callback call. 76447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Data A pointer to data buffer. 76547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Length Length in bytes of the Data. 76647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Context Callback context set by HttpInitMsgParser(). 76747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 76847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Continue to parser the message body. 76947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 77047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 77147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 77247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 77347f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingHttpBodyParserCallback ( 77447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN HTTP_BODY_PARSE_EVENT EventType, 77547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN CHAR8 *Data, 77647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN UINTN Length, 77747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN VOID *Context 77847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 77947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 78047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_TOKEN_WRAP *Wrap; 7815ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo UINTN BodyLength; 7825ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo CHAR8 *Body; 78347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 78447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EventType != BodyParseEventOnComplete) { 78547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 78647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 78747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 78847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Data == NULL || Length != 0 || Context == NULL) { 78947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 79047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 79147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 79247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = (HTTP_TOKEN_WRAP *) Context; 7935ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo Body = Wrap->HttpToken->Message->Body; 7945ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo BodyLength = Wrap->HttpToken->Message->BodyLength; 7955ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo if (Data < Body + BodyLength) { 7965ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo Wrap->HttpInstance->NextMsg = Data; 7975ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo } else { 7985ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo Wrap->HttpInstance->NextMsg = NULL; 7995ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo } 8005ba9f065a5cd401330281763fae1135961cfd8c4Zhang Lubo 80147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 80247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 803b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // Free Tx4Token or Tx6Token since already received corrsponding HTTP response. 80447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 80547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (Wrap); 80647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 80747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 80847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 80947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 81047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 81147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The work function of EfiHttpResponse(). 81247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 81347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Wrap Pointer to HTTP token's wrap data. 81447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 81547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Allocation succeeded. 81647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_OUT_OF_RESOURCES Failed to complete the opration due to lack of resources. 817b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo @retval EFI_NOT_READY Can't find a corresponding Tx4Token/Tx6Token or 8185ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu the EFI_HTTP_UTILITIES_PROTOCOL is not available. 81947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 82047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 82147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 82247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingHttpResponseWorker ( 82347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN HTTP_TOKEN_WRAP *Wrap 82447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 82547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 82647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_STATUS Status; 82747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_MESSAGE *HttpMsg; 82847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *EndofHeader; 82947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *HttpHeaders; 83047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINTN SizeofHeaders; 83147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINTN BufferSize; 83247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINTN StatusCode; 83347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *Tmp; 83447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *HeaderTmp; 83547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CHAR8 *StatusCodeStr; 83647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINTN BodyLen; 83747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 83847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_TOKEN *Token; 83947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NET_MAP_ITEM *Item; 84047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_TOKEN_WRAP *ValueInItem; 84147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting UINTN HdrLen; 84247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 8433fd7bd08f438130f9fcbcc1ab4392dea1a859c14fanwang if (Wrap == NULL || Wrap->HttpInstance == NULL) { 8443fd7bd08f438130f9fcbcc1ab4392dea1a859c14fanwang return EFI_INVALID_PARAMETER; 8453fd7bd08f438130f9fcbcc1ab4392dea1a859c14fanwang } 8463fd7bd08f438130f9fcbcc1ab4392dea1a859c14fanwang 84747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = Wrap->HttpInstance; 84847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token = Wrap->HttpToken; 84947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg = Token->Message; 85047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 851b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->EndofHeader = NULL; 852b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->HttpHeaders = NULL; 853b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpMsg->Headers = NULL; 854b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpHeaders = NULL; 855b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo SizeofHeaders = 0; 856b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo BufferSize = 0; 857b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo EndofHeader = NULL; 85847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 85947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpMsg->Data.Response != NULL) { 86047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 86147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Need receive the HTTP headers, prepare buffer. 86247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 863b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpCreateTcpRxEventForHeader (HttpInstance); 86447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 86547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 86647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 86747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 86847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 86947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether we have cached header from previous call. 87047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 87147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) { 87247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 87347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // The data is stored at [NextMsg, CacheBody + CacheLen]. 87447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 87547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HdrLen = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg; 87647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpHeaders = AllocateZeroPool (HdrLen); 87747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpHeaders == NULL) { 87847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 87947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 88047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 88147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 88247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem (HttpHeaders, HttpInstance->NextMsg, HdrLen); 88347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpInstance->CacheBody); 88447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheBody = NULL; 88547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->NextMsg = NULL; 88647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheOffset = 0; 88747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting SizeofHeaders = HdrLen; 88847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BufferSize = HttpInstance->CacheLen; 88947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 89047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 89147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether we cached the whole HTTP headers. 89247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 89347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR); 894b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 89547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 896b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->EndofHeader = &EndofHeader; 897b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpInstance->HttpHeaders = &HttpHeaders; 89847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 899b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize); 900b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (EFI_ERROR (Status)) { 901b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo goto Error; 902b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 90347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 9041b96428d92c01383dc437717db679f57cf70d980Zhang Lubo ASSERT (HttpHeaders != NULL); 9051b96428d92c01383dc437717db679f57cf70d980Zhang Lubo 90647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 90747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Cache the part of body. 90847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 90947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLen = BufferSize - (EndofHeader - HttpHeaders); 91047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (BodyLen > 0) { 91147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->CacheBody != NULL) { 91247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpInstance->CacheBody); 91347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 91447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 91547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheBody = AllocateZeroPool (BodyLen); 91647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->CacheBody == NULL) { 91747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_OUT_OF_RESOURCES; 91847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 91947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 92047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 92147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem (HttpInstance->CacheBody, EndofHeader, BodyLen); 92247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheLen = BodyLen; 92347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 92447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 92547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 92647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Search for Status Code. 92747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 92847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting StatusCodeStr = HttpHeaders + AsciiStrLen (HTTP_VERSION_STR) + 1; 92947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (StatusCodeStr == NULL) { 93047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 93147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 93247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 93347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting StatusCode = AsciiStrDecimalToUintn (StatusCodeStr); 93447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 93547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 93647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Remove the first line of HTTP message, e.g. "HTTP/1.1 200 OK\r\n". 93747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 93847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Tmp = AsciiStrStr (HttpHeaders, HTTP_CRLF_STR); 93947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Tmp == NULL) { 94047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 94147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 94247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 94347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Tmp = Tmp + AsciiStrLen (HTTP_CRLF_STR); 94447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting SizeofHeaders = SizeofHeaders - (Tmp - HttpHeaders); 94547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HeaderTmp = AllocateZeroPool (SizeofHeaders); 94647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HeaderTmp == NULL) { 94747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 94847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 94947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 95047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem (HeaderTmp, Tmp, SizeofHeaders); 95147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpHeaders); 95247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpHeaders = HeaderTmp; 9535ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu 9545ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu // 9555ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available. 9565ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu // 9575ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu if (mHttpUtilities == NULL) { 9585ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu Status = EFI_NOT_READY; 9595ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu goto Error; 9605ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu } 9615ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu 96247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 96347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Parse the HTTP header into array of key/value pairs. 96447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 9655ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu Status = mHttpUtilities->Parse ( 9665ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu mHttpUtilities, 9675ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu HttpHeaders, 9685ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu SizeofHeaders, 9695ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu &HttpMsg->Headers, 9705ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu &HttpMsg->HeaderCount 9715ca29abe529794c1c2a2663378b0719e902c1077Jiaxin Wu ); 97247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 97347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 97447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 97547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 97647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpHeaders); 97747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpHeaders = NULL; 97847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 97947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->Data.Response->StatusCode = HttpMappingToStatusCode (StatusCode); 98047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 98147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 98247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Init message-body parser by header information. 98347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 98447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_NOT_READY; 98547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ValueInItem = NULL; 98647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NetMapRemoveHead (&HttpInstance->TxTokens, (VOID**) &ValueInItem); 98747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (ValueInItem == NULL) { 98847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 98947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 99047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 99147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 992b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo // The first Tx Token not transmitted yet, insert back and return error. 99347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 99447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (!ValueInItem->TcpWrap.IsTxDone) { 99547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error2; 99647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 99747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 99847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = HttpInitMsgParser ( 99947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ValueInItem->TcpWrap.Method, 100047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->Data.Response->StatusCode, 100147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->HeaderCount, 100247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->Headers, 100347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpBodyParserCallback, 100447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting (VOID *) ValueInItem, 100547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting &HttpInstance->MsgParser 100647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ); 100747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 100847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error2; 100947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 101047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 101147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 101247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether we received a complete HTTP message. 101347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 101447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->CacheBody != NULL) { 101547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody); 101647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 101747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error2; 101847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 101947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 102047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpIsMessageComplete (HttpInstance->MsgParser)) { 102147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 102247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Free the MsgParse since we already have a full HTTP message. 102347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 102447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpFreeMsgParser (HttpInstance->MsgParser); 102547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->MsgParser = NULL; 102647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 102747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 102847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 102947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((HttpMsg->Body == NULL) || (HttpMsg->BodyLength == 0)) { 103047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_SUCCESS; 103147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Exit; 103247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 103347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 103447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 103547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 103647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Receive the response body. 103747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 103847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLen = 0; 103947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 104047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 104147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // First check whether we cached some data. 104247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 104347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->CacheBody != NULL) { 104447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 104547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Calculate the length of the cached data. 104647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 104747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->NextMsg != NULL) { 104847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 104947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // We have a cached HTTP message which includes a part of HTTP header of next message. 105047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 105147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLen = HttpInstance->NextMsg - (HttpInstance->CacheBody + HttpInstance->CacheOffset); 105247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 105347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLen = HttpInstance->CacheLen - HttpInstance->CacheOffset; 105447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 105547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 105647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (BodyLen > 0) { 105747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 105847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // We have some cached data. Just copy the data and return. 105947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 106047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpMsg->BodyLength < BodyLen) { 106147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, HttpMsg->BodyLength); 106247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheOffset = HttpInstance->CacheOffset + HttpMsg->BodyLength; 106347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } else { 106447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 106547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Copy all cached data out. 106647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 106747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, BodyLen); 106847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheOffset = BodyLen + HttpInstance->CacheOffset; 106947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->BodyLength = BodyLen; 107047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 107147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->NextMsg == NULL) { 107247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 107347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // There is no HTTP header of next message. Just free the cache buffer. 107447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 107547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpInstance->CacheBody); 107647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheBody = NULL; 107747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->NextMsg = NULL; 107847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheOffset = 0; 107947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 108047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 108147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 108247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Return since we aready received required data. 108347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 108447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_SUCCESS; 108547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Exit; 108647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 108747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 108847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (BodyLen == 0 && HttpInstance->MsgParser == NULL) { 108947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 109047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // We received a complete HTTP message, and we don't have more data to return to caller. 109147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 109247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg->BodyLength = 0; 109347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = EFI_SUCCESS; 109447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Exit; 109547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 109647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 109747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 109847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance->MsgParser != NULL); 109947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 110047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 110147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // We still need receive more data when there is no cache data and MsgParser is not NULL; 110247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 1103b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpTcpReceiveBody (Wrap, HttpMsg); 110447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 110547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 110647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 110747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 110847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 110947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 111047f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingExit: 111147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken); 111247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Item != NULL) { 111347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL); 111447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 111547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Status = Status; 111647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting gBS->SignalEvent (Token->Event); 1117b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpCloseTcpRxEvent (Wrap); 111847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (Wrap); 111947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 112047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 112147f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError2: 112247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting NetMapInsertHead (&HttpInstance->TxTokens, ValueInItem->HttpToken, ValueInItem); 112347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 112447f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError: 1125b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HttpTcpTokenCleanup (Wrap); 112647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 112747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpHeaders != NULL) { 112847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpHeaders); 112947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 113047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 113147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpMsg->Headers != NULL) { 113247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpMsg->Headers); 113347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 113447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 113547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->CacheBody != NULL) { 113647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (HttpInstance->CacheBody); 113747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance->CacheBody = NULL; 113847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 113947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 114047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Status = Status; 114147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting gBS->SignalEvent (Token->Event); 114247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 114347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 114447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 114547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 114647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 114747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 114847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 114947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The Response() function queues an HTTP response to this HTTP instance, similar to 115047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Receive() function in the EFI TCP driver. When the HTTP request is sent successfully, 115147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting or if there is an error, Status in token will be updated and Event will be signaled. 115247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 115347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The HTTP driver will queue a receive token to the underlying TCP instance. When data 115447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting is received in the underlying TCP instance, the data will be parsed and Token will 115547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting be populated with the response data. If the data received from the remote host 115647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting 115747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting (asynchronously) for more data to be sent from the remote host before signaling 115847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Event in Token. 115947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 116047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting It is the responsibility of the caller to allocate a buffer for Body and specify the 116147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting size in BodyLength. If the remote host provides a response that contains a content 116247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting body, up to BodyLength bytes will be copied from the receive buffer into Body and 116347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLength will be updated with the amount of bytes received and copied to Body. This 116447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting allows the client to download a large file in chunks instead of into one contiguous 116547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is 116647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive 116747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting token to underlying TCP instance. If data arrives in the receive buffer, up to 116847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLength bytes of data will be copied to Body. The HTTP driver will then update 116947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting BodyLength with the amount of bytes received and copied to Body. 117047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 117147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting If the HTTP driver does not have an open underlying TCP connection with the host 117247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is 117347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain 117447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting an open TCP connection between client and host. 117547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 117647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 117747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] Token Pointer to storage containing HTTP response token. 117847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 117947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Allocation succeeded. 118047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been 118147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting initialized. 118247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: 118347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting This is NULL. 118447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token is NULL. 118547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->Headers is NULL. 118647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message is NULL. 118747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->Body is not NULL, 118847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->BodyLength is non-zero, and 118947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Token->Message->Data is NULL, but a previous call to 119047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Response() has not been completed successfully. 119147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. 119247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_ACCESS_DENIED An open TCP connection is not present with the host 119347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting specified by response URL. 119447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 119547f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 119647f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 119747f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpResponse ( 119847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This, 119947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_TOKEN *Token 120047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 120147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 120247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_STATUS Status; 120347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting EFI_HTTP_MESSAGE *HttpMsg; 120447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_PROTOCOL *HttpInstance; 120547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HTTP_TOKEN_WRAP *Wrap; 120647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 120747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if ((This == NULL) || (Token == NULL)) { 120847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 120947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 121047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 121147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpMsg = Token->Message; 121247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpMsg == NULL) { 121347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 121447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 121547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 121647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 121747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL); 121847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 121947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) { 122047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_STARTED; 122147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 122247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 122347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 122447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // Check whether the token already existed. 122547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 122647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (NetMapIterate (&HttpInstance->RxTokens, HttpTokenExist, Token))) { 122747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_ACCESS_DENIED; 122847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 122947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 123047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); 123147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Wrap == NULL) { 123247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_OUT_OF_RESOURCES; 123347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 123447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 123547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpInstance = HttpInstance; 123647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Wrap->HttpToken = Token; 123747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 1238b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpCreateTcpRxEvent (Wrap); 123947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 124047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 124147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 124247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 124347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap); 124447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (EFI_ERROR (Status)) { 124547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting goto Error; 124647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 124747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 124847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 124947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // If already have pending RxTokens, return directly. 125047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting // 125147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (NetMapGetCount (&HttpInstance->RxTokens) > 1) { 125247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_SUCCESS; 125347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 125447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 125547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return HttpResponseWorker (Wrap); 125647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 125747f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingError: 125847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (Wrap != NULL) { 1259b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) { 1260b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event); 1261b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 1262b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 1263b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) { 1264b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event); 126547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 126647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting FreePool (Wrap); 126747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 126847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 126947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return Status; 127047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 127147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 127247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting/** 127347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting The Poll() function can be used by network drivers and applications to increase the 127447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting rate that data packets are moved between the communication devices and the transmit 127547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting and receive queues. 127647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 127747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting In some systems, the periodic timer event in the managed network driver may not poll 127847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting the underlying communications device fast enough to transmit and/or receive all data 127947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting packets without missing incoming packets or dropping outgoing packets. Drivers and 128047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting applications that are experiencing packet loss should try calling the Poll() function 128147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting more often. 128247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 128347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. 128447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 128547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_SUCCESS Incoming or outgoing data was processed. 128647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. 128747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_INVALID_PARAMETER This is NULL. 128847f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_READY No incoming or outgoing data is processed. 128947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. 129047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 129147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting**/ 129247f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFI_STATUS 129347f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEFIAPI 129447f51a064fbb3d3226304380674b2bec3cb33ba1Ye TingEfiHttpPoll ( 129547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting IN EFI_HTTP_PROTOCOL *This 129647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ) 129747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting{ 129849c9f74cc1bd967ea042bcfc948c849207fa71bfFu Siyuan EFI_STATUS Status; 1299b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo HTTP_PROTOCOL *HttpInstance; 130047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 130147f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting if (This == NULL) { 130247f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_INVALID_PARAMETER; 130347f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 130447f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 130547f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); 130647f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting ASSERT (HttpInstance != NULL); 130747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting 13081b96428d92c01383dc437717db679f57cf70d980Zhang Lubo if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) { 130947f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting return EFI_NOT_STARTED; 131047f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting } 1311b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 1312b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo if (HttpInstance->LocalAddressIsIPv6) { 13131b96428d92c01383dc437717db679f57cf70d980Zhang Lubo if (HttpInstance->Tcp6 == NULL) { 13141b96428d92c01383dc437717db679f57cf70d980Zhang Lubo return EFI_NOT_STARTED; 13151b96428d92c01383dc437717db679f57cf70d980Zhang Lubo } 1316b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); 1317b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } else { 13181b96428d92c01383dc437717db679f57cf70d980Zhang Lubo if (HttpInstance->Tcp4 == NULL) { 13191b96428d92c01383dc437717db679f57cf70d980Zhang Lubo return EFI_NOT_STARTED; 13201b96428d92c01383dc437717db679f57cf70d980Zhang Lubo } 1321b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); 1322b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo } 1323b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 132449c9f74cc1bd967ea042bcfc948c849207fa71bfFu Siyuan DispatchDpc (); 1325b659408b933f40765960e877de3e1f8ceaab52cbZhang Lubo 132649c9f74cc1bd967ea042bcfc948c849207fa71bfFu Siyuan return Status; 132747f51a064fbb3d3226304380674b2bec3cb33ba1Ye Ting} 1328