/** @file
  Miscellaneous routines for HttpDxe driver.

Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
(c) Copyright 2025 HP Development Company, L.P.
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;
  }

  HttpInstance->UrlLen = HTTP_URL_BUFFER_LEN;
  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;
    HttpInstance->UrlLen = 0;
  }

  if (HttpInstance->ProxyUrl != NULL) {
    FreePool (HttpInstance->ProxyUrl);
    HttpInstance->ProxyUrl    = NULL;
    HttpInstance->ProxyUrlLen = 0;
  }

  if (HttpInstance->EndPointHostName != NULL) {
    FreePool (HttpInstance->EndPointHostName);
    HttpInstance->EndPointHostName = NULL;
  }

  HttpInstance->ProxyConnected = FALSE;

  NetMapClean (&HttpInstance->TxTokens);
  NetMapClean (&HttpInstance->RxTokens);

  if ((HttpInstance->TlsSb != NULL) && HttpInstance->TlsAlreadyCreated) {
    //
    // Destroy the TLS instance.
    //
    HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->Handle);
    HttpInstance->TlsAlreadyCreated = FALSE;
  }

  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   = PcdGet32 (PcdHttpTransferBufferSize);
  Tcp4Option->SendBufferSize      = PcdGet32 (PcdHttpTransferBufferSize);
  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;
  Tcp4Option->EnableWindowScaling = 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   = PcdGet32 (PcdHttpTransferBufferSize);
  Tcp6Option->SendBufferSize      = PcdGet32 (PcdHttpTransferBufferSize);
  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;
  Tcp6Option->EnableWindowScaling = 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.
  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls session.

  @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,
  IN  BOOLEAN        TlsConfigure
  )
{
  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) && (!HttpInstance->ProxyConnected || !TlsConfigure)) {
    return EFI_SUCCESS;
  } else if (Tcp4State > Tcp4StateEstablished) {
    HttpCloseConnection (HttpInstance);
  }

  if (!HttpInstance->ProxyConnected) {
    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.
  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls session.

  @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,
  IN  BOOLEAN        TlsConfigure
  )
{
  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) && (!HttpInstance->ProxyConnected || !TlsConfigure)) {
    return EFI_SUCCESS;
  } else if (Tcp6State > Tcp6StateEstablished) {
    HttpCloseConnection (HttpInstance);
  }

  if (!HttpInstance->ProxyConnected) {
    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);
    HttpNotify (HttpEventTlsConfigured, Status);
    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, TlsConfigure);
    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, TlsConfigure);
    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);
  }
}
