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