TianoCore EDK2 master
Loading...
Searching...
No Matches
RedfishHttpData.c
Go to the documentation of this file.
1
10#include "RedfishHttpData.h"
12
26 IN CHAR8 *Token
27 )
28{
29 if ((Service == NULL) || IS_EMPTY_STRING (Token)) {
30 return EFI_INVALID_PARAMETER;
31 }
32
33 if (Service->SessionToken != NULL) {
34 FreePool (Service->SessionToken);
35 }
36
37 Service->SessionToken = ASCII_STR_DUPLICATE (Token);
38 if (Service->SessionToken == NULL) {
39 return EFI_OUT_OF_RESOURCES;
40 }
41
42 return EFI_SUCCESS;
43}
44
57 )
58{
59 if (Service == NULL) {
60 return EFI_INVALID_PARAMETER;
61 }
62
63 if (Service->Host != NULL) {
64 FreePool (Service->Host);
65 }
66
67 if (Service->HostName != NULL) {
68 FreePool (Service->HostName);
69 }
70
71 if (Service->BasicAuth != NULL) {
72 ZeroMem (Service->BasicAuth, AsciiStrSize (Service->BasicAuth));
73 FreePool (Service->BasicAuth);
74 }
75
76 if (Service->SessionToken != NULL) {
77 ZeroMem (Service->SessionToken, AsciiStrSize (Service->SessionToken));
78 FreePool (Service->SessionToken);
79 }
80
81 FreePool (Service);
82
83 return EFI_SUCCESS;
84}
85
102 IN CHAR8 *Host,
103 IN CHAR8 *HostName,
104 IN CHAR8 *BasicAuth OPTIONAL,
105 IN CHAR8 *SessionToken OPTIONAL,
107 )
108{
109 REDFISH_SERVICE_PRIVATE *NewService;
110 UINTN AuthStrSize;
111
112 if (IS_EMPTY_STRING (Host) || IS_EMPTY_STRING (HostName) || (RestEx == NULL)) {
113 return NULL;
114 }
115
116 NewService = AllocateZeroPool (sizeof (REDFISH_SERVICE_PRIVATE));
117 if (NewService == NULL) {
118 return NULL;
119 }
120
121 NewService->Signature = REDFISH_HTTP_SERVICE_SIGNATURE;
122 NewService->Host = ASCII_STR_DUPLICATE (Host);
123 if (NewService->Host == NULL) {
124 goto ON_ERROR;
125 }
126
127 NewService->HostName = ASCII_STR_DUPLICATE (HostName);
128 if (NewService->HostName == NULL) {
129 goto ON_ERROR;
130 }
131
132 if (!IS_EMPTY_STRING (BasicAuth)) {
133 AuthStrSize = AsciiStrSize (BasicAuth) + AsciiStrLen (REDFISH_HTTP_BASIC_AUTH_STR);
134 NewService->BasicAuth = AllocateZeroPool (AuthStrSize);
135 if (NewService->BasicAuth == NULL) {
136 goto ON_ERROR;
137 }
138
139 AsciiSPrint (NewService->BasicAuth, AuthStrSize, "%a%a", REDFISH_HTTP_BASIC_AUTH_STR, BasicAuth);
140 }
141
142 if (!IS_EMPTY_STRING (SessionToken)) {
143 NewService->SessionToken = ASCII_STR_DUPLICATE (SessionToken);
144 if (NewService->SessionToken == NULL) {
145 goto ON_ERROR;
146 }
147 }
148
149 NewService->RestEx = RestEx;
150
151 return NewService;
152
153ON_ERROR:
154
155 ReleaseRedfishService (NewService);
156
157 return NULL;
158}
159
172 )
173{
174 if (Payload == NULL) {
175 return EFI_INVALID_PARAMETER;
176 }
177
178 if (Payload->Service != NULL) {
179 ReleaseRedfishService (Payload->Service);
180 }
181
182 if (Payload->JsonValue != NULL) {
183 JsonValueFree (Payload->JsonValue);
184 }
185
186 FreePool (Payload);
187
188 return EFI_SUCCESS;
189}
190
205 IN EDKII_JSON_VALUE JsonValue
206 )
207{
208 REDFISH_PAYLOAD_PRIVATE *NewPayload;
209
210 if ((Service == NULL) || (JsonValue == NULL)) {
211 return NULL;
212 }
213
214 NewPayload = AllocateZeroPool (sizeof (REDFISH_PAYLOAD_PRIVATE));
215 if (NewPayload == NULL) {
216 return NULL;
217 }
218
219 NewPayload->Signature = REDFISH_HTTP_PAYLOAD_SIGNATURE;
220 NewPayload->Service = CreateRedfishService (Service->Host, Service->HostName, Service->BasicAuth, Service->SessionToken, Service->RestEx);
221 if (NewPayload->Service == NULL) {
222 goto ON_ERROR;
223 }
224
225 NewPayload->JsonValue = JsonValueClone (JsonValue);
226 if (NewPayload->JsonValue == NULL) {
227 goto ON_ERROR;
228 }
229
230 return NewPayload;
231
232ON_ERROR:
233
234 ReleaseRedfishPayload (NewPayload);
235
236 return NULL;
237}
238
251 IN REDFISH_RESPONSE *SrcResponse,
252 OUT REDFISH_RESPONSE *DstResponse
253 )
254{
256 UINTN Index;
257
258 if ((SrcResponse == NULL) || (DstResponse == NULL)) {
259 return EFI_INVALID_PARAMETER;
260 }
261
262 if (SrcResponse == DstResponse) {
263 return EFI_SUCCESS;
264 }
265
266 //
267 // Status code
268 //
269 if (SrcResponse->StatusCode != NULL) {
270 DstResponse->StatusCode = AllocateCopyPool (sizeof (EFI_HTTP_STATUS_CODE), SrcResponse->StatusCode);
271 if (DstResponse->StatusCode == NULL) {
272 goto ON_ERROR;
273 }
274 }
275
276 //
277 // Header
278 //
279 if ((SrcResponse->HeaderCount > 0) && (SrcResponse->Headers != NULL)) {
280 DstResponse->HeaderCount = 0;
281 DstResponse->Headers = AllocateZeroPool (sizeof (EFI_HTTP_HEADER) * SrcResponse->HeaderCount);
282 if (DstResponse->Headers == NULL) {
283 goto ON_ERROR;
284 }
285
286 DstResponse->HeaderCount = SrcResponse->HeaderCount;
287
288 for (Index = 0; Index < SrcResponse->HeaderCount; Index++) {
289 DstResponse->Headers[Index].FieldName = ASCII_STR_DUPLICATE (SrcResponse->Headers[Index].FieldName);
290 if (DstResponse->Headers[Index].FieldName == NULL) {
291 goto ON_ERROR;
292 }
293
294 DstResponse->Headers[Index].FieldValue = ASCII_STR_DUPLICATE (SrcResponse->Headers[Index].FieldValue);
295 if (DstResponse->Headers[Index].FieldValue == NULL) {
296 goto ON_ERROR;
297 }
298 }
299 }
300
301 //
302 // Payload
303 //
304 if (SrcResponse->Payload != NULL) {
305 Payload = (REDFISH_PAYLOAD_PRIVATE *)SrcResponse->Payload;
306 if (Payload->Signature != REDFISH_HTTP_PAYLOAD_SIGNATURE) {
307 DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
308 goto ON_ERROR;
309 }
310
311 DstResponse->Payload = CreateRedfishPayload (Payload->Service, Payload->JsonValue);
312 if (DstResponse->Payload == NULL) {
313 goto ON_ERROR;
314 }
315 }
316
317 return EFI_SUCCESS;
318
319ON_ERROR:
320
321 ReleaseRedfishResponse (DstResponse);
322
323 return EFI_OUT_OF_RESOURCES;
324}
325
337 IN REDFISH_RESPONSE *Response
338 )
339{
340 EFI_STATUS Status;
341 REDFISH_RESPONSE *NewResponse;
342
343 if (Response == NULL) {
344 return NULL;
345 }
346
347 NewResponse = AllocateZeroPool (sizeof (REDFISH_RESPONSE));
348 if (NewResponse == NULL) {
349 return NULL;
350 }
351
352 Status = CopyRedfishResponse (Response, NewResponse);
353 if (EFI_ERROR (Status)) {
354 FreePool (NewResponse);
355 return NULL;
356 }
357
358 return NewResponse;
359}
360
373 )
374{
375 if (Data == NULL) {
376 return EFI_INVALID_PARAMETER;
377 }
378
379 if (Data->Uri != NULL) {
380 FreePool (Data->Uri);
381 }
382
383 if (Data->Response != NULL) {
384 ReleaseRedfishResponse (Data->Response);
385 FreePool (Data->Response);
386 }
387
388 FreePool (Data);
389
390 return EFI_SUCCESS;
391}
392
405 IN EFI_STRING Uri,
406 IN REDFISH_RESPONSE *Response
407 )
408{
410 UINTN Size;
411
412 if (IS_EMPTY_STRING (Uri) || (Response == NULL)) {
413 return NULL;
414 }
415
416 NewData = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_DATA));
417 if (NewData == NULL) {
418 return NULL;
419 }
420
421 NewData->Signature = REDFISH_HTTP_CACHE_SIGNATURE;
422 Size = StrSize (Uri);
423 NewData->Uri = AllocateCopyPool (Size, Uri);
424 if (NewData->Uri == NULL) {
425 goto ON_ERROR;
426 }
427
428 NewData->Response = Response;
429 NewData->HitCount = 1;
430
431 return NewData;
432
433ON_ERROR:
434
435 if (NewData != NULL) {
436 ReleaseHttpCacheData (NewData);
437 }
438
439 return NULL;
440}
441
454 IN LIST_ENTRY *ListHeader,
455 IN EFI_STRING Uri
456 )
457{
458 LIST_ENTRY *List;
460
461 if (IS_EMPTY_STRING (Uri)) {
462 return NULL;
463 }
464
465 if (IsListEmpty (ListHeader)) {
466 return NULL;
467 }
468
469 Data = NULL;
470 List = GetFirstNode (ListHeader);
471 while (!IsNull (ListHeader, List)) {
472 Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
473
474 if (StrCmp (Data->Uri, Uri) == 0) {
475 return Data;
476 }
477
478 List = GetNextNode (ListHeader, List);
479 }
480
481 return NULL;
482}
483
495 IN LIST_ENTRY *ListHeader
496 )
497{
498 LIST_ENTRY *List;
500 REDFISH_HTTP_CACHE_DATA *UnusedData;
501 UINTN HitCount;
502
503 if (IsListEmpty (ListHeader)) {
504 return NULL;
505 }
506
507 Data = NULL;
508 UnusedData = NULL;
509 HitCount = 0;
510
511 List = GetFirstNode (ListHeader);
512 Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
513 UnusedData = Data;
514 HitCount = Data->HitCount;
515 List = GetNextNode (ListHeader, List);
516
517 while (!IsNull (ListHeader, List)) {
518 Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
519
520 if (Data->HitCount < HitCount) {
521 HitCount = Data->HitCount;
522 UnusedData = Data;
523 }
524
525 List = GetNextNode (ListHeader, List);
526 }
527
528 return UnusedData;
529}
530
545 )
546{
547 if ((List == NULL) || (Data == NULL)) {
548 return EFI_INVALID_PARAMETER;
549 }
550
551 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: delete: %s\n", __func__, Data->Uri));
552
553 RemoveEntryList (&Data->List);
554 --List->Count;
555
556 return ReleaseHttpCacheData (Data);
557}
558
573 IN EFI_STRING Uri,
574 IN REDFISH_RESPONSE *Response
575 )
576{
579 REDFISH_HTTP_CACHE_DATA *UnusedData;
580 REDFISH_RESPONSE *NewResponse;
581
582 if ((List == NULL) || IS_EMPTY_STRING (Uri) || (Response == NULL)) {
583 return EFI_INVALID_PARAMETER;
584 }
585
586 //
587 // If same cache data exist, replace it with latest one.
588 //
589 OldData = FindHttpCacheData (&List->Head, Uri);
590 if (OldData != NULL) {
591 DeleteHttpCacheData (List, OldData);
592 }
593
594 //
595 // Check capacity
596 //
597 if (List->Count >= List->Capacity) {
598 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: list is full and retire unused cache\n", __func__));
599 UnusedData = FindUnusedHttpCacheData (&List->Head);
600 if (UnusedData == NULL) {
601 return EFI_OUT_OF_RESOURCES;
602 }
603
604 DeleteHttpCacheData (List, UnusedData);
605 }
606
607 //
608 // Clone a local copy
609 //
610 NewResponse = CloneRedfishResponse (Response);
611 if (NewResponse == NULL) {
612 return EFI_OUT_OF_RESOURCES;
613 }
614
615 NewData = NewHttpCacheData (Uri, NewResponse);
616 if (NewData == NULL) {
617 return EFI_OUT_OF_RESOURCES;
618 }
619
620 InsertTailList (&List->Head, &NewData->List);
621 ++List->Count;
622
623 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache(%d/%d) %s\n", __func__, List->Count, List->Capacity, NewData->Uri));
624
625 return EFI_SUCCESS;
626}
627
639 IN REDFISH_HTTP_CACHE_LIST *CacheList
640 )
641{
642 LIST_ENTRY *List;
643 LIST_ENTRY *Next;
645
646 if (CacheList == NULL) {
647 return EFI_INVALID_PARAMETER;
648 }
649
650 if (IsListEmpty (&CacheList->Head)) {
651 return EFI_SUCCESS;
652 }
653
654 Data = NULL;
655 Next = NULL;
656 List = GetFirstNode (&CacheList->Head);
657 while (!IsNull (&CacheList->Head, List)) {
658 Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
659 Next = GetNextNode (&CacheList->Head, List);
660
661 DeleteHttpCacheData (CacheList, Data);
662
663 List = Next;
664 }
665
666 return EFI_SUCCESS;
667}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID EFIAPI JsonValueFree(IN EDKII_JSON_VALUE Json)
Definition: JsonLib.c:269
EDKII_JSON_VALUE EFIAPI JsonValueClone(IN EDKII_JSON_VALUE Json)
Definition: JsonLib.c:295
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_HTTP_STATUS_CODE
Definition: Http.h:59
EFI_STATUS AddHttpCacheData(IN REDFISH_HTTP_CACHE_LIST *List, IN EFI_STRING Uri, IN REDFISH_RESPONSE *Response)
EFI_STATUS ReleaseRedfishPayload(IN REDFISH_PAYLOAD_PRIVATE *Payload)
REDFISH_HTTP_CACHE_DATA * FindUnusedHttpCacheData(IN LIST_ENTRY *ListHeader)
REDFISH_SERVICE_PRIVATE * CreateRedfishService(IN CHAR8 *Host, IN CHAR8 *HostName, IN CHAR8 *BasicAuth OPTIONAL, IN CHAR8 *SessionToken OPTIONAL, IN EFI_REST_EX_PROTOCOL *RestEx)
EFI_STATUS CopyRedfishResponse(IN REDFISH_RESPONSE *SrcResponse, OUT REDFISH_RESPONSE *DstResponse)
REDFISH_RESPONSE * CloneRedfishResponse(IN REDFISH_RESPONSE *Response)
EFI_STATUS UpdateSessionToken(IN REDFISH_SERVICE_PRIVATE *Service, IN CHAR8 *Token)
EFI_STATUS ReleaseRedfishService(IN REDFISH_SERVICE_PRIVATE *Service)
REDFISH_HTTP_CACHE_DATA * NewHttpCacheData(IN EFI_STRING Uri, IN REDFISH_RESPONSE *Response)
EFI_STATUS ReleaseCacheList(IN REDFISH_HTTP_CACHE_LIST *CacheList)
EFI_STATUS DeleteHttpCacheData(IN REDFISH_HTTP_CACHE_LIST *List, IN REDFISH_HTTP_CACHE_DATA *Data)
REDFISH_HTTP_CACHE_DATA * FindHttpCacheData(IN LIST_ENTRY *ListHeader, IN EFI_STRING Uri)
REDFISH_PAYLOAD_PRIVATE * CreateRedfishPayload(IN REDFISH_SERVICE_PRIVATE *Service, IN EDKII_JSON_VALUE JsonValue)
EFI_STATUS ReleaseHttpCacheData(IN REDFISH_HTTP_CACHE_DATA *Data)
EFI_STATUS ReleaseRedfishResponse(IN REDFISH_RESPONSE *Response)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112