diff options
author | Jiaxin Wu <jiaxin.wu@intel.com> | 2015-08-24 01:24:20 +0000 |
---|---|---|
committer | jiaxinwu <jiaxinwu@Edk2> | 2015-08-24 01:24:20 +0000 |
commit | aa498f8c3885b45a560c02a4e7f8b751e6d6451d (patch) | |
tree | 20a5d6b93838900690f2b2bec1069c82d6b0e5f0 /NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c | |
parent | 38dcf8edfe8e0d30363284ae7728bf254e718364 (diff) | |
download | edk2-platforms-aa498f8c3885b45a560c02a4e7f8b751e6d6451d.tar.xz |
NetworkPkg: Add HTTP utilities driver
This patch is used to add HTTP utilities driver.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@hp.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18260 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c')
-rw-r--r-- | NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c b/NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c new file mode 100644 index 0000000000..71b39f2831 --- /dev/null +++ b/NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesProtocol.c @@ -0,0 +1,393 @@ +/** @file + Implementation of EFI_HTTP_PROTOCOL protocol interfaces. + + 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 + 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 (IsValidHttpHeader( DeleteList, DeleteCount, SeedHeaderFields[Index].FieldName)) { + Status = SetFieldNameAndValue ( + &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 = SetFieldNameAndValue ( + &NewHeaderFields[Index], + TempHeaderFields[Index].FieldName, + TempHeaderFields[Index].FieldValue + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } + + NewFieldCount = TempFieldCount; + + for (Index = 0; Index < AppendCount; Index++) { + HttpHeader = FindHttpHeader (NewHeaderFields, NewFieldCount, AppendList[Index]->FieldName); + if (HttpHeader != NULL) { + Status = SetFieldNameAndValue ( + HttpHeader, + AppendList[Index]->FieldName, + AppendList[Index]->FieldValue + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } else { + Status = SetFieldNameAndValue ( + &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; + + // + // Final 0 for end flag + // + *NewMessageSize += 1; + + *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; + + *NewMessagePtr = 0; + + ASSERT (*NewMessageSize == (UINTN)NewMessagePtr - (UINTN)(*NewMessage) + 1); + + // + // Free allocated buffer + // +ON_EXIT: + if (SeedHeaderFields != NULL) { + FreeHeaderFields(SeedHeaderFields, SeedFieldCount); + } + + if (TempHeaderFields != NULL) { + FreeHeaderFields(TempHeaderFields, TempFieldCount); + } + + if (NewHeaderFields != NULL) { + FreeHeaderFields(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; + *FieldCount = 0; + 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 + // + Token = TempHttpMessage; + while (TRUE) { + FieldName = NULL; + FieldValue = NULL; + NextToken = GetFieldNameAndValue (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 = GetFieldNameAndValue (Token, &FieldName, &FieldValue); + Token = NextToken; + if (FieldName == NULL || FieldValue == NULL) { + break; + } + + Status = SetFieldNameAndValue (&(*HeaderFields)[Index], FieldName, FieldValue); + if (EFI_ERROR (Status)) { + *FieldCount = 0; + FreeHeaderFields (*HeaderFields, Index); + goto ON_EXIT; + } + + Index++; + } + + // + // Free allocated buffer + // +ON_EXIT: + if (TempHttpMessage != NULL) { + FreePool (TempHttpMessage); + } + + return Status; +}
\ No newline at end of file |