public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot
@ 2022-06-22 22:54 Saloni Kasbekar
  2022-07-01 14:04 ` Maciej Rabeda
  0 siblings, 1 reply; 3+ messages in thread
From: Saloni Kasbekar @ 2022-06-22 22:54 UTC (permalink / raw)
  To: devel
  Cc: Saloni Kasbekar, Maciej Rabeda, Wu Jiaxin, Siyuan Fu, Jian J Wang,
	Liming Gao

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3951

Add CONNECT HTTP command in order to create a tunnel from HTTPS
Proxy Server to EndPoint Server.
Add support to connect through proxy server using DevicePath
sent to the Boot Manager.

Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
---
 .../Library/UefiBootManagerLib/BmBoot.c       |  11 ++
 MdePkg/Include/Protocol/Http.h                |   5 +
 NetworkPkg/HttpBootDxe/HttpBootClient.c       | 168 +++++++++++++++++-
 NetworkPkg/HttpBootDxe/HttpBootClient.h       |  16 ++
 NetworkPkg/HttpBootDxe/HttpBootDxe.h          |   6 +
 NetworkPkg/HttpBootDxe/HttpBootImpl.c         |  46 +++--
 NetworkPkg/HttpBootDxe/HttpBootSupport.c      |  13 +-
 NetworkPkg/HttpBootDxe/HttpBootSupport.h      |   8 +-
 NetworkPkg/HttpDxe/HttpImpl.c                 |  21 ++-
 NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c    |   5 +
 10 files changed, 273 insertions(+), 26 deletions(-)

diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
index 962892d38f14..c5f09b619a89 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
@@ -1513,7 +1513,9 @@ BmExpandLoadFiles (
   UINTN                     HandleCount;
   UINTN                     Index;
   EFI_DEVICE_PATH_PROTOCOL  *Node;
+  URI_DEVICE_PATH           *NullUriPath;
 
+  NullUriPath = NULL;
   //
   // Get file buffer from load file instance.
   //
@@ -1543,10 +1545,19 @@ BmExpandLoadFiles (
       HandleCount = 0;
     }
 
+    NullUriPath = (URI_DEVICE_PATH *)CreateDeviceNode (
+                                       MESSAGING_DEVICE_PATH,
+                                       MSG_URI_DP,
+                                       (UINT16)(sizeof (URI_DEVICE_PATH))
+                                       );
+
     for (Index = 0; Index < HandleCount; Index++) {
       if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) {
         Handle = Handles[Index];
         break;
+      } else if (BmMatchHttpBootDevicePath (AppendDevicePathNode (DevicePathFromHandle (Handles[Index]), (EFI_DEVICE_PATH_PROTOCOL *)NullUriPath), FilePath)) {
+        Handle = Handles[Index];
+        break;
       }
     }
 
diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h
index 28e622159392..4cf8fa4c0c97 100644
--- a/MdePkg/Include/Protocol/Http.h
+++ b/MdePkg/Include/Protocol/Http.h
@@ -191,6 +191,11 @@ typedef struct {
   /// is assumed. See RFC 3986 for more details on URI syntax.
   ///
   CHAR16             *Url;
+  ///
+  /// The URI of an endpoint host if the Url field contains the address of a proxy server.
+  /// This field will be NULL if a proxy server is not involved.
+  ///
+  CHAR16             *EndPointUrl;
 } EFI_HTTP_REQUEST_DATA;
 
 ///
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c
index 62e87238fef7..2a4608414bd9 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c
@@ -901,6 +901,168 @@ HttpBootGetBootFileCallback (
   return EFI_SUCCESS;
 }
 
+/**
+  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_REQUEST_DATA  *RequestData;
+  HTTP_IO_RESPONSE_DATA  *ResponseData;
+  HTTP_IO                *HttpIo;
+  HTTP_IO_HEADER         *HttpIoHeader;
+  CHAR16                 *Url;
+  CHAR16                 *EndPointUrl;
+  UINTN                  UrlSize;
+
+  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->EndPointUri);
+  EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
+  if (EndPointUrl == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (EndPointUrl, Private->EndPointUri, UrlSize);
+
+  //
+  // 2. Send HTTP request message.
+  //
+
+  //
+  // 2.1 Build HTTP header for the request, 2 header is needed to send a CONNECT method:
+  //       Host
+  //       User
+  //
+  HttpIoHeader = HttpIoCreateHeader (2);
+  if (HttpIoHeader == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR_3;
+  }
+
+  //
+  // Add HTTP header field 1: Host (proxy)
+  //
+  HostName = Private->EndPointUri;
+  Status   = HttpIoSetHeader (
+               HttpIoHeader,
+               HTTP_HEADER_HOST,
+               HostName
+               );
+  if (EFI_ERROR (Status)) {
+    goto ERROR_3;
+  }
+
+  //
+  // 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 ERROR_3;
+  }
+
+  //
+  // 2.2 Build the rest of HTTP request info.
+  //
+  RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
+  if (RequestData == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR_3;
+  }
+
+  RequestData->Method      = HttpMethodConnect;
+  RequestData->Url         = Url;
+  RequestData->EndPointUrl = EndPointUrl;
+
+  //
+  // 2.4 Send out the request to HTTP server.
+  //
+  HttpIo = &Private->HttpIo;
+  Status = HttpIoSendRequest (
+             HttpIo,
+             RequestData,
+             HttpIoHeader->HeaderCount,
+             HttpIoHeader->Headers,
+             0,
+             NULL
+             );
+  if (EFI_ERROR (Status)) {
+    goto ERROR_4;
+  }
+
+  //
+  // 3. Receive HTTP response message.
+  //
+
+  //
+  // 3.1 First step, 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 ERROR_4;
+  }
+
+  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;
+    }
+
+    goto ERROR_5;
+  }
+
+  return Status;
+
+ERROR_5:
+  if (ResponseData != NULL) {
+    FreePool (ResponseData);
+  }
+
+ERROR_4:
+  if (RequestData != NULL) {
+    FreePool (RequestData);
+  }
+
+ERROR_3:
+  HttpIoFreeHeader (HttpIoHeader);
+
+  if (Url != NULL) {
+    FreePool (Url);
+  }
+
+  return Status;
+}
+
 /**
   This function download the boot file by using UEFI HTTP protocol.
 
@@ -922,6 +1084,7 @@ HttpBootGetBootFileCallback (
   @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.
                                    BufferSize has been updated with the size needed to complete
                                    the request.
+  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.
   @retval Others                   Unexpected error happened.
 
 **/
@@ -1072,8 +1235,9 @@ HttpBootGetBootFile (
     goto ERROR_3;
   }
 
-  RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;
-  RequestData->Url    = Url;
+  RequestData->Method      = HeaderOnly ? HttpMethodHead : HttpMethodGet;
+  RequestData->Url         = Url;
+  RequestData->EndPointUrl = NULL;
 
   //
   // 2.3 Record the request info in a temp cache item.
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h
index 406529dfd927..d702aa6e9f70 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h
@@ -85,6 +85,21 @@ HttpBootCreateHttpIo (
   IN     HTTP_BOOT_PRIVATE_DATA  *Private
   );
 
+/**
+  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.
 
@@ -106,6 +121,7 @@ HttpBootCreateHttpIo (
   @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.
                                    BufferSize has been updated with the size needed to complete
                                    the request.
+  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.
   @retval Others                   Unexpected error happened.
 
 **/
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
index 5acbae9bfa76..cb3b7214f26e 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
@@ -217,6 +217,12 @@ struct _HTTP_BOOT_PRIVATE_DATA {
   CHAR8                                        *FilePathUri;
   VOID                                         *FilePathUriParser;
 
+  //
+  // URI string for the endpoint host if BootFileUri contains the path
+  // for a proxy server
+  //
+  CHAR8                                        *EndPointUri;
+
   //
   // Cached HTTP data
   //
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
index 3da585a29164..2b112fb3ced8 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
@@ -116,8 +116,10 @@ HttpBootStart (
   UINTN       Index;
   EFI_STATUS  Status;
   CHAR8       *Uri;
+  CHAR8       *EndPointUri;
 
-  Uri = NULL;
+  Uri         = NULL;
+  EndPointUri = NULL;
 
   if ((Private == NULL) || (FilePath == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -127,7 +129,7 @@ HttpBootStart (
   // Check the URI 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, &Uri, &EndPointUri);
   if (EFI_ERROR (Status)) {
     return EFI_INVALID_PARAMETER;
   }
@@ -187,6 +189,7 @@ HttpBootStart (
   // Record the specified URI and prepare the URI parser if needed.
   //
   Private->FilePathUri = Uri;
+  Private->EndPointUri = EndPointUri;
   if (Private->FilePathUri != NULL) {
     Status = HttpParseUrl (
                Private->FilePathUri,
@@ -306,6 +309,7 @@ HttpBootLoadFile (
   )
 {
   EFI_STATUS  Status;
+  UINT8       Index;
 
   if ((Private == NULL) || (ImageType == NULL) || (BufferSize == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -349,30 +353,40 @@ HttpBootLoadFile (
     //
     // Discover the information about the bootfile if we haven't.
     //
+    for (Index = 0; Index < 2; Index++) {
+      if (Index == 1) {
+        Status = HttpBootConnectProxy (Private);
+      }
 
-    //
-    // Try to use HTTP HEAD method.
-    //
-    Status = HttpBootGetBootFile (
-               Private,
-               TRUE,
-               &Private->BootFileSize,
-               NULL,
-               &Private->ImageType
-               );
-    if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
       //
-      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
+      // Try to use HTTP HEAD method.
       //
-      ASSERT (Private->BootFileSize == 0);
       Status = HttpBootGetBootFile (
                  Private,
-                 FALSE,
+                 TRUE,
                  &Private->BootFileSize,
                  NULL,
                  &Private->ImageType
                  );
       if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+        //
+        // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
+        //
+        ASSERT (Private->BootFileSize == 0);
+        Status = HttpBootGetBootFile (
+                   Private,
+                   FALSE,
+                   &Private->BootFileSize,
+                   NULL,
+                   &Private->ImageType
+                   );
+      }
+
+      if (Status == EFI_SUCCESS) {
+        break;
+      }
+
+      if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL) && (Index == 2)) {
         AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
         goto ON_EXIT;
       }
diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
index 236ef259318b..1de36f61a98b 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
@@ -558,6 +558,7 @@ HttpBootCheckUriScheme (
 
   @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[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server
 
   @retval EFI_SUCCESS            The URI string is returned.
   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
@@ -566,7 +567,8 @@ HttpBootCheckUriScheme (
 EFI_STATUS
 HttpBootParseFilePath (
   IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,
-  OUT CHAR8                        **UriAddress
+  OUT CHAR8                        **UriAddress,
+  OUT CHAR8                        **EndPointUriAddress
   )
 {
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
@@ -578,8 +580,9 @@ HttpBootParseFilePath (
     return EFI_INVALID_PARAMETER;
   }
 
-  *UriAddress = NULL;
-
+  Uri                 = NULL;
+  *UriAddress         = NULL;
+  *EndPointUriAddress = NULL;
   //
   // Extract the URI address from the FilePath
   //
@@ -601,6 +604,10 @@ HttpBootParseFilePath (
         break;
       }
 
+      if (Uri != NULL) {
+        *EndPointUriAddress = Uri;
+      }
+
       Uri = AllocatePool (UriStrLength + 1);
       if (Uri == NULL) {
         return EFI_OUT_OF_RESOURCES;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
index 3698e5593642..6228f37e3676 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
@@ -138,8 +138,9 @@ HttpBootCheckUriScheme (
 
   Caller need to free the buffer in the UriAddress pointer.
 
-  @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]  UriAddress         The URI address string extract from the device path.
+  @param[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server
 
   @retval EFI_SUCCESS            The URI string is returned.
   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
@@ -148,7 +149,8 @@ HttpBootCheckUriScheme (
 EFI_STATUS
 HttpBootParseFilePath (
   IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,
-  OUT CHAR8                        **UriAddress
+  OUT CHAR8                        **UriAddress,
+  OUT CHAR8                        **EndPointUriAddress
   );
 
 /**
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 7c5c925cf78b..14084ba14a99 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -243,6 +243,7 @@ EfiHttpRequest (
   BOOLEAN                TlsConfigure;
   CHAR8                  *RequestMsg;
   CHAR8                  *Url;
+  CHAR8                  *EndPointUrl;
   UINTN                  UrlLen;
   CHAR16                 *HostNameStr;
   HTTP_TOKEN_WRAP        *Wrap;
@@ -262,6 +263,7 @@ EfiHttpRequest (
   Wrap         = NULL;
   FileUrl      = NULL;
   TlsConfigure = FALSE;
+  EndPointUrl  = NULL;
 
   if ((This == NULL) || (Token == NULL)) {
     return EFI_INVALID_PARAMETER;
@@ -280,7 +282,7 @@ 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) && (Request->Method != HttpMethodConnect))
   {
     return EFI_UNSUPPORTED;
   }
@@ -352,6 +354,17 @@ EfiHttpRequest (
     }
 
     UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
+    if (Request->EndPointUrl != NULL) {
+      UrlLen = StrLen (Request->EndPointUrl) + 1;
+      if (UrlLen > HTTP_URL_BUFFER_LEN) {
+        EndPointUrl = AllocateZeroPool (UrlLen);
+        if (EndPointUrl == NULL) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+      }
+
+      EndPointUrl = (CHAR8 *)Request->EndPointUrl;
+    }
 
     //
     // From the information in Url, the HTTP instance will
@@ -632,7 +645,11 @@ EfiHttpRequest (
     }
   }
 
-  Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+  if (HttpInstance->Method == HttpMethodConnect) {
+    Status = HttpGenRequestMessage (HttpMsg, EndPointUrl, &RequestMsg, &RequestMsgSize);
+  } else {
+    Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+  }
 
   if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
     goto Error3;
diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
index 6a5d78629bb3..45087a19350a 100644
--- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
+++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
@@ -1927,6 +1927,11 @@ HttpGenRequestMessage (
         CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
         RequestPtr += StrLength;
         break;
+      case HttpMethodConnect:
+        StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;
+        CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);
+        RequestPtr += StrLength;
+        break;
       default:
         ASSERT (FALSE);
         Status = EFI_INVALID_PARAMETER;
-- 
2.36.1.windows.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot
  2022-06-22 22:54 [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot Saloni Kasbekar
@ 2022-07-01 14:04 ` Maciej Rabeda
  2022-07-07 22:17   ` Saloni Kasbekar
  0 siblings, 1 reply; 3+ messages in thread
From: Maciej Rabeda @ 2022-07-01 14:04 UTC (permalink / raw)
  To: Saloni Kasbekar, devel; +Cc: Wu Jiaxin, Siyuan Fu, Jian J Wang, Liming Gao

[-- Attachment #1: Type: text/plain, Size: 20857 bytes --]

Hi Saloni,

This patch contains several problems. At minimum:

 1. HttpBootLoadFile() logic around calling HttpBootGetBootFile() is
    becoming more complex - and BZ 2504 patch adds to it. I am becoming
    convinced that this part of HttpBootLoadFile() should have a
    separate function with a looped state machine, to cover all cases.
 2. EfiHttpRequest(): "EndPointUrl = AllocateZeroPool (UrlLen)" followed
    with... "EndPointUrl = (CHAR8 *)Request->EndPointUrl". Was it
    supposed to be a copy from Request->EndPointUrl to EndPointUrl
    buffer or some other operation that I cannot comprehend?
 3. Could you provide more more information on device path shenanigans
    around proxy URI?

Thanks,
Maciej

On 23 cze 2022 00:54, Saloni Kasbekar wrote:
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3951
>
> Add CONNECT HTTP command in order to create a tunnel from HTTPS
> Proxy Server to EndPoint Server.
> Add support to connect through proxy server using DevicePath
> sent to the Boot Manager.
>
> Cc: Maciej Rabeda<maciej.rabeda@linux.intel.com>
> Cc: Wu Jiaxin<jiaxin.wu@intel.com>
> Cc: Siyuan Fu<siyuan.fu@intel.com>
> Cc: Jian J Wang<jian.j.wang@intel.com>
> Cc: Liming Gao<gaoliming@byosoft.com.cn>
> Signed-off-by: Saloni Kasbekar<saloni.kasbekar@intel.com>
> ---
>   .../Library/UefiBootManagerLib/BmBoot.c       |  11 ++
>   MdePkg/Include/Protocol/Http.h                |   5 +
>   NetworkPkg/HttpBootDxe/HttpBootClient.c       | 168 +++++++++++++++++-
>   NetworkPkg/HttpBootDxe/HttpBootClient.h       |  16 ++
>   NetworkPkg/HttpBootDxe/HttpBootDxe.h          |   6 +
>   NetworkPkg/HttpBootDxe/HttpBootImpl.c         |  46 +++--
>   NetworkPkg/HttpBootDxe/HttpBootSupport.c      |  13 +-
>   NetworkPkg/HttpBootDxe/HttpBootSupport.h      |   8 +-
>   NetworkPkg/HttpDxe/HttpImpl.c                 |  21 ++-
>   NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c    |   5 +
>   10 files changed, 273 insertions(+), 26 deletions(-)
>
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> index 962892d38f14..c5f09b619a89 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> @@ -1513,7 +1513,9 @@ BmExpandLoadFiles (
>     UINTN                     HandleCount;
>     UINTN                     Index;
>     EFI_DEVICE_PATH_PROTOCOL  *Node;
> +  URI_DEVICE_PATH           *NullUriPath;
>   
> +  NullUriPath = NULL;
>     //
>     // Get file buffer from load file instance.
>     //
> @@ -1543,10 +1545,19 @@ BmExpandLoadFiles (
>         HandleCount = 0;
>       }
>   
> +    NullUriPath = (URI_DEVICE_PATH *)CreateDeviceNode (
> +                                       MESSAGING_DEVICE_PATH,
> +                                       MSG_URI_DP,
> +                                       (UINT16)(sizeof (URI_DEVICE_PATH))
> +                                       );
> +
>       for (Index = 0; Index < HandleCount; Index++) {
>         if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) {
>           Handle = Handles[Index];
>           break;
> +      } else if (BmMatchHttpBootDevicePath (AppendDevicePathNode (DevicePathFromHandle (Handles[Index]), (EFI_DEVICE_PATH_PROTOCOL *)NullUriPath), FilePath)) {
> +        Handle = Handles[Index];
> +        break;
>         }
>       }
>   
> diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h
> index 28e622159392..4cf8fa4c0c97 100644
> --- a/MdePkg/Include/Protocol/Http.h
> +++ b/MdePkg/Include/Protocol/Http.h
> @@ -191,6 +191,11 @@ typedef struct {
>     /// is assumed. See RFC 3986 for more details on URI syntax.
>     ///
>     CHAR16             *Url;
> +  ///
> +  /// The URI of an endpoint host if the Url field contains the address of a proxy server.
> +  /// This field will be NULL if a proxy server is not involved.
> +  ///
> +  CHAR16             *EndPointUrl;
>   } EFI_HTTP_REQUEST_DATA;
>   
>   ///
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c
> index 62e87238fef7..2a4608414bd9 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c
> +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c
> @@ -901,6 +901,168 @@ HttpBootGetBootFileCallback (
>     return EFI_SUCCESS;
>   }
>   
> +/**
> +  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_REQUEST_DATA  *RequestData;
> +  HTTP_IO_RESPONSE_DATA  *ResponseData;
> +  HTTP_IO                *HttpIo;
> +  HTTP_IO_HEADER         *HttpIoHeader;
> +  CHAR16                 *Url;
> +  CHAR16                 *EndPointUrl;
> +  UINTN                  UrlSize;
> +
> +  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->EndPointUri);
> +  EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
> +  if (EndPointUrl == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  CopyMem (EndPointUrl, Private->EndPointUri, UrlSize);
> +
> +  //
> +  // 2. Send HTTP request message.
> +  //
> +
> +  //
> +  // 2.1 Build HTTP header for the request, 2 header is needed to send a CONNECT method:
> +  //       Host
> +  //       User
> +  //
> +  HttpIoHeader = HttpIoCreateHeader (2);
> +  if (HttpIoHeader == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR_3;
> +  }
> +
> +  //
> +  // Add HTTP header field 1: Host (proxy)
> +  //
> +  HostName = Private->EndPointUri;
> +  Status   = HttpIoSetHeader (
> +               HttpIoHeader,
> +               HTTP_HEADER_HOST,
> +               HostName
> +               );
> +  if (EFI_ERROR (Status)) {
> +    goto ERROR_3;
> +  }
> +
> +  //
> +  // 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 ERROR_3;
> +  }
> +
> +  //
> +  // 2.2 Build the rest of HTTP request info.
> +  //
> +  RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
> +  if (RequestData == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR_3;
> +  }
> +
> +  RequestData->Method      = HttpMethodConnect;
> +  RequestData->Url         = Url;
> +  RequestData->EndPointUrl = EndPointUrl;
> +
> +  //
> +  // 2.4 Send out the request to HTTP server.
> +  //
> +  HttpIo = &Private->HttpIo;
> +  Status = HttpIoSendRequest (
> +             HttpIo,
> +             RequestData,
> +             HttpIoHeader->HeaderCount,
> +             HttpIoHeader->Headers,
> +             0,
> +             NULL
> +             );
> +  if (EFI_ERROR (Status)) {
> +    goto ERROR_4;
> +  }
> +
> +  //
> +  // 3. Receive HTTP response message.
> +  //
> +
> +  //
> +  // 3.1 First step, 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 ERROR_4;
> +  }
> +
> +  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;
> +    }
> +
> +    goto ERROR_5;
> +  }
> +
> +  return Status;
> +
> +ERROR_5:
> +  if (ResponseData != NULL) {
> +    FreePool (ResponseData);
> +  }
> +
> +ERROR_4:
> +  if (RequestData != NULL) {
> +    FreePool (RequestData);
> +  }
> +
> +ERROR_3:
> +  HttpIoFreeHeader (HttpIoHeader);
> +
> +  if (Url != NULL) {
> +    FreePool (Url);
> +  }
> +
> +  return Status;
> +}
> +
>   /**
>     This function download the boot file by using UEFI HTTP protocol.
>   
> @@ -922,6 +1084,7 @@ HttpBootGetBootFileCallback (
>     @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.
>                                      BufferSize has been updated with the size needed to complete
>                                      the request.
> +  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.
>     @retval Others                   Unexpected error happened.
>   
>   **/
> @@ -1072,8 +1235,9 @@ HttpBootGetBootFile (
>       goto ERROR_3;
>     }
>   
> -  RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;
> -  RequestData->Url    = Url;
> +  RequestData->Method      = HeaderOnly ? HttpMethodHead : HttpMethodGet;
> +  RequestData->Url         = Url;
> +  RequestData->EndPointUrl = NULL;
>   
>     //
>     // 2.3 Record the request info in a temp cache item.
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h
> index 406529dfd927..d702aa6e9f70 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootClient.h
> +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h
> @@ -85,6 +85,21 @@ HttpBootCreateHttpIo (
>     IN     HTTP_BOOT_PRIVATE_DATA  *Private
>     );
>   
> +/**
> +  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.
>   
> @@ -106,6 +121,7 @@ HttpBootCreateHttpIo (
>     @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.
>                                      BufferSize has been updated with the size needed to complete
>                                      the request.
> +  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.
>     @retval Others                   Unexpected error happened.
>   
>   **/
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
> index 5acbae9bfa76..cb3b7214f26e 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h
> +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
> @@ -217,6 +217,12 @@ struct _HTTP_BOOT_PRIVATE_DATA {
>     CHAR8                                        *FilePathUri;
>     VOID                                         *FilePathUriParser;
>   
> +  //
> +  // URI string for the endpoint host if BootFileUri contains the path
> +  // for a proxy server
> +  //
> +  CHAR8                                        *EndPointUri;
> +
>     //
>     // Cached HTTP data
>     //
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
> index 3da585a29164..2b112fb3ced8 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c
> +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
> @@ -116,8 +116,10 @@ HttpBootStart (
>     UINTN       Index;
>     EFI_STATUS  Status;
>     CHAR8       *Uri;
> +  CHAR8       *EndPointUri;
>   
> -  Uri = NULL;
> +  Uri         = NULL;
> +  EndPointUri = NULL;
>   
>     if ((Private == NULL) || (FilePath == NULL)) {
>       return EFI_INVALID_PARAMETER;
> @@ -127,7 +129,7 @@ HttpBootStart (
>     // Check the URI 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, &Uri, &EndPointUri);
>     if (EFI_ERROR (Status)) {
>       return EFI_INVALID_PARAMETER;
>     }
> @@ -187,6 +189,7 @@ HttpBootStart (
>     // Record the specified URI and prepare the URI parser if needed.
>     //
>     Private->FilePathUri = Uri;
> +  Private->EndPointUri = EndPointUri;
>     if (Private->FilePathUri != NULL) {
>       Status = HttpParseUrl (
>                  Private->FilePathUri,
> @@ -306,6 +309,7 @@ HttpBootLoadFile (
>     )
>   {
>     EFI_STATUS  Status;
> +  UINT8       Index;
>   
>     if ((Private == NULL) || (ImageType == NULL) || (BufferSize == NULL)) {
>       return EFI_INVALID_PARAMETER;
> @@ -349,30 +353,40 @@ HttpBootLoadFile (
>       //
>       // Discover the information about the bootfile if we haven't.
>       //
> +    for (Index = 0; Index < 2; Index++) {
> +      if (Index == 1) {
> +        Status = HttpBootConnectProxy (Private);
> +      }
>   
> -    //
> -    // Try to use HTTP HEAD method.
> -    //
> -    Status = HttpBootGetBootFile (
> -               Private,
> -               TRUE,
> -               &Private->BootFileSize,
> -               NULL,
> -               &Private->ImageType
> -               );
> -    if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
>         //
> -      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
> +      // Try to use HTTP HEAD method.
>         //
> -      ASSERT (Private->BootFileSize == 0);
>         Status = HttpBootGetBootFile (
>                    Private,
> -                 FALSE,
> +                 TRUE,
>                    &Private->BootFileSize,
>                    NULL,
>                    &Private->ImageType
>                    );
>         if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
> +        //
> +        // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
> +        //
> +        ASSERT (Private->BootFileSize == 0);
> +        Status = HttpBootGetBootFile (
> +                   Private,
> +                   FALSE,
> +                   &Private->BootFileSize,
> +                   NULL,
> +                   &Private->ImageType
> +                   );
> +      }
> +
> +      if (Status == EFI_SUCCESS) {
> +        break;
> +      }
> +
> +      if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL) && (Index == 2)) {
>           AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
>           goto ON_EXIT;
>         }
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
> index 236ef259318b..1de36f61a98b 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c
> +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
> @@ -558,6 +558,7 @@ HttpBootCheckUriScheme (
>   
>     @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[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server
>   
>     @retval EFI_SUCCESS            The URI string is returned.
>     @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
> @@ -566,7 +567,8 @@ HttpBootCheckUriScheme (
>   EFI_STATUS
>   HttpBootParseFilePath (
>     IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,
> -  OUT CHAR8                        **UriAddress
> +  OUT CHAR8                        **UriAddress,
> +  OUT CHAR8                        **EndPointUriAddress
>     )
>   {
>     EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
> @@ -578,8 +580,9 @@ HttpBootParseFilePath (
>       return EFI_INVALID_PARAMETER;
>     }
>   
> -  *UriAddress = NULL;
> -
> +  Uri                 = NULL;
> +  *UriAddress         = NULL;
> +  *EndPointUriAddress = NULL;
>     //
>     // Extract the URI address from the FilePath
>     //
> @@ -601,6 +604,10 @@ HttpBootParseFilePath (
>           break;
>         }
>   
> +      if (Uri != NULL) {
> +        *EndPointUriAddress = Uri;
> +      }
> +
>         Uri = AllocatePool (UriStrLength + 1);
>         if (Uri == NULL) {
>           return EFI_OUT_OF_RESOURCES;
> diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
> index 3698e5593642..6228f37e3676 100644
> --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h
> +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
> @@ -138,8 +138,9 @@ HttpBootCheckUriScheme (
>   
>     Caller need to free the buffer in the UriAddress pointer.
>   
> -  @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]  UriAddress         The URI address string extract from the device path.
> +  @param[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server
>   
>     @retval EFI_SUCCESS            The URI string is returned.
>     @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
> @@ -148,7 +149,8 @@ HttpBootCheckUriScheme (
>   EFI_STATUS
>   HttpBootParseFilePath (
>     IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,
> -  OUT CHAR8                        **UriAddress
> +  OUT CHAR8                        **UriAddress,
> +  OUT CHAR8                        **EndPointUriAddress
>     );
>   
>   /**
> diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
> index 7c5c925cf78b..14084ba14a99 100644
> --- a/NetworkPkg/HttpDxe/HttpImpl.c
> +++ b/NetworkPkg/HttpDxe/HttpImpl.c
> @@ -243,6 +243,7 @@ EfiHttpRequest (
>     BOOLEAN                TlsConfigure;
>     CHAR8                  *RequestMsg;
>     CHAR8                  *Url;
> +  CHAR8                  *EndPointUrl;
>     UINTN                  UrlLen;
>     CHAR16                 *HostNameStr;
>     HTTP_TOKEN_WRAP        *Wrap;
> @@ -262,6 +263,7 @@ EfiHttpRequest (
>     Wrap         = NULL;
>     FileUrl      = NULL;
>     TlsConfigure = FALSE;
> +  EndPointUrl  = NULL;
>   
>     if ((This == NULL) || (Token == NULL)) {
>       return EFI_INVALID_PARAMETER;
> @@ -280,7 +282,7 @@ 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) && (Request->Method != HttpMethodConnect))
>     {
>       return EFI_UNSUPPORTED;
>     }
> @@ -352,6 +354,17 @@ EfiHttpRequest (
>       }
>   
>       UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
> +    if (Request->EndPointUrl != NULL) {
> +      UrlLen = StrLen (Request->EndPointUrl) + 1;
> +      if (UrlLen > HTTP_URL_BUFFER_LEN) {
> +        EndPointUrl = AllocateZeroPool (UrlLen);
> +        if (EndPointUrl == NULL) {
> +          return EFI_OUT_OF_RESOURCES;
> +        }
> +      }
> +
> +      EndPointUrl = (CHAR8 *)Request->EndPointUrl;
> +    }
>   
>       //
>       // From the information in Url, the HTTP instance will
> @@ -632,7 +645,11 @@ EfiHttpRequest (
>       }
>     }
>   
> -  Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
> +  if (HttpInstance->Method == HttpMethodConnect) {
> +    Status = HttpGenRequestMessage (HttpMsg, EndPointUrl, &RequestMsg, &RequestMsgSize);
> +  } else {
> +    Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
> +  }
>   
>     if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
>       goto Error3;
> diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
> index 6a5d78629bb3..45087a19350a 100644
> --- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
> +++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
> @@ -1927,6 +1927,11 @@ HttpGenRequestMessage (
>           CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
>           RequestPtr += StrLength;
>           break;
> +      case HttpMethodConnect:
> +        StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;
> +        CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);
> +        RequestPtr += StrLength;
> +        break;
>         default:
>           ASSERT (FALSE);
>           Status = EFI_INVALID_PARAMETER;

[-- Attachment #2: Type: text/html, Size: 20979 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot
  2022-07-01 14:04 ` Maciej Rabeda
@ 2022-07-07 22:17   ` Saloni Kasbekar
  0 siblings, 0 replies; 3+ messages in thread
From: Saloni Kasbekar @ 2022-07-07 22:17 UTC (permalink / raw)
  To: Rabeda, Maciej, devel@edk2.groups.io
  Cc: Wu, Jiaxin, Siyuan Fu, Wang, Jian J, Gao, Liming

[-- Attachment #1: Type: text/plain, Size: 22656 bytes --]

Hi Maciej,


  1.  I will update the code to add a new function to split that code into a separate function. Once the basic auth patch is checked in, I’ll re-send the changes for review so that we have the complete logic in the new function.
  2.  I see your point. I’ll update the code to fix it.
  3.  The code has been updated to include the proxy server and the endpoint server in the device path. Currently the device path just includes one URI which is described as (server_path/file_path). I’ve added a new option so that we can add an endpoint server to that device path to include the proxy server option. This will be have two URIs in the device path. For eg - (endpoint_server_path) /(proxy_server_path/file_path). If this is ok with you, I can update the code so that the comments makes this more clear.

Thanks,
Saloni

From: Rabeda, Maciej <maciej.rabeda@linux.intel.com>
Sent: Friday, July 1, 2022 7:05 AM
To: Kasbekar, Saloni <saloni.kasbekar@intel.com>; devel@edk2.groups.io
Cc: Wu, Jiaxin <jiaxin.wu@intel.com>; Siyuan Fu <siyuan.fu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>
Subject: Re: [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot


Hi Saloni,

This patch contains several problems. At minimum:

  1.  HttpBootLoadFile() logic around calling HttpBootGetBootFile() is becoming more complex - and BZ 2504 patch adds to it. I am becoming convinced that this part of HttpBootLoadFile() should have a separate function with a looped state machine, to cover all cases.
  2.  EfiHttpRequest(): "EndPointUrl = AllocateZeroPool (UrlLen)" followed with... "EndPointUrl = (CHAR8 *)Request->EndPointUrl". Was it supposed to be a copy from Request->EndPointUrl to EndPointUrl buffer or some other operation that I cannot comprehend?
  3.  Could you provide more more information on device path shenanigans around proxy URI?
Thanks,
Maciej
On 23 cze 2022 00:54, Saloni Kasbekar wrote:

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3951



Add CONNECT HTTP command in order to create a tunnel from HTTPS

Proxy Server to EndPoint Server.

Add support to connect through proxy server using DevicePath

sent to the Boot Manager.



Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com><mailto:maciej.rabeda@linux.intel.com>

Cc: Wu Jiaxin <jiaxin.wu@intel.com><mailto:jiaxin.wu@intel.com>

Cc: Siyuan Fu <siyuan.fu@intel.com><mailto:siyuan.fu@intel.com>

Cc: Jian J Wang <jian.j.wang@intel.com><mailto:jian.j.wang@intel.com>

Cc: Liming Gao <gaoliming@byosoft.com.cn><mailto:gaoliming@byosoft.com.cn>

Signed-off-by: Saloni Kasbekar <saloni.kasbekar@intel.com><mailto:saloni.kasbekar@intel.com>

---

 .../Library/UefiBootManagerLib/BmBoot.c       |  11 ++

 MdePkg/Include/Protocol/Http.h                |   5 +

 NetworkPkg/HttpBootDxe/HttpBootClient.c       | 168 +++++++++++++++++-

 NetworkPkg/HttpBootDxe/HttpBootClient.h       |  16 ++

 NetworkPkg/HttpBootDxe/HttpBootDxe.h          |   6 +

 NetworkPkg/HttpBootDxe/HttpBootImpl.c         |  46 +++--

 NetworkPkg/HttpBootDxe/HttpBootSupport.c      |  13 +-

 NetworkPkg/HttpBootDxe/HttpBootSupport.h      |   8 +-

 NetworkPkg/HttpDxe/HttpImpl.c                 |  21 ++-

 NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c    |   5 +

 10 files changed, 273 insertions(+), 26 deletions(-)



diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c

index 962892d38f14..c5f09b619a89 100644

--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c

+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c

@@ -1513,7 +1513,9 @@ BmExpandLoadFiles (

   UINTN                     HandleCount;

   UINTN                     Index;

   EFI_DEVICE_PATH_PROTOCOL  *Node;

+  URI_DEVICE_PATH           *NullUriPath;



+  NullUriPath = NULL;

   //

   // Get file buffer from load file instance.

   //

@@ -1543,10 +1545,19 @@ BmExpandLoadFiles (

       HandleCount = 0;

     }



+    NullUriPath = (URI_DEVICE_PATH *)CreateDeviceNode (

+                                       MESSAGING_DEVICE_PATH,

+                                       MSG_URI_DP,

+                                       (UINT16)(sizeof (URI_DEVICE_PATH))

+                                       );

+

     for (Index = 0; Index < HandleCount; Index++) {

       if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) {

         Handle = Handles[Index];

         break;

+      } else if (BmMatchHttpBootDevicePath (AppendDevicePathNode (DevicePathFromHandle (Handles[Index]), (EFI_DEVICE_PATH_PROTOCOL *)NullUriPath), FilePath)) {

+        Handle = Handles[Index];

+        break;

       }

     }



diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h

index 28e622159392..4cf8fa4c0c97 100644

--- a/MdePkg/Include/Protocol/Http.h

+++ b/MdePkg/Include/Protocol/Http.h

@@ -191,6 +191,11 @@ typedef struct {

   /// is assumed. See RFC 3986 for more details on URI syntax.

   ///

   CHAR16             *Url;

+  ///

+  /// The URI of an endpoint host if the Url field contains the address of a proxy server.

+  /// This field will be NULL if a proxy server is not involved.

+  ///

+  CHAR16             *EndPointUrl;

 } EFI_HTTP_REQUEST_DATA;



 ///

diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c

index 62e87238fef7..2a4608414bd9 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootClient.c

+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c

@@ -901,6 +901,168 @@ HttpBootGetBootFileCallback (

   return EFI_SUCCESS;

 }



+/**

+  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_REQUEST_DATA  *RequestData;

+  HTTP_IO_RESPONSE_DATA  *ResponseData;

+  HTTP_IO                *HttpIo;

+  HTTP_IO_HEADER         *HttpIoHeader;

+  CHAR16                 *Url;

+  CHAR16                 *EndPointUrl;

+  UINTN                  UrlSize;

+

+  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->EndPointUri);

+  EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));

+  if (EndPointUrl == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  CopyMem (EndPointUrl, Private->EndPointUri, UrlSize);

+

+  //

+  // 2. Send HTTP request message.

+  //

+

+  //

+  // 2.1 Build HTTP header for the request, 2 header is needed to send a CONNECT method:

+  //       Host

+  //       User

+  //

+  HttpIoHeader = HttpIoCreateHeader (2);

+  if (HttpIoHeader == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ERROR_3;

+  }

+

+  //

+  // Add HTTP header field 1: Host (proxy)

+  //

+  HostName = Private->EndPointUri;

+  Status   = HttpIoSetHeader (

+               HttpIoHeader,

+               HTTP_HEADER_HOST,

+               HostName

+               );

+  if (EFI_ERROR (Status)) {

+    goto ERROR_3;

+  }

+

+  //

+  // 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 ERROR_3;

+  }

+

+  //

+  // 2.2 Build the rest of HTTP request info.

+  //

+  RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));

+  if (RequestData == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto ERROR_3;

+  }

+

+  RequestData->Method      = HttpMethodConnect;

+  RequestData->Url         = Url;

+  RequestData->EndPointUrl = EndPointUrl;

+

+  //

+  // 2.4 Send out the request to HTTP server.

+  //

+  HttpIo = &Private->HttpIo;

+  Status = HttpIoSendRequest (

+             HttpIo,

+             RequestData,

+             HttpIoHeader->HeaderCount,

+             HttpIoHeader->Headers,

+             0,

+             NULL

+             );

+  if (EFI_ERROR (Status)) {

+    goto ERROR_4;

+  }

+

+  //

+  // 3. Receive HTTP response message.

+  //

+

+  //

+  // 3.1 First step, 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 ERROR_4;

+  }

+

+  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;

+    }

+

+    goto ERROR_5;

+  }

+

+  return Status;

+

+ERROR_5:

+  if (ResponseData != NULL) {

+    FreePool (ResponseData);

+  }

+

+ERROR_4:

+  if (RequestData != NULL) {

+    FreePool (RequestData);

+  }

+

+ERROR_3:

+  HttpIoFreeHeader (HttpIoHeader);

+

+  if (Url != NULL) {

+    FreePool (Url);

+  }

+

+  return Status;

+}

+

 /**

   This function download the boot file by using UEFI HTTP protocol.



@@ -922,6 +1084,7 @@ HttpBootGetBootFileCallback (

   @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.

                                    BufferSize has been updated with the size needed to complete

                                    the request.

+  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.

   @retval Others                   Unexpected error happened.



 **/

@@ -1072,8 +1235,9 @@ HttpBootGetBootFile (

     goto ERROR_3;

   }



-  RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;

-  RequestData->Url    = Url;

+  RequestData->Method      = HeaderOnly ? HttpMethodHead : HttpMethodGet;

+  RequestData->Url         = Url;

+  RequestData->EndPointUrl = NULL;



   //

   // 2.3 Record the request info in a temp cache item.

diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h

index 406529dfd927..d702aa6e9f70 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootClient.h

+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h

@@ -85,6 +85,21 @@ HttpBootCreateHttpIo (

   IN     HTTP_BOOT_PRIVATE_DATA  *Private

   );



+/**

+  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.



@@ -106,6 +121,7 @@ HttpBootCreateHttpIo (

   @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.

                                    BufferSize has been updated with the size needed to complete

                                    the request.

+  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.

   @retval Others                   Unexpected error happened.



 **/

diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h

index 5acbae9bfa76..cb3b7214f26e 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h

+++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h

@@ -217,6 +217,12 @@ struct _HTTP_BOOT_PRIVATE_DATA {

   CHAR8                                        *FilePathUri;

   VOID                                         *FilePathUriParser;



+  //

+  // URI string for the endpoint host if BootFileUri contains the path

+  // for a proxy server

+  //

+  CHAR8                                        *EndPointUri;

+

   //

   // Cached HTTP data

   //

diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c

index 3da585a29164..2b112fb3ced8 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c

+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c

@@ -116,8 +116,10 @@ HttpBootStart (

   UINTN       Index;

   EFI_STATUS  Status;

   CHAR8       *Uri;

+  CHAR8       *EndPointUri;



-  Uri = NULL;

+  Uri         = NULL;

+  EndPointUri = NULL;



   if ((Private == NULL) || (FilePath == NULL)) {

     return EFI_INVALID_PARAMETER;

@@ -127,7 +129,7 @@ HttpBootStart (

   // Check the URI 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, &Uri, &EndPointUri);

   if (EFI_ERROR (Status)) {

     return EFI_INVALID_PARAMETER;

   }

@@ -187,6 +189,7 @@ HttpBootStart (

   // Record the specified URI and prepare the URI parser if needed.

   //

   Private->FilePathUri = Uri;

+  Private->EndPointUri = EndPointUri;

   if (Private->FilePathUri != NULL) {

     Status = HttpParseUrl (

                Private->FilePathUri,

@@ -306,6 +309,7 @@ HttpBootLoadFile (

   )

 {

   EFI_STATUS  Status;

+  UINT8       Index;



   if ((Private == NULL) || (ImageType == NULL) || (BufferSize == NULL)) {

     return EFI_INVALID_PARAMETER;

@@ -349,30 +353,40 @@ HttpBootLoadFile (

     //

     // Discover the information about the bootfile if we haven't.

     //

+    for (Index = 0; Index < 2; Index++) {

+      if (Index == 1) {

+        Status = HttpBootConnectProxy (Private);

+      }



-    //

-    // Try to use HTTP HEAD method.

-    //

-    Status = HttpBootGetBootFile (

-               Private,

-               TRUE,

-               &Private->BootFileSize,

-               NULL,

-               &Private->ImageType

-               );

-    if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {

       //

-      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.

+      // Try to use HTTP HEAD method.

       //

-      ASSERT (Private->BootFileSize == 0);

       Status = HttpBootGetBootFile (

                  Private,

-                 FALSE,

+                 TRUE,

                  &Private->BootFileSize,

                  NULL,

                  &Private->ImageType

                  );

       if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {

+        //

+        // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.

+        //

+        ASSERT (Private->BootFileSize == 0);

+        Status = HttpBootGetBootFile (

+                   Private,

+                   FALSE,

+                   &Private->BootFileSize,

+                   NULL,

+                   &Private->ImageType

+                   );

+      }

+

+      if (Status == EFI_SUCCESS) {

+        break;

+      }

+

+      if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL) && (Index == 2)) {

         AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");

         goto ON_EXIT;

       }

diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c

index 236ef259318b..1de36f61a98b 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c

+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c

@@ -558,6 +558,7 @@ HttpBootCheckUriScheme (



   @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[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server



   @retval EFI_SUCCESS            The URI string is returned.

   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.

@@ -566,7 +567,8 @@ HttpBootCheckUriScheme (

 EFI_STATUS

 HttpBootParseFilePath (

   IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,

-  OUT CHAR8                        **UriAddress

+  OUT CHAR8                        **UriAddress,

+  OUT CHAR8                        **EndPointUriAddress

   )

 {

   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

@@ -578,8 +580,9 @@ HttpBootParseFilePath (

     return EFI_INVALID_PARAMETER;

   }



-  *UriAddress = NULL;

-

+  Uri                 = NULL;

+  *UriAddress         = NULL;

+  *EndPointUriAddress = NULL;

   //

   // Extract the URI address from the FilePath

   //

@@ -601,6 +604,10 @@ HttpBootParseFilePath (

         break;

       }



+      if (Uri != NULL) {

+        *EndPointUriAddress = Uri;

+      }

+

       Uri = AllocatePool (UriStrLength + 1);

       if (Uri == NULL) {

         return EFI_OUT_OF_RESOURCES;

diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h

index 3698e5593642..6228f37e3676 100644

--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h

+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h

@@ -138,8 +138,9 @@ HttpBootCheckUriScheme (



   Caller need to free the buffer in the UriAddress pointer.



-  @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]  UriAddress         The URI address string extract from the device path.

+  @param[out]  EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server



   @retval EFI_SUCCESS            The URI string is returned.

   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.

@@ -148,7 +149,8 @@ HttpBootCheckUriScheme (

 EFI_STATUS

 HttpBootParseFilePath (

   IN     EFI_DEVICE_PATH_PROTOCOL  *FilePath,

-  OUT CHAR8                        **UriAddress

+  OUT CHAR8                        **UriAddress,

+  OUT CHAR8                        **EndPointUriAddress

   );



 /**

diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c

index 7c5c925cf78b..14084ba14a99 100644

--- a/NetworkPkg/HttpDxe/HttpImpl.c

+++ b/NetworkPkg/HttpDxe/HttpImpl.c

@@ -243,6 +243,7 @@ EfiHttpRequest (

   BOOLEAN                TlsConfigure;

   CHAR8                  *RequestMsg;

   CHAR8                  *Url;

+  CHAR8                  *EndPointUrl;

   UINTN                  UrlLen;

   CHAR16                 *HostNameStr;

   HTTP_TOKEN_WRAP        *Wrap;

@@ -262,6 +263,7 @@ EfiHttpRequest (

   Wrap         = NULL;

   FileUrl      = NULL;

   TlsConfigure = FALSE;

+  EndPointUrl  = NULL;



   if ((This == NULL) || (Token == NULL)) {

     return EFI_INVALID_PARAMETER;

@@ -280,7 +282,7 @@ 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) && (Request->Method != HttpMethodConnect))

   {

     return EFI_UNSUPPORTED;

   }

@@ -352,6 +354,17 @@ EfiHttpRequest (

     }



     UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);

+    if (Request->EndPointUrl != NULL) {

+      UrlLen = StrLen (Request->EndPointUrl) + 1;

+      if (UrlLen > HTTP_URL_BUFFER_LEN) {

+        EndPointUrl = AllocateZeroPool (UrlLen);

+        if (EndPointUrl == NULL) {

+          return EFI_OUT_OF_RESOURCES;

+        }

+      }

+

+      EndPointUrl = (CHAR8 *)Request->EndPointUrl;

+    }



     //

     // From the information in Url, the HTTP instance will

@@ -632,7 +645,11 @@ EfiHttpRequest (

     }

   }



-  Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);

+  if (HttpInstance->Method == HttpMethodConnect) {

+    Status = HttpGenRequestMessage (HttpMsg, EndPointUrl, &RequestMsg, &RequestMsgSize);

+  } else {

+    Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);

+  }



   if (EFI_ERROR (Status) || (NULL == RequestMsg)) {

     goto Error3;

diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c

index 6a5d78629bb3..45087a19350a 100644

--- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c

+++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c

@@ -1927,6 +1927,11 @@ HttpGenRequestMessage (

         CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);

         RequestPtr += StrLength;

         break;

+      case HttpMethodConnect:

+        StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;

+        CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);

+        RequestPtr += StrLength;

+        break;

       default:

         ASSERT (FALSE);

         Status = EFI_INVALID_PARAMETER;

[-- Attachment #2: Type: text/html, Size: 53238 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-07-07 22:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-06-22 22:54 [PATCH 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot Saloni Kasbekar
2022-07-01 14:04 ` Maciej Rabeda
2022-07-07 22:17   ` Saloni Kasbekar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox