]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpBootDxe/HttpBootSupport.c
BaseTools/Capsule: Do not support -o with --dump-info
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootSupport.c
index 56c4c15836c956c1090c803441fe8d503c72ec45..b5974a514823568b9018af1888ab5e979a83d94e 100644 (file)
@@ -1,14 +1,14 @@
 /** @file\r
   Support functions implementation for UEFI HTTP boot driver.\r
 \r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials are licensed and made available under\r
 the terms and conditions of the BSD License that accompanies this distribution.\r
 The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php.                                          \r
-    \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
@@ -160,42 +160,46 @@ HttpBootPrintErrorMessage (
   AsciiPrint ("\n");\r
 \r
   switch (StatusCode) {\r
-  case HTTP_STATUS_300_MULTIPLE_CHIOCES:\r
+  case HTTP_STATUS_300_MULTIPLE_CHOICES:\r
     AsciiPrint ("\n  Redirection: 300 Multiple Choices");\r
-    break; \r
-    \r
+    break;\r
+\r
   case HTTP_STATUS_301_MOVED_PERMANENTLY:\r
     AsciiPrint ("\n  Redirection: 301 Moved Permanently");\r
-    break; \r
-    \r
+    break;\r
+\r
   case HTTP_STATUS_302_FOUND:\r
     AsciiPrint ("\n  Redirection: 302 Found");\r
-    break; \r
-    \r
+    break;\r
+\r
   case HTTP_STATUS_303_SEE_OTHER:\r
     AsciiPrint ("\n  Redirection: 303 See Other");\r
-    break; \r
+    break;\r
 \r
   case HTTP_STATUS_304_NOT_MODIFIED:\r
     AsciiPrint ("\n  Redirection: 304 Not Modified");\r
-    break; \r
+    break;\r
 \r
   case HTTP_STATUS_305_USE_PROXY:\r
     AsciiPrint ("\n  Redirection: 305 Use Proxy");\r
-    break; \r
+    break;\r
 \r
   case HTTP_STATUS_307_TEMPORARY_REDIRECT:\r
     AsciiPrint ("\n  Redirection: 307 Temporary Redirect");\r
-    break; \r
+    break;\r
+\r
+  case HTTP_STATUS_308_PERMANENT_REDIRECT:\r
+    AsciiPrint ("\n  Redirection: 308 Permanent Redirect");\r
+    break;\r
 \r
   case HTTP_STATUS_400_BAD_REQUEST:\r
     AsciiPrint ("\n  Client Error: 400 Bad Request");\r
     break;\r
-    \r
+\r
   case HTTP_STATUS_401_UNAUTHORIZED:\r
     AsciiPrint ("\n  Client Error: 401 Unauthorized");\r
     break;\r
-    \r
+\r
   case HTTP_STATUS_402_PAYMENT_REQUIRED:\r
     AsciiPrint ("\n  Client Error: 402 Payment Required");\r
     break;\r
@@ -285,7 +289,7 @@ HttpBootPrintErrorMessage (
     break;\r
 \r
   default: ;\r
-  \r
+\r
   }\r
 }\r
 \r
@@ -315,13 +319,13 @@ HttpBootCommonNotify (
 \r
   @retval EFI_SUCCESS             Operation succeeded.\r
   @retval EFI_DEVICE_ERROR        An unexpected network error occurred.\r
-  @retval Others                  Other errors as indicated.  \r
+  @retval Others                  Other errors as indicated.\r
 **/\r
 EFI_STATUS\r
 HttpBootDns (\r
   IN     HTTP_BOOT_PRIVATE_DATA   *Private,\r
   IN     CHAR16                   *HostName,\r
-     OUT EFI_IPv6_ADDRESS         *IpAddress \r
+     OUT EFI_IPv6_ADDRESS         *IpAddress\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -333,14 +337,14 @@ HttpBootDns (
   EFI_IPv6_ADDRESS                *DnsServerList;\r
   UINTN                           DnsServerListCount;\r
   UINTN                           DataSize;\r
-  BOOLEAN                         IsDone;  \r
-  \r
+  BOOLEAN                         IsDone;\r
+\r
   DnsServerList       = NULL;\r
   DnsServerListCount  = 0;\r
   Dns6                = NULL;\r
   Dns6Handle          = NULL;\r
   ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));\r
-  \r
+\r
   //\r
   // Get DNS server list from EFI IPv6 Configuration protocol.\r
   //\r
@@ -355,7 +359,7 @@ HttpBootDns (
       DnsServerList = AllocatePool (DataSize);\r
       if (DnsServerList == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
-      }  \r
+      }\r
 \r
       Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);\r
       if (EFI_ERROR (Status)) {\r
@@ -377,8 +381,8 @@ HttpBootDns (
              );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
-  } \r
-  \r
+  }\r
+\r
   Status = gBS->OpenProtocol (\r
                   Dns6Handle,\r
                   &gEfiDns6ProtocolGuid,\r
@@ -407,7 +411,7 @@ HttpBootDns (
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
-  \r
+\r
   Token.Status = EFI_NOT_READY;\r
   IsDone       = FALSE;\r
   //\r
@@ -435,11 +439,11 @@ HttpBootDns (
   while (!IsDone) {\r
     Dns6->Poll (Dns6);\r
   }\r
-  \r
+\r
   //\r
   // Name resolution is done, check result.\r
   //\r
-  Status = Token.Status;  \r
+  Status = Token.Status;\r
   if (!EFI_ERROR (Status)) {\r
     if (Token.RspData.H2AData == NULL) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -469,7 +473,7 @@ Exit:
 \r
   if (Dns6 != NULL) {\r
     Dns6->Configure (Dns6, NULL);\r
-    \r
+\r
     gBS->CloseProtocol (\r
            Dns6Handle,\r
            &gEfiDns6ProtocolGuid,\r
@@ -490,8 +494,8 @@ Exit:
   if (DnsServerList != NULL) {\r
     FreePool (DnsServerList);\r
   }\r
-  \r
-  return Status;  \r
+\r
+  return Status;\r
 }\r
 /**\r
   Create a HTTP_IO_HEADER to hold the HTTP header items.\r
@@ -499,7 +503,7 @@ Exit:
   @param[in]  MaxHeaderCount         The maximun number of HTTP header in this holder.\r
 \r
   @return    A pointer of the HTTP header holder or NULL if failed.\r
-  \r
+\r
 **/\r
 HTTP_IO_HEADER *\r
 HttpBootCreateHeader (\r
@@ -524,7 +528,7 @@ HttpBootCreateHeader (
 }\r
 \r
 /**\r
-  Destroy the HTTP_IO_HEADER and release the resouces. \r
+  Destroy the HTTP_IO_HEADER and release the resouces.\r
 \r
   @param[in]  HttpIoHeader       Point to the HTTP header holder to be destroyed.\r
 \r
@@ -535,7 +539,7 @@ HttpBootFreeHeader (
   )\r
 {\r
   UINTN      Index;\r
-  \r
+\r
   if (HttpIoHeader != NULL) {\r
     if (HttpIoHeader->HeaderCount != 0) {\r
       for (Index = 0; Index < HttpIoHeader->HeaderCount; Index++) {\r
@@ -558,7 +562,7 @@ HttpBootFreeHeader (
   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.\r
   @retval  EFI_OUT_OF_RESOURCES  Insufficient resource to complete the operation.\r
   @retval  Other                 Unexpected error happened.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 HttpBootSetHeader (\r
@@ -570,7 +574,7 @@ HttpBootSetHeader (
   EFI_HTTP_HEADER       *Header;\r
   UINTN                 StrSize;\r
   CHAR8                 *NewFieldValue;\r
-  \r
+\r
   if (HttpIoHeader == NULL || FieldName == NULL || FieldValue == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -614,7 +618,7 @@ HttpBootSetHeader (
     }\r
     CopyMem (NewFieldValue, FieldValue, StrSize);\r
     NewFieldValue[StrSize -1] = '\0';\r
-    \r
+\r
     if (Header->FieldValue != NULL) {\r
       FreePool (Header->FieldValue);\r
     }\r
@@ -667,8 +671,11 @@ HttpIoNotify (
   @param[in]  Controller     The handle of the controller.\r
   @param[in]  IpVersion      IP_VERSION_4 or IP_VERSION_6.\r
   @param[in]  ConfigData     The HTTP_IO configuration data.\r
+  @param[in]  Callback       Callback function which will be invoked when specified\r
+                             HTTP_IO_CALLBACK_EVENT happened.\r
+  @param[in]  Context        The Context data which will be passed to the Callback function.\r
   @param[out] HttpIo         The HTTP_IO.\r
-  \r
+\r
   @retval EFI_SUCCESS            The HTTP_IO is created and configured.\r
   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.\r
   @retval EFI_UNSUPPORTED        One or more of the control options are not\r
@@ -683,6 +690,8 @@ HttpIoCreateIo (
   IN EFI_HANDLE             Controller,\r
   IN UINT8                  IpVersion,\r
   IN HTTP_IO_CONFIG_DATA    *ConfigData,\r
+  IN HTTP_IO_CALLBACK       Callback,\r
+  IN VOID                   *Context,\r
   OUT HTTP_IO               *HttpIo\r
   )\r
 {\r
@@ -692,7 +701,7 @@ HttpIoCreateIo (
   EFI_HTTPv6_ACCESS_POINT   Http6AccessPoint;\r
   EFI_HTTP_PROTOCOL         *Http;\r
   EFI_EVENT                 Event;\r
-  \r
+\r
   if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (HttpIo == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -702,10 +711,10 @@ HttpIoCreateIo (
   }\r
 \r
   ZeroMem (HttpIo, sizeof (HTTP_IO));\r
-  \r
+\r
   //\r
   // Create the HTTP child instance and get the HTTP protocol.\r
-  //  \r
+  //\r
   Status = NetLibCreateServiceChild (\r
              Controller,\r
              Image,\r
@@ -735,25 +744,27 @@ HttpIoCreateIo (
   HttpIo->Controller  = Controller;\r
   HttpIo->IpVersion   = IpVersion;\r
   HttpIo->Http        = Http;\r
+  HttpIo->Callback    = Callback;\r
+  HttpIo->Context     = Context;\r
 \r
   ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA));\r
   HttpConfigData.HttpVersion        = HttpVersion11;\r
   HttpConfigData.TimeOutMillisec    = ConfigData->Config4.RequestTimeOut;\r
   if (HttpIo->IpVersion == IP_VERSION_4) {\r
     HttpConfigData.LocalAddressIsIPv6 = FALSE;\r
-    \r
+\r
     Http4AccessPoint.UseDefaultAddress = ConfigData->Config4.UseDefaultAddress;\r
     Http4AccessPoint.LocalPort         = ConfigData->Config4.LocalPort;\r
     IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Config4.LocalIp);\r
     IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config4.SubnetMask);\r
-    HttpConfigData.AccessPoint.IPv4Node = &Http4AccessPoint;   \r
+    HttpConfigData.AccessPoint.IPv4Node = &Http4AccessPoint;\r
   } else {\r
     HttpConfigData.LocalAddressIsIPv6 = TRUE;\r
     Http6AccessPoint.LocalPort        = ConfigData->Config6.LocalPort;\r
     IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Config6.LocalIp);\r
     HttpConfigData.AccessPoint.IPv6Node = &Http6AccessPoint;\r
   }\r
-  \r
+\r
   Status = Http->Configure (Http, &HttpConfigData);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
@@ -804,7 +815,7 @@ HttpIoCreateIo (
   HttpIo->TimeoutEvent = Event;\r
 \r
   return EFI_SUCCESS;\r
-  \r
+\r
 ON_ERROR:\r
   HttpIoDestroyIo (HttpIo);\r
 \r
@@ -812,7 +823,7 @@ ON_ERROR:
 }\r
 \r
 /**\r
-  Destroy the HTTP_IO and release the resouces. \r
+  Destroy the HTTP_IO and release the resouces.\r
 \r
   @param[in]  HttpIo          The HTTP_IO which wraps the HTTP service to be destroyed.\r
 \r
@@ -843,7 +854,7 @@ HttpIoDestroyIo (
   if (Event != NULL) {\r
     gBS->CloseEvent (Event);\r
   }\r
-  \r
+\r
   Http = HttpIo->Http;\r
   if (Http != NULL) {\r
     Http->Configure (Http, NULL);\r
@@ -865,14 +876,14 @@ HttpIoDestroyIo (
 \r
 /**\r
   Synchronously send a HTTP REQUEST message to the server.\r
-  \r
+\r
   @param[in]   HttpIo           The HttpIo wrapping the HTTP service.\r
   @param[in]   Request          A pointer to storage such data as URL and HTTP method.\r
-  @param[in]   HeaderCount      Number of HTTP header structures in Headers list. \r
+  @param[in]   HeaderCount      Number of HTTP header structures in Headers list.\r
   @param[in]   Headers          Array containing list of HTTP headers.\r
   @param[in]   BodyLength       Length in bytes of the HTTP body.\r
-  @param[in]   Body             Body associated with the HTTP request. \r
-  \r
+  @param[in]   Body             Body associated with the HTTP request.\r
+\r
   @retval EFI_SUCCESS            The HTTP request is trasmitted.\r
   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.\r
   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.\r
@@ -904,6 +915,17 @@ HttpIoSendRequest (
   HttpIo->ReqToken.Message->BodyLength   = BodyLength;\r
   HttpIo->ReqToken.Message->Body         = Body;\r
 \r
+  if (HttpIo->Callback != NULL) {\r
+    Status = HttpIo->Callback (\r
+               HttpIoRequest,\r
+               HttpIo->ReqToken.Message,\r
+               HttpIo->Context\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
   //\r
   // Queue the request token to HTTP instances.\r
   //\r
@@ -929,12 +951,12 @@ HttpIoSendRequest (
 \r
 /**\r
   Synchronously receive a HTTP RESPONSE message from the server.\r
-  \r
+\r
   @param[in]   HttpIo           The HttpIo wrapping the HTTP service.\r
   @param[in]   RecvMsgHeader    TRUE to receive a new HTTP response (from message header).\r
                                 FALSE to continue receive the previous response message.\r
   @param[out]  ResponseData     Point to a wrapper of the received response data.\r
-  \r
+\r
   @retval EFI_SUCCESS            The HTTP response is received.\r
   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.\r
   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.\r
@@ -984,7 +1006,7 @@ HttpIoRecvResponse (
                    Http,\r
                    &HttpIo->RspToken\r
                    );\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0);\r
     return Status;\r
@@ -1004,14 +1026,26 @@ HttpIoRecvResponse (
     // Timeout occurs, cancel the response token.\r
     //\r
     Http->Cancel (Http, &HttpIo->RspToken);\r
-   \r
+\r
     Status = EFI_TIMEOUT;\r
-    \r
+\r
     return Status;\r
   } else {\r
     HttpIo->IsRxDone = FALSE;\r
   }\r
 \r
+  if ((HttpIo->Callback != NULL) &&\r
+      (HttpIo->RspToken.Status == EFI_SUCCESS || HttpIo->RspToken.Status == EFI_HTTP_ERROR)) {\r
+    Status = HttpIo->Callback (\r
+               HttpIoResponse,\r
+               HttpIo->RspToken.Message,\r
+               HttpIo->Context\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
   //\r
   // Store the received data into the wrapper.\r
   //\r
@@ -1027,7 +1061,7 @@ HttpIoRecvResponse (
   This function checks the HTTP(S) URI scheme.\r
 \r
   @param[in]    Uri              The pointer to the URI string.\r
-  \r
+\r
   @retval EFI_SUCCESS            The URI scheme is valid.\r
   @retval EFI_INVALID_PARAMETER  The URI scheme is not HTTP or HTTPS.\r
   @retval EFI_ACCESS_DENIED      HTTP is disabled and the URI is HTTP.\r
@@ -1062,7 +1096,7 @@ HttpBootCheckUriScheme (
     DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: Invalid Uri.\n"));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   //\r
   // HTTP is disabled, return EFI_ACCESS_DENIED if the URI is HTTP.\r
   //\r
@@ -1078,10 +1112,10 @@ HttpBootCheckUriScheme (
   Get the URI address string from the input device path.\r
 \r
   Caller need to free the buffer in the UriAddress pointer.\r
-  \r
+\r
   @param[in]   FilePath         Pointer to the device path which contains a URI device path node.\r
   @param[out]  UriAddress       The URI address string extract from the device path.\r
-  \r
+\r
   @retval EFI_SUCCESS            The URI string is returned.\r
   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.\r
 \r
@@ -1142,11 +1176,11 @@ HttpBootParseFilePath (
   and also the image's URI info.\r
 \r
   @param[in]    Uri              The pointer to the image's URI string.\r
-  @param[in]    UriParser        URI Parse result returned by NetHttpParseUrl(). \r
-  @param[in]    HeaderCount      Number of HTTP header structures in Headers list. \r
+  @param[in]    UriParser        URI Parse result returned by NetHttpParseUrl().\r
+  @param[in]    HeaderCount      Number of HTTP header structures in Headers list.\r
   @param[in]    Headers          Array containing list of HTTP headers.\r
   @param[out]   ImageType        The image type of the downloaded file.\r
-  \r
+\r
   @retval EFI_SUCCESS            The image type is returned in ImageType.\r
   @retval EFI_INVALID_PARAMETER  ImageType, Uri or UriParser is NULL.\r
   @retval EFI_INVALID_PARAMETER  HeaderCount is not zero, and Headers is NULL.\r
@@ -1229,7 +1263,7 @@ HttpBootCheckImageType (
 \r
 /**\r
   This function register the RAM disk info to the system.\r
-  \r
+\r
   @param[in]       Private         The pointer to the driver's private data.\r
   @param[in]       BufferSize      The size of Buffer in bytes.\r
   @param[in]       Buffer          The base address of the RAM disk.\r
@@ -1253,7 +1287,7 @@ HttpBootRegisterRamDisk (
   EFI_STATUS                 Status;\r
   EFI_DEVICE_PATH_PROTOCOL   *DevicePath;\r
   EFI_GUID                   *RamDiskType;\r
-  \r
+\r
   ASSERT (Private != NULL);\r
   ASSERT (Buffer != NULL);\r
   ASSERT (BufferSize != 0);\r
@@ -1271,7 +1305,7 @@ HttpBootRegisterRamDisk (
   } else {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  \r
+\r
   Status = RamDisk->Register (\r
              (UINTN)Buffer,\r
              (UINT64)BufferSize,\r
@@ -1286,3 +1320,25 @@ HttpBootRegisterRamDisk (
   return Status;\r
 }\r
 \r
+/**\r
+  Indicate if the HTTP status code indicates a redirection.\r
+\r
+  @param[in]  StatusCode      HTTP status code from server.\r
+\r
+  @return                     TRUE if it's redirection.\r
+\r
+**/\r
+BOOLEAN\r
+HttpBootIsHttpRedirectStatusCode (\r
+  IN   EFI_HTTP_STATUS_CODE        StatusCode\r
+  )\r
+{\r
+  if (StatusCode == HTTP_STATUS_301_MOVED_PERMANENTLY ||\r
+      StatusCode == HTTP_STATUS_302_FOUND ||\r
+      StatusCode == HTTP_STATUS_307_TEMPORARY_REDIRECT ||\r
+      StatusCode == HTTP_STATUS_308_PERMANENT_REDIRECT) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r