/** @file\r
Implementation of EFI_HTTP_PROTOCOL protocol interfaces.\r
\r
- Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
\r
This program and the accompanying materials\r
\r
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.\r
@param[out] HttpConfigData Point to buffer for operational parameters of this\r
- HTTP instance.\r
+ HTTP instance. It is the responsibility of the caller \r
+ to allocate the memory for HttpConfigData and \r
+ HttpConfigData->AccessPoint.IPv6Node/IPv4Node. In fact, \r
+ it is recommended to allocate sufficient memory to record \r
+ IPv6Node since it is big enough for all possibilities. \r
\r
@retval EFI_SUCCESS Operation succeeded.\r
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
This is NULL.\r
HttpConfigData is NULL.\r
- HttpInstance->LocalAddressIsIPv6 is FALSE and\r
- HttpConfigData->IPv4Node is NULL.\r
- HttpInstance->LocalAddressIsIPv6 is TRUE and\r
- HttpConfigData->IPv6Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv4Node or \r
+ HttpConfigData->AccessPoint.IPv6Node is NULL.\r
@retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.\r
\r
**/\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
- if ((HttpInstance->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
- (!HttpInstance->LocalAddressIsIPv6 && HttpConfigData->AccessPoint.IPv4Node == NULL)) {\r
+ if ((HttpConfigData->AccessPoint.IPv6Node == NULL) ||\r
+ (HttpConfigData->AccessPoint.IPv4Node == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
This is NULL.\r
HttpConfigData->LocalAddressIsIPv6 is FALSE and\r
- HttpConfigData->IPv4Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv4Node is NULL.\r
HttpConfigData->LocalAddressIsIPv6 is TRUE and\r
- HttpConfigData->IPv6Node is NULL.\r
+ HttpConfigData->AccessPoint.IPv6Node is NULL.\r
@retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling\r
Configure() with NULL to reset it.\r
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
EFIAPI\r
EfiHttpConfigure (\r
IN EFI_HTTP_PROTOCOL *This,\r
- IN EFI_HTTP_CONFIG_DATA *HttpConfigData\r
+ IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL\r
) \r
{\r
HTTP_PROTOCOL *HttpInstance;\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL && HttpInstance->Service != NULL);\r
+ ASSERT (HttpInstance->Service != NULL);\r
\r
if (HttpConfigData != NULL) {\r
\r
+ if (HttpConfigData->HttpVersion >= HttpVersionUnsupported) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
//\r
// Now configure this HTTP instance.\r
//\r
HTTP_TOKEN_WRAP *Wrap;\r
CHAR8 *FileUrl;\r
UINTN RequestMsgSize;\r
+ EFI_HANDLE ImageHandle;\r
\r
//\r
// Initializations\r
Request = HttpMsg->Data.Request;\r
\r
//\r
- // Only support GET, HEAD, PUT and POST method in current implementation.\r
+ // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation.\r
//\r
if ((Request != NULL) && (Request->Method != HttpMethodGet) &&\r
- (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost)) {\r
+ (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) && \r
+ (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) && \r
+ (Request->Method != HttpMethodPatch)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
//\r
// Capture the method into HttpInstance.\r
\r
if (Request == NULL) {\r
//\r
- // Request would be NULL only for PUT/POST operation (in the current implementation)\r
+ // Request would be NULL only for PUT/POST/PATCH operation (in the current implementation)\r
//\r
- if ((HttpInstance->Method != HttpMethodPut) && (HttpInstance->Method != HttpMethodPost)) {\r
+ if ((HttpInstance->Method != HttpMethodPut) && \r
+ (HttpInstance->Method != HttpMethodPost) && \r
+ (HttpInstance->Method != HttpMethodPatch)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
- // For PUT/POST, we need to have the TCP already configured. Bail out if it is not!\r
+ // For PUT/POST/PATCH, we need to have the TCP already configured. Bail out if it is not!\r
//\r
if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED) {\r
return EFI_INVALID_PARAMETER;\r
//\r
HttpInstance->UseHttps = IsHttpsUrl (Url);\r
\r
+ //\r
+ // HTTP is disabled, return directly if the URI is not HTTPS.\r
+ //\r
+ if (!PcdGetBool (PcdAllowHttpConnections) && !(HttpInstance->UseHttps)) {\r
+ \r
+ DEBUG ((EFI_D_ERROR, "EfiHttpRequest: HTTP is disabled.\n"));\r
+\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
//\r
// Check whether we need to create Tls child and open the TLS protocol.\r
//\r
//\r
// Use TlsSb to create Tls child and open the TLS protocol.\r
//\r
+ if (HttpInstance->LocalAddressIsIPv6) {\r
+ ImageHandle = HttpInstance->Service->Ip6DriverBindingHandle;\r
+ } else {\r
+ ImageHandle = HttpInstance->Service->Ip4DriverBindingHandle;\r
+ }\r
+\r
HttpInstance->TlsChildHandle = TlsCreateChild (\r
- HttpInstance->Service->ImageHandle,\r
+ ImageHandle,\r
+ &(HttpInstance->TlsSb),\r
&(HttpInstance->Tls),\r
&(HttpInstance->TlsConfiguration)\r
);\r
\r
FreePool (HostName);\r
\r
+ HttpUrlFreeParser (UrlParser);\r
+\r
//\r
// Queue the HTTP token and return.\r
//\r
\r
FreePool (HostNameStr);\r
if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Error: Could not retrieve the host address from DNS server.\n"));\r
goto Error1;\r
}\r
}\r
\r
Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);\r
\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) || NULL == RequestMsg) {\r
goto Error3;\r
}\r
\r
//\r
// Every request we insert a TxToken and a response call would remove the TxToken.\r
- // In cases of PUT/POST, after an initial request-response pair, we would do a\r
+ // In cases of PUT/POST/PATCH, after an initial request-response pair, we would do a\r
// continuous request without a response call. So, in such cases, where Request\r
// structure is NULL, we would not insert a TxToken.\r
//\r
if (HostName != NULL) {\r
FreePool (HostName);\r
}\r
+\r
+ if (UrlParser != NULL) {\r
+ HttpUrlFreeParser (UrlParser);\r
+ }\r
\r
return EFI_SUCCESS;\r
\r
if (Wrap != NULL) {\r
FreePool (Wrap);\r
}\r
- if (UrlParser!= NULL) {\r
+ if (UrlParser != NULL) {\r
HttpUrlFreeParser (UrlParser);\r
}\r
\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r
ValueInItem = NULL;\r
\r
//\r
- // In cases of PUT/POST, after an initial request-response pair, we would do a\r
+ // In cases of PUT/POST/PATCH, after an initial request-response pair, we would do a\r
// continuous request without a response call. So, we would not do an insert of\r
// TxToken. After we have sent the complete file, we will call a response to get\r
// a final response from server. In such a case, we would not have any TxTokens.\r
// We receive part of header of next HTTP msg.\r
//\r
if (HttpInstance->NextMsg != NULL) {\r
- HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg - (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);\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
CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
HttpInstance->CacheOffset = 0;\r
\r
- HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN) (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg->BodyLength));\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
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r
}\r
\r
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);\r
- ASSERT (HttpInstance != NULL);\r
\r
if (HttpInstance->State != HTTP_STATE_TCP_CONNECTED) {\r
return EFI_NOT_STARTED;\r