/** @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
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
//\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
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
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
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
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
} \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
//\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
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
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
{\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
}\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
UINTN ContentLength;\r
HTTP_BOOT_CACHE_CONTENT *Cache;\r
UINT8 *Block;\r
+ UINTN UrlSize;\r
CHAR16 *Url;\r
BOOLEAN IdentityMode;\r
UINTN ReceivedSize;\r
//\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
}\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
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
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
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
\r
if (*BufferSize < ContentLength) {\r
Status = EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ Status = EFI_SUCCESS;\r
}\r
*BufferSize = ContentLength;\r
\r
HttpFreeMsgParser (Parser);\r
}\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
\r
ERROR_6:\r
if (Parser != NULL) {\r