/** @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, Intel Corporation. All rights reserved.<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 <Uefi.h>
#include <Library/NetLib.h>
#include <Library/HttpLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>

#define BIT(x)  (1 << x)

#define NET_IS_HEX_CHAR(Ch)   \
  ((('0' <= (Ch)) && ((Ch) <= '9')) ||  \
   (('A' <= (Ch)) && ((Ch) <= 'F')) ||  \
   (('a' <= (Ch)) && ((Ch) <= 'f')))

//
// Field index of the HTTP URL parse result.
//
#define   HTTP_URI_FIELD_SCHEME           0
#define   HTTP_URI_FIELD_AUTHORITY        1
#define   HTTP_URI_FIELD_PATH             2
#define   HTTP_URI_FIELD_QUERY            3
#define   HTTP_URI_FIELD_FRAGMENT         4
#define   HTTP_URI_FIELD_USERINFO         5
#define   HTTP_URI_FIELD_HOST             6
#define   HTTP_URI_FIELD_PORT             7
#define   HTTP_URI_FIELD_MAX              8

//
// Structure to store the parse result of a HTTP URL.
//
typedef struct {
    UINT32      Offset;
    UINT32      Length;
} HTTP_URL_FILED_DATA;

typedef struct {
  UINT16                  FieldBitMap;
  HTTP_URL_FILED_DATA     FieldData[HTTP_URI_FIELD_MAX];
} HTTP_URL_PARSER;

typedef enum {
  UrlParserUrlStart,
  UrlParserScheme,
  UrlParserSchemeColon,            // ":"
  UrlParserSchemeColonSlash,       // ":/"
  UrlParserSchemeColonSlashSlash,  // "://"
  UrlParserAuthority,
  UrlParserAtInAuthority,
  UrlParserPath,
  UrlParserQueryStart,    // "?"
  UrlParserQuery,
  UrlParserFragmentStart, // "#"
  UrlParserFragment,
  UrlParserUserInfo,
  UrlParserHostStart,     // "@"
  UrlParserHost,
  UrlParserHostIpv6,      // "["(Ipv6 address) "]"
  UrlParserPortStart,     // ":"
  UrlParserPort,
  UrlParserStateMax
} HTTP_URL_PARSE_STATE;

/**
  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 accroding 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 accroding 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 accoring 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;
  UINT32        ResultLength;
  HTTP_URL_PARSER      *Parser;

  if (Url == NULL || UrlParser == NULL || Port == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  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';
  *Port = (UINT16) AsciiStrDecimalToUintn (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset);

  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 *
HttpIoFindHeader (
  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 = HttpIoFindHeader (HeaderCount, Headers, "Content-Length");
  if (Header == NULL) {
    return EFI_NOT_FOUND;
  }

  *ContentLength = AsciiStrDecimalToUintn (Header->FieldValue);
  return EFI_SUCCESS;
}

/**

  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 = HttpIoFindHeader (HeaderCount, Headers, "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 accroding 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);
}
