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