X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FHttpDxe%2FHttpImpl.c;h=d64cd9e965c0d890ea5ddc2e1b2f96e73a3c0924;hb=d1050b9dff1cace252aff86630bfdb59dff5f507;hp=f70e116f38d7e78f7bfc131c343b26aa4bc622bc;hpb=f75a7f568e6d0944327970b3f3f2dafd9bba76b1;p=mirror_edk2.git diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c index f70e116f38..d64cd9e965 100644 --- a/NetworkPkg/HttpDxe/HttpImpl.c +++ b/NetworkPkg/HttpDxe/HttpImpl.c @@ -1,16 +1,10 @@ /** @file Implementation of EFI_HTTP_PROTOCOL protocol interfaces. - Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -51,11 +45,11 @@ EFI_HTTP_PROTOCOL mEfiHttpTemplate = { EFI_STATUS EFIAPI EfiHttpGetModeData ( - IN EFI_HTTP_PROTOCOL *This, - OUT EFI_HTTP_CONFIG_DATA *HttpConfigData + IN EFI_HTTP_PROTOCOL *This, + OUT EFI_HTTP_CONFIG_DATA *HttpConfigData ) { - HTTP_PROTOCOL *HttpInstance; + HTTP_PROTOCOL *HttpInstance; // // Check input parameters. @@ -67,7 +61,8 @@ EfiHttpGetModeData ( HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); if ((HttpConfigData->AccessPoint.IPv6Node == NULL) || - (HttpConfigData->AccessPoint.IPv4Node == NULL)) { + (HttpConfigData->AccessPoint.IPv4Node == NULL)) + { return EFI_INVALID_PARAMETER; } @@ -84,7 +79,7 @@ EfiHttpGetModeData ( HttpConfigData->AccessPoint.IPv6Node, &HttpInstance->Ipv6Node, sizeof (HttpInstance->Ipv6Node) - ); + ); } else { CopyMem ( HttpConfigData->AccessPoint.IPv4Node, @@ -130,20 +125,21 @@ EfiHttpGetModeData ( EFI_STATUS EFIAPI EfiHttpConfigure ( - IN EFI_HTTP_PROTOCOL *This, - IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL ) { - HTTP_PROTOCOL *HttpInstance; - EFI_STATUS Status; + HTTP_PROTOCOL *HttpInstance; + EFI_STATUS Status; // // Check input parameters. // - if (This == NULL || - (HttpConfigData != NULL && - ((HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) || - (!HttpConfigData->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)))) { + if ((This == NULL) || + ((HttpConfigData != NULL) && + ((HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv6Node == NULL)) || + (!HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv4Node == NULL))))) + { return EFI_INVALID_PARAMETER; } @@ -151,7 +147,6 @@ EfiHttpConfigure ( ASSERT (HttpInstance->Service != NULL); if (HttpConfigData != NULL) { - if (HttpConfigData->HttpVersion >= HttpVersionUnsupported) { return EFI_UNSUPPORTED; } @@ -191,10 +186,9 @@ EfiHttpConfigure ( HttpInstance->State = HTTP_STATE_HTTP_CONFIGED; return EFI_SUCCESS; - } else { // - // Reset all the resources related to HttpInsance. + // Reset all the resources related to HttpInstance. // HttpCleanProtocol (HttpInstance); HttpInstance->State = HTTP_STATE_UNCONFIGED; @@ -202,7 +196,6 @@ EfiHttpConfigure ( } } - /** The Request() function queues an HTTP request to this HTTP instance. @@ -232,41 +225,41 @@ EfiHttpConfigure ( EFI_STATUS EFIAPI EfiHttpRequest ( - IN EFI_HTTP_PROTOCOL *This, - IN EFI_HTTP_TOKEN *Token + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token ) { - EFI_HTTP_MESSAGE *HttpMsg; - EFI_HTTP_REQUEST_DATA *Request; - VOID *UrlParser; - EFI_STATUS Status; - CHAR8 *HostName; - UINTN HostNameSize; - UINT16 RemotePort; - HTTP_PROTOCOL *HttpInstance; - BOOLEAN Configure; - BOOLEAN ReConfigure; - BOOLEAN TlsConfigure; - CHAR8 *RequestMsg; - CHAR8 *Url; - UINTN UrlLen; - CHAR16 *HostNameStr; - HTTP_TOKEN_WRAP *Wrap; - CHAR8 *FileUrl; - UINTN RequestMsgSize; - EFI_HANDLE ImageHandle; + EFI_HTTP_MESSAGE *HttpMsg; + EFI_HTTP_REQUEST_DATA *Request; + VOID *UrlParser; + EFI_STATUS Status; + CHAR8 *HostName; + UINTN HostNameSize; + UINT16 RemotePort; + HTTP_PROTOCOL *HttpInstance; + BOOLEAN Configure; + BOOLEAN ReConfigure; + BOOLEAN TlsConfigure; + CHAR8 *RequestMsg; + CHAR8 *Url; + UINTN UrlLen; + CHAR16 *HostNameStr; + HTTP_TOKEN_WRAP *Wrap; + CHAR8 *FileUrl; + UINTN RequestMsgSize; + EFI_HANDLE ImageHandle; // // Initializations // - Url = NULL; - UrlParser = NULL; - RemotePort = 0; - HostName = NULL; - RequestMsg = NULL; - HostNameStr = NULL; - Wrap = NULL; - FileUrl = NULL; + Url = NULL; + UrlParser = NULL; + RemotePort = 0; + HostName = NULL; + RequestMsg = NULL; + HostNameStr = NULL; + Wrap = NULL; + FileUrl = NULL; TlsConfigure = FALSE; if ((This == NULL) || (Token == NULL)) { @@ -286,7 +279,8 @@ EfiHttpRequest ( if ((Request != NULL) && (Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) && - (Request->Method != HttpMethodPatch)) { + (Request->Method != HttpMethodPatch)) + { return EFI_UNSUPPORTED; } @@ -309,7 +303,8 @@ EfiHttpRequest ( // if ((HttpInstance->Method != HttpMethodPut) && (HttpInstance->Method != HttpMethodPost) && - (HttpInstance->Method != HttpMethodPatch)) { + (HttpInstance->Method != HttpMethodPatch)) + { return EFI_INVALID_PARAMETER; } @@ -323,7 +318,7 @@ EfiHttpRequest ( // // We need to have the Message Body for sending the HTTP message across in these cases. // - if (HttpMsg->Body == NULL || HttpMsg->BodyLength == 0) { + if ((HttpMsg->Body == NULL) || (HttpMsg->BodyLength == 0)) { return EFI_INVALID_PARAMETER; } @@ -343,18 +338,18 @@ EfiHttpRequest ( // // Parse the URI of the remote host. // - Url = HttpInstance->Url; + Url = HttpInstance->Url; UrlLen = StrLen (Request->Url) + 1; if (UrlLen > HTTP_URL_BUFFER_LEN) { Url = AllocateZeroPool (UrlLen); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } + FreePool (HttpInstance->Url); HttpInstance->Url = Url; } - UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen); // @@ -367,8 +362,7 @@ EfiHttpRequest ( // HTTP is disabled, return directly if the URI is not HTTPS. // if (!PcdGetBool (PcdAllowHttpConnections) && !(HttpInstance->UseHttps)) { - - DEBUG ((EFI_D_ERROR, "EfiHttpRequest: HTTP is disabled.\n")); + DEBUG ((DEBUG_ERROR, "EfiHttpRequest: HTTP is disabled.\n")); return EFI_ACCESS_DENIED; } @@ -376,7 +370,7 @@ EfiHttpRequest ( // // Check whether we need to create Tls child and open the TLS protocol. // - if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) { + if (HttpInstance->UseHttps && (HttpInstance->TlsChildHandle == NULL)) { // // Use TlsSb to create Tls child and open the TLS protocol. // @@ -400,15 +394,27 @@ EfiHttpRequest ( } UrlParser = NULL; - Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser); + Status = HttpParseUrl (Url, (UINT32)AsciiStrLen (Url), FALSE, &UrlParser); if (EFI_ERROR (Status)) { goto Error1; } - HostName = NULL; - Status = HttpUrlGetHostName (Url, UrlParser, &HostName); + Status = HttpUrlGetHostName (Url, UrlParser, &HostName); if (EFI_ERROR (Status)) { - goto Error1; + goto Error1; + } + + if (HttpInstance->LocalAddressIsIPv6) { + HostNameSize = AsciiStrSize (HostName); + + if ((HostNameSize > 2) && (HostName[0] == '[') && (HostName[HostNameSize - 2] == ']')) { + // + // HostName format is expressed as IPv6, so, remove '[' and ']'. + // + HostNameSize -= 2; + CopyMem (HostName, HostName + 1, HostNameSize - 1); + HostName[HostNameSize - 1] = '\0'; + } } Status = HttpUrlGetPort (Url, UrlParser, &RemotePort); @@ -419,6 +425,7 @@ EfiHttpRequest ( RemotePort = HTTP_DEFAULT_PORT; } } + // // If Configure is TRUE, it indicates the first time to call Request(); // If ReConfigure is TRUE, it indicates the request URL is not same @@ -437,7 +444,8 @@ EfiHttpRequest ( (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) && (!HttpInstance->UseHttps || (HttpInstance->UseHttps && !TlsConfigure && - HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) { + (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring)))) + { // // Host Name and port number of the request URL are the same with previous call to Request(). // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring. @@ -509,7 +517,7 @@ EfiHttpRequest ( if (EFI_ERROR (Status)) { HostNameSize = AsciiStrSize (HostName); - HostNameStr = AllocateZeroPool (HostNameSize * sizeof (CHAR16)); + HostNameStr = AllocateZeroPool (HostNameSize * sizeof (CHAR16)); if (HostNameStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; @@ -522,9 +530,11 @@ EfiHttpRequest ( Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr); } + HttpNotify (HttpEventDns, Status); + FreePool (HostNameStr); if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Error: Could not retrieve the host address from DNS server.\n")); + DEBUG ((DEBUG_ERROR, "Error: Could not retrieve the host address from DNS server.\n")); goto Error1; } } @@ -535,7 +545,7 @@ EfiHttpRequest ( ASSERT (HttpInstance->RemoteHost == NULL); HttpInstance->RemotePort = RemotePort; HttpInstance->RemoteHost = HostName; - HostName = NULL; + HostName = NULL; } if (ReConfigure) { @@ -570,8 +580,8 @@ EfiHttpRequest ( goto Error1; } - Wrap->HttpToken = Token; - Wrap->HttpInstance = HttpInstance; + Wrap->HttpToken = Token; + Wrap->HttpInstance = HttpInstance; if (Request != NULL) { Wrap->TcpWrap.Method = Request->Method; } @@ -582,6 +592,7 @@ EfiHttpRequest ( Configure || ReConfigure, TlsConfigure ); + HttpNotify (HttpEventInitSession, Status); if (EFI_ERROR (Status)) { goto Error2; } @@ -600,13 +611,14 @@ EfiHttpRequest ( // Create request message. // FileUrl = Url; - if (Url != NULL && *FileUrl != '/') { + if ((Url != NULL) && (*FileUrl != '/')) { // // Convert the absolute-URI to the absolute-path // while (*FileUrl != ':') { FileUrl++; } + if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) { FileUrl += 3; while (*FileUrl != '/') { @@ -620,7 +632,7 @@ EfiHttpRequest ( Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize); - if (EFI_ERROR (Status) || NULL == RequestMsg) { + if (EFI_ERROR (Status) || (NULL == RequestMsg)) { goto Error3; } @@ -643,7 +655,7 @@ EfiHttpRequest ( Status = HttpTransmitTcp ( HttpInstance, Wrap, - (UINT8*) RequestMsg, + (UINT8 *)RequestMsg, RequestMsgSize ); if (EFI_ERROR (Status)) { @@ -690,6 +702,7 @@ Error2: gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event); Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL; } + if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) { gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event); Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL; @@ -699,15 +712,16 @@ Error1: if (HostName != NULL) { FreePool (HostName); } + if (Wrap != NULL) { FreePool (Wrap); } + if (UrlParser != NULL) { HttpUrlFreeParser (UrlParser); } return Status; - } /** @@ -724,16 +738,16 @@ Error1: EFI_STATUS EFIAPI HttpCancelTokens ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Context + IN NET_MAP *Map, + IN NET_MAP_ITEM *Item, + IN VOID *Context ) { - EFI_HTTP_TOKEN *Token; - HTTP_TOKEN_WRAP *Wrap; - HTTP_PROTOCOL *HttpInstance; + EFI_HTTP_TOKEN *Token; + HTTP_TOKEN_WRAP *Wrap; + HTTP_PROTOCOL *HttpInstance; - Token = (EFI_HTTP_TOKEN *) Context; + Token = (EFI_HTTP_TOKEN *)Context; // // Return EFI_SUCCESS to check the next item in the map if @@ -743,14 +757,14 @@ HttpCancelTokens ( return EFI_SUCCESS; } - Wrap = (HTTP_TOKEN_WRAP *) Item->Value; + Wrap = (HTTP_TOKEN_WRAP *)Item->Value; ASSERT (Wrap != NULL); HttpInstance = Wrap->HttpInstance; if (!HttpInstance->LocalAddressIsIPv6) { if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) { // - // Cancle the Token before close its Event. + // Cancel the Token before close its Event. // HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &Wrap->TcpWrap.Rx4Token.CompletionToken); @@ -762,7 +776,7 @@ HttpCancelTokens ( } else { if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) { // - // Cancle the Token before close its Event. + // Cancel the Token before close its Event. // HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &Wrap->TcpWrap.Rx6Token.CompletionToken); @@ -800,11 +814,11 @@ HttpCancelTokens ( **/ EFI_STATUS HttpCancel ( - IN HTTP_PROTOCOL *HttpInstance, - IN EFI_HTTP_TOKEN *Token + IN HTTP_PROTOCOL *HttpInstance, + IN EFI_HTTP_TOKEN *Token ) { - EFI_STATUS Status; + EFI_STATUS Status; // // First check the tokens queued by EfiHttpRequest(). @@ -847,7 +861,6 @@ HttpCancel ( return EFI_SUCCESS; } - /** Abort an asynchronous HTTP request or response token. @@ -873,11 +886,11 @@ HttpCancel ( EFI_STATUS EFIAPI EfiHttpCancel ( - IN EFI_HTTP_PROTOCOL *This, - IN EFI_HTTP_TOKEN *Token + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token ) { - HTTP_PROTOCOL *HttpInstance; + HTTP_PROTOCOL *HttpInstance; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -890,7 +903,6 @@ EfiHttpCancel ( } return HttpCancel (HttpInstance, Token); - } /** @@ -910,39 +922,37 @@ EfiHttpCancel ( EFI_STATUS EFIAPI HttpBodyParserCallback ( - IN HTTP_BODY_PARSE_EVENT EventType, - IN CHAR8 *Data, - IN UINTN Length, - IN VOID *Context + IN HTTP_BODY_PARSE_EVENT EventType, + IN CHAR8 *Data, + IN UINTN Length, + IN VOID *Context ) { - HTTP_TOKEN_WRAP *Wrap; - UINTN BodyLength; - CHAR8 *Body; + HTTP_CALLBACK_DATA *CallbackData; + HTTP_TOKEN_WRAP *Wrap; + UINTN BodyLength; + CHAR8 *Body; if (EventType != BodyParseEventOnComplete) { return EFI_SUCCESS; } - if (Data == NULL || Length != 0 || Context == NULL) { + if ((Data == NULL) || (Length != 0) || (Context == NULL)) { return EFI_SUCCESS; } - Wrap = (HTTP_TOKEN_WRAP *) Context; - Body = Wrap->HttpToken->Message->Body; - BodyLength = Wrap->HttpToken->Message->BodyLength; + CallbackData = (HTTP_CALLBACK_DATA *)Context; + + Wrap = (HTTP_TOKEN_WRAP *)(CallbackData->Wrap); + Body = CallbackData->ParseData; + BodyLength = CallbackData->ParseDataLength; + if (Data < Body + BodyLength) { Wrap->HttpInstance->NextMsg = Data; } else { Wrap->HttpInstance->NextMsg = NULL; } - - // - // Free Tx4Token or Tx6Token since already received corrsponding HTTP response. - // - FreePool (Wrap); - return EFI_SUCCESS; } @@ -952,41 +962,42 @@ HttpBodyParserCallback ( @param[in] Wrap Pointer to HTTP token's wrap data. @retval EFI_SUCCESS Allocation succeeded. - @retval EFI_OUT_OF_RESOURCES Failed to complete the opration due to lack of resources. + @retval EFI_OUT_OF_RESOURCES Failed to complete the operation due to lack of resources. @retval EFI_NOT_READY Can't find a corresponding Tx4Token/Tx6Token or the EFI_HTTP_UTILITIES_PROTOCOL is not available. **/ EFI_STATUS HttpResponseWorker ( - IN HTTP_TOKEN_WRAP *Wrap + IN HTTP_TOKEN_WRAP *Wrap ) { - EFI_STATUS Status; - EFI_HTTP_MESSAGE *HttpMsg; - CHAR8 *EndofHeader; - CHAR8 *HttpHeaders; - UINTN SizeofHeaders; - UINTN BufferSize; - UINTN StatusCode; - CHAR8 *Tmp; - CHAR8 *HeaderTmp; - CHAR8 *StatusCodeStr; - UINTN BodyLen; - HTTP_PROTOCOL *HttpInstance; - EFI_HTTP_TOKEN *Token; - NET_MAP_ITEM *Item; - HTTP_TOKEN_WRAP *ValueInItem; - UINTN HdrLen; - NET_FRAGMENT Fragment; - - if (Wrap == NULL || Wrap->HttpInstance == NULL) { + EFI_STATUS Status; + EFI_HTTP_MESSAGE *HttpMsg; + CHAR8 *EndofHeader; + CHAR8 *HttpHeaders; + UINTN SizeofHeaders; + UINTN BufferSize; + UINTN StatusCode; + CHAR8 *Tmp; + CHAR8 *HeaderTmp; + CHAR8 *StatusCodeStr; + UINTN BodyLen; + HTTP_PROTOCOL *HttpInstance; + EFI_HTTP_TOKEN *Token; + NET_MAP_ITEM *Item; + HTTP_TOKEN_WRAP *ValueInItem; + UINTN HdrLen; + NET_FRAGMENT Fragment; + UINT32 TimeoutValue; + + if ((Wrap == NULL) || (Wrap->HttpInstance == NULL)) { return EFI_INVALID_PARAMETER; } HttpInstance = Wrap->HttpInstance; - Token = Wrap->HttpToken; - HttpMsg = Token->Message; + Token = Wrap->HttpToken; + HttpMsg = Token->Message; HttpInstance->EndofHeader = NULL; HttpInstance->HttpHeaders = NULL; @@ -1007,7 +1018,7 @@ HttpResponseWorker ( // // The data is stored at [NextMsg, CacheBody + CacheLen]. // - HdrLen = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg; + HdrLen = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg; HttpHeaders = AllocateZeroPool (HdrLen); if (HttpHeaders == NULL) { Status = EFI_OUT_OF_RESOURCES; @@ -1019,8 +1030,8 @@ HttpResponseWorker ( HttpInstance->CacheBody = NULL; HttpInstance->NextMsg = NULL; HttpInstance->CacheOffset = 0; - SizeofHeaders = HdrLen; - BufferSize = HttpInstance->CacheLen; + SizeofHeaders = HdrLen; + BufferSize = HttpInstance->CacheLen; // // Check whether we cached the whole HTTP headers. @@ -1031,7 +1042,6 @@ HttpResponseWorker ( HttpInstance->EndofHeader = &EndofHeader; HttpInstance->HttpHeaders = &HttpHeaders; - if (HttpInstance->TimeoutEvent == NULL) { // // Create TimeoutEvent for response @@ -1048,10 +1058,15 @@ HttpResponseWorker ( } } + // + // Get HTTP timeout value + // + TimeoutValue = PcdGet32 (PcdHttpIoTimeout); + // // Start the timer, and wait Timeout seconds to receive the header packet. // - Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND); + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS); if (EFI_ERROR (Status)) { goto Error; } @@ -1119,9 +1134,9 @@ HttpResponseWorker ( } HttpMsg->Data.Response->StatusCode = HttpMappingToStatusCode (StatusCode); - HttpInstance->StatusCode = StatusCode; + HttpInstance->StatusCode = StatusCode; - Status = EFI_NOT_READY; + Status = EFI_NOT_READY; ValueInItem = NULL; // @@ -1132,8 +1147,8 @@ HttpResponseWorker ( // Hence, check that case before doing a NetMapRemoveHead. // if (!NetMapIsEmpty (&HttpInstance->TxTokens)) { - NetMapRemoveHead (&HttpInstance->TxTokens, (VOID**) &ValueInItem); - if (ValueInItem == NULL) { + NetMapRemoveHead (&HttpInstance->TxTokens, (VOID **)&ValueInItem); + if (ValueInItem == NULL) { goto Error; } @@ -1181,7 +1196,6 @@ HttpResponseWorker ( FreePool (HttpHeaders); HttpHeaders = NULL; - // // Init message-body parser by header information. // @@ -1191,7 +1205,7 @@ HttpResponseWorker ( HttpMsg->HeaderCount, HttpMsg->Headers, HttpBodyParserCallback, - (VOID *) ValueInItem, + (VOID *)(&HttpInstance->CallbackData), &HttpInstance->MsgParser ); if (EFI_ERROR (Status)) { @@ -1202,18 +1216,28 @@ HttpResponseWorker ( // Check whether we received a complete HTTP message. // if (HttpInstance->CacheBody != NULL) { + // + // Record the CallbackData data. + // + HttpInstance->CallbackData.Wrap = (VOID *)Wrap; + HttpInstance->CallbackData.ParseData = (VOID *)HttpInstance->CacheBody; + HttpInstance->CallbackData.ParseDataLength = HttpInstance->CacheLen; + + // + // Parse message with CallbackData data. + // Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody); if (EFI_ERROR (Status)) { goto Error2; } + } - if (HttpIsMessageComplete (HttpInstance->MsgParser)) { - // - // Free the MsgParse since we already have a full HTTP message. - // - HttpFreeMsgParser (HttpInstance->MsgParser); - HttpInstance->MsgParser = NULL; - } + if (HttpIsMessageComplete (HttpInstance->MsgParser)) { + // + // Free the MsgParse since we already have a full HTTP message. + // + HttpFreeMsgParser (HttpInstance->MsgParser); + HttpInstance->MsgParser = NULL; } } @@ -1257,7 +1281,7 @@ HttpResponseWorker ( // CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, BodyLen); HttpInstance->CacheOffset = BodyLen + HttpInstance->CacheOffset; - HttpMsg->BodyLength = BodyLen; + HttpMsg->BodyLength = BodyLen; if (HttpInstance->NextMsg == NULL) { // @@ -1269,19 +1293,20 @@ HttpResponseWorker ( HttpInstance->CacheOffset = 0; } } + // - // Return since we aready received required data. + // Return since we already received required data. // Status = EFI_SUCCESS; goto Exit; } - if (BodyLen == 0 && HttpInstance->MsgParser == NULL) { + if ((BodyLen == 0) && (HttpInstance->MsgParser == NULL)) { // // We received a complete HTTP message, and we don't have more data to return to caller. // HttpMsg->BodyLength = 0; - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; goto Exit; } } @@ -1297,7 +1322,6 @@ HttpResponseWorker ( if (EFI_ERROR (Status)) { goto Error2; } - } else { if (HttpInstance->TimeoutEvent == NULL) { // @@ -1315,10 +1339,15 @@ HttpResponseWorker ( } } + // + // Get HTTP timeout value + // + TimeoutValue = PcdGet32 (PcdHttpIoTimeout); + // // Start the timer, and wait Timeout seconds to receive the body packet. // - Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND); + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS); if (EFI_ERROR (Status)) { goto Error2; } @@ -1332,12 +1361,26 @@ HttpResponseWorker ( } // - // Check whether we receive a complete HTTP message. + // Process the received the body packet. + // + HttpMsg->BodyLength = MIN ((UINTN)Fragment.Len, HttpMsg->BodyLength); + + CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength); + + // + // Record the CallbackData data. + // + HttpInstance->CallbackData.Wrap = (VOID *)Wrap; + HttpInstance->CallbackData.ParseData = HttpMsg->Body; + HttpInstance->CallbackData.ParseDataLength = HttpMsg->BodyLength; + + // + // Parse Body with CallbackData data. // Status = HttpParseMessageBody ( HttpInstance->MsgParser, - (UINTN) Fragment.Len, - (CHAR8 *) Fragment.Bulk + HttpMsg->BodyLength, + HttpMsg->Body ); if (EFI_ERROR (Status)) { goto Error2; @@ -1352,46 +1395,28 @@ HttpResponseWorker ( } // - // We receive part of header of next HTTP msg. + // Check whether there is the next message header in the HttpMsg->Body. // if (HttpInstance->NextMsg != NULL) { - HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength); - CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength); - - HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength; - if (HttpInstance->CacheLen != 0) { - if (HttpInstance->CacheBody != NULL) { - FreePool (HttpInstance->CacheBody); - } - - HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen); - if (HttpInstance->CacheBody == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error2; - } - - CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen); - HttpInstance->CacheOffset = 0; + HttpMsg->BodyLength = HttpInstance->NextMsg - (CHAR8 *)HttpMsg->Body; + } - HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength)); + HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength; + if (HttpInstance->CacheLen != 0) { + if (HttpInstance->CacheBody != NULL) { + FreePool (HttpInstance->CacheBody); } - } else { - HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength); - CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength); - HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength; - if (HttpInstance->CacheLen != 0) { - if (HttpInstance->CacheBody != NULL) { - FreePool (HttpInstance->CacheBody); - } - HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen); - if (HttpInstance->CacheBody == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error2; - } + HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen); + if (HttpInstance->CacheBody == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error2; + } - CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen); - HttpInstance->CacheOffset = 0; + CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen); + HttpInstance->CacheOffset = 0; + if (HttpInstance->NextMsg != NULL) { + HttpInstance->NextMsg = HttpInstance->CacheBody; } } @@ -1468,10 +1493,8 @@ Error: gBS->SignalEvent (Token->Event); return Status; - } - /** The Response() function queues an HTTP response to this HTTP instance, similar to Receive() function in the EFI TCP driver. When the HTTP response is received successfully, @@ -1522,14 +1545,14 @@ Error: EFI_STATUS EFIAPI EfiHttpResponse ( - IN EFI_HTTP_PROTOCOL *This, - IN EFI_HTTP_TOKEN *Token + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token ) { - EFI_STATUS Status; - EFI_HTTP_MESSAGE *HttpMsg; - HTTP_PROTOCOL *HttpInstance; - HTTP_TOKEN_WRAP *Wrap; + EFI_STATUS Status; + EFI_HTTP_MESSAGE *HttpMsg; + HTTP_PROTOCOL *HttpInstance; + HTTP_TOKEN_WRAP *Wrap; if ((This == NULL) || (Token == NULL)) { return EFI_INVALID_PARAMETER; @@ -1596,6 +1619,7 @@ Error: if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) { gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event); } + FreePool (Wrap); } @@ -1625,11 +1649,11 @@ Error: EFI_STATUS EFIAPI EfiHttpPoll ( - IN EFI_HTTP_PROTOCOL *This + IN EFI_HTTP_PROTOCOL *This ) { - EFI_STATUS Status; - HTTP_PROTOCOL *HttpInstance; + EFI_STATUS Status; + HTTP_PROTOCOL *HttpInstance; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -1645,11 +1669,13 @@ EfiHttpPoll ( if (HttpInstance->Tcp6 == NULL) { return EFI_NOT_STARTED; } + Status = HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); } else { if (HttpInstance->Tcp4 == NULL) { return EFI_NOT_STARTED; } + Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); }