X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FHttpBootDxe%2FHttpBootSupport.c;h=d508e2c1a979f85df8ace5f4a5c2940bdfb2c921;hb=2913ebb2b550f50a14f105e26995dd095e627ba4;hp=9410bf9e15209cf2c21eaf0121fef297985247ad;hpb=7570696c57d446f163050c2befb78b8fc6cfeb02;p=mirror_edk2.git diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c index 9410bf9e15..d508e2c1a9 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -1,7 +1,7 @@ /** @file Support functions implementation for UEFI HTTP boot driver. -Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2017, 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. @@ -86,11 +86,10 @@ HttpBootUintnToAscDecWithFormat ( { UINTN Remainder; - while (Length > 0) { - Length--; + for (; Length > 0; Length--) { Remainder = Number % 10; Number /= 10; - Buffer[Length] = (UINT8) ('0' + Remainder); + Buffer[Length - 1] = (UINT8) ('0' + Remainder); } } @@ -161,7 +160,7 @@ HttpBootPrintErrorMessage ( AsciiPrint ("\n"); switch (StatusCode) { - case HTTP_STATUS_300_MULTIPLE_CHIOCES: + case HTTP_STATUS_300_MULTIPLE_CHOICES: AsciiPrint ("\n Redirection: 300 Multiple Choices"); break; @@ -187,6 +186,10 @@ HttpBootPrintErrorMessage ( case HTTP_STATUS_307_TEMPORARY_REDIRECT: AsciiPrint ("\n Redirection: 307 Temporary Redirect"); + break; + + case HTTP_STATUS_308_PERMANENT_REDIRECT: + AsciiPrint ("\n Redirection: 308 Permanent Redirect"); break; case HTTP_STATUS_400_BAD_REQUEST: @@ -625,6 +628,41 @@ HttpBootSetHeader ( return EFI_SUCCESS; } +/** + Notify the callback function when an event is triggered. + + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotifyDpc ( + IN VOID *Context + ) +{ + *((BOOLEAN *) Context) = TRUE; +} + +/** + Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK. + + @param[in] Event The event signaled. + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK + // + QueueDpc (TPL_CALLBACK, HttpIoNotifyDpc, Context); +} + /** Create a HTTP_IO to access the HTTP service. It will create and configure a HTTP child handle. @@ -633,6 +671,9 @@ HttpBootSetHeader ( @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[in] Callback Callback function which will be invoked when specified + HTTP_IO_CALLBACK_EVENT happened. + @param[in] Context The Context data which will be passed to the Callback function. @param[out] HttpIo The HTTP_IO. @retval EFI_SUCCESS The HTTP_IO is created and configured. @@ -649,6 +690,8 @@ HttpIoCreateIo ( IN EFI_HANDLE Controller, IN UINT8 IpVersion, IN HTTP_IO_CONFIG_DATA *ConfigData, + IN HTTP_IO_CALLBACK Callback, + IN VOID *Context, OUT HTTP_IO *HttpIo ) { @@ -701,6 +744,8 @@ HttpIoCreateIo ( HttpIo->Controller = Controller; HttpIo->IpVersion = IpVersion; HttpIo->Http = Http; + HttpIo->Callback = Callback; + HttpIo->Context = Context; ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); HttpConfigData.HttpVersion = HttpVersion11; @@ -731,7 +776,7 @@ HttpIoCreateIo ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, - HttpBootCommonNotify, + HttpIoNotify, &HttpIo->IsTxDone, &Event ); @@ -744,7 +789,7 @@ HttpIoCreateIo ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, - HttpBootCommonNotify, + HttpIoNotify, &HttpIo->IsRxDone, &Event ); @@ -870,6 +915,17 @@ HttpIoSendRequest ( HttpIo->ReqToken.Message->BodyLength = BodyLength; HttpIo->ReqToken.Message->Body = Body; + if (HttpIo->Callback != NULL) { + Status = HttpIo->Callback ( + HttpIoRequest, + HttpIo->ReqToken.Message, + HttpIo->Context + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + // // Queue the request token to HTTP instances. // @@ -978,6 +1034,18 @@ HttpIoRecvResponse ( HttpIo->IsRxDone = FALSE; } + if ((HttpIo->Callback != NULL) && + (HttpIo->RspToken.Status == EFI_SUCCESS || HttpIo->RspToken.Status == EFI_HTTP_ERROR)) { + Status = HttpIo->Callback ( + HttpIoResponse, + HttpIo->RspToken.Message, + HttpIo->Context + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + // // Store the received data into the wrapper. // @@ -989,6 +1057,57 @@ HttpIoRecvResponse ( return Status; } +/** + This function checks the HTTP(S) URI scheme. + + @param[in] Uri The pointer to the URI string. + + @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 +HttpBootCheckUriScheme ( + IN CHAR8 *Uri + ) +{ + UINTN Index; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + // + // Convert the scheme to all lower case. + // + for (Index = 0; Index < AsciiStrLen (Uri); Index++) { + if (Uri[Index] == ':') { + break; + } + if (Uri[Index] >= 'A' && Uri[Index] <= 'Z') { + Uri[Index] -= (CHAR8)('A' - 'a'); + } + } + + // + // Return EFI_INVALID_PARAMETER if the URI is not HTTP or HTTPS. + // + if ((AsciiStrnCmp (Uri, "http://", 7) != 0) && (AsciiStrnCmp (Uri, "https://", 8) != 0)) { + DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: Invalid Uri.\n")); + return EFI_INVALID_PARAMETER; + } + + // + // HTTP is disabled, return EFI_ACCESS_DENIED if the URI is HTTP. + // + if (!PcdGetBool (PcdAllowHttpConnections) && (AsciiStrnCmp (Uri, "http://", 7) == 0)) { + DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: HTTP is disabled.\n")); + return EFI_ACCESS_DENIED; + } + + return Status; +} + /** Get the URI address string from the input device path. @@ -1093,13 +1212,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; } } @@ -1193,3 +1320,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; +}