/** @file
  This library is used to share code between UEFI network stack modules.
  It provides the helper routines to parse the HTTP message byte stream.

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<BR>
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 "DxeHttpLib.h"



/**
  Decode a percent-encoded URI component to the ASCII character.
  
  Decode the input component in Buffer according to RFC 3986. The caller is responsible to make 
  sure ResultBuffer points to a buffer with size equal or greater than ((AsciiStrSize (Buffer))
  in bytes. 

  @param[in]    Buffer           The pointer to a percent-encoded URI component.
  @param[in]    BufferLength     Length of Buffer in bytes.
  @param[out]   ResultBuffer     Point to the buffer to store the decode result.
  @param[out]   ResultLength     Length of decoded string in ResultBuffer in bytes.

  @retval EFI_SUCCESS            Successfully decoded the URI.
  @retval EFI_INVALID_PARAMETER  Buffer is not a valid percent-encoded string.
  
**/
EFI_STATUS
EFIAPI
UriPercentDecode (
  IN      CHAR8            *Buffer,
  IN      UINT32            BufferLength,
     OUT  CHAR8            *ResultBuffer,
     OUT  UINT32           *ResultLength
  )
{
  UINTN           Index;
  UINTN           Offset;
  CHAR8           HexStr[3];

  if (Buffer == NULL || BufferLength == 0 || ResultBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  Index = 0;
  Offset = 0;
  HexStr[2] = '\0';
  while (Index < BufferLength) {
    if (Buffer[Index] == '%') {
      if (!NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) {
        return EFI_INVALID_PARAMETER;
      }
      HexStr[0] = Buffer[Index+1];
      HexStr[1] = Buffer[Index+2];
      ResultBuffer[Offset] = (CHAR8) AsciiStrHexToUintn (HexStr);
      Index += 3;
    } else {
      ResultBuffer[Offset] = Buffer[Index];
      Index++;
    }
    Offset++;
  }

  *ResultLength = (UINT32) Offset;
    
  return EFI_SUCCESS;
}

/**
  This function return the updated state according to the input state and next character of
  the authority.

  @param[in]       Char           Next character.
  @param[in]       State          Current value of the parser state machine.
  @param[in]       IsRightBracket TRUE if there is an sign ']' in the authority component and 
                                  indicates the next part is ':' before Port.                                

  @return          Updated state value.
**/
HTTP_URL_PARSE_STATE
NetHttpParseAuthorityChar (
  IN  CHAR8                  Char,
  IN  HTTP_URL_PARSE_STATE   State,
  IN  BOOLEAN                *IsRightBracket
  )
{

  //
  // RFC 3986:
  // The authority component is preceded by a double slash ("//") and is
  // terminated by the next slash ("/"), question mark ("?"), or number
  // sign ("#") character, or by the end of the URI.
  //
  if (Char == ' ' || Char == '\r' || Char == '\n') {
    return UrlParserStateMax;
  }

  //
  // authority   = [ userinfo "@" ] host [ ":" port ]
  //
  switch (State) {
  case UrlParserUserInfo:
    if (Char == '@') {
      return UrlParserHostStart;
    }
    break;

  case UrlParserHost:
  case UrlParserHostStart:  
    if (Char == '[') {
      return UrlParserHostIpv6;
    }
    
    if (Char == ':') {
      return UrlParserPortStart;
    }
    
    return UrlParserHost;
    
  case UrlParserHostIpv6:  
    if (Char == ']') {
      *IsRightBracket = TRUE;
    }
    
    if (Char == ':' && *IsRightBracket) {
      return UrlParserPortStart;
    }
    return UrlParserHostIpv6;
    
  case UrlParserPort:
  case UrlParserPortStart:
    return UrlParserPort;

  default:
    break;
  }

  return State;
}

/**
  This function parse the authority component of the input URL and update the parser.

  @param[in]       Url            The pointer to a HTTP URL string.
  @param[in]       FoundAt        TRUE if there is an at sign ('@') in the authority component.
  @param[in, out]  UrlParser      Pointer to the buffer of the parse result.

  @retval EFI_SUCCESS             Successfully parse the authority.
  @retval Other                   Error happened.

**/
EFI_STATUS
NetHttpParseAuthority (
  IN      CHAR8              *Url,
  IN      BOOLEAN            FoundAt,
  IN OUT  HTTP_URL_PARSER    *UrlParser
  )
{
  CHAR8                 *Char;
  CHAR8                 *Authority;
  UINT32                Length;
  HTTP_URL_PARSE_STATE  State;
  UINT32                Field;
  UINT32                OldField;
  BOOLEAN               IsrightBracket;
  
  ASSERT ((UrlParser->FieldBitMap & BIT (HTTP_URI_FIELD_AUTHORITY)) != 0);

  //
  // authority   = [ userinfo "@" ] host [ ":" port ]
  //
  if (FoundAt) {
    State = UrlParserUserInfo;
  } else {
    State = UrlParserHost;
  }

  IsrightBracket = FALSE;
  Field = HTTP_URI_FIELD_MAX;
  OldField = Field;
  Authority = Url + UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Offset;
  Length = UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Length;
  for (Char = Authority; Char < Authority + Length; Char++) {
    State = NetHttpParseAuthorityChar (*Char, State, &IsrightBracket);
    switch (State) {
    case UrlParserStateMax:
      return EFI_INVALID_PARAMETER;

    case UrlParserHostStart:
    case UrlParserPortStart:
      continue;

    case UrlParserUserInfo:
      Field = HTTP_URI_FIELD_USERINFO;
      break;
      
    case UrlParserHost:
      Field = HTTP_URI_FIELD_HOST;
      break;

    case UrlParserHostIpv6:
      Field = HTTP_URI_FIELD_HOST;
      break;
      
    case UrlParserPort:
      Field = HTTP_URI_FIELD_PORT;
      break;

    default:
      ASSERT (FALSE);
    }

    //
    // Field not changed, count the length.
    //
    ASSERT (Field < HTTP_URI_FIELD_MAX);
    if (Field == OldField) {
      UrlParser->FieldData[Field].Length++;
      continue;
    }

    //
    // New field start
    //
    UrlParser->FieldBitMap |= BIT (Field);
    UrlParser->FieldData[Field].Offset = (UINT32) (Char - Url);
    UrlParser->FieldData[Field].Length = 1;
    OldField = Field;
  }

  return EFI_SUCCESS;
}

/**
  This function return the updated state according to the input state and next character of a URL.

  @param[in]       Char           Next character.
  @param[in]       State          Current value of the parser state machine.

  @return          Updated state value.

**/
HTTP_URL_PARSE_STATE
NetHttpParseUrlChar (
  IN  CHAR8                  Char,
  IN  HTTP_URL_PARSE_STATE   State
  )
{
  if (Char == ' ' || Char == '\r' || Char == '\n') {
    return UrlParserStateMax;
  }
  
  //
  // http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
  // 
  // Request-URI    = "*" | absolute-URI | path-absolute | authority
  // 
  // absolute-URI  = scheme ":" hier-part [ "?" query ]
  // path-absolute = "/" [ segment-nz *( "/" segment ) ]
  // authority   = [ userinfo "@" ] host [ ":" port ]
  //
  switch (State) {
  case UrlParserUrlStart:
    if (Char == '*' || Char == '/') {
      return UrlParserPath;
    }
    return UrlParserScheme;

  case UrlParserScheme:
    if (Char == ':') {
      return UrlParserSchemeColon;
    }
    break;

  case UrlParserSchemeColon:
    if (Char == '/') {
      return UrlParserSchemeColonSlash;
    }
    break;

  case UrlParserSchemeColonSlash:
    if (Char == '/') {
      return UrlParserSchemeColonSlashSlash;
    }
    break;

  case UrlParserAtInAuthority:
    if (Char == '@') {
      return UrlParserStateMax;
    }

  case UrlParserAuthority:
  case UrlParserSchemeColonSlashSlash:
    if (Char == '@') {
      return UrlParserAtInAuthority;
    }
    if (Char == '/') {
      return UrlParserPath;
    }
    if (Char == '?') {
      return UrlParserQueryStart;
    }
    if (Char == '#') {
      return UrlParserFragmentStart;
    }
    return UrlParserAuthority;

  case UrlParserPath:
    if (Char == '?') {
      return UrlParserQueryStart;
    }
    if (Char == '#') {
      return UrlParserFragmentStart;
    }
    break;

  case UrlParserQuery:
  case UrlParserQueryStart:
    if (Char == '#') {
      return UrlParserFragmentStart;
    }
    return UrlParserQuery;

  case UrlParserFragmentStart:
    return UrlParserFragment;
    
  default:
    break;
  }

  return State;
}
/**
  Create a URL parser for the input URL string.

  This function will parse and dereference the input HTTP URL into it components. The original
  content of the URL won't be modified and the result will be returned in UrlParser, which can
  be used in other functions like NetHttpUrlGetHostName().

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    Length             Length of Url in bytes.
  @param[in]    IsConnectMethod    Whether the Url is used in HTTP CONNECT method or not.
  @param[out]   UrlParser          Pointer to the returned buffer to store the parse result.

  @retval EFI_SUCCESS              Successfully dereferenced the HTTP URL.
  @retval EFI_INVALID_PARAMETER    UrlParser is NULL or Url is not a valid HTTP URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.

**/
EFI_STATUS
EFIAPI
HttpParseUrl (
  IN      CHAR8              *Url,
  IN      UINT32             Length,
  IN      BOOLEAN            IsConnectMethod,
     OUT  VOID               **UrlParser
  )
{
  HTTP_URL_PARSE_STATE  State;
  CHAR8                 *Char;
  UINT32                Field;
  UINT32                OldField;
  BOOLEAN               FoundAt;
  EFI_STATUS            Status;
  HTTP_URL_PARSER       *Parser;
  
  if (Url == NULL || Length == 0 || UrlParser == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = AllocateZeroPool (sizeof (HTTP_URL_PARSER));
  if (Parser == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  if (IsConnectMethod) {
    //
    // According to RFC 2616, the authority form is only used by the CONNECT method.
    //
    State = UrlParserAuthority;
  } else {
    State = UrlParserUrlStart;
  }

  Field = HTTP_URI_FIELD_MAX;
  OldField = Field;
  FoundAt = FALSE;
  for (Char = Url; Char < Url + Length; Char++) {
    //
    // Update state machine according to next char.
    //
    State = NetHttpParseUrlChar (*Char, State);

    switch (State) {
    case UrlParserStateMax:
      return EFI_INVALID_PARAMETER;
      
    case UrlParserSchemeColon:
    case UrlParserSchemeColonSlash:
    case UrlParserSchemeColonSlashSlash:
    case UrlParserQueryStart:
    case UrlParserFragmentStart:
      //
      // Skip all the delimiting char: "://" "?" "@"
      //
      continue;
    
    case UrlParserScheme:
      Field = HTTP_URI_FIELD_SCHEME;
      break;

    case UrlParserAtInAuthority:
      FoundAt = TRUE;
    case UrlParserAuthority:
      Field = HTTP_URI_FIELD_AUTHORITY;
      break;

    case UrlParserPath:
      Field = HTTP_URI_FIELD_PATH;
      break;

    case UrlParserQuery:
      Field = HTTP_URI_FIELD_QUERY;
      break;

    case UrlParserFragment:
      Field = HTTP_URI_FIELD_FRAGMENT;
      break;

    default:
      ASSERT (FALSE);
    }

    //
    // Field not changed, count the length.
    //
    ASSERT (Field < HTTP_URI_FIELD_MAX);
    if (Field == OldField) {
      Parser->FieldData[Field].Length++;
      continue;
    }

    //
    // New field start
    //
    Parser->FieldBitMap |= BIT (Field);
    Parser->FieldData[Field].Offset = (UINT32) (Char - Url);
    Parser->FieldData[Field].Length = 1;
    OldField = Field;
  }

  //
  // If has authority component, continue to parse the username, host and port.
  //
  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_AUTHORITY)) != 0) {
    Status = NetHttpParseAuthority (Url, FoundAt, Parser);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  *UrlParser = Parser;
  return EFI_SUCCESS;  
}

/**
  Get the Hostname from a HTTP URL.

  This function will return the HostName according to the Url and previous parse result ,and
  it is the caller's responsibility to free the buffer returned in *HostName.

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().
  @param[out]   HostName           Pointer to a buffer to store the HostName.

  @retval EFI_SUCCESS              Successfully get the required component.
  @retval EFI_INVALID_PARAMETER    Uri is NULL or HostName is NULL or UrlParser is invalid.
  @retval EFI_NOT_FOUND            No hostName component in the URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  
**/
EFI_STATUS
EFIAPI
HttpUrlGetHostName (
  IN      CHAR8              *Url,
  IN      VOID               *UrlParser,
     OUT  CHAR8              **HostName
  )
{
  CHAR8                *Name;
  EFI_STATUS           Status;
  UINT32               ResultLength;
  HTTP_URL_PARSER      *Parser;

  if (Url == NULL || UrlParser == NULL || HostName == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_URL_PARSER*) UrlParser;

  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
    return EFI_NOT_FOUND;
  }

  Name = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_HOST].Length + 1);
  if (Name == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  Status = UriPercentDecode (
             Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,
             Parser->FieldData[HTTP_URI_FIELD_HOST].Length,
             Name,
             &ResultLength
             );
  if (EFI_ERROR (Status)) {
    FreePool (Name);
    return Status;
  }

  Name[ResultLength] = '\0';
  *HostName = Name;
  return EFI_SUCCESS;
}


/**
  Get the IPv4 address from a HTTP URL.

  This function will return the IPv4 address according to the Url and previous parse result.

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().
  @param[out]   Ip4Address         Pointer to a buffer to store the IP address.

  @retval EFI_SUCCESS              Successfully get the required component.
  @retval EFI_INVALID_PARAMETER    Uri is NULL or Ip4Address is NULL or UrlParser is invalid.
  @retval EFI_NOT_FOUND            No IPv4 address component in the URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  
**/
EFI_STATUS
EFIAPI
HttpUrlGetIp4 (
  IN      CHAR8              *Url,
  IN      VOID               *UrlParser,
     OUT  EFI_IPv4_ADDRESS   *Ip4Address
  )
{
  CHAR8                *Ip4String;
  EFI_STATUS           Status;
  UINT32               ResultLength;
  HTTP_URL_PARSER      *Parser;
  
  if (Url == NULL || UrlParser == NULL || Ip4Address == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_URL_PARSER*) UrlParser;

  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  Ip4String = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_HOST].Length + 1);
  if (Ip4String == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  Status = UriPercentDecode (
             Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,
             Parser->FieldData[HTTP_URI_FIELD_HOST].Length,
             Ip4String,
             &ResultLength
             );
  if (EFI_ERROR (Status)) {
    FreePool (Ip4String);
    return Status;
  }

  Ip4String[ResultLength] = '\0';
  Status = NetLibAsciiStrToIp4 (Ip4String, Ip4Address);
  FreePool (Ip4String);

  return Status;
}

/**
  Get the IPv6 address from a HTTP URL.

  This function will return the IPv6 address according to the Url and previous parse result.

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().
  @param[out]   Ip6Address         Pointer to a buffer to store the IP address.

  @retval EFI_SUCCESS              Successfully get the required component.
  @retval EFI_INVALID_PARAMETER    Uri is NULL or Ip6Address is NULL or UrlParser is invalid.
  @retval EFI_NOT_FOUND            No IPv6 address component in the URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  
**/
EFI_STATUS
EFIAPI
HttpUrlGetIp6 (
  IN      CHAR8              *Url,
  IN      VOID               *UrlParser,
     OUT  EFI_IPv6_ADDRESS   *Ip6Address
  )
{
  CHAR8                *Ip6String;
  CHAR8                *Ptr;
  UINT32               Length;
  EFI_STATUS           Status;
  UINT32               ResultLength;
  HTTP_URL_PARSER      *Parser;
  
  if (Url == NULL || UrlParser == NULL || Ip6Address == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_URL_PARSER*) UrlParser;

  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // IP-literal = "[" ( IPv6address / IPvFuture  ) "]"
  //
  Length = Parser->FieldData[HTTP_URI_FIELD_HOST].Length;
  if (Length < 2) {
    return EFI_INVALID_PARAMETER;
  }

  Ptr    = Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset;
  if ((Ptr[0] != '[') || (Ptr[Length - 1] != ']')) {
    return EFI_INVALID_PARAMETER;
  }

  Ip6String = AllocatePool (Length);
  if (Ip6String == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  Status = UriPercentDecode (
             Ptr + 1,
             Length - 2,
             Ip6String,
             &ResultLength
             );
  if (EFI_ERROR (Status)) {
    FreePool (Ip6String);
    return Status;
  }
  
  Ip6String[ResultLength] = '\0';
  Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address);
  FreePool (Ip6String);

  return Status;
}

/**
  Get the port number from a HTTP URL.

  This function will return the port number according to the Url and previous parse result.

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().
  @param[out]   Port               Pointer to a buffer to store the port number.

  @retval EFI_SUCCESS              Successfully get the required component.
  @retval EFI_INVALID_PARAMETER    Uri is NULL or Port is NULL or UrlParser is invalid.
  @retval EFI_NOT_FOUND            No port number in the URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  
**/
EFI_STATUS
EFIAPI
HttpUrlGetPort (
  IN      CHAR8              *Url,
  IN      VOID               *UrlParser,
     OUT  UINT16             *Port
  )
{
  CHAR8         *PortString;
  EFI_STATUS    Status;
  UINTN         Index;
  UINTN         Data;
  UINT32        ResultLength;
  HTTP_URL_PARSER      *Parser;

  if (Url == NULL || UrlParser == NULL || Port == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Port = 0;
  Index = 0;

  Parser = (HTTP_URL_PARSER*) UrlParser;

  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PORT)) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  PortString = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_PORT].Length + 1);
  if (PortString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = UriPercentDecode (
             Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset,
             Parser->FieldData[HTTP_URI_FIELD_PORT].Length,
             PortString,
             &ResultLength
             );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  PortString[ResultLength] = '\0';

  while (Index < ResultLength) {
    if (!NET_IS_DIGIT (PortString[Index])) {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }
    Index ++;
  }

  Status =  AsciiStrDecimalToUintnS (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset, (CHAR8 **) NULL, &Data);

  if (Data > HTTP_URI_PORT_MAX_NUM) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  *Port = (UINT16) Data;

ON_EXIT:
  FreePool (PortString);
  return Status;
}

/**
  Get the Path from a HTTP URL.

  This function will return the Path according to the Url and previous parse result,and
  it is the caller's responsibility to free the buffer returned in *Path.

  @param[in]    Url                The pointer to a HTTP URL string.
  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().
  @param[out]   Path               Pointer to a buffer to store the Path.

  @retval EFI_SUCCESS              Successfully get the required component.
  @retval EFI_INVALID_PARAMETER    Uri is NULL or HostName is NULL or UrlParser is invalid.
  @retval EFI_NOT_FOUND            No hostName component in the URL.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  
**/
EFI_STATUS
EFIAPI
HttpUrlGetPath (
  IN      CHAR8              *Url,
  IN      VOID               *UrlParser,
     OUT  CHAR8              **Path
  )
{
  CHAR8                *PathStr;
  EFI_STATUS           Status;
  UINT32               ResultLength;
  HTTP_URL_PARSER      *Parser;

  if (Url == NULL || UrlParser == NULL || Path == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_URL_PARSER*) UrlParser;

  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PATH)) == 0) {
    return EFI_NOT_FOUND;
  }

  PathStr = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_PATH].Length + 1);
  if (PathStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  Status = UriPercentDecode (
             Url + Parser->FieldData[HTTP_URI_FIELD_PATH].Offset,
             Parser->FieldData[HTTP_URI_FIELD_PATH].Length,
             PathStr,
             &ResultLength
             );
  if (EFI_ERROR (Status)) {
    FreePool (PathStr);
    return Status;
  }

  PathStr[ResultLength] = '\0';
  *Path = PathStr;
  return EFI_SUCCESS;
}

/**
  Release the resource of the URL parser.

  @param[in]    UrlParser            Pointer to the parser.
  
**/
VOID
EFIAPI
HttpUrlFreeParser (
  IN      VOID               *UrlParser
  )
{
  FreePool (UrlParser);
}

/**
  Find a specified header field according to the field name.

  @param[in]   HeaderCount      Number of HTTP header structures in Headers list. 
  @param[in]   Headers          Array containing list of HTTP headers.
  @param[in]   FieldName        Null terminated string which describes a field name. 

  @return    Pointer to the found header or NULL.

**/
EFI_HTTP_HEADER *
EFIAPI
HttpFindHeader (
  IN  UINTN                HeaderCount,
  IN  EFI_HTTP_HEADER      *Headers,
  IN  CHAR8                *FieldName
  )
{
  UINTN                 Index;

  if (HeaderCount == 0 || Headers == NULL || FieldName == NULL) {
    return NULL;
  }

  for (Index = 0; Index < HeaderCount; Index++){
    //
    // Field names are case-insensitive (RFC 2616).
    //
    if (AsciiStriCmp (Headers[Index].FieldName, FieldName) == 0) {
      return &Headers[Index];
    }
  }
  return NULL;
}

typedef enum {
  BodyParserBodyStart,
  BodyParserBodyIdentity,
  BodyParserChunkSizeStart,
  BodyParserChunkSize,
  BodyParserChunkSizeEndCR,
  BodyParserChunkExtStart,
  BodyParserChunkDataStart,
  BodyParserChunkDataEnd,
  BodyParserChunkDataEndCR,
  BodyParserTrailer,
  BodyParserLastCRLF,
  BodyParserLastCRLFEnd,
  BodyParserComplete,
  BodyParserStateMax
} HTTP_BODY_PARSE_STATE;

typedef struct {
  BOOLEAN                       IgnoreBody;    // "MUST NOT" include a message-body
  BOOLEAN                       IsChunked;     // "chunked" transfer-coding.
  BOOLEAN                       ContentLengthIsValid;
  UINTN                         ContentLength; // Entity length (not the message-body length), invalid until ContentLengthIsValid is TRUE

  HTTP_BODY_PARSER_CALLBACK     Callback;
  VOID                          *Context;
  UINTN                         ParsedBodyLength;
  HTTP_BODY_PARSE_STATE         State;
  UINTN                         CurrentChunkSize;
  UINTN                         CurrentChunkParsedSize;
} HTTP_BODY_PARSER;

/**

  Convert an Ascii char to its uppercase.

  @param[in]       Char           Ascii character.

  @return          Uppercase value of the input Char.

**/
CHAR8
HttpIoCharToUpper (
  IN      CHAR8                    Char
  )
{
  if (Char >= 'a' && Char <= 'z') {
    return  Char - ('a' - 'A');
  }

  return Char;
}

/**
  Convert an hexadecimal char to a value of type UINTN.

  @param[in]       Char           Ascii character.

  @return          Value translated from Char.

**/
UINTN
HttpIoHexCharToUintn (
  IN CHAR8           Char
  )
{
  if (Char >= '0' && Char <= '9') {
    return Char - '0';
  }

  return (10 + HttpIoCharToUpper (Char) - 'A');
}

/**
  Get the value of the content length if there is a "Content-Length" header.

  @param[in]    HeaderCount        Number of HTTP header structures in Headers.
  @param[in]    Headers            Array containing list of HTTP headers.
  @param[out]   ContentLength      Pointer to save the value of the content length.

  @retval EFI_SUCCESS              Successfully get the content length.
  @retval EFI_NOT_FOUND            No "Content-Length" header in the Headers.

**/
EFI_STATUS
HttpIoParseContentLengthHeader (
  IN     UINTN                HeaderCount,
  IN     EFI_HTTP_HEADER      *Headers,
     OUT UINTN                *ContentLength
  )
{
  EFI_HTTP_HEADER       *Header;

  Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_LENGTH);
  if (Header == NULL) {
    return EFI_NOT_FOUND;
  }

  return AsciiStrDecimalToUintnS (Header->FieldValue, (CHAR8 **) NULL, ContentLength);
}

/**

  Check whether the HTTP message is using the "chunked" transfer-coding.

  @param[in]    HeaderCount        Number of HTTP header structures in Headers.
  @param[in]    Headers            Array containing list of HTTP headers.

  @return       The message is "chunked" transfer-coding (TRUE) or not (FALSE).
 
**/
BOOLEAN
HttpIoIsChunked (
  IN   UINTN                    HeaderCount,
  IN   EFI_HTTP_HEADER          *Headers
  )
{
  EFI_HTTP_HEADER       *Header;


  Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_TRANSFER_ENCODING);
  if (Header == NULL) {
    return FALSE;
  }

  if (AsciiStriCmp (Header->FieldValue, "identity") != 0) {
    return TRUE;
  }

  return FALSE;
}

/**
  Check whether the HTTP message should have a message-body.

  @param[in]    Method             The HTTP method (e.g. GET, POST) for this HTTP message.
  @param[in]    StatusCode         Response status code returned by the remote host.

  @return       The message should have a message-body (FALSE) or not (TRUE).

**/
BOOLEAN
HttpIoNoMessageBody (
  IN   EFI_HTTP_METHOD          Method,
  IN   EFI_HTTP_STATUS_CODE     StatusCode
  )
{
  //
  // RFC 2616:
  // All responses to the HEAD request method
  // MUST NOT include a message-body, even though the presence of entity-
  // header fields might lead one to believe they do. All 1xx
  // (informational), 204 (no content), and 304 (not modified) responses
  // MUST NOT include a message-body. All other responses do include a
  // message-body, although it MAY be of zero length.
  //
  if (Method == HttpMethodHead) {
    return TRUE;
  }

  if ((StatusCode == HTTP_STATUS_100_CONTINUE) ||
      (StatusCode == HTTP_STATUS_101_SWITCHING_PROTOCOLS) ||
      (StatusCode == HTTP_STATUS_204_NO_CONTENT) ||
      (StatusCode == HTTP_STATUS_304_NOT_MODIFIED))
  {
    return TRUE;
  }

  return FALSE;
}

/**
  Initialize a HTTP message-body parser.

  This function will create and initialize a HTTP message parser according to caller provided HTTP message
  header information. It is the caller's responsibility to free the buffer returned in *UrlParser by HttpFreeMsgParser().

  @param[in]    Method             The HTTP method (e.g. GET, POST) for this HTTP message.
  @param[in]    StatusCode         Response status code returned by the remote host.
  @param[in]    HeaderCount        Number of HTTP header structures in Headers.
  @param[in]    Headers            Array containing list of HTTP headers.
  @param[in]    Callback           Callback function that is invoked when parsing the HTTP message-body,
                                   set to NULL to ignore all events.
  @param[in]    Context            Pointer to the context that will be passed to Callback.
  @param[out]   MsgParser          Pointer to the returned buffer to store the message parser.

  @retval EFI_SUCCESS              Successfully initialized the parser.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.
  @retval EFI_INVALID_PARAMETER    MsgParser is NULL or HeaderCount is not NULL but Headers is NULL.
  @retval Others                   Failed to initialize the parser.

**/
EFI_STATUS
EFIAPI
HttpInitMsgParser (
  IN     EFI_HTTP_METHOD               Method,
  IN     EFI_HTTP_STATUS_CODE          StatusCode,
  IN     UINTN                         HeaderCount,
  IN     EFI_HTTP_HEADER               *Headers,
  IN     HTTP_BODY_PARSER_CALLBACK     Callback,
  IN     VOID                          *Context,
    OUT  VOID                          **MsgParser
  )
{
  EFI_STATUS            Status;
  HTTP_BODY_PARSER      *Parser;
  
  if (HeaderCount != 0 && Headers == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (MsgParser == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = AllocateZeroPool (sizeof (HTTP_BODY_PARSER));
  if (Parser == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Parser->State = BodyParserBodyStart;
  
  //
  // Determine the message length according to RFC 2616.
  // 1. Check whether the message "MUST NOT" have a message-body.
  //
  Parser->IgnoreBody = HttpIoNoMessageBody (Method, StatusCode);
  //
  // 2. Check whether the message using "chunked" transfer-coding.
  //
  Parser->IsChunked  = HttpIoIsChunked (HeaderCount, Headers);
  //
  // 3. Check whether the message has a Content-Length header field.
  //
  Status = HttpIoParseContentLengthHeader (HeaderCount, Headers, &Parser->ContentLength);
  if (!EFI_ERROR (Status)) {
    Parser->ContentLengthIsValid = TRUE;
  }
  //
  // 4. Range header is not supported now, so we won't meet media type "multipart/byteranges".
  // 5. By server closing the connection
  //
  
  //
  // Set state to skip body parser if the message shouldn't have a message body.
  //
  if (Parser->IgnoreBody) {
    Parser->State = BodyParserComplete;
  } else {
    Parser->Callback = Callback;
    Parser->Context  = Context;
  }

  *MsgParser = Parser;
  return EFI_SUCCESS;
}

/**
  Parse message body.

  Parse BodyLength of message-body. This function can be called repeatedly to parse the message-body partially.

  @param[in, out]    MsgParser            Pointer to the message parser.
  @param[in]         BodyLength           Length in bytes of the Body.
  @param[in]         Body                 Pointer to the buffer of the message-body to be parsed.

  @retval EFI_SUCCESS                Successfully parse the message-body.
  @retval EFI_INVALID_PARAMETER      MsgParser is NULL or Body is NULL or BodyLength is 0.
  @retval Others                     Operation aborted.

**/
EFI_STATUS
EFIAPI
HttpParseMessageBody (
  IN OUT VOID              *MsgParser,
  IN     UINTN             BodyLength,
  IN     CHAR8             *Body
  )
{
  CHAR8                 *Char;
  UINTN                 RemainderLengthInThis;
  UINTN                 LengthForCallback;
  EFI_STATUS            Status;
  HTTP_BODY_PARSER      *Parser;
  
  if (BodyLength == 0 || Body == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (MsgParser == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_BODY_PARSER*) MsgParser;

  if (Parser->IgnoreBody) {
    Parser->State = BodyParserComplete;
    if (Parser->Callback != NULL) {
      Status = Parser->Callback (
                 BodyParseEventOnComplete,
                 Body,
                 0,
                 Parser->Context
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
    return EFI_SUCCESS;
  }

  if (Parser->State == BodyParserBodyStart) {
    Parser->ParsedBodyLength = 0;
    if (Parser->IsChunked) {
      Parser->State = BodyParserChunkSizeStart;
    } else {
      Parser->State = BodyParserBodyIdentity;
    }
  }

  //
  // The message body might be truncated in anywhere, so we need to parse is byte-by-byte.
  //
  for (Char = Body; Char < Body + BodyLength; ) {

    switch (Parser->State) {
    case BodyParserStateMax:
      return EFI_ABORTED;
 
    case BodyParserBodyIdentity:
      //
      // Identity transfer-coding, just notify user to save the body data.
      //
      if (Parser->Callback != NULL) {
        Status = Parser->Callback (
                   BodyParseEventOnData,
                   Char,
                   MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength),
                   Parser->Context
                   );
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
      Char += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength);
      Parser->ParsedBodyLength += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength);
      if (Parser->ParsedBodyLength == Parser->ContentLength) {
        Parser->State = BodyParserComplete;
        if (Parser->Callback != NULL) {
          Status = Parser->Callback (
                     BodyParseEventOnComplete,
                     Char,
                     0,
                     Parser->Context
                     );
          if (EFI_ERROR (Status)) {
            return Status;
          }
        }
      }
      break;

    case BodyParserChunkSizeStart:
      //
      // First byte of chunk-size, the chunk-size might be truncated.
      //
      Parser->CurrentChunkSize = 0;
      Parser->State = BodyParserChunkSize;
    case BodyParserChunkSize:
      if (!NET_IS_HEX_CHAR (*Char)) {
        if (*Char == ';') {
          Parser->State = BodyParserChunkExtStart;
          Char++;
        } else if (*Char == '\r') {
          Parser->State = BodyParserChunkSizeEndCR;
          Char++;
        } else {
          Parser->State = BodyParserStateMax;
        }
        break;
      }

      if (Parser->CurrentChunkSize > (((~((UINTN) 0)) - 16) / 16)) {
        return EFI_INVALID_PARAMETER;
      }
      Parser->CurrentChunkSize = Parser->CurrentChunkSize * 16 + HttpIoHexCharToUintn (*Char);
      Char++;
      break;

    case BodyParserChunkExtStart:
      //
      // Ignore all the chunk extensions.
      //
      if (*Char == '\r') {
        Parser->State = BodyParserChunkSizeEndCR;
       }
      Char++;
      break;
      
    case BodyParserChunkSizeEndCR:
      if (*Char != '\n') {
        Parser->State = BodyParserStateMax;
        break;
      }
      Char++;
      if (Parser->CurrentChunkSize == 0) {
        //
        // The last chunk has been parsed and now assumed the state 
        // of HttpBodyParse is ParserLastCRLF. So it need to decide
        // whether the rest message is trailer or last CRLF in the next round.
        //
        Parser->ContentLengthIsValid = TRUE;
        Parser->State = BodyParserLastCRLF;
        break;
      }
      Parser->State = BodyParserChunkDataStart;
      Parser->CurrentChunkParsedSize = 0;
      break;
      
    case BodyParserLastCRLF:
      //
      // Judge the byte is belong to the Last CRLF or trailer, and then 
      // configure the state of HttpBodyParse to corresponding state.
      //
      if (*Char == '\r') {
        Char++;
        Parser->State = BodyParserLastCRLFEnd;
        break;
      } else {
        Parser->State = BodyParserTrailer;
        break;
      }
      
    case BodyParserLastCRLFEnd:
      if (*Char == '\n') {
        Parser->State = BodyParserComplete;
        Char++;
        if (Parser->Callback != NULL) {
          Status = Parser->Callback (
                     BodyParseEventOnComplete,
                     Char,
                     0,
                     Parser->Context
                     );
          if (EFI_ERROR (Status)) {
            return Status;
          }
        }
        break;
      } else {
        Parser->State = BodyParserStateMax;
        break;
      }
      
    case BodyParserTrailer:
      if (*Char == '\r') {
        Parser->State = BodyParserChunkSizeEndCR;
      }
      Char++;
      break;      

    case BodyParserChunkDataStart:
      //
      // First byte of chunk-data, the chunk data also might be truncated.
      //
      RemainderLengthInThis = BodyLength - (Char - Body);
      LengthForCallback = MIN (Parser->CurrentChunkSize - Parser->CurrentChunkParsedSize, RemainderLengthInThis);
      if (Parser->Callback != NULL) {
        Status = Parser->Callback (
                   BodyParseEventOnData,
                   Char,
                   LengthForCallback,
                   Parser->Context
                   );
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
      Char += LengthForCallback;
      Parser->ContentLength += LengthForCallback;
      Parser->CurrentChunkParsedSize += LengthForCallback;
      if (Parser->CurrentChunkParsedSize == Parser->CurrentChunkSize) {
        Parser->State = BodyParserChunkDataEnd;
      }           
      break;

    case BodyParserChunkDataEnd:
      if (*Char == '\r') {
        Parser->State = BodyParserChunkDataEndCR;
      } else {
        Parser->State = BodyParserStateMax;
      }
      Char++;
      break;

    case BodyParserChunkDataEndCR:
      if (*Char != '\n') {
        Parser->State = BodyParserStateMax;
        break;
      }
      Char++;
      Parser->State = BodyParserChunkSizeStart;
      break;     

    default:
      break;
    }

  }

  if (Parser->State == BodyParserStateMax) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Check whether the message-body is complete or not.

  @param[in]    MsgParser            Pointer to the message parser.

  @retval TRUE                       Message-body is complete.
  @retval FALSE                      Message-body is not complete.

**/
BOOLEAN
EFIAPI
HttpIsMessageComplete (
  IN VOID              *MsgParser
  )
{
  HTTP_BODY_PARSER      *Parser;

  Parser = (HTTP_BODY_PARSER*) MsgParser;

  if (Parser->State == BodyParserComplete) {
    return TRUE;
  }
  return FALSE;
}

/**
  Get the content length of the entity.

  Note that in trunk transfer, the entity length is not valid until the whole message body is received.

  @param[in]    MsgParser            Pointer to the message parser.
  @param[out]   ContentLength        Pointer to store the length of the entity.

  @retval EFI_SUCCESS                Successfully to get the entity length.
  @retval EFI_NOT_READY              Entity length is not valid yet.
  @retval EFI_INVALID_PARAMETER      MsgParser is NULL or ContentLength is NULL.
  
**/
EFI_STATUS
EFIAPI
HttpGetEntityLength (
  IN  VOID              *MsgParser,
  OUT UINTN             *ContentLength
  )
{
  HTTP_BODY_PARSER      *Parser;

  if (MsgParser == NULL || ContentLength == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Parser = (HTTP_BODY_PARSER*) MsgParser;

  if (!Parser->ContentLengthIsValid) {
    return EFI_NOT_READY;
  }

  *ContentLength = Parser->ContentLength;
  return EFI_SUCCESS;
}

/**
  Release the resource of the message parser.

  @param[in]    MsgParser            Pointer to the message parser.
  
**/
VOID
EFIAPI
HttpFreeMsgParser (
  IN  VOID           *MsgParser
  )
{
  FreePool (MsgParser);
}


/**
  Get the next string, which is distinguished by specified separator.

  @param[in]  String             Pointer to the string.
  @param[in]  Separator          Specified separator used to distinguish where is the beginning
                                 of next string.

  @return     Pointer to the next string.
  @return     NULL if not find or String is NULL.

**/
CHAR8 *
EFIAPI
AsciiStrGetNextToken (
  IN CONST CHAR8 *String,
  IN       CHAR8 Separator
  )
{
  CONST CHAR8 *Token;

  Token = String;
  while (TRUE) {
    if (*Token == 0) {
      return NULL;
    }
    if (*Token == Separator) {
      return (CHAR8 *)(Token + 1);
    }
    Token++;
  }
}

/**
  Set FieldName and FieldValue into specified HttpHeader.

  @param[in,out]  HttpHeader      Specified HttpHeader.
  @param[in]  FieldName           FieldName of this HttpHeader, a NULL terminated ASCII string.
  @param[in]  FieldValue          FieldValue of this HttpHeader, a NULL terminated ASCII string.


  @retval EFI_SUCCESS             The FieldName and FieldValue are set into HttpHeader successfully.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate resources.

**/
EFI_STATUS
EFIAPI
HttpSetFieldNameAndValue (
  IN  OUT   EFI_HTTP_HEADER       *HttpHeader,
  IN  CONST CHAR8                 *FieldName,
  IN  CONST CHAR8                 *FieldValue
  )
{
  UINTN                       FieldNameSize;
  UINTN                       FieldValueSize;

  if (HttpHeader->FieldName != NULL) {
    FreePool (HttpHeader->FieldName);
  }
  if (HttpHeader->FieldValue != NULL) {
    FreePool (HttpHeader->FieldValue);
  }

  FieldNameSize = AsciiStrSize (FieldName);
  HttpHeader->FieldName = AllocateZeroPool (FieldNameSize);
  if (HttpHeader->FieldName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  CopyMem (HttpHeader->FieldName, FieldName, FieldNameSize);
  HttpHeader->FieldName[FieldNameSize - 1] = 0;

  FieldValueSize = AsciiStrSize (FieldValue);
  HttpHeader->FieldValue = AllocateZeroPool (FieldValueSize);
  if (HttpHeader->FieldValue == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  CopyMem (HttpHeader->FieldValue, FieldValue, FieldValueSize);
  HttpHeader->FieldValue[FieldValueSize - 1] = 0;

  return EFI_SUCCESS;
}

/**
  Get one key/value header pair from the raw string.

  @param[in]  String             Pointer to the raw string.
  @param[out] FieldName          Points directly to field name within 'HttpHeader'.
  @param[out] FieldValue         Points directly to field value within 'HttpHeader'.

  @return     Pointer to the next raw string.
  @return     NULL if no key/value header pair from this raw string.

**/
CHAR8 *
EFIAPI
HttpGetFieldNameAndValue (
  IN     CHAR8   *String,
     OUT CHAR8   **FieldName,
     OUT CHAR8   **FieldValue
  )
{
  CHAR8  *FieldNameStr;
  CHAR8  *FieldValueStr;
  CHAR8  *StrPtr;

  if (String == NULL || FieldName == NULL || FieldValue == NULL) {
    return NULL;
  }

  *FieldName    = NULL;
  *FieldValue   = NULL;
  FieldNameStr  = NULL;
  FieldValueStr = NULL;
  StrPtr        = NULL;

  //
  // Each header field consists of a name followed by a colon (":") and the field value.
  //
  FieldNameStr = String;
  FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':');
  if (FieldValueStr == NULL) {
    return NULL;
  }

  //
  // Replace ':' with 0
  //
  *(FieldValueStr - 1) = 0;

  //
  // The field value MAY be preceded by any amount of LWS, though a single SP is preferred.
  //
  while (TRUE) {
    if (*FieldValueStr == ' ' || *FieldValueStr == '\t') {
      FieldValueStr ++;
    } else if (*FieldValueStr == '\r' && *(FieldValueStr + 1) == '\n' &&
               (*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t')) {
      FieldValueStr = FieldValueStr + 3;
    } else {
      break;
    }
  }

  //
  // Header fields can be extended over multiple lines by preceding each extra
  // line with at least one SP or HT.
  //
  StrPtr = FieldValueStr;
  do {
    StrPtr = AsciiStrGetNextToken (StrPtr, '\r');
    if (StrPtr == NULL || *StrPtr != '\n') {
      return NULL;
    }

    StrPtr++;
  } while (*StrPtr == ' ' || *StrPtr == '\t');

  //
  // Replace '\r' with 0
  //
  *(StrPtr - 2) = 0;

  //
  // Get FieldName and FieldValue.
  //
  *FieldName = FieldNameStr;
  *FieldValue = FieldValueStr;

  return StrPtr;
}

/**
  Free existing HeaderFields.

  @param[in]  HeaderFields       Pointer to array of key/value header pairs waitting for free.
  @param[in]  FieldCount         The number of header pairs in HeaderFields.

**/
VOID
EFIAPI
HttpFreeHeaderFields (
  IN  EFI_HTTP_HEADER  *HeaderFields,
  IN  UINTN            FieldCount
  )
{
  UINTN                       Index;

  if (HeaderFields != NULL) {
    for (Index = 0; Index < FieldCount; Index++) {
      if (HeaderFields[Index].FieldName != NULL) {
        FreePool (HeaderFields[Index].FieldName);
      }
      if (HeaderFields[Index].FieldValue != NULL) {
        FreePool (HeaderFields[Index].FieldValue);
      }
    }

    FreePool (HeaderFields);
  }
}

/**
  Generate HTTP request message.

  This function will allocate memory for the whole HTTP message and generate a
  well formatted HTTP Request message in it, include the Request-Line, header
  fields and also the message body. It is the caller's responsibility to free
  the buffer returned in *RequestMsg.

  @param[in]   Message            Pointer to the EFI_HTTP_MESSAGE structure which
                                  contains the required information to generate
                                  the HTTP request message.
  @param[in]   Url                The URL of a remote host.
  @param[out]  RequestMsg         Pointer to the created HTTP request message.
                                  NULL if any error occured.
  @param[out]  RequestMsgSize     Size of the RequestMsg (in bytes).

  @return EFI_SUCCESS             If HTTP request string was created successfully
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate resources.
  @retval EFI_INVALID_PARAMETER   The input arguments are invalid

**/
EFI_STATUS
EFIAPI
HttpGenRequestMessage (
  IN     CONST EFI_HTTP_MESSAGE        *Message,
  IN     CONST CHAR8                   *Url,
     OUT CHAR8                         **RequestMsg,
     OUT UINTN                         *RequestMsgSize
  )
{
  EFI_STATUS                       Status;
  UINTN                            StrLength;
  CHAR8                            *RequestPtr;
  UINTN                            HttpHdrSize;
  UINTN                            MsgSize;
  BOOLEAN                          Success;
  VOID                             *HttpHdr;
  EFI_HTTP_HEADER                  **AppendList;
  UINTN                            Index;
  EFI_HTTP_UTILITIES_PROTOCOL      *HttpUtilitiesProtocol;


  ASSERT (Message != NULL);

  *RequestMsg           = NULL;
  Status                = EFI_SUCCESS;
  HttpHdrSize           = 0;
  MsgSize               = 0;
  Success               = FALSE;
  HttpHdr               = NULL;
  AppendList            = NULL;
  HttpUtilitiesProtocol = NULL;

  //
  // 1. If we have a Request, we cannot have a NULL Url
  // 2. If we have a Request, HeaderCount can not be non-zero
  // 3. If we do not have a Request, HeaderCount should be zero
  // 4. If we do not have Request and Headers, we need at least a message-body
  //
  if ((Message->Data.Request != NULL && Url == NULL) ||
      (Message->Data.Request != NULL && Message->HeaderCount == 0) ||
      (Message->Data.Request == NULL && Message->HeaderCount != 0) ||
      (Message->Data.Request == NULL && Message->HeaderCount == 0 && Message->BodyLength == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Message->HeaderCount != 0) {
    //
    // Locate the HTTP_UTILITIES protocol.
    //
    Status = gBS->LocateProtocol (
                    &gEfiHttpUtilitiesProtocolGuid,
                    NULL,
                    (VOID **)&HttpUtilitiesProtocol
                    );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR,"Failed to locate Http Utilities protocol. Status = %r.\n", Status));
      return Status;
    }

    //
    // Build AppendList to send into HttpUtilitiesBuild
    //
    AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));
    if (AppendList == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    for(Index = 0; Index < Message->HeaderCount; Index++){
      AppendList[Index] = &Message->Headers[Index];
    }

    //
    // Build raw HTTP Headers
    //
    Status = HttpUtilitiesProtocol->Build (
                HttpUtilitiesProtocol,
                0,
                NULL,
                0,
                NULL,
                Message->HeaderCount,
                AppendList,
                &HttpHdrSize,
                &HttpHdr
                );

    if (AppendList != NULL) {
      FreePool (AppendList);
    }

    if (EFI_ERROR (Status) || HttpHdr == NULL){
      return Status;
    }
  }

  //
  // If we have headers to be sent, account for it.
  //
  if (Message->HeaderCount != 0) {
    MsgSize = HttpHdrSize;
  }

  //
  // If we have a request line, account for the fields.
  //
  if (Message->Data.Request != NULL) {
    MsgSize += HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (HTTP_VERSION_CRLF_STR) + AsciiStrLen (Url);
  }


  //
  // If we have a message body to be sent, account for it.
  //
  MsgSize += Message->BodyLength;

  //
  // memory for the string that needs to be sent to TCP
  //
  *RequestMsg = AllocateZeroPool (MsgSize);
  if (*RequestMsg == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  RequestPtr = *RequestMsg;
  //
  // Construct header request
  //
  if (Message->Data.Request != NULL) {
    switch (Message->Data.Request->Method) {
    case HttpMethodGet:
      StrLength = sizeof (HTTP_METHOD_GET) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);
      RequestPtr += StrLength;
      break;
    case HttpMethodPut:
      StrLength = sizeof (HTTP_METHOD_PUT) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength);
      RequestPtr += StrLength;
      break;
    case HttpMethodPatch:
      StrLength = sizeof (HTTP_METHOD_PATCH) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength);
      RequestPtr += StrLength;
      break;
    case HttpMethodPost:
      StrLength = sizeof (HTTP_METHOD_POST) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength);
      RequestPtr += StrLength;
      break;
    case HttpMethodHead:
      StrLength = sizeof (HTTP_METHOD_HEAD) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);
      RequestPtr += StrLength;
      break;
    case HttpMethodDelete:
      StrLength = sizeof (HTTP_METHOD_DELETE) - 1;
      CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
      RequestPtr += StrLength;
      break;
    default:
      ASSERT (FALSE);
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    StrLength = AsciiStrLen(EMPTY_SPACE);
    CopyMem (RequestPtr, EMPTY_SPACE, StrLength);
    RequestPtr += StrLength;

    StrLength = AsciiStrLen (Url);
    CopyMem (RequestPtr, Url, StrLength);
    RequestPtr += StrLength;

    StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;
    CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);
    RequestPtr += StrLength;

    if (HttpHdr != NULL) {
      //
      // Construct header
      //
      CopyMem (RequestPtr, HttpHdr, HttpHdrSize);
      RequestPtr += HttpHdrSize;
    }
  }

  //
  // Construct body
  //
  if (Message->Body != NULL) {
    CopyMem (RequestPtr, Message->Body, Message->BodyLength);
    RequestPtr += Message->BodyLength;
  }

  //
  // Done
  //
  (*RequestMsgSize) = (UINTN)(RequestPtr) - (UINTN)(*RequestMsg);
  Success     = TRUE;

Exit:

  if (!Success) {
    if (*RequestMsg != NULL) {
      FreePool (*RequestMsg);
    }
    *RequestMsg = NULL;
    return Status;
  }

  if (HttpHdr != NULL) {
    FreePool (HttpHdr);
  }

  return EFI_SUCCESS;
}

/**
  Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
  in UEFI 2.5 specification.

  @param[in]  StatusCode         The status code value in HTTP message.

  @return                        Value defined in EFI_HTTP_STATUS_CODE .

**/
EFI_HTTP_STATUS_CODE
EFIAPI
HttpMappingToStatusCode (
  IN UINTN                  StatusCode
  )
{
  switch (StatusCode) {
  case 100:
    return HTTP_STATUS_100_CONTINUE;
  case 101:
    return HTTP_STATUS_101_SWITCHING_PROTOCOLS;
  case 200:
    return HTTP_STATUS_200_OK;
  case 201:
    return HTTP_STATUS_201_CREATED;
  case 202:
    return HTTP_STATUS_202_ACCEPTED;
  case 203:
    return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION;
  case 204:
    return HTTP_STATUS_204_NO_CONTENT;
  case 205:
    return HTTP_STATUS_205_RESET_CONTENT;
  case 206:
    return HTTP_STATUS_206_PARTIAL_CONTENT;
  case 300:
    return HTTP_STATUS_300_MULTIPLE_CHIOCES;
  case 301:
    return HTTP_STATUS_301_MOVED_PERMANENTLY;
  case 302:
    return HTTP_STATUS_302_FOUND;
  case 303:
    return HTTP_STATUS_303_SEE_OTHER;
  case 304:
    return HTTP_STATUS_304_NOT_MODIFIED;
  case 305:
    return HTTP_STATUS_305_USE_PROXY;
  case 307:
    return HTTP_STATUS_307_TEMPORARY_REDIRECT;
  case 308:
    return HTTP_STATUS_308_PERMANENT_REDIRECT;
  case 400:
    return HTTP_STATUS_400_BAD_REQUEST;
  case 401:
    return HTTP_STATUS_401_UNAUTHORIZED;
  case 402:
    return HTTP_STATUS_402_PAYMENT_REQUIRED;
  case 403:
    return HTTP_STATUS_403_FORBIDDEN;
  case 404:
    return HTTP_STATUS_404_NOT_FOUND;
  case 405:
    return HTTP_STATUS_405_METHOD_NOT_ALLOWED;
  case 406:
    return HTTP_STATUS_406_NOT_ACCEPTABLE;
  case 407:
    return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED;
  case 408:
    return HTTP_STATUS_408_REQUEST_TIME_OUT;
  case 409:
    return HTTP_STATUS_409_CONFLICT;
  case 410:
    return HTTP_STATUS_410_GONE;
  case 411:
    return HTTP_STATUS_411_LENGTH_REQUIRED;
  case 412:
    return HTTP_STATUS_412_PRECONDITION_FAILED;
  case 413:
    return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE;
  case 414:
    return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE;
  case 415:
    return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE;
  case 416:
    return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;
  case 417:
    return HTTP_STATUS_417_EXPECTATION_FAILED;
  case 500:
    return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;
  case 501:
    return HTTP_STATUS_501_NOT_IMPLEMENTED;
  case 502:
    return HTTP_STATUS_502_BAD_GATEWAY;
  case 503:
    return HTTP_STATUS_503_SERVICE_UNAVAILABLE;
  case 504:
    return HTTP_STATUS_504_GATEWAY_TIME_OUT;
  case 505:
    return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED;

  default:
    return HTTP_STATUS_UNSUPPORTED_STATUS;
  }
}

/**
  Check whether header field called FieldName is in DeleteList.

  @param[in]  DeleteList        Pointer to array of key/value header pairs.
  @param[in]  DeleteCount       The number of header pairs.
  @param[in]  FieldName         Pointer to header field's name.

  @return     TRUE if FieldName is not in DeleteList, that means this header field is valid.
  @return     FALSE if FieldName is in DeleteList, that means this header field is invalid.

**/
BOOLEAN
EFIAPI
HttpIsValidHttpHeader (
  IN  CHAR8            *DeleteList[],
  IN  UINTN            DeleteCount,
  IN  CHAR8            *FieldName
  )
{
  UINTN                       Index;

  for (Index = 0; Index < DeleteCount; Index++) {
    if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {
      return FALSE;
    }
  }

  return TRUE;
}

