From 39254d922e550ccc9c5ab5639c3c28a4ee4e13fd Mon Sep 17 00:00:00 2001 From: Abner Chang Date: Fri, 10 Feb 2023 02:05:12 +0800 Subject: RedfishPkg/RedfishRestExDxe: Two PCDs for controlling the requests Since BIOS should work with different BMC implementation chunked requests as well as Expect header should be optional. - One PCD is used to enable/disable Expect header. - Another PCD is used to enable/disable chunked requests. Reviewed-by: Abner Chang Cc: Abner Chang Cc: Nickle Wang Signed-off-by: Igor Kulchytskyy --- RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf | 5 +- RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c | 24 ++-- .../RedfishRestExDxe/RedfishRestExProtocol.c | 138 +++++++++++++-------- 3 files changed, 105 insertions(+), 62 deletions(-) (limited to 'RedfishPkg/RedfishRestExDxe') diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf index 75437b086a..2f7a2188e8 100644 --- a/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf @@ -3,6 +3,7 @@ # # Copyright (c) 2019, Intel Corporation. All rights reserved.
# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, American Megatrends International LLC. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -56,7 +57,9 @@ gEfiDevicePathProtocolGuid ## TO_START [Pcd] - gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand ## CONSUMES + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand ## CONSUMES + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExChunkRequestMode ## CONSUMES + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExAddingExpect ## CONSUMES [UserExtensions.TianoCore."ExtraFiles"] RedfishRestExDxeExtra.uni diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c index 952e9d103a..75b3f1fab8 100644 --- a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, American Megatrends International LLC. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -140,9 +141,6 @@ RedfishHttpAddExpectation ( } *ItsWrite = FALSE; - if (PreservedRequestHeaders != NULL) { - *PreservedRequestHeaders = RequestMessage->Headers; - } if ((RequestMessage->Data.Request->Method != HttpMethodPut) && (RequestMessage->Data.Request->Method != HttpMethodPost) && (RequestMessage->Data.Request->Method != HttpMethodPatch)) @@ -152,10 +150,20 @@ RedfishHttpAddExpectation ( *ItsWrite = TRUE; - NewHeaders = AllocateZeroPool ((RequestMessage->HeaderCount + 1) * sizeof (EFI_HTTP_HEADER)); - CopyMem ((VOID *)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER)); - HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE); - RequestMessage->HeaderCount++; - RequestMessage->Headers = NewHeaders; + // + // Check PCD before adding Expect header + // + if (FixedPcdGetBool (PcdRedfishRestExAddingExpect)) { + if (PreservedRequestHeaders != NULL) { + *PreservedRequestHeaders = RequestMessage->Headers; + } + + NewHeaders = AllocateZeroPool ((RequestMessage->HeaderCount + 1) * sizeof (EFI_HTTP_HEADER)); + CopyMem ((VOID *)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER)); + HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE); + RequestMessage->HeaderCount++; + RequestMessage->Headers = NewHeaders; + } + return EFI_SUCCESS; } diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c index 4b61fc01ad..1c3deab09a 100644 --- a/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c @@ -3,6 +3,7 @@ Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, American Megatrends International LLC. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -66,11 +67,13 @@ RedfishRestExSendReceive ( HTTP_IO_SEND_NON_CHUNK_PROCESS SendNonChunkProcess; EFI_HTTP_MESSAGE ChunkTransferRequestMessage; - Status = EFI_SUCCESS; - ResponseData = NULL; - IsGetChunkedTransfer = FALSE; - SendChunkProcess = HttpIoSendChunkNone; - SendNonChunkProcess = HttpIoSendNonChunkNone; + Status = EFI_SUCCESS; + ResponseData = NULL; + IsGetChunkedTransfer = FALSE; + SendChunkProcess = HttpIoSendChunkNone; + SendNonChunkProcess = HttpIoSendNonChunkNone; + ItsWrite = FALSE; + PreservedRequestHeaders = NULL; // // Validate the parameters @@ -94,67 +97,84 @@ RedfishRestExSendReceive ( DEBUG ((DEBUG_INFO, "\nRedfishRestExSendReceive():\n")); DEBUG ((DEBUG_INFO, "*** Perform HTTP Request Method - %d, URL: %s\n", RequestMessage->Data.Request->Method, RequestMessage->Data.Request->Url)); - // - // Add header "Expect" to server, only for URL write. - // - Status = RedfishHttpAddExpectation (This, RequestMessage, &PreservedRequestHeaders, &ItsWrite); - if (EFI_ERROR (Status)) { - return Status; - } + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode)) { + // + // Add header "Expect" to server, only for URL write. + // + Status = RedfishHttpAddExpectation (This, RequestMessage, &PreservedRequestHeaders, &ItsWrite); + if (EFI_ERROR (Status)) { + return Status; + } - if (ItsWrite == TRUE) { - if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) { - // - // Send chunked transfer. - // - SendChunkProcess++; - CopyMem ((VOID *)&ChunkTransferRequestMessage, (VOID *)RequestMessage, sizeof (EFI_HTTP_MESSAGE)); - } else { - SendNonChunkProcess++; + if (ItsWrite == TRUE) { + if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) { + // + // Send chunked transfer. + // + SendChunkProcess++; + CopyMem ((VOID *)&ChunkTransferRequestMessage, (VOID *)RequestMessage, sizeof (EFI_HTTP_MESSAGE)); + } else { + SendNonChunkProcess++; + } } } ReSendRequest:; - // - // Send out the request to REST service. - // - if (ItsWrite == TRUE) { + + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode)) { // - // This is write to URI + // Send the chunked request to REST service. // - if (SendChunkProcess > HttpIoSendChunkNone) { + if (ItsWrite == TRUE) { // - // This is chunk transfer for writing large payload. - // Send request header first and then handle the - // following request message body using chunk transfer. + // This is write to URI // - do { - Status = HttpIoSendChunkedTransfer ( + if (SendChunkProcess > HttpIoSendChunkNone) { + // + // This is chunk transfer for writing large payload. + // Send request header first and then handle the + // following request message body using chunk transfer. + // + do { + Status = HttpIoSendChunkedTransfer ( + &(Instance->HttpIo), + &SendChunkProcess, + &ChunkTransferRequestMessage + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } while (SendChunkProcess == HttpIoSendChunkContent || SendChunkProcess == HttpIoSendChunkEndChunk); + } else { + // + // This is the non-chunk transfer, send request header first and then + // handle the following request message body using chunk transfer. + // + Status = HttpIoSendRequest ( &(Instance->HttpIo), - &SendChunkProcess, - &ChunkTransferRequestMessage + (SendNonChunkProcess == HttpIoSendNonChunkContent) ? NULL : RequestMessage->Data.Request, + (SendNonChunkProcess == HttpIoSendNonChunkContent) ? 0 : RequestMessage->HeaderCount, + (SendNonChunkProcess == HttpIoSendNonChunkContent) ? NULL : RequestMessage->Headers, + (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ? 0 : RequestMessage->BodyLength, + (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ? NULL : RequestMessage->Body ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - } while (SendChunkProcess == HttpIoSendChunkContent || SendChunkProcess == HttpIoSendChunkEndChunk); + } } else { // - // This is the non-chunk transfer, send request header first and then - // handle the following request message body using chunk transfer. + // This is read from URI. // Status = HttpIoSendRequest ( &(Instance->HttpIo), - (SendNonChunkProcess == HttpIoSendNonChunkContent) ? NULL : RequestMessage->Data.Request, - (SendNonChunkProcess == HttpIoSendNonChunkContent) ? 0 : RequestMessage->HeaderCount, - (SendNonChunkProcess == HttpIoSendNonChunkContent) ? NULL : RequestMessage->Headers, - (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ? 0 : RequestMessage->BodyLength, - (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ? NULL : RequestMessage->Body + RequestMessage->Data.Request, + RequestMessage->HeaderCount, + RequestMessage->Headers, + RequestMessage->BodyLength, + RequestMessage->Body ); } } else { // - // This is read from URI. + // This is normal request to URI. // Status = HttpIoSendRequest ( &(Instance->HttpIo), @@ -213,7 +233,7 @@ ReSendRequest:; // // Restore the headers if it ever changed in RedfishHttpAddExpectation(). // - if (RequestMessage->Headers != PreservedRequestHeaders) { + if (FixedPcdGetBool (PcdRedfishRestExAddingExpect) && (RequestMessage->Headers != PreservedRequestHeaders)) { FreePool (RequestMessage->Headers); RequestMessage->Headers = PreservedRequestHeaders; // Restore headers before we adding "Expect". RequestMessage->HeaderCount--; // Minus one header count for "Expect". @@ -223,11 +243,23 @@ ReSendRequest:; if (ResponseData->Response.StatusCode == HTTP_STATUS_200_OK) { DEBUG ((DEBUG_INFO, "HTTP_STATUS_200_OK\n")); - if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { - DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chunks.")); + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) { + DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chunks - %d.", ResponseData->Response.StatusCode)); + SendChunkProcess++; + goto ReSendRequest; + } + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_204_NO_CONTENT) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_204_NO_CONTENT\n")); + + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) { + DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chunks - %d.", ResponseData->Response.StatusCode)); SendChunkProcess++; goto ReSendRequest; } + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_201_CREATED) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_201_CREATED\n")); + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_202_ACCEPTED) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_202_ACCEPTED\n")); } else if (ResponseData->Response.StatusCode == HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE) { DEBUG ((DEBUG_INFO, "HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE\n")); @@ -240,14 +272,14 @@ ReSendRequest:; goto ON_EXIT; } else if (ResponseData->Response.StatusCode == HTTP_STATUS_400_BAD_REQUEST) { DEBUG ((DEBUG_INFO, "HTTP_STATUS_400_BAD_REQUEST\n")); - if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) { DEBUG ((DEBUG_INFO, "Bad request may caused by zero length chunk. Try to send all chunks...\n")); SendChunkProcess++; goto ReSendRequest; } } else if (ResponseData->Response.StatusCode == HTTP_STATUS_100_CONTINUE) { DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE\n")); - if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) { // // We get HTTP_STATUS_100_CONTINUE to send the body using chunk transfer. // @@ -256,7 +288,7 @@ ReSendRequest:; goto ReSendRequest; } - if (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) { + if (FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)) { DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for non chunk transfer...\n")); SendNonChunkProcess++; goto ReSendRequest; @@ -394,7 +426,7 @@ ReSendRequest:; TotalReceivedSize += ResponseData->BodyLength; } - DEBUG ((DEBUG_INFO, "Total of lengh of Response :%d\n", TotalReceivedSize)); + DEBUG ((DEBUG_INFO, "Total of length of Response :%d\n", TotalReceivedSize)); } DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive()- EFI_STATUS: %r\n", Status)); -- cgit v1.2.3