X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FHttpBootDxe%2FHttpBootSupport.c;h=37a95e031e9ccbba75580ae1506472360ac0cfa3;hb=40c4cd54213b78ef0daee2f4b186150d7ef63bb4;hp=bdb29ae9a0f6c57fafcb71ff802d8ee665a3054f;hpb=413535bb33d60417d681725af0274086630e7987;p=mirror_edk2.git diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c index bdb29ae9a0..37a95e031e 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -1,15 +1,9 @@ /** @file Support functions implementation for UEFI HTTP boot driver. -Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that accompanies this distribution. -The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php. - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -160,42 +154,46 @@ HttpBootPrintErrorMessage ( AsciiPrint ("\n"); switch (StatusCode) { - case HTTP_STATUS_300_MULTIPLE_CHIOCES: + case HTTP_STATUS_300_MULTIPLE_CHOICES: AsciiPrint ("\n Redirection: 300 Multiple Choices"); - break; - + break; + case HTTP_STATUS_301_MOVED_PERMANENTLY: AsciiPrint ("\n Redirection: 301 Moved Permanently"); - break; - + break; + case HTTP_STATUS_302_FOUND: AsciiPrint ("\n Redirection: 302 Found"); - break; - + break; + case HTTP_STATUS_303_SEE_OTHER: AsciiPrint ("\n Redirection: 303 See Other"); - break; + break; case HTTP_STATUS_304_NOT_MODIFIED: AsciiPrint ("\n Redirection: 304 Not Modified"); - break; + break; case HTTP_STATUS_305_USE_PROXY: AsciiPrint ("\n Redirection: 305 Use Proxy"); - break; + break; case HTTP_STATUS_307_TEMPORARY_REDIRECT: AsciiPrint ("\n Redirection: 307 Temporary Redirect"); - break; + break; + + case HTTP_STATUS_308_PERMANENT_REDIRECT: + AsciiPrint ("\n Redirection: 308 Permanent Redirect"); + break; case HTTP_STATUS_400_BAD_REQUEST: AsciiPrint ("\n Client Error: 400 Bad Request"); break; - + case HTTP_STATUS_401_UNAUTHORIZED: AsciiPrint ("\n Client Error: 401 Unauthorized"); break; - + case HTTP_STATUS_402_PAYMENT_REQUIRED: AsciiPrint ("\n Client Error: 402 Payment Required"); break; @@ -285,7 +283,7 @@ HttpBootPrintErrorMessage ( break; default: ; - + } } @@ -315,13 +313,13 @@ HttpBootCommonNotify ( @retval EFI_SUCCESS Operation succeeded. @retval EFI_DEVICE_ERROR An unexpected network error occurred. - @retval Others Other errors as indicated. + @retval Others Other errors as indicated. **/ EFI_STATUS HttpBootDns ( IN HTTP_BOOT_PRIVATE_DATA *Private, IN CHAR16 *HostName, - OUT EFI_IPv6_ADDRESS *IpAddress + OUT EFI_IPv6_ADDRESS *IpAddress ) { EFI_STATUS Status; @@ -333,14 +331,14 @@ HttpBootDns ( EFI_IPv6_ADDRESS *DnsServerList; UINTN DnsServerListCount; UINTN DataSize; - BOOLEAN IsDone; - + BOOLEAN IsDone; + DnsServerList = NULL; DnsServerListCount = 0; Dns6 = NULL; Dns6Handle = NULL; ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN)); - + // // Get DNS server list from EFI IPv6 Configuration protocol. // @@ -355,7 +353,7 @@ HttpBootDns ( DnsServerList = AllocatePool (DataSize); if (DnsServerList == NULL) { return EFI_OUT_OF_RESOURCES; - } + } Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList); if (EFI_ERROR (Status)) { @@ -377,8 +375,8 @@ HttpBootDns ( ); if (EFI_ERROR (Status)) { goto Exit; - } - + } + Status = gBS->OpenProtocol ( Dns6Handle, &gEfiDns6ProtocolGuid, @@ -407,7 +405,7 @@ HttpBootDns ( if (EFI_ERROR (Status)) { goto Exit; } - + Token.Status = EFI_NOT_READY; IsDone = FALSE; // @@ -435,11 +433,11 @@ HttpBootDns ( while (!IsDone) { Dns6->Poll (Dns6); } - + // // Name resolution is done, check result. // - Status = Token.Status; + Status = Token.Status; if (!EFI_ERROR (Status)) { if (Token.RspData.H2AData == NULL) { Status = EFI_DEVICE_ERROR; @@ -469,7 +467,7 @@ Exit: if (Dns6 != NULL) { Dns6->Configure (Dns6, NULL); - + gBS->CloseProtocol ( Dns6Handle, &gEfiDns6ProtocolGuid, @@ -490,501 +488,58 @@ Exit: if (DnsServerList != NULL) { FreePool (DnsServerList); } - - return Status; -} -/** - Create a HTTP_IO_HEADER to hold the HTTP header items. - - @param[in] MaxHeaderCount The maximun number of HTTP header in this holder. - - @return A pointer of the HTTP header holder or NULL if failed. - -**/ -HTTP_IO_HEADER * -HttpBootCreateHeader ( - UINTN MaxHeaderCount - ) -{ - HTTP_IO_HEADER *HttpIoHeader; - - if (MaxHeaderCount == 0) { - return NULL; - } - - HttpIoHeader = AllocateZeroPool (sizeof (HTTP_IO_HEADER) + MaxHeaderCount * sizeof (EFI_HTTP_HEADER)); - if (HttpIoHeader == NULL) { - return NULL; - } - - HttpIoHeader->MaxHeaderCount = MaxHeaderCount; - HttpIoHeader->Headers = (EFI_HTTP_HEADER *) (HttpIoHeader + 1); - - return HttpIoHeader; -} - -/** - Destroy the HTTP_IO_HEADER and release the resouces. - - @param[in] HttpIoHeader Point to the HTTP header holder to be destroyed. - -**/ -VOID -HttpBootFreeHeader ( - IN HTTP_IO_HEADER *HttpIoHeader - ) -{ - UINTN Index; - - if (HttpIoHeader != NULL) { - if (HttpIoHeader->HeaderCount != 0) { - for (Index = 0; Index < HttpIoHeader->HeaderCount; Index++) { - FreePool (HttpIoHeader->Headers[Index].FieldName); - FreePool (HttpIoHeader->Headers[Index].FieldValue); - } - } - FreePool (HttpIoHeader); - } -} - -/** - Set or update a HTTP header with the field name and corresponding value. - - @param[in] HttpIoHeader Point to the HTTP header holder. - @param[in] FieldName Null terminated string which describes a field name. - @param[in] FieldValue Null terminated string which describes the corresponding field value. - - @retval EFI_SUCCESS The HTTP header has been set or updated. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Insufficient resource to complete the operation. - @retval Other Unexpected error happened. - -**/ -EFI_STATUS -HttpBootSetHeader ( - IN HTTP_IO_HEADER *HttpIoHeader, - IN CHAR8 *FieldName, - IN CHAR8 *FieldValue - ) -{ - EFI_HTTP_HEADER *Header; - UINTN StrSize; - CHAR8 *NewFieldValue; - - if (HttpIoHeader == NULL || FieldName == NULL || FieldValue == NULL) { - return EFI_INVALID_PARAMETER; - } - - Header = HttpFindHeader (HttpIoHeader->HeaderCount, HttpIoHeader->Headers, FieldName); - if (Header == NULL) { - // - // Add a new header. - // - if (HttpIoHeader->HeaderCount >= HttpIoHeader->MaxHeaderCount) { - return EFI_OUT_OF_RESOURCES; - } - Header = &HttpIoHeader->Headers[HttpIoHeader->HeaderCount]; - - StrSize = AsciiStrSize (FieldName); - Header->FieldName = AllocatePool (StrSize); - if (Header->FieldName == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (Header->FieldName, FieldName, StrSize); - Header->FieldName[StrSize -1] = '\0'; - - StrSize = AsciiStrSize (FieldValue); - Header->FieldValue = AllocatePool (StrSize); - if (Header->FieldValue == NULL) { - FreePool (Header->FieldName); - return EFI_OUT_OF_RESOURCES; - } - CopyMem (Header->FieldValue, FieldValue, StrSize); - Header->FieldValue[StrSize -1] = '\0'; - - HttpIoHeader->HeaderCount++; - } else { - // - // Update an existing one. - // - StrSize = AsciiStrSize (FieldValue); - NewFieldValue = AllocatePool (StrSize); - if (NewFieldValue == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (NewFieldValue, FieldValue, StrSize); - NewFieldValue[StrSize -1] = '\0'; - - if (Header->FieldValue != NULL) { - FreePool (Header->FieldValue); - } - Header->FieldValue = NewFieldValue; - } - - return EFI_SUCCESS; -} - -/** - Create a HTTP_IO to access the HTTP service. It will create and configure - a HTTP child handle. - - @param[in] Image The handle of the driver image. - @param[in] Controller The handle of the controller. - @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. - @param[in] ConfigData The HTTP_IO configuration data. - @param[out] HttpIo The HTTP_IO. - - @retval EFI_SUCCESS The HTTP_IO is created and configured. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED One or more of the control options are not - supported in the implementation. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval Others Failed to create the HTTP_IO or configure it. - -**/ -EFI_STATUS -HttpIoCreateIo ( - IN EFI_HANDLE Image, - IN EFI_HANDLE Controller, - IN UINT8 IpVersion, - IN HTTP_IO_CONFIG_DATA *ConfigData, - OUT HTTP_IO *HttpIo - ) -{ - EFI_STATUS Status; - EFI_HTTP_CONFIG_DATA HttpConfigData; - EFI_HTTPv4_ACCESS_POINT Http4AccessPoint; - EFI_HTTPv6_ACCESS_POINT Http6AccessPoint; - EFI_HTTP_PROTOCOL *Http; - EFI_EVENT Event; - - if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (HttpIo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (IpVersion != IP_VERSION_4 && IpVersion != IP_VERSION_6) { - return EFI_UNSUPPORTED; - } - - ZeroMem (HttpIo, sizeof (HTTP_IO)); - - // - // Create the HTTP child instance and get the HTTP protocol. - // - Status = NetLibCreateServiceChild ( - Controller, - Image, - &gEfiHttpServiceBindingProtocolGuid, - &HttpIo->Handle - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->OpenProtocol ( - HttpIo->Handle, - &gEfiHttpProtocolGuid, - (VOID **) &Http, - Image, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) || (Http == NULL)) { - goto ON_ERROR; - } - - // - // Init the configuration data and configure the HTTP child. - // - HttpIo->Image = Image; - HttpIo->Controller = Controller; - HttpIo->IpVersion = IpVersion; - HttpIo->Http = Http; - - ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); - HttpConfigData.HttpVersion = HttpVersion11; - HttpConfigData.TimeOutMillisec = ConfigData->Config4.RequestTimeOut; - if (HttpIo->IpVersion == IP_VERSION_4) { - HttpConfigData.LocalAddressIsIPv6 = FALSE; - - Http4AccessPoint.UseDefaultAddress = ConfigData->Config4.UseDefaultAddress; - Http4AccessPoint.LocalPort = ConfigData->Config4.LocalPort; - IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Config4.LocalIp); - IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config4.SubnetMask); - HttpConfigData.AccessPoint.IPv4Node = &Http4AccessPoint; - } else { - HttpConfigData.LocalAddressIsIPv6 = TRUE; - Http6AccessPoint.LocalPort = ConfigData->Config6.LocalPort; - IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Config6.LocalIp); - HttpConfigData.AccessPoint.IPv6Node = &Http6AccessPoint; - } - - Status = Http->Configure (Http, &HttpConfigData); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Create events for variuos asynchronous operations. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpBootCommonNotify, - &HttpIo->IsTxDone, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->ReqToken.Event = Event; - HttpIo->ReqToken.Message = &HttpIo->ReqMessage; - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpBootCommonNotify, - &HttpIo->IsRxDone, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->RspToken.Event = Event; - HttpIo->RspToken.Message = &HttpIo->RspMessage; - - // - // Create TimeoutEvent for response - // - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->TimeoutEvent = Event; - - return EFI_SUCCESS; - -ON_ERROR: - HttpIoDestroyIo (HttpIo); return Status; } /** - Destroy the HTTP_IO and release the resouces. + This function checks the HTTP(S) URI scheme. - @param[in] HttpIo The HTTP_IO which wraps the HTTP service to be destroyed. + @param[in] Uri The pointer to the URI string. -**/ -VOID -HttpIoDestroyIo ( - IN HTTP_IO *HttpIo - ) -{ - EFI_HTTP_PROTOCOL *Http; - EFI_EVENT Event; - - if (HttpIo == NULL) { - return; - } - - Event = HttpIo->ReqToken.Event; - if (Event != NULL) { - gBS->CloseEvent (Event); - } - - Event = HttpIo->RspToken.Event; - if (Event != NULL) { - gBS->CloseEvent (Event); - } - - Event = HttpIo->TimeoutEvent; - if (Event != NULL) { - gBS->CloseEvent (Event); - } - - Http = HttpIo->Http; - if (Http != NULL) { - Http->Configure (Http, NULL); - gBS->CloseProtocol ( - HttpIo->Handle, - &gEfiHttpProtocolGuid, - HttpIo->Image, - HttpIo->Controller - ); - } - - NetLibDestroyServiceChild ( - HttpIo->Controller, - HttpIo->Image, - &gEfiHttpServiceBindingProtocolGuid, - HttpIo->Handle - ); -} - -/** - Synchronously send a HTTP REQUEST message to the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] Request A pointer to storage such data as URL and HTTP method. - @param[in] HeaderCount Number of HTTP header structures in Headers list. - @param[in] Headers Array containing list of HTTP headers. - @param[in] BodyLength Length in bytes of the HTTP body. - @param[in] Body Body associated with the HTTP request. - - @retval EFI_SUCCESS The HTTP request is trasmitted. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. - @retval Others Other errors as indicated. + @retval EFI_SUCCESS The URI scheme is valid. + @retval EFI_INVALID_PARAMETER The URI scheme is not HTTP or HTTPS. + @retval EFI_ACCESS_DENIED HTTP is disabled and the URI is HTTP. **/ EFI_STATUS -HttpIoSendRequest ( - IN HTTP_IO *HttpIo, - IN EFI_HTTP_REQUEST_DATA *Request, - IN UINTN HeaderCount, - IN EFI_HTTP_HEADER *Headers, - IN UINTN BodyLength, - IN VOID *Body +HttpBootCheckUriScheme ( + IN CHAR8 *Uri ) { - EFI_STATUS Status; - EFI_HTTP_PROTOCOL *Http; + UINTN Index; + EFI_STATUS Status; - if (HttpIo == NULL || HttpIo->Http == NULL) { - return EFI_INVALID_PARAMETER; - } - - HttpIo->ReqToken.Status = EFI_NOT_READY; - HttpIo->ReqToken.Message->Data.Request = Request; - HttpIo->ReqToken.Message->HeaderCount = HeaderCount; - HttpIo->ReqToken.Message->Headers = Headers; - HttpIo->ReqToken.Message->BodyLength = BodyLength; - HttpIo->ReqToken.Message->Body = Body; + Status = EFI_SUCCESS; // - // Queue the request token to HTTP instances. + // Convert the scheme to all lower case. // - Http = HttpIo->Http; - HttpIo->IsTxDone = FALSE; - Status = Http->Request ( - Http, - &HttpIo->ReqToken - ); - if (EFI_ERROR (Status)) { - return Status; + for (Index = 0; Index < AsciiStrLen (Uri); Index++) { + if (Uri[Index] == ':') { + break; + } + if (Uri[Index] >= 'A' && Uri[Index] <= 'Z') { + Uri[Index] -= (CHAR8)('A' - 'a'); + } } // - // Poll the network until transmit finish. + // Return EFI_INVALID_PARAMETER if the URI is not HTTP or HTTPS. // - while (!HttpIo->IsTxDone) { - Http->Poll (Http); - } - - return HttpIo->ReqToken.Status; -} - -/** - Synchronously receive a HTTP RESPONSE message from the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] RecvMsgHeader TRUE to receive a new HTTP response (from message header). - FALSE to continue receive the previous response message. - @param[out] ResponseData Point to a wrapper of the received response data. - - @retval EFI_SUCCESS The HTTP response is received. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -HttpIoRecvResponse ( - IN HTTP_IO *HttpIo, - IN BOOLEAN RecvMsgHeader, - OUT HTTP_IO_RESPONSE_DATA *ResponseData - ) -{ - EFI_STATUS Status; - EFI_HTTP_PROTOCOL *Http; - - if (HttpIo == NULL || HttpIo->Http == NULL || ResponseData == NULL) { + if ((AsciiStrnCmp (Uri, "http://", 7) != 0) && (AsciiStrnCmp (Uri, "https://", 8) != 0)) { + DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: Invalid Uri.\n")); return EFI_INVALID_PARAMETER; } // - // Start the timer, and wait Timeout seconds to receive the header packet. + // HTTP is disabled, return EFI_ACCESS_DENIED if the URI is HTTP. // - Status = gBS->SetTimer (HttpIo->TimeoutEvent, TimerRelative, HTTP_BOOT_RESPONSE_TIMEOUT * TICKS_PER_MS); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Queue the response token to HTTP instances. - // - HttpIo->RspToken.Status = EFI_NOT_READY; - if (RecvMsgHeader) { - HttpIo->RspToken.Message->Data.Response = &ResponseData->Response; - } else { - HttpIo->RspToken.Message->Data.Response = NULL; - } - HttpIo->RspToken.Message->HeaderCount = 0; - HttpIo->RspToken.Message->Headers = NULL; - HttpIo->RspToken.Message->BodyLength = ResponseData->BodyLength; - HttpIo->RspToken.Message->Body = ResponseData->Body; - - Http = HttpIo->Http; - HttpIo->IsRxDone = FALSE; - Status = Http->Response ( - Http, - &HttpIo->RspToken - ); - - if (EFI_ERROR (Status)) { - gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); - return Status; - } - - // - // Poll the network until receive finish. - // - while (!HttpIo->IsRxDone && ((HttpIo->TimeoutEvent == NULL) || EFI_ERROR (gBS->CheckEvent (HttpIo->TimeoutEvent)))) { - Http->Poll (Http); - } - - gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); - - if (!HttpIo->IsRxDone) { - // - // Timeout occurs, cancel the response token. - // - Http->Cancel (Http, &HttpIo->RspToken); - - Status = EFI_TIMEOUT; - - return Status; - } else { - HttpIo->IsRxDone = FALSE; + if (!PcdGetBool (PcdAllowHttpConnections) && (AsciiStrnCmp (Uri, "http://", 7) == 0)) { + DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: HTTP is disabled.\n")); + return EFI_ACCESS_DENIED; } - // - // Store the received data into the wrapper. - // - ResponseData->Status = HttpIo->RspToken.Status; - ResponseData->HeaderCount = HttpIo->RspToken.Message->HeaderCount; - ResponseData->Headers = HttpIo->RspToken.Message->Headers; - ResponseData->BodyLength = HttpIo->RspToken.Message->BodyLength; - return Status; } @@ -992,10 +547,10 @@ HttpIoRecvResponse ( Get the URI address string from the input device path. 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. - + @retval EFI_SUCCESS The URI string is returned. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @@ -1056,16 +611,16 @@ HttpBootParseFilePath ( and also the image's URI info. @param[in] Uri The pointer to the image's URI string. - @param[in] UriParser URI Parse result returned by NetHttpParseUrl(). - @param[in] HeaderCount Number of HTTP header structures in Headers list. + @param[in] UriParser URI Parse result returned by NetHttpParseUrl(). + @param[in] HeaderCount Number of HTTP header structures in Headers list. @param[in] Headers Array containing list of HTTP headers. @param[out] ImageType The image type of the downloaded file. - + @retval EFI_SUCCESS The image type is returned in ImageType. @retval EFI_INVALID_PARAMETER ImageType, Uri or UriParser is NULL. @retval EFI_INVALID_PARAMETER HeaderCount is not zero, and Headers is NULL. @retval EFI_NOT_FOUND Failed to identify the image type. - @retval Others Unexpect error happened. + @retval Others Unexpected error happened. **/ EFI_STATUS @@ -1092,13 +647,21 @@ HttpBootCheckImageType ( // // Determine the image type by the HTTP Content-Type header field first. - // "application/efi" -> EFI Image + // "application/efi" -> EFI Image + // "application/vnd.efi-iso" -> CD/DVD Image + // "application/vnd.efi-img" -> Virtual Disk Image // Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_TYPE); if (Header != NULL) { if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_EFI) == 0) { *ImageType = ImageTypeEfi; return EFI_SUCCESS; + } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_ISO) == 0) { + *ImageType = ImageTypeVirtualCd; + return EFI_SUCCESS; + } else if (AsciiStriCmp (Header->FieldValue, HTTP_CONTENT_TYPE_APP_IMG) == 0) { + *ImageType = ImageTypeVirtualDisk; + return EFI_SUCCESS; } } @@ -1135,7 +698,7 @@ HttpBootCheckImageType ( /** This function register the RAM disk info to the system. - + @param[in] Private The pointer to the driver's private data. @param[in] BufferSize The size of Buffer in bytes. @param[in] Buffer The base address of the RAM disk. @@ -1159,7 +722,7 @@ HttpBootRegisterRamDisk ( EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_GUID *RamDiskType; - + ASSERT (Private != NULL); ASSERT (Buffer != NULL); ASSERT (BufferSize != 0); @@ -1177,7 +740,7 @@ HttpBootRegisterRamDisk ( } else { return EFI_UNSUPPORTED; } - + Status = RamDisk->Register ( (UINTN)Buffer, (UINT64)BufferSize, @@ -1192,3 +755,25 @@ HttpBootRegisterRamDisk ( return Status; } +/** + Indicate if the HTTP status code indicates a redirection. + + @param[in] StatusCode HTTP status code from server. + + @return TRUE if it's redirection. + +**/ +BOOLEAN +HttpBootIsHttpRedirectStatusCode ( + IN EFI_HTTP_STATUS_CODE StatusCode + ) +{ + if (StatusCode == HTTP_STATUS_301_MOVED_PERMANENTLY || + StatusCode == HTTP_STATUS_302_FOUND || + StatusCode == HTTP_STATUS_307_TEMPORARY_REDIRECT || + StatusCode == HTTP_STATUS_308_PERMANENT_REDIRECT) { + return TRUE; + } + + return FALSE; +}