/** @file
  Miscellaneous routines for HttpDxe driver.

Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HttpDriver.h"

/**
  The common notify function used in HTTP driver.

  @param[in]  Event   The event signaled.
  @param[in]  Context The context.

**/
VOID
EFIAPI
HttpCommonNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  if ((Event == NULL) || (Context == NULL)) {
    return;
  }

  *((BOOLEAN *)Context) = TRUE;
}

/**
  The notify function associated with Tx4Token for Tcp4->Transmit() or Tx6Token for Tcp6->Transmit().

  @param[in]  Context The context.

**/
VOID
EFIAPI
HttpTcpTransmitNotifyDpc (
  IN VOID  *Context
  )
{
  HTTP_TOKEN_WRAP  *Wrap;
  HTTP_PROTOCOL    *HttpInstance;

  if (Context == NULL) {
    return;
  }

  Wrap         = (HTTP_TOKEN_WRAP *)Context;
  HttpInstance = Wrap->HttpInstance;

  if (!HttpInstance->LocalAddressIsIPv6) {
    Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;
    gBS->SignalEvent (Wrap->HttpToken->Event);

    //
    // Free resources.
    //
    if (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {
      FreePool (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer);
    }

    if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
    }
  } else {
    Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;
    gBS->SignalEvent (Wrap->HttpToken->Event);

    //
    // Free resources.
    //
    if (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {
      FreePool (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer);
    }

    if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
    }
  }

  Wrap->TcpWrap.IsTxDone = TRUE;

  //
  // Check pending TxTokens and sent out.
  //
  NetMapIterate (&Wrap->HttpInstance->TxTokens, HttpTcpTransmit, NULL);
}

/**
  Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK.

  @param  Event                 The receive event delivered to TCP for transmit.
  @param  Context               Context for the callback.

**/
VOID
EFIAPI
HttpTcpTransmitNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, HttpTcpTransmitNotifyDpc, Context);
}

/**
  The notify function associated with Rx4Token for Tcp4->Receive () or Rx6Token for Tcp6->Receive().

  @param[in]  Context The context.

**/
VOID
EFIAPI
HttpTcpReceiveNotifyDpc (
  IN VOID  *Context
  )
{
  HTTP_TOKEN_WRAP  *Wrap;
  NET_MAP_ITEM     *Item;
  UINTN            Length;
  EFI_STATUS       Status;
  HTTP_PROTOCOL    *HttpInstance;
  BOOLEAN          UsingIpv6;

  if (Context == NULL) {
    return;
  }

  Wrap         = (HTTP_TOKEN_WRAP *)Context;
  HttpInstance = Wrap->HttpInstance;
  UsingIpv6    = HttpInstance->LocalAddressIsIPv6;

  if (UsingIpv6) {
    gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
    Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;

    if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {
      DEBUG ((DEBUG_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));
      Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;
      gBS->SignalEvent (Wrap->HttpToken->Event);

      Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);
      if (Item != NULL) {
        NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);
      }

      FreePool (Wrap);
      Wrap = NULL;

      return;
    }
  } else {
    gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
    Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;

    if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {
      DEBUG ((DEBUG_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));
      Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;
      gBS->SignalEvent (Wrap->HttpToken->Event);

      Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);
      if (Item != NULL) {
        NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);
      }

      FreePool (Wrap);
      Wrap = NULL;

      return;
    }
  }

  //
  // Check whether we receive a complete HTTP message.
  //
  ASSERT (HttpInstance->MsgParser != NULL);
  if (UsingIpv6) {
    Length = (UINTN)Wrap->TcpWrap.Rx6Data.FragmentTable[0].FragmentLength;
  } else {
    Length = (UINTN)Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;
  }

  //
  // Record the CallbackData data.
  //
  HttpInstance->CallbackData.Wrap            = (VOID *)Wrap;
  HttpInstance->CallbackData.ParseData       = Wrap->HttpToken->Message->Body;
  HttpInstance->CallbackData.ParseDataLength = Length;

  //
  // Parse Body with CallbackData data.
  //
  Status = HttpParseMessageBody (
             HttpInstance->MsgParser,
             Length,
             Wrap->HttpToken->Message->Body
             );
  if (EFI_ERROR (Status)) {
    return;
  }

  if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
    //
    // Free the MsgParse since we already have a full HTTP message.
    //
    HttpFreeMsgParser (HttpInstance->MsgParser);
    HttpInstance->MsgParser = NULL;
  }

  Wrap->HttpToken->Message->BodyLength = Length;
  ASSERT (HttpInstance->CacheBody == NULL);
  //
  // We receive part of header of next HTTP msg.
  //
  if (HttpInstance->NextMsg != NULL) {
    Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg -
                                           (CHAR8 *)Wrap->HttpToken->Message->Body;
    HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength;
    if (HttpInstance->CacheLen != 0) {
      HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
      if (HttpInstance->CacheBody == NULL) {
        return;
      }

      CopyMem (HttpInstance->CacheBody, HttpInstance->NextMsg, HttpInstance->CacheLen);
      HttpInstance->NextMsg     = HttpInstance->CacheBody;
      HttpInstance->CacheOffset = 0;
    }
  }

  Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
  if (Item != NULL) {
    NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
  }

  Wrap->TcpWrap.IsRxDone = TRUE;
  if (UsingIpv6) {
    Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;
  } else {
    Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;
  }

  gBS->SignalEvent (Wrap->HttpToken->Event);

  //
  // Check pending RxTokens and receive the HTTP message.
  //
  NetMapIterate (&Wrap->HttpInstance->RxTokens, HttpTcpReceive, NULL);

  FreePool (Wrap);
  Wrap = NULL;
}

/**
  Request HttpTcpReceiveNotifyDpc as a DPC at TPL_CALLBACK.

  @param  Event                 The receive event delivered to TCP for receive.
  @param  Context               Context for the callback.

**/
VOID
EFIAPI
HttpTcpReceiveNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, HttpTcpReceiveNotifyDpc, Context);
}

/**
  Create events for the TCP connection token and TCP close token.

  @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.

  @retval EFI_SUCCESS            The events are created successfully.
  @retval others                 Other error as indicated.

**/
EFI_STATUS
HttpCreateTcpConnCloseEvent (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  if (!HttpInstance->LocalAddressIsIPv6) {
    //
    // Create events for various asynchronous operations.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsTcp4ConnDone,
                    &HttpInstance->Tcp4ConnToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    //
    // Initialize Tcp4CloseToken
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsTcp4CloseDone,
                    &HttpInstance->Tcp4CloseToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }
  } else {
    //
    // Create events for various asynchronous operations.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsTcp6ConnDone,
                    &HttpInstance->Tcp6ConnToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    //
    // Initialize Tcp6CloseToken
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsTcp6CloseDone,
                    &HttpInstance->Tcp6CloseToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }
  }

  return EFI_SUCCESS;

ERROR:
  //
  // Error handling
  //
  HttpCloseTcpConnCloseEvent (HttpInstance);

  return Status;
}

/**
  Close events in the TCP connection token and TCP close token.

  @param[in]  HttpInstance   Pointer to HTTP_PROTOCOL structure.

**/
VOID
HttpCloseTcpConnCloseEvent (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  ASSERT (HttpInstance != NULL);

  if (HttpInstance->LocalAddressIsIPv6) {
    if (NULL != HttpInstance->Tcp6ConnToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp6ConnToken.CompletionToken.Event);
      HttpInstance->Tcp6ConnToken.CompletionToken.Event = NULL;
    }

    if (NULL != HttpInstance->Tcp6CloseToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp6CloseToken.CompletionToken.Event);
      HttpInstance->Tcp6CloseToken.CompletionToken.Event = NULL;
    }
  } else {
    if (NULL != HttpInstance->Tcp4ConnToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp4ConnToken.CompletionToken.Event);
      HttpInstance->Tcp4ConnToken.CompletionToken.Event = NULL;
    }

    if (NULL != HttpInstance->Tcp4CloseToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp4CloseToken.CompletionToken.Event);
      HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;
    }
  }
}

/**
  Create event for the TCP transmit token.

  @param[in]  Wrap               Point to HTTP token's wrap data.

  @retval EFI_SUCCESS            The events is created successfully.
  @retval others                 Other error as indicated.

**/
EFI_STATUS
HttpCreateTcpTxEvent (
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  EFI_STATUS           Status;
  HTTP_PROTOCOL        *HttpInstance;
  HTTP_TCP_TOKEN_WRAP  *TcpWrap;

  HttpInstance = Wrap->HttpInstance;
  TcpWrap      = &Wrap->TcpWrap;

  if (!HttpInstance->LocalAddressIsIPv6) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpTcpTransmitNotify,
                    Wrap,
                    &TcpWrap->Tx4Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    TcpWrap->Tx4Data.Push                    = TRUE;
    TcpWrap->Tx4Data.Urgent                  = FALSE;
    TcpWrap->Tx4Data.FragmentCount           = 1;
    TcpWrap->Tx4Token.Packet.TxData          = &Wrap->TcpWrap.Tx4Data;
    TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;
  } else {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpTcpTransmitNotify,
                    Wrap,
                    &TcpWrap->Tx6Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    TcpWrap->Tx6Data.Push                    = TRUE;
    TcpWrap->Tx6Data.Urgent                  = FALSE;
    TcpWrap->Tx6Data.FragmentCount           = 1;
    TcpWrap->Tx6Token.Packet.TxData          = &Wrap->TcpWrap.Tx6Data;
    TcpWrap->Tx6Token.CompletionToken.Status = EFI_NOT_READY;
  }

  return EFI_SUCCESS;
}

/**
  Create event for the TCP receive token which is used to receive HTTP header.

  @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.

  @retval EFI_SUCCESS            The events is created successfully.
  @retval others                 Other error as indicated.

**/
EFI_STATUS
HttpCreateTcpRxEventForHeader (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  if (!HttpInstance->LocalAddressIsIPv6) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsRxDone,
                    &HttpInstance->Rx4Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    HttpInstance->Rx4Data.FragmentCount           = 1;
    HttpInstance->Rx4Token.Packet.RxData          = &HttpInstance->Rx4Data;
    HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;
  } else {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->IsRxDone,
                    &HttpInstance->Rx6Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    HttpInstance->Rx6Data.FragmentCount           = 1;
    HttpInstance->Rx6Token.Packet.RxData          = &HttpInstance->Rx6Data;
    HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;
  }

  return EFI_SUCCESS;
}

/**
  Create event for the TCP receive token which is used to receive HTTP body.

  @param[in]  Wrap               Point to HTTP token's wrap data.

  @retval EFI_SUCCESS            The events is created successfully.
  @retval others                 Other error as indicated.

**/
EFI_STATUS
HttpCreateTcpRxEvent (
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  EFI_STATUS           Status;
  HTTP_PROTOCOL        *HttpInstance;
  HTTP_TCP_TOKEN_WRAP  *TcpWrap;

  HttpInstance = Wrap->HttpInstance;
  TcpWrap      = &Wrap->TcpWrap;
  if (!HttpInstance->LocalAddressIsIPv6) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpTcpReceiveNotify,
                    Wrap,
                    &TcpWrap->Rx4Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    TcpWrap->Rx4Data.FragmentCount           = 1;
    TcpWrap->Rx4Token.Packet.RxData          = &Wrap->TcpWrap.Rx4Data;
    TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;
  } else {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpTcpReceiveNotify,
                    Wrap,
                    &TcpWrap->Rx6Token.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    TcpWrap->Rx6Data.FragmentCount           = 1;
    TcpWrap->Rx6Token.Packet.RxData          = &Wrap->TcpWrap.Rx6Data;
    TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;
  }

  return EFI_SUCCESS;
}

/**
  Close Events for Tcp Receive Tokens for HTTP body and HTTP header.

  @param[in]  Wrap               Pointer to HTTP token's wrap data.

**/
VOID
HttpCloseTcpRxEvent (
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  HTTP_PROTOCOL  *HttpInstance;

  ASSERT (Wrap != NULL);
  HttpInstance = Wrap->HttpInstance;

  if (HttpInstance->LocalAddressIsIPv6) {
    if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
    }

    if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);
      HttpInstance->Rx6Token.CompletionToken.Event = NULL;
    }
  } else {
    if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
    }

    if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {
      gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);
      HttpInstance->Rx4Token.CompletionToken.Event = NULL;
    }
  }
}

/**
  Initialize the HTTP_PROTOCOL structure to the unconfigured state.

  @param[in, out]  HttpInstance         Pointer to HTTP_PROTOCOL structure.
  @param[in]       IpVersion            Indicate us TCP4 protocol or TCP6 protocol.

  @retval EFI_SUCCESS       HTTP_PROTOCOL structure is initialized successfully.
  @retval Others            Other error as indicated.

**/
EFI_STATUS
HttpInitProtocol (
  IN OUT HTTP_PROTOCOL  *HttpInstance,
  IN     BOOLEAN        IpVersion
  )
{
  EFI_STATUS  Status;
  VOID        *Interface;
  BOOLEAN     UsingIpv6;

  ASSERT (HttpInstance != NULL);
  UsingIpv6 = IpVersion;

  if (!UsingIpv6) {
    //
    // Create TCP4 child.
    //
    Status = NetLibCreateServiceChild (
               HttpInstance->Service->ControllerHandle,
               HttpInstance->Service->Ip4DriverBindingHandle,
               &gEfiTcp4ServiceBindingProtocolGuid,
               &HttpInstance->Tcp4ChildHandle
               );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Tcp4ChildHandle,
                    &gEfiTcp4ProtocolGuid,
                    (VOID **)&Interface,
                    HttpInstance->Service->Ip4DriverBindingHandle,
                    HttpInstance->Service->ControllerHandle,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Tcp4ChildHandle,
                    &gEfiTcp4ProtocolGuid,
                    (VOID **)&HttpInstance->Tcp4,
                    HttpInstance->Service->Ip4DriverBindingHandle,
                    HttpInstance->Handle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Service->Tcp4ChildHandle,
                    &gEfiTcp4ProtocolGuid,
                    (VOID **)&Interface,
                    HttpInstance->Service->Ip4DriverBindingHandle,
                    HttpInstance->Handle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  } else {
    //
    // Create TCP6 Child.
    //
    Status = NetLibCreateServiceChild (
               HttpInstance->Service->ControllerHandle,
               HttpInstance->Service->Ip6DriverBindingHandle,
               &gEfiTcp6ServiceBindingProtocolGuid,
               &HttpInstance->Tcp6ChildHandle
               );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Tcp6ChildHandle,
                    &gEfiTcp6ProtocolGuid,
                    (VOID **)&Interface,
                    HttpInstance->Service->Ip6DriverBindingHandle,
                    HttpInstance->Service->ControllerHandle,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Tcp6ChildHandle,
                    &gEfiTcp6ProtocolGuid,
                    (VOID **)&HttpInstance->Tcp6,
                    HttpInstance->Service->Ip6DriverBindingHandle,
                    HttpInstance->Handle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    Status = gBS->OpenProtocol (
                    HttpInstance->Service->Tcp6ChildHandle,
                    &gEfiTcp6ProtocolGuid,
                    (VOID **)&Interface,
                    HttpInstance->Service->Ip6DriverBindingHandle,
                    HttpInstance->Handle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);
  if (HttpInstance->Url == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (HttpInstance->Tcp4ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Service->ControllerHandle
           );

    gBS->CloseProtocol (
           HttpInstance->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Handle
           );

    NetLibDestroyServiceChild (
      HttpInstance->Service->ControllerHandle,
      HttpInstance->Service->Ip4DriverBindingHandle,
      &gEfiTcp4ServiceBindingProtocolGuid,
      HttpInstance->Tcp4ChildHandle
      );
  }

  if (HttpInstance->Service->Tcp4ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Service->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Handle
           );
  }

  if (HttpInstance->Tcp6ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Service->ControllerHandle
           );

    gBS->CloseProtocol (
           HttpInstance->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Handle
           );

    NetLibDestroyServiceChild (
      HttpInstance->Service->ControllerHandle,
      HttpInstance->Service->Ip6DriverBindingHandle,
      &gEfiTcp6ServiceBindingProtocolGuid,
      HttpInstance->Tcp6ChildHandle
      );
  }

  if (HttpInstance->Service->Tcp6ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Service->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Handle
           );
  }

  return EFI_UNSUPPORTED;
}

/**
  Clean up the HTTP child, release all the resources used by it.

  @param[in]  HttpInstance       The HTTP child to clean up.

**/
VOID
HttpCleanProtocol (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  HttpCloseConnection (HttpInstance);

  HttpCloseTcpConnCloseEvent (HttpInstance);

  if (HttpInstance->TimeoutEvent != NULL) {
    gBS->CloseEvent (HttpInstance->TimeoutEvent);
    HttpInstance->TimeoutEvent = NULL;
  }

  if (HttpInstance->CacheBody != NULL) {
    FreePool (HttpInstance->CacheBody);
    HttpInstance->CacheBody = NULL;
    HttpInstance->NextMsg   = NULL;
  }

  if (HttpInstance->RemoteHost != NULL) {
    FreePool (HttpInstance->RemoteHost);
    HttpInstance->RemoteHost = NULL;
  }

  if (HttpInstance->MsgParser != NULL) {
    HttpFreeMsgParser (HttpInstance->MsgParser);
    HttpInstance->MsgParser = NULL;
  }

  if (HttpInstance->Url != NULL) {
    FreePool (HttpInstance->Url);
    HttpInstance->Url = NULL;
  }

  NetMapClean (&HttpInstance->TxTokens);
  NetMapClean (&HttpInstance->RxTokens);

  if ((HttpInstance->TlsSb != NULL) && (HttpInstance->TlsChildHandle != NULL)) {
    //
    // Destroy the TLS instance.
    //
    HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);
    HttpInstance->TlsChildHandle = NULL;
  }

  if (HttpInstance->Tcp4ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Service->ControllerHandle
           );

    gBS->CloseProtocol (
           HttpInstance->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Handle
           );

    NetLibDestroyServiceChild (
      HttpInstance->Service->ControllerHandle,
      HttpInstance->Service->Ip4DriverBindingHandle,
      &gEfiTcp4ServiceBindingProtocolGuid,
      HttpInstance->Tcp4ChildHandle
      );
  }

  if (HttpInstance->Service->Tcp4ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Service->Tcp4ChildHandle,
           &gEfiTcp4ProtocolGuid,
           HttpInstance->Service->Ip4DriverBindingHandle,
           HttpInstance->Handle
           );
  }

  if (HttpInstance->Tcp6ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Service->ControllerHandle
           );

    gBS->CloseProtocol (
           HttpInstance->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Handle
           );

    NetLibDestroyServiceChild (
      HttpInstance->Service->ControllerHandle,
      HttpInstance->Service->Ip6DriverBindingHandle,
      &gEfiTcp6ServiceBindingProtocolGuid,
      HttpInstance->Tcp6ChildHandle
      );
  }

  if (HttpInstance->Service->Tcp6ChildHandle != NULL) {
    gBS->CloseProtocol (
           HttpInstance->Service->Tcp6ChildHandle,
           &gEfiTcp6ProtocolGuid,
           HttpInstance->Service->Ip6DriverBindingHandle,
           HttpInstance->Handle
           );
  }

  TlsCloseTxRxEvent (HttpInstance);
}

/**
  Establish TCP connection with HTTP server.

  @param[in]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            The TCP connection is established.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpCreateConnection (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  //
  // Connect to Http server
  //
  if (!HttpInstance->LocalAddressIsIPv6) {
    HttpInstance->IsTcp4ConnDone                       = FALSE;
    HttpInstance->Tcp4ConnToken.CompletionToken.Status = EFI_NOT_READY;
    Status                                             = HttpInstance->Tcp4->Connect (HttpInstance->Tcp4, &HttpInstance->Tcp4ConnToken);
    HttpNotify (HttpEventConnectTcp, Status);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));
      return Status;
    }

    while (!HttpInstance->IsTcp4ConnDone) {
      HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
    }

    Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;
  } else {
    HttpInstance->IsTcp6ConnDone                       = FALSE;
    HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;
    Status                                             = HttpInstance->Tcp6->Connect (HttpInstance->Tcp6, &HttpInstance->Tcp6ConnToken);
    HttpNotify (HttpEventConnectTcp, Status);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "HttpCreateConnection: Tcp6->Connect() = %r\n", Status));
      return Status;
    }

    while (!HttpInstance->IsTcp6ConnDone) {
      HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
    }

    Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;
  }

  if (!EFI_ERROR (Status)) {
    HttpInstance->State = HTTP_STATE_TCP_CONNECTED;
  }

  return Status;
}

/**
  Close existing TCP connection.

  @param[in]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            The TCP connection is closed.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpCloseConnection (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  if (HttpInstance->State == HTTP_STATE_TCP_CONNECTED) {
    if (HttpInstance->LocalAddressIsIPv6) {
      HttpInstance->Tcp6CloseToken.AbortOnClose = TRUE;
      HttpInstance->IsTcp6CloseDone             = FALSE;
      Status                                    = HttpInstance->Tcp6->Close (HttpInstance->Tcp6, &HttpInstance->Tcp6CloseToken);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      while (!HttpInstance->IsTcp6CloseDone) {
        HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
      }
    } else {
      HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;
      HttpInstance->IsTcp4CloseDone             = FALSE;
      Status                                    = HttpInstance->Tcp4->Close (HttpInstance->Tcp4, &HttpInstance->Tcp4CloseToken);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      while (!HttpInstance->IsTcp4CloseDone) {
        HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
      }
    }
  }

  HttpInstance->State = HTTP_STATE_TCP_CLOSED;
  return EFI_SUCCESS;
}

/**
  Configure TCP4 protocol child.

  @param[in]  HttpInstance       The HTTP instance private data.
  @param[in]  Wrap               The HTTP token's wrap data.

  @retval EFI_SUCCESS            The TCP4 protocol child is configured.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpConfigureTcp4 (
  IN  HTTP_PROTOCOL    *HttpInstance,
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  EFI_STATUS             Status;
  EFI_TCP4_CONFIG_DATA   *Tcp4CfgData;
  EFI_TCP4_ACCESS_POINT  *Tcp4AP;
  EFI_TCP4_OPTION        *Tcp4Option;

  ASSERT (HttpInstance != NULL);

  Tcp4CfgData = &HttpInstance->Tcp4CfgData;
  ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));

  Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT;
  Tcp4CfgData->TimeToLive    = HTTP_TTL_DEAULT;
  Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option;

  Tcp4AP                    = &Tcp4CfgData->AccessPoint;
  Tcp4AP->UseDefaultAddress = HttpInstance->IPv4Node.UseDefaultAddress;
  if (!Tcp4AP->UseDefaultAddress) {
    IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress);
    IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);
  }

  Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort;
  Tcp4AP->RemotePort  = HttpInstance->RemotePort;
  Tcp4AP->ActiveFlag  = TRUE;
  IP4_COPY_ADDRESS (&Tcp4AP->RemoteAddress, &HttpInstance->RemoteAddr);

  Tcp4Option                    = Tcp4CfgData->ControlOption;
  Tcp4Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;
  Tcp4Option->SendBufferSize    = HTTP_BUFFER_SIZE_DEAULT;
  Tcp4Option->MaxSynBackLog     = HTTP_MAX_SYN_BACK_LOG;
  Tcp4Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;
  Tcp4Option->DataRetries       = HTTP_DATA_RETRIES;
  Tcp4Option->FinTimeout        = HTTP_FIN_TIMEOUT;
  Tcp4Option->KeepAliveProbes   = HTTP_KEEP_ALIVE_PROBES;
  Tcp4Option->KeepAliveTime     = HTTP_KEEP_ALIVE_TIME;
  Tcp4Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;
  Tcp4Option->EnableNagle       = TRUE;
  Tcp4CfgData->ControlOption    = Tcp4Option;

  if ((HttpInstance->State == HTTP_STATE_TCP_CONNECTED) ||
      (HttpInstance->State == HTTP_STATE_TCP_CLOSED))
  {
    Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, NULL);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "HttpConfigureTcp4(NULL) - %r\n", Status));
      return Status;
    }

    HttpInstance->State = HTTP_STATE_TCP_UNCONFIGED;
  }

  Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, Tcp4CfgData);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "HttpConfigureTcp4 - %r\n", Status));
    return Status;
  }

  Status = HttpCreateTcpConnCloseEvent (HttpInstance);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = HttpCreateTcpTxEvent (Wrap);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  HttpInstance->State = HTTP_STATE_TCP_CONFIGED;

  return EFI_SUCCESS;
}

/**
  Configure TCP6 protocol child.

  @param[in]  HttpInstance       The HTTP instance private data.
  @param[in]  Wrap               The HTTP token's wrap data.

  @retval EFI_SUCCESS            The TCP6 protocol child is configured.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpConfigureTcp6 (
  IN  HTTP_PROTOCOL    *HttpInstance,
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  EFI_STATUS             Status;
  EFI_TCP6_CONFIG_DATA   *Tcp6CfgData;
  EFI_TCP6_ACCESS_POINT  *Tcp6Ap;
  EFI_TCP6_OPTION        *Tcp6Option;

  ASSERT (HttpInstance != NULL);

  Tcp6CfgData = &HttpInstance->Tcp6CfgData;
  ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA));

  Tcp6CfgData->TrafficClass  = 0;
  Tcp6CfgData->HopLimit      = 255;
  Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option;

  Tcp6Ap              = &Tcp6CfgData->AccessPoint;
  Tcp6Ap->ActiveFlag  = TRUE;
  Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;
  Tcp6Ap->RemotePort  = HttpInstance->RemotePort;
  IP6_COPY_ADDRESS (&Tcp6Ap->StationAddress, &HttpInstance->Ipv6Node.LocalAddress);
  IP6_COPY_ADDRESS (&Tcp6Ap->RemoteAddress, &HttpInstance->RemoteIpv6Addr);

  Tcp6Option                    = Tcp6CfgData->ControlOption;
  Tcp6Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;
  Tcp6Option->SendBufferSize    = HTTP_BUFFER_SIZE_DEAULT;
  Tcp6Option->MaxSynBackLog     = HTTP_MAX_SYN_BACK_LOG;
  Tcp6Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;
  Tcp6Option->DataRetries       = HTTP_DATA_RETRIES;
  Tcp6Option->FinTimeout        = HTTP_FIN_TIMEOUT;
  Tcp6Option->KeepAliveProbes   = HTTP_KEEP_ALIVE_PROBES;
  Tcp6Option->KeepAliveTime     = HTTP_KEEP_ALIVE_TIME;
  Tcp6Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;
  Tcp6Option->EnableNagle       = TRUE;

  if ((HttpInstance->State == HTTP_STATE_TCP_CONNECTED) ||
      (HttpInstance->State == HTTP_STATE_TCP_CLOSED))
  {
    Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, NULL);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "HttpConfigureTcp6(NULL) - %r\n", Status));
      return Status;
    }

    HttpInstance->State = HTTP_STATE_TCP_UNCONFIGED;
  }

  Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, Tcp6CfgData);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "HttpConfigureTcp6 - %r\n", Status));
    return Status;
  }

  Status = HttpCreateTcpConnCloseEvent (HttpInstance);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = HttpCreateTcpTxEvent (Wrap);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  HttpInstance->State = HTTP_STATE_TCP_CONFIGED;

  return EFI_SUCCESS;
}

/**
  Check existing TCP connection, if in error state, recover TCP4 connection. Then,
  connect one TLS session if required.

  @param[in]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            The TCP connection is established.
  @retval EFI_NOT_READY          TCP4 protocol child is not created or configured.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpConnectTcp4 (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS                 Status;
  EFI_TCP4_CONNECTION_STATE  Tcp4State;

  if ((HttpInstance->State < HTTP_STATE_TCP_CONFIGED) || (HttpInstance->Tcp4 == NULL)) {
    return EFI_NOT_READY;
  }

  Status = HttpInstance->Tcp4->GetModeData (
                                 HttpInstance->Tcp4,
                                 &Tcp4State,
                                 NULL,
                                 NULL,
                                 NULL,
                                 NULL
                                 );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Tcp4 GetModeData fail - %x\n", Status));
    return Status;
  }

  if (Tcp4State == Tcp4StateEstablished) {
    return EFI_SUCCESS;
  } else if (Tcp4State > Tcp4StateEstablished ) {
    HttpCloseConnection (HttpInstance);
  }

  Status = HttpCreateConnection (HttpInstance);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status));
    return Status;
  }

  //
  // Tls session connection.
  //
  if (HttpInstance->UseHttps) {
    if (HttpInstance->TimeoutEvent == NULL) {
      //
      // Create TimeoutEvent for TLS connection.
      //
      Status = gBS->CreateEvent (
                      EVT_TIMER,
                      TPL_CALLBACK,
                      NULL,
                      NULL,
                      &HttpInstance->TimeoutEvent
                      );
      if (EFI_ERROR (Status)) {
        TlsCloseTxRxEvent (HttpInstance);
        return Status;
      }
    }

    //
    // Start the timer, and wait Timeout seconds for connection.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
    if (EFI_ERROR (Status)) {
      TlsCloseTxRxEvent (HttpInstance);
      return Status;
    }

    Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
    HttpNotify (HttpEventTlsConnectSession, Status);

    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);

    if (EFI_ERROR (Status)) {
      TlsCloseTxRxEvent (HttpInstance);
      return Status;
    }
  }

  return Status;
}

/**
  Check existing TCP connection, if in error state, recover TCP6 connection. Then,
  connect one TLS session if required.

  @param[in]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            The TCP connection is established.
  @retval EFI_NOT_READY          TCP6 protocol child is not created or configured.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpConnectTcp6 (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS                 Status;
  EFI_TCP6_CONNECTION_STATE  Tcp6State;

  if ((HttpInstance->State < HTTP_STATE_TCP_CONFIGED) || (HttpInstance->Tcp6 == NULL)) {
    return EFI_NOT_READY;
  }

  Status = HttpInstance->Tcp6->GetModeData (
                                 HttpInstance->Tcp6,
                                 &Tcp6State,
                                 NULL,
                                 NULL,
                                 NULL,
                                 NULL
                                 );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Tcp6 GetModeData fail - %x\n", Status));
    return Status;
  }

  if (Tcp6State == Tcp6StateEstablished) {
    return EFI_SUCCESS;
  } else if (Tcp6State > Tcp6StateEstablished ) {
    HttpCloseConnection (HttpInstance);
  }

  Status = HttpCreateConnection (HttpInstance);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status));
    return Status;
  }

  //
  // Tls session connection.
  //
  if (HttpInstance->UseHttps) {
    if (HttpInstance->TimeoutEvent == NULL) {
      //
      // Create TimeoutEvent for TLS connection.
      //
      Status = gBS->CreateEvent (
                      EVT_TIMER,
                      TPL_CALLBACK,
                      NULL,
                      NULL,
                      &HttpInstance->TimeoutEvent
                      );
      if (EFI_ERROR (Status)) {
        TlsCloseTxRxEvent (HttpInstance);
        return Status;
      }
    }

    //
    // Start the timer, and wait Timeout seconds for connection.
    //
    Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
    if (EFI_ERROR (Status)) {
      TlsCloseTxRxEvent (HttpInstance);
      return Status;
    }

    Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
    HttpNotify (HttpEventTlsConnectSession, Status);

    gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);

    if (EFI_ERROR (Status)) {
      TlsCloseTxRxEvent (HttpInstance);
      return Status;
    }
  }

  return Status;
}

/**
  Initialize Http session.

  @param[in]  HttpInstance       The HTTP instance private data.
  @param[in]  Wrap               The HTTP token's wrap data.
  @param[in]  Configure          The Flag indicates whether need to initialize session.
  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls session.

  @retval EFI_SUCCESS            The initialization of session is done.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpInitSession (
  IN  HTTP_PROTOCOL    *HttpInstance,
  IN  HTTP_TOKEN_WRAP  *Wrap,
  IN  BOOLEAN          Configure,
  IN  BOOLEAN          TlsConfigure
  )
{
  EFI_STATUS  Status;

  ASSERT (HttpInstance != NULL);

  //
  // Configure Tls session.
  //
  if (TlsConfigure) {
    Status = TlsConfigureSession (HttpInstance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (!HttpInstance->LocalAddressIsIPv6) {
    //
    // Configure TCP instance.
    //
    if (Configure) {
      Status = HttpConfigureTcp4 (HttpInstance, Wrap);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    //
    // Connect TCP.
    //
    Status = HttpConnectTcp4 (HttpInstance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    //
    // Configure TCP instance.
    //
    if (Configure) {
      Status = HttpConfigureTcp6 (HttpInstance, Wrap);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    //
    // Connect TCP.
    //
    Status = HttpConnectTcp6 (HttpInstance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Send the HTTP or HTTPS message through TCP4 or TCP6.

  @param[in]  HttpInstance       The HTTP instance private data.
  @param[in]  Wrap               The HTTP token's wrap data.
  @param[in]  TxString           Buffer containing the HTTP message string.
  @param[in]  TxStringLen        Length of the HTTP message string in bytes.

  @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit queue.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpTransmitTcp (
  IN  HTTP_PROTOCOL    *HttpInstance,
  IN  HTTP_TOKEN_WRAP  *Wrap,
  IN  UINT8            *TxString,
  IN  UINTN            TxStringLen
  )
{
  EFI_STATUS         Status;
  EFI_TCP4_IO_TOKEN  *Tx4Token;
  EFI_TCP4_PROTOCOL  *Tcp4;
  EFI_TCP6_IO_TOKEN  *Tx6Token;
  EFI_TCP6_PROTOCOL  *Tcp6;
  UINT8              *TlsRecord;
  UINT16             PayloadSize;
  NET_FRAGMENT       TempFragment;
  NET_FRAGMENT       Fragment;
  UINTN              RecordCount;
  UINTN              RemainingLen;

  Status            = EFI_SUCCESS;
  TlsRecord         = NULL;
  PayloadSize       = 0;
  TempFragment.Len  = 0;
  TempFragment.Bulk = NULL;
  Fragment.Len      = 0;
  Fragment.Bulk     = NULL;
  RecordCount       = 0;
  RemainingLen      = 0;

  //
  // Need to encrypt data.
  //
  if (HttpInstance->UseHttps) {
    //
    // Allocate enough buffer for each TLS plaintext records.
    //
    TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);
    if (TlsRecord == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    //
    // Allocate enough buffer for all TLS ciphertext records.
    //
    RecordCount   = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1;
    Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));
    if (Fragment.Bulk == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }

    //
    // Encrypt each TLS plaintext records.
    //
    RemainingLen = TxStringLen;
    while (RemainingLen != 0) {
      PayloadSize = (UINT16)MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen);

      ((TLS_RECORD_HEADER *)TlsRecord)->ContentType   = TlsContentTypeApplicationData;
      ((TLS_RECORD_HEADER *)TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
      ((TLS_RECORD_HEADER *)TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
      ((TLS_RECORD_HEADER *)TlsRecord)->Length        = PayloadSize;

      CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize);

      Status = TlsProcessMessage (
                 HttpInstance,
                 TlsRecord,
                 TLS_RECORD_HEADER_LENGTH + PayloadSize,
                 EfiTlsEncrypt,
                 &TempFragment
                 );
      if (EFI_ERROR (Status)) {
        goto ON_ERROR;
      }

      //
      // Record the processed/encrypted Packet.
      //
      CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len);
      Fragment.Len += TempFragment.Len;

      FreePool (TempFragment.Bulk);
      TempFragment.Len  = 0;
      TempFragment.Bulk = NULL;

      RemainingLen -= (UINTN)PayloadSize;
      ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);
    }

    FreePool (TlsRecord);
    TlsRecord = NULL;
  }

  if (!HttpInstance->LocalAddressIsIPv6) {
    Tcp4     = HttpInstance->Tcp4;
    Tx4Token = &Wrap->TcpWrap.Tx4Token;

    if (HttpInstance->UseHttps) {
      Tx4Token->Packet.TxData->DataLength                      = Fragment.Len;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)Fragment.Bulk;
    } else {
      Tx4Token->Packet.TxData->DataLength                      = (UINT32)TxStringLen;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)TxStringLen;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)TxString;
    }

    Tx4Token->CompletionToken.Status = EFI_NOT_READY;

    Wrap->TcpWrap.IsTxDone = FALSE;
    Status                 = Tcp4->Transmit (Tcp4, Tx4Token);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Transmit failed: %r\n", Status));
      goto ON_ERROR;
    }
  } else {
    Tcp6     = HttpInstance->Tcp6;
    Tx6Token = &Wrap->TcpWrap.Tx6Token;

    if (HttpInstance->UseHttps) {
      Tx6Token->Packet.TxData->DataLength                      = Fragment.Len;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)Fragment.Bulk;
    } else {
      Tx6Token->Packet.TxData->DataLength                      = (UINT32)TxStringLen;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)TxStringLen;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)TxString;
    }

    Tx6Token->CompletionToken.Status = EFI_NOT_READY;

    Wrap->TcpWrap.IsTxDone = FALSE;
    Status                 = Tcp6->Transmit (Tcp6, Tx6Token);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Transmit failed: %r\n", Status));
      goto ON_ERROR;
    }
  }

  return Status;

ON_ERROR:

  if (HttpInstance->UseHttps) {
    if (TlsRecord != NULL) {
      FreePool (TlsRecord);
      TlsRecord = NULL;
    }

    if (Fragment.Bulk != NULL) {
      FreePool (Fragment.Bulk);
      Fragment.Bulk = NULL;
    }
  }

  return Status;
}

/**
  Check whether the user's token or event has already
  been enqueue on HTTP Tx or Rx Token list.

  @param[in]  Map                The container of either user's transmit or receive
                                 token.
  @param[in]  Item               Current item to check against.
  @param[in]  Context            The Token to check against.

  @retval EFI_ACCESS_DENIED      The token or event has already been enqueued in IP
  @retval EFI_SUCCESS            The current item isn't the same token/event as the
                                 context.

**/
EFI_STATUS
EFIAPI
HttpTokenExist (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  EFI_HTTP_TOKEN  *Token;
  EFI_HTTP_TOKEN  *TokenInItem;

  Token       = (EFI_HTTP_TOKEN *)Context;
  TokenInItem = (EFI_HTTP_TOKEN *)Item->Key;

  if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  Check whether the HTTP message associated with Tx4Token or Tx6Token is already sent out.

  @param[in]  Map                The container of Tx4Token or Tx6Token.
  @param[in]  Item               Current item to check against.
  @param[in]  Context            The Token to check against.

  @retval EFI_NOT_READY          The HTTP message is still queued in the list.
  @retval EFI_SUCCESS            The HTTP message has been sent out.

**/
EFI_STATUS
EFIAPI
HttpTcpNotReady (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  HTTP_TOKEN_WRAP  *ValueInItem;

  ValueInItem = (HTTP_TOKEN_WRAP *)Item->Value;

  if (!ValueInItem->TcpWrap.IsTxDone) {
    return EFI_NOT_READY;
  }

  return EFI_SUCCESS;
}

/**
  Transmit the HTTP or HTTPS message by processing the associated HTTP token.

  @param[in]  Map                The container of Tx4Token or Tx6Token.
  @param[in]  Item               Current item to check against.
  @param[in]  Context            The Token to check against.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
  @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit
                                 queue.

**/
EFI_STATUS
EFIAPI
HttpTcpTransmit (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  HTTP_TOKEN_WRAP  *ValueInItem;
  EFI_STATUS       Status;
  CHAR8            *RequestMsg;
  CHAR8            *Url;
  UINTN            UrlSize;
  UINTN            RequestMsgSize;

  RequestMsg = NULL;

  ValueInItem = (HTTP_TOKEN_WRAP *)Item->Value;
  if (ValueInItem->TcpWrap.IsTxDone) {
    return EFI_SUCCESS;
  }

  //
  // Parse the URI of the remote host.
  //
  UrlSize = StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1;
  Url     = AllocatePool (UrlSize);
  if (Url == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStrS (ValueInItem->HttpToken->Message->Data.Request->Url, Url, UrlSize);

  //
  // Create request message.
  //
  Status = HttpGenRequestMessage (
             ValueInItem->HttpToken->Message,
             Url,
             &RequestMsg,
             &RequestMsgSize
             );
  FreePool (Url);

  if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
    return Status;
  }

  ASSERT (RequestMsg != NULL);

  //
  // Transmit the request message.
  //
  Status = HttpTransmitTcp (
             ValueInItem->HttpInstance,
             ValueInItem,
             (UINT8 *)RequestMsg,
             RequestMsgSize
             );
  FreePool (RequestMsg);
  return Status;
}

/**
  Receive the HTTP response by processing the associated HTTP token.

  @param[in]  Map                The container of Rx4Token or Rx6Token.
  @param[in]  Item               Current item to check against.
  @param[in]  Context            The Token to check against.

  @retval EFI_SUCCESS            The HTTP response is queued into TCP receive
                                 queue.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
HttpTcpReceive (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  //
  // Process the queued HTTP response.
  //
  return HttpResponseWorker ((HTTP_TOKEN_WRAP *)Item->Value);
}

/**
  Receive the HTTP header by processing the associated HTTP token.

  @param[in]       HttpInstance     The HTTP instance private data.
  @param[in, out]  SizeofHeaders    The HTTP header length.
  @param[in, out]  BufferSize       The size of buffer to cache the header message.
  @param[in]       Timeout          The time to wait for receiving the header packet.

  @retval EFI_SUCCESS               The HTTP header is received.
  @retval Others                    Other errors as indicated.

**/
EFI_STATUS
HttpTcpReceiveHeader (
  IN  HTTP_PROTOCOL  *HttpInstance,
  IN  OUT UINTN      *SizeofHeaders,
  IN  OUT UINTN      *BufferSize,
  IN  EFI_EVENT      Timeout
  )
{
  EFI_STATUS         Status;
  EFI_TCP4_IO_TOKEN  *Rx4Token;
  EFI_TCP4_PROTOCOL  *Tcp4;
  EFI_TCP6_IO_TOKEN  *Rx6Token;
  EFI_TCP6_PROTOCOL  *Tcp6;
  CHAR8              **EndofHeader;
  CHAR8              **HttpHeaders;
  CHAR8              *Buffer;
  NET_FRAGMENT       Fragment;

  ASSERT (HttpInstance != NULL);

  EndofHeader   = HttpInstance->EndofHeader;
  HttpHeaders   = HttpInstance->HttpHeaders;
  Tcp4          = HttpInstance->Tcp4;
  Tcp6          = HttpInstance->Tcp6;
  Buffer        = NULL;
  Rx4Token      = NULL;
  Rx6Token      = NULL;
  Fragment.Len  = 0;
  Fragment.Bulk = NULL;

  if (HttpInstance->LocalAddressIsIPv6) {
    ASSERT (Tcp6 != NULL);
  } else {
    ASSERT (Tcp4 != NULL);
  }

  if (!HttpInstance->UseHttps) {
    Status = HttpCreateTcpRxEventForHeader (HttpInstance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (!HttpInstance->LocalAddressIsIPv6) {
    if (!HttpInstance->UseHttps) {
      Rx4Token                                                 = &HttpInstance->Rx4Token;
      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
      if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }
    }

    //
    // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
    //
    while (*EndofHeader == NULL) {
      if (!HttpInstance->UseHttps) {
        HttpInstance->IsRxDone                                   = FALSE;
        Rx4Token->Packet.RxData->DataLength                      = DEF_BUF_LEN;
        Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
        Status                                                   = Tcp4->Receive (Tcp4, Rx4Token);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
          return Status;
        }

        while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
          Tcp4->Poll (Tcp4);
        }

        if (!HttpInstance->IsRxDone) {
          //
          // Cancel the Token before close its Event.
          //
          Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
          gBS->CloseEvent (Rx4Token->CompletionToken.Event);
          Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
        }

        Status = Rx4Token->CompletionToken.Status;
        if (EFI_ERROR (Status)) {
          return Status;
        }

        Fragment.Len  = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
        Fragment.Bulk = (UINT8 *)Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
      } else {
        if (Fragment.Bulk != NULL) {
          FreePool (Fragment.Bulk);
          Fragment.Bulk = NULL;
        }

        Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
          return Status;
        }
      }

      //
      // Append the response string along with a Null-terminator.
      //
      *BufferSize = *SizeofHeaders + Fragment.Len;
      Buffer      = AllocatePool (*BufferSize + 1);
      if (Buffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      if (*HttpHeaders != NULL) {
        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
        FreePool (*HttpHeaders);
      }

      CopyMem (
        Buffer + *SizeofHeaders,
        Fragment.Bulk,
        Fragment.Len
        );
      *(Buffer + *BufferSize) = '\0';
      *HttpHeaders            = Buffer;
      *SizeofHeaders          = *BufferSize;

      //
      // Check whether we received end of HTTP headers.
      //
      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
    }

    //
    // Free the buffer.
    //
    if ((Rx4Token != NULL) && (Rx4Token->Packet.RxData != NULL) && (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL)) {
      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
      Fragment.Bulk                                            = NULL;
    }

    if (Fragment.Bulk != NULL) {
      FreePool (Fragment.Bulk);
      Fragment.Bulk = NULL;
    }
  } else {
    if (!HttpInstance->UseHttps) {
      Rx6Token                                                 = &HttpInstance->Rx6Token;
      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
      if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }
    }

    //
    // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
    //
    while (*EndofHeader == NULL) {
      if (!HttpInstance->UseHttps) {
        HttpInstance->IsRxDone                                   = FALSE;
        Rx6Token->Packet.RxData->DataLength                      = DEF_BUF_LEN;
        Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
        Status                                                   = Tcp6->Receive (Tcp6, Rx6Token);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
          return Status;
        }

        while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
          Tcp6->Poll (Tcp6);
        }

        if (!HttpInstance->IsRxDone) {
          //
          // Cancel the Token before close its Event.
          //
          Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
          gBS->CloseEvent (Rx6Token->CompletionToken.Event);
          Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
        }

        Status = Rx6Token->CompletionToken.Status;
        if (EFI_ERROR (Status)) {
          return Status;
        }

        Fragment.Len  = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
        Fragment.Bulk = (UINT8 *)Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
      } else {
        if (Fragment.Bulk != NULL) {
          FreePool (Fragment.Bulk);
          Fragment.Bulk = NULL;
        }

        Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
          return Status;
        }
      }

      //
      // Append the response string along with a Null-terminator.
      //
      *BufferSize = *SizeofHeaders + Fragment.Len;
      Buffer      = AllocatePool (*BufferSize + 1);
      if (Buffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      if (*HttpHeaders != NULL) {
        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
        FreePool (*HttpHeaders);
      }

      CopyMem (
        Buffer + *SizeofHeaders,
        Fragment.Bulk,
        Fragment.Len
        );
      *(Buffer + *BufferSize) = '\0';
      *HttpHeaders            = Buffer;
      *SizeofHeaders          = *BufferSize;

      //
      // Check whether we received end of HTTP headers.
      //
      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
    }

    //
    // Free the buffer.
    //
    if ((Rx6Token != NULL) && (Rx6Token->Packet.RxData != NULL) && (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL)) {
      FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
      Fragment.Bulk                                            = NULL;
    }

    if (Fragment.Bulk != NULL) {
      FreePool (Fragment.Bulk);
      Fragment.Bulk = NULL;
    }
  }

  //
  // Skip the CRLF after the HTTP headers.
  //
  *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);

  *SizeofHeaders = *EndofHeader - *HttpHeaders;

  return EFI_SUCCESS;
}

/**
  Receive the HTTP body by processing the associated HTTP token.

  @param[in]  Wrap               The HTTP token's wrap data.
  @param[in]  HttpMsg            The HTTP message data.

  @retval EFI_SUCCESS            The HTTP body is received.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
HttpTcpReceiveBody (
  IN  HTTP_TOKEN_WRAP   *Wrap,
  IN  EFI_HTTP_MESSAGE  *HttpMsg
  )
{
  EFI_STATUS         Status;
  HTTP_PROTOCOL      *HttpInstance;
  EFI_TCP6_PROTOCOL  *Tcp6;
  EFI_TCP6_IO_TOKEN  *Rx6Token;
  EFI_TCP4_PROTOCOL  *Tcp4;
  EFI_TCP4_IO_TOKEN  *Rx4Token;

  HttpInstance = Wrap->HttpInstance;
  Tcp4         = HttpInstance->Tcp4;
  Tcp6         = HttpInstance->Tcp6;
  Rx4Token     = NULL;
  Rx6Token     = NULL;

  if (HttpInstance->LocalAddressIsIPv6) {
    ASSERT (Tcp6 != NULL);
  } else {
    ASSERT (Tcp4 != NULL);
  }

  if (HttpInstance->LocalAddressIsIPv6) {
    Rx6Token                                                 = &Wrap->TcpWrap.Rx6Token;
    Rx6Token->Packet.RxData->DataLength                      = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
    Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *)HttpMsg->Body;
    Rx6Token->CompletionToken.Status                         = EFI_NOT_READY;

    Status = Tcp6->Receive (Tcp6, Rx6Token);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
      return Status;
    }
  } else {
    Rx4Token                                                 = &Wrap->TcpWrap.Rx4Token;
    Rx4Token->Packet.RxData->DataLength                      = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
    Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *)HttpMsg->Body;

    Rx4Token->CompletionToken.Status = EFI_NOT_READY;
    Status                           = Tcp4->Receive (Tcp4, Rx4Token);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Clean up Tcp Tokens while the Tcp transmission error occurs.

  @param[in]  Wrap               Pointer to HTTP token's wrap data.

**/
VOID
HttpTcpTokenCleanup (
  IN  HTTP_TOKEN_WRAP  *Wrap
  )
{
  HTTP_PROTOCOL      *HttpInstance;
  EFI_TCP4_IO_TOKEN  *Rx4Token;
  EFI_TCP6_IO_TOKEN  *Rx6Token;

  ASSERT (Wrap != NULL);
  HttpInstance = Wrap->HttpInstance;
  Rx4Token     = NULL;
  Rx6Token     = NULL;

  if (HttpInstance->LocalAddressIsIPv6) {
    Rx6Token = &Wrap->TcpWrap.Rx6Token;

    if (Rx6Token->CompletionToken.Event != NULL) {
      gBS->CloseEvent (Rx6Token->CompletionToken.Event);
      Rx6Token->CompletionToken.Event = NULL;
    }

    FreePool (Wrap);

    Rx6Token = &HttpInstance->Rx6Token;

    if (Rx6Token->CompletionToken.Event != NULL) {
      gBS->CloseEvent (Rx6Token->CompletionToken.Event);
      Rx6Token->CompletionToken.Event = NULL;
    }

    if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
      FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
    }
  } else {
    Rx4Token = &Wrap->TcpWrap.Rx4Token;

    if (Rx4Token->CompletionToken.Event != NULL) {
      gBS->CloseEvent (Rx4Token->CompletionToken.Event);
      Rx4Token->CompletionToken.Event = NULL;
    }

    FreePool (Wrap);

    Rx4Token = &HttpInstance->Rx4Token;

    if (Rx4Token->CompletionToken.Event != NULL) {
      gBS->CloseEvent (Rx4Token->CompletionToken.Event);
      Rx4Token->CompletionToken.Event = NULL;
    }

    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
    }
  }
}

/**
  Send Events via EDKII_HTTP_CALLBACK_PROTOCOL.

  @param[in]  Event               The event that occurs in the current state.
  @param[in]  EventStatus         The Status of Event, EFI_SUCCESS or other errors.

**/
VOID
HttpNotify (
  IN  EDKII_HTTP_CALLBACK_EVENT  Event,
  IN  EFI_STATUS                 EventStatus
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    *Handles;
  UINTN                         Index;
  UINTN                         HandleCount;
  EFI_HANDLE                    Handle;
  EDKII_HTTP_CALLBACK_PROTOCOL  *HttpCallback;

  DEBUG ((DEBUG_INFO, "HttpNotify: Event - %d, EventStatus - %r\n", Event, EventStatus));

  Handles     = NULL;
  HandleCount = 0;
  Status      = gBS->LocateHandleBuffer (
                       ByProtocol,
                       &gEdkiiHttpCallbackProtocolGuid,
                       NULL,
                       &HandleCount,
                       &Handles
                       );
  if (Status == EFI_SUCCESS) {
    for (Index = 0; Index < HandleCount; Index++) {
      Handle = Handles[Index];
      Status = gBS->HandleProtocol (
                      Handle,
                      &gEdkiiHttpCallbackProtocolGuid,
                      (VOID **)&HttpCallback
                      );
      if (Status == EFI_SUCCESS) {
        DEBUG ((DEBUG_INFO, "HttpNotify: Notifying %p\n", HttpCallback));
        HttpCallback->Callback (
                        HttpCallback,
                        Event,
                        EventStatus
                        );
      }
    }

    FreePool (Handles);
  }
}
