mirror of https://github.com/acidanthera/audk.git
NetworkPkg: Add HTTP Driver
Add HTTP driver to support HTTP protocols defined in UEFI 2.5 specification. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hp.com> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17855 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
99c048ef4a
commit
47f51a064f
|
@ -0,0 +1,138 @@
|
|||
/** @file
|
||||
Implementation of EFI_COMPONENT_NAME_PROTOCOL and
|
||||
EFI_COMPONENT_NAME2_PROTOCOL protocol.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpDriver.h"
|
||||
|
||||
///
|
||||
/// Component Name Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME_PROTOCOL gHttpDxeComponentName = {
|
||||
(EFI_COMPONENT_NAME_GET_DRIVER_NAME) HttpDxeComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) HttpDxeComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
///
|
||||
/// Component Name 2 Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME2_PROTOCOL gHttpDxeComponentName2 = {
|
||||
HttpDxeComponentNameGetDriverName,
|
||||
HttpDxeComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
///
|
||||
/// Table of driver names
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_UNICODE_STRING_TABLE mHttpDxeDriverNameTable[] = {
|
||||
{ "eng;en", (CHAR16 *) L"HttpDxe" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mHttpDxeDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This != &gHttpDxeComponentName2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/** @file
|
||||
Header file for implementation of UEFI Component Name(2) protocol.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_COMPONENT_NAME_H__
|
||||
#define __EFI_HTTP_COMPONENT_NAME_H__
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,218 @@
|
|||
/** @file
|
||||
Routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpDriver.h"
|
||||
|
||||
/**
|
||||
Retrieve the host address using the EFI_DNS4_PROTOCOL.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
|
||||
@param[in] HostName Pointer to buffer containing hostname.
|
||||
@param[out] IpAddress On output, pointer to buffer containing IPv4 address.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network error occurred.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpDns4 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN CHAR16 *HostName,
|
||||
OUT EFI_IPv4_ADDRESS *IpAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DNS4_PROTOCOL *Dns4;
|
||||
EFI_DNS4_CONFIG_DATA Dns4CfgData;
|
||||
EFI_DNS4_COMPLETION_TOKEN Token;
|
||||
BOOLEAN IsDone;
|
||||
HTTP_SERVICE *Service;
|
||||
EFI_HANDLE Dns4Handle;
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
UINTN DnsServerListCount;
|
||||
EFI_IPv4_ADDRESS *DnsServerList;
|
||||
UINTN DataSize;
|
||||
|
||||
|
||||
Service = HttpInstance->Service;
|
||||
ASSERT (Service != NULL);
|
||||
|
||||
DnsServerList = NULL;
|
||||
DnsServerListCount = 0;
|
||||
ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));
|
||||
|
||||
//
|
||||
// Get DNS server list from EFI IPv4 Configuration II protocol.
|
||||
//
|
||||
Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Get the required size.
|
||||
//
|
||||
DataSize = 0;
|
||||
Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL);
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
DnsServerList = AllocatePool (DataSize);
|
||||
if (DnsServerList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (DnsServerList);
|
||||
DnsServerList = NULL;
|
||||
} else {
|
||||
DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dns4Handle = NULL;
|
||||
Dns4 = NULL;
|
||||
|
||||
//
|
||||
// Create a DNS child instance and get the protocol.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
Service->ControllerHandle,
|
||||
Service->ImageHandle,
|
||||
&gEfiDns4ServiceBindingProtocolGuid,
|
||||
&Dns4Handle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Dns4Handle,
|
||||
&gEfiDns4ProtocolGuid,
|
||||
(VOID **) &Dns4,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Configure DNS4 instance for the DNS server address and protocol.
|
||||
//
|
||||
ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));
|
||||
Dns4CfgData.DnsServerListCount = DnsServerListCount;
|
||||
Dns4CfgData.DnsServerList = DnsServerList;
|
||||
Dns4CfgData.UseDefaultSetting = HttpInstance->IPv4Node.UseDefaultAddress;
|
||||
if (!Dns4CfgData.UseDefaultSetting) {
|
||||
IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &HttpInstance->IPv4Node.LocalAddress);
|
||||
IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);
|
||||
}
|
||||
Dns4CfgData.EnableDnsCache = TRUE;
|
||||
Dns4CfgData.Protocol = EFI_IP_PROTO_UDP;
|
||||
Status = Dns4->Configure (
|
||||
Dns4,
|
||||
&Dns4CfgData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Create event to set the is done flag when name resolution is finished.
|
||||
//
|
||||
ZeroMem (&Token, sizeof (Token));
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
HttpCommonNotify,
|
||||
&IsDone,
|
||||
&Token.Event
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Start asynchronous name resolution.
|
||||
//
|
||||
Token.Status = EFI_NOT_READY;
|
||||
IsDone = FALSE;
|
||||
Status = Dns4->HostNameToIp (Dns4, HostName, &Token);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
while (!IsDone) {
|
||||
Dns4->Poll (Dns4);
|
||||
}
|
||||
|
||||
//
|
||||
// Name resolution is done, check result.
|
||||
//
|
||||
Status = Token.Status;
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if (Token.RspData.H2AData == NULL) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
//
|
||||
// We just return the first IP address from DNS protocol.
|
||||
//
|
||||
IP4_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if (Token.Event != NULL) {
|
||||
gBS->CloseEvent (Token.Event);
|
||||
}
|
||||
if (Token.RspData.H2AData != NULL) {
|
||||
if (Token.RspData.H2AData->IpList != NULL) {
|
||||
FreePool (Token.RspData.H2AData->IpList);
|
||||
}
|
||||
FreePool (Token.RspData.H2AData);
|
||||
}
|
||||
|
||||
if (Dns4 != NULL) {
|
||||
Dns4->Configure (Dns4, NULL);
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Dns4Handle,
|
||||
&gEfiDns4ProtocolGuid,
|
||||
Service->ImageHandle,
|
||||
Service->ControllerHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (Dns4Handle != NULL) {
|
||||
NetLibDestroyServiceChild (
|
||||
Service->ControllerHandle,
|
||||
Service->ImageHandle,
|
||||
&gEfiDns4ServiceBindingProtocolGuid,
|
||||
Dns4Handle
|
||||
);
|
||||
}
|
||||
|
||||
if (DnsServerList != NULL) {
|
||||
FreePool (DnsServerList);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/** @file
|
||||
The header file of routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_DNS_H__
|
||||
#define __EFI_HTTP_DNS_H__
|
||||
|
||||
/**
|
||||
Retrieve the host address using the EFI_DNS4_PROTOCOL.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
|
||||
@param[in] HostName Pointer to buffer containing hostname.
|
||||
@param[out] IpAddress On output, pointer to buffer containing IPv4 address.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network error occurred.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpDns4 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN CHAR16 *HostName,
|
||||
OUT EFI_IPv4_ADDRESS *IpAddress
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,669 @@
|
|||
/** @file
|
||||
The driver binding and service binding protocol for HttpDxe driver.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpDriver.h"
|
||||
|
||||
///
|
||||
/// Driver Binding Protocol instance
|
||||
///
|
||||
EFI_DRIVER_BINDING_PROTOCOL gHttpDxeDriverBinding = {
|
||||
HttpDxeDriverBindingSupported,
|
||||
HttpDxeDriverBindingStart,
|
||||
HttpDxeDriverBindingStop,
|
||||
HTTP_DRIVER_VERSION,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
Create a HTTP driver service binding private instance.
|
||||
|
||||
@param[in] Controller The controller that has TCP4 service binding
|
||||
installed.
|
||||
@param[in] ImageHandle The HTTP driver's image handle.
|
||||
@param[out] ServiceData Point to HTTP driver private instance.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
|
||||
@retval EFI_SUCCESS A new HTTP driver private instance is created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateService (
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT HTTP_SERVICE **ServiceData
|
||||
)
|
||||
{
|
||||
HTTP_SERVICE *HttpService;
|
||||
|
||||
ASSERT (ServiceData != NULL);
|
||||
*ServiceData = NULL;
|
||||
|
||||
HttpService = AllocateZeroPool (sizeof (HTTP_SERVICE));
|
||||
if (HttpService == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
HttpService->Signature = HTTP_SERVICE_SIGNATURE;
|
||||
HttpService->ServiceBinding.CreateChild = HttpServiceBindingCreateChild;
|
||||
HttpService->ServiceBinding.DestroyChild = HttpServiceBindingDestroyChild;
|
||||
HttpService->ImageHandle = ImageHandle;
|
||||
HttpService->ControllerHandle = Controller;
|
||||
HttpService->ChildrenNumber = 0;
|
||||
InitializeListHead (&HttpService->ChildrenList);
|
||||
|
||||
*ServiceData = HttpService;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Release all the resource used the HTTP service binding instance.
|
||||
|
||||
@param HttpService The HTTP private instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpCleanService (
|
||||
IN HTTP_SERVICE *HttpService
|
||||
)
|
||||
{
|
||||
if (HttpService != NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (HttpService->TcpChildHandle != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
HttpService->ImageHandle,
|
||||
HttpService->ControllerHandle
|
||||
);
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
HttpService->ControllerHandle,
|
||||
HttpService->ImageHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
HttpService->TcpChildHandle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This is the declaration of an EFI image entry point. This entry point is
|
||||
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
||||
both device drivers and bus drivers.
|
||||
|
||||
@param ImageHandle The firmware allocated handle for the UEFI image.
|
||||
@param SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval Others An unexpected error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
//
|
||||
// Install UEFI Driver Model protocol(s).
|
||||
//
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gHttpDxeDriverBinding,
|
||||
ImageHandle,
|
||||
&gHttpDxeComponentName,
|
||||
&gHttpDxeComponentName2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Any input parameter is NULL.
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDestroyChildEntryInHandleBuffer (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
UINTN NumberOfChildren;
|
||||
EFI_HANDLE *ChildHandleBuffer;
|
||||
|
||||
if (Entry == NULL || Context == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
HttpInstance = NET_LIST_USER_STRUCT_S (Entry, HTTP_PROTOCOL, Link, HTTP_PROTOCOL_SIGNATURE);
|
||||
ServiceBinding = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
|
||||
NumberOfChildren = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
|
||||
ChildHandleBuffer = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
|
||||
|
||||
if (!NetIsInHandleBuffer (HttpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, HttpInstance->Handle);
|
||||
}
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test for the HttpServiceBinding protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test for the Tcp4 Protocol
|
||||
//
|
||||
return gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
HTTP_SERVICE *HttpService;
|
||||
VOID *Interface;
|
||||
|
||||
//
|
||||
// Test for the Http service binding protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
if (Status == EFI_SUCCESS) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
Status = HttpCreateService (ControllerHandle, This->DriverBindingHandle, &HttpService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (HttpService != NULL);
|
||||
|
||||
//
|
||||
// Create a TCP child instance, but do not configure it. This will establish the parent-child relationship.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
This->DriverBindingHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
&HttpService->TcpChildHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
&Interface,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the HttpServiceBinding Protocol onto Controller
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
&HttpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
if (HttpService != NULL) {
|
||||
HttpCleanService (HttpService);
|
||||
FreePool (HttpService);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_STATUS Status;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
HTTP_SERVICE *HttpService;
|
||||
LIST_ENTRY *List;
|
||||
HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
|
||||
|
||||
//
|
||||
// HTTP driver opens TCP child, So, Controller is a TCP
|
||||
// child handle. Locate the Nic handle first. Then get the
|
||||
// HTTP private data back.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
||||
|
||||
if (!IsListEmpty (&HttpService->ChildrenList)) {
|
||||
//
|
||||
// Destroy the HTTP child instance in ChildHandleBuffer.
|
||||
//
|
||||
List = &HttpService->ChildrenList;
|
||||
Context.ServiceBinding = ServiceBinding;
|
||||
Context.NumberOfChildren = NumberOfChildren;
|
||||
Context.ChildHandleBuffer = ChildHandleBuffer;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
HttpDestroyChildEntryInHandleBuffer,
|
||||
&Context,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && IsListEmpty (&HttpService->ChildrenList)) {
|
||||
gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiHttpServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
);
|
||||
|
||||
HttpCleanService (HttpService);
|
||||
|
||||
FreePool (HttpService);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL, or ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
|
||||
the child.
|
||||
@retval other The child handle was not created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN OUT EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
HTTP_SERVICE *HttpService;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_STATUS Status;
|
||||
VOID *Interface;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
|
||||
HttpInstance = AllocateZeroPool (sizeof (HTTP_PROTOCOL));
|
||||
if (HttpInstance == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Install HTTP protocol onto ChildHandle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiHttpProtocolGuid,
|
||||
&HttpInstance->Http,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
HttpInstance->Handle = *ChildHandle;
|
||||
|
||||
Status = HttpInitProtocol (HttpService, HttpInstance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the default Tcp4 protocol by child.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
(VOID **) &Interface,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
HttpInstance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Add it to the HTTP service's child list.
|
||||
//
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
InsertTailList (&HttpService->ChildrenList, &HttpInstance->Link);
|
||||
HttpService->ChildrenNumber++;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
FreePool (HttpInstance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
HTTP_SERVICE *HttpService;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
EFI_HTTP_PROTOCOL *Http;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiHttpProtocolGuid,
|
||||
(VOID **) &Http,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (Http);
|
||||
if (HttpInstance->Service != HttpService) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (HttpInstance->InDestroy) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the Tcp4 protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
HttpService->TcpChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
gHttpDxeDriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
HttpInstance->InDestroy = TRUE;
|
||||
|
||||
//
|
||||
// Uninstall the HTTP protocol.
|
||||
//
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
ChildHandle,
|
||||
&gEfiHttpProtocolGuid,
|
||||
Http
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
HttpInstance->InDestroy = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
HttpCleanProtocol (HttpInstance);
|
||||
|
||||
RemoveEntryList (&HttpInstance->Link);
|
||||
HttpService->ChildrenNumber--;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
FreePool (HttpInstance);
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
/** @file
|
||||
The header files of the driver binding and service binding protocol for HttpDxe driver.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_DRIVER_H__
|
||||
#define __EFI_HTTP_DRIVER_H__
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
//
|
||||
// Libraries
|
||||
//
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/HttpLib.h>
|
||||
#include <Library/TcpIoLib.h>
|
||||
|
||||
//
|
||||
// UEFI Driver Model Protocols
|
||||
//
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
#include <Protocol/ComponentName2.h>
|
||||
#include <Protocol/ComponentName.h>
|
||||
|
||||
//
|
||||
// Consumed Protocols
|
||||
//
|
||||
#include <Protocol/Tcp4.h>
|
||||
#include <Protocol/Dns4.h>
|
||||
#include <Protocol/Ip4Config2.h>
|
||||
|
||||
//
|
||||
// Produced Protocols
|
||||
//
|
||||
#include <Protocol/Http.h>
|
||||
|
||||
//
|
||||
// Driver Version
|
||||
//
|
||||
#define HTTP_DRIVER_VERSION 0xa
|
||||
|
||||
//
|
||||
// Protocol instances
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gHttpDxeDriverBinding;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gHttpDxeComponentName2;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gHttpDxeComponentName;
|
||||
|
||||
//
|
||||
// Include files with function prototypes
|
||||
//
|
||||
#include "ComponentName.h"
|
||||
#include "HttpImpl.h"
|
||||
#include "HttpProto.h"
|
||||
#include "HttpDns.h"
|
||||
#include "HttpUtilities.h"
|
||||
|
||||
typedef struct {
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
UINTN NumberOfChildren;
|
||||
EFI_HANDLE *ChildHandleBuffer;
|
||||
} HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpDxeDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL, or ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
|
||||
the child.
|
||||
@retval other The child handle was not created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN OUT EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
|
||||
extern EFI_HTTP_PROTOCOL mEfiHttpProtocolTemplete;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
## @file
|
||||
# Implementation of EFI HTTP protocol interfaces.
|
||||
#
|
||||
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = HttpDxe
|
||||
FILE_GUID = 2366c20f-e15a-11e3-8bf1-e4115b28bc50
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = HttpDxeDriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
MODULE_UNI_FILE = HttpDxe.uni
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[Sources]
|
||||
ComponentName.h
|
||||
ComponentName.c
|
||||
HttpDns.h
|
||||
HttpDns.c
|
||||
HttpDriver.h
|
||||
HttpDriver.c
|
||||
HttpImpl.h
|
||||
HttpImpl.c
|
||||
HttpProto.h
|
||||
HttpProto.c
|
||||
HttpUtilities.h
|
||||
HttpUtilities.c
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
BaseLib
|
||||
UefiLib
|
||||
DebugLib
|
||||
NetLib
|
||||
HttpLib
|
||||
|
||||
[Protocols]
|
||||
gEfiHttpServiceBindingProtocolGuid ## BY_START
|
||||
gEfiHttpProtocolGuid ## BY_START
|
||||
gEfiTcp4ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiTcp4ProtocolGuid ## TO_START
|
||||
gEfiDns4ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
HttpDxeExtra.uni
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,239 @@
|
|||
/** @file
|
||||
The header files of implementation of EFI_HTTP_PROTOCOL protocol interfaces.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_IMPL_H__
|
||||
#define __EFI_HTTP_IMPL_H__
|
||||
|
||||
#define HTTP_DEFAULT_PORT 80
|
||||
#define HTTP_END_OF_HDR_STR "\r\n\r\n"
|
||||
#define HTTP_CRLF_STR "\r\n"
|
||||
#define HTTP_VERSION_STR "HTTP/1.1"
|
||||
#define HTTP_VERSION_CRLF_STR " HTTP/1.1\r\n"
|
||||
#define HTTP_GET_STR "GET "
|
||||
#define HTTP_HEAD_STR "HEAD "
|
||||
//
|
||||
// Connect method has maximum length according to EFI_HTTP_METHOD defined in
|
||||
// UEFI2.5 spec so use this.
|
||||
//
|
||||
#define HTTP_MAXIMUM_METHOD_LEN sizeof ("CONNECT")
|
||||
|
||||
/**
|
||||
Returns the operational parameters for the current HTTP child instance.
|
||||
|
||||
The GetModeData() function is used to read the current mode data (operational
|
||||
parameters) for this HTTP protocol instance.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
@param[out] HttpConfigData Point to buffer for operational parameters of this
|
||||
HTTP instance.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL.
|
||||
HttpConfigData is NULL.
|
||||
HttpConfigData->AccessPoint is NULL.
|
||||
@retval EFI_NOT_STARTED The HTTP instance is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpGetModeData (
|
||||
IN EFI_HTTP_PROTOCOL *This,
|
||||
OUT EFI_HTTP_CONFIG_DATA *HttpConfigData
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize or brutally reset the operational parameters for this EFI HTTP instance.
|
||||
|
||||
The Configure() function does the following:
|
||||
When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring
|
||||
timeout, local address, port, etc.
|
||||
When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active
|
||||
connections with remote hosts, canceling all asynchronous tokens, and flush request
|
||||
and response buffers without informing the appropriate hosts.
|
||||
|
||||
Except for GetModeData() and Configure(), No other EFI HTTP function can be executed
|
||||
by this instance until the Configure() function is executed and returns successfully.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
@param[in] HttpConfigData Pointer to the configure data to configure the instance.
|
||||
|
||||
@retval EFI_SUCCESS Operation succeeded.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL.
|
||||
HttpConfigData->LocalAddressIsIPv6 is FALSE and
|
||||
HttpConfigData->IPv4Node is NULL.
|
||||
HttpConfigData->LocalAddressIsIPv6 is TRUE and
|
||||
HttpConfigData->IPv6Node is NULL.
|
||||
@retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling
|
||||
Configure() with NULL to reset it.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when
|
||||
executing Configure().
|
||||
@retval EFI_UNSUPPORTED One or more options in ConfigData are not supported
|
||||
in the implementation.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpConfigure (
|
||||
IN EFI_HTTP_PROTOCOL *This,
|
||||
IN EFI_HTTP_CONFIG_DATA *HttpConfigData
|
||||
);
|
||||
|
||||
/**
|
||||
The Request() function queues an HTTP request to this HTTP instance.
|
||||
|
||||
Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
|
||||
successfully, or if there is an error, Status in token will be updated and Event will
|
||||
be signaled.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
@param[in] Token Pointer to storage containing HTTP request token.
|
||||
|
||||
@retval EFI_SUCCESS Outgoing data was processed.
|
||||
@retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
||||
@retval EFI_UNSUPPORTED The HTTP method is not supported in current
|
||||
implementation.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL.
|
||||
Token->Message is NULL.
|
||||
Token->Message->Body is not NULL,
|
||||
Token->Message->BodyLength is non-zero, and
|
||||
Token->Message->Data is NULL, but a previous call to
|
||||
Request()has not been completed successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpRequest (
|
||||
IN EFI_HTTP_PROTOCOL *This,
|
||||
IN EFI_HTTP_TOKEN *Token
|
||||
);
|
||||
|
||||
/**
|
||||
Abort an asynchronous HTTP request or response token.
|
||||
|
||||
The Cancel() function aborts a pending HTTP request or response transaction. If
|
||||
Token is not NULL and the token is in transmit or receive queues when it is being
|
||||
cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will
|
||||
be signaled. If the token is not in one of the queues, which usually means that the
|
||||
asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL,
|
||||
all asynchronous tokens issued by Request() or Response() will be aborted.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
@param[in] Token Point to storage containing HTTP request or response
|
||||
token.
|
||||
|
||||
@retval EFI_SUCCESS Request and Response queues are successfully flushed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_STARTED This instance hasn't been configured.
|
||||
@retval EFI_NO_MAPPING When using the default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) hasn't finished yet.
|
||||
@retval EFI_NOT_FOUND The asynchronous request or response token is not
|
||||
found.
|
||||
@retval EFI_UNSUPPORTED The implementation does not support this function.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpCancel (
|
||||
IN EFI_HTTP_PROTOCOL *This,
|
||||
IN EFI_HTTP_TOKEN *Token
|
||||
);
|
||||
|
||||
/**
|
||||
The Response() function queues an HTTP response to this HTTP instance, similar to
|
||||
Receive() function in the EFI TCP driver. When the HTTP request is sent successfully,
|
||||
or if there is an error, Status in token will be updated and Event will be signaled.
|
||||
|
||||
The HTTP driver will queue a receive token to the underlying TCP instance. When data
|
||||
is received in the underlying TCP instance, the data will be parsed and Token will
|
||||
be populated with the response data. If the data received from the remote host
|
||||
contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting
|
||||
(asynchronously) for more data to be sent from the remote host before signaling
|
||||
Event in Token.
|
||||
|
||||
It is the responsibility of the caller to allocate a buffer for Body and specify the
|
||||
size in BodyLength. If the remote host provides a response that contains a content
|
||||
body, up to BodyLength bytes will be copied from the receive buffer into Body and
|
||||
BodyLength will be updated with the amount of bytes received and copied to Body. This
|
||||
allows the client to download a large file in chunks instead of into one contiguous
|
||||
block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is
|
||||
non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive
|
||||
token to underlying TCP instance. If data arrives in the receive buffer, up to
|
||||
BodyLength bytes of data will be copied to Body. The HTTP driver will then update
|
||||
BodyLength with the amount of bytes received and copied to Body.
|
||||
|
||||
If the HTTP driver does not have an open underlying TCP connection with the host
|
||||
specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is
|
||||
consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain
|
||||
an open TCP connection between client and host.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
@param[in] Token Pointer to storage containing HTTP response token.
|
||||
|
||||
@retval EFI_SUCCESS Allocation succeeded.
|
||||
@retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been
|
||||
initialized.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL.
|
||||
Token is NULL.
|
||||
Token->Message->Headers is NULL.
|
||||
Token->Message is NULL.
|
||||
Token->Message->Body is not NULL,
|
||||
Token->Message->BodyLength is non-zero, and
|
||||
Token->Message->Data is NULL, but a previous call to
|
||||
Response() has not been completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
||||
@retval EFI_ACCESS_DENIED An open TCP connection is not present with the host
|
||||
specified by response URL.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpResponse (
|
||||
IN EFI_HTTP_PROTOCOL *This,
|
||||
IN EFI_HTTP_TOKEN *Token
|
||||
);
|
||||
|
||||
/**
|
||||
The Poll() function can be used by network drivers and applications to increase the
|
||||
rate that data packets are moved between the communication devices and the transmit
|
||||
and receive queues.
|
||||
|
||||
In some systems, the periodic timer event in the managed network driver may not poll
|
||||
the underlying communications device fast enough to transmit and/or receive all data
|
||||
packets without missing incoming packets or dropping outgoing packets. Drivers and
|
||||
applications that are experiencing packet loss should try calling the Poll() function
|
||||
more often.
|
||||
|
||||
@param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_READY No incoming or outgoing data is processed.
|
||||
@retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiHttpPoll (
|
||||
IN EFI_HTTP_PROTOCOL *This
|
||||
);
|
||||
|
||||
extern EFI_HTTP_PROTOCOL mEfiHttpTemplate;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,457 @@
|
|||
/** @file
|
||||
The header files of miscellaneous routines for HttpDxe driver.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_PROTO_H__
|
||||
#define __EFI_HTTP_PROTO_H__
|
||||
|
||||
#define DEF_BUF_LEN 2048
|
||||
|
||||
#define HTTP_SERVICE_SIGNATURE SIGNATURE_32('H', 't', 't', 'S')
|
||||
|
||||
#define HTTP_SERVICE_FROM_PROTOCOL(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
HTTP_SERVICE, \
|
||||
ServiceBinding, \
|
||||
HTTP_SERVICE_SIGNATURE \
|
||||
)
|
||||
|
||||
//
|
||||
// The state of HTTP protocol. It starts from UNCONFIGED.
|
||||
//
|
||||
#define HTTP_STATE_UNCONFIGED 0
|
||||
#define HTTP_STATE_HTTP_CONFIGED 1
|
||||
#define HTTP_STATE_TCP_CONFIGED 2
|
||||
#define HTTP_STATE_TCP_UNCONFIGED 3
|
||||
#define HTTP_STATE_TCP_CONNECTED 4
|
||||
#define HTTP_STATE_TCP_CLOSED 5
|
||||
|
||||
//
|
||||
// TCP configured data.
|
||||
//
|
||||
#define HTTP_TOS_DEAULT 8
|
||||
#define HTTP_TTL_DEAULT 255
|
||||
#define HTTP_BUFFER_SIZE_DEAULT 65535
|
||||
#define HTTP_MAX_SYN_BACK_LOG 5
|
||||
#define HTTP_CONNECTION_TIMEOUT 60
|
||||
#define HTTP_DATA_RETRIES 12
|
||||
#define HTTP_FIN_TIMEOUT 2
|
||||
#define HTTP_KEEP_ALIVE_PROBES 6
|
||||
#define HTTP_KEEP_ALIVE_TIME 7200
|
||||
#define HTTP_KEEP_ALIVE_INTERVAL 30
|
||||
|
||||
typedef struct _HTTP_SERVICE {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
LIST_ENTRY ChildrenList;
|
||||
UINTN ChildrenNumber;
|
||||
EFI_HANDLE TcpChildHandle;
|
||||
INTN State;
|
||||
} HTTP_SERVICE;
|
||||
|
||||
typedef struct {
|
||||
EFI_TCP4_IO_TOKEN TxToken;
|
||||
EFI_TCP4_TRANSMIT_DATA TxData;
|
||||
BOOLEAN IsTxDone;
|
||||
EFI_TCP4_IO_TOKEN RxToken;
|
||||
EFI_TCP4_RECEIVE_DATA RxData;
|
||||
BOOLEAN IsRxDone;
|
||||
UINTN BodyLen;
|
||||
EFI_HTTP_METHOD Method;
|
||||
} HTTP_TCP_TOKEN_WRAP;
|
||||
|
||||
typedef struct _HTTP_PROTOCOL {
|
||||
UINT32 Signature;
|
||||
EFI_HTTP_PROTOCOL Http;
|
||||
EFI_HANDLE Handle;
|
||||
HTTP_SERVICE *Service;
|
||||
LIST_ENTRY Link; // Link to all HTTP instance from the service.
|
||||
BOOLEAN InDestroy;
|
||||
INTN State;
|
||||
|
||||
EFI_HANDLE TcpChildHandle;
|
||||
EFI_TCP4_PROTOCOL *Tcp4;
|
||||
EFI_TCP4_CONFIG_DATA Tcp4CfgData;
|
||||
EFI_TCP4_OPTION Tcp4Option;
|
||||
|
||||
EFI_TCP4_CONNECTION_TOKEN ConnToken;
|
||||
BOOLEAN IsConnDone;
|
||||
EFI_TCP4_CLOSE_TOKEN CloseToken;
|
||||
BOOLEAN IsCloseDone;
|
||||
|
||||
CHAR8 *RemoteHost;
|
||||
UINT16 RemotePort;
|
||||
EFI_IPv4_ADDRESS RemoteAddr;
|
||||
//
|
||||
// RxToken used for receiving HTTP header.
|
||||
//
|
||||
EFI_TCP4_IO_TOKEN RxToken;
|
||||
EFI_TCP4_RECEIVE_DATA RxData;
|
||||
BOOLEAN IsRxDone;
|
||||
|
||||
CHAR8 *CacheBody;
|
||||
CHAR8 *NextMsg;
|
||||
UINTN CacheLen;
|
||||
UINTN CacheOffset;
|
||||
|
||||
//
|
||||
// HTTP message-body parser.
|
||||
//
|
||||
VOID *MsgParser;
|
||||
|
||||
EFI_HTTP_VERSION HttpVersion;
|
||||
UINT32 TimeOutMillisec;
|
||||
BOOLEAN LocalAddressIsIPv6;
|
||||
|
||||
EFI_HTTPv4_ACCESS_POINT IPv4Node;
|
||||
|
||||
NET_MAP TxTokens;
|
||||
NET_MAP RxTokens;
|
||||
} HTTP_PROTOCOL;
|
||||
|
||||
typedef struct {
|
||||
EFI_HTTP_TOKEN *HttpToken;
|
||||
HTTP_PROTOCOL *HttpInstance;
|
||||
HTTP_TCP_TOKEN_WRAP TcpWrap;
|
||||
} HTTP_TOKEN_WRAP;
|
||||
|
||||
|
||||
#define HTTP_PROTOCOL_SIGNATURE SIGNATURE_32('H', 't', 't', 'P')
|
||||
|
||||
#define HTTP_INSTANCE_FROM_PROTOCOL(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
HTTP_PROTOCOL, \
|
||||
Http, \
|
||||
HTTP_PROTOCOL_SIGNATURE \
|
||||
)
|
||||
|
||||
/**
|
||||
The common notify function used in HTTP driver.
|
||||
|
||||
@param[in] Event The event signaled.
|
||||
@param[in] Context The context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
HttpCommonNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Create events for the TCP4 connection token and TCP4 close token.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
@retval EFI_SUCCESS The events are created successfully.
|
||||
@retval others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4ConnCloseEvent (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Close events in the TCP4 connection token and TCP4 close token.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpCloseTcp4ConnCloseEvent (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 transmit token.
|
||||
|
||||
@param[in] Wrap Point to HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS The events is created successfully.
|
||||
@retval others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4TxEvent (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 receive token which is used to receive HTTP header.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
@retval EFI_SUCCESS The events is created successfully.
|
||||
@retval others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4RxEventForHeader (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Create event for the TCP4 receive token which is used to receive HTTP body.
|
||||
|
||||
@param[in] Wrap Point to HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS The events is created successfully.
|
||||
@retval others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateTcp4RxEvent (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Intiialize the HTTP_PROTOCOL structure to the unconfigured state.
|
||||
|
||||
@param[in] HttpSb The HTTP service private instance.
|
||||
@param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
|
||||
@retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpInitProtocol (
|
||||
IN HTTP_SERVICE *HttpSb,
|
||||
IN OUT HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up the HTTP child, release all the resources used by it.
|
||||
|
||||
@param[in] HttpInstance The HTTP child to clean up.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpCleanProtocol (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Establish TCP connection with HTTP server.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP connection is established.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCreateConnection (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Close existing TCP connection.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP connection is closed.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpCloseConnection (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Configure TCP4 protocol child.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP4 protocol child is configured.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpConfigureTcp4 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
/**
|
||||
Check existing TCP connection, if in error state, receover TCP4 connection.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
|
||||
@retval EFI_SUCCESS The TCP connection is established.
|
||||
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpConnectTcp4 (
|
||||
IN HTTP_PROTOCOL *HttpInstance
|
||||
);
|
||||
|
||||
/**
|
||||
Send the HTTP message through TCP4.
|
||||
|
||||
@param[in] HttpInstance The HTTP instance private data.
|
||||
@param[in] Wrap The HTTP token's wrap data.
|
||||
@param[in] TxString Buffer containing the HTTP message string.
|
||||
@param[in] TxStringLen Length of the HTTP message string in bytes.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP message is queued into TCP transmit queue.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpTransmitTcp4 (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN HTTP_TOKEN_WRAP *Wrap,
|
||||
IN UINT8 *TxString,
|
||||
IN UINTN TxStringLen
|
||||
);
|
||||
|
||||
/**
|
||||
Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
|
||||
in UEFI 2.5 specification.
|
||||
|
||||
@param[in] StatusCode The status code value in HTTP message.
|
||||
|
||||
@return Value defined in EFI_HTTP_STATUS_CODE .
|
||||
|
||||
**/
|
||||
EFI_HTTP_STATUS_CODE
|
||||
HttpMappingToStatusCode (
|
||||
IN UINTN StatusCode
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the user's token or event has already
|
||||
been enqueue on HTTP TxToken or RxToken list.
|
||||
|
||||
@param[in] Map The container of either user's transmit or receive
|
||||
token.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP
|
||||
@retval EFI_SUCCESS The current item isn't the same token/event as the
|
||||
context.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpTokenExist (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the HTTP message associated with TxToken is already sent out.
|
||||
|
||||
@param[in] Map The container of TxToken.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@retval EFI_NOT_READY The HTTP message is still queued in the list.
|
||||
@retval EFI_SUCCESS The HTTP message has been sent out.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpTcpNotReady (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Transmit the HTTP mssage by processing the associated HTTP token.
|
||||
|
||||
@param[in] Map The container of TxToken.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||
@retval EFI_SUCCESS The HTTP message is queued into TCP transmit
|
||||
queue.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpTcpTransmit (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Receive the HTTP response by processing the associated HTTP token.
|
||||
|
||||
@param[in] Map The container of RxToken.
|
||||
@param[in] Item Current item to check against.
|
||||
@param[in] Context The Token to check againist.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP response is queued into TCP receive
|
||||
queue.
|
||||
@retval Others Other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpTcpReceive (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Generate HTTP request string.
|
||||
|
||||
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
|
||||
@param[in] Message Pointer to storage containing HTTP message data.
|
||||
@param[in] Url The URL of a remote host.
|
||||
|
||||
@return Pointer to the created HTTP request string.
|
||||
@return NULL if any error occured.
|
||||
|
||||
**/
|
||||
CHAR8 *
|
||||
HttpGenRequestString (
|
||||
IN HTTP_PROTOCOL *HttpInstance,
|
||||
IN EFI_HTTP_MESSAGE *Message,
|
||||
IN CHAR8 *Url
|
||||
);
|
||||
|
||||
/**
|
||||
The work function of EfiHttpResponse().
|
||||
|
||||
@param[in] Wrap Pointer to HTTP token's wrap data.
|
||||
|
||||
@retval EFI_SUCCESS Allocation succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to complete the opration due to lack of resources.
|
||||
@retval EFI_NOT_READY Can't find a corresponding TxToken.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpResponseWorker (
|
||||
IN HTTP_TOKEN_WRAP *Wrap
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,622 @@
|
|||
/** @file
|
||||
|
||||
Implementation of help functions to parse HTTP message header.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpDriver.h"
|
||||
|
||||
/**
|
||||
Get the next string, which is distinguished by specified seperator.
|
||||
|
||||
@param[in] String Pointer to the string.
|
||||
@param[in] Seperator Specified seperator used to distinguish where is the beginning
|
||||
of next string.
|
||||
|
||||
@return Pointer to the next string.
|
||||
@return NULL if not find or String is NULL.
|
||||
|
||||
**/
|
||||
CHAR8 *
|
||||
AsciiStrGetNextToken (
|
||||
IN CONST CHAR8 *String,
|
||||
IN CHAR8 Seperator
|
||||
)
|
||||
{
|
||||
CONST CHAR8 *Token;
|
||||
|
||||
Token = String;
|
||||
while (TRUE) {
|
||||
if (*Token == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (*Token == Seperator) {
|
||||
return (CHAR8 *) (Token + 1);
|
||||
}
|
||||
Token++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Free existing HeaderFields.
|
||||
|
||||
@param[in] HeaderFields Pointer to array of key/value header pairs waitting for free.
|
||||
@param[in] FieldCount The number of header pairs in HeaderFields.
|
||||
|
||||
**/
|
||||
VOID
|
||||
FreeHeaderFields (
|
||||
IN EFI_HTTP_HEADER *HeaderFields,
|
||||
IN UINTN FieldCount
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
if (HeaderFields != NULL) {
|
||||
for (Index = 0; Index < FieldCount; Index++) {
|
||||
if(HeaderFields[Index].FieldName != NULL) {
|
||||
FreePool (HeaderFields[Index].FieldName);
|
||||
}
|
||||
if(HeaderFields[Index].FieldValue != NULL) {
|
||||
FreePool (HeaderFields[Index].FieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (HeaderFields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Find required header field in HeaderFields.
|
||||
|
||||
@param[in] HeaderFields Pointer to array of key/value header pairs.
|
||||
@param[in] FieldCount The number of header pairs.
|
||||
@param[in] FieldName Pointer to header field's name.
|
||||
|
||||
@return Pointer to the queried header field.
|
||||
@return NULL if not find this required header field.
|
||||
|
||||
**/
|
||||
EFI_HTTP_HEADER *
|
||||
FindHttpHeader (
|
||||
IN EFI_HTTP_HEADER *HeaderFields,
|
||||
IN UINTN FieldCount,
|
||||
IN CHAR8 *FieldName
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < FieldCount; Index++) {
|
||||
if (AsciiStrCmp (FieldName, HeaderFields[Index].FieldName) == 0) {
|
||||
//
|
||||
// Find the required header field.
|
||||
//
|
||||
return &HeaderFields[Index];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether header field called FieldName is in DeleteList.
|
||||
|
||||
@param[in] DeleteList Pointer to array of key/value header pairs.
|
||||
@param[in] DeleteCount The number of header pairs.
|
||||
@param[in] FieldName Pointer to header field's name.
|
||||
|
||||
@return TRUE if FieldName is not in DeleteList, that means this header field is valid.
|
||||
@return FALSE if FieldName is in DeleteList, that means this header field is invalid.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsValidHttpHeader (
|
||||
IN CHAR8 *DeleteList[],
|
||||
IN UINTN DeleteCount,
|
||||
IN CHAR8 *FieldName
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < DeleteCount; Index++) {
|
||||
if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Set FieldName and FieldValue into specified HttpHeader.
|
||||
|
||||
@param[in] HttpHeader Specified HttpHeader.
|
||||
@param[in] FieldName FieldName of this HttpHeader.
|
||||
@param[in] FieldValue FieldValue of this HttpHeader.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS The FieldName and FieldValue are set into HttpHeader successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetFieldNameAndValue (
|
||||
IN EFI_HTTP_HEADER *HttpHeader,
|
||||
IN CHAR8 *FieldName,
|
||||
IN CHAR8 *FieldValue
|
||||
)
|
||||
{
|
||||
UINTN FieldNameSize;
|
||||
UINTN FieldValueSize;
|
||||
|
||||
if (HttpHeader->FieldName != NULL) {
|
||||
FreePool (HttpHeader->FieldName);
|
||||
}
|
||||
if (HttpHeader->FieldValue != NULL) {
|
||||
FreePool (HttpHeader->FieldValue);
|
||||
}
|
||||
|
||||
FieldNameSize = AsciiStrSize (FieldName);
|
||||
HttpHeader->FieldName = AllocateZeroPool (FieldNameSize);
|
||||
if (HttpHeader->FieldName == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (HttpHeader->FieldName, FieldName, FieldNameSize);
|
||||
HttpHeader->FieldName[FieldNameSize - 1] = 0;
|
||||
|
||||
FieldValueSize = AsciiStrSize (FieldValue);
|
||||
HttpHeader->FieldValue = AllocateZeroPool (FieldValueSize);
|
||||
if (HttpHeader->FieldValue == NULL) {
|
||||
FreePool (HttpHeader->FieldName);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (HttpHeader->FieldValue, FieldValue, FieldValueSize);
|
||||
HttpHeader->FieldValue[FieldValueSize - 1] = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Get one key/value header pair from the raw string.
|
||||
|
||||
@param[in] String Pointer to the raw string.
|
||||
@param[out] FieldName Pointer to header field's name.
|
||||
@param[out] FieldValue Pointer to header field's value.
|
||||
|
||||
@return Pointer to the next raw string.
|
||||
@return NULL if no key/value header pair from this raw string.
|
||||
|
||||
**/
|
||||
CHAR8 *
|
||||
GetFieldNameAndValue (
|
||||
IN CHAR8 *String,
|
||||
OUT CHAR8 **FieldName,
|
||||
OUT CHAR8 **FieldValue
|
||||
)
|
||||
{
|
||||
CHAR8 *FieldNameStr;
|
||||
CHAR8 *FieldValueStr;
|
||||
CHAR8 *StrPtr;
|
||||
|
||||
if (String == NULL || FieldName == NULL || FieldValue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*FieldName = NULL;
|
||||
*FieldValue = NULL;
|
||||
FieldNameStr = NULL;
|
||||
FieldValueStr = NULL;
|
||||
StrPtr = NULL;
|
||||
|
||||
//
|
||||
// Each header field consists of a name followed by a colon (":") and the field value.
|
||||
//
|
||||
FieldNameStr = String;
|
||||
FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':');
|
||||
if (FieldValueStr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*(FieldValueStr - 1) = 0; /// Replace ':' with 0
|
||||
|
||||
//
|
||||
// The field value MAY be preceded by any amount of LWS, though a single SP is preferred.
|
||||
//
|
||||
while (TRUE) {
|
||||
if(*FieldValueStr == ' ' || *FieldValueStr == '\t') {
|
||||
FieldValueStr ++;
|
||||
} else if (*FieldValueStr == '\r' && *(FieldValueStr + 1) == '\n' &&
|
||||
(*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t')) {
|
||||
FieldValueStr = FieldValueStr + 3;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Header fields can be extended over multiple lines by preceding each extra
|
||||
// line with at least one SP or HT.
|
||||
//
|
||||
StrPtr = FieldValueStr;
|
||||
do {
|
||||
StrPtr = AsciiStrGetNextToken (StrPtr, '\r');
|
||||
if (StrPtr == NULL || *StrPtr != '\n') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StrPtr++;
|
||||
} while (*StrPtr == ' ' || *StrPtr == '\t');
|
||||
|
||||
//
|
||||
// Replace '\r' with 0.
|
||||
//
|
||||
*(StrPtr - 2) = 0;
|
||||
|
||||
//
|
||||
// Get FieldName and FieldValue.
|
||||
//
|
||||
*FieldName = FieldNameStr;
|
||||
*FieldValue = FieldValueStr;
|
||||
|
||||
return StrPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to manage the headers portion of an HTTP message by providing
|
||||
the ability to add, remove, or replace HTTP headers.
|
||||
|
||||
@param[in] SeedMessageSize Size in bytes of the initial HTTP header. This can be zero.
|
||||
@param[in] SeedMessage Initial raw unformatted HTTP header to be used as a base for
|
||||
building a new unformatted HTTP header. If NULL, SeedMessageSize
|
||||
is ignored. The buffer containing this message will be allocated
|
||||
and released by the caller.
|
||||
@param[in] DeleteCount Number of null-terminated HTTP header field names in DeleteList.
|
||||
@param[in] DeleteList List of null-terminated HTTP header field names to remove from SeedMessage.
|
||||
Only the field names are in this list because the field values are irrelevant
|
||||
to this operation. If NULL, DeleteCount is ignored. The buffer containing the
|
||||
list will be allocated and released by the caller.
|
||||
@param[in] AppendCount Number of header fields in AppendList.
|
||||
@param[in] AppendList List of HTTP headers to populate NewMessage with. If SeedMessage is not NULL,
|
||||
AppendList will be appended to the existing list from SeedMessage in NewMessage.
|
||||
@param[out] NewMessageSize Pointer to the size in bytes of the new unformatted HTTP header in NewMessage.
|
||||
@param[out] NewMessage Pointer to a new unformatted HTTP header. The storage for this NewMessage is
|
||||
allocated by the driver publishing this protocol, and must be freed by the caller.
|
||||
|
||||
@retval EFI_SUCCESS Add, remove, and replace operations succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate memory for NewMessage.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpUtilitiesBuild(
|
||||
IN UINTN SeedMessageSize,
|
||||
IN VOID *SeedMessage, OPTIONAL
|
||||
IN UINTN DeleteCount,
|
||||
IN CHAR8 *DeleteList[], OPTIONAL
|
||||
IN UINTN AppendCount,
|
||||
IN EFI_HTTP_HEADER *AppendList[], OPTIONAL
|
||||
OUT UINTN *NewMessageSize,
|
||||
OUT VOID **NewMessage
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HTTP_HEADER *SeedHeaderFields;
|
||||
UINTN SeedFieldCount;
|
||||
UINTN Index;
|
||||
EFI_HTTP_HEADER *TempHeaderFields;
|
||||
UINTN TempFieldCount;
|
||||
EFI_HTTP_HEADER *NewHeaderFields;
|
||||
UINTN NewFieldCount;
|
||||
EFI_HTTP_HEADER *HttpHeader;
|
||||
UINTN StrLength;
|
||||
UINT8 *NewMessagePtr;
|
||||
|
||||
SeedHeaderFields = NULL;
|
||||
SeedFieldCount = 0;
|
||||
TempHeaderFields = NULL;
|
||||
TempFieldCount = 0;
|
||||
NewHeaderFields = NULL;
|
||||
NewFieldCount = 0;
|
||||
|
||||
HttpHeader = NULL;
|
||||
StrLength = 0;
|
||||
NewMessagePtr = NULL;
|
||||
*NewMessageSize = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
if (SeedMessage != NULL) {
|
||||
Status = HttpUtilitiesParse (
|
||||
SeedMessage,
|
||||
SeedMessageSize,
|
||||
&SeedHeaderFields,
|
||||
&SeedFieldCount
|
||||
);
|
||||
if (EFI_ERROR (Status)){
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle DeleteList
|
||||
//
|
||||
if(SeedFieldCount != 0 && DeleteCount != 0) {
|
||||
TempHeaderFields = AllocateZeroPool (SeedFieldCount * sizeof(EFI_HTTP_HEADER));
|
||||
if (TempHeaderFields == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
for (Index = 0, TempFieldCount = 0; Index < SeedFieldCount; Index++) {
|
||||
//
|
||||
// Check whether each SeedHeaderFields member is in DeleteList
|
||||
//
|
||||
if (IsValidHttpHeader(DeleteList, DeleteCount, SeedHeaderFields[Index].FieldName)) {
|
||||
Status = SetFieldNameAndValue(
|
||||
&TempHeaderFields[TempFieldCount],
|
||||
SeedHeaderFields[Index].FieldName,
|
||||
SeedHeaderFields[Index].FieldValue
|
||||
);
|
||||
if (EFI_ERROR (Status)){
|
||||
goto ON_EXIT;
|
||||
}
|
||||
TempFieldCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TempHeaderFields = SeedHeaderFields;
|
||||
TempFieldCount = SeedFieldCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle AppendList
|
||||
//
|
||||
NewHeaderFields = AllocateZeroPool ((TempFieldCount + AppendCount) * sizeof(EFI_HTTP_HEADER));
|
||||
if (NewHeaderFields == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < TempFieldCount; Index++) {
|
||||
Status = SetFieldNameAndValue(
|
||||
&NewHeaderFields[Index],
|
||||
TempHeaderFields[Index].FieldName,
|
||||
TempHeaderFields[Index].FieldValue
|
||||
);
|
||||
if (EFI_ERROR (Status)){
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
NewFieldCount = TempFieldCount;
|
||||
|
||||
for (Index = 0; Index < AppendCount; Index++) {
|
||||
HttpHeader = FindHttpHeader(NewHeaderFields, NewFieldCount, AppendList[Index]->FieldName);
|
||||
if(HttpHeader != NULL) {
|
||||
Status = SetFieldNameAndValue(
|
||||
HttpHeader,
|
||||
AppendList[Index]->FieldName,
|
||||
AppendList[Index]->FieldValue
|
||||
);
|
||||
if (EFI_ERROR (Status)){
|
||||
goto ON_EXIT;
|
||||
}
|
||||
} else {
|
||||
Status = SetFieldNameAndValue
|
||||
(&NewHeaderFields[NewFieldCount],
|
||||
AppendList[Index]->FieldName,
|
||||
AppendList[Index]->FieldValue
|
||||
);
|
||||
if (EFI_ERROR (Status)){
|
||||
goto ON_EXIT;
|
||||
}
|
||||
NewFieldCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate NewMessageSize, then build NewMessage
|
||||
//
|
||||
for (Index = 0; Index < NewFieldCount; Index++) {
|
||||
HttpHeader = &NewHeaderFields[Index];
|
||||
|
||||
StrLength = AsciiStrLen (HttpHeader->FieldName);
|
||||
*NewMessageSize += StrLength;
|
||||
|
||||
StrLength = sizeof(": ") - 1;
|
||||
*NewMessageSize += StrLength;
|
||||
|
||||
StrLength = AsciiStrLen (HttpHeader->FieldValue);
|
||||
*NewMessageSize += StrLength;
|
||||
|
||||
StrLength = sizeof(HTTP_CRLF_STR) - 1;
|
||||
*NewMessageSize += StrLength;
|
||||
}
|
||||
StrLength = sizeof(HTTP_CRLF_STR) - 1;
|
||||
*NewMessageSize += StrLength;
|
||||
//
|
||||
// Final 0 for end flag.
|
||||
//
|
||||
*NewMessageSize += 1;
|
||||
|
||||
*NewMessage = AllocateZeroPool (*NewMessageSize);
|
||||
if (*NewMessage == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
NewMessagePtr = (UINT8 *)(*NewMessage);
|
||||
|
||||
for (Index = 0; Index < NewFieldCount; Index++) {
|
||||
HttpHeader = &NewHeaderFields[Index];
|
||||
|
||||
StrLength = AsciiStrLen (HttpHeader->FieldName);
|
||||
CopyMem (NewMessagePtr, HttpHeader->FieldName, StrLength);
|
||||
NewMessagePtr += StrLength;
|
||||
|
||||
StrLength = sizeof(": ") - 1;
|
||||
CopyMem (NewMessagePtr, ": ", StrLength);
|
||||
NewMessagePtr += StrLength;
|
||||
|
||||
StrLength = AsciiStrLen (HttpHeader->FieldValue);
|
||||
CopyMem (NewMessagePtr, HttpHeader->FieldValue, StrLength);
|
||||
NewMessagePtr += StrLength;
|
||||
|
||||
StrLength = sizeof(HTTP_CRLF_STR) - 1;
|
||||
CopyMem (NewMessagePtr, HTTP_CRLF_STR, StrLength);
|
||||
NewMessagePtr += StrLength;
|
||||
}
|
||||
StrLength = sizeof(HTTP_CRLF_STR) - 1;
|
||||
CopyMem (NewMessagePtr, HTTP_CRLF_STR, StrLength);
|
||||
NewMessagePtr += StrLength;
|
||||
|
||||
*NewMessagePtr = 0;
|
||||
|
||||
ASSERT (*NewMessageSize == (UINTN) NewMessagePtr - (UINTN) (*NewMessage) + 1);
|
||||
|
||||
//
|
||||
// Free allocated buffer
|
||||
//
|
||||
ON_EXIT:
|
||||
if(SeedHeaderFields != NULL) {
|
||||
FreeHeaderFields(SeedHeaderFields, SeedFieldCount);
|
||||
}
|
||||
|
||||
if(TempHeaderFields != NULL) {
|
||||
FreeHeaderFields(TempHeaderFields, TempFieldCount);
|
||||
}
|
||||
|
||||
if(NewHeaderFields != NULL) {
|
||||
FreeHeaderFields(NewHeaderFields, NewFieldCount);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is used to transform data stored in HttpMessage into a list of fields
|
||||
paired with their corresponding values.
|
||||
|
||||
@param[in] HttpMessage Contains raw unformatted HTTP header string. The buffer for this string will
|
||||
be allocated and released by the caller.
|
||||
@param[in] HttpMessageSize Size in bytes of raw unformatted HTTP header.
|
||||
@param[out] HeaderFields Array of key/value header pairs. The storage for all header pairs is allocated
|
||||
by the driver publishing this protocol, and must be freed by the caller.
|
||||
@param[out] FieldCount Number of headers in HeaderFields.
|
||||
|
||||
@retval EFI_SUCCESS Parse HTTP header into array of key/value pairs succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate memory for NewMessage.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
HttpMessage is NULL.
|
||||
HeaderFields is NULL.
|
||||
FieldCount is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpUtilitiesParse(
|
||||
IN CHAR8 *HttpMessage,
|
||||
IN UINTN HttpMessageSize,
|
||||
OUT EFI_HTTP_HEADER **HeaderFields,
|
||||
OUT UINTN *FieldCount
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CHAR8 *TempHttpMessage;
|
||||
CHAR8 *Token;
|
||||
CHAR8 *NextToken;
|
||||
CHAR8 *FieldName;
|
||||
CHAR8 *FieldValue;
|
||||
UINTN Index;
|
||||
|
||||
if (HttpMessage == NULL || HeaderFields == NULL || FieldCount == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
TempHttpMessage = NULL;
|
||||
*FieldCount = 0;
|
||||
Token = NULL;
|
||||
NextToken = NULL;
|
||||
FieldName = NULL;
|
||||
FieldValue = NULL;
|
||||
Index = 0;
|
||||
|
||||
TempHttpMessage = AllocateZeroPool (HttpMessageSize);
|
||||
if (TempHttpMessage == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
CopyMem (TempHttpMessage, HttpMessage, HttpMessageSize);
|
||||
|
||||
//
|
||||
// Get header number
|
||||
//
|
||||
Token = TempHttpMessage;
|
||||
while (TRUE) {
|
||||
FieldName = NULL;
|
||||
FieldValue = NULL;
|
||||
NextToken = GetFieldNameAndValue (Token, &FieldName, &FieldValue);
|
||||
Token = NextToken;
|
||||
if (FieldName == NULL || FieldValue == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
(*FieldCount)++;
|
||||
}
|
||||
|
||||
if(*FieldCount == 0) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate buffer for header
|
||||
//
|
||||
*HeaderFields = AllocateZeroPool ((*FieldCount) * sizeof(EFI_HTTP_HEADER));
|
||||
if (*HeaderFields == NULL) {
|
||||
*FieldCount = 0;
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
CopyMem (TempHttpMessage, HttpMessage, HttpMessageSize);
|
||||
|
||||
//
|
||||
// Set Field and Value to each header
|
||||
//
|
||||
Token = TempHttpMessage;
|
||||
while (Index < *FieldCount) {
|
||||
FieldName = NULL;
|
||||
FieldValue = NULL;
|
||||
NextToken = GetFieldNameAndValue (Token, &FieldName, &FieldValue);
|
||||
Token = NextToken;
|
||||
if (FieldName == NULL || FieldValue == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
Status = SetFieldNameAndValue(&(*HeaderFields)[Index], FieldName, FieldValue);
|
||||
if(EFI_ERROR(Status)){
|
||||
*FieldCount = 0;
|
||||
FreeHeaderFields (*HeaderFields, Index);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
//
|
||||
// Free allocated buffer
|
||||
//
|
||||
ON_EXIT:
|
||||
if (TempHttpMessage != NULL) {
|
||||
FreePool(TempHttpMessage);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/** @file
|
||||
The header files of HTTP helper functions for HttpDxe driver.
|
||||
|
||||
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_UTILITIES_H__
|
||||
#define __EFI_HTTP_UTILITIES_H__
|
||||
|
||||
/**
|
||||
This function is used to manage the headers portion of an HTTP message by providing
|
||||
the ability to add, remove, or replace HTTP headers.
|
||||
|
||||
@param[in] SeedMessageSize Size in bytes of the initial HTTP header. This can be zero.
|
||||
@param[in] SeedMessage Initial raw unformatted HTTP header to be used as a base for
|
||||
building a new unformatted HTTP header. If NULL, SeedMessageSize
|
||||
is ignored. The buffer containing this message will be allocated
|
||||
and released by the caller.
|
||||
@param[in] DeleteCount Number of null-terminated HTTP header field names in DeleteList.
|
||||
@param[in] DeleteList List of null-terminated HTTP header field names to remove from SeedMessage.
|
||||
Only the field names are in this list because the field values are irrelevant
|
||||
to this operation. If NULL, DeleteCount is ignored. The buffer containing the
|
||||
list will be allocated and released by the caller.
|
||||
@param[in] AppendCount Number of header fields in AppendList.
|
||||
@param[in] AppendList List of HTTP headers to populate NewMessage with. If SeedMessage is not NULL,
|
||||
AppendList will be appended to the existing list from SeedMessage in NewMessage.
|
||||
@param[out] NewMessageSize Pointer to the size in bytes of the new unformatted HTTP header in NewMessage.
|
||||
@param[out] NewMessage Pointer to a new unformatted HTTP header. The storage for this NewMessage is
|
||||
allocated by the driver publishing this protocol, and must be freed by the caller.
|
||||
|
||||
@retval EFI_SUCCESS Add, remove, and replace operations succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate memory for NewMessage.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpUtilitiesBuild(
|
||||
IN UINTN SeedMessageSize,
|
||||
IN VOID *SeedMessage, OPTIONAL
|
||||
IN UINTN DeleteCount,
|
||||
IN CHAR8 *DeleteList[], OPTIONAL
|
||||
IN UINTN AppendCount,
|
||||
IN EFI_HTTP_HEADER *AppendList[], OPTIONAL
|
||||
OUT UINTN *NewMessageSize,
|
||||
OUT VOID **NewMessage
|
||||
);
|
||||
|
||||
/**
|
||||
This function is used to transform data stored in HttpMessage into a list of fields
|
||||
paired with their corresponding values.
|
||||
|
||||
@param[in] HttpMessage Contains raw unformatted HTTP header string. The buffer for this string will
|
||||
be allocated and released by the caller.
|
||||
@param[in] HttpMessageSize Size in bytes of raw unformatted HTTP header.
|
||||
@param[out] HeaderFields Array of key/value header pairs. The storage for all header pairs is allocated
|
||||
by the driver publishing this protocol, and must be freed by the caller.
|
||||
@param[out] FieldCount Number of headers in HeaderFields.
|
||||
|
||||
@retval EFI_SUCCESS Parse HTTP header into array of key/value pairs succeeded.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate memory for NewMessage.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
HttpMessage is NULL.
|
||||
HeaderFields is NULL.
|
||||
FieldCount is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpUtilitiesParse(
|
||||
IN CHAR8 *HttpMessage,
|
||||
IN UINTN HttpMessageSize,
|
||||
OUT EFI_HTTP_HEADER **HeaderFields,
|
||||
OUT UINTN *FieldCount
|
||||
);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue