sizeof (HttpInstance->IPv4Node)\r
);\r
}\r
+ \r
//\r
// Creat Tcp child\r
//\r
HttpInstance->EndofHeader = &EndofHeader;\r
HttpInstance->HttpHeaders = &HttpHeaders;\r
\r
- Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize);\r
+\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 Error;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Start the timer, and wait Timeout seconds to receive the header packet.\r
+ //\r
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+\r
+ Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize, HttpInstance->TimeoutEvent);\r
+\r
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
+\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
\r
ASSERT (HttpInstance->MsgParser != NULL);\r
\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 Error;\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 Error;\r
+ }\r
+\r
//\r
// We still need receive more data when there is no cache data and MsgParser is not NULL;\r
//\r
- Status = HttpTcpReceiveBody (Wrap, HttpMsg);\r
+ Status = HttpTcpReceiveBody (Wrap, HttpMsg, HttpInstance->TimeoutEvent);\r
+\r
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
+\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
\r
HttpCloseTcpConnCloseEvent (HttpInstance);\r
\r
+ if (HttpInstance->TimeoutEvent != NULL) {\r
+ gBS->CloseEvent (HttpInstance->TimeoutEvent);\r
+ HttpInstance->TimeoutEvent = NULL;\r
+ }\r
+\r
if (HttpInstance->CacheBody != NULL) {\r
FreePool (HttpInstance->CacheBody);\r
HttpInstance->CacheBody = NULL;\r
@param[in] HttpInstance The HTTP instance private data.\r
@param[in, out] SizeofHeaders The HTTP header length.\r
@param[in, out] BufferSize The size of buffer to cacahe the header message.\r
+ @param[in] Timeout The time to wait for receiving the header packet.\r
\r
@retval EFI_SUCCESS The HTTP header is received. \r
@retval Others Other errors as indicated.\r
HttpTcpReceiveHeader (\r
IN HTTP_PROTOCOL *HttpInstance,\r
IN OUT UINTN *SizeofHeaders,\r
- IN OUT UINTN *BufferSize\r
+ IN OUT UINTN *BufferSize,\r
+ IN EFI_EVENT Timeout\r
)\r
{\r
EFI_STATUS Status;\r
return Status;\r
}\r
\r
- while (!HttpInstance->IsRxDone) {\r
- Tcp4->Poll (Tcp4);\r
- } \r
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+ Tcp4->Poll (Tcp4);\r
+ }\r
+\r
+ if (!HttpInstance->IsRxDone) {\r
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+ Rx4Token->CompletionToken.Status = EFI_TIMEOUT;\r
+ }\r
\r
Status = Rx4Token->CompletionToken.Status;\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- while (!HttpInstance->IsRxDone) {\r
- Tcp6->Poll (Tcp6);\r
- } \r
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+ Tcp6->Poll (Tcp6);\r
+ }\r
+\r
+ if (!HttpInstance->IsRxDone) {\r
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+ Rx6Token->CompletionToken.Status = EFI_TIMEOUT;\r
+ }\r
\r
Status = Rx6Token->CompletionToken.Status;\r
if (EFI_ERROR (Status)) {\r
\r
@param[in] Wrap The HTTP token's wrap data.\r
@param[in] HttpMsg The HTTP message data.\r
+ @param[in] Timeout The time to wait for receiving the body packet.\r
\r
@retval EFI_SUCCESS The HTTP body is received. \r
@retval Others Other error as indicated.\r
EFI_STATUS\r
HttpTcpReceiveBody (\r
IN HTTP_TOKEN_WRAP *Wrap,\r
- IN EFI_HTTP_MESSAGE *HttpMsg\r
+ IN EFI_HTTP_MESSAGE *HttpMsg,\r
+ IN EFI_EVENT Timeout\r
)\r
{\r
EFI_STATUS Status;\r
Tcp6 = HttpInstance->Tcp6;\r
Rx4Token = NULL;\r
Rx6Token = NULL;\r
-\r
\r
if (HttpInstance->LocalAddressIsIPv6) {\r
ASSERT (Tcp6 != NULL);\r
DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
return Status;\r
}\r
- \r
+\r
+ while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+ Tcp6->Poll (Tcp6);\r
+ }\r
+\r
+ if (!Wrap->TcpWrap.IsRxDone) {\r
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+ Rx6Token->CompletionToken.Status = EFI_TIMEOUT;\r
+ Wrap->HttpToken->Status = Rx6Token->CompletionToken.Status;\r
+ gBS->SignalEvent (Wrap->HttpToken->Event);\r
+ }\r
} else {\r
Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
return Status;\r
}\r
+\r
+ while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
+ Tcp4->Poll (Tcp4);\r
+ }\r
+\r
+ if (!Wrap->TcpWrap.IsRxDone) {\r
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+ Rx4Token->CompletionToken.Status = EFI_TIMEOUT;\r
+ Wrap->HttpToken->Status = Rx4Token->CompletionToken.Status;\r
+ gBS->SignalEvent (Wrap->HttpToken->Event);\r
+ }\r
}\r
\r
return EFI_SUCCESS;\r
#define HTTP_BUFFER_SIZE_DEAULT 65535\r
#define HTTP_MAX_SYN_BACK_LOG 5\r
#define HTTP_CONNECTION_TIMEOUT 60\r
+#define HTTP_RESPONSE_TIMEOUT 5\r
#define HTTP_DATA_RETRIES 12\r
#define HTTP_FIN_TIMEOUT 2\r
#define HTTP_KEEP_ALIVE_PROBES 6\r
\r
UINTN StatusCode;\r
\r
+ EFI_EVENT TimeoutEvent;\r
+\r
EFI_HANDLE Tcp4ChildHandle;\r
EFI_TCP4_PROTOCOL *Tcp4;\r
EFI_TCP4_CONFIG_DATA Tcp4CfgData;\r
EFI_TCP6_CLOSE_TOKEN Tcp6CloseToken;\r
BOOLEAN IsTcp6CloseDone;\r
EFI_IPv6_ADDRESS RemoteIpv6Addr;\r
-\r
-\r
- \r
+ \r
//\r
// Rx4Token or Rx6Token used for receiving HTTP header.\r
//\r
@param[in] HttpInstance The HTTP instance private data.\r
@param[in, out] SizeofHeaders The HTTP header length.\r
@param[in, out] BufferSize The size of buffer to cacahe the header message.\r
+ @param[in] Timeout The time to wait for receiving the header packet.\r
\r
@retval EFI_SUCCESS The HTTP header is received. \r
@retval Others Other errors as indicated.\r
HttpTcpReceiveHeader (\r
IN HTTP_PROTOCOL *HttpInstance,\r
IN OUT UINTN *SizeofHeaders,\r
- IN OUT UINTN *BufferSize\r
+ IN OUT UINTN *BufferSize,\r
+ IN EFI_EVENT Timeout\r
);\r
\r
/**\r
\r
@param[in] Wrap The HTTP token's wrap data.\r
@param[in] HttpMsg The HTTP message data.\r
+ @param[in] Timeout The time to wait for receiving the body packet.\r
\r
@retval EFI_SUCCESS The HTTP body is received. \r
@retval Others Other error as indicated.\r
EFI_STATUS\r
HttpTcpReceiveBody (\r
IN HTTP_TOKEN_WRAP *Wrap,\r
- IN EFI_HTTP_MESSAGE *HttpMsg\r
+ IN EFI_HTTP_MESSAGE *HttpMsg,\r
+ IN EFI_EVENT Timeout\r
);\r
\r
/**\r