/** @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 - 2018, 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 (Index + 1 >= BufferLength || Index + 2 >= BufferLength ||
          !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 EFI_INVALID_PARAMETER   The Url is invalid to parse the authority component.

**/
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;

  Parser = NULL;

  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:
      FreePool (Parser);
      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)) {
      FreePool (Parser);
      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_NOT_FOUND;
  }

  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_NOT_FOUND;
  }

  //
  // 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_NOT_FOUND;
  }

  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 EFI_ABORTED                Operation aborted.
  @retval Other                      Error happened while parsing message body.

**/
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;

  if (MsgParser == NULL) {
    return FALSE;
  }

  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 *
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_INVALID_PARAMETER   The parameter is invalid.
  @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 == NULL || FieldName == NULL || FieldValue == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  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) {
    FreePool (HttpHeader->FieldName);
    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;
  CHAR8  *EndofHeader;

  if (String == NULL || FieldName == NULL || FieldValue == NULL) {
    return NULL;
  }

  *FieldName    = NULL;
  *FieldValue   = NULL;
  FieldNameStr  = NULL;
  FieldValueStr = NULL;
  StrPtr        = NULL;
  EndofHeader   = NULL;


  //
  // Check whether the raw HTTP header string is valid or not.
  //
  EndofHeader = AsciiStrStr (String, "\r\n\r\n");
  if (EndofHeader == NULL) {
    return 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.
  // Note: LWS  = [CRLF] 1*(SP|HT), it can be '\r\n ' or '\r\n\t' or ' ' or '\t'.
  //       CRLF = '\r\n'.
  //       SP   = ' '.
  //       HT   = '\t' (Tab).
  //
  while (TRUE) {
    if (*FieldValueStr == ' ' || *FieldValueStr == '\t') {
      //
      // Boundary condition check.
      //
      if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 1) {
        return NULL;
      }

      FieldValueStr ++;
    } else if (*FieldValueStr == '\r') {
      //
      // Boundary condition check.
      //
      if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 3) {
        return NULL;
      }

      if (*(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).

  @retval 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;

  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 == NULL || RequestMsg == NULL || RequestMsgSize == NULL) ||
      (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
                                      );

    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 = NULL;
  *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_CHOICES;
  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;

  if (FieldName == NULL) {
    return FALSE;
  }

  for (Index = 0; Index < DeleteCount; Index++) {
    if (DeleteList[Index] == NULL) {
      continue;
    }

    if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {
      return FALSE;
    }
  }

  return TRUE;
}

