|
@@ -3,6 +3,7 @@
|
|
|
|
|
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
|
|
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
|
|
|
+ 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));
|