diff options
author | Saloni Kasbekar <saloni.kasbekar@intel.com> | 2022-12-16 19:06:53 +0100 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-03-13 00:34:01 +0000 |
commit | 80c04eb46fc97f303a50172eaa7095bdcd7e6559 (patch) | |
tree | 579188616e615009b0ef8ee933f92815b0cfb8da | |
parent | 884585818ff016d44bb8ddd2f58001cec3a8f24e (diff) | |
download | edk2-80c04eb46fc97f303a50172eaa7095bdcd7e6559.zip edk2-80c04eb46fc97f303a50172eaa7095bdcd7e6559.tar.gz edk2-80c04eb46fc97f303a50172eaa7095bdcd7e6559.tar.bz2 |
NetworkPkg/HttpBootDxe: Add proxy connect flow to *GetBootFile()
- Add HTTP CONNECT flow to connect to Proxy Server
- Provide Proxy URL to HTTP GET/HEAD Requests
Implementation based on UEFI Specification v2.11
- Section 24.7.10 to use HTTP CONNECT method to connect to Proxy
Server and use it to forward the HEAD/GET request to Endpoint Server's
BootURI.
- Section 29.6.6 to use EFI_HTTP_CONNECT_REQUEST_DATA structure for
HttpMethodConnect usage in EFI_HTTP_PROTOCOL.Request()
Signed-off-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootClient.c | 253 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootClient.h | 15 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootImpl.c | 16 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootImpl.h | 1 |
4 files changed, 251 insertions, 34 deletions
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 858e7c2..5ee90c2 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -664,52 +664,63 @@ HttpBootFreeCache ( IN HTTP_BOOT_CACHE_CONTENT *Cache
)
{
- UINTN Index;
- LIST_ENTRY *Entry;
- LIST_ENTRY *NextEntry;
- HTTP_BOOT_ENTITY_DATA *EntityData;
+ UINTN Index;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *NextEntry;
+ HTTP_BOOT_ENTITY_DATA *EntityData;
+ EFI_HTTP_CONNECT_REQUEST_DATA *ConnRequestData;
- if (Cache != NULL) {
- //
- // Free the request data
- //
- if (Cache->RequestData != NULL) {
- if (Cache->RequestData->Url != NULL) {
- FreePool (Cache->RequestData->Url);
- }
+ if (Cache == NULL) {
+ return;
+ }
- FreePool (Cache->RequestData);
+ //
+ // Free the request data
+ //
+ if (Cache->RequestData != NULL) {
+ if (Cache->RequestData->Url != NULL) {
+ FreePool (Cache->RequestData->Url);
}
- //
- // Free the response header
- //
- if (Cache->ResponseData != NULL) {
- if (Cache->ResponseData->Headers != NULL) {
- for (Index = 0; Index < Cache->ResponseData->HeaderCount; Index++) {
- FreePool (Cache->ResponseData->Headers[Index].FieldName);
- FreePool (Cache->ResponseData->Headers[Index].FieldValue);
- }
+ if (Cache->RequestData->Method == HttpMethodConnect) {
+ ConnRequestData = (EFI_HTTP_CONNECT_REQUEST_DATA *)Cache->RequestData;
- FreePool (Cache->ResponseData->Headers);
+ if (ConnRequestData->ProxyUrl != NULL) {
+ FreePool (ConnRequestData->ProxyUrl);
}
}
- //
- // Free the response body
- //
- NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Cache->EntityDataList) {
- EntityData = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_ENTITY_DATA, Link);
- if (EntityData->Block != NULL) {
- FreePool (EntityData->Block);
+ FreePool (Cache->RequestData);
+ }
+
+ //
+ // Free the response header
+ //
+ if (Cache->ResponseData != NULL) {
+ if (Cache->ResponseData->Headers != NULL) {
+ for (Index = 0; Index < Cache->ResponseData->HeaderCount; Index++) {
+ FreePool (Cache->ResponseData->Headers[Index].FieldName);
+ FreePool (Cache->ResponseData->Headers[Index].FieldValue);
}
- RemoveEntryList (&EntityData->Link);
- FreePool (EntityData);
+ FreePool (Cache->ResponseData->Headers);
}
+ }
- FreePool (Cache);
+ //
+ // Free the response body
+ //
+ NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Cache->EntityDataList) {
+ EntityData = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_ENTITY_DATA, Link);
+ if (EntityData->Block != NULL) {
+ FreePool (EntityData->Block);
+ }
+
+ RemoveEntryList (&EntityData->Link);
+ FreePool (EntityData);
}
+
+ FreePool (Cache);
}
/**
@@ -902,6 +913,182 @@ HttpBootGetBootFileCallback ( }
/**
+ This function establishes a connection through a proxy server
+
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS Connection successful.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+HttpBootConnectProxy (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_HTTP_STATUS_CODE StatusCode;
+ CHAR8 *HostName;
+ EFI_HTTP_CONNECT_REQUEST_DATA *RequestData;
+ HTTP_IO_RESPONSE_DATA *ResponseData;
+ HTTP_IO *HttpIo;
+ HTTP_IO_HEADER *HttpIoHeader;
+ CHAR16 *Url;
+ CHAR16 *ProxyUrl;
+ UINTN UrlSize;
+
+ Url = NULL;
+ ProxyUrl = NULL;
+ RequestData = NULL;
+ ResponseData = NULL;
+ HttpIoHeader = NULL;
+
+ UrlSize = AsciiStrSize (Private->BootFileUri);
+ Url = AllocatePool (UrlSize * sizeof (CHAR16));
+ if (Url == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);
+
+ UrlSize = AsciiStrSize (Private->ProxyUri);
+ ProxyUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
+ if (ProxyUrl == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ AsciiStrToUnicodeStrS (Private->ProxyUri, ProxyUrl, UrlSize);
+
+ //
+ // Send HTTP request message.
+ //
+
+ //
+ // Build HTTP header for the request, 2 headers are needed to send a CONNECT method:
+ // Host
+ // User
+ //
+ HttpIoHeader = HttpIoCreateHeader (2);
+ if (HttpIoHeader == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ //
+ // Add HTTP header field 1: Host (EndPoint URI)
+ //
+ HostName = NULL;
+ Status = HttpUrlGetHostName (
+ Private->BootFileUri,
+ Private->BootFileUriParser,
+ &HostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ Status = HttpIoSetHeader (
+ HttpIoHeader,
+ HTTP_HEADER_HOST,
+ HostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ //
+ // Add HTTP header field 2: User-Agent
+ //
+ Status = HttpIoSetHeader (
+ HttpIoHeader,
+ HTTP_HEADER_USER_AGENT,
+ HTTP_USER_AGENT_EFI_HTTP_BOOT
+ );
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ //
+ // Build the rest of HTTP request info.
+ //
+ RequestData = AllocatePool (sizeof (EFI_HTTP_CONNECT_REQUEST_DATA));
+ if (RequestData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ RequestData->Base.Method = HttpMethodConnect;
+ RequestData->Base.Url = Url;
+ RequestData->ProxyUrl = ProxyUrl;
+
+ //
+ // Send out the request to HTTP server.
+ //
+ HttpIo = &Private->HttpIo;
+ Status = HttpIoSendRequest (
+ HttpIo,
+ &RequestData->Base,
+ HttpIoHeader->HeaderCount,
+ HttpIoHeader->Headers,
+ 0,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ //
+ // Receive HTTP response message.
+ //
+
+ //
+ // Use zero BodyLength to only receive the response headers.
+ //
+ ResponseData = AllocateZeroPool (sizeof (HTTP_IO_RESPONSE_DATA));
+ if (ResponseData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ Status = HttpIoRecvResponse (
+ &Private->HttpIo,
+ TRUE,
+ ResponseData
+ );
+
+ if (EFI_ERROR (Status) || EFI_ERROR (ResponseData->Status)) {
+ if (EFI_ERROR (ResponseData->Status)) {
+ StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode;
+ HttpBootPrintErrorMessage (StatusCode);
+ Status = ResponseData->Status;
+ }
+ }
+
+EXIT:
+ if (ResponseData != NULL) {
+ FreePool (ResponseData);
+ }
+
+ if (RequestData != NULL) {
+ FreePool (RequestData);
+ }
+
+ HttpIoFreeHeader (HttpIoHeader);
+
+ if (ProxyUrl != NULL) {
+ FreePool (ProxyUrl);
+ }
+
+ if (Url != NULL) {
+ FreePool (Url);
+ }
+
+ return Status;
+}
+
+/**
This function download the boot file by using UEFI HTTP protocol.
@param[in] Private The pointer to the driver's private data.
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h index 406eefb..0eceda0 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.h +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h @@ -87,6 +87,21 @@ HttpBootCreateHttpIo ( );
/**
+ This function establishes a connection through a proxy server
+
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS Connection successful.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+HttpBootConnectProxy (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+
+/**
This function download the boot file by using UEFI HTTP protocol.
@param[in] Private The pointer to the driver's private data.
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index d56a2a7..dcc2707 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -319,7 +319,11 @@ HttpBootGetBootFileCaller ( UINT32 Retries;
if (Private->BootFileSize == 0) {
- State = GetBootFileHead;
+ if (Private->ProxyUri != NULL) {
+ State = ConnectToProxy;
+ } else {
+ State = GetBootFileHead;
+ }
} else {
State = LoadBootFile;
}
@@ -372,6 +376,16 @@ HttpBootGetBootFileCaller ( break;
+ case ConnectToProxy:
+ Status = HttpBootConnectProxy (Private);
+ if (Status == EFI_SUCCESS) {
+ State = GetBootFileHead;
+ } else {
+ State = GetBootFileError;
+ }
+
+ break;
+
case LoadBootFile:
if (*BufferSize < Private->BootFileSize) {
*BufferSize = Private->BootFileSize;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h index 33da4fe..e4ffc3e 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h @@ -14,6 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent typedef enum {
GetBootFileHead,
GetBootFileGet,
+ ConnectToProxy,
LoadBootFile,
GetBootFileError
} HTTP_GET_BOOT_FILE_STATE;
|