From nobody Wed May 15 14:50:11 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+110082+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 1698309323033433.8363448307921; Thu, 26 Oct 2023 01:35:23 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=EiFOydoiz/vrvMzV1QYZMXQzDZ/StF9FqV1XBZGB+C8=; 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=1698309322; v=1; b=WB2JrndMiMTsABWEaU+RkIp4sKf2DdTlut+D9sXVQoRag5MMK/J3Y41ZF/ZnPIqGf7YiAl5c gwAhzeDb1axZFhFxnmLvdb8+UNm8oXquDBY235ikzi1PmQ7/l1dERKqxNnB6m35Jyh68t94kgHy JL4Qy6sN9i9JnnC1fJ69Kd0Q= X-Received: by 127.0.0.2 with SMTP id Bz7zYY1788612xx5geZdIlJI; Thu, 26 Oct 2023 01:35:22 -0700 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.48]) by mx.groups.io with SMTP id smtpd.web11.65896.1698309321918962066 for ; Thu, 26 Oct 2023 01:35:22 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ek7OrjQWZWP90MOY6J+rc9AWne7L3BHAuV0NKtx6/n1ikVouXSdOpE0ve1SEgSbcr63AjyYXvC2S1fiY9k5p73tif/XqA1o7+no5F0LkoRL84Nr8tw8keiJBLyj9WraCpGs8QaTXbTR6jJSeoafoyMQDWB3J7WZwWIMdVMVsG3hYXgvvoK0fGK5Tz5mh1YGT1oxVWzbK+pG1i11WbTI3YquIHjEy5tQbVDiWroi9Ydy7w4u2HOvPBM8L/V5Mggn6nzeHTEq0pOu3lvhdpm56FBD2YTWciJHnbLLASIAIXJRMqYN9WeXrO5Zmip4FBOFndV/7jrVPL0V6EpOSw/26jw== 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=gqxzMuptFv5sZD9Dq8nZ/ni5S5A3LInRf+PeyXskmIw=; b=jKB7OJyuiSF98w4zoKhuUvRBdeOO391R+TEMiYyvcFYHjhSKQYesC7qKgUzfwkFQzoGKalNemwhBAWnvAn1ve8g3BRyCzpYxHOoaOKp5F3h1MD/OjVO/0XtSF/Gr8e8/7R++DFvKKlvuIaSFAqo1/RdwQDa+d4VkQNTIwMZt9mlDSXeZYPhWENDfwGDUtTRcHwsedQ+R8mCGiKSwKTfhyt4VawdSFwjtv+IAh0GBNNBTuJbH0EHD7q8JSYPTtAnfUAw9O/9i9ROhCMx3CCHXmtHi/OX6tf113Ixmo5nEh9pUW6kzZmORu28N8TQ518R+oJGNXcmpzPckjJ1Jz5/7Lw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) 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 DM5PR07CA0101.namprd07.prod.outlook.com (2603:10b6:4:ae::30) by SA1PR12MB6799.namprd12.prod.outlook.com (2603:10b6:806:25b::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6907.33; Thu, 26 Oct 2023 08:35:18 +0000 X-Received: from DS1PEPF00017095.namprd03.prod.outlook.com (2603:10b6:4:ae:cafe::4c) by DM5PR07CA0101.outlook.office365.com (2603:10b6:4:ae::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.22 via Frontend Transport; Thu, 26 Oct 2023 08:35:18 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) 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+110082+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C X-Received: from mail.nvidia.com (216.228.117.160) by DS1PEPF00017095.mail.protection.outlook.com (10.167.17.138) 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 08:35:17 +0000 X-Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.66) 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 01:35:05 -0700 X-Received: from rnnvmail201.nvidia.com (10.129.68.8) by rnnvmail201.nvidia.com (10.129.68.8) 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 01:35:05 -0700 X-Received: from NV-CL38DL3.nvidia.com (10.127.8.11) by mail.nvidia.com (10.129.68.8) with Microsoft SMTP Server id 15.2.986.41 via Frontend Transport; Thu, 26 Oct 2023 01:35:04 -0700 From: "Nickle Wang via groups.io" To: CC: Abner Chang , Igor Kulchytskyy , "Nick Ramirez" Subject: [edk2-devel] [edk2-redfish-client][PATCH] RedfishClientPkg/RedfishLib: align with edk2 RedfishLib Date: Thu, 26 Oct 2023 16:35:03 +0800 Message-ID: <20231026083503.20169-1-nicklew@nvidia.com> MIME-Version: 1.0 X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017095:EE_|SA1PR12MB6799:EE_ X-MS-Office365-Filtering-Correlation-Id: 690670cb-58e7-4046-996b-08dbd5fe7beb X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: DLqsSBtCntv0bHrAXEcnz9DXB3Fv9sjGC4T0kysGv3lYOnJLerpl18GLa1S/KlC8ayxzskJotBUve04mAazP1yQk7T7FhP8whO5So4IlYfWYLE2/ubcF9S5mjuGcQjp2+3bUnfqKnsFa4pjsJFTloLuZPiXqhdGLm/+F4YIl7h/64c36ltnGDRlClOwP98dhCqeLTcp5rlmag6TDkjbx1imREQnzujt0/E0fsA8UFNK6poy43TbxNhLAXQWxgWlhYuvN6J086xGxK9kaiSPKJBYz1wvl0oHGkutHmn8vV0VBYC/1Gm8xx0p4wQ6oCc/vrJVjFITejhw/dhKgsFasemu30ok9+J348TMfRd6FbBg0dPX0pC+lt9WhhnjKWNBR5x1Q+/zvIaKGkj+WNx+wvZH6NCFd7XpWHJFAobwFQcCbG6svjdl0QSXtV83AVIMngya/prrPzsHAYOMVTiZB4Iek7HaGpjDV8VNanBi+gxTWLVZfqZ8uY05XfsX4MoIKy5iZAta66ZaFLms1raUfGLoco9ZqKJ8Ay8V6uAgQutA1Oz98GicXaqYDjNp4Khyz8OA94j+6oqRVYrFamC+FNJX/yZtoyk6h4G89ulfrfQG/1Y58VTQs9G/u+NZvl7g31u1Qm3a9xpudWhT+jchFc4BaH/L7VGxt5G7W2FC7X6jefmkTP5/pNIFWTc3m5+QN7RKVljupXB4TytUAVk4huepR/uh4LEwCC/f8tkXDHKjD2sOl6X82+U2ik+MIkEITrZNrMNxiH1CpDRDQhoa+5nj7LpTc7bAuYEcYDYJUd4g= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Oct 2023 08:35:17.9098 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 690670cb-58e7-4046-996b-08dbd5fe7beb X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017095.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB6799 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: OujU8zbQbBkYkLL43bBrhrMxx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1698309324411100003 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 --- .../PrivateLibrary/RedfishLib/RedfishLib.inf | 1 + .../edk2libredfish/include/redfishPayload.h | 32 +- .../edk2libredfish/include/redfishService.h | 21 + .../PrivateLibrary/RedfishLib/RedfishLib.c | 345 +++++++++++- .../PrivateLibrary/RedfishLib/RedfishMisc.c | 13 +- .../RedfishLib/edk2libredfish/src/payload.c | 124 +--- .../RedfishLib/edk2libredfish/src/service.c | 531 ++++++------------ 7 files changed, 527 insertions(+), 540 deletions(-) diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.inf b/Re= dfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.inf index a54e397d..79d8792f 100644 --- a/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.inf +++ b/RedfishClientPkg/PrivateLibrary/RedfishLib/RedfishLib.inf @@ -3,6 +3,7 @@ # # Copyright (c) 2019, Intel Corporation. All rights reserved.
# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserve= d. # # SPDX-License-Identifier: BSD-2-Clause-Patent # diff --git a/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libredfish/incl= ude/redfishPayload.h b/RedfishClientPkg/PrivateLibrary/RedfishLib/edk2libre= dfish/include/redfishPayload.h index 8403d693..f7917603 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 @@ -65,15 +66,6 @@ patchPayload ( EFI_HTTP_STATUS_CODE **StatusCode ); =20 -redfishPayload * -patchPayloadEx ( - redfishPayload *target, - redfishPayload *payload, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ); - redfishPayload * postContentToPayload ( redfishPayload *target, @@ -83,17 +75,6 @@ postContentToPayload ( EFI_HTTP_STATUS_CODE **StatusCode ); =20 -redfishPayload * -postContentToPayloadEx ( - redfishPayload *target, - const char *data, - size_t dataSize, - const char *contentType, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ); - redfishPayload * postPayload ( redfishPayload *target, @@ -101,15 +82,6 @@ postPayload ( EFI_HTTP_STATUS_CODE **StatusCode ); =20 -redfishPayload * -postPayloadEx ( - redfishPayload *target, - redfishPayload *payload, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ); - void cleanupPayload ( redfishPayload *payload 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..8a4483b4 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. @@ -556,11 +583,9 @@ RedfishPatchToPayload ( =20 ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); =20 - RedResponse->Payload =3D (REDFISH_PAYLOAD)patchPayloadEx ( + RedResponse->Payload =3D (REDFISH_PAYLOAD)patchPayload ( Target, Payload, - &RedResponse->Headers, - &RedResponse->HeaderCount, &(RedResponse->StatusCode) ); =20 @@ -585,6 +610,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 +723,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. @@ -626,11 +749,9 @@ RedfishPostToPayload ( =20 ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); =20 - RedResponse->Payload =3D (REDFISH_PAYLOAD)postPayloadEx ( + RedResponse->Payload =3D (REDFISH_PAYLOAD)postPayload ( Target, Payload, - &RedResponse->Headers, - &RedResponse->HeaderCount, &(RedResponse->StatusCode) ); =20 @@ -670,7 +791,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 +863,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 +1089,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 +1156,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 +1246,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..39803575 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 @@ -379,45 +380,6 @@ getPayloadForPathString ( return ret; } =20 -redfishPayload * -patchPayloadEx ( - redfishPayload *target, - redfishPayload *payload, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ) -{ - json_t *json; - char *content; - char *uri; - - if (!target || !payload || (StatusCode =3D=3D NULL)) { - return NULL; - } - - *StatusCode =3D NULL; - - json =3D json_object_get (target->json, "@odata.id"); - if (json =3D=3D NULL) { - return NULL; - } - - uri =3D strdup (json_string_value (json)); - - content =3D json_dumps (payload->json, 0); - json_decref (json); - - json =3D patchUriFromServiceEx (target->service, uri, content, Headers, = HeaderCount, StatusCode); - free (uri); - free (content); - if (json =3D=3D NULL) { - return NULL; - } - - return createRedfishPayload (json, target->service); -} - redfishPayload * patchPayload ( redfishPayload *target, @@ -455,44 +417,6 @@ patchPayload ( return createRedfishPayload (json, target->service); } =20 -redfishPayload * -postContentToPayloadEx ( - redfishPayload *target, - const char *data, - size_t dataSize, - const char *contentType, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ) -{ - json_t *json; - char *uri; - - if (!target || !data || (StatusCode =3D=3D NULL)) { - return NULL; - } - - *StatusCode =3D NULL; - - json =3D json_object_get (target->json, "@odata.id"); - if (json =3D=3D NULL) { - json =3D json_object_get (target->json, "target"); - if (json =3D=3D NULL) { - return NULL; - } - } - - uri =3D strdup (json_string_value (json)); - json =3D postUriFromServiceEx (target->service, uri, data, dataSize, con= tentType, Headers, HeaderCount, StatusCode); - free (uri); - if (json =3D=3D NULL) { - return NULL; - } - - return createRedfishPayload (json, target->service); -} - redfishPayload * postContentToPayload ( redfishPayload *target, @@ -529,34 +453,6 @@ postContentToPayload ( return createRedfishPayload (json, target->service); } =20 -redfishPayload * -postPayloadEx ( - redfishPayload *target, - redfishPayload *payload, - EFI_HTTP_HEADER **Headers, - UINTN *HeaderCount, - EFI_HTTP_STATUS_CODE **StatusCode - ) -{ - char *content; - redfishPayload *ret; - - if (!target || !payload || (StatusCode =3D=3D NULL)) { - return NULL; - } - - *StatusCode =3D NULL; - - if (!json_is_object (payload->json)) { - return NULL; - } - - content =3D payloadToString (payload, false); - ret =3D postContentToPayloadEx (target, content, strlen (content), N= ULL, Headers, HeaderCount, StatusCode); - free (content); - return ret; -} - redfishPayload * postPayload ( redfishPayload *target, @@ -629,7 +525,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); @@ -725,6 +621,7 @@ collectionEvalOp ( if (((*StatusCode =3D=3D NULL) && (members =3D=3D NULL)) || ((*StatusCode !=3D NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || = (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT)))) { + free (valid); return members; } =20 @@ -738,6 +635,7 @@ collectionEvalOp ( if (((*StatusCode =3D=3D NULL) && (tmp =3D=3D NULL)) || ((*StatusCode !=3D NULL) && ((**StatusCode < HTTP_STATUS_200_OK) |= | (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT)))) { + free (valid); return tmp; } =20 @@ -763,19 +661,15 @@ collectionEvalOp ( =20 cleanupPayload (members); if (validCount =3D=3D 0) { - free (valid); - return NULL; - } - - if (validCount =3D=3D 1) { + ret =3D NULL; + } else if (validCount =3D=3D 1) { ret =3D valid[0]; - free (valid); - return ret; } else { ret =3D createCollection (payload->service, validCount, valid); - free (valid); - return ret; } + + free (valid); + return ret; } =20 static redfishPayload * 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 (#110082): https://edk2.groups.io/g/devel/message/110082 Mute This Topic: https://groups.io/mt/102196088/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-