]> git.proxmox.com Git - mirror_edk2.git/blob - RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
MdePkg/Include: EFI Redfish Discover protocol
[mirror_edk2.git] / RedfishPkg / RedfishRestExDxe / RedfishRestExImpl.c
1 /** @file
2 RestExDxe support functions implementation.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10 #include <Uefi.h>
11 #include "RedfishRestExInternal.h"
12
13 /**
14 Create a new TLS session becuase the previous on is closed.
15 status.
16
17 @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular
18 REST service.
19 @retval EFI_SUCCESS operation succeeded.
20 @retval EFI_ERROR Other errors.
21
22 **/
23 EFI_STATUS
24 ResetHttpTslSession (
25 IN RESTEX_INSTANCE *Instance
26 )
27 {
28 EFI_STATUS Status;
29
30 DEBUG ((DEBUG_INFO, "%a: TCP connection is finished. Could be TSL session closure, reset HTTP instance for the new TLS session.\n", __FUNCTION__));
31
32 Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, NULL);
33 if (EFI_ERROR (Status)) {
34 DEBUG ((DEBUG_ERROR, "%a: Error to reset HTTP instance.\n", __FUNCTION__));
35 return Status;
36 }
37 Status = Instance->HttpIo.Http->Configure(Instance->HttpIo.Http, &((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData);
38 if (EFI_ERROR (Status)) {
39 DEBUG ((DEBUG_ERROR, "%a: Error to re-initiate HTTP instance.\n", __FUNCTION__));
40 }
41 return Status;
42 }
43 /**
44 This function check
45
46 @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular
47 REST service.
48 @param[in] HttpIoReceiveStatus This is the status return from HttpIoRecvResponse
49
50 @retval EFI_SUCCESS The payload receive from Redfish service in sucessfully.
51 @retval EFI_NOT_READY May need to resend the HTTP request.
52 @retval EFI_DEVICE_ERROR Something wrong and can't be resolved.
53 @retval Others Other errors as indicated.
54
55 **/
56 EFI_STATUS
57 RedfishCheckHttpReceiveStatus (
58 IN RESTEX_INSTANCE *Instance,
59 IN EFI_STATUS HttpIoReceiveStatus
60 )
61 {
62 EFI_STATUS Status;
63 EFI_STATUS ReturnStatus;
64
65 if (!EFI_ERROR (HttpIoReceiveStatus)){
66 ReturnStatus = EFI_SUCCESS;
67 } else if (EFI_ERROR (HttpIoReceiveStatus) && HttpIoReceiveStatus != EFI_CONNECTION_FIN) {
68 if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY) == 0) {
69 DEBUG ((DEBUG_ERROR, "%a: TCP error, reset HTTP session.\n", __FUNCTION__));
70 Instance->Flags |= RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY;
71 gBS->Stall (500);
72 Status = ResetHttpTslSession (Instance);
73 if (EFI_ERROR (Status)) {
74 DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__));
75 ReturnStatus = EFI_DEVICE_ERROR;
76 } else {
77 return EFI_NOT_READY;
78 }
79 } else {
80 ReturnStatus = EFI_DEVICE_ERROR;
81 }
82 } else {
83 if (HttpIoReceiveStatus == EFI_CONNECTION_FIN) {
84 if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TLS_RETRY) != 0) {
85 DEBUG ((DEBUG_ERROR, "%a: REST_EX Send and receive fail even with a new TLS session.\n", __FUNCTION__));
86 ReturnStatus = EFI_DEVICE_ERROR;
87 }
88 Instance->Flags |= RESTEX_INSTANCE_FLAGS_TLS_RETRY;
89 Status = ResetHttpTslSession (Instance);
90 if (EFI_ERROR (Status)) {
91 DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__));
92 ReturnStatus = EFI_DEVICE_ERROR;
93 }
94 return EFI_NOT_READY;
95 }
96 }
97 //
98 // Clean TLS new session retry and error try flags.
99 //
100 Instance->Flags &= ~ (RESTEX_INSTANCE_FLAGS_TLS_RETRY | RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY);
101 return ReturnStatus;
102 }
103
104 /**
105 This function send the HTTP request without body to see
106 if the write to URL is permitted by Redfish service. This function
107 checks if the HTTP request has Content-length in HTTP header. If yes,
108 set HTTP body to NULL and then send to service. Check the HTTP status
109 for the firther actions.
110
111 @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular
112 REST service.
113 @param[in] RequestMessage Pointer to the HTTP request data for this resource
114 @param[in] PreservedRequestHeaders The pointer to save the request headers
115 @param[in] ItsWrite This is write method to URL.
116
117 @retval EFI_INVALID_PARAMETER Improper given parameters.
118 @retval EFI_SUCCESS This HTTP request is free to send to Redfish service.
119 @retval EFI_OUT_OF_RESOURCES NOt enough memory to process.
120 @retval EFI_ACCESS_DENIED Not allowed to write to this URL.
121
122 @retval Others Other errors as indicated.
123
124 **/
125 EFI_STATUS
126 RedfishHttpAddExpectation (
127 IN EFI_REST_EX_PROTOCOL *This,
128 IN EFI_HTTP_MESSAGE *RequestMessage,
129 IN EFI_HTTP_HEADER **PreservedRequestHeaders,
130 IN BOOLEAN *ItsWrite
131 )
132 {
133 EFI_HTTP_HEADER *NewHeaders;
134
135 if (This == NULL || RequestMessage == NULL) {
136 return EFI_INVALID_PARAMETER;
137 }
138
139 *ItsWrite = FALSE;
140 if (PreservedRequestHeaders != NULL) {
141 *PreservedRequestHeaders = RequestMessage->Headers;
142 }
143
144 if ((RequestMessage->Data.Request->Method != HttpMethodPut) && (RequestMessage->Data.Request->Method != HttpMethodPost) &&
145 (RequestMessage->Data.Request->Method != HttpMethodPatch)) {
146 return EFI_SUCCESS;
147 }
148 *ItsWrite = TRUE;
149
150 NewHeaders = AllocateZeroPool((RequestMessage->HeaderCount + 1) * sizeof(EFI_HTTP_HEADER));
151 CopyMem ((VOID*)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER));
152 HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE);
153 RequestMessage->HeaderCount ++;
154 RequestMessage->Headers = NewHeaders;
155 return EFI_SUCCESS;
156 }
157