]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpBootDxe/HttpBootClient.c
NetworkPkg/HttpBootDxe: Add HTTP Boot Callback protocol support.
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootClient.c
index 9d445e3c8e7c59f8698c029b91a53d4f9e41d498..68f5a49bad9ab609a3b6f34209b5cfd940c46ff3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of the boot file download function.\r
 \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2017, 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
@@ -191,6 +191,15 @@ HttpBootDhcp4ExtractUriInfo (
     Private->BootFileUri = Private->FilePathUri;\r
   }\r
 \r
+  //\r
+  // Check the URI scheme.\r
+  //\r
+  Status = HttpBootCheckUriScheme (Private->BootFileUri);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "HttpBootDhcp4ExtractUriInfo: %r.\n", Status));\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Configure the default DNS server if server assigned.\r
   //\r
@@ -224,7 +233,6 @@ HttpBootDhcp4ExtractUriInfo (
   //\r
   // All boot informations are valid here.\r
   //\r
-  AsciiPrint ("\n  URI: %a", Private->BootFileUri);\r
 \r
   //\r
   // Update the device path to include the IP and boot URI information.\r
@@ -255,6 +263,7 @@ HttpBootDhcp6ExtractUriInfo (
   EFI_DHCP6_PACKET_OPTION         *Option;\r
   EFI_IPv6_ADDRESS                IpAddr;\r
   CHAR8                           *HostName;\r
+  UINTN                           HostNameSize;\r
   CHAR16                          *HostNameStr;\r
   EFI_STATUS                      Status;\r
 \r
@@ -293,6 +302,15 @@ HttpBootDhcp6ExtractUriInfo (
     Private->BootFileUri = Private->FilePathUri;\r
   }\r
 \r
+  //\r
+  // Check the URI scheme.\r
+  //\r
+  Status = HttpBootCheckUriScheme (Private->BootFileUri);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "HttpBootDhcp6ExtractUriInfo: %r.\n", Status));\r
+    return Status;\r
+  }\r
+\r
   //\r
   //  Set the Local station address to IP layer.\r
   //\r
@@ -300,6 +318,14 @@ HttpBootDhcp6ExtractUriInfo (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
+  //\r
+  // Register the IPv6 gateway address to the network device.\r
+  //\r
+  Status = HttpBootSetIp6Gateway (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
   \r
   //\r
   // Configure the default DNS server if server assigned.\r
@@ -341,14 +367,15 @@ HttpBootDhcp6ExtractUriInfo (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-    \r
-    HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16));\r
+\r
+    HostNameSize = AsciiStrSize (HostName);\r
+    HostNameStr = AllocateZeroPool (HostNameSize * sizeof (CHAR16));\r
     if (HostNameStr == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Error;\r
     }\r
     \r
-    AsciiStrToUnicodeStr (HostName, HostNameStr);\r
+    AsciiStrToUnicodeStrS (HostName, HostNameStr, HostNameSize);\r
     Status = HttpBootDns (Private, HostNameStr, &IpAddr);\r
     FreePool (HostNameStr);\r
     if (EFI_ERROR (Status)) {\r
@@ -356,15 +383,7 @@ HttpBootDhcp6ExtractUriInfo (
     }  \r
   } \r
   \r
-  CopyMem (&Private->ServerIp.v6, &IpAddr, sizeof (EFI_IPv6_ADDRESS));  \r
-    \r
-  //\r
-  // register the IPv6 gateway address to the network device.\r
-  //\r
-  Status = HttpBootSetIp6Gateway (Private);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  CopyMem (&Private->ServerIp.v6, &IpAddr, sizeof (EFI_IPv6_ADDRESS));\r
   \r
   //\r
   // Extract the port from URL, and use default HTTP port 80 if not provided.\r
@@ -381,7 +400,7 @@ HttpBootDhcp6ExtractUriInfo (
   //\r
   // All boot informations are valid here.\r
   //\r
-  AsciiPrint ("\n  URI: %a", Private->BootFileUri);\r
+\r
   //\r
   // Update the device path to include the IP and boot URI information.\r
   //\r
@@ -431,6 +450,40 @@ HttpBootDiscoverBootInfo (
   return Status;\r
 }\r
 \r
+/**\r
+  HttpIo Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened.\r
+\r
+  @param[in]    EventType      Indicate the Event type that occurs in the current callback.\r
+  @param[in]    Message        HTTP message which will be send to, or just received from HTTP server.\r
+  @param[in]    Context        The Callback Context pointer.\r
+  \r
+  @retval EFI_SUCCESS          Tells the HttpIo to continue the HTTP process.\r
+  @retval Others               Tells the HttpIo to abort the current HTTP process.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HttpBootHttpIoCallback (\r
+  IN  HTTP_IO_CALLBACK_EVENT    EventType,\r
+  IN  EFI_HTTP_MESSAGE          *Message,\r
+  IN  VOID                      *Context\r
+  )\r
+{\r
+  HTTP_BOOT_PRIVATE_DATA       *Private;\r
+  EFI_STATUS                   Status;\r
+  Private = (HTTP_BOOT_PRIVATE_DATA *) Context;\r
+  if (Private->HttpBootCallback != NULL) {\r
+    Status = Private->HttpBootCallback->Callback (\r
+               Private->HttpBootCallback,\r
+               EventType == HttpIoRequest ? HttpBootHttpRequest : HttpBootHttpResponse,\r
+               EventType == HttpIoRequest ? FALSE : TRUE,\r
+               sizeof (EFI_HTTP_MESSAGE),\r
+               (VOID *) Message\r
+               );\r
+    return Status;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Create a HttpIo instance for the file download.\r
 \r
@@ -470,6 +523,8 @@ HttpBootCreateHttpIo (
              Private->Controller,\r
              Private->UsingIpv6 ? IP_VERSION_6 : IP_VERSION_4,\r
              &ConfigData,\r
+             HttpBootHttpIoCallback,\r
+             (VOID *) Private,\r
              &Private->HttpIo\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -666,6 +721,8 @@ HttpBootGetBootFileCallback (
 {\r
   HTTP_BOOT_CALLBACK_DATA      *CallbackData;\r
   HTTP_BOOT_ENTITY_DATA        *NewEntityData;\r
+  EFI_STATUS                   Status;\r
+  EFI_HTTP_BOOT_CALLBACK_PROTOCOL   *HttpBootCallback;\r
 \r
   //\r
   // We only care about the entity data.\r
@@ -675,6 +732,19 @@ HttpBootGetBootFileCallback (
   }\r
 \r
   CallbackData = (HTTP_BOOT_CALLBACK_DATA *) Context;\r
+  HttpBootCallback = CallbackData->Private->HttpBootCallback;\r
+  if (HttpBootCallback != NULL) {\r
+    Status = HttpBootCallback->Callback (\r
+               HttpBootCallback,\r
+               HttpBootHttpEntityBody,\r
+               TRUE,\r
+               (UINT32)Length,\r
+               Data\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
   //\r
   // Copy data if caller has provided a buffer.\r
   //\r
@@ -752,6 +822,7 @@ HttpBootGetBootFile (
   UINTN                      ContentLength;\r
   HTTP_BOOT_CACHE_CONTENT    *Cache;\r
   UINT8                      *Block;\r
+  UINTN                      UrlSize;\r
   CHAR16                     *Url;\r
   BOOLEAN                    IdentityMode;\r
   UINTN                      ReceivedSize;\r
@@ -770,11 +841,12 @@ HttpBootGetBootFile (
   //\r
   // First, check whether we already cached the requested Uri.\r
   //\r
-  Url = AllocatePool ((AsciiStrLen (Private->BootFileUri) + 1) * sizeof (CHAR16));\r
+  UrlSize = AsciiStrSize (Private->BootFileUri);\r
+  Url = AllocatePool (UrlSize * sizeof (CHAR16));\r
   if (Url == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  AsciiStrToUnicodeStr (Private->BootFileUri, Url);\r
+  AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);\r
   if (!HeaderOnly) {\r
     Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType);\r
     if (Status != EFI_NOT_FOUND) {\r
@@ -873,11 +945,6 @@ HttpBootGetBootFile (
   }\r
   RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;\r
   RequestData->Url = Url;\r
-  if (RequestData->Url == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ERROR_4;\r
-  }\r
-  AsciiStrToUnicodeStr (Private->BootFileUri, RequestData->Url);\r
 \r
   //\r
   // 2.3 Record the request info in a temp cache item.\r
@@ -960,6 +1027,7 @@ HttpBootGetBootFile (
   Context.Buffer     = Buffer;\r
   Context.BufferSize = *BufferSize;\r
   Context.Cache      = Cache;\r
+  Context.Private    = Private;\r
   Status = HttpInitMsgParser (\r
              HeaderOnly? HttpMethodHead : HttpMethodGet,\r
              ResponseData->Response.StatusCode,\r
@@ -1008,10 +1076,25 @@ HttpBootGetBootFile (
                    FALSE,\r
                    &ResponseBody\r
                    );\r
-        if (EFI_ERROR (Status)) {\r
+        if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {\r
+          if (EFI_ERROR (ResponseBody.Status)) {\r
+            Status = ResponseBody.Status;\r
+          }\r
           goto ERROR_6;\r
         }\r
         ReceivedSize += ResponseBody.BodyLength;\r
+        if (Private->HttpBootCallback != NULL) {\r
+          Status = Private->HttpBootCallback->Callback (\r
+                     Private->HttpBootCallback,\r
+                     HttpBootHttpEntityBody,\r
+                     TRUE,\r
+                     (UINT32)ResponseBody.BodyLength,\r
+                     ResponseBody.Body\r
+                     );\r
+          if (EFI_ERROR (Status)) {\r
+            goto ERROR_6;\r
+          }\r
+        }\r
       }\r
     } else {\r
       //\r
@@ -1045,7 +1128,10 @@ HttpBootGetBootFile (
                    FALSE,\r
                    &ResponseBody\r
                    );\r
-        if (EFI_ERROR (Status)) {\r
+        if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {\r
+          if (EFI_ERROR (ResponseBody.Status)) {\r
+            Status = ResponseBody.Status;\r
+          }\r
           goto ERROR_6;\r
         }\r
 \r
@@ -1074,6 +1160,8 @@ HttpBootGetBootFile (
 \r
   if (*BufferSize < ContentLength) {\r
     Status = EFI_BUFFER_TOO_SMALL;\r
+  } else {\r
+    Status = EFI_SUCCESS;\r
   }\r
   *BufferSize = ContentLength;\r
 \r
@@ -1089,7 +1177,7 @@ HttpBootGetBootFile (
     HttpFreeMsgParser (Parser);\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
   \r
 ERROR_6:\r
   if (Parser != NULL) {\r