/** @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->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);  

  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;
    }
  }

}
