/** @file
  Implementation of the boot file download function.

Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HttpBootDxe.h"

/**
  Update the device path node to include the boot resource information.

  @param[in]    Private            The pointer to the driver's private data.

  @retval EFI_SUCCESS              Device patch successfully updated.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  @retval Others                   Unexpected error happened.

**/
EFI_STATUS
HttpBootUpdateDevicePath (
  IN   HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  EFI_DEV_PATH              *Node;
  EFI_DEVICE_PATH_PROTOCOL  *TmpIpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *TmpDnsDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
  UINTN                     Length;
  EFI_STATUS                Status;

  TmpIpDevicePath  = NULL;
  TmpDnsDevicePath = NULL;

  //
  // Update the IP node with DHCP assigned information.
  //
  if (!Private->UsingIpv6) {
    Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
    if (Node == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Node->Ipv4.Header.Type    = MESSAGING_DEVICE_PATH;
    Node->Ipv4.Header.SubType = MSG_IPv4_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
    CopyMem (&Node->Ipv4.LocalIpAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));
    Node->Ipv4.RemotePort      = Private->Port;
    Node->Ipv4.Protocol        = EFI_IP_PROTO_TCP;
    Node->Ipv4.StaticIpAddress = FALSE;
    CopyMem (&Node->Ipv4.GatewayIpAddress, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Node->Ipv4.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
  } else {
    Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
    if (Node == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Node->Ipv6.Header.Type    = MESSAGING_DEVICE_PATH;
    Node->Ipv6.Header.SubType = MSG_IPv6_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
    Node->Ipv6.PrefixLength    = IP6_PREFIX_LENGTH;
    Node->Ipv6.RemotePort      = Private->Port;
    Node->Ipv6.Protocol        = EFI_IP_PROTO_TCP;
    Node->Ipv6.IpAddressOrigin = 0;
    CopyMem (&Node->Ipv6.LocalIpAddress, &Private->StationIp.v6, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&Node->Ipv6.RemoteIpAddress, &Private->ServerIp.v6, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&Node->Ipv6.GatewayIpAddress, &Private->GatewayIp.v6, sizeof (EFI_IPv6_ADDRESS));
  }

  TmpIpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
  FreePool (Node);
  if (TmpIpDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Update the DNS node with DNS server IP list if existed.
  //
  if (Private->DnsServerIp != NULL) {
    Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (Node->Dns.IsIPv6) + Private->DnsServerCount * sizeof (EFI_IP_ADDRESS);
    Node   = AllocatePool (Length);
    if (Node == NULL) {
      FreePool (TmpIpDevicePath);
      return EFI_OUT_OF_RESOURCES;
    }

    Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
    Node->DevPath.SubType = MSG_DNS_DP;
    SetDevicePathNodeLength (Node, Length);
    Node->Dns.IsIPv6 = Private->UsingIpv6 ? 0x01 : 0x00;
    CopyMem ((UINT8 *)Node + sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (Node->Dns.IsIPv6), Private->DnsServerIp, Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));

    TmpDnsDevicePath = AppendDevicePathNode (TmpIpDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
    FreePool (Node);
    FreePool (TmpIpDevicePath);
    TmpIpDevicePath = NULL;
    if (TmpDnsDevicePath == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // Update the URI node with the boot file URI.
  //
  Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (Private->BootFileUri);
  Node   = AllocatePool (Length);
  if (Node == NULL) {
    if (TmpIpDevicePath != NULL) {
      FreePool (TmpIpDevicePath);
    }

    if (TmpDnsDevicePath != NULL) {
      FreePool (TmpDnsDevicePath);
    }

    return EFI_OUT_OF_RESOURCES;
  }

  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
  Node->DevPath.SubType = MSG_URI_DP;
  SetDevicePathNodeLength (Node, Length);
  CopyMem ((UINT8 *)Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), Private->BootFileUri, AsciiStrSize (Private->BootFileUri));

  if (TmpDnsDevicePath != NULL) {
    NewDevicePath = AppendDevicePathNode (TmpDnsDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
    FreePool (TmpDnsDevicePath);
  } else {
    ASSERT (TmpIpDevicePath != NULL);
    NewDevicePath = AppendDevicePathNode (TmpIpDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
    FreePool (TmpIpDevicePath);
  }

  FreePool (Node);
  if (NewDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!Private->UsingIpv6) {
    //
    // Reinstall the device path protocol of the child handle.
    //
    Status = gBS->ReinstallProtocolInterface (
                    Private->Ip4Nic->Controller,
                    &gEfiDevicePathProtocolGuid,
                    Private->Ip4Nic->DevicePath,
                    NewDevicePath
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    FreePool (Private->Ip4Nic->DevicePath);
    Private->Ip4Nic->DevicePath = NewDevicePath;
  } else {
    //
    // Reinstall the device path protocol of the child handle.
    //
    Status = gBS->ReinstallProtocolInterface (
                    Private->Ip6Nic->Controller,
                    &gEfiDevicePathProtocolGuid,
                    Private->Ip6Nic->DevicePath,
                    NewDevicePath
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    FreePool (Private->Ip6Nic->DevicePath);
    Private->Ip6Nic->DevicePath = NewDevicePath;
  }

  return EFI_SUCCESS;
}

/**
  Parse the boot file URI information from the selected Dhcp4 offer packet.

  @param[in]    Private        The pointer to the driver's private data.

  @retval EFI_SUCCESS          Successfully parsed out all the boot information.
  @retval Others               Failed to parse out the boot information.

**/
EFI_STATUS
HttpBootDhcp4ExtractUriInfo (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  HTTP_BOOT_DHCP4_PACKET_CACHE  *SelectOffer;
  HTTP_BOOT_DHCP4_PACKET_CACHE  *HttpOffer;
  UINT32                        SelectIndex;
  UINT32                        ProxyIndex;
  UINT32                        DnsServerIndex;
  EFI_DHCP4_PACKET_OPTION       *Option;
  EFI_STATUS                    Status;

  ASSERT (Private != NULL);
  ASSERT (Private->SelectIndex != 0);
  SelectIndex = Private->SelectIndex - 1;
  ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);

  DnsServerIndex = 0;

  Status = EFI_SUCCESS;

  //
  // SelectOffer contains the IP address configuration and name server configuration.
  // HttpOffer contains the boot file URL.
  //
  SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp4;
  if (Private->FilePathUri == NULL) {
    //
    // In Corporate environment, we need a HttpOffer.
    //
    if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
        (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
        (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns))
    {
      HttpOffer = SelectOffer;
    } else {
      ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
      ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
      HttpOffer  = &Private->OfferBuffer[ProxyIndex].Dhcp4;
    }

    Private->BootFileUriParser = HttpOffer->UriParser;
    Private->BootFileUri       = (CHAR8 *)HttpOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data;
  } else {
    //
    // In Home environment the BootFileUri comes from the FilePath.
    //
    Private->BootFileUriParser = Private->FilePathUriParser;
    Private->BootFileUri       = Private->FilePathUri;
  }

  //
  // Check the URI scheme.
  //
  Status = HttpBootCheckUriScheme (Private->BootFileUri);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "HttpBootDhcp4ExtractUriInfo: %r.\n", Status));
    if (Status == EFI_INVALID_PARAMETER) {
      AsciiPrint ("\n  Error: Invalid URI address.\n");
    } else if (Status == EFI_ACCESS_DENIED) {
      AsciiPrint ("\n  Error: Access forbidden, only HTTPS connection is allowed.\n");
    }

    return Status;
  }

  if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
      (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
      (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns))
  {
    Option = SelectOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER];
    ASSERT (Option != NULL);

    //
    // Record the Dns Server address list.
    //
    Private->DnsServerCount = (Option->Length) / sizeof (EFI_IPv4_ADDRESS);

    Private->DnsServerIp = AllocateZeroPool (Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));
    if (Private->DnsServerIp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    for (DnsServerIndex = 0; DnsServerIndex < Private->DnsServerCount; DnsServerIndex++) {
      CopyMem (&(Private->DnsServerIp[DnsServerIndex].v4), &(((EFI_IPv4_ADDRESS *)Option->Data)[DnsServerIndex]), sizeof (EFI_IPv4_ADDRESS));
    }

    //
    // Configure the default DNS server if server assigned.
    //
    Status = HttpBootRegisterIp4Dns (
               Private,
               Option->Length,
               Option->Data
               );
    if (EFI_ERROR (Status)) {
      FreePool (Private->DnsServerIp);
      Private->DnsServerIp = NULL;
      return Status;
    }
  }

  //
  // Extract the port from URL, and use default HTTP port 80 if not provided.
  //
  Status = HttpUrlGetPort (
             Private->BootFileUri,
             Private->BootFileUriParser,
             &Private->Port
             );
  if (EFI_ERROR (Status) || (Private->Port == 0)) {
    Private->Port = 80;
  }

  //
  // All boot informations are valid here.
  //

  //
  // Update the device path to include the boot resource information.
  //
  Status = HttpBootUpdateDevicePath (Private);
  if (EFI_ERROR (Status) && (Private->DnsServerIp != NULL)) {
    FreePool (Private->DnsServerIp);
    Private->DnsServerIp = NULL;
  }

  return Status;
}

/**
  Parse the boot file URI information from the selected Dhcp6 offer packet.

  @param[in]    Private        The pointer to the driver's private data.

  @retval EFI_SUCCESS          Successfully parsed out all the boot information.
  @retval Others               Failed to parse out the boot information.

**/
EFI_STATUS
HttpBootDhcp6ExtractUriInfo (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  HTTP_BOOT_DHCP6_PACKET_CACHE  *SelectOffer;
  HTTP_BOOT_DHCP6_PACKET_CACHE  *HttpOffer;
  UINT32                        SelectIndex;
  UINT32                        ProxyIndex;
  UINT32                        DnsServerIndex;
  EFI_DHCP6_PACKET_OPTION       *Option;
  EFI_IPv6_ADDRESS              IpAddr;
  CHAR8                         *HostName;
  UINTN                         HostNameSize;
  CHAR16                        *HostNameStr;
  EFI_STATUS                    Status;

  ASSERT (Private != NULL);
  ASSERT (Private->SelectIndex != 0);
  SelectIndex = Private->SelectIndex - 1;
  ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);

  DnsServerIndex = 0;

  Status   = EFI_SUCCESS;
  HostName = NULL;
  //
  // SelectOffer contains the IP address configuration and name server configuration.
  // HttpOffer contains the boot file URL.
  //
  SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp6;
  if (Private->FilePathUri == NULL) {
    //
    // In Corporate environment, we need a HttpOffer.
    //
    if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
        (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
        (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns))
    {
      HttpOffer = SelectOffer;
    } else {
      ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
      ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
      HttpOffer  = &Private->OfferBuffer[ProxyIndex].Dhcp6;
    }

    Private->BootFileUriParser = HttpOffer->UriParser;
    Private->BootFileUri       = (CHAR8 *)HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;
  } else {
    //
    // In Home environment the BootFileUri comes from the FilePath.
    //
    Private->BootFileUriParser = Private->FilePathUriParser;
    Private->BootFileUri       = Private->FilePathUri;
  }

  //
  // Check the URI scheme.
  //
  Status = HttpBootCheckUriScheme (Private->BootFileUri);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "HttpBootDhcp6ExtractUriInfo: %r.\n", Status));
    if (Status == EFI_INVALID_PARAMETER) {
      AsciiPrint ("\n  Error: Invalid URI address.\n");
    } else if (Status == EFI_ACCESS_DENIED) {
      AsciiPrint ("\n  Error: Access forbidden, only HTTPS connection is allowed.\n");
    }

    return Status;
  }

  //
  //  Set the Local station address to IP layer.
  //
  Status = HttpBootSetIp6Address (Private);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Register the IPv6 gateway address to the network device.
  //
  Status = HttpBootSetIp6Gateway (Private);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
      (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
      (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns))
  {
    Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
    ASSERT (Option != NULL);

    //
    // Record the Dns Server address list.
    //
    Private->DnsServerCount = HTONS (Option->OpLen) / sizeof (EFI_IPv6_ADDRESS);

    Private->DnsServerIp = AllocateZeroPool (Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));
    if (Private->DnsServerIp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    for (DnsServerIndex = 0; DnsServerIndex < Private->DnsServerCount; DnsServerIndex++) {
      CopyMem (&(Private->DnsServerIp[DnsServerIndex].v6), &(((EFI_IPv6_ADDRESS *)Option->Data)[DnsServerIndex]), sizeof (EFI_IPv6_ADDRESS));
    }

    //
    // Configure the default DNS server if server assigned.
    //
    Status = HttpBootSetIp6Dns (
               Private,
               HTONS (Option->OpLen),
               Option->Data
               );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }

  //
  // Extract the HTTP server Ip from URL. This is used to Check route table
  // whether can send message to HTTP Server Ip through the GateWay.
  //
  Status = HttpUrlGetIp6 (
             Private->BootFileUri,
             Private->BootFileUriParser,
             &IpAddr
             );

  if (EFI_ERROR (Status)) {
    //
    // The Http server address is expressed by Name Ip, so perform DNS resolution
    //
    Status = HttpUrlGetHostName (
               Private->BootFileUri,
               Private->BootFileUriParser,
               &HostName
               );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    HostNameSize = AsciiStrSize (HostName);
    HostNameStr  = AllocateZeroPool (HostNameSize * sizeof (CHAR16));
    if (HostNameStr == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    AsciiStrToUnicodeStrS (HostName, HostNameStr, HostNameSize);

    if (HostName != NULL) {
      FreePool (HostName);
    }

    Status = HttpBootDns (Private, HostNameStr, &IpAddr);
    FreePool (HostNameStr);
    if (EFI_ERROR (Status)) {
      AsciiPrint ("\n  Error: Could not retrieve the host address from DNS server.\n");
      goto Error;
    }
  }

  CopyMem (&Private->ServerIp.v6, &IpAddr, sizeof (EFI_IPv6_ADDRESS));

  //
  // Extract the port from URL, and use default HTTP port 80 if not provided.
  //
  Status = HttpUrlGetPort (
             Private->BootFileUri,
             Private->BootFileUriParser,
             &Private->Port
             );
  if (EFI_ERROR (Status) || (Private->Port == 0)) {
    Private->Port = 80;
  }

  //
  // All boot informations are valid here.
  //

  //
  // Update the device path to include the boot resource information.
  //
  Status = HttpBootUpdateDevicePath (Private);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  return Status;

Error:
  if (Private->DnsServerIp != NULL) {
    FreePool (Private->DnsServerIp);
    Private->DnsServerIp = NULL;
  }

  return Status;
}

/**
  Discover all the boot information for boot file.

  @param[in, out]    Private        The pointer to the driver's private data.

  @retval EFI_SUCCESS          Successfully obtained all the boot information .
  @retval Others               Failed to retrieve the boot information.

**/
EFI_STATUS
HttpBootDiscoverBootInfo (
  IN OUT HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS  Status;

  //
  // Start D.O.R.A/S.A.R.R exchange to acquire station ip address and
  // other Http boot information.
  //
  Status = HttpBootDhcp (Private);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!Private->UsingIpv6) {
    Status = HttpBootDhcp4ExtractUriInfo (Private);
  } else {
    Status = HttpBootDhcp6ExtractUriInfo (Private);
  }

  return Status;
}

/**
  HttpIo Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened.

  @param[in]    EventType      Indicate the Event type that occurs in the current callback.
  @param[in]    Message        HTTP message which will be send to, or just received from HTTP server.
  @param[in]    Context        The Callback Context pointer.

  @retval EFI_SUCCESS          Tells the HttpIo to continue the HTTP process.
  @retval Others               Tells the HttpIo to abort the current HTTP process.
**/
EFI_STATUS
EFIAPI
HttpBootHttpIoCallback (
  IN  HTTP_IO_CALLBACK_EVENT  EventType,
  IN  EFI_HTTP_MESSAGE        *Message,
  IN  VOID                    *Context
  )
{
  HTTP_BOOT_PRIVATE_DATA  *Private;
  EFI_STATUS              Status;

  Private = (HTTP_BOOT_PRIVATE_DATA *)Context;
  if (Private->HttpBootCallback != NULL) {
    Status = Private->HttpBootCallback->Callback (
                                          Private->HttpBootCallback,
                                          EventType == HttpIoRequest ? HttpBootHttpRequest : HttpBootHttpResponse,
                                          EventType == HttpIoRequest ? FALSE : TRUE,
                                          sizeof (EFI_HTTP_MESSAGE),
                                          (VOID *)Message
                                          );
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Create a HttpIo instance for the file download.

  @param[in]    Private        The pointer to the driver's private data.

  @retval EFI_SUCCESS          Successfully created.
  @retval Others               Failed to create HttpIo.

**/
EFI_STATUS
HttpBootCreateHttpIo (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  HTTP_IO_CONFIG_DATA  ConfigData;
  EFI_STATUS           Status;
  EFI_HANDLE           ImageHandle;
  UINT32               TimeoutValue;

  ASSERT (Private != NULL);

  //
  // Get HTTP timeout value
  //
  TimeoutValue = PcdGet32 (PcdHttpIoTimeout);

  ZeroMem (&ConfigData, sizeof (HTTP_IO_CONFIG_DATA));
  if (!Private->UsingIpv6) {
    ConfigData.Config4.HttpVersion    = HttpVersion11;
    ConfigData.Config4.RequestTimeOut = TimeoutValue;
    IP4_COPY_ADDRESS (&ConfigData.Config4.LocalIp, &Private->StationIp.v4);
    IP4_COPY_ADDRESS (&ConfigData.Config4.SubnetMask, &Private->SubnetMask.v4);
    ImageHandle = Private->Ip4Nic->ImageHandle;
  } else {
    ConfigData.Config6.HttpVersion    = HttpVersion11;
    ConfigData.Config6.RequestTimeOut = TimeoutValue;
    IP6_COPY_ADDRESS (&ConfigData.Config6.LocalIp, &Private->StationIp.v6);
    ImageHandle = Private->Ip6Nic->ImageHandle;
  }

  Status = HttpIoCreateIo (
             ImageHandle,
             Private->Controller,
             Private->UsingIpv6 ? IP_VERSION_6 : IP_VERSION_4,
             &ConfigData,
             HttpBootHttpIoCallback,
             (VOID *)Private,
             &Private->HttpIo
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Private->HttpCreated = TRUE;
  return EFI_SUCCESS;
}

/**
  Release all the resource of a cache item.

  @param[in]          Cache         The pointer to the cache item.

**/
VOID
HttpBootFreeCache (
  IN  HTTP_BOOT_CACHE_CONTENT  *Cache
  )
{
  UINTN                          Index;
  LIST_ENTRY                     *Entry;
  LIST_ENTRY                     *NextEntry;
  HTTP_BOOT_ENTITY_DATA          *EntityData;
  EFI_HTTP_CONNECT_REQUEST_DATA  *ConnRequestData;

  if (Cache == NULL) {
    return;
  }

  //
  // Free the request data
  //
  if (Cache->RequestData != NULL) {
    if (Cache->RequestData->Url != NULL) {
      FreePool (Cache->RequestData->Url);
    }

    if (Cache->RequestData->Method == HttpMethodConnect) {
      ConnRequestData = (EFI_HTTP_CONNECT_REQUEST_DATA *)Cache->RequestData;

      if (ConnRequestData->ProxyUrl != NULL) {
        FreePool (ConnRequestData->ProxyUrl);
      }
    }

    FreePool (Cache->RequestData);
  }

  //
  // Free the response header
  //
  if (Cache->ResponseData != NULL) {
    if (Cache->ResponseData->Headers != NULL) {
      for (Index = 0; Index < Cache->ResponseData->HeaderCount; Index++) {
        FreePool (Cache->ResponseData->Headers[Index].FieldName);
        FreePool (Cache->ResponseData->Headers[Index].FieldValue);
      }

      FreePool (Cache->ResponseData->Headers);
    }
  }

  //
  // Free the response body
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Cache->EntityDataList) {
    EntityData = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_ENTITY_DATA, Link);
    if (EntityData->Block != NULL) {
      FreePool (EntityData->Block);
    }

    RemoveEntryList (&EntityData->Link);
    FreePool (EntityData);
  }

  FreePool (Cache);
}

/**
  Clean up all cached data.

  @param[in]          Private         The pointer to the driver's private data.

**/
VOID
HttpBootFreeCacheList (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  LIST_ENTRY               *Entry;
  LIST_ENTRY               *NextEntry;
  HTTP_BOOT_CACHE_CONTENT  *Cache;

  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->CacheList) {
    Cache = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_CACHE_CONTENT, Link);
    RemoveEntryList (&Cache->Link);
    HttpBootFreeCache (Cache);
  }
}

/**
  Get the file content from cached data.

  @param[in]          Private         The pointer to the driver's private data.
  @param[in]          Uri             Uri of the file to be retrieved from cache.
  @param[in, out]     BufferSize      On input the size of Buffer in bytes. On output with a return
                                      code of EFI_SUCCESS, the amount of data transferred to
                                      Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                      the size of Buffer required to retrieve the requested file.
  @param[out]         Buffer          The memory buffer to transfer the file to. IF Buffer is NULL,
                                      then the size of the requested file is returned in
                                      BufferSize.
  @param[out]         ImageType       The image type of the downloaded file.

  @retval EFI_SUCCESS          Successfully created.
  @retval Others               Failed to create HttpIo.

**/
EFI_STATUS
HttpBootGetFileFromCache (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private,
  IN     CHAR16                  *Uri,
  IN OUT UINTN                   *BufferSize,
  OUT UINT8                      *Buffer,
  OUT HTTP_BOOT_IMAGE_TYPE       *ImageType
  )
{
  LIST_ENTRY               *Entry;
  LIST_ENTRY               *Entry2;
  HTTP_BOOT_CACHE_CONTENT  *Cache;
  HTTP_BOOT_ENTITY_DATA    *EntityData;
  UINTN                    CopyedSize;

  if ((Uri == NULL) || (BufferSize == NULL) || (Buffer == NULL) || (ImageType == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_LIST_FOR_EACH (Entry, &Private->CacheList) {
    Cache = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_CACHE_CONTENT, Link);
    //
    // Compare the URI to see whether we already have a cache for this file.
    //
    if ((Cache->RequestData != NULL) &&
        (Cache->RequestData->Url != NULL) &&
        (StrCmp (Uri, Cache->RequestData->Url) == 0))
    {
      //
      // Hit in cache, record image type.
      //
      *ImageType = Cache->ImageType;

      //
      // Check buffer size.
      //
      if (*BufferSize < Cache->EntityLength) {
        *BufferSize = Cache->EntityLength;
        return EFI_BUFFER_TOO_SMALL;
      }

      //
      // Fill data to buffer.
      //
      CopyedSize = 0;
      NET_LIST_FOR_EACH (Entry2, &Cache->EntityDataList) {
        EntityData = NET_LIST_USER_STRUCT (Entry2, HTTP_BOOT_ENTITY_DATA, Link);
        if (*BufferSize > CopyedSize) {
          CopyMem (
            Buffer + CopyedSize,
            EntityData->DataStart,
            MIN (EntityData->DataLength, *BufferSize - CopyedSize)
            );
          CopyedSize += MIN (EntityData->DataLength, *BufferSize - CopyedSize);
        }
      }
      *BufferSize = CopyedSize;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  A callback function to intercept events during message parser.

  This function will be invoked during HttpParseMessageBody() with various events type. An error
  return status of the callback function will cause the HttpParseMessageBody() aborted.

  @param[in]    EventType          Event type of this callback call.
  @param[in]    Data               A pointer to data buffer.
  @param[in]    Length             Length in bytes of the Data.
  @param[in]    Context            Callback context set by HttpInitMsgParser().

  @retval EFI_SUCCESS              Continue to parser the message body.
  @retval Others                   Abort the parse.

**/
EFI_STATUS
EFIAPI
HttpBootGetBootFileCallback (
  IN HTTP_BODY_PARSE_EVENT  EventType,
  IN CHAR8                  *Data,
  IN UINTN                  Length,
  IN VOID                   *Context
  )
{
  HTTP_BOOT_CALLBACK_DATA          *CallbackData;
  HTTP_BOOT_ENTITY_DATA            *NewEntityData;
  EFI_STATUS                       Status;
  EFI_HTTP_BOOT_CALLBACK_PROTOCOL  *HttpBootCallback;

  //
  // We only care about the entity data.
  //
  if (EventType != BodyParseEventOnData) {
    return EFI_SUCCESS;
  }

  CallbackData     = (HTTP_BOOT_CALLBACK_DATA *)Context;
  HttpBootCallback = CallbackData->Private->HttpBootCallback;
  if (HttpBootCallback != NULL) {
    Status = HttpBootCallback->Callback (
                                 HttpBootCallback,
                                 HttpBootHttpEntityBody,
                                 TRUE,
                                 (UINT32)Length,
                                 Data
                                 );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Copy data if caller has provided a buffer.
  //
  if (CallbackData->BufferSize > CallbackData->CopyedSize) {
    CopyMem (
      CallbackData->Buffer + CallbackData->CopyedSize,
      Data,
      MIN (Length, CallbackData->BufferSize - CallbackData->CopyedSize)
      );
    CallbackData->CopyedSize += MIN (Length, CallbackData->BufferSize - CallbackData->CopyedSize);
  }

  //
  // The caller doesn't provide a buffer, save the block into cache list.
  //
  if (CallbackData->Cache != NULL) {
    NewEntityData = AllocatePool (sizeof (HTTP_BOOT_ENTITY_DATA));
    if (NewEntityData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    if (CallbackData->NewBlock) {
      NewEntityData->Block = CallbackData->Block;
      CallbackData->Block  = NULL;
    }

    NewEntityData->DataLength = Length;
    NewEntityData->DataStart  = (UINT8 *)Data;
    InsertTailList (&CallbackData->Cache->EntityDataList, &NewEntityData->Link);
  }

  return EFI_SUCCESS;
}

/**
  This function establishes a connection through a proxy server

  @param[in]       Private         The pointer to the driver's private data.

  @retval EFI_SUCCESS              Connection successful.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources
  @retval Others                   Unexpected error happened.

**/
EFI_STATUS
HttpBootConnectProxy (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS                     Status;
  EFI_HTTP_STATUS_CODE           StatusCode;
  CHAR8                          *HostName;
  EFI_HTTP_CONNECT_REQUEST_DATA  *RequestData;
  HTTP_IO_RESPONSE_DATA          *ResponseData;
  HTTP_IO                        *HttpIo;
  HTTP_IO_HEADER                 *HttpIoHeader;
  CHAR16                         *Url;
  CHAR16                         *ProxyUrl;
  UINTN                          UrlSize;

  Url          = NULL;
  ProxyUrl     = NULL;
  RequestData  = NULL;
  ResponseData = NULL;
  HttpIoHeader = NULL;

  UrlSize = AsciiStrSize (Private->BootFileUri);
  Url     = AllocatePool (UrlSize * sizeof (CHAR16));
  if (Url == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);

  UrlSize  = AsciiStrSize (Private->ProxyUri);
  ProxyUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
  if (ProxyUrl == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  AsciiStrToUnicodeStrS (Private->ProxyUri, ProxyUrl, UrlSize);

  //
  // Send HTTP request message.
  //

  //
  // Build HTTP header for the request, 2 headers are needed to send a CONNECT method:
  //   Host
  //   User
  //
  HttpIoHeader = HttpIoCreateHeader (2);
  if (HttpIoHeader == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  //
  // Add HTTP header field 1: Host (EndPoint URI)
  //
  HostName = NULL;
  Status   = HttpUrlGetHostName (
               Private->BootFileUri,
               Private->BootFileUriParser,
               &HostName
               );
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  Status = HttpIoSetHeader (
             HttpIoHeader,
             HTTP_HEADER_HOST,
             HostName
             );
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Add HTTP header field 2: User-Agent
  //
  Status = HttpIoSetHeader (
             HttpIoHeader,
             HTTP_HEADER_USER_AGENT,
             HTTP_USER_AGENT_EFI_HTTP_BOOT
             );
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Build the rest of HTTP request info.
  //
  RequestData = AllocatePool (sizeof (EFI_HTTP_CONNECT_REQUEST_DATA));
  if (RequestData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  RequestData->Base.Method = HttpMethodConnect;
  RequestData->Base.Url    = Url;
  RequestData->ProxyUrl    = ProxyUrl;

  //
  // Send out the request to HTTP server.
  //
  HttpIo = &Private->HttpIo;
  Status = HttpIoSendRequest (
             HttpIo,
             &RequestData->Base,
             HttpIoHeader->HeaderCount,
             HttpIoHeader->Headers,
             0,
             NULL
             );
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Receive HTTP response message.
  //

  //
  // Use zero BodyLength to only receive the response headers.
  //
  ResponseData = AllocateZeroPool (sizeof (HTTP_IO_RESPONSE_DATA));
  if (ResponseData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  Status = HttpIoRecvResponse (
             &Private->HttpIo,
             TRUE,
             ResponseData
             );

  if (EFI_ERROR (Status) || EFI_ERROR (ResponseData->Status)) {
    if (EFI_ERROR (ResponseData->Status)) {
      StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode;
      HttpBootPrintErrorMessage (StatusCode);
      Status = ResponseData->Status;
    }
  }

EXIT:
  if (ResponseData != NULL) {
    FreePool (ResponseData);
  }

  if (RequestData != NULL) {
    FreePool (RequestData);
  }

  HttpIoFreeHeader (HttpIoHeader);

  if (ProxyUrl != NULL) {
    FreePool (ProxyUrl);
  }

  if (Url != NULL) {
    FreePool (Url);
  }

  return Status;
}

/**
  This function download the boot file by using UEFI HTTP protocol.

  @param[in]       Private         The pointer to the driver's private data.
  @param[in]       HeaderOnly      Only request the response header, it could save a lot of time if
                                   the caller only want to know the size of the requested file.
  @param[in, out]  BufferSize      On input the size of Buffer in bytes. On output with a return
                                   code of EFI_SUCCESS, the amount of data transferred to
                                   Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                   the size of Buffer required to retrieve the requested file.
  @param[out]      Buffer          The memory buffer to transfer the file to. IF Buffer is NULL,
                                   then the size of the requested file is returned in
                                   BufferSize.
  @param[out]      ImageType       The image type of the downloaded file.

  @retval EFI_SUCCESS              The file was loaded.
  @retval EFI_INVALID_PARAMETER    BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources
  @retval EFI_BUFFER_TOO_SMALL     The BufferSize is too small to read the current directory entry.
                                   BufferSize has been updated with the size needed to complete
                                   the request.
  @retval EFI_ACCESS_DENIED        The server needs to authenticate the client.
  @retval EFI_NOT_READY            Data transfer has timed-out, call HttpBootGetBootFile again to resume
                                   the download operation using HTTP Range headers.
  @retval EFI_UNSUPPORTED          Some HTTP response header is not supported.
  @retval Others                   Unexpected error happened.

**/
EFI_STATUS
HttpBootGetBootFile (
  IN     HTTP_BOOT_PRIVATE_DATA  *Private,
  IN     BOOLEAN                 HeaderOnly,
  IN OUT UINTN                   *BufferSize,
  OUT UINT8                      *Buffer,
  OUT HTTP_BOOT_IMAGE_TYPE       *ImageType
  )
{
  EFI_STATUS               Status;
  EFI_HTTP_STATUS_CODE     StatusCode;
  CHAR8                    *HostName;
  EFI_HTTP_REQUEST_DATA    *RequestData;
  HTTP_IO_RESPONSE_DATA    *ResponseData;
  HTTP_IO_RESPONSE_DATA    ResponseBody;
  HTTP_IO                  *HttpIo;
  HTTP_IO_HEADER           *HttpIoHeader;
  VOID                     *Parser;
  HTTP_BOOT_CALLBACK_DATA  Context;
  UINTN                    ContentLength;
  HTTP_BOOT_CACHE_CONTENT  *Cache;
  UINT8                    *Block;
  UINTN                    UrlSize;
  CHAR16                   *Url;
  BOOLEAN                  IdentityMode;
  UINTN                    ReceivedSize;
  CHAR8                    BaseAuthValue[80];
  EFI_HTTP_HEADER          *HttpHeader;
  CHAR8                    *Data;
  UINTN                    HeadersCount;
  BOOLEAN                  ResumingOperation;
  CHAR8                    *ContentRangeResponseValue;
  CHAR8                    RangeValue[64];

  ASSERT (Private != NULL);
  ASSERT (Private->HttpCreated);

  if ((BufferSize == NULL) || (ImageType == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*BufferSize != 0) && (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // First, check whether we already cached the requested Uri.
  //
  UrlSize = AsciiStrSize (Private->BootFileUri);
  Url     = AllocatePool (UrlSize * sizeof (CHAR16));
  if (Url == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);
  if (!HeaderOnly && (Buffer != NULL)) {
    Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType);
    if (Status != EFI_NOT_FOUND) {
      FreePool (Url);
      return Status;
    }
  }

  // Check if this is a previous download that has failed and need to be resumed
  if ((!HeaderOnly) &&
      (Private->PartialTransferredSize > 0) &&
      (Private->BootFileSize == *BufferSize))
  {
    ResumingOperation = TRUE;
  } else {
    ResumingOperation = FALSE;
  }

  //
  // Not found in cache, try to download it through HTTP.
  //

  //
  // 1. Create a temp cache item for the requested URI if caller doesn't provide buffer.
  //
  Cache = NULL;
  if ((!HeaderOnly) && (*BufferSize == 0)) {
    Cache = AllocateZeroPool (sizeof (HTTP_BOOT_CACHE_CONTENT));
    if (Cache == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ERROR_1;
    }

    Cache->ImageType = ImageTypeMax;
    InitializeListHead (&Cache->EntityDataList);
  }

  //
  // 2. Send HTTP request message.
  //

  //
  // 2.1 Build HTTP header for the request, 3 header is needed to download a boot file:
  //       Host
  //       Accept
  //       User-Agent
  //       [Authorization]
  //       [Range]
  //       [If-Match]|[If-Unmodified-Since]
  //
  HeadersCount = 3;
  if (Private->AuthData != NULL) {
    HeadersCount++;
  }

  if (ResumingOperation) {
    HeadersCount++;
    if (Private->LastModifiedOrEtag) {
      HeadersCount++;
    }
  }

  HttpIoHeader = HttpIoCreateHeader (HeadersCount);

  if (HttpIoHeader == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ERROR_2;
  }

  //
  // Add HTTP header field 1: Host
  //
  HostName = NULL;
  Status   = HttpUrlGetHostName (
               Private->BootFileUri,
               Private->BootFileUriParser,
               &HostName
               );
  if (EFI_ERROR (Status)) {
    goto ERROR_3;
  }

  Status = HttpIoSetHeader (
             HttpIoHeader,
             HTTP_HEADER_HOST,
             HostName
             );
  FreePool (HostName);
  if (EFI_ERROR (Status)) {
    goto ERROR_3;
  }

  //
  // Add HTTP header field 2: Accept
  //
  Status = HttpIoSetHeader (
             HttpIoHeader,
             HTTP_HEADER_ACCEPT,
             "*/*"
             );
  if (EFI_ERROR (Status)) {
    goto ERROR_3;
  }

  //
  // Add HTTP header field 3: User-Agent
  //
  Status = HttpIoSetHeader (
             HttpIoHeader,
             HTTP_HEADER_USER_AGENT,
             HTTP_USER_AGENT_EFI_HTTP_BOOT
             );
  if (EFI_ERROR (Status)) {
    goto ERROR_3;
  }

  //
  // Add HTTP header field 4: Authorization
  //
  if (Private->AuthData != NULL) {
    ASSERT (HttpIoHeader->MaxHeaderCount == 4);

    if ((Private->AuthScheme != NULL) && (CompareMem (Private->AuthScheme, "Basic", 5) != 0)) {
      Status = EFI_UNSUPPORTED;
      goto ERROR_3;
    }

    AsciiSPrint (
      BaseAuthValue,
      sizeof (BaseAuthValue),
      "%a %a",
      "Basic",
      Private->AuthData
      );

    Status = HttpIoSetHeader (
               HttpIoHeader,
               HTTP_HEADER_AUTHORIZATION,
               BaseAuthValue
               );
    if (EFI_ERROR (Status)) {
      goto ERROR_3;
    }
  }

  //
  // Add HTTP header field 5 (optional): Range
  //
  if (ResumingOperation) {
    // Resuming a failed download. Prepare the HTTP Range Header
    Status = AsciiSPrint (
               RangeValue,
               sizeof (RangeValue),
               "bytes=%lu-%lu",
               Private->PartialTransferredSize,
               Private->BootFileSize - 1
               );
    if (EFI_ERROR (Status)) {
      goto ERROR_3;
    }

    Status = HttpIoSetHeader (HttpIoHeader, "Range", RangeValue);
    if (EFI_ERROR (Status)) {
      goto ERROR_3;
    }

    DEBUG (
      (DEBUG_WARN | DEBUG_INFO,
       "HttpBootGetBootFile: Resuming failed download. Range: %a\n",
       RangeValue)
      );

    //
    // Add HTTP header field 6 (optional): If-Match or If-Unmodified-Since
    //
    if (Private->LastModifiedOrEtag) {
      if (Private->LastModifiedOrEtag[0] == '"') {
        // An ETag value starts with "
        DEBUG (
          (DEBUG_WARN | DEBUG_INFO,
           "HttpBootGetBootFile: If-Match=%a\n",
           Private->LastModifiedOrEtag)
          );
        // Add If-Match header with the ETag value got from the first request.
        Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_MATCH, Private->LastModifiedOrEtag);
      } else {
        DEBUG (
          (DEBUG_WARN | DEBUG_INFO,
           "HttpBootGetBootFile: If-Unmodified-Since=%a\n",
           Private->LastModifiedOrEtag)
          );
        // Add If-Unmodified-Since header with the timestamp value (Last-Modified) got from the first request.
        Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_UNMODIFIED_SINCE, Private->LastModifiedOrEtag);
      }

      if (EFI_ERROR (Status)) {
        goto ERROR_3;
      }
    }
  }

  //
  // 2.2 Build the rest of HTTP request info.
  //
  RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
  if (RequestData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ERROR_3;
  }

  RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;
  RequestData->Url    = Url;

  //
  // 2.3 Record the request info in a temp cache item.
  //
  if (Cache != NULL) {
    Cache->RequestData = RequestData;
  }

  //
  // 2.4 Send out the request to HTTP server.
  //
  HttpIo = &Private->HttpIo;
  Status = HttpIoSendRequest (
             HttpIo,
             RequestData,
             HttpIoHeader->HeaderCount,
             HttpIoHeader->Headers,
             0,
             NULL
             );
  if (EFI_ERROR (Status)) {
    goto ERROR_4;
  }

  //
  // 3. Receive HTTP response message.
  //

  //
  // 3.1 First step, use zero BodyLength to only receive the response headers.
  //
  ResponseData = AllocateZeroPool (sizeof (HTTP_IO_RESPONSE_DATA));
  if (ResponseData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ERROR_4;
  }

  Data   = NULL;
  Status = HttpIoRecvResponse (
             &Private->HttpIo,
             TRUE,
             ResponseData
             );
  if (EFI_ERROR (Status) || EFI_ERROR (ResponseData->Status)) {
    if (EFI_ERROR (ResponseData->Status)) {
      StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode;
      HttpBootPrintErrorMessage (StatusCode);
      Status = ResponseData->Status;
      if ((StatusCode == HTTP_STATUS_401_UNAUTHORIZED) || \
          (StatusCode == HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED))
      {
        if ((Private->AuthData != NULL) || (Private->AuthScheme != NULL)) {
          if (Private->AuthData != NULL) {
            FreePool (Private->AuthData);
            Private->AuthData = NULL;
          }

          if (Private->AuthScheme != NULL) {
            FreePool (Private->AuthScheme);
            Private->AuthScheme = NULL;
          }

          Status = EFI_ACCESS_DENIED;
          goto ERROR_4;
        }

        //
        // Server indicates the user has to provide a user-id and password as a means of identification.
        //
        if (Private->HttpBootCallback != NULL) {
          Data = AllocateZeroPool (sizeof (CHAR8) * HTTP_BOOT_AUTHENTICATION_INFO_MAX_LEN);
          if (Data == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto ERROR_4;
          }

          Status = Private->HttpBootCallback->Callback (
                                                Private->HttpBootCallback,
                                                HttpBootHttpAuthInfo,
                                                TRUE,
                                                HTTP_BOOT_AUTHENTICATION_INFO_MAX_LEN,
                                                Data
                                                );
          if (EFI_ERROR (Status)) {
            if (Data != NULL) {
              FreePool (Data);
            }

            goto ERROR_5;
          }

          Private->AuthData = (CHAR8 *)Data;
        }

        HttpHeader = HttpFindHeader (
                       ResponseData->HeaderCount,
                       ResponseData->Headers,
                       HTTP_HEADER_WWW_AUTHENTICATE
                       );
        if (HttpHeader != NULL) {
          Private->AuthScheme = AllocateZeroPool (AsciiStrLen (HttpHeader->FieldValue) + 1);
          if (Private->AuthScheme == NULL) {
            return EFI_OUT_OF_RESOURCES;
          }

          CopyMem (Private->AuthScheme, HttpHeader->FieldValue, AsciiStrLen (HttpHeader->FieldValue));
        }

        Status = EFI_ACCESS_DENIED;
      }
    }

    goto ERROR_5;
  }

  //
  // Check the image type according to server's response.
  //
  Status = HttpBootCheckImageType (
             Private->BootFileUri,
             Private->BootFileUriParser,
             ResponseData->HeaderCount,
             ResponseData->Headers,
             ImageType
             );
  if (EFI_ERROR (Status)) {
    goto ERROR_5;
  }

  //
  // 3.2 Cache the response header.
  //
  if (Cache != NULL) {
    Cache->ResponseData = ResponseData;
    Cache->ImageType    = *ImageType;
  }

  // Cache ETag or Last-Modified response header value to
  // be used when resuming an interrupted download.
  HttpHeader = HttpFindHeader (
                 ResponseData->HeaderCount,
                 ResponseData->Headers,
                 HTTP_HEADER_ETAG
                 );
  if (HttpHeader == NULL) {
    HttpHeader = HttpFindHeader (
                   ResponseData->HeaderCount,
                   ResponseData->Headers,
                   HTTP_HEADER_LAST_MODIFIED
                   );
  }

  if (HttpHeader) {
    if (Private->LastModifiedOrEtag) {
      FreePool (Private->LastModifiedOrEtag);
    }

    Private->LastModifiedOrEtag = AllocateCopyPool (AsciiStrSize (HttpHeader->FieldValue), HttpHeader->FieldValue);
  }

  //
  // 3.2.2 Validate the range response. If operation is being resumed,
  // server must respond with Content-Range.
  //
  if (ResumingOperation) {
    HttpHeader = HttpFindHeader (
                   ResponseData->HeaderCount,
                   ResponseData->Headers,
                   HTTP_HEADER_CONTENT_RANGE
                   );
    if ((HttpHeader == NULL) ||
        (AsciiStrnCmp (HttpHeader->FieldValue, "bytes", 5) != 0))
    {
      Status = EFI_UNSUPPORTED;
      goto ERROR_5;
    }

    // Gets the total size of ranged data (Content-Range: <unit> <range-start>-<range-end>/<size>)
    // and check if it remains the same
    ContentRangeResponseValue = AsciiStrStr (HttpHeader->FieldValue, "/");
    if (ContentRangeResponseValue == NULL) {
      Status = EFI_INVALID_PARAMETER;
      goto ERROR_5;
    }

    ContentRangeResponseValue++;
    ContentLength = AsciiStrDecimalToUintn (ContentRangeResponseValue);
    if (ContentLength != *BufferSize) {
      Status = EFI_INVALID_PARAMETER;
      goto ERROR_5;
    }
  }

  //
  // 3.3 Init a message-body parser from the header information.
  //
  Parser             = NULL;
  Context.NewBlock   = FALSE;
  Context.Block      = NULL;
  Context.CopyedSize = 0;
  Context.Buffer     = Buffer;
  Context.BufferSize = *BufferSize;
  Context.Cache      = Cache;
  Context.Private    = Private;
  Status             = HttpInitMsgParser (
                         HeaderOnly ? HttpMethodHead : HttpMethodGet,
                         ResponseData->Response.StatusCode,
                         ResponseData->HeaderCount,
                         ResponseData->Headers,
                         HttpBootGetBootFileCallback,
                         (VOID *)&Context,
                         &Parser
                         );
  if (EFI_ERROR (Status)) {
    goto ERROR_6;
  }

  //
  // 3.4 Continue to receive and parse message-body if needed.
  //
  Block = NULL;
  if (!HeaderOnly) {
    //
    // 3.4.1, check whether we are in identity transfer-coding.
    //
    ContentLength = 0;
    Status        = HttpGetEntityLength (Parser, &ContentLength);
    if (!EFI_ERROR (Status)) {
      IdentityMode = TRUE;
    } else {
      IdentityMode = FALSE;
    }

    //
    // 3.4.2, start the message-body download, the identity and chunked transfer-coding
    // is handled in different path here.
    //
    ZeroMem (&ResponseBody, sizeof (HTTP_IO_RESPONSE_DATA));
    if (IdentityMode) {
      //
      // In identity transfer-coding there is no need to parse the message body,
      // just download the message body to the user provided buffer directly.
      //
      if (ResumingOperation && ((ContentLength + Private->PartialTransferredSize) > *BufferSize)) {
        Status = EFI_INVALID_PARAMETER;
        goto ERROR_6;
      }

      ReceivedSize = 0;
      while (ReceivedSize < ContentLength) {
        ResponseBody.Body       = (CHAR8 *)Buffer + (ReceivedSize + Private->PartialTransferredSize);
        ResponseBody.BodyLength = *BufferSize - (ReceivedSize + Private->PartialTransferredSize);
        Status                  = HttpIoRecvResponse (
                                    &Private->HttpIo,
                                    FALSE,
                                    &ResponseBody
                                    );
        if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {
          if (EFI_ERROR (ResponseBody.Status)) {
            Status = ResponseBody.Status;
          }

          if ((Status == EFI_TIMEOUT) || (Status == EFI_DEVICE_ERROR)) {
            // For EFI_TIMEOUT and EFI_DEVICE_ERROR errors, we may resume the operation.
            // We will not check if server sent Accept-Ranges header, because some back-ends
            // do not report this header, even when supporting it. Know example: CloudFlare CDN Cache.
            Private->PartialTransferredSize = ReceivedSize;
            DEBUG (
              (
               DEBUG_WARN | DEBUG_INFO,
               "HttpBootGetBootFile: Transfer error. Bytes transferred so far: %lu.\n",
               ReceivedSize
              )
              );
          }

          goto ERROR_6;
        }

        ReceivedSize += ResponseBody.BodyLength;
        if (Private->HttpBootCallback != NULL) {
          Status = Private->HttpBootCallback->Callback (
                                                Private->HttpBootCallback,
                                                HttpBootHttpEntityBody,
                                                TRUE,
                                                (UINT32)ResponseBody.BodyLength,
                                                ResponseBody.Body
                                                );
          if (EFI_ERROR (Status)) {
            goto ERROR_6;
          }
        }
      }

      // download completed, there is no more partial data
      Private->PartialTransferredSize = 0;
    } else {
      //
      // In "chunked" transfer-coding mode, so we need to parse the received
      // data to get the real entity content.
      //
      Block = NULL;
      while (!HttpIsMessageComplete (Parser)) {
        //
        // Allocate a buffer in Block to hold the message-body.
        // If caller provides a buffer, this Block will be reused in every HttpIoRecvResponse().
        // Otherwise a buffer, the buffer in Block will be cached and we should allocate a new before
        // every HttpIoRecvResponse().
        //
        if ((Block == NULL) || (Context.BufferSize == 0)) {
          Block = AllocatePool (HTTP_BOOT_BLOCK_SIZE);
          if (Block == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto ERROR_6;
          }

          Context.NewBlock = TRUE;
          Context.Block    = Block;
        } else {
          Context.NewBlock = FALSE;
        }

        ResponseBody.Body       = (CHAR8 *)Block;
        ResponseBody.BodyLength = HTTP_BOOT_BLOCK_SIZE;
        Status                  = HttpIoRecvResponse (
                                    &Private->HttpIo,
                                    FALSE,
                                    &ResponseBody
                                    );
        if (EFI_ERROR (Status) || EFI_ERROR (ResponseBody.Status)) {
          if (EFI_ERROR (ResponseBody.Status)) {
            Status = ResponseBody.Status;
          }

          goto ERROR_6;
        }

        //
        // Parse the new received block of the message-body, the block will be saved in cache.
        //
        Status = HttpParseMessageBody (
                   Parser,
                   ResponseBody.BodyLength,
                   ResponseBody.Body
                   );
        if (EFI_ERROR (Status)) {
          goto ERROR_6;
        }
      }
    }
  }

  //
  // 3.5 Message-body receive & parse is completed, we should be able to get the file size now.
  //
  if (!ResumingOperation) {
    Status = HttpGetEntityLength (Parser, &ContentLength);
    if (EFI_ERROR (Status)) {
      goto ERROR_6;
    }
  } else {
    ContentLength = Private->BootFileSize;
  }

  if (*BufferSize < ContentLength) {
    Status = EFI_BUFFER_TOO_SMALL;
  } else {
    Status = EFI_SUCCESS;
  }

  *BufferSize = ContentLength;

  //
  // 4. Save the cache item to driver's cache list and return.
  //
  if (Cache != NULL) {
    Cache->EntityLength = ContentLength;
    InsertTailList (&Private->CacheList, &Cache->Link);
  }

  if (Parser != NULL) {
    HttpFreeMsgParser (Parser);
  }

  return Status;

ERROR_6:
  if (Parser != NULL) {
    HttpFreeMsgParser (Parser);
  }

  if (Context.Block != NULL) {
    FreePool (Context.Block);
  }

  HttpBootFreeCache (Cache);

ERROR_5:
  if (ResponseData != NULL) {
    FreePool (ResponseData);
  }

ERROR_4:
  if (RequestData != NULL) {
    FreePool (RequestData);
  }

ERROR_3:
  HttpIoFreeHeader (HttpIoHeader);
ERROR_2:
  if (Cache != NULL) {
    FreePool (Cache);
  }

ERROR_1:
  if (Url != NULL) {
    FreePool (Url);
  }

  return Status;
}
