REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3951
Add ProxyUri to HTTP_BOOT_PRIVATE_DATA Parse HTTP Boot Device path to process Proxy and EndPoint URLs Cc: Maciej Rabeda <maciej.rab...@linux.intel.com> Cc: Wu Jiaxin <jiaxin...@intel.com> Cc: Siyuan Fu <siyuan...@intel.com> Signed-off-by: Saloni Kasbekar <saloni.kasbe...@intel.com> --- NetworkPkg/HttpBootDxe/HttpBootClient.c | 30 ++++- NetworkPkg/HttpBootDxe/HttpBootDxe.h | 6 + NetworkPkg/HttpBootDxe/HttpBootImpl.c | 57 +++++---- NetworkPkg/HttpBootDxe/HttpBootSupport.c | 154 +++++++++++++++++------ NetworkPkg/HttpBootDxe/HttpBootSupport.h | 13 +- 5 files changed, 189 insertions(+), 71 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 40f64fcb6b..b13155b576 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -678,6 +678,10 @@ HttpBootFreeCache ( FreePool (Cache->RequestData->Url); } + if (Cache->RequestData->ProxyUrl != NULL) { + FreePool (Cache->RequestData->ProxyUrl); + } + FreePool (Cache->RequestData); } @@ -950,6 +954,7 @@ HttpBootGetBootFile ( UINT8 *Block; UINTN UrlSize; CHAR16 *Url; + CHAR16 *ProxyUrl; BOOLEAN IdentityMode; UINTN ReceivedSize; CHAR8 BaseAuthValue[80]; @@ -989,6 +994,22 @@ HttpBootGetBootFile ( // Not found in cache, try to download it through HTTP. // + // + // Initialize ProxyUrl - Set to NULL if connecting without Proxy + // + if (Private->ProxyUri != NULL) { + UrlSize = AsciiStrSize (Private->ProxyUri); + ProxyUrl = AllocatePool (UrlSize * (sizeof (CHAR16))); + if (ProxyUrl == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR_1; + } + + AsciiStrToUnicodeStrS (Private->ProxyUri, ProxyUrl, UrlSize); + } else { + ProxyUrl = NULL; + } + // // 1. Create a temp cache item for the requested URI if caller doesn't provide buffer. // @@ -1106,8 +1127,9 @@ HttpBootGetBootFile ( goto ERROR_3; } - RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet; - RequestData->Url = Url; + RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet; + RequestData->Url = Url; + RequestData->ProxyUrl = ProxyUrl; // // 2.3 Record the request info in a temp cache item. @@ -1441,6 +1463,10 @@ ERROR_2: } ERROR_1: + if (ProxyUrl != NULL) { + FreePool (ProxyUrl); + } + if (Url != NULL) { FreePool (Url); } diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h index 5ff8ad4698..8caf2e9a45 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -223,6 +223,12 @@ struct _HTTP_BOOT_PRIVATE_DATA { CHAR8 *FilePathUri; VOID *FilePathUriParser; + // + // URI string for the Proxy host if BootFileUri contains a Proxy + // URI in the path + // + CHAR8 *ProxyUri; + // // Cached HTTP data // diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index b4c61925b9..5735b96d9e 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -115,19 +115,21 @@ HttpBootStart ( { UINTN Index; EFI_STATUS Status; - CHAR8 *Uri; + CHAR8 *ProxyUri; + CHAR8 *EndPointUri; - Uri = NULL; + ProxyUri = NULL; + EndPointUri = NULL; if ((Private == NULL) || (FilePath == NULL)) { return EFI_INVALID_PARAMETER; } // - // Check the URI in the input FilePath, in order to see whether it is + // Check the URIs in the input FilePath, in order to see whether it is // required to boot from a new specified boot file. // - Status = HttpBootParseFilePath (FilePath, &Uri); + Status = HttpBootParseFilePath (FilePath, &ProxyUri, &EndPointUri); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } @@ -143,28 +145,21 @@ HttpBootStart ( // recorded before. // if ((UsingIpv6 != Private->UsingIpv6) || - ((Uri != NULL) && (AsciiStrCmp (Private->BootFileUri, Uri) != 0))) + ((EndPointUri != NULL) && (AsciiStrCmp (Private->BootFileUri, EndPointUri) != 0))) { // // Restart is required, first stop then continue this start function. // Status = HttpBootStop (Private); if (EFI_ERROR (Status)) { - if (Uri != NULL) { - FreePool (Uri); - } - - return Status; + goto ERROR; } } else { // // Restart is not required. // - if (Uri != NULL) { - FreePool (Uri); - } - - return EFI_ALREADY_STARTED; + Status = EFI_ALREADY_STARTED; + goto ERROR; } } @@ -176,17 +171,16 @@ HttpBootStart ( } else if (!UsingIpv6 && (Private->Ip4Nic != NULL)) { Private->UsingIpv6 = FALSE; } else { - if (Uri != NULL) { - FreePool (Uri); - } - - return EFI_UNSUPPORTED; + Status = EFI_UNSUPPORTED; + goto ERROR; } // - // Record the specified URI and prepare the URI parser if needed. + // Record the specified URIs and prepare the URI parser if needed. // - Private->FilePathUri = Uri; + Private->ProxyUri = ProxyUri; + Private->FilePathUri = EndPointUri; + if (Private->FilePathUri != NULL) { Status = HttpParseUrl ( Private->FilePathUri, @@ -195,8 +189,7 @@ HttpBootStart ( &Private->FilePathUriParser ); if (EFI_ERROR (Status)) { - FreePool (Private->FilePathUri); - return Status; + goto ERROR; } } @@ -228,6 +221,17 @@ HttpBootStart ( Print (L"\n>>Start HTTP Boot over IPv%d", Private->UsingIpv6 ? 6 : 4); return EFI_SUCCESS; + +ERROR: + if (ProxyUri != NULL) { + FreePool (ProxyUri); + } + + if (EndPointUri != NULL) { + FreePool (EndPointUri); + } + + return Status; } /** @@ -522,6 +526,11 @@ HttpBootStop ( Private->FilePathUriParser = NULL; } + if (Private->ProxyUri != NULL) { + FreePool (Private->ProxyUri); + Private->ProxyUri = NULL; + } + ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer)); Private->OfferNum = 0; ZeroMem (Private->OfferCount, sizeof (Private->OfferCount)); diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c index 236ef25931..9af6cf0c69 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -551,71 +551,145 @@ HttpBootCheckUriScheme ( return Status; } +/** + Get the URI address string from the URI device path node. + + Caller need to free the buffer in the Uri pointer. + + @param[in] Node Pointer to the URI device path node. + @param[out] Uri URI string extracted from the device path. + + @retval EFI_SUCCESS The URI string is returned. + @retval EFI_INVALID_PARAMETER Parameters are NULL or invalid URI node. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + +**/ +EFI_STATUS +HttpBootUriFromDevicePath ( + IN URI_DEVICE_PATH *Node, + OUT CHAR8 **Uri + ) +{ + UINTN UriStrLength; + + if ((Node == NULL) || (Uri == NULL)) { + return EFI_INVALID_PARAMETER; + } + + UriStrLength = DevicePathNodeLength (Node) - sizeof (EFI_DEVICE_PATH_PROTOCOL); + + if (UriStrLength == 0) { + // Invalid URI, return. + return EFI_INVALID_PARAMETER; + } + + *Uri = AllocatePool (UriStrLength + 1); + if (*Uri == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (*Uri, Node->Uri, UriStrLength); + (*Uri)[UriStrLength] = '\0'; + + return EFI_SUCCESS; +} + /** Get the URI address string from the input device path. - Caller need to free the buffer in the UriAddress pointer. + Caller needs to free the buffers returned by this function. - @param[in] FilePath Pointer to the device path which contains a URI device path node. - @param[out] UriAddress The URI address string extract from the device path. + @param[in] FilePath Pointer to the device path which contains a URI device path node. + @param[out] ProxyUriAddress The proxy URI address string extract from the device path (if it exists) + @param[out] EndPointUriAddress The endpoint URI address string for the endpoint host. @retval EFI_SUCCESS The URI string is returned. + @retval EFI_INVALID_PARAMETER Parameters are NULL or device path is invalid. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. **/ EFI_STATUS HttpBootParseFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - OUT CHAR8 **UriAddress + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + OUT CHAR8 **ProxyUriAddress, + OUT CHAR8 **EndPointUriAddress ) { - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - URI_DEVICE_PATH *UriDevicePath; - CHAR8 *Uri; - UINTN UriStrLength; - - if (FilePath == NULL) { + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *Node[2]; + EFI_DEVICE_PATH_PROTOCOL *TempNode; + BOOLEAN NodeIsUri[2]; + UINTN Index; + + if ((FilePath == NULL) || + (ProxyUriAddress == NULL) || + (EndPointUriAddress == NULL)) + { return EFI_INVALID_PARAMETER; } - *UriAddress = NULL; + *ProxyUriAddress = NULL; + *EndPointUriAddress = NULL; + ZeroMem (Node, sizeof (Node)); + // Obtain last 2 device path nodes. + // Looking for sequences: + // 1) //....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(ProxyServer)/Uri(EndPointServer/FilePath) + // 2) //....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(EndPointServer/FilePath) // - // Extract the URI address from the FilePath - // - TempDevicePath = FilePath; - while (!IsDevicePathEnd (TempDevicePath)) { - if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (TempDevicePath) == MSG_URI_DP)) - { - UriDevicePath = (URI_DEVICE_PATH *)TempDevicePath; - // - // UEFI Spec doesn't require the URI to be a NULL-terminated string - // So we allocate a new buffer and always append a '\0' to it. - // - UriStrLength = DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); - if (UriStrLength == 0) { - // - // return a NULL UriAddress if it's a empty URI device path node. - // - break; - } - - Uri = AllocatePool (UriStrLength + 1); - if (Uri == NULL) { - return EFI_OUT_OF_RESOURCES; - } + // Expected: + // Node[1] - Uri(EndPointServer/FilePath) + // Node[0] - Either Uri(EndPointServer/FilePath) or other. + TempNode = FilePath; + + while (!IsDevicePathEnd (TempNode)) { + Node[0] = Node[1]; + Node[1] = TempNode; + TempNode = NextDevicePathNode (TempNode); + } + + // Verify if device path nodes are of type MESSAGING + URI. + for (Index = 0; Index < 2; Index++) { + if (Node[Index] == NULL) { + NodeIsUri[Index] = FALSE; + } else { + NodeIsUri[Index] = ((DevicePathType (Node[Index]) == MESSAGING_DEVICE_PATH) && + (DevicePathSubType (Node[Index]) == MSG_URI_DP)); + } + } - CopyMem (Uri, UriDevicePath->Uri, DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL)); - Uri[DevicePathNodeLength (UriDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL)] = '\0'; + // If exists, obtain endpoint URI string. + if (NodeIsUri[1]) { + Status = HttpBootUriFromDevicePath ( + (URI_DEVICE_PATH *)Node[1], + EndPointUriAddress + ); - *UriAddress = Uri; + if (EFI_ERROR (Status)) { + return Status; } - TempDevicePath = NextDevicePathNode (TempDevicePath); + // If exists, obtain proxy URI string. + if (NodeIsUri[0]) { + Status = HttpBootUriFromDevicePath ( + (URI_DEVICE_PATH *)Node[0], + ProxyUriAddress + ); + + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + } } return EFI_SUCCESS; + +ErrorExit: + ASSERT (*EndPointUriAddress != NULL); + FreePool (*EndPointUriAddress); + *EndPointUriAddress = NULL; + + return Status; } /** diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h index 3698e55936..5a46894517 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h @@ -136,19 +136,22 @@ HttpBootCheckUriScheme ( /** Get the URI address string from the input device path. - Caller need to free the buffer in the UriAddress pointer. + Caller needs to free the buffers returned by this function. - @param[in] FilePath Pointer to the device path which contains a URI device path node. - @param[out] UriAddress The URI address string extract from the device path. + @param[in] FilePath Pointer to the device path which contains a URI device path node. + @param[out] ProxyUriAddress The proxy URI address string extract from the device path (if it exists) + @param[out] EndPointUriAddress The endpoint URI address string for the endpoint host. @retval EFI_SUCCESS The URI string is returned. + @retval EFI_INVALID_PARAMETER Parameters are NULL or device path is invalid. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. **/ EFI_STATUS HttpBootParseFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - OUT CHAR8 **UriAddress + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + OUT CHAR8 **ProxyUriAddress, + OUT CHAR8 **EndPointUriAddress ); /** -- 2.36.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94817): https://edk2.groups.io/g/devel/message/94817 Mute This Topic: https://groups.io/mt/94189616/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-