/** @file
  Miscellaneous routines for HttpDxe driver.

Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "HttpDriver.h"

/**
  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 ((EFI_D_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 ((EFI_D_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;
  }

  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 variuos 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 variuos 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;
    }
  }
}

/**
  Intiialize 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);
  }

  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);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_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);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_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;

  Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, Tcp4CfgData);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_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;

  Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, Tcp6CfgData);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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);

    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 ((EFI_D_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 ((EFI_D_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);

    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                         *Buffer;  
  UINTN                         BufferSize;
  NET_FRAGMENT                  TempFragment;

  Status                = EFI_SUCCESS;
  Buffer                = NULL;
  TempFragment.Len      = 0;
  TempFragment.Bulk     = NULL;

  //
  // Need to encrypt data.
  //
  if (HttpInstance->UseHttps) {
    //
    // Build BufferOut data
    //
    BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
    Buffer     = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }
    ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData;
    ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
    ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
    ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
    CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
    
    //
    // Encrypt Packet.
    //
    Status = TlsProcessMessage (
               HttpInstance, 
               Buffer, 
               BufferSize, 
               EfiTlsEncrypt, 
               &TempFragment
               );
    
    FreePool (Buffer);

    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  
  if (!HttpInstance->LocalAddressIsIPv6) {
    Tcp4 = HttpInstance->Tcp4;
    Tx4Token = &Wrap->TcpWrap.Tx4Token;

    if (HttpInstance->UseHttps) {
      Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.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 ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
      return Status;
    }

  } else {
    Tcp6 = HttpInstance->Tcp6;
    Tx6Token = &Wrap->TcpWrap.Tx6Token;
    
    if (HttpInstance->UseHttps) {
      Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.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 ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
      return Status;
    }
  }
  
  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 againist.

  @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 againist.

  @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 mssage 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 againist.

  @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 againist.

  @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 cacahe 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 ((EFI_D_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) {
          //
          // Cancle 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 ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
          return Status;
        }
      }

      //
      // Append the response string.
      //
      *BufferSize = *SizeofHeaders + Fragment.Len;
      Buffer      = AllocateZeroPool (*BufferSize);
      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
        );
      *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 ((EFI_D_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) {
          //
          // Cancle 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 ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
          return Status;
        }
      }

      //
      // Append the response string.
      //
      *BufferSize = *SizeofHeaders + Fragment.Len;
      Buffer      = AllocateZeroPool (*BufferSize);
      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
        );
      *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 ((EFI_D_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 ((EFI_D_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;
    }
  }

}
