mirror of https://github.com/acidanthera/audk.git
NetworkPkg: Avoid the indefinite wait case in HttpDxe
Need the timer check to avoid the indefinite wait case in HttpDxe driver A.HTTP receive Header process in HttpTcpReceiveHeader(); B.HTTP receive Body process in HttpTcpReceiveBody(); Cc: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com> Cc: El-Haj-Mahmoud Samer <samer.el-haj-mahmoud@hpe.com> Cc: Ye Ting <ting.ye@intel.com> Cc: Fu Siyuan <siyuan.fu@intel.com> Cc: Zhang Lubo <lubo.zhang@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
This commit is contained in:
parent
467d5f6b30
commit
b347a22aec
|
@ -176,6 +176,7 @@ EfiHttpConfigure (
|
|||
sizeof (HttpInstance->IPv4Node)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Creat Tcp child
|
||||
//
|
||||
|
@ -897,7 +898,35 @@ HttpResponseWorker (
|
|||
HttpInstance->EndofHeader = &EndofHeader;
|
||||
HttpInstance->HttpHeaders = &HttpHeaders;
|
||||
|
||||
Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize);
|
||||
|
||||
if (HttpInstance->TimeoutEvent == NULL) {
|
||||
//
|
||||
// Create TimeoutEvent for response
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
NULL,
|
||||
NULL,
|
||||
&HttpInstance->TimeoutEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start the timer, and wait Timeout seconds to receive the header packet.
|
||||
//
|
||||
Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Status = HttpTcpReceiveHeader (HttpInstance, &SizeofHeaders, &BufferSize, HttpInstance->TimeoutEvent);
|
||||
|
||||
gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
@ -1098,10 +1127,37 @@ HttpResponseWorker (
|
|||
|
||||
ASSERT (HttpInstance->MsgParser != NULL);
|
||||
|
||||
if (HttpInstance->TimeoutEvent == NULL) {
|
||||
//
|
||||
// Create TimeoutEvent for response
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
NULL,
|
||||
NULL,
|
||||
&HttpInstance->TimeoutEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start the timer, and wait Timeout seconds to receive the body packet.
|
||||
//
|
||||
Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// We still need receive more data when there is no cache data and MsgParser is not NULL;
|
||||
//
|
||||
Status = HttpTcpReceiveBody (Wrap, HttpMsg);
|
||||
Status = HttpTcpReceiveBody (Wrap, HttpMsg, HttpInstance->TimeoutEvent);
|
||||
|
||||
gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
|
|
@ -815,6 +815,11 @@ HttpCleanProtocol (
|
|||
|
||||
HttpCloseTcpConnCloseEvent (HttpInstance);
|
||||
|
||||
if (HttpInstance->TimeoutEvent != NULL) {
|
||||
gBS->CloseEvent (HttpInstance->TimeoutEvent);
|
||||
HttpInstance->TimeoutEvent = NULL;
|
||||
}
|
||||
|
||||
if (HttpInstance->CacheBody != NULL) {
|
||||
FreePool (HttpInstance->CacheBody);
|
||||
HttpInstance->CacheBody = NULL;
|
||||
|
@ -1541,6 +1546,7 @@ HttpTcpReceive (
|
|||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in, out] SizeofHeaders The HTTP header length.
|
||||
@param[in, out] BufferSize The size of buffer to cacahe the header message.
|
||||
@param[in] Timeout The time to wait for receiving the header packet.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP header is received.
|
||||
@retval Others Other errors as indicated.
|
||||
|
@ -1550,7 +1556,8 @@ EFI_STATUS
|
|||
HttpTcpReceiveHeader (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN OUT UINTN *SizeofHeaders,
|
||||
IN OUT UINTN *BufferSize
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN EFI_EVENT Timeout
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -1599,10 +1606,15 @@ HttpTcpReceiveHeader (
|
|||
return Status;
|
||||
}
|
||||
|
||||
while (!HttpInstance->IsRxDone) {
|
||||
while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
|
||||
Tcp4->Poll (Tcp4);
|
||||
}
|
||||
|
||||
if (!HttpInstance->IsRxDone) {
|
||||
gBS->CloseEvent (Rx4Token->CompletionToken.Event);
|
||||
Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
Status = Rx4Token->CompletionToken.Status;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
|
@ -1660,10 +1672,15 @@ HttpTcpReceiveHeader (
|
|||
return Status;
|
||||
}
|
||||
|
||||
while (!HttpInstance->IsRxDone) {
|
||||
while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
|
||||
Tcp6->Poll (Tcp6);
|
||||
}
|
||||
|
||||
if (!HttpInstance->IsRxDone) {
|
||||
gBS->CloseEvent (Rx6Token->CompletionToken.Event);
|
||||
Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
|
||||
}
|
||||
|
||||
Status = Rx6Token->CompletionToken.Status;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
|
@ -1715,6 +1732,7 @@ HttpTcpReceiveHeader (
|
|||
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
@param[in] HttpMsg The HTTP message data.
|
||||
@param[in] Timeout The time to wait for receiving the body packet.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP body is received.
|
||||
@retval Others Other error as indicated.
|
||||
|
@ -1723,7 +1741,8 @@ HttpTcpReceiveHeader (
|
|||
EFI_STATUS
|
||||
HttpTcpReceiveBody (
|
||||
IN HTTP_TOKEN_WRAP *Wrap,
|
||||
IN EFI_HTTP_MESSAGE *HttpMsg
|
||||
IN EFI_HTTP_MESSAGE *HttpMsg,
|
||||
IN EFI_EVENT Timeout
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -1739,7 +1758,6 @@ HttpTcpReceiveBody (
|
|||
Rx4Token = NULL;
|
||||
Rx6Token = NULL;
|
||||
|
||||
|
||||
if (HttpInstance->LocalAddressIsIPv6) {
|
||||
ASSERT (Tcp6 != NULL);
|
||||
} else {
|
||||
|
@ -1759,6 +1777,16 @@ HttpTcpReceiveBody (
|
|||
return Status;
|
||||
}
|
||||
|
||||
while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
|
||||
Tcp6->Poll (Tcp6);
|
||||
}
|
||||
|
||||
if (!Wrap->TcpWrap.IsRxDone) {
|
||||
gBS->CloseEvent (Rx6Token->CompletionToken.Event);
|
||||
Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
|
||||
Wrap->HttpToken->Status = Rx6Token->CompletionToken.Status;
|
||||
gBS->SignalEvent (Wrap->HttpToken->Event);
|
||||
}
|
||||
} else {
|
||||
Rx4Token = &Wrap->TcpWrap.Rx4Token;
|
||||
Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;
|
||||
|
@ -1771,6 +1799,17 @@ HttpTcpReceiveBody (
|
|||
DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
while (!Wrap->TcpWrap.IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
|
||||
Tcp4->Poll (Tcp4);
|
||||
}
|
||||
|
||||
if (!Wrap->TcpWrap.IsRxDone) {
|
||||
gBS->CloseEvent (Rx4Token->CompletionToken.Event);
|
||||
Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
|
||||
Wrap->HttpToken->Status = Rx4Token->CompletionToken.Status;
|
||||
gBS->SignalEvent (Wrap->HttpToken->Event);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
|
|
@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#define HTTP_BUFFER_SIZE_DEAULT 65535
|
||||
#define HTTP_MAX_SYN_BACK_LOG 5
|
||||
#define HTTP_CONNECTION_TIMEOUT 60
|
||||
#define HTTP_RESPONSE_TIMEOUT 5
|
||||
#define HTTP_DATA_RETRIES 12
|
||||
#define HTTP_FIN_TIMEOUT 2
|
||||
#define HTTP_KEEP_ALIVE_PROBES 6
|
||||
|
@ -93,6 +94,8 @@ typedef struct _HTTP_PROTOCOL {
|
|||
|
||||
UINTN StatusCode;
|
||||
|
||||
EFI_EVENT TimeoutEvent;
|
||||
|
||||
EFI_HANDLE Tcp4ChildHandle;
|
||||
EFI_TCP4_PROTOCOL *Tcp4;
|
||||
EFI_TCP4_CONFIG_DATA Tcp4CfgData;
|
||||
|
@ -117,8 +120,6 @@ typedef struct _HTTP_PROTOCOL {
|
|||
BOOLEAN IsTcp6CloseDone;
|
||||
EFI_IPv6_ADDRESS RemoteIpv6Addr;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Rx4Token or Rx6Token used for receiving HTTP header.
|
||||
//
|
||||
|
@ -504,6 +505,7 @@ HttpTcpReceive (
|
|||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in, out] SizeofHeaders The HTTP header length.
|
||||
@param[in, out] BufferSize The size of buffer to cacahe the header message.
|
||||
@param[in] Timeout The time to wait for receiving the header packet.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP header is received.
|
||||
@retval Others Other errors as indicated.
|
||||
|
@ -513,7 +515,8 @@ EFI_STATUS
|
|||
HttpTcpReceiveHeader (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN OUT UINTN *SizeofHeaders,
|
||||
IN OUT UINTN *BufferSize
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN EFI_EVENT Timeout
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -521,6 +524,7 @@ HttpTcpReceiveHeader (
|
|||
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
@param[in] HttpMsg The HTTP message data.
|
||||
@param[in] Timeout The time to wait for receiving the body packet.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP body is received.
|
||||
@retval Others Other error as indicated.
|
||||
|
@ -529,7 +533,8 @@ HttpTcpReceiveHeader (
|
|||
EFI_STATUS
|
||||
HttpTcpReceiveBody (
|
||||
IN HTTP_TOKEN_WRAP *Wrap,
|
||||
IN EFI_HTTP_MESSAGE *HttpMsg
|
||||
IN EFI_HTTP_MESSAGE *HttpMsg,
|
||||
IN EFI_EVENT Timeout
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue