/** @file\r
Support functions implementation for UEFI HTTP boot driver.\r
\r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution. \r
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php. \r
\r
}\r
}\r
\r
+/**\r
+ This function is to display the HTTP error status.\r
+\r
+ @param[in] StatusCode The status code value in HTTP message.\r
+\r
+**/\r
+VOID\r
+HttpBootPrintErrorMessage (\r
+ EFI_HTTP_STATUS_CODE StatusCode\r
+ )\r
+{\r
+ AsciiPrint ("\n");\r
+\r
+ switch (StatusCode) {\r
+ case HTTP_STATUS_300_MULTIPLE_CHIOCES:\r
+ AsciiPrint ("\n Redirection: 300 Multiple Choices");\r
+ break; \r
+ \r
+ case HTTP_STATUS_301_MOVED_PERMANENTLY:\r
+ AsciiPrint ("\n Redirection: 301 Moved Permanently");\r
+ break; \r
+ \r
+ case HTTP_STATUS_302_FOUND:\r
+ AsciiPrint ("\n Redirection: 302 Found");\r
+ break; \r
+ \r
+ case HTTP_STATUS_303_SEE_OTHER:\r
+ AsciiPrint ("\n Redirection: 303 See Other");\r
+ break; \r
+\r
+ case HTTP_STATUS_304_NOT_MODIFIED:\r
+ AsciiPrint ("\n Redirection: 304 Not Modified");\r
+ break; \r
+\r
+ case HTTP_STATUS_305_USE_PROXY:\r
+ AsciiPrint ("\n Redirection: 305 Use Proxy");\r
+ break; \r
+\r
+ case HTTP_STATUS_307_TEMPORARY_REDIRECT:\r
+ AsciiPrint ("\n Redirection: 307 Temporary Redirect");\r
+ break; \r
+\r
+ case HTTP_STATUS_400_BAD_REQUEST:\r
+ AsciiPrint ("\n Client Error: 400 Bad Request");\r
+ break;\r
+ \r
+ case HTTP_STATUS_401_UNAUTHORIZED:\r
+ AsciiPrint ("\n Client Error: 401 Unauthorized");\r
+ break;\r
+ \r
+ case HTTP_STATUS_402_PAYMENT_REQUIRED:\r
+ AsciiPrint ("\n Client Error: 402 Payment Required");\r
+ break;\r
+\r
+ case HTTP_STATUS_403_FORBIDDEN:\r
+ AsciiPrint ("\n Client Error: 403 Forbidden");\r
+ break;\r
+\r
+ case HTTP_STATUS_404_NOT_FOUND:\r
+ AsciiPrint ("\n Client Error: 404 Not Found");\r
+ break;\r
+\r
+ case HTTP_STATUS_405_METHOD_NOT_ALLOWED:\r
+ AsciiPrint ("\n Client Error: 405 Method Not Allowed");\r
+ break;\r
+\r
+ case HTTP_STATUS_406_NOT_ACCEPTABLE:\r
+ AsciiPrint ("\n Client Error: 406 Not Acceptable");\r
+ break;\r
+\r
+ case HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED:\r
+ AsciiPrint ("\n Client Error: 407 Proxy Authentication Required");\r
+ break;\r
+\r
+ case HTTP_STATUS_408_REQUEST_TIME_OUT:\r
+ AsciiPrint ("\n Client Error: 408 Request Timeout");\r
+ break;\r
+\r
+ case HTTP_STATUS_409_CONFLICT:\r
+ AsciiPrint ("\n Client Error: 409 Conflict");\r
+ break;\r
+\r
+ case HTTP_STATUS_410_GONE:\r
+ AsciiPrint ("\n Client Error: 410 Gone");\r
+ break;\r
+\r
+ case HTTP_STATUS_411_LENGTH_REQUIRED:\r
+ AsciiPrint ("\n Client Error: 411 Length Required");\r
+ break;\r
+\r
+ case HTTP_STATUS_412_PRECONDITION_FAILED:\r
+ AsciiPrint ("\n Client Error: 412 Precondition Failed");\r
+ break;\r
+\r
+ case HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE:\r
+ AsciiPrint ("\n Client Error: 413 Request Entity Too Large");\r
+ break;\r
+\r
+ case HTTP_STATUS_414_REQUEST_URI_TOO_LARGE:\r
+ AsciiPrint ("\n Client Error: 414 Request URI Too Long");\r
+ break;\r
+\r
+ case HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE:\r
+ AsciiPrint ("\n Client Error: 415 Unsupported Media Type");\r
+ break;\r
+\r
+ case HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED:\r
+ AsciiPrint ("\n Client Error: 416 Requested Range Not Satisfiable");\r
+ break;\r
+\r
+ case HTTP_STATUS_417_EXPECTATION_FAILED:\r
+ AsciiPrint ("\n Client Error: 417 Expectation Failed");\r
+ break;\r
+\r
+ case HTTP_STATUS_500_INTERNAL_SERVER_ERROR:\r
+ AsciiPrint ("\n Server Error: 500 Internal Server Error");\r
+ break;\r
+\r
+ case HTTP_STATUS_501_NOT_IMPLEMENTED:\r
+ AsciiPrint ("\n Server Error: 501 Not Implemented");\r
+ break;\r
+\r
+ case HTTP_STATUS_502_BAD_GATEWAY:\r
+ AsciiPrint ("\n Server Error: 502 Bad Gateway");\r
+ break;\r
+\r
+ case HTTP_STATUS_503_SERVICE_UNAVAILABLE:\r
+ AsciiPrint ("\n Server Error: 503 Service Unavailable");\r
+ break;\r
+\r
+ case HTTP_STATUS_504_GATEWAY_TIME_OUT:\r
+ AsciiPrint ("\n Server Error: 504 Gateway Timeout");\r
+ break;\r
+\r
+ case HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED:\r
+ AsciiPrint ("\n Server Error: 505 HTTP Version Not Supported");\r
+ break;\r
+\r
+ default: ;\r
+ \r
+ }\r
+}\r
+\r
/**\r
Notify the callback function when an event is triggered.\r
\r
}\r
}\r
\r
-/**\r
- Find a specified header field according to the field name.\r
-\r
- @param[in] HeaderCount Number of HTTP header structures in Headers list. \r
- @param[in] Headers Array containing list of HTTP headers.\r
- @param[in] FieldName Null terminated string which describes a field name. \r
-\r
- @return Pointer to the found header or NULL.\r
-\r
-**/\r
-EFI_HTTP_HEADER *\r
-HttpBootFindHeader (\r
- IN UINTN HeaderCount,\r
- IN EFI_HTTP_HEADER *Headers,\r
- IN CHAR8 *FieldName\r
- )\r
-{\r
- UINTN Index;\r
- \r
- if (HeaderCount == 0 || Headers == NULL || FieldName == NULL) {\r
- return NULL;\r
- }\r
-\r
- for (Index = 0; Index < HeaderCount; Index++){\r
- //\r
- // Field names are case-insensitive (RFC 2616).\r
- //\r
- if (AsciiStriCmp (Headers[Index].FieldName, FieldName) == 0) {\r
- return &Headers[Index];\r
- }\r
- }\r
- return NULL;\r
-}\r
-\r
/**\r
Set or update a HTTP header with the field name and corresponding value.\r
\r
@param[in] HttpIoHeader Point to the HTTP header holder.\r
- @param[in] FieldName Null terminated string which describes a field name. \r
+ @param[in] FieldName Null terminated string which describes a field name.\r
@param[in] FieldValue Null terminated string which describes the corresponding field value.\r
\r
@retval EFI_SUCCESS The HTTP header has been set or updated.\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Header = HttpBootFindHeader (HttpIoHeader->HeaderCount, HttpIoHeader->Headers, FieldName);\r
+ Header = HttpFindHeader (HttpIoHeader->HeaderCount, HttpIoHeader->Headers, FieldName);\r
if (Header == NULL) {\r
//\r
// Add a new header.\r
FALSE to continue receive the previous response message.\r
@param[out] ResponseData Point to a wrapper of the received response data.\r
\r
- @retval EFI_SUCCESS The HTTP resopnse is received.\r
+ @retval EFI_SUCCESS The HTTP response is received.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.\r
HttpIoRecvResponse (\r
IN HTTP_IO *HttpIo,\r
IN BOOLEAN RecvMsgHeader,\r
- OUT HTTP_IO_RESOPNSE_DATA *ResponseData\r
+ OUT HTTP_IO_RESPONSE_DATA *ResponseData\r
)\r
{\r
EFI_STATUS Status;\r
}\r
\r
//\r
- // Poll the network until transmit finish.\r
+ // Poll the network until receive finish.\r
//\r
while (!HttpIo->IsRxDone) {\r
Http->Poll (Http);\r
//\r
// Store the received data into the wrapper.\r
//\r
- Status = HttpIo->RspToken.Status;\r
- if (!EFI_ERROR (Status)) {\r
- ResponseData->HeaderCount = HttpIo->RspToken.Message->HeaderCount;\r
- ResponseData->Headers = HttpIo->RspToken.Message->Headers;\r
- ResponseData->BodyLength = HttpIo->RspToken.Message->BodyLength;\r
- }\r
+ ResponseData->Status = HttpIo->RspToken.Status;\r
+ ResponseData->HeaderCount = HttpIo->RspToken.Message->HeaderCount;\r
+ ResponseData->Headers = HttpIo->RspToken.Message->Headers;\r
+ ResponseData->BodyLength = HttpIo->RspToken.Message->BodyLength;\r
\r
return Status;\r
}\r
+\r
+/**\r
+ Get the URI address string from the input device path.\r
+\r
+ Caller need to free the buffer in the UriAddress pointer.\r
+ \r
+ @param[in] FilePath Pointer to the device path which contains a URI device path node.\r
+ @param[in] UriAddress The URI address string extract from the device path.\r
+ \r
+ @retval EFI_SUCCESS The URI string is returned.\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpBootParseFilePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ OUT CHAR8 **UriAddress\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ URI_DEVICE_PATH *UriDevicePath;\r
+ CHAR8 *Uri;\r
+ UINTN UriStrLength;\r
+\r
+ if (FilePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *UriAddress = NULL;\r
+\r
+ //\r
+ // Extract the URI address from the FilePath\r
+ //\r
+ TempDevicePath = FilePath;\r
+ while (!IsDevicePathEnd (TempDevicePath)) {\r
+ if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (TempDevicePath) == MSG_URI_DP)) {\r
+ UriDevicePath = (URI_DEVICE_PATH*) TempDevicePath;\r
+ //\r
+ // UEFI Spec doesn't require the URI to be a NULL-terminated string\r
+ // So we allocate a new buffer and always append a '\0' to it.\r
+ //\r
+ UriStrLength = DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
+ if (UriStrLength == 0) {\r
+ //\r
+ // return a NULL UriAddress if it's a empty URI device path node.\r
+ //\r
+ break;\r
+ }\r
+ Uri = AllocatePool (UriStrLength + 1);\r
+ if (Uri == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (Uri, UriDevicePath->Uri, DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL));\r
+ Uri[DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL)] = '\0';\r
+\r
+ *UriAddress = Uri;\r
+ }\r
+ TempDevicePath = NextDevicePathNode (TempDevicePath);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r