| /** @file | |
| The functions for HttpUtilities driver. | |
| 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" | |
| /** | |
| Get the next string, which is distinguished by specified seperator. | |
| @param[in] String Pointer to the string. | |
| @param[in] Seperator Specified seperator used to distinguish where is the beginning | |
| of next string. | |
| @return Pointer to the next string. | |
| @return NULL if not find or String is NULL. | |
| **/ | |
| CHAR8 * | |
| AsciiStrGetNextToken ( | |
| IN CONST CHAR8 *String, | |
| IN CHAR8 Seperator | |
| ) | |
| { | |
| CONST CHAR8 *Token; | |
| Token = String; | |
| while (TRUE) { | |
| if (*Token == 0) { | |
| return NULL; | |
| } | |
| if (*Token == Seperator) { | |
| return (CHAR8 *)(Token + 1); | |
| } | |
| Token++; | |
| } | |
| } | |
| /** | |
| 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 | |
| FreeHeaderFields ( | |
| 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); | |
| } | |
| } | |
| /** | |
| Find required header field in HeaderFields. | |
| @param[in] HeaderFields Pointer to array of key/value header pairs. | |
| @param[in] FieldCount The number of header pairs. | |
| @param[in] FieldName Pointer to header field's name. | |
| @return Pointer to the queried header field. | |
| @return NULL if not find this required header field. | |
| **/ | |
| EFI_HTTP_HEADER * | |
| FindHttpHeader ( | |
| IN EFI_HTTP_HEADER *HeaderFields, | |
| IN UINTN FieldCount, | |
| IN CHAR8 *FieldName | |
| ) | |
| { | |
| UINTN Index; | |
| for (Index = 0; Index < FieldCount; Index++) { | |
| if (AsciiStrCmp (FieldName, HeaderFields[Index].FieldName) == 0) { | |
| // | |
| // Find the required header field. | |
| // | |
| return &HeaderFields[Index]; | |
| } | |
| } | |
| return NULL; | |
| } | |
| /** | |
| 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 | |
| IsValidHttpHeader ( | |
| 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; | |
| } | |
| /** | |
| Set FieldName and FieldValue into specified HttpHeader. | |
| @param[in] HttpHeader Specified HttpHeader. | |
| @param[in] FieldName FieldName of this HttpHeader. | |
| @param[in] FieldValue FieldValue of this HttpHeader. | |
| @retval EFI_SUCCESS The FieldName and FieldValue are set into HttpHeader successfully. | |
| @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. | |
| **/ | |
| EFI_STATUS | |
| SetFieldNameAndValue ( | |
| IN EFI_HTTP_HEADER *HttpHeader, | |
| IN CHAR8 *FieldName, | |
| IN 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 Pointer to header field's name. | |
| @param[out] FieldValue Pointer to header field's value. | |
| @return Pointer to the next raw string. | |
| @return NULL if no key/value header pair from this raw string. | |
| **/ | |
| CHAR8 * | |
| GetFieldNameAndValue ( | |
| 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; | |
| } | |