/** @file
  Implementation of EFI_HTTP_PROTOCOL protocol interfaces.

  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "HttpUtilitiesDxe.h"

EFI_HTTP_UTILITIES_PROTOCOL mHttpUtilitiesProtocol = {
  HttpUtilitiesBuild,
  HttpUtilitiesParse
};


/**
  Create HTTP header based on a combination of seed header, fields
  to delete, and fields to append.

  The Build() function is used to manage the headers portion of an
  HTTP message by providing the ability to add, remove, or replace
  HTTP headers.

  @param[in]  This                Pointer to EFI_HTTP_UTILITIES_PROTOCOL instance.
  @param[in]  SeedMessageSize     Size of the initial HTTP header. This can be zero.
  @param[in]  SeedMessage         Initial HTTP header to be used as a base for
                                  building a new HTTP header. If NULL,
                                  SeedMessageSize is ignored.
  @param[in]  DeleteCount         Number of null-terminated HTTP header field names
                                  in DeleteList.
  @param[in]  DeleteList          List of null-terminated HTTP header field names to
                                  remove from SeedMessage. Only the field names are
                                  in this list because the field values are irrelevant
                                  to this operation.
  @param[in]  AppendCount         Number of header fields in AppendList.
  @param[in]  AppendList          List of HTTP headers to populate NewMessage with.
                                  If SeedMessage is not NULL, AppendList will be
                                  appended to the existing list from SeedMessage in
                                  NewMessage.
  @param[out] NewMessageSize      Pointer to number of header fields in NewMessage.
  @param[out] NewMessage          Pointer to a new list of HTTP headers based on.

  @retval EFI_SUCCESS             Add, remove, and replace operations succeeded.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory for NewMessage.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
**/
EFI_STATUS
EFIAPI
HttpUtilitiesBuild (
  IN     EFI_HTTP_UTILITIES_PROTOCOL *This,
  IN     UINTN                       SeedMessageSize,
  IN     VOID                        *SeedMessage, OPTIONAL
  IN     UINTN                       DeleteCount,
  IN     CHAR8                       *DeleteList[], OPTIONAL
  IN     UINTN                       AppendCount,
  IN     EFI_HTTP_HEADER             *AppendList[], OPTIONAL
     OUT UINTN                       *NewMessageSize,
     OUT VOID                        **NewMessage
  )
{
  EFI_STATUS                Status;
  EFI_HTTP_HEADER           *SeedHeaderFields;
  UINTN                     SeedFieldCount;
  UINTN                     Index;
  EFI_HTTP_HEADER           *TempHeaderFields;
  UINTN                     TempFieldCount;
  EFI_HTTP_HEADER           *NewHeaderFields;
  UINTN                     NewFieldCount;
  EFI_HTTP_HEADER           *HttpHeader;
  UINTN                     StrLength;
  UINT8                     *NewMessagePtr;

  SeedHeaderFields = NULL;
  SeedFieldCount   = 0;
  TempHeaderFields = NULL;
  TempFieldCount   = 0;
  NewHeaderFields  = NULL;
  NewFieldCount    = 0;

  HttpHeader       = NULL;
  StrLength        = 0;
  NewMessagePtr    = NULL;
  *NewMessageSize  = 0;
  Status           = EFI_SUCCESS;
  
  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (SeedMessage != NULL) {
    Status = This->Parse (
                     This, 
                     SeedMessage, 
                     SeedMessageSize, 
                     &SeedHeaderFields, 
                     &SeedFieldCount
                     );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Handle DeleteList
  //
  if (SeedFieldCount != 0 && DeleteCount != 0) {
    TempHeaderFields = AllocateZeroPool (SeedFieldCount * sizeof(EFI_HTTP_HEADER));
    if (TempHeaderFields == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    
    for (Index = 0, TempFieldCount = 0; Index < SeedFieldCount; Index++) {
      //
      // Check whether each SeedHeaderFields member is in DeleteList
      //
      if (HttpIsValidHttpHeader( DeleteList, DeleteCount, SeedHeaderFields[Index].FieldName)) {
        Status = HttpSetFieldNameAndValue (
                   &TempHeaderFields[TempFieldCount], 
                   SeedHeaderFields[Index].FieldName, 
                   SeedHeaderFields[Index].FieldValue
                   );
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }
        TempFieldCount++;
      }
    }
  } else {
    TempHeaderFields = SeedHeaderFields;
    TempFieldCount = SeedFieldCount;
  }

  //
  // Handle AppendList
  //
  NewHeaderFields = AllocateZeroPool ((TempFieldCount + AppendCount) * sizeof (EFI_HTTP_HEADER));
  if (NewHeaderFields == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  for (Index = 0; Index < TempFieldCount; Index++) {
    Status = HttpSetFieldNameAndValue (
               &NewHeaderFields[Index], 
               TempHeaderFields[Index].FieldName, 
               TempHeaderFields[Index].FieldValue
               );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }
  
  NewFieldCount = TempFieldCount;

  for (Index = 0; Index < AppendCount; Index++) {
    HttpHeader = HttpFindHeader (NewFieldCount, NewHeaderFields, AppendList[Index]->FieldName);
    if (HttpHeader != NULL) {
      Status = HttpSetFieldNameAndValue (
                 HttpHeader, 
                 AppendList[Index]->FieldName, 
                 AppendList[Index]->FieldValue
                 );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }
    } else {
      Status = HttpSetFieldNameAndValue (
                 &NewHeaderFields[NewFieldCount], 
                 AppendList[Index]->FieldName, 
                 AppendList[Index]->FieldValue
                 );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }
      NewFieldCount++;
    }
  }

  //
  // Calculate NewMessageSize, then build NewMessage
  //
  for (Index = 0; Index < NewFieldCount; Index++) {
    HttpHeader = &NewHeaderFields[Index];

    StrLength = AsciiStrLen (HttpHeader->FieldName);
    *NewMessageSize += StrLength;

    StrLength = sizeof(": ") - 1;
    *NewMessageSize += StrLength;

    StrLength = AsciiStrLen (HttpHeader->FieldValue);
    *NewMessageSize += StrLength;

    StrLength = sizeof("\r\n") - 1;
    *NewMessageSize += StrLength;
  }
  StrLength = sizeof("\r\n") - 1;
  *NewMessageSize += StrLength;

  *NewMessage = AllocateZeroPool (*NewMessageSize);
  if (*NewMessage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  NewMessagePtr = (UINT8 *)(*NewMessage);

  for (Index = 0; Index < NewFieldCount; Index++) {
    HttpHeader = &NewHeaderFields[Index];

    StrLength = AsciiStrLen (HttpHeader->FieldName);
    CopyMem (NewMessagePtr, HttpHeader->FieldName, StrLength);
    NewMessagePtr += StrLength;

    StrLength = sizeof(": ") - 1;
    CopyMem (NewMessagePtr, ": ", StrLength);
    NewMessagePtr += StrLength;

    StrLength = AsciiStrLen (HttpHeader->FieldValue);
    CopyMem (NewMessagePtr, HttpHeader->FieldValue, StrLength);
    NewMessagePtr += StrLength;

    StrLength = sizeof("\r\n") - 1;
    CopyMem (NewMessagePtr, "\r\n", StrLength);
    NewMessagePtr += StrLength;
  }
  StrLength = sizeof("\r\n") - 1;
  CopyMem (NewMessagePtr, "\r\n", StrLength);
  NewMessagePtr += StrLength;

  ASSERT (*NewMessageSize == (UINTN)NewMessagePtr - (UINTN)(*NewMessage));

  //
  // Free allocated buffer 
  //
ON_EXIT:
  if (SeedHeaderFields != NULL) {
    HttpFreeHeaderFields(SeedHeaderFields, SeedFieldCount);
  }
  
  if (TempHeaderFields != NULL) {
    HttpFreeHeaderFields(TempHeaderFields, TempFieldCount);
  }

  if (NewHeaderFields != NULL) {
    HttpFreeHeaderFields(NewHeaderFields, NewFieldCount);
  }
  
  return Status;
}


/**
  Parses HTTP header and produces an array of key/value pairs.

  The Parse() function is used to transform data stored in HttpHeader
  into a list of fields paired with their corresponding values.

  @param[in]  This                Pointer to EFI_HTTP_UTILITIES_PROTOCOL instance.
  @param[in]  HttpMessage         Contains raw unformatted HTTP header string.
  @param[in]  HttpMessageSize     Size of HTTP header.
  @param[out] HeaderFields        Array of key/value header pairs.
  @param[out] FieldCount          Number of headers in HeaderFields.

  @retval EFI_SUCCESS             Allocation succeeded.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been
                                  initialized.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  HttpMessage is NULL.
                                  HeaderFields is NULL.
                                  FieldCount is NULL.
**/
EFI_STATUS
EFIAPI
HttpUtilitiesParse (
  IN  EFI_HTTP_UTILITIES_PROTOCOL  *This,
  IN  CHAR8                        *HttpMessage,
  IN  UINTN                        HttpMessageSize,
  OUT EFI_HTTP_HEADER              **HeaderFields,
  OUT UINTN                        *FieldCount
  )
{
  EFI_STATUS                Status;
  CHAR8                     *TempHttpMessage;
  CHAR8                     *Token;
  CHAR8                     *NextToken;
  CHAR8                     *FieldName;
  CHAR8                     *FieldValue;
  UINTN                     Index;
  
  Status          = EFI_SUCCESS;
  TempHttpMessage = NULL;
  Token           = NULL;
  NextToken       = NULL;
  FieldName       = NULL;
  FieldValue      = NULL;
  Index           = 0;
  
  if (This == NULL || HttpMessage == NULL || HeaderFields == NULL || FieldCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  TempHttpMessage = AllocateZeroPool (HttpMessageSize);
  if (TempHttpMessage == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (TempHttpMessage, HttpMessage, HttpMessageSize);
  
  //
  // Get header number
  //
  *FieldCount = 0;
  Token = TempHttpMessage;
  while (TRUE) {
    FieldName     = NULL;
    FieldValue    = NULL;
    NextToken = HttpGetFieldNameAndValue (Token, &FieldName, &FieldValue);
    Token     = NextToken;
    if (FieldName == NULL || FieldValue == NULL) {
      break;
    }

    (*FieldCount)++;
  }

  if (*FieldCount == 0) {
    Status =  EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  
  //
  // Allocate buffer for header
  //
  *HeaderFields = AllocateZeroPool ((*FieldCount) * sizeof(EFI_HTTP_HEADER));
  if (*HeaderFields == NULL) {
    *FieldCount = 0;
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  
  CopyMem (TempHttpMessage, HttpMessage, HttpMessageSize);
  
  //
  // Set Field and Value to each header
  //
  Token = TempHttpMessage;
  while (Index < *FieldCount) {
    FieldName     = NULL;
    FieldValue    = NULL;
    NextToken = HttpGetFieldNameAndValue (Token, &FieldName, &FieldValue);
    Token     = NextToken;
    if (FieldName == NULL || FieldValue == NULL) {
      break;
    }

    Status = HttpSetFieldNameAndValue (&(*HeaderFields)[Index], FieldName, FieldValue);
    if (EFI_ERROR (Status)) {
      *FieldCount = 0;
      HttpFreeHeaderFields (*HeaderFields, Index);
      goto ON_EXIT;
    }
    
    Index++;
  }

  //
  // Free allocated buffer 
  //
ON_EXIT:
  if (TempHttpMessage != NULL) {
    FreePool (TempHttpMessage);
  }
  
  return Status;
}