123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /** @file
- Implementation of EFI_HTTP_PROTOCOL protocol interfaces.
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #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;
- UINTN HttpBufferSize;
- 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;
- }
- //
- // Append the http response string along with a Null-terminator.
- //
- HttpBufferSize = HttpMessageSize + 1;
- TempHttpMessage = AllocatePool (HttpBufferSize);
- if (TempHttpMessage == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (TempHttpMessage, HttpMessage, HttpMessageSize);
- *(TempHttpMessage + HttpMessageSize) = '\0';
- //
- // 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;
- }
|