+ } else {\r
+ if (HttpInstance->TimeoutEvent == NULL) {\r
+ //\r
+ // Create TimeoutEvent for response\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_CALLBACK,\r
+ NULL,\r
+ NULL,\r
+ &HttpInstance->TimeoutEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error2;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Start the timer, and wait Timeout seconds to receive the body packet.\r
+ //\r
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error2;\r
+ }\r
+\r
+ Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);\r
+\r
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error2;\r
+ }\r
+\r
+ //\r
+ // Check whether we receive a complete HTTP message.\r
+ //\r
+ Status = HttpParseMessageBody (\r
+ HttpInstance->MsgParser,\r
+ (UINTN) Fragment.Len,\r
+ (CHAR8 *) Fragment.Bulk\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error2;\r
+ }\r
+\r
+ if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
+ //\r
+ // Free the MsgParse since we already have a full HTTP message.\r
+ //\r
+ HttpFreeMsgParser (HttpInstance->MsgParser);\r
+ HttpInstance->MsgParser = NULL;\r
+ }\r
+\r
+ //\r
+ // We receive part of header of next HTTP msg.\r
+ //\r
+ if (HttpInstance->NextMsg != NULL) {\r
+ HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength);\r
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
+\r
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
+ if (HttpInstance->CacheLen != 0) {\r
+ if (HttpInstance->CacheBody != NULL) {\r
+ FreePool (HttpInstance->CacheBody);\r
+ }\r
+\r
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
+ if (HttpInstance->CacheBody == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Error2;\r
+ }\r
+\r
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
+ HttpInstance->CacheOffset = 0;\r
+\r
+ HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength));\r
+ }\r
+ } else {\r
+ HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);\r
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
+ if (HttpInstance->CacheLen != 0) {\r
+ if (HttpInstance->CacheBody != NULL) {\r
+ FreePool (HttpInstance->CacheBody);\r
+ }\r
+\r
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
+ if (HttpInstance->CacheBody == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Error2;\r
+ }\r
+\r
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
+ HttpInstance->CacheOffset = 0;\r
+ }\r
+ }\r
+\r
+ if (Fragment.Bulk != NULL) {\r
+ FreePool (Fragment.Bulk);\r
+ Fragment.Bulk = NULL;\r
+ }\r
+\r
+ goto Exit;\r