/** @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)) {
    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)) {
    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)) {
    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)) {
    return Status;
  }

  PortString[ResultLength] = '\0';

  while (Index < ResultLength) {
    if (!NET_IS_DIGIT (PortString[Index])) {
      return EFI_INVALID_PARAMETER;
    }
    Index ++;
  }

  Status =  AsciiStrDecimalToUintnS (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset, (CHAR8 **) NULL, &Data);

  if (Data > HTTP_URI_PORT_MAX_NUM) {
    return EFI_INVALID_PARAMETER;
  }

  *Port = (UINT16) Data;
  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)) {
    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 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;
}

