/** @file
  The implementation for the 'http' Shell command.

  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) 2020, Broadcom. All rights reserved. <BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "Http.h"

#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH  32

//
// Constant strings and definitions related to the message
// indicating the amount of progress in the dowloading of a HTTP file.
//

//
// Number of steps in the progression slider.
//
#define HTTP_PROGRESS_SLIDER_STEPS  \
  ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 3)

//
// Size in number of characters plus one (final zero) of the message to
// indicate the progress of an HTTP download. The format is "[(progress slider:
// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
// are thus the number of characters in HTTP_PROGR_FRAME[] plus 11 characters
// (2 // spaces, "Kb" and seven characters for the number of KBytes).
//
#define HTTP_PROGRESS_MESSAGE_SIZE  \
  ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) + 12)

//
// Buffer size. Note that larger buffer does not mean better speed.
//
#define DEFAULT_BUF_SIZE  SIZE_32KB
#define MAX_BUF_SIZE      SIZE_4MB

#define MIN_PARAM_COUNT  2
#define MAX_PARAM_COUNT  4
#define NEED_REDIRECTION(Code) \
  (((Code >= HTTP_STATUS_300_MULTIPLE_CHOICES) \
  && (Code <= HTTP_STATUS_307_TEMPORARY_REDIRECT)) \
  || (Code == HTTP_STATUS_308_PERMANENT_REDIRECT))

#define CLOSE_HTTP_HANDLE(ControllerHandle, HttpChildHandle) \
  do { \
    if (HttpChildHandle) { \
      CloseProtocolAndDestroyServiceChild ( \
        ControllerHandle, \
        &gEfiHttpServiceBindingProtocolGuid, \
        &gEfiHttpProtocolGuid, \
        HttpChildHandle \
        ); \
      HttpChildHandle = NULL; \
    } \
  } while (0)

typedef enum {
  HdrHost,
  HdrConn,
  HdrAgent,
  HdrMax
} HDR_TYPE;

#define USER_AGENT_HDR  "Mozilla/5.0 (EDK2; Linux) Gecko/20100101 Firefox/79.0"

#define TIMER_MAX_TIMEOUT_S  10

//
// File name to use when Uri ends with "/".
//
#define DEFAULT_HTML_FILE   L"index.html"
#define DEFAULT_HTTP_PROTO  L"http"

//
// String to delete the HTTP progress message to be able to update it :
// (HTTP_PROGRESS_MESSAGE_SIZE-1) '\b'.
//
#define HTTP_PROGRESS_DEL \
  L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\
\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"

#define HTTP_KB  L"\b\b\b\b\b\b\b\b\b\b"
//
// Frame for the progression slider.
//
#define HTTP_PROGR_FRAME  L"[                                        ]"

//
// Improve readability by using these macros.
//
#define PRINT_HII(token, ...) \
  ShellPrintHiiEx (\
      -1, -1, NULL, token, mHttpHiiHandle, __VA_ARGS__)

#define PRINT_HII_APP(token, value) \
  PRINT_HII (token, HTTP_APP_NAME, value)

//
// TimeBaseLib.h constants.
// These will be removed once the library gets fixed.
//

//
// Define EPOCH (1970-JANUARY-01) in the Julian Date representation.
//
#define EPOCH_JULIAN_DATE  2440588

//
// Seconds per unit.
//
#define SEC_PER_MIN   ((UINTN)    60)
#define SEC_PER_HOUR  ((UINTN)  3600)
#define SEC_PER_DAY   ((UINTN) 86400)

//
// String descriptions for server errors.
//
STATIC CONST CHAR16  *ErrStatusDesc[] =
{
  L"400 Bad Request",
  L"401 Unauthorized",
  L"402 Payment required",
  L"403 Forbidden",
  L"404 Not Found",
  L"405 Method not allowed",
  L"406 Not acceptable",
  L"407 Proxy authentication required",
  L"408 Request time out",
  L"409 Conflict",
  L"410 Gone",
  L"411 Length required",
  L"412 Precondition failed",
  L"413 Request entity too large",
  L"414 Request URI to large",
  L"415 Unsupported media type",
  L"416 Requested range not satisfied",
  L"417 Expectation failed",
  L"500 Internal server error",
  L"501 Not implemented",
  L"502 Bad gateway",
  L"503 Service unavailable",
  L"504 Gateway timeout",
  L"505 HTTP version not supported"
};

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-i", TypeValue },
  { L"-k", TypeFlag  },
  { L"-l", TypeValue },
  { L"-m", TypeFlag  },
  { L"-s", TypeValue },
  { L"-t", TypeValue },
  { NULL,  TypeMax   }
};

//
// Local File Handle.
//
STATIC SHELL_FILE_HANDLE  mFileHandle = NULL;

//
// Path of the local file, Unicode encoded.
//
STATIC CONST CHAR16  *mLocalFilePath;

STATIC BOOLEAN  gRequestCallbackComplete  = FALSE;
STATIC BOOLEAN  gResponseCallbackComplete = FALSE;

STATIC BOOLEAN  gHttpError;

EFI_HII_HANDLE  mHttpHiiHandle;

//
// Functions declarations.
//

/**
  Check and convert the UINT16 option values of the 'http' command.

  @param[in]  ValueStr  Value as an Unicode encoded string.
  @param[out] Value     UINT16 value.

  @retval     TRUE      The value was returned.
  @retval     FALSE     A parsing error occured.
**/
STATIC
BOOLEAN
StringToUint16 (
  IN   CONST CHAR16  *ValueStr,
  OUT  UINT16        *Value
  );

/**
  Get the name of the NIC.

  @param[in]   ControllerHandle  The network physical device handle.
  @param[in]   NicNumber         The network physical device number.
  @param[out]  NicName           Address where to store the NIC name.
                                 The memory area has to be at least
                                 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
                                 double byte wide.

  @retval  EFI_SUCCESS  The name of the NIC was returned.
  @retval  Others       The creation of the child for the Managed
                        Network Service failed or the opening of
                        the Managed Network Protocol failed or
                        the operational parameters for the
                        Managed Network Protocol could not be
                        read.
**/
STATIC
EFI_STATUS
GetNicName (
  IN   EFI_HANDLE  ControllerHandle,
  IN   UINTN       NicNumber,
  OUT  CHAR16      *NicName
  );

/**
  Create a child for the service identified by its service binding protocol GUID
  and get from the child the interface of the protocol identified by its GUID.

  @param[in]   ControllerHandle            Controller handle.
  @param[in]   ServiceBindingProtocolGuid  Service binding protocol GUID of the
                                           service to be created.
  @param[in]   ProtocolGuid                GUID of the protocol to be open.
  @param[out]  ChildHandle                 Address where the handler of the
                                           created child is returned. NULL is
                                           returned in case of error.
  @param[out]  Interface                   Address where a pointer to the
                                           protocol interface is returned in
                                           case of success.

  @retval  EFI_SUCCESS  The child was created and the protocol opened.
  @retval  Others       Either the creation of the child or the opening
                        of the protocol failed.
**/
STATIC
EFI_STATUS
CreateServiceChildAndOpenProtocol (
  IN   EFI_HANDLE  ControllerHandle,
  IN   EFI_GUID    *ServiceBindingProtocolGuid,
  IN   EFI_GUID    *ProtocolGuid,
  OUT  EFI_HANDLE  *ChildHandle,
  OUT  VOID        **Interface
  );

/**
  Close the protocol identified by its GUID on the child handle of the service
  identified by its service binding protocol GUID, then destroy the child
  handle.

  @param[in]  ControllerHandle            Controller handle.
  @param[in]  ServiceBindingProtocolGuid  Service binding protocol GUID of the
                                          service to be destroyed.
  @param[in]  ProtocolGuid                GUID of the protocol to be closed.
  @param[in]  ChildHandle                 Handle of the child to be destroyed.

**/
STATIC
VOID
CloseProtocolAndDestroyServiceChild (
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_GUID    *ServiceBindingProtocolGuid,
  IN  EFI_GUID    *ProtocolGuid,
  IN  EFI_HANDLE  ChildHandle
  );

/**
  Worker function that download the data of a file from an HTTP server given
  the path of the file and its size.

  @param[in]   Context           A pointer to the download context.

  @retval  EFI_SUCCESS           The file was downloaded.
  @retval  EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval  Others                The downloading of the file
                                 from the server failed.
**/
STATIC
EFI_STATUS
DownloadFile (
  IN   HTTP_DOWNLOAD_CONTEXT  *Context,
  IN   EFI_HANDLE             ControllerHandle,
  IN   CHAR16                 *NicName
  );

/**
  Cleans off leading and trailing spaces and tabs.

  @param[in]                      String pointer to the string to trim them off.

  @retval EFI_SUCCESS             No errors.
  @retval EFI_INVALID_PARAMETER   String pointer is NULL.
**/
STATIC
EFI_STATUS
TrimSpaces (
  IN CHAR16  *String
  )
{
  CHAR16  *Str;
  UINTN   Len;

  ASSERT (String != NULL);

  if (String == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Str = String;

  //
  // Remove any whitespace at the beginning of the Str.
  //
  while (*Str == L' ' || *Str == L'\t') {
    Str++;
  }

  //
  // Remove any whitespace at the end of the Str.
  //
  do {
    Len = StrLen (Str);
    if (!Len || ((Str[Len - 1] != L' ') && (Str[Len - 1] != '\t'))) {
      break;
    }

    Str[Len - 1] = CHAR_NULL;
  } while (Len);

  CopyMem (String, Str, StrSize (Str));

  return EFI_SUCCESS;
}

//
// Callbacks for request and response.
// We just acknowledge that operation has completed here.
//

/**
  Callback to set the request completion flag.

  @param[in] Event:   The event.
  @param[in] Context: pointer to Notification Context.
 **/
STATIC
VOID
EFIAPI
RequestCallback (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  gRequestCallbackComplete = TRUE;
}

/**
  Callback to set the response completion flag.
  @param[in] Event:   The event.
  @param[in] Context: pointer to Notification Context.
 **/
STATIC
VOID
EFIAPI
ResponseCallback (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  gResponseCallbackComplete = TRUE;
}

//
// Set of functions from TimeBaseLib.
// This will be removed once TimeBaseLib is enabled for ShellPkg.
//

/**
  Calculate Epoch days.

  @param[in] Time - a pointer to the EFI_TIME abstraction.

  @retval           Number of days elapsed since EPOCH_JULIAN_DAY.
 **/
STATIC
UINTN
EfiGetEpochDays (
  IN  EFI_TIME  *Time
  )
{
  UINTN  a;
  UINTN  y;
  UINTN  m;
  //
  // Absolute Julian Date representation of the supplied Time.
  //
  UINTN  JulianDate;
  //
  // Number of days elapsed since EPOCH_JULIAN_DAY.
  //
  UINTN  EpochDays;

  a = (14 - Time->Month) / 12;
  y = Time->Year + 4800 - a;
  m = Time->Month + (12 * a) - 3;

  JulianDate = Time->Day + ((153 * m + 2) / 5) + (365 * y) + (y / 4) -
               (y / 100) + (y / 400) - 32045;

  ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
  EpochDays = JulianDate - EPOCH_JULIAN_DATE;

  return EpochDays;
}

/**
  Converts EFI_TIME to Epoch seconds
  (elapsed since 1970 JANUARY 01, 00:00:00 UTC).

  @param[in] Time: a pointer to EFI_TIME abstraction.
 **/
STATIC
UINTN
EFIAPI
EfiTimeToEpoch (
  IN  EFI_TIME  *Time
  )
{
  //
  // Number of days elapsed since EPOCH_JULIAN_DAY.
  //
  UINTN  EpochDays;
  UINTN  EpochSeconds;

  EpochDays = EfiGetEpochDays (Time);

  EpochSeconds = (EpochDays * SEC_PER_DAY) +
                 ((UINTN)Time->Hour * SEC_PER_HOUR) +
                 (Time->Minute * SEC_PER_MIN) + Time->Second;

  return EpochSeconds;
}

/**
  Function for 'http' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).

  @retval  SHELL_SUCCESS            The 'http' command completed successfully.
  @retval  SHELL_ABORTED            The Shell Library initialization failed.
  @retval  SHELL_INVALID_PARAMETER  At least one of the command's arguments is
                                    not valid.
  @retval  SHELL_OUT_OF_RESOURCES   A memory allocation failed.
  @retval  SHELL_NOT_FOUND          Network Interface Card not found.
  @retval  SHELL_UNSUPPORTED        Command was valid, but the server returned
                                    a status code indicating some error.
                                    Examine the file requested for error body.
**/
SHELL_STATUS
RunHttp (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS               Status;
  LIST_ENTRY               *CheckPackage;
  UINTN                    ParamCount;
  UINTN                    HandleCount;
  UINTN                    NicNumber;
  UINTN                    InitialSize;
  UINTN                    ParamOffset;
  UINTN                    StartSize;
  CHAR16                   *ProblemParam;
  CHAR16                   NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];
  CHAR16                   *Walker1;
  CHAR16                   *VStr;
  CONST CHAR16             *UserNicName;
  CONST CHAR16             *ValueStr;
  CONST CHAR16             *RemoteFilePath;
  CONST CHAR16             *Walker;
  EFI_HTTPv4_ACCESS_POINT  IPv4Node;
  EFI_HANDLE               *Handles;
  EFI_HANDLE               ControllerHandle;
  HTTP_DOWNLOAD_CONTEXT    Context;
  BOOLEAN                  NicFound;

  ProblemParam   = NULL;
  RemoteFilePath = NULL;
  NicFound       = FALSE;
  Handles        = NULL;

  //
  // Initialize the Shell library (we must be in non-auto-init...).
  //
  ParamOffset = 0;
  gHttpError  = FALSE;

  Status = ShellInitialize ();
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return SHELL_ABORTED;
  }

  ZeroMem (&Context, sizeof (Context));

  //
  // Parse the command line.
  //
  Status = ShellCommandLineParse (
             ParamList,
             &CheckPackage,
             &ProblemParam,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    if (  (Status == EFI_VOLUME_CORRUPTED)
       && (ProblemParam != NULL))
    {
      PRINT_HII_APP (STRING_TOKEN (STR_GEN_PROBLEM), ProblemParam);
      SHELL_FREE_NON_NULL (ProblemParam);
    } else {
      ASSERT (FALSE);
    }

    goto Error;
  }

  //
  // Check the number of parameters.
  //
  Status = EFI_INVALID_PARAMETER;

  ParamCount = ShellCommandLineGetCount (CheckPackage);
  if (ParamCount > MAX_PARAM_COUNT) {
    PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_MANY), NULL);
    goto Error;
  }

  if (ParamCount < MIN_PARAM_COUNT) {
    PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_FEW), NULL);
    goto Error;
  }

  ZeroMem (&Context.HttpConfigData, sizeof (Context.HttpConfigData));
  ZeroMem (&IPv4Node, sizeof (IPv4Node));
  IPv4Node.UseDefaultAddress = TRUE;

  Context.HttpConfigData.HttpVersion          = HttpVersion11;
  Context.HttpConfigData.AccessPoint.IPv4Node = &IPv4Node;

  //
  // Get the host address (not necessarily IPv4 format).
  //
  ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
  if (!ValueStr) {
    PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
    goto Error;
  } else {
    StartSize = 0;
    TrimSpaces ((CHAR16 *)ValueStr);
    if (!StrStr (ValueStr, L"://")) {
      Context.ServerAddrAndProto = StrnCatGrow (
                                     &Context.ServerAddrAndProto,
                                     &StartSize,
                                     DEFAULT_HTTP_PROTO,
                                     StrLen (DEFAULT_HTTP_PROTO)
                                     );
      Context.ServerAddrAndProto = StrnCatGrow (
                                     &Context.ServerAddrAndProto,
                                     &StartSize,
                                     L"://",
                                     StrLen (L"://")
                                     );
      VStr = (CHAR16 *)ValueStr;
    } else {
      VStr = StrStr (ValueStr, L"://") + StrLen (L"://");
    }

    for (Walker1 = VStr; *Walker1; Walker1++) {
      if (*Walker1 == L'/') {
        break;
      }
    }

    if (*Walker1 == L'/') {
      ParamOffset    = 1;
      RemoteFilePath = Walker1;
    }

    Context.ServerAddrAndProto = StrnCatGrow (
                                   &Context.ServerAddrAndProto,
                                   &StartSize,
                                   ValueStr,
                                   StrLen (ValueStr) - StrLen (Walker1)
                                   );
    if (!Context.ServerAddrAndProto) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }
  }

  if (!RemoteFilePath) {
    RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
    if (!RemoteFilePath) {
      //
      // If no path given, assume just "/".
      //
      RemoteFilePath = L"/";
    }
  }

  TrimSpaces ((CHAR16 *)RemoteFilePath);

  if (ParamCount == MAX_PARAM_COUNT - ParamOffset) {
    mLocalFilePath = ShellCommandLineGetRawValue (
                       CheckPackage,
                       MAX_PARAM_COUNT - 1 - ParamOffset
                       );
  } else {
    Walker = RemoteFilePath + StrLen (RemoteFilePath);
    while ((--Walker) >= RemoteFilePath) {
      if ((*Walker == L'\\') ||
          (*Walker == L'/'))
      {
        break;
      }
    }

    mLocalFilePath = Walker + 1;
  }

  if (!StrLen (mLocalFilePath)) {
    mLocalFilePath = DEFAULT_HTML_FILE;
  }

  InitialSize = 0;
  Context.Uri = StrnCatGrow (
                  &Context.Uri,
                  &InitialSize,
                  RemoteFilePath,
                  StrLen (RemoteFilePath)
                  );
  if (!Context.Uri) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  //
  // Get the name of the Network Interface Card to be used if any.
  //
  UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");
  if (  (ValueStr != NULL)
     && (!StringToUint16 (
            ValueStr,
            &Context.HttpConfigData.AccessPoint.IPv4Node->LocalPort
            )
         ))
  {
    goto Error;
  }

  Context.BufferSize = DEFAULT_BUF_SIZE;

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");
  if (ValueStr != NULL) {
    Context.BufferSize = ShellStrToUintn (ValueStr);
    if (!Context.BufferSize || (Context.BufferSize > MAX_BUF_SIZE)) {
      PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
      goto Error;
    }
  }

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
  if (ValueStr != NULL) {
    Context.HttpConfigData.TimeOutMillisec = (UINT32)ShellStrToUintn (ValueStr);
  }

  //
  // Locate all HTTP Service Binding protocols.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiManagedNetworkServiceBindingProtocolGuid,
                  NULL,
                  &HandleCount,
                  &Handles
                  );
  if (EFI_ERROR (Status) || (HandleCount == 0)) {
    PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NO_NIC), NULL);
    if (!EFI_ERROR (Status)) {
      Status = EFI_NOT_FOUND;
    }

    goto Error;
  }

  Status = EFI_NOT_FOUND;

  Context.Flags = 0;
  if (ShellCommandLineGetFlag (CheckPackage, L"-m")) {
    Context.Flags |= DL_FLAG_TIME;
  }

  if (ShellCommandLineGetFlag (CheckPackage, L"-k")) {
    Context.Flags |= DL_FLAG_KEEP_BAD;
  }

  for (NicNumber = 0;
       (NicNumber < HandleCount) && (Status != EFI_SUCCESS);
       NicNumber++)
  {
    ControllerHandle = Handles[NicNumber];

    Status = GetNicName (ControllerHandle, NicNumber, NicName);
    if (EFI_ERROR (Status)) {
      PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NAME), NicNumber, Status);
      continue;
    }

    if (UserNicName != NULL) {
      if (StrCmp (NicName, UserNicName) != 0) {
        Status = EFI_NOT_FOUND;
        continue;
      }

      NicFound = TRUE;
    }

    Status = DownloadFile (&Context, ControllerHandle, NicName);
    PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);

    if (EFI_ERROR (Status)) {
      PRINT_HII (
        STRING_TOKEN (STR_HTTP_ERR_DOWNLOAD),
        RemoteFilePath,
        NicName,
        Status
        );
      //
      // If a user aborted the operation,
      // do not try another controller.
      //
      if (Status == EFI_ABORTED) {
        goto Error;
      }
    }

    if (gHttpError) {
      //
      // This is not related to connection, so no need to repeat with
      // another interface.
      //
      break;
    }
  }

  if ((UserNicName != NULL) && (!NicFound)) {
    PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NOT_FOUND), UserNicName);
  }

Error:
  ShellCommandLineFreeVarList (CheckPackage);
  SHELL_FREE_NON_NULL (Handles);
  SHELL_FREE_NON_NULL (Context.ServerAddrAndProto);
  SHELL_FREE_NON_NULL (Context.Uri);

  return Status & ~MAX_BIT;
}

/**
  Check and convert the UINT16 option values of the 'http' command

  @param[in]  ValueStr  Value as an Unicode encoded string
  @param[out] Value     UINT16 value

  @retval     TRUE      The value was returned.
  @retval     FALSE     A parsing error occured.
**/
STATIC
BOOLEAN
StringToUint16 (
  IN   CONST CHAR16  *ValueStr,
  OUT  UINT16        *Value
  )
{
  UINTN  Val;

  Val = ShellStrToUintn (ValueStr);
  if (Val > MAX_UINT16) {
    PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
    return FALSE;
  }

  *Value = (UINT16)Val;
  return TRUE;
}

/**
  Get the name of the NIC.

  @param[in]   ControllerHandle  The network physical device handle.
  @param[in]   NicNumber         The network physical device number.
  @param[out]  NicName           Address where to store the NIC name.
                                 The memory area has to be at least
                                 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
                                 double byte wide.

  @retval  EFI_SUCCESS  The name of the NIC was returned.
  @retval  Others       The creation of the child for the Managed
                        Network Service failed or the opening of
                        the Managed Network Protocol failed or
                        the operational parameters for the
                        Managed Network Protocol could not be
                        read.
**/
STATIC
EFI_STATUS
GetNicName (
  IN   EFI_HANDLE  ControllerHandle,
  IN   UINTN       NicNumber,
  OUT  CHAR16      *NicName
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    MnpHandle;
  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;
  EFI_SIMPLE_NETWORK_MODE       SnpMode;

  Status = CreateServiceChildAndOpenProtocol (
             ControllerHandle,
             &gEfiManagedNetworkServiceBindingProtocolGuid,
             &gEfiManagedNetworkProtocolGuid,
             &MnpHandle,
             (VOID **)&Mnp
             );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
  if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
    goto Error;
  }

  UnicodeSPrint (
    NicName,
    IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
    SnpMode.IfType == NET_IFTYPE_ETHERNET ? L"eth%d" : L"unk%d",
    NicNumber
    );

  Status = EFI_SUCCESS;

Error:

  if (MnpHandle != NULL) {
    CloseProtocolAndDestroyServiceChild (
      ControllerHandle,
      &gEfiManagedNetworkServiceBindingProtocolGuid,
      &gEfiManagedNetworkProtocolGuid,
      MnpHandle
      );
  }

  return Status;
}

/**
  Create a child for the service identified by its service binding protocol GUID
  and get from the child the interface of the protocol identified by its GUID.

  @param[in]   ControllerHandle            Controller handle.
  @param[in]   ServiceBindingProtocolGuid  Service binding protocol GUID of the
                                           service to be created.
  @param[in]   ProtocolGuid                GUID of the protocol to be open.
  @param[out]  ChildHandle                 Address where the handler of the
                                           created child is returned. NULL is
                                           returned in case of error.
  @param[out]  Interface                   Address where a pointer to the
                                           protocol interface is returned in
                                           case of success.

  @retval  EFI_SUCCESS  The child was created and the protocol opened.
  @retval  Others       Either the creation of the child or the opening
                        of the protocol failed.
**/
STATIC
EFI_STATUS
CreateServiceChildAndOpenProtocol (
  IN   EFI_HANDLE  ControllerHandle,
  IN   EFI_GUID    *ServiceBindingProtocolGuid,
  IN   EFI_GUID    *ProtocolGuid,
  OUT  EFI_HANDLE  *ChildHandle,
  OUT  VOID        **Interface
  )
{
  EFI_STATUS  Status;

  *ChildHandle = NULL;
  Status       = NetLibCreateServiceChild (
                   ControllerHandle,
                   gImageHandle,
                   ServiceBindingProtocolGuid,
                   ChildHandle
                   );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    *ChildHandle,
                    ProtocolGuid,
                    Interface,
                    gImageHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      NetLibDestroyServiceChild (
        ControllerHandle,
        gImageHandle,
        ServiceBindingProtocolGuid,
        *ChildHandle
        );
      *ChildHandle = NULL;
    }
  }

  return Status;
}

/**
  Close the protocol identified by its GUID on the child handle of the service
  identified by its service binding protocol GUID, then destroy the child
  handle.

  @param[in]  ControllerHandle            Controller handle.
  @param[in]  ServiceBindingProtocolGuid  Service binding protocol GUID of the
                                          service to be destroyed.
  @param[in]  ProtocolGuid                GUID of the protocol to be closed.
  @param[in]  ChildHandle                 Handle of the child to be destroyed.
**/
STATIC
VOID
CloseProtocolAndDestroyServiceChild (
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_GUID    *ServiceBindingProtocolGuid,
  IN  EFI_GUID    *ProtocolGuid,
  IN  EFI_HANDLE  ChildHandle
  )
{
  gBS->CloseProtocol (
         ChildHandle,
         ProtocolGuid,
         gImageHandle,
         ControllerHandle
         );

  NetLibDestroyServiceChild (
    ControllerHandle,
    gImageHandle,
    ServiceBindingProtocolGuid,
    ChildHandle
    );
}

/**
  Wait until operation completes. Completion is indicated by
  setting of an appropriate variable.

  @param[in]      Context             A pointer to the HTTP download context.
  @param[in, out]  CallBackComplete   A pointer to the callback completion
                                      variable set by the callback.

  @retval  EFI_SUCCESS                Callback signalled completion.
  @retval  EFI_TIMEOUT                Timed out waiting for completion.
  @retval  Others                     Error waiting for completion.
**/
STATIC
EFI_STATUS
WaitForCompletion (
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN OUT BOOLEAN            *CallBackComplete
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   WaitEvt;

  Status = EFI_SUCCESS;

  //
  // Use a timer to measure timeout. Cannot use Stall here!
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &WaitEvt
                  );
  ASSERT_EFI_ERROR (Status);

  if (!EFI_ERROR (Status)) {
    Status = gBS->SetTimer (
                    WaitEvt,
                    TimerRelative,
                    EFI_TIMER_PERIOD_SECONDS (TIMER_MAX_TIMEOUT_S)
                    );

    ASSERT_EFI_ERROR (Status);
  }

  while (  !*CallBackComplete
        && (!EFI_ERROR (Status))
        && EFI_ERROR (gBS->CheckEvent (WaitEvt)))
  {
    Status = Context->Http->Poll (Context->Http);
    if (  !Context->ContentDownloaded
       && (CallBackComplete == &gResponseCallbackComplete))
    {
      //
      // An HTTP server may just send a response redirection header.
      // In this case, don't wait for the event as
      // it might never happen and we waste 10s waiting.
      // Note that at this point Response may not has been populated,
      // so it needs to be checked first.
      //
      if (  Context->ResponseToken.Message
         && Context->ResponseToken.Message->Data.Response
         && (NEED_REDIRECTION (
               Context->ResponseToken.Message->Data.Response->StatusCode
               )
             ))
      {
        break;
      }
    }
  }

  gBS->SetTimer (WaitEvt, TimerCancel, 0);
  gBS->CloseEvent (WaitEvt);

  if (*CallBackComplete) {
    return EFI_SUCCESS;
  }

  if (!EFI_ERROR (Status)) {
    Status = EFI_TIMEOUT;
  }

  return Status;
}

/**
  Generate and send a request to the http server.

  @param[in]   Context           HTTP download context.
  @param[in]   DownloadUrl       Fully qualified URL to be downloaded.

  @retval EFI_SUCCESS            Request has been sent successfully.
  @retval EFI_INVALID_PARAMETER  Invalid URL.
  @retval EFI_OUT_OF_RESOURCES   Out of memory.
  @retval EFI_DEVICE_ERROR       If HTTPS is used, this probably
                                 means that TLS support either was not
                                 installed or not configured.
  @retval Others                 Error sending the request.
**/
STATIC
EFI_STATUS
SendRequest (
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN CHAR16                 *DownloadUrl
  )
{
  EFI_HTTP_REQUEST_DATA  RequestData;
  EFI_HTTP_HEADER        RequestHeader[HdrMax];
  EFI_HTTP_MESSAGE       RequestMessage;
  EFI_STATUS             Status;
  CHAR16                 *Host;
  UINTN                  StringSize;

  ZeroMem (&RequestData, sizeof (RequestData));
  ZeroMem (&RequestHeader, sizeof (RequestHeader));
  ZeroMem (&RequestMessage, sizeof (RequestMessage));
  ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));

  RequestHeader[HdrHost].FieldName  = "Host";
  RequestHeader[HdrConn].FieldName  = "Connection";
  RequestHeader[HdrAgent].FieldName = "User-Agent";

  Host = (CHAR16 *)Context->ServerAddrAndProto;
  while (*Host != CHAR_NULL && *Host != L'/') {
    Host++;
  }

  if (*Host == CHAR_NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the next slash.
  //
  Host++;
  //
  // And now the host name.
  //
  Host++;

  StringSize                        = StrLen (Host) + 1;
  RequestHeader[HdrHost].FieldValue = AllocatePool (StringSize);
  if (!RequestHeader[HdrHost].FieldValue) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStrS (
    Host,
    RequestHeader[HdrHost].FieldValue,
    StringSize
    );

  RequestHeader[HdrConn].FieldValue  = "close";
  RequestHeader[HdrAgent].FieldValue = USER_AGENT_HDR;
  RequestMessage.HeaderCount         = HdrMax;

  RequestData.Method = HttpMethodGet;
  RequestData.Url    = DownloadUrl;

  RequestMessage.Data.Request = &RequestData;
  RequestMessage.Headers      = RequestHeader;
  RequestMessage.BodyLength   = 0;
  RequestMessage.Body         = NULL;
  Context->RequestToken.Event = NULL;

  //
  // Completion callback event to be set when Request completes.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RequestCallback,
                  Context,
                  &Context->RequestToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  Context->RequestToken.Status  = EFI_SUCCESS;
  Context->RequestToken.Message = &RequestMessage;
  gRequestCallbackComplete      = FALSE;
  Status                        = Context->Http->Request (Context->Http, &Context->RequestToken);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = WaitForCompletion (Context, &gRequestCallbackComplete);
  if (EFI_ERROR (Status)) {
    Context->Http->Cancel (Context->Http, &Context->RequestToken);
  }

Error:
  SHELL_FREE_NON_NULL (RequestHeader[HdrHost].FieldValue);
  if (Context->RequestToken.Event) {
    gBS->CloseEvent (Context->RequestToken.Event);
    ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));
  }

  return Status;
}

/**
  Update the progress of a file download
  This procedure is called each time a new HTTP body portion is received.

  @param[in]  Context      HTTP download context.
  @param[in]  DownloadLen  Portion size, in bytes.
  @param[in]  Buffer       The pointer to the parsed buffer.

  @retval  EFI_SUCCESS     Portion saved.
  @retval  Other           Error saving the portion.
**/
STATIC
EFI_STATUS
EFIAPI
SavePortion (
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN UINTN                  DownloadLen,
  IN CHAR8                  *Buffer
  )
{
  CHAR16      Progress[HTTP_PROGRESS_MESSAGE_SIZE];
  UINTN       NbOfKb;
  UINTN       Index;
  UINTN       LastStep;
  UINTN       Step;
  EFI_STATUS  Status;

  LastStep = 0;
  Step     = 0;

  ShellSetFilePosition (mFileHandle, Context->LastReportedNbOfBytes);
  Status = ShellWriteFile (mFileHandle, &DownloadLen, Buffer);
  if (EFI_ERROR (Status)) {
    if (Context->ContentDownloaded > 0) {
      PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);
    }

    PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_WRITE), mLocalFilePath, Status);
    return Status;
  }

  if (Context->ContentDownloaded == 0) {
    ShellPrintEx (-1, -1, L"%s       0 Kb", HTTP_PROGR_FRAME);
  }

  Context->ContentDownloaded += DownloadLen;
  NbOfKb                      = Context->ContentDownloaded >> 10;

  Progress[0] = L'\0';
  if (Context->ContentLength) {
    LastStep = (Context->LastReportedNbOfBytes * HTTP_PROGRESS_SLIDER_STEPS) /
               Context->ContentLength;
    Step = (Context->ContentDownloaded * HTTP_PROGRESS_SLIDER_STEPS) /
           Context->ContentLength;
  }

  Context->LastReportedNbOfBytes = Context->ContentDownloaded;

  if (Step <= LastStep) {
    if (!Context->ContentLength) {
      //
      // Update downloaded size, there is no length info available.
      //
      ShellPrintEx (-1, -1, L"%s", HTTP_KB);
      ShellPrintEx (-1, -1, L"%7d Kb", NbOfKb);
    }

    return EFI_SUCCESS;
  }

  ShellPrintEx (-1, -1, L"%s", HTTP_PROGRESS_DEL);

  Status = StrCpyS (Progress, HTTP_PROGRESS_MESSAGE_SIZE, HTTP_PROGR_FRAME);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 1; Index < Step; Index++) {
    Progress[Index] = L'=';
  }

  if (Step) {
    Progress[Step] = L'>';
  }

  UnicodeSPrint (
    Progress + (sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 1,
    sizeof (Progress) - sizeof (HTTP_PROGR_FRAME),
    L" %7d Kb",
    NbOfKb
    );

  ShellPrintEx (-1, -1, L"%s", Progress);

  return EFI_SUCCESS;
}

/**
  Replace the original Host and Uri with Host and Uri returned by the
  HTTP server in 'Location' header (redirection).

  @param[in]   Location           A pointer to the 'Location' string
                                  provided by HTTP server.
  @param[in]   Context            A pointer to HTTP download context.
  @param[in]   DownloadUrl        Fully qualified HTTP URL.

  @retval  EFI_SUCCESS            Host and Uri were successfully set.
  @retval  EFI_OUT_OF_RESOURCES   Error setting Host or Uri.
**/
STATIC
EFI_STATUS
SetHostURI (
  IN CHAR8                  *Location,
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN CHAR16                 *DownloadUrl
  )
{
  EFI_STATUS  Status;
  UINTN       StringSize;
  UINTN       FirstStep;
  UINTN       Idx;
  UINTN       Step;
  CHAR8       *Walker;
  CHAR16      *Temp;
  CHAR8       *Tmp;
  CHAR16      *Url;
  BOOLEAN     IsAbEmptyUrl;

  Tmp          = NULL;
  Url          = NULL;
  IsAbEmptyUrl = FALSE;
  FirstStep    = 0;

  StringSize = (AsciiStrSize (Location) * sizeof (CHAR16));
  Url        = AllocateZeroPool (StringSize);
  if (!Url) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AsciiStrToUnicodeStrS (
             (CONST CHAR8 *)Location,
             Url,
             StringSize
             );

  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // If an HTTP server redirects to the same location more than once,
  // then stop attempts and tell it is not reachable.
  //
  if (!StrCmp (Url, DownloadUrl)) {
    Status = EFI_NO_MAPPING;
    goto Error;
  }

  if (AsciiStrLen (Location) > 2) {
    //
    // Some servers return 'Location: //server/resource'
    //
    IsAbEmptyUrl = (Location[0] == '/') && (Location[1] == '/');
    if (IsAbEmptyUrl) {
      //
      // Skip first "//"
      //
      Location += 2;
      FirstStep = 1;
    }
  }

  if (AsciiStrStr (Location, "://") || IsAbEmptyUrl) {
    Idx    = 0;
    Walker = Location;

    for (Step = FirstStep; Step < 2; Step++) {
      for ( ; *Walker != '/' && *Walker != '\0'; Walker++) {
        Idx++;
      }

      if (!Step) {
        //
        // Skip "//"
        //
        Idx    += 2;
        Walker += 2;
      }
    }

    Tmp = AllocateZeroPool (Idx + 1);
    if (!Tmp) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    CopyMem (Tmp, Location, Idx);

    //
    // Location now points to Uri
    //
    Location  += Idx;
    StringSize = (Idx + 1) * sizeof (CHAR16);

    SHELL_FREE_NON_NULL (Context->ServerAddrAndProto);

    Temp = AllocateZeroPool (StringSize);
    if (!Temp) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    Status = AsciiStrToUnicodeStrS (
               (CONST CHAR8 *)Tmp,
               Temp,
               StringSize
               );
    if (EFI_ERROR (Status)) {
      SHELL_FREE_NON_NULL (Temp);
      goto Error;
    }

    Idx = 0;
    if (IsAbEmptyUrl) {
      Context->ServerAddrAndProto = StrnCatGrow (
                                      &Context->ServerAddrAndProto,
                                      &Idx,
                                      L"http://",
                                      StrLen (L"http://")
                                      );
    }

    Context->ServerAddrAndProto = StrnCatGrow (
                                    &Context->ServerAddrAndProto,
                                    &Idx,
                                    Temp,
                                    StrLen (Temp)
                                    );
    SHELL_FREE_NON_NULL (Temp);
    if (!Context->ServerAddrAndProto) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }
  }

  SHELL_FREE_NON_NULL (Context->Uri);

  StringSize   = AsciiStrSize (Location) * sizeof (CHAR16);
  Context->Uri = AllocateZeroPool (StringSize);
  if (!Context->Uri) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  //
  // Now make changes to the Uri part.
  //
  Status = AsciiStrToUnicodeStrS (
             (CONST CHAR8 *)Location,
             Context->Uri,
             StringSize
             );
Error:
  SHELL_FREE_NON_NULL (Tmp);
  SHELL_FREE_NON_NULL (Url);

  return Status;
}

/**
  Message parser callback.
  Save a portion of HTTP body.

  @param[in]   EventType       Type of event. Can be either
                               OnComplete or OnData.
  @param[in]   Data            A pointer to the buffer with data.
  @param[in]   Length          Data length of this portion.
  @param[in]   Context         A pointer to the HTTP download context.

  @retval      EFI_SUCCESS    The portion was processed successfully.
  @retval      Other          Error returned by SavePortion.
**/
STATIC
EFI_STATUS
EFIAPI
ParseMsg (
  IN HTTP_BODY_PARSE_EVENT  EventType,
  IN CHAR8                  *Data,
  IN UINTN                  Length,
  IN VOID                   *Context
  )
{
  if (  (Data == NULL)
     || (EventType == BodyParseEventOnComplete)
     || (Context == NULL))
  {
    return EFI_SUCCESS;
  }

  return SavePortion (Context, Length, Data);
}

/**
  Get HTTP server response and collect the whole body as a file.
  Set appropriate status in Context (REQ_OK, REQ_REPEAT, REQ_ERROR).
  Note that even if HTTP server returns an error code, it might send
  the body as well. This body will be collected in the resultant file.

  @param[in]   Context         A pointer to the HTTP download context.
  @param[in]   DownloadUrl     A pointer to the fully qualified URL to download.

  @retval  EFI_SUCCESS         Valid file. Body successfully collected.
  @retval  EFI_HTTP_ERROR      Response is a valid HTTP response, but the
                               HTTP server
                               indicated an error (HTTP code >= 400).
                               Response body MAY contain full
                               HTTP server response.
  @retval Others               Error getting the reponse from the HTTP server.
                               Response body is not collected.
**/
STATIC
EFI_STATUS
GetResponse (
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN CHAR16                 *DownloadUrl
  )
{
  EFI_HTTP_RESPONSE_DATA  ResponseData;
  EFI_HTTP_MESSAGE        ResponseMessage;
  EFI_HTTP_HEADER         *Header;
  EFI_STATUS              Status;
  VOID                    *MsgParser;
  EFI_TIME                StartTime;
  EFI_TIME                EndTime;
  CONST CHAR16            *Desc;
  UINTN                   ElapsedSeconds;
  BOOLEAN                 IsTrunked;
  BOOLEAN                 CanMeasureTime;

  ZeroMem (&ResponseData, sizeof (ResponseData));
  ZeroMem (&ResponseMessage, sizeof (ResponseMessage));
  ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
  IsTrunked = FALSE;

  ResponseMessage.Body           = Context->Buffer;
  Context->ResponseToken.Status  = EFI_SUCCESS;
  Context->ResponseToken.Message = &ResponseMessage;
  Context->ContentLength         = 0;
  Context->Status                = REQ_OK;
  Status                         = EFI_SUCCESS;
  MsgParser                      = NULL;
  ResponseData.StatusCode        = HTTP_STATUS_UNSUPPORTED_STATUS;
  ResponseMessage.Data.Response  = &ResponseData;
  Context->ResponseToken.Event   = NULL;
  CanMeasureTime                 = FALSE;
  if (Context->Flags & DL_FLAG_TIME) {
    ZeroMem (&StartTime, sizeof (StartTime));
    CanMeasureTime = !EFI_ERROR (gRT->GetTime (&StartTime, NULL));
  }

  do {
    SHELL_FREE_NON_NULL (ResponseMessage.Headers);
    ResponseMessage.HeaderCount = 0;
    gResponseCallbackComplete   = FALSE;
    ResponseMessage.BodyLength  = Context->BufferSize;

    if (ShellGetExecutionBreakFlag ()) {
      Status = EFI_ABORTED;
      break;
    }

    if (!Context->ContentDownloaded && !Context->ResponseToken.Event) {
      Status = gBS->CreateEvent (
                      EVT_NOTIFY_SIGNAL,
                      TPL_CALLBACK,
                      ResponseCallback,
                      Context,
                      &Context->ResponseToken.Event
                      );
      ASSERT_EFI_ERROR (Status);
    } else {
      ResponseMessage.Data.Response = NULL;
    }

    if (EFI_ERROR (Status)) {
      break;
    }

    Status = Context->Http->Response (Context->Http, &Context->ResponseToken);
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = WaitForCompletion (Context, &gResponseCallbackComplete);
    if (EFI_ERROR (Status) && ResponseMessage.HeaderCount) {
      Status = EFI_SUCCESS;
    }

    if (EFI_ERROR (Status)) {
      Context->Http->Cancel (Context->Http, &Context->ResponseToken);
      break;
    }

    if (!Context->ContentDownloaded) {
      if (NEED_REDIRECTION (ResponseData.StatusCode)) {
        //
        // Need to repeat the request with new Location (server redirected).
        //
        Context->Status = REQ_NEED_REPEAT;

        Header = HttpFindHeader (
                   ResponseMessage.HeaderCount,
                   ResponseMessage.Headers,
                   "Location"
                   );
        if (Header) {
          Status = SetHostURI (Header->FieldValue, Context, DownloadUrl);
          if (Status == EFI_NO_MAPPING) {
            PRINT_HII (
              STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
              Context->ServerAddrAndProto,
              L"Recursive HTTP server relocation",
              Context->Uri
              );
          }
        } else {
          //
          // Bad reply from the server. Server must specify the location.
          // Indicate that resource was not found, and no body collected.
          //
          Status = EFI_NOT_FOUND;
        }

        Context->Http->Cancel (Context->Http, &Context->ResponseToken);
        break;
      }

      //
      // Init message-body parser by header information.
      //
      if (!MsgParser) {
        Status = HttpInitMsgParser (
                   ResponseMessage.Data.Request->Method,
                   ResponseData.StatusCode,
                   ResponseMessage.HeaderCount,
                   ResponseMessage.Headers,
                   ParseMsg,
                   Context,
                   &MsgParser
                   );
        if (EFI_ERROR (Status)) {
          break;
        }
      }

      //
      // If it is a trunked message, rely on the parser.
      //
      Header = HttpFindHeader (
                 ResponseMessage.HeaderCount,
                 ResponseMessage.Headers,
                 "Transfer-Encoding"
                 );
      IsTrunked = (Header && !AsciiStrCmp (Header->FieldValue, "chunked"));

      HttpGetEntityLength (MsgParser, &Context->ContentLength);

      if (  (ResponseData.StatusCode >= HTTP_STATUS_400_BAD_REQUEST)
         && (ResponseData.StatusCode != HTTP_STATUS_308_PERMANENT_REDIRECT))
      {
        //
        // Server reported an error via Response code.
        // Collect the body if any.
        //
        if (!gHttpError) {
          gHttpError = TRUE;

          Desc = ErrStatusDesc[ResponseData.StatusCode -
                               HTTP_STATUS_400_BAD_REQUEST];
          PRINT_HII (
            STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
            Context->ServerAddrAndProto,
            Desc,
            Context->Uri
            );

          //
          // This gives an RFC HTTP error.
          //
          Context->Status = ShellStrToUintn (Desc);
          Status          = ENCODE_ERROR (Context->Status);
        }
      }
    }

    //
    // Do NOT try to parse an empty body.
    //
    if (ResponseMessage.BodyLength || IsTrunked) {
      Status = HttpParseMessageBody (
                 MsgParser,
                 ResponseMessage.BodyLength,
                 ResponseMessage.Body
                 );
    }
  } while (  !HttpIsMessageComplete (MsgParser)
          && !EFI_ERROR (Status)
          && ResponseMessage.BodyLength);

  if (  (Context->Status != REQ_NEED_REPEAT)
     && (Status == EFI_SUCCESS)
     && CanMeasureTime)
  {
    if (!EFI_ERROR (gRT->GetTime (&EndTime, NULL))) {
      ElapsedSeconds = EfiTimeToEpoch (&EndTime) - EfiTimeToEpoch (&StartTime);
      Print (
        L",%a%Lus",
        ElapsedSeconds ? " " : " < ",
        ElapsedSeconds > 1 ? (UINT64)ElapsedSeconds : 1
        );
    }
  }

  SHELL_FREE_NON_NULL (MsgParser);
  if (Context->ResponseToken.Event) {
    gBS->CloseEvent (Context->ResponseToken.Event);
    ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
  }

  return Status;
}

/**
  Worker function that downloads the data of a file from an HTTP server given
  the path of the file and its size.

  @param[in]   Context           A pointer to the HTTP download context.
  @param[in]   ControllerHandle  The handle of the network interface controller
  @param[in]   NicName           NIC name

  @retval  EFI_SUCCESS           The file was downloaded.
  @retval  EFI_OUT_OF_RESOURCES  A memory allocation failed.
  #return  EFI_HTTP_ERROR        The server returned a valid HTTP error.
                                 Examine the mLocalFilePath file
                                 to get error body.
  @retval  Others                The downloading of the file from the server
                                 failed.
**/
STATIC
EFI_STATUS
DownloadFile (
  IN HTTP_DOWNLOAD_CONTEXT  *Context,
  IN EFI_HANDLE             ControllerHandle,
  IN CHAR16                 *NicName
  )
{
  EFI_STATUS  Status;
  CHAR16      *DownloadUrl;
  UINTN       UrlSize;
  EFI_HANDLE  HttpChildHandle;

  ASSERT (Context);
  if (Context == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DownloadUrl     = NULL;
  HttpChildHandle = NULL;

  Context->Buffer = AllocatePool (Context->BufferSize);
  if (Context->Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Open the file.
  //
  if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
    ShellDeleteFileByName (mLocalFilePath);
  }

  Status = ShellOpenFileByName (
             mLocalFilePath,
             &mFileHandle,
             EFI_FILE_MODE_CREATE |
             EFI_FILE_MODE_WRITE  |
             EFI_FILE_MODE_READ,
             0
             );
  if (EFI_ERROR (Status)) {
    PRINT_HII_APP (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), mLocalFilePath);
    goto ON_EXIT;
  }

  do {
    SHELL_FREE_NON_NULL (DownloadUrl);

    CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);

    Status = CreateServiceChildAndOpenProtocol (
               ControllerHandle,
               &gEfiHttpServiceBindingProtocolGuid,
               &gEfiHttpProtocolGuid,
               &HttpChildHandle,
               (VOID **)&Context->Http
               );

    if (EFI_ERROR (Status)) {
      PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_OPEN_PROTOCOL), NicName, Status);
      goto ON_EXIT;
    }

    Status = Context->Http->Configure (Context->Http, &Context->HttpConfigData);
    if (EFI_ERROR (Status)) {
      PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_CONFIGURE), NicName, Status);
      goto ON_EXIT;
    }

    UrlSize     = 0;
    DownloadUrl = StrnCatGrow (
                    &DownloadUrl,
                    &UrlSize,
                    Context->ServerAddrAndProto,
                    StrLen (Context->ServerAddrAndProto)
                    );
    if (Context->Uri[0] != L'/') {
      DownloadUrl = StrnCatGrow (
                      &DownloadUrl,
                      &UrlSize,
                      L"/",
                      StrLen (Context->ServerAddrAndProto)
                      );
    }

    DownloadUrl = StrnCatGrow (
                    &DownloadUrl,
                    &UrlSize,
                    Context->Uri,
                    StrLen (Context->Uri)
                    );
    if (DownloadUrl == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    PRINT_HII (STRING_TOKEN (STR_HTTP_DOWNLOADING), DownloadUrl);

    Status = SendRequest (Context, DownloadUrl);
    if (Status) {
      goto ON_EXIT;
    }

    Status = GetResponse (Context, DownloadUrl);

    if (Status) {
      goto ON_EXIT;
    }
  } while (Context->Status == REQ_NEED_REPEAT);

  if (Context->Status) {
    Status = ENCODE_ERROR (Context->Status);
  }

ON_EXIT:
  //
  // Close the file.
  //
  if (mFileHandle != NULL) {
    if (EFI_ERROR (Status) && !(Context->Flags & DL_FLAG_KEEP_BAD)) {
      ShellDeleteFile (&mFileHandle);
    } else {
      ShellCloseFile (&mFileHandle);
    }
  }

  SHELL_FREE_NON_NULL (DownloadUrl);
  SHELL_FREE_NON_NULL (Context->Buffer);

  CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);

  return Status;
}

/**
  Retrive HII package list from ImageHandle and publish to HII database.

  @param[in] ImageHandle            The image handle of the process.

  @retval HII handle.
**/
EFI_HII_HANDLE
InitializeHiiPackage (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                   Status;
  EFI_HII_PACKAGE_LIST_HEADER  *PackageList;
  EFI_HII_HANDLE               HiiHandle;

  //
  // Retrieve HII package list from ImageHandle.
  //
  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiHiiPackageListProtocolGuid,
                  (VOID **)&PackageList,
                  ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Publish HII package list to HII Database.
  //
  Status = gHiiDatabase->NewPackageList (
                           gHiiDatabase,
                           PackageList,
                           NULL,
                           &HiiHandle
                           );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  return HiiHandle;
}
