From nobody Wed May 15 16:31:14 2024 Delivered-To: importer@patchew.org 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+110084+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1698312627794112.27016383927014; Thu, 26 Oct 2023 02:30:27 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=zoaxGz2yhA7sJumnX2C63SX80w5u6+0LzqqMw4VZWyk=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1698312627; v=1; b=gS26cEKAzuzek57LOfg61MoVMTHsR8ztNuMLzi/fHd2+TwaSibVqolJ+0Tee75KgvAuHQ047 soWxuRQM1vLFmmCmBA5cySD1MFpokQVZxub/23yl+W2Cj/7nGDN1qtRoET+y3jR4qwjmRKaCzvY y2mbV1XoWhLUq0F5LqBCZ05Y= X-Received: by 127.0.0.2 with SMTP id lBx5YY1788612xRGa79u4eXs; Thu, 26 Oct 2023 02:30:27 -0700 X-Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.44]) by mx.groups.io with SMTP id smtpd.web10.196090.1698312626245944666 for ; Thu, 26 Oct 2023 02:30:26 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NfqGQiwExOcTIX8VrkrUfQWhw+UGHVC0K4UkhiBDlKqdxxY0LOEB/YU56phOuULP4mUWaW3vKJQXVaEmAlReA/CZm6A30jOIG1GqEqRgxKGjD2h0K1z3Zu2xFRbI9u+hrl+pGHH/SvbKduXc+LJq5zQSjlup3uajjmeI+2OjUh6sHnwiHjdznXpr38Q+c+asMeyMwOG4AEUbPSHbOSmZP/4zBIEtgcBxy+TXDmfVBh3aAssPjZ0xIT3k+9G/06p4w/dHU7EVX7u+96edIZNQSFjNeYGDJCtwYRTpGghMQUDJDSt12dZSHyoBCWGEPJthNt1FcQ3yE3lWIWLJHrOgHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=DPRA0E5vJ0lJ3PztEkMiVft9oGkugtuXalItGm17IKE=; b=VN6B5kPCydvb7pod3ZjdMj5cyxmdugH5YbGwcrRSflqgxnWhGpVIc7XdApnDjajX2UCRL40r9K3O9xEbqwTRMP5Jehthmeag6ASTPoiykDUuHxRe1uWt5EaA/12axn1tkiVJvN0FoLEC+TxNUhKwMEnX+NRu/CvxGICcjtuNLj9yiJYb28oR3iWcy5oyEDtxegIxzPwNBn8osF6vin3KcuaP98vgpol/4wJ7rpKsNZBaTNdZq2wjAkXYt9C8pP8ONj8ikusedl4iLWvUqJ9Y0zewPSneUu3OLfNO1oNKAXkZledZagEEcINuue/greaS1yvwmJhJsQ0cEyC6Or3Ktw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) X-Received: from SJ0PR03CA0168.namprd03.prod.outlook.com (2603:10b6:a03:338::23) by MN0PR12MB5786.namprd12.prod.outlook.com (2603:10b6:208:375::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6907.31; Thu, 26 Oct 2023 09:30:22 +0000 X-Received: from MWH0EPF000971E4.namprd02.prod.outlook.com (2603:10b6:a03:338:cafe::16) by SJ0PR03CA0168.outlook.office365.com (2603:10b6:a03:338::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6907.35 via Frontend Transport; Thu, 26 Oct 2023 09:30:21 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; 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+110084+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C X-Received: from mail.nvidia.com (216.228.118.232) by MWH0EPF000971E4.mail.protection.outlook.com (10.167.243.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.15 via Frontend Transport; Thu, 26 Oct 2023 09:30:21 +0000 X-Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Thu, 26 Oct 2023 02:30:09 -0700 X-Received: from drhqmail203.nvidia.com (10.126.190.182) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.41; Thu, 26 Oct 2023 02:30:09 -0700 X-Received: from NV-CL38DL3.nvidia.com (10.127.8.11) by mail.nvidia.com (10.126.190.182) with Microsoft SMTP Server id 15.2.986.41 via Frontend Transport; Thu, 26 Oct 2023 02:30:08 -0700 From: "Nickle Wang via groups.io" To: CC: Abner Chang , Igor Kulchytskyy , "Nick Ramirez" Subject: [edk2-devel] [edk2-redfish-client][PATCH v2] RedfishClientPkg/RedfishLib: align with edk2 RedfishLib Date: Thu, 26 Oct 2023 17:30:07 +0800 Message-ID: <20231026093007.28717-1-nicklew@nvidia.com> MIME-Version: 1.0 X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWH0EPF000971E4:EE_|MN0PR12MB5786:EE_ X-MS-Office365-Filtering-Correlation-Id: fbbf7025-6b33-4bf1-66fc-08dbd6062cc7 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: WDDp6sRfrgEeF8Deph/oBygLeJ1kCd+p/w1CRguSYnDVoMW1UQxggpYtR4g/zvql5nu4Ql9MRGeCiXRnkWaQBGHhnkJCuhSosJHZvjaX3MsMk+RO5WXFxeF9W6Y0ZGF9vpI46V2NWaexi8CYPkDWUpvNwkAgUizRvrRhn4v39qGeWr7RzZ6bHu3UwKM9Ve5RpssMJxsHd0ZcLPI4g8E5GiKq1bx0dobgjVtpnzzy78GtxeVHrKy/s9r1q9UqxyBf3AaSEXesSV308Up4uqQTdKwh8NeXLaYfXouALyUhMbDR63YSHG3M5Vum5uA0aRFduU8QfT5QGoG8im8n76YQfytrZPwYQCVBJuVrN7RUC8/5bAMoPpiYMLTQEh58gt3ftoZwyYOwfReyk2kyD0ir+zZkTinClJQvsh05F5IWVkRb8gblC5SFIi8yInEpG8BEyl98snJYwNH0oCX5zhJFhIjrcNz0IYaNNSKBdcnHXEJTKPjp21/IahNnzSeh/FT39U0SUzxidpx/zGN0IIJt0+uNFWRwWPV8sn6MrgEkRWC6Ilog3undGYomZb+nDnRPgrQ+CPqrZ67ZQ8fExMO2q5W7oexV2iFsLN23UfqVmluQAtM92RwiKkwC/5ANkJZzZ57RyeFhXLnG+q7rqndelbjAOUMytI13vdUFORv74TCY5F0N/0g8v3jU0vtdHL2J3jbTD5XFg9iLx4vn80KKHc09jRBWXxuVyankI8P88qekj6F/qPBc/ccjQPdSih0bOEJoxtj1Vx6CsEM4hz6jijIzAkSjpKRYgQFCagYrlhg= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Oct 2023 09:30:21.1689 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fbbf7025-6b33-4bf1-66fc-08dbd6062cc7 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.118.232];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: MWH0EPF000971E4.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR12MB5786 Precedence: Bulk List-Subscribe: List-Help: 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,nicklew@nvidia.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 5fhOpybTpOzwi9LQtZrQIItWx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1698312630012100001 Content-Type: text/plain; charset="utf-8" Update RedfishLib to align with RedfishLib in edk2 repository. RedfishLib commits on edk2: cf68ff61 RedfishPkg/RedfishLib: introduce new interfaces. 1cbdd6e9 RedfishPkg/libredfish: introduce new interfaces. 8765f3eb RedfishPkg/RedfishLib: return HTTP headers to caller. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Igor Kulchytskyy Cc: Nick Ramirez --- .../edk2libredfish/include/redfishPayload.h | 3 +- .../edk2libredfish/include/redfishService.h | 21 + .../PrivateLibrary/RedfishLib/RedfishLib.c | 337 ++++++++++- .../PrivateLibrary/RedfishLib/RedfishMisc.c | 13 +- .../RedfishLib/edk2libredfish/src/payload.c | 3 +- .../RedfishLib/edk2libredfish/src/service.c | 531 ++++++------------ 6 files changed, 517 insertions(+), 391 deletions(-) diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/incl= ude/redfishPayload.h b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libre= dfish/include/redfishPayload.h index 8403d693..4e91b724 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/red= fishPayload.h +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/red= fishPayload.h @@ -10,6 +10,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -19,7 +20,7 @@ #define LIBREDFISH_REDFISH_PAYLOAD_H_ =20 #include - +#include #include #include #include diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/incl= ude/redfishService.h b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libre= dfish/include/redfishService.h index c41c0d14..c2e0fd32 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/red= fishService.h +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/red= fishService.h @@ -10,6 +10,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -153,6 +154,18 @@ postUriFromServiceEx ( EFI_HTTP_STATUS_CODE **StatusCode ); =20 +json_t * +putUriFromServiceEx ( + redfishService *service, + const char *uri, + const char *content, + size_t contentLength, + const char *contentType, + EFI_HTTP_HEADER **Headers, + UINTN *HeaderCount, + EFI_HTTP_STATUS_CODE **StatusCode + ); + json_t * deleteUriFromService ( redfishService *service, @@ -160,6 +173,14 @@ deleteUriFromService ( EFI_HTTP_STATUS_CODE **StatusCode ); =20 +json_t * +deleteUriFromServiceEx ( + redfishService *service, + const char *uri, + const char *content, + EFI_HTTP_STATUS_CODE **StatusCode + ); + redfishPayload * getRedfishServiceRoot ( redfishService *service, diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.c b/Redf= ishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.c index c00b15f6..9dc64991 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.c +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.c @@ -4,6 +4,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -167,6 +168,30 @@ RedfishJsonInPayload ( return ((redfishPayload *)Payload)->json; } =20 +/** + This function returns the Redfish service of a REDFISH_PAYLOAD. + + Caller doesn't need to free the returned JSON value because it will be r= eleased + in corresponding RedfishCleanupService() function. + + @param[in] Payload A REDFISH_PAYLOAD instance. + + @return Redfish service of the payload. + +**/ +REDFISH_SERVICE +EFIAPI +RedfishServiceInPayload ( + IN REDFISH_PAYLOAD Payload + ) +{ + if (Payload =3D=3D NULL) { + return NULL; + } + + return ((redfishPayload *)Payload)->service; +} + /** Fill the input RedPath string with system UUID from SMBIOS table or use = the customized ID if FromSmbios =3D=3D FALSE. @@ -244,7 +269,7 @@ RedfishBuildPathWithSystemUuid ( from the root node. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX. The correspon= ding redfish resource has been returned in Payload within RedRespo= nse. @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse = is NULL. @@ -304,7 +329,7 @@ RedfishGetByService ( @param[in] Uri String to address a resource. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX. The correspon= ding redfish resource has been returned in Payload within RedRespo= nse. @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse = is NULL. @@ -367,7 +392,7 @@ RedfishGetByUri ( @param[in] RedPath Relative RedPath string to address a res= ource inside Payload. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful: + @retval EFI_SUCCESS The operation is successful: 1. The HTTP StatusCode is NULL and the r= eturned Payload in RedResponse is not NULL, indicates the R= edfish resource has been parsed from the input payload direc= tly. @@ -440,7 +465,7 @@ RedfishGetByPayload ( @param[in] Content JSON represented properties to be up= date. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX. The Redfish r= esource will be returned in Payload within RedResponse if server = send it back in the HTTP response message body. @@ -473,10 +498,12 @@ RedfishPatchToUri ( =20 ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); =20 - JsonValue =3D (EDKII_JSON_VALUE)patchUriFromService ( + JsonValue =3D (EDKII_JSON_VALUE)patchUriFromServiceEx ( RedfishService, Uri, Content, + &(RedResponse->Headers), + &(RedResponse->HeaderCount), &(RedResponse->StatusCode) ); =20 @@ -527,10 +554,10 @@ ON_EXIT: redfish response data. =20 @param[in] Target The target payload to be updated. - @param[in] Payload Palyoad with properties to be changed. + @param[in] Payload Payload with properties to be changed. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX. The Redfish r= esource will be returned in Payload within RedResponse if server = send it back in the HTTP response message body. @@ -585,6 +612,104 @@ RedfishPatchToPayload ( return EFI_SUCCESS; } =20 +/** + Use HTTP POST to create new Redfish resource in the Resource Collection. + + The POST request should be submitted to the Resource Collection in which= the new resource + is to belong. The Resource Collection is addressed by URI. The Redfish m= ay + ignore any service controlled properties. The corresponding redfish resp= onse will returned, + including HTTP StatusCode, Headers and Payload which record any HTTP res= ponse messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Pay= load returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish re= sources. + @param[in] Uri Relative path to address the resourc= e. + @param[in] Content JSON represented properties to be up= date. + @param[in] ContentSize Size of the Content to be send to Re= dfish service + @param[in] ContentType Type of the Content to be send to Re= dfish service + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not + NULL and the value is 2XX. The Redfish r= esource will be returned + in Payload within RedResponse if server = send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, Content, or RedResp= onse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error oc= curred. Callers can get + more error info from returned HTTP Statu= sCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, i= ndicates any error happen. + 2. If the returned StatusCode is not NUL= L and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPostToUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + IN CONST CHAR8 *Content, + IN UINTN ContentSize OPTIONAL, + IN CONST CHAR8 *ContentType OPTIONAL, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + + Status =3D EFI_SUCCESS; + JsonValue =3D NULL; + + if ((RedfishService =3D=3D NULL) || (Uri =3D=3D NULL) || (Content =3D=3D= NULL) || (RedResponse =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue =3D (EDKII_JSON_VALUE)postUriFromServiceEx ( + RedfishService, + Uri, + Content, + ContentSize, + ContentType, + &(RedResponse->Headers), + &(RedResponse->HeaderCount), + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, i= ndicates any error happen. + // NOTE: If there is any error message returned from server, it will = be returned in + // Payload within RedResponse. + // + if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \ + (*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)) + { + Status =3D EFI_DEVICE_ERROR; + } + +ON_EXIT: + if (JsonValue !=3D NULL) { + RedResponse->Payload =3D createRedfishPayload (JsonValue, RedfishServi= ce); + if (RedResponse->Payload =3D=3D NULL) { + // + // Ignore the error when create RedfishPayload, just free the JsonVa= lue since it's not what + // we care about if the returned StatusCode is 2XX. + // + JsonValueFree (JsonValue); + } + } + + return Status; +} + /** Use HTTP POST to create a new resource in target payload. =20 @@ -600,7 +725,7 @@ RedfishPatchToPayload ( @param[in] Payload The new resource to be created. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX. The Redfish r= esource will be returned in Payload within RedResponse if server = send it back in the HTTP response message body. @@ -670,7 +795,7 @@ RedfishPostToPayload ( @param[in] Uri Relative path to address the resourc= e. @param[out] RedResponse Pointer to the Redfish response data. =20 - @retval EFI_SUCCESS The opeartion is successful, indicates t= he HTTP StatusCode is not + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not NULL and the value is 2XX, the Redfish r= esource has been removed. If there is any message returned from se= rver, it will be returned in Payload within RedResponse. @@ -742,6 +867,96 @@ ON_EXIT: return Status; } =20 +/** + Use HTTP DELETE to remove a resource. + + This function uses the RedfishService to remove a Redfish resource which= is addressed + by input Uri (only the relative path is required). The corresponding red= fish response will + returned, including HTTP StatusCode, Headers and Payload which record an= y HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Pay= load returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish re= sources. + @param[in] Uri Relative path to address the resourc= e. + @param[in] Content JSON represented properties to be de= leted. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not + NULL and the value is 2XX, the Redfish r= esource has been removed. + If there is any message returned from se= rver, it will be returned + in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, or RedResponse is N= ULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error oc= curred. Callers can get + more error info from returned HTTP Statu= sCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, i= ndicates any error happen. + 2. If the returned StatusCode is not NUL= L and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishDeleteByUriEx ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + IN CONST CHAR8 *Content, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + + Status =3D EFI_SUCCESS; + JsonValue =3D NULL; + + if ((RedfishService =3D=3D NULL) || (Content =3D=3D NULL) || (Uri =3D=3D= NULL) || (RedResponse =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue =3D (EDKII_JSON_VALUE)deleteUriFromServiceEx ( + RedfishService, + Uri, + Content, + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, i= ndicates any error happen. + // NOTE: If there is any error message returned from server, it will = be returned in + // Payload within RedResponse. + // + if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \ + (*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)) + { + Status =3D EFI_DEVICE_ERROR; + } + +ON_EXIT: + if (JsonValue !=3D NULL) { + RedResponse->Payload =3D createRedfishPayload (JsonValue, RedfishServi= ce); + if (RedResponse->Payload =3D=3D NULL) { + // + // Ignore the error when create RedfishPayload, just free the JsonVa= lue since it's not what + // we care about if the returned StatusCode is 2XX. + // + JsonValueFree (JsonValue); + } + } + + return Status; +} + /** Dump text in fractions. =20 @@ -878,7 +1093,7 @@ RedfishFreeResponse ( Check if the "@odata.type" in Payload is valid or not. =20 @param[in] Payload The Redfish payload to be checked. - @param[in] OdataTypeName OdataType will be retrived from map= ping list. + @param[in] OdataTypeName OdataType will be retrieved from ma= pping list. @param[in] OdataTypeMappingList The list of OdataType. @param[in] OdataTypeMappingListSize The number of mapping list =20 @@ -945,7 +1160,7 @@ RedfishIsPayloadCollection ( @param[in] Payload The Redfish collection payload @param[in] CollectionSize Size of this collection =20 - @return EFI_SUCCESS Coolection size is returned in Collecti= onSize + @return EFI_SUCCESS Collection size is returned in Collecti= onSize @return EFI_INVALID_PARAMETER The payload is not a collection. **/ EFI_STATUS @@ -1035,3 +1250,103 @@ RedfishCheckIfRedpathExist ( =20 return EFI_SUCCESS; } + +/** + Use HTTP PUT to create new Redfish resource in the Resource Collection. + + This function uses the RedfishService to put a Redfish resource addresse= d by + Uri (only the relative path is required). Changes to one or more propert= ies within + the target resource are represented in the input Content, properties not= specified + in Content won't be changed by this request. The corresponding redfish r= esponse will + returned, including HTTP StatusCode, Headers and Payload which record an= y HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Pay= load returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish re= sources. + @param[in] Uri Relative path to address the resourc= e. + @param[in] Content JSON represented properties to be up= date. + @param[in] ContentSize Size of the Content to be send to Re= dfish service + @param[in] ContentType Type of the Content to be send to Re= dfish service + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The operation is successful, indicates t= he HTTP StatusCode is not + NULL and the value is 2XX. The Redfish r= esource will be returned + in Payload within RedResponse if server = send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, Content, or RedResp= onse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error oc= curred. Callers can get + more error info from returned HTTP Statu= sCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, i= ndicates any error happen. + 2. If the returned StatusCode is not NUL= L and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPutToUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + IN CONST CHAR8 *Content, + IN UINTN ContentSize OPTIONAL, + IN CONST CHAR8 *ContentType OPTIONAL, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + + Status =3D EFI_SUCCESS; + JsonValue =3D NULL; + + if ((RedfishService =3D=3D NULL) || (Uri =3D=3D NULL) || (Content =3D=3D= NULL) || (RedResponse =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue =3D (EDKII_JSON_VALUE)putUriFromServiceEx ( + RedfishService, + Uri, + Content, + ContentSize, + ContentType, + &(RedResponse->Headers), + &(RedResponse->HeaderCount), + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode =3D=3D NULL) { + Status =3D EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, i= ndicates any error happen. + // NOTE: If there is any error message returned from server, it will = be returned in + // Payload within RedResponse. + // + if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \ + (*(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)) + { + Status =3D EFI_DEVICE_ERROR; + } + +ON_EXIT: + if (JsonValue !=3D NULL) { + RedResponse->Payload =3D createRedfishPayload (JsonValue, RedfishServi= ce); + if (RedResponse->Payload =3D=3D NULL) { + // + // Ignore the error when create RedfishPayload, just free the JsonVa= lue since it's not what + // we care about if the returned StatusCode is 2XX. + // + JsonValueFree (JsonValue); + } + } + + return Status; +} diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishMisc.c b/Red= fishClientPkg/PrivateLibrary/RedfishLib/RedfishMisc.c index 0eb23196..b6e9a111 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishMisc.c +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishMisc.c @@ -3,6 +3,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -168,18 +169,18 @@ RedfishGetAuthInfo ( /** This function returns the string of Redfish service version. =20 - @param[in] ServiceVerisonStr The string of Redfish service version. + @param[in] ServiceVersionStr The string of Redfish service version. @param[in] Url The URL to build Redpath with ID. Start with "/", for example "/Registries" @param[in] Id ID string - @param[out] Redpath Pointer to retrive Redpath, caller has to= free + @param[out] Redpath Pointer to retrieved Redpath, caller has = to free the memory allocated for this string. @return EFI_STATUS =20 **/ EFI_STATUS RedfishBuildRedpathUseId ( - IN CHAR8 *ServiceVerisonStr, + IN CHAR8 *ServiceVersionStr, IN CHAR8 *Url, IN CHAR8 *Id, OUT CHAR8 **Redpath @@ -187,12 +188,12 @@ RedfishBuildRedpathUseId ( { UINTN RedpathSize; =20 - if ((Redpath =3D=3D NULL) || (ServiceVerisonStr =3D=3D NULL) || (Url =3D= =3D NULL) || (Id =3D=3D NULL)) { + if ((Redpath =3D=3D NULL) || (ServiceVersionStr =3D=3D NULL) || (Url =3D= =3D NULL) || (Id =3D=3D NULL)) { return EFI_INVALID_PARAMETER; } =20 RedpathSize =3D AsciiStrLen ("/") + - AsciiStrLen (ServiceVerisonStr) + + AsciiStrLen (ServiceVersionStr) + AsciiStrLen (Url) + AsciiStrLen ("[Id=3D]") + AsciiStrLen (Id) + 1; @@ -201,6 +202,6 @@ RedfishBuildRedpathUseId ( return EFI_OUT_OF_RESOURCES; } =20 - AsciiSPrint (*Redpath, RedpathSize, "/%a%a[Id=3D%a]", ServiceVerisonStr,= Url, Id); + AsciiSPrint (*Redpath, RedpathSize, "/%a%a[Id=3D%a]", ServiceVersionStr,= Url, Id); return EFI_SUCCESS; } diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/= payload.c b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/p= ayload.c index 8ec2ed4a..d845d51f 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/payload= .c +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/payload= .c @@ -10,6 +10,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -629,7 +630,7 @@ getOpResult ( } =20 stringProp =3D prop->json; - jsonType =3D json_get_type (prop->json); + jsonType =3D JsonGetType (prop->json); switch (jsonType) { case JSON_OBJECT: stringProp =3D json_object_get (prop->json, propName); diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/= service.c b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/s= ervice.c index a38bdfbe..58c23e8c 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service= .c +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service= .c @@ -10,6 +10,7 @@ =20 Copyright (c) 2019, Intel Corporation. All rights reserved.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -279,9 +280,9 @@ DecodeResponseContent ( **/ EFI_STATUS RedfishBuildUrl ( - IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, - IN CHAR16 *RelativePath, OPTIONAL - OUT CHAR16 **HttpUrl + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, + IN CHAR16 *RelativePath OPTIONAL, + OUT CHAR16 **HttpUrl ) { CHAR16 *Url; @@ -434,8 +435,8 @@ json_t * getUriFromServiceEx ( redfishService *service, const char *uri, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, + EFI_HTTP_HEADER **Headers OPTIONAL, + UINTN *HeaderCount OPTIONAL, EFI_HTTP_STATUS_CODE **StatusCode ) { @@ -448,20 +449,25 @@ getUriFromServiceEx ( EFI_HTTP_MESSAGE ResponseMsg; EFI_HTTP_HEADER *ContentEncodedHeader; =20 - if ((service =3D=3D NULL) || (uri =3D=3D NULL) || (Headers =3D=3D NULL) = || (HeaderCount =3D=3D NULL) || (StatusCode =3D=3D NULL)) { + if ((service =3D=3D NULL) || (uri =3D=3D NULL) || (StatusCode =3D=3D NUL= L)) { return NULL; } =20 - *StatusCode =3D NULL; - *HeaderCount =3D 0; - *Headers =3D NULL; + *StatusCode =3D NULL; + if (HeaderCount !=3D NULL) { + *HeaderCount =3D 0; + } + + if (Headers !=3D NULL) { + *Headers =3D NULL; + } =20 url =3D makeUrlForService (service, uri); if (!url) { return NULL; } =20 - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: getUriFromServiceEx(): %a\n", = url)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: %a\n", __func__, url)); =20 // // Step 1: Create HTTP request message with 4 headers: @@ -524,166 +530,23 @@ getUriFromServiceEx ( Status =3D service->RestEx->SendReceive (service->RestEx, RequestMsg, &R= esponseMsg); if (EFI_ERROR (Status)) { ret =3D NULL; - goto ON_EXIT; - } - - // - // Step 5: Return the HTTP StatusCode and Body message. - // - if (ResponseMsg.Data.Response !=3D NULL) { - *StatusCode =3D AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); - if (*StatusCode =3D=3D NULL) { - ret =3D NULL; - goto ON_EXIT; - } =20 // - // The caller shall take the responsibility to free the buffer. + // Deliver status code to caller when error happens so caller can do e= rror handling. // - **StatusCode =3D ResponseMsg.Data.Response->StatusCode; - } - - if (ResponseMsg.Headers !=3D NULL) { - *Headers =3D cloneHttpHeaders (&ResponseMsg, HeaderCount); - } - - if ((ResponseMsg.BodyLength !=3D 0) && (ResponseMsg.Body !=3D NULL)) { - // - // Check if data is encoded. - // - ContentEncodedHeader =3D HttpFindHeader (ResponseMsg.HeaderCount, Resp= onseMsg.Headers, HTTP_HEADER_CONTENT_ENCODING); - if (ContentEncodedHeader !=3D NULL) { - // - // The content is encoded. - // - Status =3D DecodeResponseContent (ContentEncodedHeader->FieldValue, = &ResponseMsg.Body, &ResponseMsg.BodyLength); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: Failed to decompress the response conten= t %r\n.", __func__, Status)); + if (ResponseMsg.Data.Response !=3D NULL) { + *StatusCode =3D AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode =3D=3D NULL) { ret =3D NULL; goto ON_EXIT; } - } - - ret =3D json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); - } else { - // - // There is no message body returned from server. - // - ret =3D NULL; - } =20 -ON_EXIT: - if (url !=3D NULL) { - free (url); - } - - if (HttpIoHeader !=3D NULL) { - HttpIoFreeHeader (HttpIoHeader); - } - - if (RequestData !=3D NULL) { - RestConfigFreeHttpRequestData (RequestData); - } - - if (RequestMsg !=3D NULL) { - FreePool (RequestMsg); - } - - RestConfigFreeHttpMessage (&ResponseMsg, FALSE); - - return ret; -} - -json_t * -getUriFromService ( - redfishService *service, - const char *uri, - EFI_HTTP_STATUS_CODE **StatusCode - ) -{ - char *url; - json_t *ret; - HTTP_IO_HEADER *HttpIoHeader =3D NULL; - EFI_STATUS Status; - EFI_HTTP_REQUEST_DATA *RequestData =3D NULL; - EFI_HTTP_MESSAGE *RequestMsg =3D NULL; - EFI_HTTP_MESSAGE ResponseMsg; - EFI_HTTP_HEADER *ContentEncodedHeader; - - if ((service =3D=3D NULL) || (uri =3D=3D NULL) || (StatusCode =3D=3D NUL= L)) { - return NULL; - } - - *StatusCode =3D NULL; - - url =3D makeUrlForService (service, uri); - if (!url) { - return NULL; - } - - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: getUriFromService(): %a\n", ur= l)); - - // - // Step 1: Create HTTP request message with 4 headers: - // - HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken || service->= basicAuthStr) ? 6 : 5); - if (HttpIoHeader =3D=3D NULL) { - ret =3D NULL; - goto ON_EXIT; - } - - if (service->sessionToken) { - Status =3D HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->ses= sionToken); - ASSERT_EFI_ERROR (Status); - } else if (service->basicAuthStr) { - Status =3D HttpIoSetHeader (HttpIoHeader, "Authorization", service->ba= sicAuthStr); - ASSERT_EFI_ERROR (Status); - } - - Status =3D HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderVal= ue); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "Accept", "application/json"); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); - ASSERT_EFI_ERROR (Status); - - // - // Step 2: build the rest of HTTP request info. - // - RequestData =3D AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); - if (RequestData =3D=3D NULL) { - ret =3D NULL; - goto ON_EXIT; - } - - RequestData->Method =3D HttpMethodGet; - RequestData->Url =3D C8ToC16 (url); - - // - // Step 3: fill in EFI_HTTP_MESSAGE - // - RequestMsg =3D AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); - if (RequestMsg =3D=3D NULL) { - ret =3D NULL; - goto ON_EXIT; - } - - RequestMsg->Data.Request =3D RequestData; - RequestMsg->HeaderCount =3D HttpIoHeader->HeaderCount; - RequestMsg->Headers =3D HttpIoHeader->Headers; - - ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); + // + // The caller shall take the responsibility to free the buffer. + // + **StatusCode =3D ResponseMsg.Data.Response->StatusCode; + } =20 - // - // Step 4: call RESTEx to get response from REST service. - // - Status =3D service->RestEx->SendReceive (service->RestEx, RequestMsg, &R= esponseMsg); - if (EFI_ERROR (Status)) { - ret =3D NULL; goto ON_EXIT; } =20 @@ -703,6 +566,10 @@ getUriFromService ( **StatusCode =3D ResponseMsg.Data.Response->StatusCode; } =20 + if ((ResponseMsg.Headers !=3D NULL) && (Headers !=3D NULL) && (HeaderCou= nt !=3D NULL)) { + *Headers =3D cloneHttpHeaders (&ResponseMsg, HeaderCount); + } + if ((ResponseMsg.BodyLength !=3D 0) && (ResponseMsg.Body !=3D NULL)) { // // Check if data is encoded. @@ -751,12 +618,14 @@ ON_EXIT: } =20 json_t * -patchUriFromServiceEx ( +putUriFromServiceEx ( redfishService *service, const char *uri, const char *content, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, + size_t contentLength, + const char *contentType, + EFI_HTTP_HEADER **Headers OPTIONAL, + UINTN *HeaderCount OPTIONAL, EFI_HTTP_STATUS_CODE **StatusCode ) { @@ -776,18 +645,29 @@ patchUriFromServiceEx ( } =20 *StatusCode =3D NULL; + if (HeaderCount !=3D NULL) { + *HeaderCount =3D 0; + } + + if (Headers !=3D NULL) { + *Headers =3D NULL; + } =20 url =3D makeUrlForService (service, uri); - if (!url) { + if (url =3D=3D NULL) { return NULL; } =20 - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: patchUriFromService(): %a\n", = url)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: %a\n", __func__, url)); + + if (contentLength =3D=3D 0) { + contentLength =3D strlen (content); + } =20 // // Step 1: Create HTTP request message with 4 headers: // - HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken || service->= basicAuthStr) ? 9 : 8); + HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken !=3D NULL ||= service->basicAuthStr !=3D NULL) ? 9 : 8); if (HttpIoHeader =3D=3D NULL) { ret =3D NULL; goto ON_EXIT; @@ -801,6 +681,14 @@ patchUriFromServiceEx ( ASSERT_EFI_ERROR (Status); } =20 + if (contentType =3D=3D NULL) { + Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", "application= /json"); + ASSERT_EFI_ERROR (Status); + } else { + Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", (CHAR8 *)con= tentType); + ASSERT_EFI_ERROR (Status); + } + Status =3D HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderVal= ue); ASSERT_EFI_ERROR (Status); Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", "application/j= son"); @@ -816,7 +704,7 @@ patchUriFromServiceEx ( ContentLengthStr, sizeof (ContentLengthStr), "%lu", - (UINT64)strlen (content) + (UINT64)contentLength ); Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Length", ContentLengt= hStr); ASSERT_EFI_ERROR (Status); @@ -832,7 +720,7 @@ patchUriFromServiceEx ( goto ON_EXIT; } =20 - RequestData->Method =3D HttpMethodPatch; + RequestData->Method =3D HttpMethodPut; RequestData->Url =3D C8ToC16 (url); =20 // @@ -845,7 +733,7 @@ patchUriFromServiceEx ( } =20 EncodedContent =3D (CHAR8 *)content; - EncodedContentLen =3D strlen (content); + EncodedContentLen =3D contentLength; // // We currently only support gzip Content-Encoding. // @@ -896,7 +784,7 @@ patchUriFromServiceEx ( **StatusCode =3D ResponseMsg.Data.Response->StatusCode; } =20 - if (ResponseMsg.Headers !=3D NULL) { + if ((ResponseMsg.Headers !=3D NULL) && (Headers !=3D NULL) && (HeaderCou= nt !=3D NULL)) { *Headers =3D cloneHttpHeaders (&ResponseMsg, HeaderCount); } =20 @@ -936,10 +824,12 @@ ON_EXIT: } =20 json_t * -patchUriFromService ( +patchUriFromServiceEx ( redfishService *service, const char *uri, const char *content, + EFI_HTTP_HEADER **Headers OPTIONAL, + UINTN *HeaderCount OPTIONAL, EFI_HTTP_STATUS_CODE **StatusCode ) { @@ -959,13 +849,20 @@ patchUriFromService ( } =20 *StatusCode =3D NULL; + if (HeaderCount !=3D NULL) { + *HeaderCount =3D 0; + } + + if (Headers !=3D NULL) { + *Headers =3D NULL; + } =20 url =3D makeUrlForService (service, uri); if (!url) { return NULL; } =20 - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: patchUriFromService(): %a\n", = url)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: %a\n", __func__, url)); =20 // // Step 1: Create HTTP request message with 4 headers: @@ -1079,6 +976,10 @@ patchUriFromService ( **StatusCode =3D ResponseMsg.Data.Response->StatusCode; } =20 + if ((ResponseMsg.Headers !=3D NULL) && (Headers !=3D NULL) && (HeaderCou= nt !=3D NULL)) { + *Headers =3D cloneHttpHeaders (&ResponseMsg, HeaderCount); + } + if (EncodedContent !=3D content) { FreePool (EncodedContent); } @@ -1121,8 +1022,8 @@ postUriFromServiceEx ( const char *content, size_t contentLength, const char *contentType, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, + EFI_HTTP_HEADER **Headers OPTIONAL, + UINTN *HeaderCount OPTIONAL, EFI_HTTP_STATUS_CODE **StatusCode ) { @@ -1143,13 +1044,20 @@ postUriFromServiceEx ( } =20 *StatusCode =3D NULL; + if (HeaderCount !=3D NULL) { + *HeaderCount =3D 0; + } + + if (Headers !=3D NULL) { + *Headers =3D NULL; + } =20 url =3D makeUrlForService (service, uri); if (!url) { return NULL; } =20 - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: postUriFromService(): %a\n", u= rl)); + DEBUG ((DEBUG_MANAGEABILITY, "%a: %a\n", __func__, url)); =20 if (contentLength =3D=3D 0) { contentLength =3D strlen (content); @@ -1230,7 +1138,12 @@ postUriFromServiceEx ( // Status =3D service->RestEx->SendReceive (service->RestEx, RequestMsg, &R= esponseMsg); if (EFI_ERROR (Status)) { - goto ON_EXIT; + // + // If there is no response to handle, go to error exit. + // + if (ResponseMsg.Data.Response =3D=3D NULL) { + goto ON_EXIT; + } } =20 // @@ -1248,7 +1161,7 @@ postUriFromServiceEx ( **StatusCode =3D ResponseMsg.Data.Response->StatusCode; } =20 - if (ResponseMsg.Headers !=3D NULL) { + if ((ResponseMsg.Headers !=3D NULL) && (Headers !=3D NULL) && (HeaderCou= nt !=3D NULL)) { *Headers =3D cloneHttpHeaders (&ResponseMsg, HeaderCount); } =20 @@ -1257,10 +1170,11 @@ postUriFromServiceEx ( } =20 // - // Step 6: Parsing the HttpHeader to retrive the X-Auth-Token if the HTT= P StatusCode is correct. + // Step 6: Parsing the HttpHeader to retrieve the X-Auth-Token if the HT= TP StatusCode is correct. // - if ((ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_200_OK) || - (ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_204_NO_CON= TENT)) + if ((ResponseMsg.Data.Response !=3D NULL) && + ((ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_200_OK) || + (ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_204_NO_CO= NTENT))) { HttpHeader =3D HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.He= aders, "X-Auth-Token"); if (HttpHeader !=3D NULL) { @@ -1270,19 +1184,6 @@ postUriFromServiceEx ( =20 service->sessionToken =3D AllocateCopyPool (AsciiStrSize (HttpHeader= ->FieldValue), HttpHeader->FieldValue); } - - /* - // - // Below opeation seems to be unnecessary. - // Besides, the FieldValue for the Location is the full HTTP URI (Http= ://0.0.0.0:5000/XXX), so we can't use it as the - // parameter of getUriFromService () directly. - // - HttpHeader =3D HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.He= aders, "Location"); - if (HttpHeader !=3D NULL) { - ret =3D getUriFromService(service, HttpHeader->FieldValue); - goto ON_EXIT; - } - */ } =20 ON_EXIT: @@ -1307,6 +1208,27 @@ ON_EXIT: return ret; } =20 +json_t * +getUriFromService ( + redfishService *service, + const char *uri, + EFI_HTTP_STATUS_CODE **StatusCode + ) +{ + return getUriFromServiceEx (service, uri, NULL, NULL, StatusCode); +} + +json_t * +patchUriFromService ( + redfishService *service, + const char *uri, + const char *content, + EFI_HTTP_STATUS_CODE **StatusCode + ) +{ + return patchUriFromServiceEx (service, uri, content, NULL, NULL, StatusC= ode); +} + json_t * postUriFromService ( redfishService *service, @@ -1317,187 +1239,14 @@ postUriFromService ( EFI_HTTP_STATUS_CODE **StatusCode ) { - char *url =3D NULL; - json_t *ret; - HTTP_IO_HEADER *HttpIoHeader =3D NULL; - EFI_STATUS Status; - EFI_HTTP_REQUEST_DATA *RequestData =3D NULL; - EFI_HTTP_MESSAGE *RequestMsg =3D NULL; - EFI_HTTP_MESSAGE ResponseMsg; - CHAR8 ContentLengthStr[80]; - EFI_HTTP_HEADER *HttpHeader =3D NULL; - - ret =3D NULL; - - if ((service =3D=3D NULL) || (uri =3D=3D NULL) || (content =3D=3D NULL) = || (StatusCode =3D=3D NULL)) { - return NULL; - } - - *StatusCode =3D NULL; - - url =3D makeUrlForService (service, uri); - if (!url) { - return NULL; - } - - DEBUG ((DEBUG_MANAGEABILITY, "libredfish: postUriFromService(): %a\n", u= rl)); - - if (contentLength =3D=3D 0) { - contentLength =3D strlen (content); - } - - // - // Step 1: Create HTTP request message with 4 headers: - // - HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken || service->= basicAuthStr) ? 8 : 7); - if (HttpIoHeader =3D=3D NULL) { - goto ON_EXIT; - } - - if (service->sessionToken) { - Status =3D HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->ses= sionToken); - ASSERT_EFI_ERROR (Status); - } else if (service->basicAuthStr) { - Status =3D HttpIoSetHeader (HttpIoHeader, "Authorization", service->ba= sicAuthStr); - ASSERT_EFI_ERROR (Status); - } - - if (contentType =3D=3D NULL) { - Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", "application= /json"); - ASSERT_EFI_ERROR (Status); - } else { - Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", (CHAR8 *)con= tentType); - ASSERT_EFI_ERROR (Status); - } - - Status =3D HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderVal= ue); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "Accept", "application/json"); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); - ASSERT_EFI_ERROR (Status); - AsciiSPrint ( - ContentLengthStr, - sizeof (ContentLengthStr), - "%lu", - (UINT64)contentLength - ); - Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Length", ContentLengt= hStr); - ASSERT_EFI_ERROR (Status); - Status =3D HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); - ASSERT_EFI_ERROR (Status); - - // - // Step 2: build the rest of HTTP request info. - // - RequestData =3D AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); - if (RequestData =3D=3D NULL) { - goto ON_EXIT; - } - - RequestData->Method =3D HttpMethodPost; - RequestData->Url =3D C8ToC16 (url); - - // - // Step 3: fill in EFI_HTTP_MESSAGE - // - RequestMsg =3D AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); - if (RequestMsg =3D=3D NULL) { - goto ON_EXIT; - } - - RequestMsg->Data.Request =3D RequestData; - RequestMsg->HeaderCount =3D HttpIoHeader->HeaderCount; - RequestMsg->Headers =3D HttpIoHeader->Headers; - RequestMsg->BodyLength =3D contentLength; - RequestMsg->Body =3D (VOID *)content; - - ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); - - // - // Step 4: call RESTEx to get response from REST service. - // - Status =3D service->RestEx->SendReceive (service->RestEx, RequestMsg, &R= esponseMsg); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - // - // Step 5: Return the HTTP StatusCode and Body message. - // - if (ResponseMsg.Data.Response !=3D NULL) { - *StatusCode =3D AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); - if (*StatusCode =3D=3D NULL) { - goto ON_EXIT; - } - - // - // The caller shall take the responsibility to free the buffer. - // - **StatusCode =3D ResponseMsg.Data.Response->StatusCode; - } - - if ((ResponseMsg.BodyLength !=3D 0) && (ResponseMsg.Body !=3D NULL)) { - ret =3D json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); - } - - // - // Step 6: Parsing the HttpHeader to retrive the X-Auth-Token if the HTT= P StatusCode is correct. - // - if ((ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_200_OK) || - (ResponseMsg.Data.Response->StatusCode =3D=3D HTTP_STATUS_204_NO_CON= TENT)) - { - HttpHeader =3D HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.He= aders, "X-Auth-Token"); - if (HttpHeader !=3D NULL) { - if (service->sessionToken) { - free (service->sessionToken); - } - - service->sessionToken =3D AllocateCopyPool (AsciiStrSize (HttpHeader= ->FieldValue), HttpHeader->FieldValue); - } - - /* - // - // Below opeation seems to be unnecessary. - // Besides, the FieldValue for the Location is the full HTTP URI (Http= ://0.0.0.0:5000/XXX), so we can't use it as the - // parameter of getUriFromService () directly. - // - HttpHeader =3D HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.He= aders, "Location"); - if (HttpHeader !=3D NULL) { - ret =3D getUriFromService(service, HttpHeader->FieldValue); - goto ON_EXIT; - } - */ - } - -ON_EXIT: - if (url !=3D NULL) { - free (url); - } - - if (HttpIoHeader !=3D NULL) { - HttpIoFreeHeader (HttpIoHeader); - } - - if (RequestData !=3D NULL) { - RestConfigFreeHttpRequestData (RequestData); - } - - if (RequestMsg !=3D NULL) { - FreePool (RequestMsg); - } - - RestConfigFreeHttpMessage (&ResponseMsg, FALSE); - - return ret; + return postUriFromServiceEx (service, uri, content, contentLength, conte= ntType, NULL, NULL, StatusCode); } =20 json_t * -deleteUriFromService ( +deleteUriFromServiceEx ( redfishService *service, const char *uri, + const char *content, EFI_HTTP_STATUS_CODE **StatusCode ) { @@ -1508,6 +1257,8 @@ deleteUriFromService ( EFI_HTTP_REQUEST_DATA *RequestData =3D NULL; EFI_HTTP_MESSAGE *RequestMsg =3D NULL; EFI_HTTP_MESSAGE ResponseMsg; + CHAR8 ContentLengthStr[80]; + size_t contentLength; =20 ret =3D NULL; =20 @@ -1527,7 +1278,7 @@ deleteUriFromService ( // // Step 1: Create HTTP request message with 4 headers: // - HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken || service->= basicAuthStr) ? 5 : 4); + HttpIoHeader =3D HttpIoCreateHeader ((service->sessionToken || service->= basicAuthStr) ? 8 : 7); if (HttpIoHeader =3D=3D NULL) { ret =3D NULL; goto ON_EXIT; @@ -1550,6 +1301,23 @@ deleteUriFromService ( Status =3D HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); ASSERT_EFI_ERROR (Status); =20 + Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Type", "application/j= son"); + ASSERT_EFI_ERROR (Status); + + if (content !=3D NULL) { + contentLength =3D strlen (content); + AsciiSPrint ( + ContentLengthStr, + sizeof (ContentLengthStr), + "%lu", + (UINT64)contentLength + ); + Status =3D HttpIoSetHeader (HttpIoHeader, "Content-Length", ContentLen= gthStr); + ASSERT_EFI_ERROR (Status); + Status =3D HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); + ASSERT_EFI_ERROR (Status); + } + // // Step 2: build the rest of HTTP request info. // @@ -1575,6 +1343,11 @@ deleteUriFromService ( RequestMsg->HeaderCount =3D HttpIoHeader->HeaderCount; RequestMsg->Headers =3D HttpIoHeader->Headers; =20 + if (content !=3D NULL) { + RequestMsg->BodyLength =3D contentLength; + RequestMsg->Body =3D (VOID *)content; + } + ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); =20 // @@ -1628,6 +1401,16 @@ ON_EXIT: return ret; } =20 +json_t * +deleteUriFromService ( + redfishService *service, + const char *uri, + EFI_HTTP_STATUS_CODE **StatusCode + ) +{ + return deleteUriFromServiceEx (service, uri, NULL, StatusCode); +} + redfishPayload * getRedfishServiceRoot ( redfishService *service, @@ -2034,6 +1817,10 @@ makeUrlForService ( } =20 url =3D (char *)malloc (strlen (service->host)+strlen (uri)+1); + if (url =3D=3D NULL) { + return NULL; + } + strcpy (url, service->host); strcat (url, uri); return url; --=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 (#110084): https://edk2.groups.io/g/devel/message/110084 Mute This Topic: https://groups.io/mt/102196559/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-