From nobody Mon May 13 10:50:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+66915+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66915+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1604383945; cv=none; d=zohomail.com; s=zohoarc; b=JjfBcPhSxFi4BvZDOE6+2jrirZXXInMUr3+A2OWX8ov9WCqmRgs2uiUEkflJ8l5w6idVvkXUTs2OOvZD3a6IfvXQYW/3At97aAcTW5pCox9mzTaRYPpUpFd62bazXVXJvww/FUjrRRFzrVjE1+BSbsMkgvDOGw0AZxjRLfBDyN0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604383945; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=qGICOSDBodEPcvCtEaSObPMHTTe2gKs3DntkcAaOsFc=; b=nHOBkQnwovQgp+WqiwCEbtGW2UtQcdFb7qgMLXFeHsQxo20rYIt6zBNblsfZ58Fghh+QbZYLot5yIKgszKPfxGBZndPhsLpCZxq3+aC/cW1gXj52lNd1JAF/0i894ZMEkRRrvZ3IeBaaVBCiBIs14rZzeRQqfg1fsVKc/3DO6fk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66915+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604383945621265.08637642655924; Mon, 2 Nov 2020 22:12:25 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8HT6YY1788612xz2yieUSDFa; Mon, 02 Nov 2020 22:12:25 -0800 X-Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by mx.groups.io with SMTP id smtpd.web11.438.1604383944748792738 for ; Mon, 02 Nov 2020 22:12:24 -0800 X-Received: from pps.filterd (m0134421.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0A36B6rM023386; Tue, 3 Nov 2020 06:12:23 GMT X-Received: from g2t2354.austin.hpe.com (g2t2354.austin.hpe.com [15.233.44.27]) by mx0b-002e3701.pphosted.com with ESMTP id 34hh9wr68h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 03 Nov 2020 06:12:23 +0000 X-Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2354.austin.hpe.com (Postfix) with ESMTP id DD4F3AE; Tue, 3 Nov 2020 06:12:22 +0000 (UTC) X-Received: from abner-virtual-machine.asiapacific.hpqcorp.net (abner-virtual-machine.asiapacific.hpqcorp.net [15.119.210.153]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id 868913A; Tue, 3 Nov 2020 06:12:21 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: Maciej Rabeda , Jiaxin Wu , Siyuan Fu , Nickle Wang Subject: [edk2-devel] [DxeHttpIoLib PATCH V5 1/3] NetworkPkg/Library: Implementation of Http IO Helper Library Date: Tue, 3 Nov 2020 13:26:49 +0800 Message-Id: <20201103052651.16250-2-abner.chang@hpe.com> In-Reply-To: <20201103052651.16250-1-abner.chang@hpe.com> References: <20201103052651.16250-1-abner.chang@hpe.com> X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: teqYFmMSivzNrOxwkLMzxCuSx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604383945; bh=CmvLUlfmvasTlbA7rYTRMdHnqEuV6hLbAKAXHsBc3m4=; h=Cc:Date:From:Reply-To:Subject:To; b=wAFs5qbbeGfS7xoVzMBigPwy/Zlt0d5iERbgqq5w/K+DioHPEFX12tN18mJsBGTPsV0 KRCPaFkJ8UENybK2KJ5rPFO+QHN8QphD0dQHWR+XZc9El60+a7cAGSM3HBS8QMAoanSrs GZSKs9XQLUT0A5kCxf/t1LaRmqfNRldGS4E= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add HTTP IO helper library which could be used by HTTP applications such as HTTP Boot, Redfish HTTP REST EX driver instance and etc. Signed-off-by: Abner Chang Cc: Maciej Rabeda Cc: Jiaxin Wu Cc: Siyuan Fu Cc: Nickle Wang Reviewed-by: Maciej Rabeda --- NetworkPkg/Include/Library/HttpIoLib.h | 328 +++++++ .../Library/DxeHttpIoLib/DxeHttpIoLib.c | 853 ++++++++++++++++++ .../Library/DxeHttpIoLib/DxeHttpIoLib.inf | 46 + .../Library/DxeHttpIoLib/DxeHttpIoLib.uni | 13 + 4 files changed, 1240 insertions(+) create mode 100644 NetworkPkg/Include/Library/HttpIoLib.h create mode 100644 NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.c create mode 100644 NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf create mode 100644 NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.uni diff --git a/NetworkPkg/Include/Library/HttpIoLib.h b/NetworkPkg/Include/Li= brary/HttpIoLib.h new file mode 100644 index 0000000000..8f3804ca42 --- /dev/null +++ b/NetworkPkg/Include/Library/HttpIoLib.h @@ -0,0 +1,328 @@ +/** @file + HttpIoLib.h. + +(C) Copyright 2020 Hewlett-Packard Development Company, L.P.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HTTP_IO_LIB_H_ +#define HTTP_IO_LIB_H_ + +#include + +#include +#include +#include + +#define HTTP_IO_MAX_SEND_PAYLOAD 1024 +#define HTTP_IO_CHUNK_SIZE_STRING_LEN 50 +#define HTTP_IO_CHUNKED_TRANSFER_CODING_DATA_LENGTH 256 + +/// +/// HTTP_IO_CALLBACK_EVENT +/// +typedef enum { + HttpIoRequest, + HttpIoResponse +} HTTP_IO_CALLBACK_EVENT; + +/** + HttpIo Callback function which will be invoked when specified HTTP_IO_CA= LLBACK_EVENT happened. + + @param[in] EventType Indicate the Event type that occurs in the = current callback. + @param[in] Message HTTP message which will be send to, or just= received from HTTP server. + @param[in] Context The Callback Context pointer. + + @retval EFI_SUCCESS Tells the HttpIo to continue the HTTP proce= ss. + @retval Others Tells the HttpIo to abort the current HTTP = process. +**/ +typedef +EFI_STATUS +(EFIAPI * HTTP_IO_CALLBACK) ( + IN HTTP_IO_CALLBACK_EVENT EventType, + IN EFI_HTTP_MESSAGE *Message, + IN VOID *Context + ); + +/// +/// A wrapper structure to hold the received HTTP response data. +/// +typedef struct { + EFI_HTTP_RESPONSE_DATA Response; + UINTN HeaderCount; + EFI_HTTP_HEADER *Headers; + UINTN BodyLength; + CHAR8 *Body; + EFI_STATUS Status; +} HTTP_IO_RESPONSE_DATA; + +/// +/// HTTP_IO configuration data for IPv4 +/// +typedef struct { + EFI_HTTP_VERSION HttpVersion; + UINT32 RequestTimeOut; ///< In milliseconds. + UINT32 ResponseTimeOut; ///< In milliseconds. + BOOLEAN UseDefaultAddress; + EFI_IPv4_ADDRESS LocalIp; + EFI_IPv4_ADDRESS SubnetMask; + UINT16 LocalPort; +} HTTP4_IO_CONFIG_DATA; + +/// +/// HTTP_IO configuration data for IPv6 +/// +typedef struct { + EFI_HTTP_VERSION HttpVersion; + UINT32 RequestTimeOut; ///< In milliseconds. + BOOLEAN UseDefaultAddress; + EFI_IPv6_ADDRESS LocalIp; + UINT16 LocalPort; +} HTTP6_IO_CONFIG_DATA; + +/// +/// HTTP_IO configuration +/// +typedef union { + HTTP4_IO_CONFIG_DATA Config4; + HTTP6_IO_CONFIG_DATA Config6; +} HTTP_IO_CONFIG_DATA; + +/// +/// HTTP_IO wrapper of the EFI HTTP service. +/// +typedef struct { + UINT8 IpVersion; + EFI_HANDLE Image; + EFI_HANDLE Controller; + EFI_HANDLE Handle; + + EFI_HTTP_PROTOCOL *Http; + + HTTP_IO_CALLBACK Callback; + VOID *Context; + + EFI_HTTP_TOKEN ReqToken; + EFI_HTTP_MESSAGE ReqMessage; + EFI_HTTP_TOKEN RspToken; + EFI_HTTP_MESSAGE RspMessage; + + BOOLEAN IsTxDone; + BOOLEAN IsRxDone; + + EFI_EVENT TimeoutEvent; + UINT32 Timeout; +} HTTP_IO; + +/// +/// Process code of HTTP chunk transfer. +/// +typedef enum { + HttpIoSendChunkNone =3D 0, + HttpIoSendChunkHeaderZeroContent, + HttpIoSendChunkContent, + HttpIoSendChunkEndChunk, + HttpIoSendChunkFinish +} HTTP_IO_SEND_CHUNK_PROCESS; + +/// +/// Process code of HTTP non chunk transfer. +/// +typedef enum { + HttpIoSendNonChunkNone =3D 0, + HttpIoSendNonChunkHeaderZeroContent, + HttpIoSendNonChunkContent, + HttpIoSendNonChunkFinish +} HTTP_IO_SEND_NON_CHUNK_PROCESS; + +/// +/// Chunk links for HTTP chunked transfer coding. +/// +typedef struct { + LIST_ENTRY NextChunk; + UINTN Length; + CHAR8 *Data; +} HTTP_IO_CHUNKS; + +/** + Notify the callback function when an event is triggered. + + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotifyDpc ( + IN VOID *Context + ); + +/** + Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK. + + @param[in] Event The event signaled. + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Destroy the HTTP_IO and release the resources. + + @param[in] HttpIo The HTTP_IO which wraps the HTTP service to = be destroyed. + +**/ +VOID +HttpIoDestroyIo ( + IN HTTP_IO *HttpIo + ); + +/** + Create a HTTP_IO to access the HTTP service. It will create and configure + a HTTP child handle. + + @param[in] Image The handle of the driver image. + @param[in] Controller The handle of the controller. + @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. + @param[in] ConfigData The HTTP_IO configuration data. + @param[in] Callback Callback function which will be invoked when = specified + HTTP_IO_CALLBACK_EVENT happened. + @param[in] Context The Context data which will be passed to the = Callback function. + @param[out] HttpIo The HTTP_IO. + + @retval EFI_SUCCESS The HTTP_IO is created and configured. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED One or more of the control options are not + supported in the implementation. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Others Failed to create the HTTP_IO or configure= it. + +**/ +EFI_STATUS +HttpIoCreateIo ( + IN EFI_HANDLE Image, + IN EFI_HANDLE Controller, + IN UINT8 IpVersion, + IN HTTP_IO_CONFIG_DATA *ConfigData, + IN HTTP_IO_CALLBACK Callback, + IN VOID *Context, + OUT HTTP_IO *HttpIo + ); + +/** + Synchronously send a HTTP REQUEST message to the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] Request A pointer to storage such data as URL and = HTTP method. + @param[in] HeaderCount Number of HTTP header structures in Header= s list. + @param[in] Headers Array containing list of HTTP headers. + @param[in] BodyLength Length in bytes of the HTTP body. + @param[in] Body Body associated with the HTTP request. + + @retval EFI_SUCCESS The HTTP request is transmitted. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoSendRequest ( + IN HTTP_IO *HttpIo, + IN EFI_HTTP_REQUEST_DATA *Request, OPTIONAL + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, OPTIONAL + IN UINTN BodyLength, + IN VOID *Body OPTIONAL + ); + +/** + Synchronously receive a HTTP RESPONSE message from the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] RecvMsgHeader TRUE to receive a new HTTP response (from = message header). + FALSE to continue receive the previous res= ponse message. + @param[out] ResponseData Point to a wrapper of the received respons= e data. + + @retval EFI_SUCCESS The HTTP response is received. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoRecvResponse ( + IN HTTP_IO *HttpIo, + IN BOOLEAN RecvMsgHeader, + OUT HTTP_IO_RESPONSE_DATA *ResponseData + ); + +/** + Get the value of the content length if there is a "Content-Length" heade= r. + + @param[in] HeaderCount Number of HTTP header structures in Hea= ders. + @param[in] Headers Array containing list of HTTP headers. + @param[out] ContentLength Pointer to save the value of the conten= t length. + + @retval EFI_SUCCESS Successfully get the content length. + @retval EFI_NOT_FOUND No "Content-Length" header in the Heade= rs. + +**/ +EFI_STATUS +HttpIoGetContentLength ( + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + OUT UINTN *ContentLength + ); + +/** + Synchronously receive a HTTP RESPONSE message from the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] HeaderCount Number of headers in Headers. + @param[in] Headers Array containing list of HTTP headers. + @param[out] ChunkListHead A pointer to receivce list head of chunked= data. + Caller has to release memory of ChunkListH= ead + and all list entries. + @param[out] ContentLength Total content length + + @retval EFI_SUCCESS The HTTP chunked transfer is received. + @retval EFI_NOT_FOUND No chunked transfer coding header found. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_INVALID_PARAMETER Improper parameters. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoGetChunkedTransferContent ( + IN HTTP_IO *HttpIo, + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + OUT LIST_ENTRY **ChunkListHead, + OUT UINTN *ContentLength + ); + +/** + Send HTTP request in chunks. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] SendChunkProcess Pointer to current chunk process status. + @param[out] RequestMessage Request to send. + + @retval EFI_SUCCESS Successfully to send chunk data accordin= g to SendChunkProcess. + @retval Other Other errors. + +**/ +EFI_STATUS +HttpIoSendChunkedTransfer ( + IN HTTP_IO *HttpIo, + IN HTTP_IO_SEND_CHUNK_PROCESS *SendChunkProcess, + IN EFI_HTTP_MESSAGE *RequestMessage +); +#endif diff --git a/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.c b/NetworkPkg/Li= brary/DxeHttpIoLib/DxeHttpIoLib.c new file mode 100644 index 0000000000..67583fb220 --- /dev/null +++ b/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.c @@ -0,0 +1,853 @@ +/** @file + Http IO Helper Library. + + (C) Copyright 2020 Hewlett-Packard Development Company, L.P.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +/** + Notify the callback function when an event is triggered. + + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotifyDpc ( + IN VOID *Context + ) +{ + *((BOOLEAN *) Context) =3D TRUE; +} + +/** + Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK. + + @param[in] Event The event signaled. + @param[in] Context The opaque parameter to the function. + +**/ +VOID +EFIAPI +HttpIoNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK + // + QueueDpc (TPL_CALLBACK, HttpIoNotifyDpc, Context); +} + +/** + Destroy the HTTP_IO and release the resources. + + @param[in] HttpIo The HTTP_IO which wraps the HTTP service to = be destroyed. + +**/ +VOID +HttpIoDestroyIo ( + IN HTTP_IO *HttpIo + ) +{ + EFI_HTTP_PROTOCOL *Http; + EFI_EVENT Event; + + if (HttpIo =3D=3D NULL) { + return; + } + + Event =3D HttpIo->ReqToken.Event; + if (Event !=3D NULL) { + gBS->CloseEvent (Event); + } + + Event =3D HttpIo->RspToken.Event; + if (Event !=3D NULL) { + gBS->CloseEvent (Event); + } + + Event =3D HttpIo->TimeoutEvent; + if (Event !=3D NULL) { + gBS->CloseEvent (Event); + } + + Http =3D HttpIo->Http; + if (Http !=3D NULL) { + Http->Configure (Http, NULL); + gBS->CloseProtocol ( + HttpIo->Handle, + &gEfiHttpProtocolGuid, + HttpIo->Image, + HttpIo->Controller + ); + } + + NetLibDestroyServiceChild ( + HttpIo->Controller, + HttpIo->Image, + &gEfiHttpServiceBindingProtocolGuid, + HttpIo->Handle + ); +} + +/** + Create a HTTP_IO to access the HTTP service. It will create and configure + a HTTP child handle. + + @param[in] Image The handle of the driver image. + @param[in] Controller The handle of the controller. + @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. + @param[in] ConfigData The HTTP_IO configuration data , + NULL means not to configure the HTTP child. + @param[in] Callback Callback function which will be invoked when = specified + HTTP_IO_CALLBACK_EVENT happened. + @param[in] Context The Context data which will be passed to the = Callback function. + @param[out] HttpIo The HTTP_IO. + + @retval EFI_SUCCESS The HTTP_IO is created and configured. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED One or more of the control options are not + supported in the implementation. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Others Failed to create the HTTP_IO or configure= it. + +**/ +EFI_STATUS +HttpIoCreateIo ( + IN EFI_HANDLE Image, + IN EFI_HANDLE Controller, + IN UINT8 IpVersion, + IN HTTP_IO_CONFIG_DATA *ConfigData, OPTIONAL + IN HTTP_IO_CALLBACK Callback, + IN VOID *Context, + OUT HTTP_IO *HttpIo + ) +{ + EFI_STATUS Status; + EFI_HTTP_CONFIG_DATA HttpConfigData; + EFI_HTTPv4_ACCESS_POINT Http4AccessPoint; + EFI_HTTPv6_ACCESS_POINT Http6AccessPoint; + EFI_HTTP_PROTOCOL *Http; + EFI_EVENT Event; + + if ((Image =3D=3D NULL) || (Controller =3D=3D NULL) || (HttpIo =3D=3D NU= LL)) { + return EFI_INVALID_PARAMETER; + } + + if (IpVersion !=3D IP_VERSION_4 && IpVersion !=3D IP_VERSION_6) { + return EFI_UNSUPPORTED; + } + + ZeroMem (HttpIo, sizeof (HTTP_IO)); + ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); + + // + // Create the HTTP child instance and get the HTTP protocol. + // + Status =3D NetLibCreateServiceChild ( + Controller, + Image, + &gEfiHttpServiceBindingProtocolGuid, + &HttpIo->Handle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gBS->OpenProtocol ( + HttpIo->Handle, + &gEfiHttpProtocolGuid, + (VOID **) &Http, + Image, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) || (Http =3D=3D NULL)) { + goto ON_ERROR; + } + + // + // Init the configuration data and configure the HTTP child. + // + HttpIo->Image =3D Image; + HttpIo->Controller =3D Controller; + HttpIo->IpVersion =3D IpVersion; + HttpIo->Http =3D Http; + HttpIo->Callback =3D Callback; + HttpIo->Context =3D Context; + + if (ConfigData !=3D NULL) { + if (HttpIo->IpVersion =3D=3D IP_VERSION_4) { + HttpConfigData.LocalAddressIsIPv6 =3D FALSE; + HttpConfigData.HttpVersion =3D ConfigData->Config4.HttpVersi= on; + HttpConfigData.TimeOutMillisec =3D ConfigData->Config4.RequestTi= meOut; + + Http4AccessPoint.UseDefaultAddress =3D ConfigData->Config4.UseDefaul= tAddress; + Http4AccessPoint.LocalPort =3D ConfigData->Config4.LocalPort; + IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Confi= g4.LocalIp); + IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config= 4.SubnetMask); + HttpConfigData.AccessPoint.IPv4Node =3D &Http4AccessPoint; + } else { + HttpConfigData.LocalAddressIsIPv6 =3D TRUE; + HttpConfigData.HttpVersion =3D ConfigData->Config6.HttpVersi= on; + HttpConfigData.TimeOutMillisec =3D ConfigData->Config6.RequestTi= meOut; + + Http6AccessPoint.LocalPort =3D ConfigData->Config6.LocalPort; + IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Confi= g6.LocalIp); + HttpConfigData.AccessPoint.IPv6Node =3D &Http6AccessPoint; + } + + Status =3D Http->Configure (Http, &HttpConfigData); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + } + + // + // Create events for variuos asynchronous operations. + // + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpIoNotify, + &HttpIo->IsTxDone, + &Event + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + HttpIo->ReqToken.Event =3D Event; + HttpIo->ReqToken.Message =3D &HttpIo->ReqMessage; + + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpIoNotify, + &HttpIo->IsRxDone, + &Event + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + HttpIo->RspToken.Event =3D Event; + HttpIo->RspToken.Message =3D &HttpIo->RspMessage; + + // + // Create TimeoutEvent for response + // + Status =3D gBS->CreateEvent ( + EVT_TIMER, + TPL_CALLBACK, + NULL, + NULL, + &Event + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + HttpIo->TimeoutEvent =3D Event; + return EFI_SUCCESS; + +ON_ERROR: + HttpIoDestroyIo (HttpIo); + + return Status; +} + +/** + Synchronously send a HTTP REQUEST message to the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] Request A pointer to storage such data as URL and = HTTP method. + @param[in] HeaderCount Number of HTTP header structures in Header= s list. + @param[in] Headers Array containing list of HTTP headers. + @param[in] BodyLength Length in bytes of the HTTP body. + @param[in] Body Body associated with the HTTP request. + + @retval EFI_SUCCESS The HTTP request is trasmitted. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoSendRequest ( + IN HTTP_IO *HttpIo, + IN EFI_HTTP_REQUEST_DATA *Request, + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + IN UINTN BodyLength, + IN VOID *Body + ) +{ + EFI_STATUS Status; + EFI_HTTP_PROTOCOL *Http; + + if (HttpIo =3D=3D NULL || HttpIo->Http =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + HttpIo->ReqToken.Status =3D EFI_NOT_READY; + HttpIo->ReqToken.Message->Data.Request =3D Request; + HttpIo->ReqToken.Message->HeaderCount =3D HeaderCount; + HttpIo->ReqToken.Message->Headers =3D Headers; + HttpIo->ReqToken.Message->BodyLength =3D BodyLength; + HttpIo->ReqToken.Message->Body =3D Body; + + if (HttpIo->Callback !=3D NULL) { + Status =3D HttpIo->Callback ( + HttpIoRequest, + HttpIo->ReqToken.Message, + HttpIo->Context + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Queue the request token to HTTP instances. + // + Http =3D HttpIo->Http; + HttpIo->IsTxDone =3D FALSE; + Status =3D Http->Request ( + Http, + &HttpIo->ReqToken + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Poll the network until transmit finish. + // + while (!HttpIo->IsTxDone) { + Http->Poll (Http); + } + + return HttpIo->ReqToken.Status; +} + +/** + Synchronously receive a HTTP RESPONSE message from the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] RecvMsgHeader TRUE to receive a new HTTP response (from = message header). + FALSE to continue receive the previous res= ponse message. + @param[out] ResponseData Point to a wrapper of the received respons= e data. + + @retval EFI_SUCCESS The HTTP response is received. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoRecvResponse ( + IN HTTP_IO *HttpIo, + IN BOOLEAN RecvMsgHeader, + OUT HTTP_IO_RESPONSE_DATA *ResponseData + ) +{ + EFI_STATUS Status; + EFI_HTTP_PROTOCOL *Http; + + if (HttpIo =3D=3D NULL || HttpIo->Http =3D=3D NULL || ResponseData =3D= =3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Queue the response token to HTTP instances. + // + HttpIo->RspToken.Status =3D EFI_NOT_READY; + if (RecvMsgHeader) { + HttpIo->RspToken.Message->Data.Response =3D &ResponseData->Response; + } else { + HttpIo->RspToken.Message->Data.Response =3D NULL; + } + HttpIo->RspToken.Message->HeaderCount =3D 0; + HttpIo->RspToken.Message->Headers =3D NULL; + HttpIo->RspToken.Message->BodyLength =3D ResponseData->BodyLength; + HttpIo->RspToken.Message->Body =3D ResponseData->Body; + + Http =3D HttpIo->Http; + HttpIo->IsRxDone =3D FALSE; + + // + // Start the timer, and wait Timeout seconds to receive the header packe= t. + // + Status =3D gBS->SetTimer (HttpIo->TimeoutEvent, TimerRelative, HttpIo->T= imeout * TICKS_PER_MS); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D Http->Response ( + Http, + &HttpIo->RspToken + ); + + if (EFI_ERROR (Status)) { + // + // Remove timeout timer from the event list. + // + gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); + return Status; + } + + // + // Poll the network until receive finish. + // + while (!HttpIo->IsRxDone && EFI_ERROR (gBS->CheckEvent (HttpIo->TimeoutE= vent))) { + Http->Poll (Http); + } + + // + // Remove timeout timer from the event list. + // + gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); + + if (!HttpIo->IsRxDone) { + // + // Timeout occurs, cancel the response token. + // + Http->Cancel (Http, &HttpIo->RspToken); + + Status =3D EFI_TIMEOUT; + + return Status; + } else { + HttpIo->IsRxDone =3D FALSE; + } + + if ((HttpIo->Callback !=3D NULL) && + (HttpIo->RspToken.Status =3D=3D EFI_SUCCESS || HttpIo->RspToken.Stat= us =3D=3D EFI_HTTP_ERROR)) { + Status =3D HttpIo->Callback ( + HttpIoResponse, + HttpIo->RspToken.Message, + HttpIo->Context + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Store the received data into the wrapper. + // + ResponseData->Status =3D HttpIo->RspToken.Status; + ResponseData->HeaderCount =3D HttpIo->RspToken.Message->HeaderCount; + ResponseData->Headers =3D HttpIo->RspToken.Message->Headers; + ResponseData->BodyLength =3D HttpIo->RspToken.Message->BodyLength; + + return Status; +} + +/** + Get the value of the content length if there is a "Content-Length" heade= r. + + @param[in] HeaderCount Number of HTTP header structures in Hea= ders. + @param[in] Headers Array containing list of HTTP headers. + @param[out] ContentLength Pointer to save the value of the conten= t length. + + @retval EFI_SUCCESS Successfully get the content length. + @retval EFI_NOT_FOUND No "Content-Length" header in the Heade= rs. + +**/ +EFI_STATUS +HttpIoGetContentLength ( + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + OUT UINTN *ContentLength + ) +{ + EFI_HTTP_HEADER *Header; + + Header =3D HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_LEN= GTH); + if (Header =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return AsciiStrDecimalToUintnS (Header->FieldValue, (CHAR8 **) NULL, Con= tentLength); +} +/** + Send HTTP request in chunks. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] SendChunkProcess Pointer to current chunk process status. + @param[in] RequestMessage Request to send. + + @retval EFI_SUCCESS Successfully to send chunk data accordin= g to SendChunkProcess. + @retval Other Other errors. + +**/ +EFI_STATUS +HttpIoSendChunkedTransfer ( + IN HTTP_IO *HttpIo, + IN HTTP_IO_SEND_CHUNK_PROCESS *SendChunkProcess, + IN EFI_HTTP_MESSAGE *RequestMessage +) +{ + EFI_STATUS Status; + EFI_HTTP_HEADER *NewHeaders; + EFI_HTTP_HEADER *ContentLengthHeader; + UINTN AddNewHeader; + UINTN HeaderCount; + CHAR8 *MessageBody; + UINTN MessageBodyLength; + UINTN ChunkLength; + CHAR8 ChunkLengthStr [HTTP_IO_CHUNK_SIZE_STRING_LEN]; + EFI_HTTP_REQUEST_DATA *SentRequestData; + + AddNewHeader =3D 0; + NewHeaders =3D NULL; + MessageBody =3D NULL; + ContentLengthHeader =3D NULL; + MessageBodyLength =3D 0; + + switch (*SendChunkProcess) { + case HttpIoSendChunkHeaderZeroContent: + ContentLengthHeader =3D HttpFindHeader (RequestMessage->HeaderCount,= RequestMessage->Headers, HTTP_HEADER_CONTENT_LENGTH); + if (ContentLengthHeader =3D=3D NULL) { + AddNewHeader =3D 1; + } + + NewHeaders =3D AllocateZeroPool ((RequestMessage->HeaderCount + AddN= ewHeader) * sizeof(EFI_HTTP_HEADER)); + CopyMem ((VOID*)NewHeaders, (VOID *)RequestMessage->Headers, Request= Message->HeaderCount * sizeof (EFI_HTTP_HEADER)); + if (AddNewHeader =3D=3D 0) { + // + // Override content-length to Transfer-Encoding. + // + ContentLengthHeader =3D HttpFindHeader (RequestMessage->HeaderCoun= t, NewHeaders, HTTP_HEADER_CONTENT_LENGTH); + ContentLengthHeader->FieldName =3D NULL; + ContentLengthHeader->FieldValue =3D NULL; + } else { + ContentLengthHeader =3D NewHeaders + RequestMessage->HeaderCount; + } + HttpSetFieldNameAndValue (ContentLengthHeader, HTTP_HEADER_TRANSFER_= ENCODING, HTTP_HEADER_TRANSFER_ENCODING_CHUNKED); + HeaderCount =3D RequestMessage->HeaderCount + AddNewHeader; + MessageBodyLength =3D 0; + MessageBody =3D NULL; + SentRequestData =3D RequestMessage->Data.Request; + break; + + case HttpIoSendChunkContent: + HeaderCount =3D 0; + NewHeaders =3D NULL; + SentRequestData =3D NULL; + if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) { + MessageBodyLength =3D HTTP_IO_MAX_SEND_PAYLOAD; + } else { + MessageBodyLength =3D RequestMessage->BodyLength; + } + AsciiSPrint ( + ChunkLengthStr, + HTTP_IO_CHUNK_SIZE_STRING_LEN, + "%x%c%c", + MessageBodyLength, + CHUNKED_TRANSFER_CODING_CR, + CHUNKED_TRANSFER_CODING_LF + ); + ChunkLength =3D AsciiStrLen (ChunkLengthStr); + MessageBody =3D AllocatePool (ChunkLength + MessageBodyLength + 2); + if (MessageBody =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "Not enough memory for chunk transfer\n")); + return EFI_OUT_OF_RESOURCES; + } + // + // Build up the chunk transfer paylaod. + // + CopyMem (MessageBody, ChunkLengthStr, ChunkLength); + CopyMem (MessageBody + ChunkLength, RequestMessage->Body, MessageBod= yLength); + *(MessageBody + ChunkLength + MessageBodyLength) =3D CHUNKED_TRANSFE= R_CODING_CR; + *(MessageBody + ChunkLength + MessageBodyLength + 1) =3D CHUNKED_TRA= NSFER_CODING_LF; + // + // Change variables for the next chunk trasnfer. + // + RequestMessage->BodyLength -=3D MessageBodyLength; + RequestMessage->Body =3D (VOID *)((CHAR8 *)RequestMessage->Body + Me= ssageBodyLength); + MessageBodyLength +=3D (ChunkLength + 2); + if (RequestMessage->BodyLength =3D=3D 0) { + *SendChunkProcess =3D HttpIoSendChunkEndChunk; + } + break; + + case HttpIoSendChunkEndChunk: + HeaderCount =3D 0; + NewHeaders =3D NULL; + SentRequestData =3D NULL; + AsciiSPrint ( + ChunkLengthStr, + HTTP_IO_CHUNK_SIZE_STRING_LEN, + "0%c%c%c%c", + CHUNKED_TRANSFER_CODING_CR, + CHUNKED_TRANSFER_CODING_LF, + CHUNKED_TRANSFER_CODING_CR, + CHUNKED_TRANSFER_CODING_LF + ); + MessageBody =3D AllocatePool (AsciiStrLen(ChunkLengthStr)); + if (MessageBody =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "Not enough memory for the end chunk transfer\= n")); + return EFI_OUT_OF_RESOURCES; + } + CopyMem (MessageBody, ChunkLengthStr, AsciiStrLen (ChunkLengthStr)); + MessageBodyLength =3D AsciiStrLen (ChunkLengthStr); + *SendChunkProcess =3D HttpIoSendChunkFinish; + break; + + default: + return EFI_INVALID_PARAMETER; + } + + Status =3D HttpIoSendRequest ( + HttpIo, + SentRequestData, + HeaderCount, + NewHeaders, + MessageBodyLength, + MessageBody + ); + if (ContentLengthHeader !=3D NULL) { + if (ContentLengthHeader->FieldName !=3D NULL) { + FreePool (ContentLengthHeader->FieldName); + } + if (ContentLengthHeader->FieldValue !=3D NULL) { + FreePool (ContentLengthHeader->FieldValue); + } + } + if (NewHeaders !=3D NULL) { + FreePool (NewHeaders); + } + if (MessageBody !=3D NULL) { + FreePool (MessageBody); + } + return Status; +} + +/** + Synchronously receive a HTTP RESPONSE message from the server. + + @param[in] HttpIo The HttpIo wrapping the HTTP service. + @param[in] HeaderCount Number of headers in Headers. + @param[in] Headers Array containing list of HTTP headers. + @param[out] ChunkListHead A pointer to receive list head + of chunked data. Caller has to + release memory of ChunkListHead + and all list entries. + @param[out] ContentLength Total content length + + @retval EFI_SUCCESS The HTTP chunked transfer is received. + @retval EFI_NOT_FOUND No chunked transfer coding header found. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_INVALID_PARAMETER Improper parameters. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +HttpIoGetChunkedTransferContent ( + IN HTTP_IO *HttpIo, + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + OUT LIST_ENTRY **ChunkListHead, + OUT UINTN *ContentLength + ) +{ + EFI_HTTP_HEADER *Header; + CHAR8 ChunkSizeAscii [256]; + EFI_STATUS Status; + UINTN Index; + HTTP_IO_RESPONSE_DATA ResponseData; + UINTN TotalLength; + UINTN MaxTotalLength; + LIST_ENTRY *HttpChunks; + HTTP_IO_CHUNKS *ThisChunk; + LIST_ENTRY *ThisListEntry; + + if (ChunkListHead =3D=3D NULL || ContentLength =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + *ContentLength =3D 0; + Header =3D HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_TRANSFER_EN= CODING); + if (Header =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + if (AsciiStrCmp (Header->FieldValue, HTTP_HEADER_TRANSFER_ENCODING_CHUNK= ED) !=3D 0) { + return EFI_NOT_FOUND; + } + // + // Loop to get all chunks. + // + TotalLength =3D 0; + MaxTotalLength =3D PcdGet32 (PcdMaxHttpChunkTransfer); + HttpChunks =3D (LIST_ENTRY *)AllocateZeroPool (sizeof (LIST_ENTRY)); + if (HttpChunks =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ExitDeleteChunks; + } + InitializeListHead (HttpChunks); + DEBUG ((DEBUG_INFO, " Chunked transfer\n")); + while (TRUE) { + ZeroMem((VOID *)&ResponseData, sizeof(HTTP_IO_RESPONSE_DATA)); + ResponseData.BodyLength =3D HTTP_IO_CHUNKED_TRANSFER_CODING_DATA_LENGT= H; + ResponseData.Body =3D ChunkSizeAscii; + Status =3D HttpIoRecvResponse ( + HttpIo, + FALSE, + &ResponseData + ); + if (EFI_ERROR (Status)) { + goto ExitDeleteChunks; + } + // + // Decoding Chunked Transfer Coding. + // Only decode chunk-size and last chunk. + // + DEBUG ((DEBUG_INFO, " Chunk HTTP Response StatusCode - %d\n", Resp= onseData.Response.StatusCode)); + // + // Break if this is last chunk. + // + if (ChunkSizeAscii [0] =3D=3D CHUNKED_TRANSFER_CODING_LAST_CHUNK) { + // + // Check if this is a valid Last-Chunk. + // + if ((ChunkSizeAscii [1] !=3D CHUNKED_TRANSFER_CODING_CR) || + (ChunkSizeAscii [2] !=3D CHUNKED_TRANSFER_CODING_LF) + ) { + DEBUG ((DEBUG_ERROR, " This is an invalid Last-chunk\n")); + Status =3D EFI_INVALID_PARAMETER; + goto ExitDeleteChunks; + } + + Status =3D EFI_SUCCESS; + DEBUG ((DEBUG_INFO, " Last-chunk\n")); + ThisChunk =3D (HTTP_IO_CHUNKS *)AllocateZeroPool (sizeof (HTTP_IO_CH= UNKS)); + if (ThisChunk =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ExitDeleteChunks; + } + + InitializeListHead (&ThisChunk->NextChunk); + ThisChunk->Length =3D ResponseData.BodyLength - 1 - 2; // Minus size= of '0' and CRLF. + ThisChunk->Data =3D (CHAR8 *)AllocatePool (ThisChunk->Length); + if (ThisChunk->Data =3D=3D NULL) { + FreePool ((UINT8 *)ThisChunk); + Status =3D EFI_OUT_OF_RESOURCES; + goto ExitDeleteChunks; + } + CopyMem ((UINT8 *)ThisChunk->Data, (UINT8 *)ResponseData.Body + 1, T= hisChunk->Length); + TotalLength +=3D ThisChunk->Length; + InsertTailList (HttpChunks, &ThisChunk->NextChunk); + break; + } + + // + // Get the chunk length + // + Index =3D 0; + while ((ChunkSizeAscii [Index] !=3D CHUNKED_TRANSFER_CODING_EXTENSION_= SEPARATOR) && + (ChunkSizeAscii [Index] !=3D (CHAR8)CHUNKED_TRANSFER_CODING_CR)= && + (Index !=3D HTTP_IO_CHUNKED_TRANSFER_CODING_DATA_LENGTH)) { + Index ++; + } + + if (Index =3D=3D HTTP_IO_CHUNKED_TRANSFER_CODING_DATA_LENGTH) { + Status =3D EFI_NOT_FOUND; + goto ExitDeleteChunks; + } + ChunkSizeAscii[Index] =3D 0; + AsciiStrHexToUintnS (ChunkSizeAscii, NULL, ContentLength); + DEBUG ((DEBUG_INFO, " Length of this chunk %d\n", *ContentLength)); + // + // Receive the data; + // + ThisChunk =3D (HTTP_IO_CHUNKS *)AllocateZeroPool (sizeof (HTTP_IO_CHUN= KS)); + if (ThisChunk =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ExitDeleteChunks; + } + ResponseData.BodyLength =3D *ContentLength; + ResponseData.Body =3D (CHAR8 *)AllocatePool (*ContentLength); + if (ResponseData.Body =3D=3D NULL) { + FreePool (ThisChunk); + Status =3D EFI_OUT_OF_RESOURCES; + goto ExitDeleteChunks; + } + InitializeListHead (&ThisChunk->NextChunk); + ThisChunk->Length =3D *ContentLength; + ThisChunk->Data =3D ResponseData.Body; + InsertTailList (HttpChunks, &ThisChunk->NextChunk); + Status =3D HttpIoRecvResponse ( + HttpIo, + FALSE, + &ResponseData + ); + if (EFI_ERROR (Status)) { + goto ExitDeleteChunks; + } + // + // Read CRLF + // + ZeroMem((VOID *)&ResponseData, sizeof(HTTP_IO_RESPONSE_DATA)); + ResponseData.BodyLength =3D 2; + ResponseData.Body =3D ChunkSizeAscii; + Status =3D HttpIoRecvResponse ( + HttpIo, + FALSE, + &ResponseData + ); + if (EFI_ERROR (Status)) { + goto ExitDeleteChunks; + } + // + // Verify the end of chunk payload. + // + if ((ChunkSizeAscii [0] !=3D CHUNKED_TRANSFER_CODING_CR) || + (ChunkSizeAscii [1] !=3D CHUNKED_TRANSFER_CODING_LF) + ) { + DEBUG ((DEBUG_ERROR, " This is an invalid End-of-chunk notation= .\n")); + goto ExitDeleteChunks; + } + TotalLength +=3D *ContentLength; + if (TotalLength > MaxTotalLength) { + DEBUG ((DEBUG_ERROR, " Total chunk transfer payload exceeds the= size defined by PcdMaxHttpChunkTransfer.\n")); + goto ExitDeleteChunks; + } + } + + *ContentLength =3D TotalLength; + *ChunkListHead =3D HttpChunks; + DEBUG ((DEBUG_INFO, " Total of lengh of chunks :%d\n", TotalLength)); + return EFI_SUCCESS; + +ExitDeleteChunks: + if (HttpChunks !=3D NULL) { + while (!IsListEmpty(HttpChunks)) { + ThisListEntry =3D GetFirstNode (HttpChunks); + RemoveEntryList (ThisListEntry); + ThisChunk =3D (HTTP_IO_CHUNKS *)ThisListEntry; + if (ThisChunk->Data !=3D NULL) { + FreePool (ThisChunk->Data); + } + FreePool(ThisListEntry); + } + FreePool (HttpChunks); + } + return Status; +} diff --git a/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf b/NetworkPkg/= Library/DxeHttpIoLib/DxeHttpIoLib.inf new file mode 100644 index 0000000000..d20cace84e --- /dev/null +++ b/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf @@ -0,0 +1,46 @@ +## @file +# This library instance provides HTTP IO helper functions. +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001b + BASE_NAME =3D DxeHttpIoLib + MODULE_UNI_FILE =3D DxeHttpIoLib.uni + FILE_GUID =3D 50B198F8-7986-4F51-A857-CFE4643D59F3 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D HttpIoLib| DXE_CORE DXE_DRIVER DXE_RU= NTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC ARM AARM64 RISCV64 +# + +[Sources] + DxeHttpIoLib.c + +[Packages] + MdePkg/MdePkg.dec + NetworkPkg/NetworkPkg.dec + + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DpcLib + MemoryAllocationLib + PrintLib + UefiBootServicesTableLib + +[Protocols] + gEfiHttpProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd] + gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer ## SOMETIMES_CONSU= MES + diff --git a/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.uni b/NetworkPkg/= Library/DxeHttpIoLib/DxeHttpIoLib.uni new file mode 100644 index 0000000000..d419b1a49d --- /dev/null +++ b/NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.uni @@ -0,0 +1,13 @@ +// /** @file +// The library instance provides HTTP IO helper functions. +// +// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "HTTP IO Helper Li= brary" + +#string STR_MODULE_DESCRIPTION #language en-US "The library insta= nce provides HTTP IO helper functions." + --=20 2.17.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#66915): https://edk2.groups.io/g/devel/message/66915 Mute This Topic: https://groups.io/mt/78001076/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 10:50:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+66916+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66916+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1604383946; cv=none; d=zohomail.com; s=zohoarc; b=k9Pv8lfkDJO7qQuhUKeMs9zNhPrYc447t2gcdAfiF+4mhWmROwELjSEuO6ikM1hoLKxLbxsjmUoa2HqWGD6tA1c2YRlnYoHBpXEWgV4ZP4jaktBPbf7StYK6ZmGwszFuRvifjV/RtFE1eJPyjkS/d64JfYjMvSufP/sVYRjoKsw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604383946; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=S+LNNemQflV2JIRpoJMdtk+niqN5YdwadYyzs4KOLS0=; b=d7nw/Nwhhi+x3Jr1b/AsHgkFZWGciVkjcz4O+1Vn3puxKNeXhRetMD65eNc0ZigXQ/regGhYMgrJWMqzOHX1nc1oM3Z8cDCQkPOhi51r7wsY0g2RGZu0/pxkqzu8gFxt4HX8Fz5kaVvR9Z7a3oImj5nS2gSk4TYF+bV3U3ovqek= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66916+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604383946224504.6376997193976; Mon, 2 Nov 2020 22:12:26 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id wtjUYY1788612xyEntw8gH00; Mon, 02 Nov 2020 22:12:25 -0800 X-Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by mx.groups.io with SMTP id smtpd.web08.422.1604383945491066773 for ; Mon, 02 Nov 2020 22:12:25 -0800 X-Received: from pps.filterd (m0150242.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0A3688Qo030939; Tue, 3 Nov 2020 06:12:25 GMT X-Received: from g2t2352.austin.hpe.com (g2t2352.austin.hpe.com [15.233.44.25]) by mx0a-002e3701.pphosted.com with ESMTP id 34hj0g05gq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 03 Nov 2020 06:12:25 +0000 X-Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2352.austin.hpe.com (Postfix) with ESMTP id 64318A7; Tue, 3 Nov 2020 06:12:24 +0000 (UTC) X-Received: from abner-virtual-machine.asiapacific.hpqcorp.net (abner-virtual-machine.asiapacific.hpqcorp.net [15.119.210.153]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id 3707239; Tue, 3 Nov 2020 06:12:23 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: Maciej Rabeda , Jiaxin Wu , Siyuan Fu , Nickle Wang Subject: [edk2-devel] [DxeHttpIoLib PATCH V5 2/3] NetworkPkg: Add Http IO Helper Library to NetworkPkg Date: Tue, 3 Nov 2020 13:26:50 +0800 Message-Id: <20201103052651.16250-3-abner.chang@hpe.com> In-Reply-To: <20201103052651.16250-1-abner.chang@hpe.com> References: <20201103052651.16250-1-abner.chang@hpe.com> X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: XMu7MAH6UvBFFXxllhtnfO2Ax1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604383945; bh=uiGfJyIpONtRuLyE5V/hrw8qnmc3hPjKACDu/IxHCCE=; h=Cc:Date:From:Reply-To:Subject:To; b=gOk1AW009EA+3n0PS4+RAp4ENE9Hv7CrqidbkGwuUl6WvtyN4AuswwaCDZ3b1CzFnG9 PE+gXRamOHqBrR6p2Lv+YLv4YlKc8j9qRFT8dqIjmmuUTqWDuUlbyP169Y++0It/R5sAb IxUAygdolpuhYxMoLrBrPeeh7fzo5mgsEWM= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This library provides HTTP IO helper functions. Signed-off-by: Abner Chang Cc: Maciej Rabeda Cc: Jiaxin Wu Cc: Siyuan Fu Cc: Nickle Wang Reviewed-by: Maciej Rabeda --- NetworkPkg/NetworkLibs.dsc.inc | 5 ++++- NetworkPkg/NetworkPkg.dec | 10 +++++++++- NetworkPkg/NetworkPkg.dsc | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/NetworkPkg/NetworkLibs.dsc.inc b/NetworkPkg/NetworkLibs.dsc.inc index 4b99f48085..7cfc1a151a 100644 --- a/NetworkPkg/NetworkLibs.dsc.inc +++ b/NetworkPkg/NetworkLibs.dsc.inc @@ -6,6 +6,7 @@ # of EDKII network library classes. # # Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -16,5 +17,7 @@ IpIoLib|NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf UdpIoLib|NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf TcpIoLib|NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf - # HttpLib is used for Http Boot + # HttpLib and HttpIoLib are used for Http Boot and other + # HTTP applications. HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf + HttpIoLib|NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index 66e500cbea..2d0d7fd2dc 100644 --- a/NetworkPkg/NetworkPkg.dec +++ b/NetworkPkg/NetworkPkg.dec @@ -4,7 +4,7 @@ # This package provides network modules that conform to UEFI 2.4 specifica= tion. # # Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
-# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP
+# (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -41,6 +41,10 @@ # This library is only intended to be used by UEFI network stack modul= es. HttpLib|Include/Library/HttpLib.h =20 + ## @libraryclass Http IO helper routines for HTTP transfer. + # This library is only intended to be used by UEFI network stack modul= es. + HttpIoLib|Include/Library/HttpIoLib.h + ## @libraryclass Library for Deferred Procedure Calls. DpcLib|Include/Library/DpcLib.h =20 @@ -89,6 +93,10 @@ # @Prompt Max attempt number. gEfiNetworkPkgTokenSpaceGuid.PcdMaxIScsiAttemptNumber|0x08|UINT8|0x00000= 00D =20 + ## The maximum size of total HTTP chunk transfer. + # @Prompt Max size of total HTTP chunk transfer. the default value is 12= MB. + gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer|0x0C00000|UINT32|0x= 0000000E + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Indicates whether HTTP connections (i.e., unsecured) are permitted or= not. # TRUE - HTTP connections are allowed. Both the "https://" and "http://= " URI schemes are permitted. diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 716d04fdad..216479a2f6 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -107,6 +107,7 @@ NetworkPkg/Application/VConfig/VConfig.inf NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf + NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf NetworkPkg/Library/DxeNetLib/DxeNetLib.inf NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf --=20 2.17.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#66916): https://edk2.groups.io/g/devel/message/66916 Mute This Topic: https://groups.io/mt/78001078/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon May 13 10:50:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+66917+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66917+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1604383953; cv=none; d=zohomail.com; s=zohoarc; b=ewmR2NCIcQ0PPLGFbMeFV/35KXQ0aglygkjTxW1a6a9gQg5CWNmgnvlfhHTPQOo66BHu3CZM8UvQRS7yaqS3mANrEyifoCv4x5neKfukU4F2lG4fuMxP8PsfTBNDKXZwcWHeSslzyMRlRvYkbrUniqd2aAOd8w6+nQP+q4r14iE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604383953; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=s1DphHwYn/nTmxLpq+2wY5WtRsAGBnxDIrdNYStDQt0=; b=eQ1vaMGGv3UcsybhEysfut9EHoqiOWcojppOEErgYyTnuUxrjT1C4EgIl+O2c+hiymTzILRHj080oGMJwrCsGnSLw1CxZ+TGgkCzScoC6qG1vm8QKiFdEYqsbWXaVobl1YqRHPVYWhLgWFwOjsbdxBB5YWDZv6GycBzX0rsy8+A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66917+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604383953323655.7767649948189; Mon, 2 Nov 2020 22:12:33 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id xF2ZYY1788612xPJ5ya97Ex5; Mon, 02 Nov 2020 22:12:32 -0800 X-Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web12.433.1604383947264665956 for ; Mon, 02 Nov 2020 22:12:27 -0800 X-Received: from pps.filterd (m0150244.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0A363RYs012872; Tue, 3 Nov 2020 06:12:26 GMT X-Received: from g2t2354.austin.hpe.com (g2t2354.austin.hpe.com [15.233.44.27]) by mx0b-002e3701.pphosted.com with ESMTP id 34h0k2539h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 03 Nov 2020 06:12:26 +0000 X-Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2354.austin.hpe.com (Postfix) with ESMTP id E30DFAE; Tue, 3 Nov 2020 06:12:25 +0000 (UTC) X-Received: from abner-virtual-machine.asiapacific.hpqcorp.net (abner-virtual-machine.asiapacific.hpqcorp.net [15.119.210.153]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id B391737; Tue, 3 Nov 2020 06:12:24 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: Maciej Rabeda , Jiaxin Wu , Siyuan Fu , Nickle Wang Subject: [edk2-devel] [DxeHttpIoLib PATCH V5 3/3] NetworkPkg/HttpBootDxe: Utilize HttpIoLib Date: Tue, 3 Nov 2020 13:26:51 +0800 Message-Id: <20201103052651.16250-4-abner.chang@hpe.com> In-Reply-To: <20201103052651.16250-1-abner.chang@hpe.com> References: <20201103052651.16250-1-abner.chang@hpe.com> X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: ya5mgWAq42YoDaDeuPBO3Ocix1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604383952; bh=J1UsKuIzdBsZuBWzUFgcJ8W4NF7pMsL6mUGuZzjYJ6w=; h=Cc:Date:From:Reply-To:Subject:To; b=Mz3mVARKVQxGKG8HZetx71POBQK4LnOzt86G98UKKodWbbYMtf0l2ZA0AbPhuaFe10I 6Tu/I2IAEgPhmw+o6gvT1NDLdF7CfSIPduhe99rtxINQkM89SZPePFdCC8r6tVwzpxMn6 ccvnS/Lgwf1z+Ud7/orUPsfOmLI5153DKJg= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Remove HTTP IO realted funcitons from HttpBootDxe and use HttpIoLib instead. Signed-off-by: Abner Chang Cc: Maciej Rabeda Cc: Jiaxin Wu Cc: Siyuan Fu Cc: Nickle Wang Reviewed-by: Maciej Rabeda --- NetworkPkg/HttpBootDxe/HttpBootDxe.h | 3 +- NetworkPkg/HttpBootDxe/HttpBootDxe.inf | 2 + NetworkPkg/HttpBootDxe/HttpBootSupport.c | 431 +---------------------- NetworkPkg/HttpBootDxe/HttpBootSupport.h | 189 +--------- 4 files changed, 6 insertions(+), 619 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/= HttpBootDxe.h index 0b45f9de0b..d692c3ad3c 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -2,7 +2,7 @@ UEFI HTTP boot driver's private data structure and interfaces declaratio= n. =20 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+(C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -28,6 +28,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include #include diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf b/NetworkPkg/HttpBootDx= e/HttpBootDxe.inf index 5beab728dd..a27a561722 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf @@ -2,6 +2,7 @@ # This modules produce the Load File Protocol for UEFI HTTP boot. # # Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+# (C) Copyright 2020 Hewlett-Packard Development Company, L.P.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -52,6 +53,7 @@ DebugLib NetLib HttpLib + HttpIoLib HiiLib PrintLib DpcLib diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBoot= Dxe/HttpBootSupport.c index 5b0e054a05..93d9dfc464 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -2,7 +2,7 @@ Support functions implementation for UEFI HTTP boot driver. =20 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+(C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -622,435 +622,6 @@ HttpBootSetHeader ( return EFI_SUCCESS; } =20 -/** - Notify the callback function when an event is triggered. - - @param[in] Context The opaque parameter to the function. - -**/ -VOID -EFIAPI -HttpIoNotifyDpc ( - IN VOID *Context - ) -{ - *((BOOLEAN *) Context) =3D TRUE; -} - -/** - Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK. - - @param[in] Event The event signaled. - @param[in] Context The opaque parameter to the function. - -**/ -VOID -EFIAPI -HttpIoNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK - // - QueueDpc (TPL_CALLBACK, HttpIoNotifyDpc, Context); -} - -/** - Create a HTTP_IO to access the HTTP service. It will create and configure - a HTTP child handle. - - @param[in] Image The handle of the driver image. - @param[in] Controller The handle of the controller. - @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. - @param[in] ConfigData The HTTP_IO configuration data. - @param[in] Callback Callback function which will be invoked when = specified - HTTP_IO_CALLBACK_EVENT happened. - @param[in] Context The Context data which will be passed to the = Callback function. - @param[out] HttpIo The HTTP_IO. - - @retval EFI_SUCCESS The HTTP_IO is created and configured. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED One or more of the control options are not - supported in the implementation. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval Others Failed to create the HTTP_IO or configure= it. - -**/ -EFI_STATUS -HttpIoCreateIo ( - IN EFI_HANDLE Image, - IN EFI_HANDLE Controller, - IN UINT8 IpVersion, - IN HTTP_IO_CONFIG_DATA *ConfigData, - IN HTTP_IO_CALLBACK Callback, - IN VOID *Context, - OUT HTTP_IO *HttpIo - ) -{ - EFI_STATUS Status; - EFI_HTTP_CONFIG_DATA HttpConfigData; - EFI_HTTPv4_ACCESS_POINT Http4AccessPoint; - EFI_HTTPv6_ACCESS_POINT Http6AccessPoint; - EFI_HTTP_PROTOCOL *Http; - EFI_EVENT Event; - - if ((Image =3D=3D NULL) || (Controller =3D=3D NULL) || (ConfigData =3D= =3D NULL) || (HttpIo =3D=3D NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (IpVersion !=3D IP_VERSION_4 && IpVersion !=3D IP_VERSION_6) { - return EFI_UNSUPPORTED; - } - - ZeroMem (HttpIo, sizeof (HTTP_IO)); - - // - // Create the HTTP child instance and get the HTTP protocol. - // - Status =3D NetLibCreateServiceChild ( - Controller, - Image, - &gEfiHttpServiceBindingProtocolGuid, - &HttpIo->Handle - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status =3D gBS->OpenProtocol ( - HttpIo->Handle, - &gEfiHttpProtocolGuid, - (VOID **) &Http, - Image, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) || (Http =3D=3D NULL)) { - goto ON_ERROR; - } - - // - // Init the configuration data and configure the HTTP child. - // - HttpIo->Image =3D Image; - HttpIo->Controller =3D Controller; - HttpIo->IpVersion =3D IpVersion; - HttpIo->Http =3D Http; - HttpIo->Callback =3D Callback; - HttpIo->Context =3D Context; - - ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); - HttpConfigData.HttpVersion =3D HttpVersion11; - HttpConfigData.TimeOutMillisec =3D ConfigData->Config4.RequestTimeOut; - if (HttpIo->IpVersion =3D=3D IP_VERSION_4) { - HttpConfigData.LocalAddressIsIPv6 =3D FALSE; - - Http4AccessPoint.UseDefaultAddress =3D ConfigData->Config4.UseDefaultA= ddress; - Http4AccessPoint.LocalPort =3D ConfigData->Config4.LocalPort; - IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Config4= .LocalIp); - IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config4.= SubnetMask); - HttpConfigData.AccessPoint.IPv4Node =3D &Http4AccessPoint; - } else { - HttpConfigData.LocalAddressIsIPv6 =3D TRUE; - Http6AccessPoint.LocalPort =3D ConfigData->Config6.LocalPort; - IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Config6= .LocalIp); - HttpConfigData.AccessPoint.IPv6Node =3D &Http6AccessPoint; - } - - Status =3D Http->Configure (Http, &HttpConfigData); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Create events for various asynchronous operations. - // - Status =3D gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpIoNotify, - &HttpIo->IsTxDone, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->ReqToken.Event =3D Event; - HttpIo->ReqToken.Message =3D &HttpIo->ReqMessage; - - Status =3D gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpIoNotify, - &HttpIo->IsRxDone, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->RspToken.Event =3D Event; - HttpIo->RspToken.Message =3D &HttpIo->RspMessage; - - // - // Create TimeoutEvent for response - // - Status =3D gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - HttpIo->TimeoutEvent =3D Event; - - return EFI_SUCCESS; - -ON_ERROR: - HttpIoDestroyIo (HttpIo); - - return Status; -} - -/** - Destroy the HTTP_IO and release the resources. - - @param[in] HttpIo The HTTP_IO which wraps the HTTP service to = be destroyed. - -**/ -VOID -HttpIoDestroyIo ( - IN HTTP_IO *HttpIo - ) -{ - EFI_HTTP_PROTOCOL *Http; - EFI_EVENT Event; - - if (HttpIo =3D=3D NULL) { - return; - } - - Event =3D HttpIo->ReqToken.Event; - if (Event !=3D NULL) { - gBS->CloseEvent (Event); - } - - Event =3D HttpIo->RspToken.Event; - if (Event !=3D NULL) { - gBS->CloseEvent (Event); - } - - Event =3D HttpIo->TimeoutEvent; - if (Event !=3D NULL) { - gBS->CloseEvent (Event); - } - - Http =3D HttpIo->Http; - if (Http !=3D NULL) { - Http->Configure (Http, NULL); - gBS->CloseProtocol ( - HttpIo->Handle, - &gEfiHttpProtocolGuid, - HttpIo->Image, - HttpIo->Controller - ); - } - - NetLibDestroyServiceChild ( - HttpIo->Controller, - HttpIo->Image, - &gEfiHttpServiceBindingProtocolGuid, - HttpIo->Handle - ); -} - -/** - Synchronously send a HTTP REQUEST message to the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] Request A pointer to storage such data as URL and = HTTP method. - @param[in] HeaderCount Number of HTTP header structures in Header= s list. - @param[in] Headers Array containing list of HTTP headers. - @param[in] BodyLength Length in bytes of the HTTP body. - @param[in] Body Body associated with the HTTP request. - - @retval EFI_SUCCESS The HTTP request is transmitted. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -HttpIoSendRequest ( - IN HTTP_IO *HttpIo, - IN EFI_HTTP_REQUEST_DATA *Request, - IN UINTN HeaderCount, - IN EFI_HTTP_HEADER *Headers, - IN UINTN BodyLength, - IN VOID *Body - ) -{ - EFI_STATUS Status; - EFI_HTTP_PROTOCOL *Http; - - if (HttpIo =3D=3D NULL || HttpIo->Http =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - HttpIo->ReqToken.Status =3D EFI_NOT_READY; - HttpIo->ReqToken.Message->Data.Request =3D Request; - HttpIo->ReqToken.Message->HeaderCount =3D HeaderCount; - HttpIo->ReqToken.Message->Headers =3D Headers; - HttpIo->ReqToken.Message->BodyLength =3D BodyLength; - HttpIo->ReqToken.Message->Body =3D Body; - - if (HttpIo->Callback !=3D NULL) { - Status =3D HttpIo->Callback ( - HttpIoRequest, - HttpIo->ReqToken.Message, - HttpIo->Context - ); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Queue the request token to HTTP instances. - // - Http =3D HttpIo->Http; - HttpIo->IsTxDone =3D FALSE; - Status =3D Http->Request ( - Http, - &HttpIo->ReqToken - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Poll the network until transmit finish. - // - while (!HttpIo->IsTxDone) { - Http->Poll (Http); - } - - return HttpIo->ReqToken.Status; -} - -/** - Synchronously receive a HTTP RESPONSE message from the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] RecvMsgHeader TRUE to receive a new HTTP response (from = message header). - FALSE to continue receive the previous res= ponse message. - @param[out] ResponseData Point to a wrapper of the received respons= e data. - - @retval EFI_SUCCESS The HTTP response is received. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -HttpIoRecvResponse ( - IN HTTP_IO *HttpIo, - IN BOOLEAN RecvMsgHeader, - OUT HTTP_IO_RESPONSE_DATA *ResponseData - ) -{ - EFI_STATUS Status; - EFI_HTTP_PROTOCOL *Http; - - if (HttpIo =3D=3D NULL || HttpIo->Http =3D=3D NULL || ResponseData =3D= =3D NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Start the timer, and wait Timeout seconds to receive the header packe= t. - // - Status =3D gBS->SetTimer (HttpIo->TimeoutEvent, TimerRelative, HTTP_BOOT= _RESPONSE_TIMEOUT * TICKS_PER_MS); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Queue the response token to HTTP instances. - // - HttpIo->RspToken.Status =3D EFI_NOT_READY; - if (RecvMsgHeader) { - HttpIo->RspToken.Message->Data.Response =3D &ResponseData->Response; - } else { - HttpIo->RspToken.Message->Data.Response =3D NULL; - } - HttpIo->RspToken.Message->HeaderCount =3D 0; - HttpIo->RspToken.Message->Headers =3D NULL; - HttpIo->RspToken.Message->BodyLength =3D ResponseData->BodyLength; - HttpIo->RspToken.Message->Body =3D ResponseData->Body; - - Http =3D HttpIo->Http; - HttpIo->IsRxDone =3D FALSE; - Status =3D Http->Response ( - Http, - &HttpIo->RspToken - ); - - if (EFI_ERROR (Status)) { - gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); - return Status; - } - - // - // Poll the network until receive finish. - // - while (!HttpIo->IsRxDone && ((HttpIo->TimeoutEvent =3D=3D NULL) || EFI_E= RROR (gBS->CheckEvent (HttpIo->TimeoutEvent)))) { - Http->Poll (Http); - } - - gBS->SetTimer (HttpIo->TimeoutEvent, TimerCancel, 0); - - if (!HttpIo->IsRxDone) { - // - // Timeout occurs, cancel the response token. - // - Http->Cancel (Http, &HttpIo->RspToken); - - Status =3D EFI_TIMEOUT; - - return Status; - } else { - HttpIo->IsRxDone =3D FALSE; - } - - if ((HttpIo->Callback !=3D NULL) && - (HttpIo->RspToken.Status =3D=3D EFI_SUCCESS || HttpIo->RspToken.Stat= us =3D=3D EFI_HTTP_ERROR)) { - Status =3D HttpIo->Callback ( - HttpIoResponse, - HttpIo->RspToken.Message, - HttpIo->Context - ); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Store the received data into the wrapper. - // - ResponseData->Status =3D HttpIo->RspToken.Status; - ResponseData->HeaderCount =3D HttpIo->RspToken.Message->HeaderCount; - ResponseData->Headers =3D HttpIo->RspToken.Message->Headers; - ResponseData->BodyLength =3D HttpIo->RspToken.Message->BodyLength; - - return Status; -} - /** This function checks the HTTP(S) URI scheme. =20 diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBoot= Dxe/HttpBootSupport.h index 81d072ae37..1a2d32dd5a 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h @@ -2,6 +2,7 @@ Support functions declaration for UEFI HTTP boot driver. =20 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2020 Hewlett-Packard Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -139,102 +140,6 @@ HttpBootSetHeader ( IN CHAR8 *FieldValue ); =20 -/// -/// HTTP_IO_CALLBACK_EVENT -/// -typedef enum { - HttpIoRequest, - HttpIoResponse -} HTTP_IO_CALLBACK_EVENT; - -/** - HttpIo Callback function which will be invoked when specified HTTP_IO_CA= LLBACK_EVENT happened. - - @param[in] EventType Indicate the Event type that occurs in the = current callback. - @param[in] Message HTTP message which will be send to, or just= received from HTTP server. - @param[in] Context The Callback Context pointer. - - @retval EFI_SUCCESS Tells the HttpIo to continue the HTTP proce= ss. - @retval Others Tells the HttpIo to abort the current HTTP = process. -**/ -typedef -EFI_STATUS -(EFIAPI * HTTP_IO_CALLBACK) ( - IN HTTP_IO_CALLBACK_EVENT EventType, - IN EFI_HTTP_MESSAGE *Message, - IN VOID *Context - ); - -// -// HTTP_IO configuration data for IPv4 -// -typedef struct { - EFI_HTTP_VERSION HttpVersion; - UINT32 RequestTimeOut; // In milliseconds. - UINT32 ResponseTimeOut; // In milliseconds. - BOOLEAN UseDefaultAddress; - EFI_IPv4_ADDRESS LocalIp; - EFI_IPv4_ADDRESS SubnetMask; - UINT16 LocalPort; -} HTTP4_IO_CONFIG_DATA; - -// -// HTTP_IO configuration data for IPv6 -// -typedef struct { - EFI_HTTP_VERSION HttpVersion; - UINT32 RequestTimeOut; // In milliseconds. - BOOLEAN UseDefaultAddress; - EFI_IPv6_ADDRESS LocalIp; - UINT16 LocalPort; -} HTTP6_IO_CONFIG_DATA; - - -// -// HTTP_IO configuration -// -typedef union { - HTTP4_IO_CONFIG_DATA Config4; - HTTP6_IO_CONFIG_DATA Config6; -} HTTP_IO_CONFIG_DATA; - -// -// HTTP_IO wrapper of the EFI HTTP service. -// -typedef struct { - UINT8 IpVersion; - EFI_HANDLE Image; - EFI_HANDLE Controller; - EFI_HANDLE Handle; - - EFI_HTTP_PROTOCOL *Http; - - HTTP_IO_CALLBACK Callback; - VOID *Context; - - EFI_HTTP_TOKEN ReqToken; - EFI_HTTP_MESSAGE ReqMessage; - EFI_HTTP_TOKEN RspToken; - EFI_HTTP_MESSAGE RspMessage; - - BOOLEAN IsTxDone; - BOOLEAN IsRxDone; - - EFI_EVENT TimeoutEvent; -} HTTP_IO; - -// -// A wrapper structure to hold the received HTTP response data. -// -typedef struct { - EFI_HTTP_RESPONSE_DATA Response; - UINTN HeaderCount; - EFI_HTTP_HEADER *Headers; - UINTN BodyLength; - CHAR8 *Body; - EFI_STATUS Status; -} HTTP_IO_RESPONSE_DATA; - /** Retrieve the host address using the EFI_DNS6_PROTOCOL. =20 @@ -267,98 +172,6 @@ HttpBootCommonNotify ( IN VOID *Context ); =20 -/** - Create a HTTP_IO to access the HTTP service. It will create and configure - a HTTP child handle. - - @param[in] Image The handle of the driver image. - @param[in] Controller The handle of the controller. - @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. - @param[in] ConfigData The HTTP_IO configuration data. - @param[in] Callback Callback function which will be invoked when = specified - HTTP_IO_CALLBACK_EVENT happened. - @param[in] Context The Context data which will be passed to the = Callback function. - @param[out] HttpIo The HTTP_IO. - - @retval EFI_SUCCESS The HTTP_IO is created and configured. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED One or more of the control options are not - supported in the implementation. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval Others Failed to create the HTTP_IO or configure= it. - -**/ -EFI_STATUS -HttpIoCreateIo ( - IN EFI_HANDLE Image, - IN EFI_HANDLE Controller, - IN UINT8 IpVersion, - IN HTTP_IO_CONFIG_DATA *ConfigData, - IN HTTP_IO_CALLBACK Callback, - IN VOID *Context, - OUT HTTP_IO *HttpIo - ); - -/** - Destroy the HTTP_IO and release the resources. - - @param[in] HttpIo The HTTP_IO which wraps the HTTP service to = be destroyed. - -**/ -VOID -HttpIoDestroyIo ( - IN HTTP_IO *HttpIo - ); - -/** - Synchronously send a HTTP REQUEST message to the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] Request A pointer to storage such data as URL and = HTTP method. - @param[in] HeaderCount Number of HTTP header structures in Header= s list. - @param[in] Headers Array containing list of HTTP headers. - @param[in] BodyLength Length in bytes of the HTTP body. - @param[in] Body Body associated with the HTTP request. - - @retval EFI_SUCCESS The HTTP request is transmitted. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -HttpIoSendRequest ( - IN HTTP_IO *HttpIo, - IN EFI_HTTP_REQUEST_DATA *Request, OPTIONAL - IN UINTN HeaderCount, - IN EFI_HTTP_HEADER *Headers, OPTIONAL - IN UINTN BodyLength, - IN VOID *Body OPTIONAL - ); - -/** - Synchronously receive a HTTP RESPONSE message from the server. - - @param[in] HttpIo The HttpIo wrapping the HTTP service. - @param[in] RecvMsgHeader TRUE to receive a new HTTP response (from = message header). - FALSE to continue receive the previous res= ponse message. - @param[out] ResponseData Point to a wrapper of the received respons= e data. - - @retval EFI_SUCCESS The HTTP response is received. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval EFI_DEVICE_ERROR An unexpected network or system error occ= urred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -HttpIoRecvResponse ( - IN HTTP_IO *HttpIo, - IN BOOLEAN RecvMsgHeader, - OUT HTTP_IO_RESPONSE_DATA *ResponseData - ); - /** This function checks the HTTP(S) URI scheme. =20 --=20 2.17.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#66917): https://edk2.groups.io/g/devel/message/66917 Mute This Topic: https://groups.io/mt/78001082/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-