59 UINTN TotalReceivedSize;
63 BOOLEAN CopyChunkData;
67 BOOLEAN IsGetChunkedTransfer;
74 IsGetChunkedTransfer =
FALSE;
75 SendChunkProcess = HttpIoSendChunkNone;
76 SendNonChunkProcess = HttpIoSendNonChunkNone;
78 PreservedRequestHeaders =
NULL;
83 if ((This ==
NULL) || (RequestMessage ==
NULL) || (ResponseMessage ==
NULL)) {
84 return EFI_INVALID_PARAMETER;
87 Instance = RESTEX_INSTANCE_FROM_THIS (This);
100 DEBUG ((
DEBUG_REDFISH_NETWORK,
"*** Perform HTTP Request Method - %d, URL: %s\n", RequestMessage->Data.Request->Method, RequestMessage->Data.Request->Url));
107 if (EFI_ERROR (Status)) {
111 if (ItsWrite ==
TRUE) {
112 if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) {
119 SendNonChunkProcess++;
130 if (ItsWrite ==
TRUE) {
134 if (SendChunkProcess > HttpIoSendChunkNone) {
144 &ChunkTransferRequestMessage
146 if (EFI_ERROR (Status)) {
149 }
while (SendChunkProcess == HttpIoSendChunkContent || SendChunkProcess == HttpIoSendChunkEndChunk);
157 (SendNonChunkProcess == HttpIoSendNonChunkContent) ?
NULL : RequestMessage->Data.Request,
158 (SendNonChunkProcess == HttpIoSendNonChunkContent) ? 0 : RequestMessage->HeaderCount,
159 (SendNonChunkProcess == HttpIoSendNonChunkContent) ?
NULL : RequestMessage->Headers,
160 (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ? 0 : RequestMessage->BodyLength,
161 (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) ?
NULL : RequestMessage->Body
170 RequestMessage->Data.Request,
171 RequestMessage->HeaderCount,
172 RequestMessage->Headers,
173 RequestMessage->BodyLength,
183 RequestMessage->Data.Request,
184 RequestMessage->HeaderCount,
185 RequestMessage->Headers,
186 RequestMessage->BodyLength,
191 if (EFI_ERROR (Status)) {
204 if (ResponseMessage->Data.Response !=
NULL) {
205 FreePool (ResponseMessage->Data.Response);
206 ResponseMessage->Data.Response =
NULL;
209 ResponseMessage->BodyLength = 0;
210 if (ResponseMessage->Body !=
NULL) {
212 ResponseMessage->Body =
NULL;
219 if (ResponseData ==
NULL) {
220 Status = EFI_OUT_OF_RESOURCES;
233 if (Status == EFI_NOT_READY) {
235 }
else if (Status == EFI_DEVICE_ERROR) {
242 if (
FixedPcdGetBool (PcdRedfishRestExAddingExpect) && (RequestMessage->Headers != PreservedRequestHeaders)) {
244 RequestMessage->Headers = PreservedRequestHeaders;
245 RequestMessage->HeaderCount--;
249 if (ResponseData->Response.
StatusCode == HTTP_STATUS_200_OK) {
252 if (
FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) {
257 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_204_NO_CONTENT) {
258 DEBUG ((DEBUG_MANAGEABILITY,
"HTTP_STATUS_204_NO_CONTENT\n"));
260 if (
FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) {
261 DEBUG ((DEBUG_MANAGEABILITY,
"This is chunk transfer, start to send all chunks - %d.", ResponseData->Response.
StatusCode));
265 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_201_CREATED) {
266 DEBUG ((DEBUG_MANAGEABILITY,
"HTTP_STATUS_201_CREATED\n"));
267 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_202_ACCEPTED) {
268 DEBUG ((DEBUG_MANAGEABILITY,
"HTTP_STATUS_202_ACCEPTED\n"));
269 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE) {
272 Status = EFI_BAD_BUFFER_SIZE;
274 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_405_METHOD_NOT_ALLOWED) {
275 DEBUG ((DEBUG_ERROR,
"HTTP_STATUS_405_METHOD_NOT_ALLOWED\n"));
277 Status = EFI_ACCESS_DENIED;
279 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_400_BAD_REQUEST) {
281 if (
FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) {
286 }
else if (ResponseData->Response.
StatusCode == HTTP_STATUS_100_CONTINUE) {
288 if (
FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendChunkProcess == HttpIoSendChunkHeaderZeroContent)) {
297 if (
FixedPcdGetBool (PcdRedfishRestExChunkRequestMode) && (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)) {
299 SendNonChunkProcess++;
307 if ((ResponseData->Headers !=
NULL) && (ResponseData->HeaderCount != 0)) {
317 if (EFI_ERROR (Status)) {
321 DEBUG ((DEBUG_ERROR,
"This HTTP Status is not handled!\n"));
323 Status = EFI_UNSUPPORTED;
329 if (ResponseMessage->Data.Response ==
NULL) {
330 Status = EFI_OUT_OF_RESOURCES;
334 ResponseMessage->Data.Response->StatusCode = ResponseData->Response.
StatusCode;
343 if (ResponseMessage->Data.Response ==
NULL) {
344 Status = EFI_OUT_OF_RESOURCES;
348 ResponseMessage->Data.Response->StatusCode = ResponseData->Response.
StatusCode;
349 ResponseMessage->HeaderCount = ResponseData->HeaderCount;
350 ResponseMessage->Headers = ResponseData->Headers;
355 if (ResponseMessage->HeaderCount > 0) {
356 Status =
HttpIoGetContentLength (ResponseMessage->HeaderCount, ResponseMessage->Headers, &ResponseMessage->BodyLength);
357 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
361 if (Status == EFI_NOT_FOUND) {
362 ASSERT (ResponseMessage->BodyLength == 0);
365 if (ResponseMessage->BodyLength == 0) {
371 ResponseMessage->HeaderCount,
372 ResponseMessage->Headers,
374 &ResponseMessage->BodyLength
376 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
381 (ChunkListLink !=
NULL) &&
383 (ResponseMessage->BodyLength != 0))
385 IsGetChunkedTransfer =
TRUE;
389 CopyChunkData =
TRUE;
391 if (ResponseMessage->Body ==
NULL) {
392 Status = EFI_OUT_OF_RESOURCES;
393 CopyChunkData =
FALSE;
400 CopyMem (((UINT8 *)ResponseMessage->Body + Index), (UINT8 *)ThisChunk->Data, ThisChunk->Length);
401 Index += ThisChunk->Length;
419 if ((ResponseMessage->BodyLength > 0) && !IsGetChunkedTransfer) {
420 ResponseData->HeaderCount = 0;
421 ResponseData->Headers =
NULL;
424 if (ResponseMessage->Body ==
NULL) {
425 Status = EFI_OUT_OF_RESOURCES;
432 TotalReceivedSize = 0;
433 while (TotalReceivedSize < ResponseMessage->BodyLength) {
434 ResponseData->BodyLength = ResponseMessage->BodyLength - TotalReceivedSize;
435 ResponseData->Body = (CHAR8 *)ResponseMessage->Body + TotalReceivedSize;
441 if (EFI_ERROR (Status)) {
445 TotalReceivedSize += ResponseData->BodyLength;
455 if (ResponseData !=
NULL) {
491 return EFI_UNSUPPORTED;
538 if ((This ==
NULL) || (RestExServiceInfo ==
NULL)) {
539 return EFI_INVALID_PARAMETER;
542 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
544 Instance = RESTEX_INSTANCE_FROM_THIS (This);
547 if (ServiceInfo ==
NULL) {
548 return EFI_OUT_OF_RESOURCES;
553 *RestExServiceInfo = ServiceInfo;
555 gBS->RestoreTPL (OldTpl);
590 OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData
593 return EFI_UNSUPPORTED;
631 IN EFI_REST_EX_CONFIG_DATA RestExConfigData
641 HttpConfigData =
NULL;
644 return EFI_INVALID_PARAMETER;
647 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
649 Instance = RESTEX_INSTANCE_FROM_THIS (This);
651 if (RestExConfigData ==
NULL) {
657 if (Instance->ConfigData !=
NULL) {
663 Instance->ConfigData =
NULL;
666 Instance->State = RESTEX_STATE_UNCONFIGED;
669 Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, HttpConfigData);
670 if (EFI_ERROR (Status)) {
677 if (Instance->ConfigData ==
NULL) {
678 Status = EFI_OUT_OF_RESOURCES;
686 Status = EFI_OUT_OF_RESOURCES;
692 HttpConfigData->AccessPoint.
IPv6Node,
698 Status = EFI_OUT_OF_RESOURCES;
704 HttpConfigData->AccessPoint.
IPv4Node,
709 Instance->State = RESTEX_STATE_CONFIGED;
713 gBS->RestoreTPL (OldTpl);
754 IN UINTN *TimeOutInMilliSeconds OPTIONAL
757 return EFI_UNSUPPORTED;
794 return EFI_UNSUPPORTED;
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
HTTP_IO_SEND_NON_CHUNK_PROCESS
EFI_STATUS HttpIoGetContentLength(IN UINTN HeaderCount, IN EFI_HTTP_HEADER *Headers, OUT UINTN *ContentLength)
EFI_STATUS HttpIoSendChunkedTransfer(IN HTTP_IO *HttpIo, IN HTTP_IO_SEND_CHUNK_PROCESS *SendChunkProcess, IN EFI_HTTP_MESSAGE *RequestMessage)
HTTP_IO_SEND_CHUNK_PROCESS
EFI_STATUS HttpIoGetChunkedTransferContent(IN HTTP_IO *HttpIo, IN UINTN HeaderCount, IN EFI_HTTP_HEADER *Headers, OUT LIST_ENTRY **ChunkListHead, OUT UINTN *ContentLength)
VOID HttpIoDestroyIo(IN HTTP_IO *HttpIo)
EFI_STATUS HttpIoSendRequest(IN HTTP_IO *HttpIo, IN EFI_HTTP_REQUEST_DATA *Request OPTIONAL, IN UINTN HeaderCount, IN EFI_HTTP_HEADER *Headers OPTIONAL, IN UINTN BodyLength, IN VOID *Body OPTIONAL)
EFI_STATUS HttpIoRecvResponse(IN HTTP_IO *HttpIo, IN BOOLEAN RecvMsgHeader, OUT HTTP_IO_RESPONSE_DATA *ResponseData)
#define DEBUG(Expression)
EFI_STATUS EFIAPI NetLibDetectMedia(IN EFI_HANDLE ServiceHandle, OUT BOOLEAN *MediaPresent)
#define FixedPcdGetBool(TokenName)
EFI_STATUS DumpHttpStatusCode(IN UINTN ErrorLevel, IN EFI_HTTP_STATUS_CODE HttpStatusCode)
#define DEBUG_REDFISH_NETWORK
Debug error level for Redfish networking function.
EFI_STATUS ResetHttpTslSession(IN RESTEX_INSTANCE *Instance)
EFI_STATUS RedfishCheckHttpReceiveStatus(IN RESTEX_INSTANCE *Instance, IN EFI_STATUS HttpIoReceiveStatus)
EFI_STATUS RedfishHttpAddExpectation(IN EFI_REST_EX_PROTOCOL *This, IN EFI_HTTP_MESSAGE *RequestMessage, IN EFI_HTTP_HEADER **PreservedRequestHeaders, IN BOOLEAN *ItsWrite)
EFI_STATUS EFIAPI RedfishRestExEventService(IN EFI_REST_EX_PROTOCOL *This, IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, IN EFI_REST_EX_TOKEN *RestExToken)
EFI_STATUS EFIAPI RedfishRestExSendReceive(IN EFI_REST_EX_PROTOCOL *This, IN EFI_HTTP_MESSAGE *RequestMessage, OUT EFI_HTTP_MESSAGE *ResponseMessage)
EFI_STATUS EFIAPI RedfishRestExGetServiceTime(IN EFI_REST_EX_PROTOCOL *This, OUT EFI_TIME *Time)
EFI_STATUS EFIAPI RedfishRestExConfigure(IN EFI_REST_EX_PROTOCOL *This, IN EFI_REST_EX_CONFIG_DATA RestExConfigData)
EFI_STATUS EFIAPI RedfishRestExGetModeData(IN EFI_REST_EX_PROTOCOL *This, OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData)
EFI_STATUS EFIAPI RedfishRestExGetService(IN EFI_REST_EX_PROTOCOL *This, OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo)
EFI_STATUS EFIAPI RedfishRestExAyncSendReceive(IN EFI_REST_EX_PROTOCOL *This, IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, IN EFI_REST_EX_TOKEN *RestExToken, IN UINTN *TimeOutInMilliSeconds OPTIONAL)
EFI_HTTPv6_ACCESS_POINT * IPv6Node
EFI_HTTPv4_ACCESS_POINT * IPv4Node
BOOLEAN LocalAddressIsIPv6
EFI_HTTP_STATUS_CODE StatusCode