\r
if (UsingIpv6) {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
+ Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;\r
\r
if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {\r
+ DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
+\r
+ Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
+ if (Item != NULL) {\r
+ NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
+ }\r
+ \r
FreePool (Wrap);\r
+ Wrap = NULL;\r
+ \r
return ;\r
}\r
\r
} else {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
+ Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;\r
\r
if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {\r
+ DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
+ \r
+ Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
+ if (Item != NULL) {\r
+ NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
+ }\r
+ \r
FreePool (Wrap);\r
+ Wrap = NULL;\r
+ \r
return ;\r
}\r
}\r
// Check pending RxTokens and receive the HTTP message.\r
//\r
NetMapIterate (&Wrap->HttpInstance->RxTokens, HttpTcpReceive, NULL);\r
- \r
+\r
FreePool (Wrap);\r
+ Wrap = NULL;\r
}\r
\r
/**\r
Wrap,\r
&TcpWrap->Tx4Token.CompletionToken.Event\r
);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- \r
- TcpWrap->Tx4Data.Push = TRUE;\r
- TcpWrap->Tx4Data.Urgent = FALSE;\r
- TcpWrap->Tx4Data.FragmentCount = 1;\r
- TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;\r
- TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ TcpWrap->Tx4Data.Push = TRUE;\r
+ TcpWrap->Tx4Data.Urgent = FALSE;\r
+ TcpWrap->Tx4Data.FragmentCount = 1;\r
+ TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;\r
+ TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;\r
\r
} else {\r
Status = gBS->CreateEvent (\r
TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
\r
- \r
}\r
\r
return EFI_SUCCESS;\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
return Status;\r
}\r
\r
-/**\r
- Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined \r
- in UEFI 2.5 specification.\r
-\r
- @param[in] StatusCode The status code value in HTTP message.\r
-\r
- @return Value defined in EFI_HTTP_STATUS_CODE .\r
-\r
-**/\r
-EFI_HTTP_STATUS_CODE\r
-HttpMappingToStatusCode (\r
- IN UINTN StatusCode\r
- ) \r
-{\r
- switch (StatusCode) {\r
- case 100:\r
- return HTTP_STATUS_100_CONTINUE;\r
- case 101:\r
- return HTTP_STATUS_101_SWITCHING_PROTOCOLS;\r
- case 200:\r
- return HTTP_STATUS_200_OK;\r
- case 201:\r
- return HTTP_STATUS_201_CREATED;\r
- case 202:\r
- return HTTP_STATUS_202_ACCEPTED;\r
- case 203:\r
- return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION;\r
- case 204:\r
- return HTTP_STATUS_204_NO_CONTENT;\r
- case 205:\r
- return HTTP_STATUS_205_RESET_CONTENT;\r
- case 206:\r
- return HTTP_STATUS_206_PARTIAL_CONTENT;\r
- case 300:\r
- return HTTP_STATUS_300_MULTIPLE_CHIOCES;\r
- case 301:\r
- return HTTP_STATUS_301_MOVED_PERMANENTLY;\r
- case 302:\r
- return HTTP_STATUS_302_FOUND;\r
- case 303:\r
- return HTTP_STATUS_303_SEE_OTHER;\r
- case 304:\r
- return HTTP_STATUS_304_NOT_MODIFIED;\r
- case 305:\r
- return HTTP_STATUS_305_USE_PROXY;\r
- case 307:\r
- return HTTP_STATUS_307_TEMPORARY_REDIRECT;\r
- case 400:\r
- return HTTP_STATUS_400_BAD_REQUEST;\r
- case 401:\r
- return HTTP_STATUS_401_UNAUTHORIZED;\r
- case 402:\r
- return HTTP_STATUS_402_PAYMENT_REQUIRED;\r
- case 403:\r
- return HTTP_STATUS_403_FORBIDDEN;\r
- case 404:\r
- return HTTP_STATUS_404_NOT_FOUND;\r
- case 405:\r
- return HTTP_STATUS_405_METHOD_NOT_ALLOWED;\r
- case 406:\r
- return HTTP_STATUS_406_NOT_ACCEPTABLE;\r
- case 407:\r
- return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED;\r
- case 408:\r
- return HTTP_STATUS_408_REQUEST_TIME_OUT;\r
- case 409:\r
- return HTTP_STATUS_409_CONFLICT;\r
- case 410:\r
- return HTTP_STATUS_410_GONE;\r
- case 411:\r
- return HTTP_STATUS_411_LENGTH_REQUIRED;\r
- case 412:\r
- return HTTP_STATUS_412_PRECONDITION_FAILED;\r
- case 413:\r
- return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE;\r
- case 414:\r
- return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE;\r
- case 415:\r
- return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE;\r
- case 416:\r
- return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;\r
- case 417:\r
- return HTTP_STATUS_417_EXPECTATION_FAILED;\r
- case 500:\r
- return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;\r
- case 501:\r
- return HTTP_STATUS_501_NOT_IMPLEMENTED;\r
- case 502:\r
- return HTTP_STATUS_502_BAD_GATEWAY;\r
- case 503:\r
- return HTTP_STATUS_503_SERVICE_UNAVAILABLE;\r
- case 504:\r
- return HTTP_STATUS_504_GATEWAY_TIME_OUT;\r
- case 505:\r
- return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED;\r
-\r
- default:\r
- return HTTP_STATUS_UNSUPPORTED_STATUS;\r
- }\r
-}\r
-\r
/**\r
Check whether the user's token or event has already\r
been enqueue on HTTP Tx or Rx Token list.\r
{\r
HTTP_TOKEN_WRAP *ValueInItem;\r
EFI_STATUS Status;\r
- CHAR8 *RequestStr;\r
+ CHAR8 *RequestMsg;\r
CHAR8 *Url;\r
+ UINTN RequestMsgSize;\r
\r
ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value;\r
if (ValueInItem->TcpWrap.IsTxDone) {\r
//\r
// Create request message.\r
//\r
- RequestStr = HttpGenRequestString (\r
- ValueInItem->HttpInstance,\r
+ Status = HttpGenRequestMessage (\r
ValueInItem->HttpToken->Message,\r
- Url\r
+ Url,\r
+ &RequestMsg,\r
+ &RequestMsgSize\r
);\r
FreePool (Url);\r
- if (RequestStr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+\r
+ if (EFI_ERROR (Status)){\r
+ return Status;\r
}\r
\r
//\r
Status = HttpTransmitTcp (\r
ValueInItem->HttpInstance,\r
ValueInItem,\r
- (UINT8*) RequestStr,\r
- AsciiStrLen (RequestStr)\r
+ (UINT8*) RequestMsg,\r
+ RequestMsgSize\r
);\r
- FreePool (RequestStr);\r
+ FreePool (RequestMsg);\r
return Status;\r
}\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
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
+ //\r
+ // Cancle the Token before close its Event.\r
+ //\r
+ Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);\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
+ //\r
+ // Cancle the Token before close its Event.\r
+ //\r
+ Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);\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
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
} else {\r
Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
Rx6Token = NULL;\r
\r
if (HttpInstance->LocalAddressIsIPv6) {\r
- if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
- gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
- }\r
-\r
Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
- if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
- FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+ \r
+ if (Rx6Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+ Rx6Token->CompletionToken.Event = NULL;\r
}\r
- FreePool (Wrap);\r
\r
- if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {\r
- gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);\r
- HttpInstance->Rx6Token.CompletionToken.Event = NULL;\r
- }\r
+ FreePool (Wrap);\r
\r
Rx6Token = &HttpInstance->Rx6Token;\r
+ \r
+ if (Rx6Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
+ Rx6Token->CompletionToken.Event = NULL;\r
+ }\r
+ \r
if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
}\r
\r
} else {\r
- if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
- gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
- }\r
Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
- if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
- FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
+ \r
+ if (Rx4Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+ Rx4Token->CompletionToken.Event = NULL;\r
}\r
+ \r
FreePool (Wrap);\r
\r
- if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
- gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
- HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
+ Rx4Token = &HttpInstance->Rx4Token;\r
+\r
+ if (Rx4Token->CompletionToken.Event != NULL) {\r
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
+ Rx4Token->CompletionToken.Event = NULL;\r
}\r
\r
- Rx4Token = &HttpInstance->Rx4Token;\r
+ \r
if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
}\r
\r
}\r
-\r
-/**\r
- Generate HTTP request string.\r
-\r
- @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
- @param[in] Message Pointer to storage containing HTTP message data.\r
- @param[in] Url The URL of a remote host.\r
-\r
- @return Pointer to the created HTTP request string.\r
- @return NULL if any error occured.\r
-\r
-**/\r
-CHAR8 *\r
-HttpGenRequestString (\r
- IN HTTP_PROTOCOL *HttpInstance,\r
- IN EFI_HTTP_MESSAGE *Message,\r
- IN CHAR8 *Url\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN StrLength;\r
- UINT8 *Request;\r
- UINT8 *RequestPtr;\r
- UINTN HttpHdrSize;\r
- UINTN MsgSize;\r
- BOOLEAN Success;\r
- VOID *HttpHdr;\r
- EFI_HTTP_HEADER **AppendList; \r
- UINTN Index;\r
- \r
- ASSERT (HttpInstance != NULL);\r
- ASSERT (Message != NULL);\r
-\r
- DEBUG ((EFI_D_ERROR, "HttpMethod - %x\n", Message->Data.Request->Method));\r
-\r
- Request = NULL;\r
- Success = FALSE;\r
- HttpHdr = NULL;\r
- AppendList = NULL;\r
-\r
- //\r
- // Build AppendList\r
- //\r
- AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));\r
- if (AppendList == NULL) {\r
- return NULL;\r
- }\r
-\r
- for(Index = 0; Index < Message->HeaderCount; Index++){\r
- AppendList[Index] = &Message->Headers[Index];\r
- }\r
-\r
- //\r
- // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available.\r
- //\r
- if (mHttpUtilities == NULL) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Build raw unformatted HTTP headers.\r
- //\r
- Status = mHttpUtilities->Build (\r
- mHttpUtilities,\r
- 0,\r
- NULL,\r
- 0,\r
- NULL,\r
- Message->HeaderCount,\r
- AppendList,\r
- &HttpHdrSize,\r
- &HttpHdr\r
- );\r
- FreePool (AppendList);\r
- if (EFI_ERROR (Status) || HttpHdr == NULL) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Calculate HTTP message length.\r
- //\r
- MsgSize = Message->BodyLength + HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (Url) +\r
- AsciiStrLen (HTTP_VERSION_CRLF_STR) + HttpHdrSize;\r
- Request = AllocateZeroPool (MsgSize);\r
- if (Request == NULL) {\r
- goto Exit;\r
- } \r
-\r
- RequestPtr = Request;\r
- //\r
- // Construct header request\r
- //\r
- switch (Message->Data.Request->Method) {\r
- case HttpMethodGet:\r
- StrLength = sizeof (HTTP_METHOD_GET) - 1;\r
- CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);\r
- RequestPtr += StrLength;\r
- break;\r
- case HttpMethodHead:\r
- StrLength = sizeof (HTTP_METHOD_HEAD) - 1;\r
- CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);\r
- RequestPtr += StrLength;\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- goto Exit;\r
- }\r
-\r
- StrLength = AsciiStrLen(" ");\r
- CopyMem (RequestPtr, " ", StrLength);\r
- RequestPtr += StrLength;\r
-\r
- StrLength = AsciiStrLen (Url);\r
- CopyMem (RequestPtr, Url, StrLength);\r
- RequestPtr += StrLength;\r
-\r
- StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;\r
- CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);\r
- RequestPtr += StrLength;\r
-\r
- //\r
- // Construct header\r
- //\r
- CopyMem (RequestPtr, HttpHdr, HttpHdrSize);\r
- RequestPtr += HttpHdrSize;\r
-\r
- //\r
- // Construct body\r
- //\r
- if (Message->Body != NULL) {\r
- CopyMem (RequestPtr, Message->Body, Message->BodyLength);\r
- RequestPtr += Message->BodyLength;\r
- }\r
-\r
- //\r
- // Done\r
- //\r
- *RequestPtr = 0;\r
- Success = TRUE;\r
- \r
-Exit:\r
-\r
- if (!Success) {\r
- if (Request != NULL) {\r
- FreePool (Request);\r
- }\r
-\r
- Request = NULL;\r
- }\r
-\r
- if (HttpHdr != NULL) {\r
- FreePool (HttpHdr);\r
- }\r
-\r
- return (CHAR8*) Request;\r
-}\r