From: "Saloni Kasbekar" <saloni.kasbekar@intel.com>
To: devel@edk2.groups.io
Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>,
Maciej Rabeda <maciej.rabeda@linux.intel.com>,
Wu Jiaxin <jiaxin.wu@intel.com>, Siyuan Fu <siyuan.fu@intel.com>
Subject: [edk2-staging/HttpProxy PATCH v3 3/7] NetworkPkg/HttpBootDxe: Update HTTP Boot Driver with parsed Proxy URL
Date: Fri, 2 Dec 2022 11:12:22 -0800 [thread overview]
Message-ID: <40249646b0fd9e44940b3a001589c1d22e53e076.1670008048.git.saloni.kasbekar@intel.com> (raw)
In-Reply-To: <cover.1670008048.git.saloni.kasbekar@intel.com>
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.rabeda@linux.intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar@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
next prev parent reply other threads:[~2022-12-02 19:12 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-02 19:12 [edk2-staging/HttpProxy PATCH v3 0/7] Support HTTPS Proxy Server for HTTP Boot Saloni Kasbekar
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 1/7] MdeModulePkg/Library: Support multi-URI HTTP Boot device path Saloni Kasbekar
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 2/7] MdePkg/Include: Add Proxy Server URL in EFI_HTTP_REQUEST_DATA Saloni Kasbekar
2022-12-02 19:12 ` Saloni Kasbekar [this message]
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 4/7] NetworkPkg: Add Proxy Support to HTTP_PROTOCOL Saloni Kasbekar
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 5/7] NetworkPkg: Add support for HTTP CONNECT Method Saloni Kasbekar
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 6/7] NetworkPkg/HttpDxe: Support HTTPS EndPoint server with Proxy Saloni Kasbekar
2022-12-02 19:12 ` [edk2-staging/HttpProxy PATCH v3 7/7] NetworkPkg/HttpBootDxe: Add Proxy URI input in setup menu Saloni Kasbekar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=40249646b0fd9e44940b3a001589c1d22e53e076.1670008048.git.saloni.kasbekar@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox