/** @file
  Implementation of EFI_HTTP_PROTOCOL protocol interfaces.

  Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HttpDriver.h"

EFI_HTTP_PROTOCOL  mEfiHttpTemplate = {
  EfiHttpGetModeData,
  EfiHttpConfigure,
  EfiHttpRequest,
  EfiHttpCancel,
  EfiHttpResponse,
  EfiHttpPoll
};

/**
  Returns the operational parameters for the current HTTP child instance.

  The GetModeData() function is used to read the current mode data (operational
  parameters) for this HTTP protocol instance.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[out] HttpConfigData      Point to buffer for operational parameters of this
                                  HTTP instance. It is the responsibility of the caller
                                  to allocate the memory for HttpConfigData and
                                  HttpConfigData->AccessPoint.IPv6Node/IPv4Node. In fact,
                                  it is recommended to allocate sufficient memory to record
                                  IPv6Node since it is big enough for all possibilities.

  @retval EFI_SUCCESS             Operation succeeded.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  HttpConfigData is NULL.
                                  HttpConfigData->AccessPoint.IPv4Node or
                                  HttpConfigData->AccessPoint.IPv6Node is NULL.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.

**/
EFI_STATUS
EFIAPI
EfiHttpGetModeData (
  IN  EFI_HTTP_PROTOCOL     *This,
  OUT EFI_HTTP_CONFIG_DATA  *HttpConfigData
  )
{
  HTTP_PROTOCOL  *HttpInstance;

  //
  // Check input parameters.
  //
  if ((This == NULL) || (HttpConfigData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

  if ((HttpConfigData->AccessPoint.IPv6Node == NULL) ||
      (HttpConfigData->AccessPoint.IPv4Node == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  HttpConfigData->HttpVersion        = HttpInstance->HttpVersion;
  HttpConfigData->TimeOutMillisec    = HttpInstance->TimeOutMillisec;
  HttpConfigData->LocalAddressIsIPv6 = HttpInstance->LocalAddressIsIPv6;

  if (HttpInstance->LocalAddressIsIPv6) {
    CopyMem (
      HttpConfigData->AccessPoint.IPv6Node,
      &HttpInstance->Ipv6Node,
      sizeof (HttpInstance->Ipv6Node)
      );
  } else {
    CopyMem (
      HttpConfigData->AccessPoint.IPv4Node,
      &HttpInstance->IPv4Node,
      sizeof (HttpInstance->IPv4Node)
      );
  }

  return EFI_SUCCESS;
}

/**
  Initialize or brutally reset the operational parameters for this EFI HTTP instance.

  The Configure() function does the following:
  When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring
  timeout, local address, port, etc.
  When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active
  connections with remote hosts, canceling all asynchronous tokens, and flush request
  and response buffers without informing the appropriate hosts.

  No other EFI HTTP function can be executed by this instance until the Configure()
  function is executed and returns successfully.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  HttpConfigData      Pointer to the configure data to configure the instance.

  @retval EFI_SUCCESS             Operation succeeded.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  HttpConfigData->LocalAddressIsIPv6 is FALSE and
                                  HttpConfigData->AccessPoint.IPv4Node is NULL.
                                  HttpConfigData->LocalAddressIsIPv6 is TRUE and
                                  HttpConfigData->AccessPoint.IPv6Node is NULL.
  @retval EFI_ALREADY_STARTED     Reinitialize this HTTP instance without calling
                                  Configure() with NULL to reset it.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources when
                                  executing Configure().
  @retval EFI_UNSUPPORTED         One or more options in HttpConfigData are not supported
                                  in the implementation.
**/
EFI_STATUS
EFIAPI
EfiHttpConfigure (
  IN  EFI_HTTP_PROTOCOL     *This,
  IN  EFI_HTTP_CONFIG_DATA  *HttpConfigData OPTIONAL
  )
{
  HTTP_PROTOCOL  *HttpInstance;
  EFI_STATUS     Status;

  //
  // Check input parameters.
  //
  if ((This == NULL) ||
      ((HttpConfigData != NULL) &&
       ((HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv6Node == NULL)) ||
        (!HttpConfigData->LocalAddressIsIPv6 && (HttpConfigData->AccessPoint.IPv4Node == NULL)))))
  {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
  ASSERT (HttpInstance->Service != NULL);

  if (HttpConfigData != NULL) {
    if (HttpConfigData->HttpVersion >= HttpVersionUnsupported) {
      return EFI_UNSUPPORTED;
    }

    //
    // Now configure this HTTP instance.
    //
    if (HttpInstance->State != HTTP_STATE_UNCONFIGED) {
      return EFI_ALREADY_STARTED;
    }

    HttpInstance->HttpVersion        = HttpConfigData->HttpVersion;
    HttpInstance->TimeOutMillisec    = HttpConfigData->TimeOutMillisec;
    HttpInstance->LocalAddressIsIPv6 = HttpConfigData->LocalAddressIsIPv6;
    HttpInstance->ConnectionClose    = FALSE;

    if (HttpConfigData->LocalAddressIsIPv6) {
      CopyMem (
        &HttpInstance->Ipv6Node,
        HttpConfigData->AccessPoint.IPv6Node,
        sizeof (HttpInstance->Ipv6Node)
        );
    } else {
      CopyMem (
        &HttpInstance->IPv4Node,
        HttpConfigData->AccessPoint.IPv4Node,
        sizeof (HttpInstance->IPv4Node)
        );
    }

    //
    // Creat Tcp child
    //
    Status = HttpInitProtocol (HttpInstance, HttpInstance->LocalAddressIsIPv6);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    HttpInstance->State = HTTP_STATE_HTTP_CONFIGED;
    return EFI_SUCCESS;
  } else {
    //
    // Reset all the resources related to HttpInstance.
    //
    HttpCleanProtocol (HttpInstance);
    HttpInstance->State = HTTP_STATE_UNCONFIGED;
    return EFI_SUCCESS;
  }
}

/**
  The Request() function queues an HTTP request to this HTTP instance.

  Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
  successfully, or if there is an error, Status in token will be updated and Event will
  be signaled.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  Token               Pointer to storage containing HTTP request token.

  @retval EFI_SUCCESS             Outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_TIMEOUT             Data was dropped out of the transmit or receive queue.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
  @retval EFI_UNSUPPORTED         The HTTP method is not supported in current
                                  implementation.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token->Message is NULL.
                                  Token->Message->Body is not NULL,
                                  Token->Message->BodyLength is non-zero, and
                                  Token->Message->Data is NULL, but a previous call to
                                  Request()has not been completed successfully.
**/
EFI_STATUS
EFIAPI
EfiHttpRequest (
  IN  EFI_HTTP_PROTOCOL  *This,
  IN  EFI_HTTP_TOKEN     *Token
  )
{
  EFI_HTTP_MESSAGE       *HttpMsg;
  EFI_HTTP_REQUEST_DATA  *Request;
  VOID                   *UrlParser;
  EFI_STATUS             Status;
  CHAR8                  *HostName;
  UINTN                  HostNameSize;
  UINT16                 RemotePort;
  HTTP_PROTOCOL          *HttpInstance;
  BOOLEAN                Configure;
  BOOLEAN                ReConfigure;
  BOOLEAN                TlsConfigure;
  CHAR8                  *RequestMsg;
  CHAR8                  *Url;
  UINTN                  UrlLen;
  CHAR16                 *HostNameStr;
  HTTP_TOKEN_WRAP        *Wrap;
  CHAR8                  *FileUrl;
  UINTN                  RequestMsgSize;
  EFI_HANDLE             ImageHandle;

  //
  // Initializations
  //
  Url          = NULL;
  UrlParser    = NULL;
  RemotePort   = 0;
  HostName     = NULL;
  RequestMsg   = NULL;
  HostNameStr  = NULL;
  Wrap         = NULL;
  FileUrl      = NULL;
  TlsConfigure = FALSE;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpMsg = Token->Message;
  if (HttpMsg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Request = HttpMsg->Data.Request;

  //
  // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation.
  //
  if ((Request != NULL) && (Request->Method != HttpMethodGet) &&
      (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) &&
      (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) &&
      (Request->Method != HttpMethodPatch))
  {
    return EFI_UNSUPPORTED;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

  //
  // Capture the method into HttpInstance.
  //
  if (Request != NULL) {
    HttpInstance->Method = Request->Method;
  }

  if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (Request == NULL) {
    //
    // Request would be NULL only for PUT/POST/PATCH operation (in the current implementation)
    //
    if ((HttpInstance->Method != HttpMethodPut) &&
        (HttpInstance->Method != HttpMethodPost) &&
        (HttpInstance->Method != HttpMethodPatch))
    {
      return EFI_INVALID_PARAMETER;
    }

    //
    // For PUT/POST/PATCH, we need to have the TCP already configured. Bail out if it is not!
    //
    if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // We need to have the Message Body for sending the HTTP message across in these cases.
    //
    if ((HttpMsg->Body == NULL) || (HttpMsg->BodyLength == 0)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Use existing TCP instance to transmit the packet.
    //
    Configure   = FALSE;
    ReConfigure = FALSE;
  } else {
    //
    // Check whether the token already existed.
    //
    if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) {
      return EFI_ACCESS_DENIED;
    }

    //
    // Parse the URI of the remote host.
    //
    Url    = HttpInstance->Url;
    UrlLen = StrLen (Request->Url) + 1;
    if (UrlLen > HTTP_URL_BUFFER_LEN) {
      Url = AllocateZeroPool (UrlLen);
      if (Url == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      FreePool (HttpInstance->Url);
      HttpInstance->Url = Url;
    }

    UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);

    //
    // From the information in Url, the HTTP instance will
    // be able to determine whether to use http or https.
    //
    HttpInstance->UseHttps = IsHttpsUrl (Url);

    //
    // HTTP is disabled, return directly if the URI is not HTTPS.
    //
    if (!PcdGetBool (PcdAllowHttpConnections) && !(HttpInstance->UseHttps)) {
      DEBUG ((DEBUG_ERROR, "EfiHttpRequest: HTTP is disabled.\n"));

      return EFI_ACCESS_DENIED;
    }

    //
    // Check whether we need to create Tls child and open the TLS protocol.
    //
    if (HttpInstance->UseHttps && (HttpInstance->TlsChildHandle == NULL)) {
      //
      // Use TlsSb to create Tls child and open the TLS protocol.
      //
      if (HttpInstance->LocalAddressIsIPv6) {
        ImageHandle = HttpInstance->Service->Ip6DriverBindingHandle;
      } else {
        ImageHandle = HttpInstance->Service->Ip4DriverBindingHandle;
      }

      HttpInstance->TlsChildHandle = TlsCreateChild (
                                       ImageHandle,
                                       &(HttpInstance->TlsSb),
                                       &(HttpInstance->Tls),
                                       &(HttpInstance->TlsConfiguration)
                                       );
      if (HttpInstance->TlsChildHandle == NULL) {
        return EFI_DEVICE_ERROR;
      }

      TlsConfigure = TRUE;
    }

    UrlParser = NULL;
    Status    = HttpParseUrl (Url, (UINT32)AsciiStrLen (Url), FALSE, &UrlParser);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }

    Status = HttpUrlGetHostName (Url, UrlParser, &HostName);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }

    if (HttpInstance->LocalAddressIsIPv6) {
      HostNameSize = AsciiStrSize (HostName);

      if ((HostNameSize > 2) && (HostName[0] == '[') && (HostName[HostNameSize - 2] == ']')) {
        //
        // HostName format is expressed as IPv6, so, remove '[' and ']'.
        //
        HostNameSize -= 2;
        CopyMem (HostName, HostName + 1, HostNameSize - 1);
        HostName[HostNameSize - 1] = '\0';
      }
    }

    Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
    if (EFI_ERROR (Status)) {
      if (HttpInstance->UseHttps) {
        RemotePort = HTTPS_DEFAULT_PORT;
      } else {
        RemotePort = HTTP_DEFAULT_PORT;
      }
    }

    //
    // If Configure is TRUE, it indicates the first time to call Request();
    // If ReConfigure is TRUE, it indicates the request URL is not same
    // with the previous call to Request();
    //
    Configure   = TRUE;
    ReConfigure = TRUE;

    if (HttpInstance->RemoteHost == NULL) {
      //
      // Request() is called the first time.
      //
      ReConfigure = FALSE;
    } else {
      if ((HttpInstance->ConnectionClose == FALSE) &&
          (HttpInstance->RemotePort == RemotePort) &&
          (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
          (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
                                       !TlsConfigure &&
                                       (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))
      {
        //
        // Host Name and port number of the request URL are the same with previous call to Request().
        // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring.
        // Check whether previous TCP packet sent out.
        //

        if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
          //
          // Wrap the HTTP token in HTTP_TOKEN_WRAP
          //
          Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
          if (Wrap == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto Error1;
          }

          Wrap->HttpToken    = Token;
          Wrap->HttpInstance = HttpInstance;

          Status = HttpCreateTcpTxEvent (Wrap);
          if (EFI_ERROR (Status)) {
            goto Error1;
          }

          Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
          if (EFI_ERROR (Status)) {
            goto Error1;
          }

          Wrap->TcpWrap.Method = Request->Method;

          FreePool (HostName);

          HttpUrlFreeParser (UrlParser);

          //
          // Queue the HTTP token and return.
          //
          return EFI_SUCCESS;
        } else {
          //
          // Use existing TCP instance to transmit the packet.
          //
          Configure   = FALSE;
          ReConfigure = FALSE;
        }
      } else {
        //
        // Need close existing TCP instance and create a new TCP instance for data transmit.
        //
        if (HttpInstance->RemoteHost != NULL) {
          FreePool (HttpInstance->RemoteHost);
          HttpInstance->RemoteHost = NULL;
          HttpInstance->RemotePort = 0;
        }
      }
    }
  }

  if (Configure) {
    //
    // Parse Url for IPv4 or IPv6 address, if failed, perform DNS resolution.
    //
    if (!HttpInstance->LocalAddressIsIPv6) {
      Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
    } else {
      Status = HttpUrlGetIp6 (Url, UrlParser, &HttpInstance->RemoteIpv6Addr);
    }

    if (EFI_ERROR (Status)) {
      HostNameSize = AsciiStrSize (HostName);
      HostNameStr  = AllocateZeroPool (HostNameSize * sizeof (CHAR16));
      if (HostNameStr == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error1;
      }

      AsciiStrToUnicodeStrS (HostName, HostNameStr, HostNameSize);
      if (!HttpInstance->LocalAddressIsIPv6) {
        Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);
      } else {
        Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr);
      }

      HttpNotify (HttpEventDns, Status);

      FreePool (HostNameStr);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "Error: Could not retrieve the host address from DNS server.\n"));
        goto Error1;
      }
    }

    //
    // Save the RemotePort and RemoteHost.
    //
    ASSERT (HttpInstance->RemoteHost == NULL);
    HttpInstance->RemotePort = RemotePort;
    HttpInstance->RemoteHost = HostName;
    HostName                 = NULL;
  }

  if (ReConfigure) {
    //
    // The request URL is different from previous calls to Request(), close existing TCP instance.
    //
    if (!HttpInstance->LocalAddressIsIPv6) {
      ASSERT (HttpInstance->Tcp4 != NULL);
    } else {
      ASSERT (HttpInstance->Tcp6 != NULL);
    }

    if (HttpInstance->UseHttps && !TlsConfigure) {
      Status = TlsCloseSession (HttpInstance);
      if (EFI_ERROR (Status)) {
        goto Error1;
      }

      TlsCloseTxRxEvent (HttpInstance);
    }

    HttpCloseConnection (HttpInstance);
    EfiHttpCancel (This, NULL);
  }

  //
  // Wrap the HTTP token in HTTP_TOKEN_WRAP
  //
  Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
  if (Wrap == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error1;
  }

  Wrap->HttpToken    = Token;
  Wrap->HttpInstance = HttpInstance;
  if (Request != NULL) {
    Wrap->TcpWrap.Method = Request->Method;
  }

  Status = HttpInitSession (
             HttpInstance,
             Wrap,
             Configure || ReConfigure,
             TlsConfigure
             );
  HttpNotify (HttpEventInitSession, Status);
  if (EFI_ERROR (Status)) {
    goto Error2;
  }

  if (!Configure && !ReConfigure && !TlsConfigure) {
    //
    // For the new HTTP token, create TX TCP token events.
    //
    Status = HttpCreateTcpTxEvent (Wrap);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }
  }

  //
  // Create request message.
  //
  FileUrl = Url;
  if ((Url != NULL) && (*FileUrl != '/')) {
    //
    // Convert the absolute-URI to the absolute-path
    //
    while (*FileUrl != ':') {
      FileUrl++;
    }

    if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) {
      FileUrl += 3;
      while (*FileUrl != '/') {
        FileUrl++;
      }
    } else {
      Status = EFI_INVALID_PARAMETER;
      goto Error3;
    }
  }

  Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);

  if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
    goto Error3;
  }

  //
  // Every request we insert a TxToken and a response call would remove the TxToken.
  // In cases of PUT/POST/PATCH, after an initial request-response pair, we would do a
  // continuous request without a response call. So, in such cases, where Request
  // structure is NULL, we would not insert a TxToken.
  //
  if (Request != NULL) {
    Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
    if (EFI_ERROR (Status)) {
      goto Error4;
    }
  }

  HttpInstance->ConnectionClose = FALSE;

  //
  // Transmit the request message.
  //
  Status = HttpTransmitTcp (
             HttpInstance,
             Wrap,
             (UINT8 *)RequestMsg,
             RequestMsgSize
             );
  if (EFI_ERROR (Status)) {
    goto Error5;
  }

  DispatchDpc ();

  if (HostName != NULL) {
    FreePool (HostName);
  }

  if (UrlParser != NULL) {
    HttpUrlFreeParser (UrlParser);
  }

  return EFI_SUCCESS;

Error5:
  //
  // We would have inserted a TxToken only if Request structure is not NULL.
  // Hence check before we do a remove in this error case.
  //
  if (Request != NULL) {
    NetMapRemoveTail (&HttpInstance->TxTokens, NULL);
  }

Error4:
  if (RequestMsg != NULL) {
    FreePool (RequestMsg);
  }

Error3:
  if (HttpInstance->UseHttps) {
    TlsCloseSession (HttpInstance);
    TlsCloseTxRxEvent (HttpInstance);
  }

Error2:
  HttpCloseConnection (HttpInstance);

  HttpCloseTcpConnCloseEvent (HttpInstance);
  if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
    gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
    Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
  }

  if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) {
    gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
    Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL;
  }

Error1:
  if (HostName != NULL) {
    FreePool (HostName);
  }

  if (Wrap != NULL) {
    FreePool (Wrap);
  }

  if (UrlParser != NULL) {
    HttpUrlFreeParser (UrlParser);
  }

  return Status;
}

/**
  Cancel a user's Token.

  @param[in]  Map                The HTTP instance's token queue.
  @param[in]  Item               Object container for one HTTP token and token's wrap.
  @param[in]  Context            The user's token to cancel.

  @retval EFI_SUCCESS            Continue to check the next Item.
  @retval EFI_ABORTED            The user's Token (Token != NULL) is cancelled.

**/
EFI_STATUS
EFIAPI
HttpCancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  EFI_HTTP_TOKEN   *Token;
  HTTP_TOKEN_WRAP  *Wrap;
  HTTP_PROTOCOL    *HttpInstance;

  Token = (EFI_HTTP_TOKEN *)Context;

  //
  // Return EFI_SUCCESS to check the next item in the map if
  // this one doesn't match.
  //
  if ((Token != NULL) && (Token != Item->Key)) {
    return EFI_SUCCESS;
  }

  Wrap = (HTTP_TOKEN_WRAP *)Item->Value;
  ASSERT (Wrap != NULL);
  HttpInstance = Wrap->HttpInstance;

  if (!HttpInstance->LocalAddressIsIPv6) {
    if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
      //
      // Cancel the Token before close its Event.
      //
      HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &Wrap->TcpWrap.Rx4Token.CompletionToken);

      //
      // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
      //
      DispatchDpc ();
    }
  } else {
    if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
      //
      // Cancel the Token before close its Event.
      //
      HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &Wrap->TcpWrap.Rx6Token.CompletionToken);

      //
      // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
      //
      DispatchDpc ();
    }
  }

  //
  // If only one item is to be cancel, return EFI_ABORTED to stop
  // iterating the map any more.
  //
  if (Token != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Cancel the user's receive/transmit request. It is the worker function of
  EfiHttpCancel API. If a matching token is found, it will call HttpCancelTokens to cancel the
  token.

  @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
  @param[in]  Token              The token to cancel. If NULL, all token will be
                                 cancelled.

  @retval EFI_SUCCESS            The token is cancelled.
  @retval EFI_NOT_FOUND          The asynchronous request or response token is not found.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpCancel (
  IN  HTTP_PROTOCOL   *HttpInstance,
  IN  EFI_HTTP_TOKEN  *Token
  )
{
  EFI_STATUS  Status;

  //
  // First check the tokens queued by EfiHttpRequest().
  //
  Status = NetMapIterate (&HttpInstance->TxTokens, HttpCancelTokens, Token);
  if (EFI_ERROR (Status)) {
    if (Token != NULL) {
      if (Status == EFI_ABORTED) {
        return EFI_SUCCESS;
      }
    } else {
      return Status;
    }
  }

  if (!HttpInstance->UseHttps) {
    //
    // Then check the tokens queued by EfiHttpResponse(), except for Https.
    //
    Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
    if (EFI_ERROR (Status)) {
      if (Token != NULL) {
        if (Status == EFI_ABORTED) {
          return EFI_SUCCESS;
        } else {
          return EFI_NOT_FOUND;
        }
      } else {
        return Status;
      }
    }
  } else {
    if (!HttpInstance->LocalAddressIsIPv6) {
      HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
    } else {
      HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
    }
  }

  return EFI_SUCCESS;
}

/**
  Abort an asynchronous HTTP request or response token.

  The Cancel() function aborts a pending HTTP request or response transaction. If
  Token is not NULL and the token is in transmit or receive queues when it is being
  cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will
  be signaled. If the token is not in one of the queues, which usually means that the
  asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL,
  all asynchronous tokens issued by Request() or Response() will be aborted.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  Token               Point to storage containing HTTP request or response
                                  token.

  @retval EFI_SUCCESS             Request and Response queues are successfully flushed.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_NOT_STARTED         This instance hasn't been configured.
  @retval EFI_NOT_FOUND           The asynchronous request or response token is not
                                  found.
  @retval EFI_UNSUPPORTED         The implementation does not support this function.

**/
EFI_STATUS
EFIAPI
EfiHttpCancel (
  IN  EFI_HTTP_PROTOCOL  *This,
  IN  EFI_HTTP_TOKEN     *Token
  )
{
  HTTP_PROTOCOL  *HttpInstance;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

  if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {
    return EFI_NOT_STARTED;
  }

  return HttpCancel (HttpInstance, Token);
}

/**
  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.

**/
EFI_STATUS
EFIAPI
HttpBodyParserCallback (
  IN HTTP_BODY_PARSE_EVENT  EventType,
  IN CHAR8                  *Data,
  IN UINTN                  Length,
  IN VOID                   *Context
  )
{
  HTTP_CALLBACK_DATA  *CallbackData;
  HTTP_TOKEN_WRAP     *Wrap;
  UINTN               BodyLength;
  CHAR8               *Body;

  if (EventType != BodyParseEventOnComplete) {
    return EFI_SUCCESS;
  }

  if ((Data == NULL) || (Length != 0) || (Context == NULL)) {
    return EFI_SUCCESS;
  }

  CallbackData = (HTTP_CALLBACK_DATA *)Context;

  Wrap       = (HTTP_TOKEN_WRAP *)(CallbackData->Wrap);
  Body       = CallbackData->ParseData;
  BodyLength = CallbackData->ParseDataLength;

  if (Data < Body + BodyLength) {
    Wrap->HttpInstance->NextMsg = Data;
  } else {
    Wrap->HttpInstance->NextMsg = NULL;
  }

  return EFI_SUCCESS;
}

/**
  The work function of EfiHttpResponse().

  @param[in]  Wrap                Pointer to HTTP token's wrap data.

  @retval EFI_SUCCESS             Allocation succeeded.
  @retval EFI_OUT_OF_RESOURCES    Failed to complete the operation due to lack of resources.
  @retval EFI_NOT_READY           Can't find a corresponding Tx4Token/Tx6Token or
                                  the EFI_HTTP_UTILITIES_PROTOCOL is not available.

**/
EFI_STATUS
HttpResponseWorker (
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  EFI_STATUS        Status;
  EFI_HTTP_MESSAGE  *HttpMsg;
  CHAR8             *EndofHeader;
  CHAR8             *HttpHeaders;
  UINTN             SizeofHeaders;
  UINTN             BufferSize;
  UINTN             StatusCode;
  CHAR8             *Tmp;
  CHAR8             *HeaderTmp;
  CHAR8             *StatusCodeStr;
  UINTN             BodyLen;
  HTTP_PROTOCOL     *HttpInstance;
  EFI_HTTP_TOKEN    *Token;
  NET_MAP_ITEM      *Item;
  HTTP_TOKEN_WRAP   *ValueInItem;
  UINTN             HdrLen;
  NET_FRAGMENT      Fragment;
  UINT32            TimeoutValue;
  UINTN             Index;

  if ((Wrap == NULL) || (Wrap->HttpInstance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = Wrap->HttpInstance;
  Token        = Wrap->HttpToken;
  HttpMsg      = Token->Message;

  HttpInstance->EndofHeader = NULL;
  HttpInstance->HttpHeaders = NULL;
  HttpMsg->Headers          = NULL;
  HttpHeaders               = NULL;
  SizeofHeaders             = 0;
  BufferSize                = 0;
  EndofHeader               = NULL;
  ValueInItem               = NULL;
  Fragment.Len              = 0;
  Fragment.Bulk             = NULL;

  if (HttpMsg->Data.Response != NULL) {
    //
    // Check whether we have cached header from previous call.
    //
    if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) {
      //
      // The data is stored at [NextMsg, CacheBody + CacheLen].
      //
      HdrLen      = HttpInstance->CacheBody + HttpInstance->CacheLen - HttpInstance->NextMsg;
      HttpHeaders = AllocateZeroPool (HdrLen);
      if (HttpHeaders == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error;
      }

      CopyMem (HttpHeaders, HttpInstance->NextMsg, HdrLen);
      FreePool (HttpInstance->CacheBody);
      HttpInstance->CacheBody   = NULL;
      HttpInstance->NextMsg     = NULL;
      HttpInstance->CacheOffset = 0;
      SizeofHeaders             = HdrLen;
      BufferSize                = HttpInstance->CacheLen;

      //
      // Check whether we cached the whole HTTP headers.
      //
      EndofHeader = AsciiStrStr (HttpHeaders, HTTP_END_OF_HDR_STR);
    }

    HttpInstance->EndofHeader = &EndofHeader;
    HttpInstance->HttpHeaders = &HttpHeaders;

    if (HttpInstance->TimeoutEvent == NULL) {
      //
      // Create TimeoutEvent for response
      //
      Status = gBS->CreateEvent (
                      EVT_TIMER,
                      TPL_CALLBACK,
                      NULL,
                      NULL,
                      &HttpInstance->TimeoutEvent
                      );
      if (EFI_ERROR (Status)) {
        goto Error;
      }
    }

    //
    // Get HTTP timeout value
    //
    TimeoutValue = PcdGet32 (PcdHttpIoTimeout);

    //
    // Start the timer, and wait Timeout seconds to receive the header packet.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS);
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize, HttpInstance->TimeoutEvent);

    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);

    if (EFI_ERROR (Status)) {
      goto Error;
    }

    ASSERT (HttpHeaders != NULL);

    //
    // Cache the part of body.
    //
    BodyLen = BufferSize - (EndofHeader - HttpHeaders);
    if (BodyLen > 0) {
      if (HttpInstance->CacheBody != NULL) {
        FreePool (HttpInstance->CacheBody);
      }

      HttpInstance->CacheBody = AllocateZeroPool (BodyLen);
      if (HttpInstance->CacheBody == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error;
      }

      CopyMem (HttpInstance->CacheBody, EndofHeader, BodyLen);
      HttpInstance->CacheLen = BodyLen;
    }

    //
    // Check server's HTTP version.
    //
    if (AsciiStrnCmp (HttpHeaders, "HTTP/1.0", sizeof ("HTTP/1.0") - 1) == 0) {
      DEBUG ((DEBUG_VERBOSE, "HTTP: Server version is 1.0. Setting Connection close.\n"));
      HttpInstance->ConnectionClose = TRUE;
    }

    //
    // Search for Status Code.
    //
    StatusCodeStr = HttpHeaders + AsciiStrLen (HTTP_VERSION_STR) + 1;
    if (StatusCodeStr == NULL) {
      Status = EFI_NOT_READY;
      goto Error;
    }

    StatusCode = AsciiStrDecimalToUintn (StatusCodeStr);

    //
    // Remove the first line of HTTP message, e.g. "HTTP/1.1 200 OK\r\n".
    //
    Tmp = AsciiStrStr (HttpHeaders, HTTP_CRLF_STR);
    if (Tmp == NULL) {
      Status = EFI_NOT_READY;
      goto Error;
    }

    //
    // We could have response with just a HTTP message and no headers. For Example,
    // "100 Continue". In such cases, we would not want to unnecessarily call a Parse
    // method. A "\r\n" following Tmp string again would indicate an end. Compare and
    // set SizeofHeaders to 0.
    //
    Tmp = Tmp + AsciiStrLen (HTTP_CRLF_STR);
    if (CompareMem (Tmp, HTTP_CRLF_STR, AsciiStrLen (HTTP_CRLF_STR)) == 0) {
      SizeofHeaders = 0;
    } else {
      SizeofHeaders = SizeofHeaders - (Tmp - HttpHeaders);
    }

    HttpMsg->Data.Response->StatusCode = HttpMappingToStatusCode (StatusCode);
    HttpInstance->StatusCode           = StatusCode;

    Status      = EFI_NOT_READY;
    ValueInItem = NULL;

    //
    // In cases of PUT/POST/PATCH, after an initial request-response pair, we would do a
    // continuous request without a response call. So, we would not do an insert of
    // TxToken. After we have sent the complete file, we will call a response to get
    // a final response from server. In such a case, we would not have any TxTokens.
    // Hence, check that case before doing a NetMapRemoveHead.
    //
    if (!NetMapIsEmpty (&HttpInstance->TxTokens)) {
      NetMapRemoveHead (&HttpInstance->TxTokens, (VOID **)&ValueInItem);
      if (ValueInItem == NULL) {
        goto Error;
      }

      //
      // The first Tx Token not transmitted yet, insert back and return error.
      //
      if (!ValueInItem->TcpWrap.IsTxDone) {
        goto Error2;
      }
    }

    if (SizeofHeaders != 0) {
      HeaderTmp = AllocateZeroPool (SizeofHeaders);
      if (HeaderTmp == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error2;
      }

      CopyMem (HeaderTmp, Tmp, SizeofHeaders);
      FreePool (HttpHeaders);
      HttpHeaders = HeaderTmp;

      //
      // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available.
      //
      if (mHttpUtilities == NULL) {
        Status = EFI_NOT_READY;
        goto Error2;
      }

      //
      // Parse the HTTP header into array of key/value pairs.
      //
      Status = mHttpUtilities->Parse (
                                 mHttpUtilities,
                                 HttpHeaders,
                                 SizeofHeaders,
                                 &HttpMsg->Headers,
                                 &HttpMsg->HeaderCount
                                 );
      if (EFI_ERROR (Status)) {
        goto Error2;
      }

      FreePool (HttpHeaders);
      HttpHeaders = NULL;

      for (Index = 0; Index < HttpMsg->HeaderCount; ++Index) {
        if ((AsciiStriCmp ("Connection", HttpMsg->Headers[Index].FieldName) == 0) &&
            (AsciiStriCmp ("close", HttpMsg->Headers[Index].FieldValue) == 0))
        {
          DEBUG ((DEBUG_VERBOSE, "Http: 'Connection: close' header received.\n"));
          HttpInstance->ConnectionClose = TRUE;
          break;
        }
      }

      //
      // Init message-body parser by header information.
      //
      Status = HttpInitMsgParser (
                 HttpInstance->Method,
                 HttpMsg->Data.Response->StatusCode,
                 HttpMsg->HeaderCount,
                 HttpMsg->Headers,
                 HttpBodyParserCallback,
                 (VOID *)(&HttpInstance->CallbackData),
                 &HttpInstance->MsgParser
                 );
      if (EFI_ERROR (Status)) {
        goto Error2;
      }

      //
      // Check whether we received a complete HTTP message.
      //
      if (HttpInstance->CacheBody != NULL) {
        //
        // Record the CallbackData data.
        //
        HttpInstance->CallbackData.Wrap            = (VOID *)Wrap;
        HttpInstance->CallbackData.ParseData       = (VOID *)HttpInstance->CacheBody;
        HttpInstance->CallbackData.ParseDataLength = HttpInstance->CacheLen;

        //
        // Parse message with CallbackData data.
        //
        Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody);
        if (EFI_ERROR (Status)) {
          goto Error2;
        }
      }

      if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
        //
        // Free the MsgParse since we already have a full HTTP message.
        //
        HttpFreeMsgParser (HttpInstance->MsgParser);
        HttpInstance->MsgParser = NULL;
      }
    }

    if ((HttpMsg->Body == NULL) || (HttpMsg->BodyLength == 0)) {
      Status = EFI_SUCCESS;
      goto Exit;
    }
  }

  //
  // Receive the response body.
  //
  BodyLen = 0;

  //
  // First check whether we cached some data.
  //
  if (HttpInstance->CacheBody != NULL) {
    //
    // Calculate the length of the cached data.
    //
    if (HttpInstance->NextMsg != NULL) {
      //
      // We have a cached HTTP message which includes a part of HTTP header of next message.
      //
      BodyLen = HttpInstance->NextMsg - (HttpInstance->CacheBody + HttpInstance->CacheOffset);
    } else {
      BodyLen = HttpInstance->CacheLen - HttpInstance->CacheOffset;
    }

    if (BodyLen > 0) {
      //
      // We have some cached data. Just copy the data and return.
      //
      if (HttpMsg->BodyLength < BodyLen) {
        CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, HttpMsg->BodyLength);
        HttpInstance->CacheOffset = HttpInstance->CacheOffset + HttpMsg->BodyLength;
      } else {
        //
        // Copy all cached data out.
        //
        CopyMem (HttpMsg->Body, HttpInstance->CacheBody + HttpInstance->CacheOffset, BodyLen);
        HttpInstance->CacheOffset = BodyLen + HttpInstance->CacheOffset;
        HttpMsg->BodyLength       = BodyLen;

        if (HttpInstance->NextMsg == NULL) {
          //
          // There is no HTTP header of next message. Just free the cache buffer.
          //
          FreePool (HttpInstance->CacheBody);
          HttpInstance->CacheBody   = NULL;
          HttpInstance->NextMsg     = NULL;
          HttpInstance->CacheOffset = 0;
        }
      }

      //
      // Return since we already received required data.
      //
      Status = EFI_SUCCESS;
      goto Exit;
    }

    if ((BodyLen == 0) && (HttpInstance->MsgParser == NULL)) {
      //
      // We received a complete HTTP message, and we don't have more data to return to caller.
      //
      HttpMsg->BodyLength = 0;
      Status              = EFI_SUCCESS;
      goto Exit;
    }
  }

  ASSERT (HttpInstance->MsgParser != NULL);

  //
  // We still need receive more data when there is no cache data and MsgParser is not NULL;
  //
  if (!HttpInstance->UseHttps) {
    Status = HttpTcpReceiveBody (Wrap, HttpMsg);

    if (EFI_ERROR (Status)) {
      goto Error2;
    }
  } else {
    if (HttpInstance->TimeoutEvent == NULL) {
      //
      // Create TimeoutEvent for response
      //
      Status = gBS->CreateEvent (
                      EVT_TIMER,
                      TPL_CALLBACK,
                      NULL,
                      NULL,
                      &HttpInstance->TimeoutEvent
                      );
      if (EFI_ERROR (Status)) {
        goto Error2;
      }
    }

    //
    // Get HTTP timeout value
    //
    TimeoutValue = PcdGet32 (PcdHttpIoTimeout);

    //
    // Start the timer, and wait Timeout seconds to receive the body packet.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, TimeoutValue * TICKS_PER_MS);
    if (EFI_ERROR (Status)) {
      goto Error2;
    }

    Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);

    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);

    if (EFI_ERROR (Status)) {
      goto Error2;
    }

    //
    // Process the received the body packet.
    //
    HttpMsg->BodyLength = MIN ((UINTN)Fragment.Len, HttpMsg->BodyLength);

    CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);

    //
    // Record the CallbackData data.
    //
    HttpInstance->CallbackData.Wrap            = (VOID *)Wrap;
    HttpInstance->CallbackData.ParseData       = HttpMsg->Body;
    HttpInstance->CallbackData.ParseDataLength = HttpMsg->BodyLength;

    //
    // Parse Body with CallbackData data.
    //
    Status = HttpParseMessageBody (
               HttpInstance->MsgParser,
               HttpMsg->BodyLength,
               HttpMsg->Body
               );
    if (EFI_ERROR (Status)) {
      goto Error2;
    }

    if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
      //
      // Free the MsgParse since we already have a full HTTP message.
      //
      HttpFreeMsgParser (HttpInstance->MsgParser);
      HttpInstance->MsgParser = NULL;
    }

    //
    // Check whether there is the next message header in the HttpMsg->Body.
    //
    if (HttpInstance->NextMsg != NULL) {
      HttpMsg->BodyLength = HttpInstance->NextMsg - (CHAR8 *)HttpMsg->Body;
    }

    HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
    if (HttpInstance->CacheLen != 0) {
      if (HttpInstance->CacheBody != NULL) {
        FreePool (HttpInstance->CacheBody);
      }

      HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
      if (HttpInstance->CacheBody == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error2;
      }

      CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
      HttpInstance->CacheOffset = 0;
      if (HttpInstance->NextMsg != NULL) {
        HttpInstance->NextMsg = HttpInstance->CacheBody;
      }
    }

    if (Fragment.Bulk != NULL) {
      FreePool (Fragment.Bulk);
      Fragment.Bulk = NULL;
    }

    goto Exit;
  }

  return Status;

Exit:
  Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
  if (Item != NULL) {
    NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
  }

  if (HttpInstance->StatusCode >= HTTP_ERROR_OR_NOT_SUPPORT_STATUS_CODE) {
    Token->Status = EFI_HTTP_ERROR;
  } else {
    Token->Status = Status;
  }

  gBS->SignalEvent (Token->Event);
  HttpCloseTcpRxEvent (Wrap);
  FreePool (Wrap);
  return Status;

Error2:
  if (ValueInItem != NULL) {
    NetMapInsertHead (&HttpInstance->TxTokens, ValueInItem->HttpToken, ValueInItem);
  }

Error:
  Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
  if (Item != NULL) {
    NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
  }

  if (!HttpInstance->UseHttps) {
    HttpTcpTokenCleanup (Wrap);
  } else {
    FreePool (Wrap);
  }

  if (HttpHeaders != NULL) {
    FreePool (HttpHeaders);
    HttpHeaders = NULL;
  }

  if (Fragment.Bulk != NULL) {
    FreePool (Fragment.Bulk);
    Fragment.Bulk = NULL;
  }

  if (HttpMsg->Headers != NULL) {
    FreePool (HttpMsg->Headers);
    HttpMsg->Headers = NULL;
  }

  if (HttpInstance->CacheBody != NULL) {
    FreePool (HttpInstance->CacheBody);
    HttpInstance->CacheBody = NULL;
  }

  if (HttpInstance->StatusCode >= HTTP_ERROR_OR_NOT_SUPPORT_STATUS_CODE) {
    Token->Status = EFI_HTTP_ERROR;
  } else {
    Token->Status = Status;
  }

  gBS->SignalEvent (Token->Event);

  return Status;
}

/**
  The Response() function queues an HTTP response to this HTTP instance, similar to
  Receive() function in the EFI TCP driver. When the HTTP response is received successfully,
  or if there is an error, Status in token will be updated and Event will be signaled.

  The HTTP driver will queue a receive token to the underlying TCP instance. When data
  is received in the underlying TCP instance, the data will be parsed and Token will
  be populated with the response data. If the data received from the remote host
  contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting
  (asynchronously) for more data to be sent from the remote host before signaling
  Event in Token.

  It is the responsibility of the caller to allocate a buffer for Body and specify the
  size in BodyLength. If the remote host provides a response that contains a content
  body, up to BodyLength bytes will be copied from the receive buffer into Body and
  BodyLength will be updated with the amount of bytes received and copied to Body. This
  allows the client to download a large file in chunks instead of into one contiguous
  block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is
  non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive
  token to underlying TCP instance. If data arrives in the receive buffer, up to
  BodyLength bytes of data will be copied to Body. The HTTP driver will then update
  BodyLength with the amount of bytes received and copied to Body.

  If the HTTP driver does not have an open underlying TCP connection with the host
  specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is
  consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain
  an open TCP connection between client and host.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  Token               Pointer to storage containing HTTP response token.

  @retval EFI_SUCCESS             Allocation succeeded.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been
                                  initialized.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token->Message->Headers is NULL.
                                  Token->Message is NULL.
                                  Token->Message->Body is not NULL,
                                  Token->Message->BodyLength is non-zero, and
                                  Token->Message->Data is NULL, but a previous call to
                                  Response() has not been completed successfully.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
  @retval EFI_ACCESS_DENIED       An open TCP connection is not present with the host
                                  specified by response URL.
**/
EFI_STATUS
EFIAPI
EfiHttpResponse (
  IN  EFI_HTTP_PROTOCOL  *This,
  IN  EFI_HTTP_TOKEN     *Token
  )
{
  EFI_STATUS        Status;
  EFI_HTTP_MESSAGE  *HttpMsg;
  HTTP_PROTOCOL     *HttpInstance;
  HTTP_TOKEN_WRAP   *Wrap;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpMsg = Token->Message;
  if (HttpMsg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

  if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {
    return EFI_NOT_STARTED;
  }

  //
  // Check whether the token already existed.
  //
  if (EFI_ERROR (NetMapIterate (&HttpInstance->RxTokens, HttpTokenExist, Token))) {
    return EFI_ACCESS_DENIED;
  }

  Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
  if (Wrap == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Wrap->HttpInstance = HttpInstance;
  Wrap->HttpToken    = Token;

  //
  // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to
  // receive the https response. A special TlsRxToken is used for receiving TLS
  // related messages. It should be a blocking response.
  //
  if (!HttpInstance->UseHttps) {
    Status = HttpCreateTcpRxEvent (Wrap);
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }

  Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // If already have pending RxTokens, return directly.
  //
  if (NetMapGetCount (&HttpInstance->RxTokens) > 1) {
    return EFI_SUCCESS;
  }

  return HttpResponseWorker (Wrap);

Error:
  if (Wrap != NULL) {
    if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
    }

    if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
    }

    FreePool (Wrap);
  }

  return Status;
}

/**
  The Poll() function can be used by network drivers and applications to increase the
  rate that data packets are moved between the communication devices and the transmit
  and receive queues.

  In some systems, the periodic timer event in the managed network driver may not poll
  the underlying communications device fast enough to transmit and/or receive all data
  packets without missing incoming packets or dropping outgoing packets. Drivers and
  applications that are experiencing packet loss should try calling the Poll() function
  more often.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.

  @retval EFI_SUCCESS             Incoming or outgoing data was processed.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_NOT_READY           No incoming or outgoing data is processed.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.

**/
EFI_STATUS
EFIAPI
EfiHttpPoll (
  IN  EFI_HTTP_PROTOCOL  *This
  )
{
  EFI_STATUS     Status;
  HTTP_PROTOCOL  *HttpInstance;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

  if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {
    return EFI_NOT_STARTED;
  }

  if (HttpInstance->LocalAddressIsIPv6) {
    if (HttpInstance->Tcp6 == NULL) {
      return EFI_NOT_STARTED;
    }

    Status = HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
  } else {
    if (HttpInstance->Tcp4 == NULL) {
      return EFI_NOT_STARTED;
    }

    Status = HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
  }

  DispatchDpc ();

  return Status;
}
