/** @file
  Implementation of EFI_HTTP_PROTOCOL protocol interfaces.

  Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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.

  @retval EFI_SUCCESS             Operation succeeded.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  HttpConfigData is NULL.
                                  HttpInstance->LocalAddressIsIPv6 is FALSE and
                                  HttpConfigData->IPv4Node is NULL.
                                  HttpInstance->LocalAddressIsIPv6 is TRUE and
                                  HttpConfigData->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);
  ASSERT (HttpInstance != NULL);

  if ((HttpInstance->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||
      (!HttpInstance->LocalAddressIsIPv6 && 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->IPv4Node is NULL.
                                  HttpConfigData->LocalAddressIsIPv6 is TRUE and
                                  HttpConfigData->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
  ) 
{
  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 != NULL && HttpInstance->Service != NULL);

  if (HttpConfigData != NULL) {

    //
    // 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;
    
    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 HttpInsance.
    //
    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, PUT and POST method in current implementation.
  //
  if ((Request != NULL) && (Request->Method != HttpMethodGet) &&
      (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost)) {
    return EFI_UNSUPPORTED;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
  ASSERT (HttpInstance != NULL);

  //
  // 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 operation (in the current implementation)
    //
    if ((HttpInstance->Method != HttpMethodPut) && (HttpInstance->Method != HttpMethodPost)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // For PUT/POST, 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 ((EFI_D_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->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;
    }

    HostName   = NULL;
    Status     = HttpUrlGetHostName (Url, UrlParser, &HostName);
    if (EFI_ERROR (Status)) {
     goto Error1;
    }

    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->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);

          //
          // 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);
      }
      
      FreePool (HostNameStr);
      if (EFI_ERROR (Status)) {
        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
             );
  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;
  }

  ASSERT (RequestMsg != NULL);

  //
  // Every request we insert a TxToken and a response call would remove the TxToken.
  // In cases of PUT/POST, 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;
    }
  }

  //
  // Transmit the request message.
  //
  Status = HttpTransmitTcp (
             HttpInstance,
             Wrap,
             (UINT8*) RequestMsg,
             RequestMsgSize
             );
  if (EFI_ERROR (Status)) {
    goto Error5;    
  }

  DispatchDpc ();
  
  if (HostName != NULL) {
    FreePool (HostName);
  }
  
  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) {
      //
      // Cancle 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) {
      //
      // Cancle 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);
  ASSERT (HttpInstance != NULL);

  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_TOKEN_WRAP               *Wrap;
  UINTN                         BodyLength;
  CHAR8                         *Body;

  if (EventType != BodyParseEventOnComplete) {
    return EFI_SUCCESS;
  }

  if (Data == NULL || Length != 0 || Context == NULL) {
    return EFI_SUCCESS;
  }

  Wrap = (HTTP_TOKEN_WRAP *) Context;
  Body = Wrap->HttpToken->Message->Body;
  BodyLength = Wrap->HttpToken->Message->BodyLength;
  if (Data < Body + BodyLength) {
    Wrap->HttpInstance->NextMsg = Data;
  } else {
    Wrap->HttpInstance->NextMsg = NULL;
  }
  

  //
  // Free Tx4Token or Tx6Token since already received corrsponding HTTP response.
  //
  FreePool (Wrap);

  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 opration 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;

  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;
      }
    }

    //
    // Start the timer, and wait Timeout seconds to receive the header packet.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
    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;
    }

    //
    // 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, 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;


      //
      // Init message-body parser by header information.
      //
      Status = HttpInitMsgParser (
                 HttpInstance->Method,
                 HttpMsg->Data.Response->StatusCode,
                 HttpMsg->HeaderCount,
                 HttpMsg->Headers,
                 HttpBodyParserCallback,
                 (VOID *) ValueInItem,
                 &HttpInstance->MsgParser
                 );
      if (EFI_ERROR (Status)) {
        goto Error2;
      }

      //
      // Check whether we received a complete HTTP message.
      //
      if (HttpInstance->CacheBody != NULL) {
        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 aready 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;
      }
    }

    //
    // Start the timer, and wait Timeout seconds to receive the body packet.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
    if (EFI_ERROR (Status)) {
      goto Error2;
    }
  
    Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);

    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
    
    if (EFI_ERROR (Status)) {
      goto Error2;
    }

    //
    // Check whether we receive a complete HTTP message.
    //
    Status = HttpParseMessageBody (
               HttpInstance->MsgParser,
               (UINTN) Fragment.Len,
               (CHAR8 *) Fragment.Bulk
               );
    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;
    }

    //
    // We receive part of header of next HTTP msg.
    //
    if (HttpInstance->NextMsg != NULL) {
      HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength);
      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
      
      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;

        HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength));
      }
    } else {
      HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
      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 (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);
  ASSERT (HttpInstance != NULL);

  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);
  ASSERT (HttpInstance != NULL);

  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;
}
