diff options
Diffstat (limited to 'NetworkPkg/HttpDxe/HttpImpl.c')
-rw-r--r-- | NetworkPkg/HttpDxe/HttpImpl.c | 252 |
1 files changed, 187 insertions, 65 deletions
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c index 9500f56..7ce6882 100644 --- a/NetworkPkg/HttpDxe/HttpImpl.c +++ b/NetworkPkg/HttpDxe/HttpImpl.c @@ -3,7 +3,7 @@ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (C) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -163,6 +163,7 @@ EfiHttpConfigure ( HttpInstance->TimeOutMillisec = HttpConfigData->TimeOutMillisec;
HttpInstance->LocalAddressIsIPv6 = HttpConfigData->LocalAddressIsIPv6;
HttpInstance->ConnectionClose = FALSE;
+ HttpInstance->ProxyConnected = FALSE;
if (HttpConfigData->LocalAddressIsIPv6) {
CopyMem (
@@ -179,7 +180,7 @@ EfiHttpConfigure ( }
//
- // Creat Tcp child
+ // Create Tcp child
//
Status = HttpInitProtocol (HttpInstance, HttpInstance->LocalAddressIsIPv6);
if (EFI_ERROR (Status)) {
@@ -231,37 +232,49 @@ EfiHttpRequest ( IN EFI_HTTP_TOKEN *Token
)
{
- EFI_HTTP_MESSAGE *HttpMsg;
- EFI_HTTP_REQUEST_DATA *Request;
- VOID *UrlParser;
- EFI_STATUS Status;
- CHAR8 *HostName;
- UINTN HostNameSize;
- UINT16 RemotePort;
- HTTP_PROTOCOL *HttpInstance;
- BOOLEAN Configure;
- BOOLEAN ReConfigure;
- BOOLEAN TlsConfigure;
- CHAR8 *RequestMsg;
- CHAR8 *Url;
- UINTN UrlLen;
- CHAR16 *HostNameStr;
- HTTP_TOKEN_WRAP *Wrap;
- CHAR8 *FileUrl;
- UINTN RequestMsgSize;
+ EFI_HTTP_MESSAGE *HttpMsg;
+ EFI_HTTP_REQUEST_DATA *Request;
+ VOID *UrlParser;
+ VOID *EndPointUrlParser;
+ EFI_STATUS Status;
+ CHAR8 *HostName;
+ UINTN HostNameSize;
+ UINT16 RemotePort;
+ HTTP_PROTOCOL *HttpInstance;
+ BOOLEAN Configure;
+ BOOLEAN ReConfigure;
+ BOOLEAN TlsConfigure;
+ CHAR8 *RequestMsg;
+ CHAR8 *Url;
+ UINTN UrlLen;
+ CHAR8 *ProxyUrl;
+ UINTN ProxyUrlLen;
+ CHAR8 *ParseUrl;
+ CHAR16 *HostNameStr;
+ HTTP_TOKEN_WRAP *Wrap;
+ CHAR8 *FileUrl;
+ UINTN RequestMsgSize;
+ UINT16 EndPointRemotePort;
+ CHAR8 *EndPointUrlMsg;
+ EFI_HTTP_CONNECT_REQUEST_DATA *ConnRequest;
//
// Initializations
//
- Url = NULL;
- UrlParser = NULL;
- RemotePort = 0;
- HostName = NULL;
- RequestMsg = NULL;
- HostNameStr = NULL;
- Wrap = NULL;
- FileUrl = NULL;
- TlsConfigure = FALSE;
+ Url = NULL;
+ ProxyUrl = NULL;
+ UrlParser = NULL;
+ EndPointUrlParser = NULL;
+ RemotePort = 0;
+ HostName = NULL;
+ RequestMsg = NULL;
+ HostNameStr = NULL;
+ Wrap = NULL;
+ FileUrl = NULL;
+ TlsConfigure = FALSE;
+ EndPointUrlMsg = NULL;
+ EndPointRemotePort = 0;
+ ConnRequest = NULL;
if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -275,14 +288,27 @@ EfiHttpRequest ( Request = HttpMsg->Data.Request;
//
- // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation.
+ // Only support GET, HEAD, DELETE, CONNECT, PATCH, PUT and POST method in current implementation.
//
- if ((Request != NULL) && (Request->Method != HttpMethodGet) &&
- (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) &&
- (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) &&
- (Request->Method != HttpMethodPatch))
- {
- return EFI_UNSUPPORTED;
+ if (Request != NULL) {
+ switch (Request->Method) {
+ case HttpMethodGet:
+ case HttpMethodHead:
+ case HttpMethodDelete:
+ case HttpMethodPut:
+ case HttpMethodPost:
+ case HttpMethodPatch:
+ break;
+ case HttpMethodConnect:
+ ConnRequest = (EFI_HTTP_CONNECT_REQUEST_DATA *)Request;
+ if (ConnRequest->ProxyUrl == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
}
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
@@ -337,7 +363,7 @@ EfiHttpRequest ( }
//
- // Parse the URI of the remote host.
+ // Parse the Request URI.
//
Url = HttpInstance->Url;
UrlLen = StrLen (Request->Url) + 1;
@@ -358,10 +384,37 @@ EfiHttpRequest ( UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
//
- // From the information in Url, the HTTP instance will
+ // In case of HTTP Connect, parse proxy URI from Request.
+ //
+ if (Request->Method == HttpMethodConnect) {
+ ProxyUrl = HttpInstance->ProxyUrl;
+ ProxyUrlLen = StrLen (ConnRequest->ProxyUrl) + 1;
+ if (ProxyUrlLen > HttpInstance->ProxyUrlLen) {
+ ProxyUrl = AllocateZeroPool (ProxyUrlLen);
+ if (ProxyUrl == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (HttpInstance->ProxyUrl != NULL) {
+ FreePool (HttpInstance->ProxyUrl);
+ }
+
+ HttpInstance->ProxyUrl = ProxyUrl;
+ HttpInstance->ProxyUrlLen = ProxyUrlLen;
+ }
+
+ UnicodeStrToAsciiStrS (ConnRequest->ProxyUrl, ProxyUrl, ProxyUrlLen);
+ }
+
+ //
+ // From the information in the Urls, the HTTP instance will
// be able to determine whether to use http or https.
//
- HttpInstance->UseHttps = IsHttpsUrl (Url);
+ if (Request->Method == HttpMethodConnect) {
+ HttpInstance->UseHttps = IsHttpsUrl (ProxyUrl);
+ } else {
+ HttpInstance->UseHttps = IsHttpsUrl (Url);
+ }
//
// HTTP is disabled, return directly if the URI is not HTTPS.
@@ -385,13 +438,26 @@ EfiHttpRequest ( TlsConfigure = TRUE;
}
- UrlParser = NULL;
- Status = HttpParseUrl (Url, (UINT32)AsciiStrLen (Url), FALSE, &UrlParser);
+ //
+ // Setup RemoteAddress and RemotePort of HttpInstance.
+ //
+ if (Request->Method == HttpMethodConnect) {
+ // Case 1: HTTP Connect request
+ ParseUrl = ProxyUrl;
+ } else if (HttpInstance->ProxyConnected == TRUE) {
+ // Case 2: Other HTTP request (proxy connected)
+ ParseUrl = HttpInstance->ProxyUrl;
+ } else {
+ // Case 3: Other HTTP request (proxy not connected)
+ ParseUrl = Url;
+ }
+
+ Status = HttpParseUrl (ParseUrl, (UINT32)AsciiStrLen (ParseUrl), FALSE, &UrlParser);
if (EFI_ERROR (Status)) {
goto Error1;
}
- Status = HttpUrlGetHostName (Url, UrlParser, &HostName);
+ Status = HttpUrlGetHostName (ParseUrl, UrlParser, &HostName);
if (EFI_ERROR (Status)) {
goto Error1;
}
@@ -409,7 +475,7 @@ EfiHttpRequest ( }
}
- Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
+ Status = HttpUrlGetPort (ParseUrl, UrlParser, &RemotePort);
if (EFI_ERROR (Status)) {
if (HttpInstance->UseHttps) {
RemotePort = HTTPS_DEFAULT_PORT;
@@ -435,9 +501,10 @@ EfiHttpRequest ( if ((HttpInstance->ConnectionClose == FALSE) &&
(HttpInstance->RemotePort == RemotePort) &&
(AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
- (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
- !TlsConfigure &&
- (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))
+ (!HttpInstance->UseHttps ||
+ HttpInstance->ProxyConnected || (HttpInstance->UseHttps &&
+ !TlsConfigure &&
+ (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))
{
//
// Host Name and port number of the request URL are the same with previous call to Request().
@@ -505,7 +572,7 @@ EfiHttpRequest ( if (!HttpInstance->LocalAddressIsIPv6) {
Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
} else {
- Status = HttpUrlGetIp6 (Url, UrlParser, &HttpInstance->RemoteIpv6Addr);
+ Status = HttpUrlGetIp6 (ParseUrl, UrlParser, &HttpInstance->RemoteIpv6Addr);
}
if (EFI_ERROR (Status)) {
@@ -590,7 +657,7 @@ EfiHttpRequest ( goto Error2;
}
- if (!Configure && !ReConfigure && !TlsConfigure) {
+ if ((!Configure && !ReConfigure) && ((HttpInstance->ProxyConnected && TlsConfigure) || (!TlsConfigure))) {
//
// For the new HTTP token, create TX TCP token events.
//
@@ -603,27 +670,74 @@ EfiHttpRequest ( //
// Create request message.
//
- FileUrl = Url;
- if ((Url != NULL) && (*FileUrl != '/')) {
+ if ((Request != NULL) && (Request->Method == HttpMethodConnect)) {
//
- // Convert the absolute-URI to the absolute-path
+ // HTTP Connect shall contain EndPoint host name in URI
//
- while (*FileUrl != ':') {
- FileUrl++;
+ Status = HttpParseUrl (Url, (UINT32)AsciiStrLen (Url), FALSE, &EndPointUrlParser);
+ if (EFI_ERROR (Status)) {
+ goto Error3;
}
- if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) {
- FileUrl += 3;
- while (*FileUrl != '/') {
- FileUrl++;
+ Status = HttpUrlGetHostName (
+ Url,
+ EndPointUrlParser,
+ &HttpInstance->EndPointHostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error3;
+ }
+
+ Status = HttpUrlGetPort (Url, EndPointUrlParser, &EndPointRemotePort);
+ if (EFI_ERROR (Status)) {
+ if (IsHttpsUrl (Url)) {
+ EndPointRemotePort = HTTPS_DEFAULT_PORT;
+ } else {
+ EndPointRemotePort = HTTP_DEFAULT_PORT;
}
- } else {
- Status = EFI_INVALID_PARAMETER;
+ }
+
+ EndPointUrlMsg = AllocateZeroPool (URI_STR_MAX_SIZE);
+ if (EndPointUrlMsg == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
goto Error3;
}
- }
- Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+ AsciiSPrint (
+ EndPointUrlMsg,
+ URI_STR_MAX_SIZE,
+ "%a:%d",
+ HttpInstance->EndPointHostName,
+ EndPointRemotePort
+ );
+
+ Status = HttpGenRequestMessage (HttpMsg, EndPointUrlMsg, &RequestMsg, &RequestMsgSize);
+
+ FreePool (EndPointUrlMsg);
+ HttpUrlFreeParser (EndPointUrlParser);
+ } else {
+ FileUrl = Url;
+ if ((Url != NULL) && (*FileUrl != '/')) {
+ //
+ // Convert the absolute-URI to the absolute-path
+ //
+ while (*FileUrl != ':') {
+ FileUrl++;
+ }
+
+ if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) {
+ FileUrl += 3;
+ while (*FileUrl != '/') {
+ FileUrl++;
+ }
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error3;
+ }
+ }
+
+ Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+ }
if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
goto Error3;
@@ -659,6 +773,10 @@ EfiHttpRequest ( DispatchDpc ();
+ if (HttpInstance->Method == HttpMethodConnect) {
+ HttpInstance->ProxyConnected = TRUE;
+ }
+
if (HostName != NULL) {
FreePool (HostName);
}
@@ -704,6 +822,14 @@ Error2: }
Error1:
+ if (EndPointUrlMsg != NULL) {
+ FreePool (EndPointUrlMsg);
+ }
+
+ if (EndPointUrlParser != NULL) {
+ HttpUrlFreeParser (EndPointUrlParser);
+ }
+
if (HostName != NULL) {
FreePool (HostName);
}
@@ -1108,10 +1234,6 @@ HttpResponseWorker ( // Search for Status Code.
//
StatusCodeStr = HttpHeaders + AsciiStrLen (HTTP_VERSION_STR) + 1;
- if (StatusCodeStr == NULL) {
- Status = EFI_NOT_READY;
- goto Error;
- }
StatusCode = AsciiStrDecimalToUintn (StatusCodeStr);
|