TianoCore EDK2 master
Loading...
Searching...
No Matches
HttpProto.c
Go to the documentation of this file.
1
11#include "HttpDriver.h"
12
20VOID
21EFIAPI
23 IN EFI_EVENT Event,
24 IN VOID *Context
25 )
26{
27 if ((Event == NULL) || (Context == NULL)) {
28 return;
29 }
30
31 *((BOOLEAN *)Context) = TRUE;
32}
33
40VOID
41EFIAPI
43 IN VOID *Context
44 )
45{
46 HTTP_TOKEN_WRAP *Wrap;
47 HTTP_PROTOCOL *HttpInstance;
48
49 if (Context == NULL) {
50 return;
51 }
52
53 Wrap = (HTTP_TOKEN_WRAP *)Context;
54 HttpInstance = Wrap->HttpInstance;
55
56 if (!HttpInstance->LocalAddressIsIPv6) {
57 Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;
58 gBS->SignalEvent (Wrap->HttpToken->Event);
59
60 //
61 // Free resources.
62 //
63 if (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {
64 FreePool (Wrap->TcpWrap.Tx4Token.Packet.TxData->FragmentTable[0].FragmentBuffer);
65 }
66
67 if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {
68 gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
69 }
70 } else {
71 Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;
72 gBS->SignalEvent (Wrap->HttpToken->Event);
73
74 //
75 // Free resources.
76 //
77 if (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer != NULL) {
78 FreePool (Wrap->TcpWrap.Tx6Token.Packet.TxData->FragmentTable[0].FragmentBuffer);
79 }
80
81 if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {
82 gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
83 }
84 }
85
86 Wrap->TcpWrap.IsTxDone = TRUE;
87
88 //
89 // Check pending TxTokens and sent out.
90 //
91 NetMapIterate (&Wrap->HttpInstance->TxTokens, HttpTcpTransmit, NULL);
92}
93
101VOID
102EFIAPI
104 IN EFI_EVENT Event,
105 IN VOID *Context
106 )
107{
108 //
109 // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK
110 //
111 QueueDpc (TPL_CALLBACK, HttpTcpTransmitNotifyDpc, Context);
112}
113
120VOID
121EFIAPI
123 IN VOID *Context
124 )
125{
126 HTTP_TOKEN_WRAP *Wrap;
127 NET_MAP_ITEM *Item;
128 UINTN Length;
129 EFI_STATUS Status;
130 HTTP_PROTOCOL *HttpInstance;
131 BOOLEAN UsingIpv6;
132
133 if (Context == NULL) {
134 return;
135 }
136
137 Wrap = (HTTP_TOKEN_WRAP *)Context;
138 HttpInstance = Wrap->HttpInstance;
139 UsingIpv6 = HttpInstance->LocalAddressIsIPv6;
140
141 if (UsingIpv6) {
142 gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
143 Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;
144
145 if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {
146 DEBUG ((DEBUG_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));
147 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;
148 gBS->SignalEvent (Wrap->HttpToken->Event);
149
150 Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);
151 if (Item != NULL) {
152 NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);
153 }
154
155 FreePool (Wrap);
156 Wrap = NULL;
157
158 return;
159 }
160 } else {
161 gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
162 Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;
163
164 if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {
165 DEBUG ((DEBUG_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));
166 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;
167 gBS->SignalEvent (Wrap->HttpToken->Event);
168
169 Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);
170 if (Item != NULL) {
171 NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);
172 }
173
174 FreePool (Wrap);
175 Wrap = NULL;
176
177 return;
178 }
179 }
180
181 //
182 // Check whether we receive a complete HTTP message.
183 //
184 ASSERT (HttpInstance->MsgParser != NULL);
185 if (UsingIpv6) {
186 Length = (UINTN)Wrap->TcpWrap.Rx6Data.FragmentTable[0].FragmentLength;
187 } else {
188 Length = (UINTN)Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;
189 }
190
191 //
192 // Record the CallbackData data.
193 //
194 HttpInstance->CallbackData.Wrap = (VOID *)Wrap;
195 HttpInstance->CallbackData.ParseData = Wrap->HttpToken->Message->Body;
196 HttpInstance->CallbackData.ParseDataLength = Length;
197
198 //
199 // Parse Body with CallbackData data.
200 //
201 Status = HttpParseMessageBody (
202 HttpInstance->MsgParser,
203 Length,
204 Wrap->HttpToken->Message->Body
205 );
206 if (EFI_ERROR (Status)) {
207 return;
208 }
209
210 if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
211 //
212 // Free the MsgParse since we already have a full HTTP message.
213 //
214 HttpFreeMsgParser (HttpInstance->MsgParser);
215 HttpInstance->MsgParser = NULL;
216 }
217
218 Wrap->HttpToken->Message->BodyLength = Length;
219 ASSERT (HttpInstance->CacheBody == NULL);
220 //
221 // We receive part of header of next HTTP msg.
222 //
223 if (HttpInstance->NextMsg != NULL) {
224 Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg -
225 (CHAR8 *)Wrap->HttpToken->Message->Body;
226 HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength;
227 if (HttpInstance->CacheLen != 0) {
228 HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
229 if (HttpInstance->CacheBody == NULL) {
230 return;
231 }
232
233 CopyMem (HttpInstance->CacheBody, HttpInstance->NextMsg, HttpInstance->CacheLen);
234 HttpInstance->NextMsg = HttpInstance->CacheBody;
235 HttpInstance->CacheOffset = 0;
236 }
237 }
238
239 Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
240 if (Item != NULL) {
241 NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
242 }
243
244 Wrap->TcpWrap.IsRxDone = TRUE;
245 if (UsingIpv6) {
246 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;
247 } else {
248 Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;
249 }
250
251 gBS->SignalEvent (Wrap->HttpToken->Event);
252
253 //
254 // Check pending RxTokens and receive the HTTP message.
255 //
256 NetMapIterate (&Wrap->HttpInstance->RxTokens, HttpTcpReceive, NULL);
257
258 FreePool (Wrap);
259 Wrap = NULL;
260}
261
269VOID
270EFIAPI
272 IN EFI_EVENT Event,
273 IN VOID *Context
274 )
275{
276 //
277 // Request HttpTcpTransmitNotifyDpc as a DPC at TPL_CALLBACK
278 //
279 QueueDpc (TPL_CALLBACK, HttpTcpReceiveNotifyDpc, Context);
280}
281
293 IN HTTP_PROTOCOL *HttpInstance
294 )
295{
296 EFI_STATUS Status;
297
298 if (!HttpInstance->LocalAddressIsIPv6) {
299 //
300 // Create events for various asynchronous operations.
301 //
302 Status = gBS->CreateEvent (
303 EVT_NOTIFY_SIGNAL,
304 TPL_NOTIFY,
306 &HttpInstance->IsTcp4ConnDone,
307 &HttpInstance->Tcp4ConnToken.CompletionToken.Event
308 );
309 if (EFI_ERROR (Status)) {
310 goto ERROR;
311 }
312
313 //
314 // Initialize Tcp4CloseToken
315 //
316 Status = gBS->CreateEvent (
317 EVT_NOTIFY_SIGNAL,
318 TPL_NOTIFY,
320 &HttpInstance->IsTcp4CloseDone,
321 &HttpInstance->Tcp4CloseToken.CompletionToken.Event
322 );
323 if (EFI_ERROR (Status)) {
324 goto ERROR;
325 }
326 } else {
327 //
328 // Create events for various asynchronous operations.
329 //
330 Status = gBS->CreateEvent (
331 EVT_NOTIFY_SIGNAL,
332 TPL_NOTIFY,
334 &HttpInstance->IsTcp6ConnDone,
335 &HttpInstance->Tcp6ConnToken.CompletionToken.Event
336 );
337 if (EFI_ERROR (Status)) {
338 goto ERROR;
339 }
340
341 //
342 // Initialize Tcp6CloseToken
343 //
344 Status = gBS->CreateEvent (
345 EVT_NOTIFY_SIGNAL,
346 TPL_NOTIFY,
348 &HttpInstance->IsTcp6CloseDone,
349 &HttpInstance->Tcp6CloseToken.CompletionToken.Event
350 );
351 if (EFI_ERROR (Status)) {
352 goto ERROR;
353 }
354 }
355
356 return EFI_SUCCESS;
357
358ERROR:
359 //
360 // Error handling
361 //
362 HttpCloseTcpConnCloseEvent (HttpInstance);
363
364 return Status;
365}
366
373VOID
375 IN HTTP_PROTOCOL *HttpInstance
376 )
377{
378 ASSERT (HttpInstance != NULL);
379
380 if (HttpInstance->LocalAddressIsIPv6) {
381 if (NULL != HttpInstance->Tcp6ConnToken.CompletionToken.Event) {
382 gBS->CloseEvent (HttpInstance->Tcp6ConnToken.CompletionToken.Event);
383 HttpInstance->Tcp6ConnToken.CompletionToken.Event = NULL;
384 }
385
386 if (NULL != HttpInstance->Tcp6CloseToken.CompletionToken.Event) {
387 gBS->CloseEvent (HttpInstance->Tcp6CloseToken.CompletionToken.Event);
388 HttpInstance->Tcp6CloseToken.CompletionToken.Event = NULL;
389 }
390 } else {
391 if (NULL != HttpInstance->Tcp4ConnToken.CompletionToken.Event) {
392 gBS->CloseEvent (HttpInstance->Tcp4ConnToken.CompletionToken.Event);
393 HttpInstance->Tcp4ConnToken.CompletionToken.Event = NULL;
394 }
395
396 if (NULL != HttpInstance->Tcp4CloseToken.CompletionToken.Event) {
397 gBS->CloseEvent (HttpInstance->Tcp4CloseToken.CompletionToken.Event);
398 HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;
399 }
400 }
401}
402
414 IN HTTP_TOKEN_WRAP *Wrap
415 )
416{
417 EFI_STATUS Status;
418 HTTP_PROTOCOL *HttpInstance;
419 HTTP_TCP_TOKEN_WRAP *TcpWrap;
420
421 HttpInstance = Wrap->HttpInstance;
422 TcpWrap = &Wrap->TcpWrap;
423
424 if (!HttpInstance->LocalAddressIsIPv6) {
425 Status = gBS->CreateEvent (
426 EVT_NOTIFY_SIGNAL,
427 TPL_NOTIFY,
429 Wrap,
430 &TcpWrap->Tx4Token.CompletionToken.Event
431 );
432 if (EFI_ERROR (Status)) {
433 return Status;
434 }
435
436 TcpWrap->Tx4Data.Push = TRUE;
437 TcpWrap->Tx4Data.Urgent = FALSE;
438 TcpWrap->Tx4Data.FragmentCount = 1;
439 TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;
440 TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;
441 } else {
442 Status = gBS->CreateEvent (
443 EVT_NOTIFY_SIGNAL,
444 TPL_NOTIFY,
446 Wrap,
447 &TcpWrap->Tx6Token.CompletionToken.Event
448 );
449 if (EFI_ERROR (Status)) {
450 return Status;
451 }
452
453 TcpWrap->Tx6Data.Push = TRUE;
454 TcpWrap->Tx6Data.Urgent = FALSE;
455 TcpWrap->Tx6Data.FragmentCount = 1;
456 TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;
457 TcpWrap->Tx6Token.CompletionToken.Status = EFI_NOT_READY;
458 }
459
460 return EFI_SUCCESS;
461}
462
474 IN HTTP_PROTOCOL *HttpInstance
475 )
476{
477 EFI_STATUS Status;
478
479 if (!HttpInstance->LocalAddressIsIPv6) {
480 Status = gBS->CreateEvent (
481 EVT_NOTIFY_SIGNAL,
482 TPL_NOTIFY,
484 &HttpInstance->IsRxDone,
485 &HttpInstance->Rx4Token.CompletionToken.Event
486 );
487 if (EFI_ERROR (Status)) {
488 return Status;
489 }
490
491 HttpInstance->Rx4Data.FragmentCount = 1;
492 HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data;
493 HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;
494 } else {
495 Status = gBS->CreateEvent (
496 EVT_NOTIFY_SIGNAL,
497 TPL_NOTIFY,
499 &HttpInstance->IsRxDone,
500 &HttpInstance->Rx6Token.CompletionToken.Event
501 );
502 if (EFI_ERROR (Status)) {
503 return Status;
504 }
505
506 HttpInstance->Rx6Data.FragmentCount = 1;
507 HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data;
508 HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;
509 }
510
511 return EFI_SUCCESS;
512}
513
525 IN HTTP_TOKEN_WRAP *Wrap
526 )
527{
528 EFI_STATUS Status;
529 HTTP_PROTOCOL *HttpInstance;
530 HTTP_TCP_TOKEN_WRAP *TcpWrap;
531
532 HttpInstance = Wrap->HttpInstance;
533 TcpWrap = &Wrap->TcpWrap;
534 if (!HttpInstance->LocalAddressIsIPv6) {
535 Status = gBS->CreateEvent (
536 EVT_NOTIFY_SIGNAL,
537 TPL_NOTIFY,
539 Wrap,
540 &TcpWrap->Rx4Token.CompletionToken.Event
541 );
542 if (EFI_ERROR (Status)) {
543 return Status;
544 }
545
546 TcpWrap->Rx4Data.FragmentCount = 1;
547 TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data;
548 TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;
549 } else {
550 Status = gBS->CreateEvent (
551 EVT_NOTIFY_SIGNAL,
552 TPL_NOTIFY,
554 Wrap,
555 &TcpWrap->Rx6Token.CompletionToken.Event
556 );
557 if (EFI_ERROR (Status)) {
558 return Status;
559 }
560
561 TcpWrap->Rx6Data.FragmentCount = 1;
562 TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data;
563 TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;
564 }
565
566 return EFI_SUCCESS;
567}
568
575VOID
577 IN HTTP_TOKEN_WRAP *Wrap
578 )
579{
580 HTTP_PROTOCOL *HttpInstance;
581
582 ASSERT (Wrap != NULL);
583 HttpInstance = Wrap->HttpInstance;
584
585 if (HttpInstance->LocalAddressIsIPv6) {
586 if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {
587 gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);
588 }
589
590 if (HttpInstance->Rx6Token.CompletionToken.Event != NULL) {
591 gBS->CloseEvent (HttpInstance->Rx6Token.CompletionToken.Event);
592 HttpInstance->Rx6Token.CompletionToken.Event = NULL;
593 }
594 } else {
595 if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {
596 gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);
597 }
598
599 if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {
600 gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);
601 HttpInstance->Rx4Token.CompletionToken.Event = NULL;
602 }
603 }
604}
605
618 IN OUT HTTP_PROTOCOL *HttpInstance,
619 IN BOOLEAN IpVersion
620 )
621{
622 EFI_STATUS Status;
623 VOID *Interface;
624 BOOLEAN UsingIpv6;
625
626 ASSERT (HttpInstance != NULL);
627 UsingIpv6 = IpVersion;
628
629 if (!UsingIpv6) {
630 //
631 // Create TCP4 child.
632 //
633 Status = NetLibCreateServiceChild (
634 HttpInstance->Service->ControllerHandle,
635 HttpInstance->Service->Ip4DriverBindingHandle,
636 &gEfiTcp4ServiceBindingProtocolGuid,
637 &HttpInstance->Tcp4ChildHandle
638 );
639
640 if (EFI_ERROR (Status)) {
641 goto ON_ERROR;
642 }
643
644 Status = gBS->OpenProtocol (
645 HttpInstance->Tcp4ChildHandle,
646 &gEfiTcp4ProtocolGuid,
647 (VOID **)&Interface,
648 HttpInstance->Service->Ip4DriverBindingHandle,
649 HttpInstance->Service->ControllerHandle,
650 EFI_OPEN_PROTOCOL_BY_DRIVER
651 );
652
653 if (EFI_ERROR (Status)) {
654 goto ON_ERROR;
655 }
656
657 Status = gBS->OpenProtocol (
658 HttpInstance->Tcp4ChildHandle,
659 &gEfiTcp4ProtocolGuid,
660 (VOID **)&HttpInstance->Tcp4,
661 HttpInstance->Service->Ip4DriverBindingHandle,
662 HttpInstance->Handle,
663 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
664 );
665 if (EFI_ERROR (Status)) {
666 goto ON_ERROR;
667 }
668
669 Status = gBS->OpenProtocol (
670 HttpInstance->Service->Tcp4ChildHandle,
671 &gEfiTcp4ProtocolGuid,
672 (VOID **)&Interface,
673 HttpInstance->Service->Ip4DriverBindingHandle,
674 HttpInstance->Handle,
675 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
676 );
677 if (EFI_ERROR (Status)) {
678 goto ON_ERROR;
679 }
680 } else {
681 //
682 // Create TCP6 Child.
683 //
684 Status = NetLibCreateServiceChild (
685 HttpInstance->Service->ControllerHandle,
686 HttpInstance->Service->Ip6DriverBindingHandle,
687 &gEfiTcp6ServiceBindingProtocolGuid,
688 &HttpInstance->Tcp6ChildHandle
689 );
690
691 if (EFI_ERROR (Status)) {
692 goto ON_ERROR;
693 }
694
695 Status = gBS->OpenProtocol (
696 HttpInstance->Tcp6ChildHandle,
697 &gEfiTcp6ProtocolGuid,
698 (VOID **)&Interface,
699 HttpInstance->Service->Ip6DriverBindingHandle,
700 HttpInstance->Service->ControllerHandle,
701 EFI_OPEN_PROTOCOL_BY_DRIVER
702 );
703
704 if (EFI_ERROR (Status)) {
705 goto ON_ERROR;
706 }
707
708 Status = gBS->OpenProtocol (
709 HttpInstance->Tcp6ChildHandle,
710 &gEfiTcp6ProtocolGuid,
711 (VOID **)&HttpInstance->Tcp6,
712 HttpInstance->Service->Ip6DriverBindingHandle,
713 HttpInstance->Handle,
714 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
715 );
716
717 if (EFI_ERROR (Status)) {
718 goto ON_ERROR;
719 }
720
721 Status = gBS->OpenProtocol (
722 HttpInstance->Service->Tcp6ChildHandle,
723 &gEfiTcp6ProtocolGuid,
724 (VOID **)&Interface,
725 HttpInstance->Service->Ip6DriverBindingHandle,
726 HttpInstance->Handle,
727 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
728 );
729
730 if (EFI_ERROR (Status)) {
731 goto ON_ERROR;
732 }
733 }
734
735 HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);
736 if (HttpInstance->Url == NULL) {
737 Status = EFI_OUT_OF_RESOURCES;
738 goto ON_ERROR;
739 }
740
741 HttpInstance->UrlLen = HTTP_URL_BUFFER_LEN;
742 return EFI_SUCCESS;
743
744ON_ERROR:
745
746 if (HttpInstance->Tcp4ChildHandle != NULL) {
747 gBS->CloseProtocol (
748 HttpInstance->Tcp4ChildHandle,
749 &gEfiTcp4ProtocolGuid,
750 HttpInstance->Service->Ip4DriverBindingHandle,
751 HttpInstance->Service->ControllerHandle
752 );
753
754 gBS->CloseProtocol (
755 HttpInstance->Tcp4ChildHandle,
756 &gEfiTcp4ProtocolGuid,
757 HttpInstance->Service->Ip4DriverBindingHandle,
758 HttpInstance->Handle
759 );
760
762 HttpInstance->Service->ControllerHandle,
763 HttpInstance->Service->Ip4DriverBindingHandle,
764 &gEfiTcp4ServiceBindingProtocolGuid,
765 HttpInstance->Tcp4ChildHandle
766 );
767 }
768
769 if (HttpInstance->Service->Tcp4ChildHandle != NULL) {
770 gBS->CloseProtocol (
771 HttpInstance->Service->Tcp4ChildHandle,
772 &gEfiTcp4ProtocolGuid,
773 HttpInstance->Service->Ip4DriverBindingHandle,
774 HttpInstance->Handle
775 );
776 }
777
778 if (HttpInstance->Tcp6ChildHandle != NULL) {
779 gBS->CloseProtocol (
780 HttpInstance->Tcp6ChildHandle,
781 &gEfiTcp6ProtocolGuid,
782 HttpInstance->Service->Ip6DriverBindingHandle,
783 HttpInstance->Service->ControllerHandle
784 );
785
786 gBS->CloseProtocol (
787 HttpInstance->Tcp6ChildHandle,
788 &gEfiTcp6ProtocolGuid,
789 HttpInstance->Service->Ip6DriverBindingHandle,
790 HttpInstance->Handle
791 );
792
794 HttpInstance->Service->ControllerHandle,
795 HttpInstance->Service->Ip6DriverBindingHandle,
796 &gEfiTcp6ServiceBindingProtocolGuid,
797 HttpInstance->Tcp6ChildHandle
798 );
799 }
800
801 if (HttpInstance->Service->Tcp6ChildHandle != NULL) {
802 gBS->CloseProtocol (
803 HttpInstance->Service->Tcp6ChildHandle,
804 &gEfiTcp6ProtocolGuid,
805 HttpInstance->Service->Ip6DriverBindingHandle,
806 HttpInstance->Handle
807 );
808 }
809
810 return EFI_UNSUPPORTED;
811}
812
819VOID
821 IN HTTP_PROTOCOL *HttpInstance
822 )
823{
824 HttpCloseConnection (HttpInstance);
825
826 HttpCloseTcpConnCloseEvent (HttpInstance);
827
828 if (HttpInstance->TimeoutEvent != NULL) {
829 gBS->CloseEvent (HttpInstance->TimeoutEvent);
830 HttpInstance->TimeoutEvent = NULL;
831 }
832
833 if (HttpInstance->CacheBody != NULL) {
834 FreePool (HttpInstance->CacheBody);
835 HttpInstance->CacheBody = NULL;
836 HttpInstance->NextMsg = NULL;
837 }
838
839 if (HttpInstance->RemoteHost != NULL) {
840 FreePool (HttpInstance->RemoteHost);
841 HttpInstance->RemoteHost = NULL;
842 }
843
844 if (HttpInstance->MsgParser != NULL) {
845 HttpFreeMsgParser (HttpInstance->MsgParser);
846 HttpInstance->MsgParser = NULL;
847 }
848
849 if (HttpInstance->Url != NULL) {
850 FreePool (HttpInstance->Url);
851 HttpInstance->Url = NULL;
852 HttpInstance->UrlLen = 0;
853 }
854
855 NetMapClean (&HttpInstance->TxTokens);
856 NetMapClean (&HttpInstance->RxTokens);
857
858 if ((HttpInstance->TlsSb != NULL) && HttpInstance->TlsAlreadyCreated) {
859 //
860 // Destroy the TLS instance.
861 //
862 HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->Handle);
863 HttpInstance->TlsAlreadyCreated = FALSE;
864 }
865
866 if (HttpInstance->Tcp4ChildHandle != NULL) {
867 gBS->CloseProtocol (
868 HttpInstance->Tcp4ChildHandle,
869 &gEfiTcp4ProtocolGuid,
870 HttpInstance->Service->Ip4DriverBindingHandle,
871 HttpInstance->Service->ControllerHandle
872 );
873
874 gBS->CloseProtocol (
875 HttpInstance->Tcp4ChildHandle,
876 &gEfiTcp4ProtocolGuid,
877 HttpInstance->Service->Ip4DriverBindingHandle,
878 HttpInstance->Handle
879 );
880
882 HttpInstance->Service->ControllerHandle,
883 HttpInstance->Service->Ip4DriverBindingHandle,
884 &gEfiTcp4ServiceBindingProtocolGuid,
885 HttpInstance->Tcp4ChildHandle
886 );
887 }
888
889 if (HttpInstance->Service->Tcp4ChildHandle != NULL) {
890 gBS->CloseProtocol (
891 HttpInstance->Service->Tcp4ChildHandle,
892 &gEfiTcp4ProtocolGuid,
893 HttpInstance->Service->Ip4DriverBindingHandle,
894 HttpInstance->Handle
895 );
896 }
897
898 if (HttpInstance->Tcp6ChildHandle != NULL) {
899 gBS->CloseProtocol (
900 HttpInstance->Tcp6ChildHandle,
901 &gEfiTcp6ProtocolGuid,
902 HttpInstance->Service->Ip6DriverBindingHandle,
903 HttpInstance->Service->ControllerHandle
904 );
905
906 gBS->CloseProtocol (
907 HttpInstance->Tcp6ChildHandle,
908 &gEfiTcp6ProtocolGuid,
909 HttpInstance->Service->Ip6DriverBindingHandle,
910 HttpInstance->Handle
911 );
912
914 HttpInstance->Service->ControllerHandle,
915 HttpInstance->Service->Ip6DriverBindingHandle,
916 &gEfiTcp6ServiceBindingProtocolGuid,
917 HttpInstance->Tcp6ChildHandle
918 );
919 }
920
921 if (HttpInstance->Service->Tcp6ChildHandle != NULL) {
922 gBS->CloseProtocol (
923 HttpInstance->Service->Tcp6ChildHandle,
924 &gEfiTcp6ProtocolGuid,
925 HttpInstance->Service->Ip6DriverBindingHandle,
926 HttpInstance->Handle
927 );
928 }
929
930 TlsCloseTxRxEvent (HttpInstance);
931}
932
944 IN HTTP_PROTOCOL *HttpInstance
945 )
946{
947 EFI_STATUS Status;
948
949 //
950 // Connect to Http server
951 //
952 if (!HttpInstance->LocalAddressIsIPv6) {
953 HttpInstance->IsTcp4ConnDone = FALSE;
954 HttpInstance->Tcp4ConnToken.CompletionToken.Status = EFI_NOT_READY;
955 Status = HttpInstance->Tcp4->Connect (HttpInstance->Tcp4, &HttpInstance->Tcp4ConnToken);
957 if (EFI_ERROR (Status)) {
958 DEBUG ((DEBUG_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));
959 return Status;
960 }
961
962 while (!HttpInstance->IsTcp4ConnDone) {
963 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
964 }
965
966 Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;
967 } else {
968 HttpInstance->IsTcp6ConnDone = FALSE;
969 HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;
970 Status = HttpInstance->Tcp6->Connect (HttpInstance->Tcp6, &HttpInstance->Tcp6ConnToken);
972 if (EFI_ERROR (Status)) {
973 DEBUG ((DEBUG_ERROR, "HttpCreateConnection: Tcp6->Connect() = %r\n", Status));
974 return Status;
975 }
976
977 while (!HttpInstance->IsTcp6ConnDone) {
978 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
979 }
980
981 Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;
982 }
983
984 if (!EFI_ERROR (Status)) {
985 HttpInstance->State = HTTP_STATE_TCP_CONNECTED;
986 }
987
988 return Status;
989}
990
1002 IN HTTP_PROTOCOL *HttpInstance
1003 )
1004{
1005 EFI_STATUS Status;
1006
1007 if (HttpInstance->State == HTTP_STATE_TCP_CONNECTED) {
1008 if (HttpInstance->LocalAddressIsIPv6) {
1009 HttpInstance->Tcp6CloseToken.AbortOnClose = TRUE;
1010 HttpInstance->IsTcp6CloseDone = FALSE;
1011 Status = HttpInstance->Tcp6->Close (HttpInstance->Tcp6, &HttpInstance->Tcp6CloseToken);
1012 if (EFI_ERROR (Status)) {
1013 return Status;
1014 }
1015
1016 while (!HttpInstance->IsTcp6CloseDone) {
1017 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
1018 }
1019 } else {
1020 HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;
1021 HttpInstance->IsTcp4CloseDone = FALSE;
1022 Status = HttpInstance->Tcp4->Close (HttpInstance->Tcp4, &HttpInstance->Tcp4CloseToken);
1023 if (EFI_ERROR (Status)) {
1024 return Status;
1025 }
1026
1027 while (!HttpInstance->IsTcp4CloseDone) {
1028 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
1029 }
1030 }
1031 }
1032
1033 HttpInstance->State = HTTP_STATE_TCP_CLOSED;
1034 return EFI_SUCCESS;
1035}
1036
1049 IN HTTP_PROTOCOL *HttpInstance,
1050 IN HTTP_TOKEN_WRAP *Wrap
1051 )
1052{
1053 EFI_STATUS Status;
1054 EFI_TCP4_CONFIG_DATA *Tcp4CfgData;
1055 EFI_TCP4_ACCESS_POINT *Tcp4AP;
1056 EFI_TCP4_OPTION *Tcp4Option;
1057
1058 ASSERT (HttpInstance != NULL);
1059
1060 Tcp4CfgData = &HttpInstance->Tcp4CfgData;
1061 ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));
1062
1063 Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT;
1064 Tcp4CfgData->TimeToLive = HTTP_TTL_DEAULT;
1065 Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option;
1066
1067 Tcp4AP = &Tcp4CfgData->AccessPoint;
1068 Tcp4AP->UseDefaultAddress = HttpInstance->IPv4Node.UseDefaultAddress;
1069 if (!Tcp4AP->UseDefaultAddress) {
1070 IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress);
1071 IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);
1072 }
1073
1074 Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort;
1075 Tcp4AP->RemotePort = HttpInstance->RemotePort;
1076 Tcp4AP->ActiveFlag = TRUE;
1077 IP4_COPY_ADDRESS (&Tcp4AP->RemoteAddress, &HttpInstance->RemoteAddr);
1078
1079 Tcp4Option = Tcp4CfgData->ControlOption;
1080 Tcp4Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;
1081 Tcp4Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT;
1082 Tcp4Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG;
1083 Tcp4Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;
1084 Tcp4Option->DataRetries = HTTP_DATA_RETRIES;
1085 Tcp4Option->FinTimeout = HTTP_FIN_TIMEOUT;
1086 Tcp4Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES;
1087 Tcp4Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME;
1088 Tcp4Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;
1089 Tcp4Option->EnableNagle = TRUE;
1090 Tcp4Option->EnableWindowScaling = TRUE;
1091 Tcp4CfgData->ControlOption = Tcp4Option;
1092
1093 if ((HttpInstance->State == HTTP_STATE_TCP_CONNECTED) ||
1094 (HttpInstance->State == HTTP_STATE_TCP_CLOSED))
1095 {
1096 Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, NULL);
1097 if (EFI_ERROR (Status)) {
1098 DEBUG ((DEBUG_ERROR, "HttpConfigureTcp4(NULL) - %r\n", Status));
1099 return Status;
1100 }
1101
1102 HttpInstance->State = HTTP_STATE_TCP_UNCONFIGED;
1103 }
1104
1105 Status = HttpInstance->Tcp4->Configure (HttpInstance->Tcp4, Tcp4CfgData);
1106 if (EFI_ERROR (Status)) {
1107 DEBUG ((DEBUG_ERROR, "HttpConfigureTcp4 - %r\n", Status));
1108 return Status;
1109 }
1110
1111 Status = HttpCreateTcpConnCloseEvent (HttpInstance);
1112 if (EFI_ERROR (Status)) {
1113 return Status;
1114 }
1115
1116 Status = HttpCreateTcpTxEvent (Wrap);
1117 if (EFI_ERROR (Status)) {
1118 return Status;
1119 }
1120
1121 HttpInstance->State = HTTP_STATE_TCP_CONFIGED;
1122
1123 return EFI_SUCCESS;
1124}
1125
1138 IN HTTP_PROTOCOL *HttpInstance,
1139 IN HTTP_TOKEN_WRAP *Wrap
1140 )
1141{
1142 EFI_STATUS Status;
1143 EFI_TCP6_CONFIG_DATA *Tcp6CfgData;
1144 EFI_TCP6_ACCESS_POINT *Tcp6Ap;
1145 EFI_TCP6_OPTION *Tcp6Option;
1146
1147 ASSERT (HttpInstance != NULL);
1148
1149 Tcp6CfgData = &HttpInstance->Tcp6CfgData;
1150 ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA));
1151
1152 Tcp6CfgData->TrafficClass = 0;
1153 Tcp6CfgData->HopLimit = 255;
1154 Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option;
1155
1156 Tcp6Ap = &Tcp6CfgData->AccessPoint;
1157 Tcp6Ap->ActiveFlag = TRUE;
1158 Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;
1159 Tcp6Ap->RemotePort = HttpInstance->RemotePort;
1160 IP6_COPY_ADDRESS (&Tcp6Ap->StationAddress, &HttpInstance->Ipv6Node.LocalAddress);
1161 IP6_COPY_ADDRESS (&Tcp6Ap->RemoteAddress, &HttpInstance->RemoteIpv6Addr);
1162
1163 Tcp6Option = Tcp6CfgData->ControlOption;
1164 Tcp6Option->ReceiveBufferSize = HTTP_BUFFER_SIZE_DEAULT;
1165 Tcp6Option->SendBufferSize = HTTP_BUFFER_SIZE_DEAULT;
1166 Tcp6Option->MaxSynBackLog = HTTP_MAX_SYN_BACK_LOG;
1167 Tcp6Option->ConnectionTimeout = HTTP_CONNECTION_TIMEOUT;
1168 Tcp6Option->DataRetries = HTTP_DATA_RETRIES;
1169 Tcp6Option->FinTimeout = HTTP_FIN_TIMEOUT;
1170 Tcp6Option->KeepAliveProbes = HTTP_KEEP_ALIVE_PROBES;
1171 Tcp6Option->KeepAliveTime = HTTP_KEEP_ALIVE_TIME;
1172 Tcp6Option->KeepAliveInterval = HTTP_KEEP_ALIVE_INTERVAL;
1173 Tcp6Option->EnableNagle = TRUE;
1174 Tcp6Option->EnableWindowScaling = TRUE;
1175
1176 if ((HttpInstance->State == HTTP_STATE_TCP_CONNECTED) ||
1177 (HttpInstance->State == HTTP_STATE_TCP_CLOSED))
1178 {
1179 Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, NULL);
1180 if (EFI_ERROR (Status)) {
1181 DEBUG ((DEBUG_ERROR, "HttpConfigureTcp6(NULL) - %r\n", Status));
1182 return Status;
1183 }
1184
1185 HttpInstance->State = HTTP_STATE_TCP_UNCONFIGED;
1186 }
1187
1188 Status = HttpInstance->Tcp6->Configure (HttpInstance->Tcp6, Tcp6CfgData);
1189 if (EFI_ERROR (Status)) {
1190 DEBUG ((DEBUG_ERROR, "HttpConfigureTcp6 - %r\n", Status));
1191 return Status;
1192 }
1193
1194 Status = HttpCreateTcpConnCloseEvent (HttpInstance);
1195 if (EFI_ERROR (Status)) {
1196 return Status;
1197 }
1198
1199 Status = HttpCreateTcpTxEvent (Wrap);
1200 if (EFI_ERROR (Status)) {
1201 return Status;
1202 }
1203
1204 HttpInstance->State = HTTP_STATE_TCP_CONFIGED;
1205
1206 return EFI_SUCCESS;
1207}
1208
1222 IN HTTP_PROTOCOL *HttpInstance
1223 )
1224{
1225 EFI_STATUS Status;
1226 EFI_TCP4_CONNECTION_STATE Tcp4State;
1227
1228 if ((HttpInstance->State < HTTP_STATE_TCP_CONFIGED) || (HttpInstance->Tcp4 == NULL)) {
1229 return EFI_NOT_READY;
1230 }
1231
1232 Status = HttpInstance->Tcp4->GetModeData (
1233 HttpInstance->Tcp4,
1234 &Tcp4State,
1235 NULL,
1236 NULL,
1237 NULL,
1238 NULL
1239 );
1240 if (EFI_ERROR (Status)) {
1241 DEBUG ((DEBUG_ERROR, "Tcp4 GetModeData fail - %x\n", Status));
1242 return Status;
1243 }
1244
1245 if (Tcp4State == Tcp4StateEstablished) {
1246 return EFI_SUCCESS;
1247 } else if (Tcp4State > Tcp4StateEstablished ) {
1248 HttpCloseConnection (HttpInstance);
1249 }
1250
1251 Status = HttpCreateConnection (HttpInstance);
1252 if (EFI_ERROR (Status)) {
1253 DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status));
1254 return Status;
1255 }
1256
1257 //
1258 // Tls session connection.
1259 //
1260 if (HttpInstance->UseHttps) {
1261 if (HttpInstance->TimeoutEvent == NULL) {
1262 //
1263 // Create TimeoutEvent for TLS connection.
1264 //
1265 Status = gBS->CreateEvent (
1266 EVT_TIMER,
1267 TPL_CALLBACK,
1268 NULL,
1269 NULL,
1270 &HttpInstance->TimeoutEvent
1271 );
1272 if (EFI_ERROR (Status)) {
1273 TlsCloseTxRxEvent (HttpInstance);
1274 return Status;
1275 }
1276 }
1277
1278 //
1279 // Start the timer, and wait Timeout seconds for connection.
1280 //
1281 Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
1282 if (EFI_ERROR (Status)) {
1283 TlsCloseTxRxEvent (HttpInstance);
1284 return Status;
1285 }
1286
1287 Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
1289
1290 gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
1291
1292 if (EFI_ERROR (Status)) {
1293 TlsCloseTxRxEvent (HttpInstance);
1294 return Status;
1295 }
1296 }
1297
1298 return Status;
1299}
1300
1314 IN HTTP_PROTOCOL *HttpInstance
1315 )
1316{
1317 EFI_STATUS Status;
1318 EFI_TCP6_CONNECTION_STATE Tcp6State;
1319
1320 if ((HttpInstance->State < HTTP_STATE_TCP_CONFIGED) || (HttpInstance->Tcp6 == NULL)) {
1321 return EFI_NOT_READY;
1322 }
1323
1324 Status = HttpInstance->Tcp6->GetModeData (
1325 HttpInstance->Tcp6,
1326 &Tcp6State,
1327 NULL,
1328 NULL,
1329 NULL,
1330 NULL
1331 );
1332
1333 if (EFI_ERROR (Status)) {
1334 DEBUG ((DEBUG_ERROR, "Tcp6 GetModeData fail - %x\n", Status));
1335 return Status;
1336 }
1337
1338 if (Tcp6State == Tcp6StateEstablished) {
1339 return EFI_SUCCESS;
1340 } else if (Tcp6State > Tcp6StateEstablished ) {
1341 HttpCloseConnection (HttpInstance);
1342 }
1343
1344 Status = HttpCreateConnection (HttpInstance);
1345 if (EFI_ERROR (Status)) {
1346 DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status));
1347 return Status;
1348 }
1349
1350 //
1351 // Tls session connection.
1352 //
1353 if (HttpInstance->UseHttps) {
1354 if (HttpInstance->TimeoutEvent == NULL) {
1355 //
1356 // Create TimeoutEvent for TLS connection.
1357 //
1358 Status = gBS->CreateEvent (
1359 EVT_TIMER,
1360 TPL_CALLBACK,
1361 NULL,
1362 NULL,
1363 &HttpInstance->TimeoutEvent
1364 );
1365 if (EFI_ERROR (Status)) {
1366 TlsCloseTxRxEvent (HttpInstance);
1367 return Status;
1368 }
1369 }
1370
1371 //
1372 // Start the timer, and wait Timeout seconds for connection.
1373 //
1374 Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
1375 if (EFI_ERROR (Status)) {
1376 TlsCloseTxRxEvent (HttpInstance);
1377 return Status;
1378 }
1379
1380 Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
1382
1383 gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
1384
1385 if (EFI_ERROR (Status)) {
1386 TlsCloseTxRxEvent (HttpInstance);
1387 return Status;
1388 }
1389 }
1390
1391 return Status;
1392}
1393
1408 IN HTTP_PROTOCOL *HttpInstance,
1409 IN HTTP_TOKEN_WRAP *Wrap,
1410 IN BOOLEAN Configure,
1411 IN BOOLEAN TlsConfigure
1412 )
1413{
1414 EFI_STATUS Status;
1415
1416 ASSERT (HttpInstance != NULL);
1417
1418 //
1419 // Configure Tls session.
1420 //
1421 if (TlsConfigure) {
1422 Status = TlsConfigureSession (HttpInstance);
1424 if (EFI_ERROR (Status)) {
1425 return Status;
1426 }
1427 }
1428
1429 if (!HttpInstance->LocalAddressIsIPv6) {
1430 //
1431 // Configure TCP instance.
1432 //
1433 if (Configure) {
1434 Status = HttpConfigureTcp4 (HttpInstance, Wrap);
1435 if (EFI_ERROR (Status)) {
1436 return Status;
1437 }
1438 }
1439
1440 //
1441 // Connect TCP.
1442 //
1443 Status = HttpConnectTcp4 (HttpInstance);
1444 if (EFI_ERROR (Status)) {
1445 return Status;
1446 }
1447 } else {
1448 //
1449 // Configure TCP instance.
1450 //
1451 if (Configure) {
1452 Status = HttpConfigureTcp6 (HttpInstance, Wrap);
1453 if (EFI_ERROR (Status)) {
1454 return Status;
1455 }
1456 }
1457
1458 //
1459 // Connect TCP.
1460 //
1461 Status = HttpConnectTcp6 (HttpInstance);
1462 if (EFI_ERROR (Status)) {
1463 return Status;
1464 }
1465 }
1466
1467 return EFI_SUCCESS;
1468}
1469
1484 IN HTTP_PROTOCOL *HttpInstance,
1485 IN HTTP_TOKEN_WRAP *Wrap,
1486 IN UINT8 *TxString,
1487 IN UINTN TxStringLen
1488 )
1489{
1490 EFI_STATUS Status;
1491 EFI_TCP4_IO_TOKEN *Tx4Token;
1492 EFI_TCP4_PROTOCOL *Tcp4;
1493 EFI_TCP6_IO_TOKEN *Tx6Token;
1494 EFI_TCP6_PROTOCOL *Tcp6;
1495 UINT8 *TlsRecord;
1496 UINT16 PayloadSize;
1497 NET_FRAGMENT TempFragment;
1498 NET_FRAGMENT Fragment;
1499 UINTN RecordCount;
1500 UINTN RemainingLen;
1501
1502 Status = EFI_SUCCESS;
1503 TlsRecord = NULL;
1504 PayloadSize = 0;
1505 TempFragment.Len = 0;
1506 TempFragment.Bulk = NULL;
1507 Fragment.Len = 0;
1508 Fragment.Bulk = NULL;
1509 RecordCount = 0;
1510 RemainingLen = 0;
1511
1512 //
1513 // Need to encrypt data.
1514 //
1515 if (HttpInstance->UseHttps) {
1516 //
1517 // Allocate enough buffer for each TLS plaintext records.
1518 //
1519 TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);
1520 if (TlsRecord == NULL) {
1521 Status = EFI_OUT_OF_RESOURCES;
1522 return Status;
1523 }
1524
1525 //
1526 // Allocate enough buffer for all TLS ciphertext records.
1527 //
1528 RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1;
1529 Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));
1530 if (Fragment.Bulk == NULL) {
1531 Status = EFI_OUT_OF_RESOURCES;
1532 goto ON_ERROR;
1533 }
1534
1535 //
1536 // Encrypt each TLS plaintext records.
1537 //
1538 RemainingLen = TxStringLen;
1539 while (RemainingLen != 0) {
1540 PayloadSize = (UINT16)MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen);
1541
1542 ((TLS_RECORD_HEADER *)TlsRecord)->ContentType = TlsContentTypeApplicationData;
1543 ((TLS_RECORD_HEADER *)TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
1544 ((TLS_RECORD_HEADER *)TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
1545 ((TLS_RECORD_HEADER *)TlsRecord)->Length = PayloadSize;
1546
1547 CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize);
1548
1549 Status = TlsProcessMessage (
1550 HttpInstance,
1551 TlsRecord,
1552 TLS_RECORD_HEADER_LENGTH + PayloadSize,
1554 &TempFragment
1555 );
1556 if (EFI_ERROR (Status)) {
1557 goto ON_ERROR;
1558 }
1559
1560 //
1561 // Record the processed/encrypted Packet.
1562 //
1563 CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len);
1564 Fragment.Len += TempFragment.Len;
1565
1566 FreePool (TempFragment.Bulk);
1567 TempFragment.Len = 0;
1568 TempFragment.Bulk = NULL;
1569
1570 RemainingLen -= (UINTN)PayloadSize;
1571 ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);
1572 }
1573
1574 FreePool (TlsRecord);
1575 TlsRecord = NULL;
1576 }
1577
1578 if (!HttpInstance->LocalAddressIsIPv6) {
1579 Tcp4 = HttpInstance->Tcp4;
1580 Tx4Token = &Wrap->TcpWrap.Tx4Token;
1581
1582 if (HttpInstance->UseHttps) {
1583 Tx4Token->Packet.TxData->DataLength = Fragment.Len;
1584 Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;
1585 Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)Fragment.Bulk;
1586 } else {
1587 Tx4Token->Packet.TxData->DataLength = (UINT32)TxStringLen;
1588 Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)TxStringLen;
1589 Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)TxString;
1590 }
1591
1592 Tx4Token->CompletionToken.Status = EFI_NOT_READY;
1593
1594 Wrap->TcpWrap.IsTxDone = FALSE;
1595 Status = Tcp4->Transmit (Tcp4, Tx4Token);
1596 if (EFI_ERROR (Status)) {
1597 DEBUG ((DEBUG_ERROR, "Transmit failed: %r\n", Status));
1598 goto ON_ERROR;
1599 }
1600 } else {
1601 Tcp6 = HttpInstance->Tcp6;
1602 Tx6Token = &Wrap->TcpWrap.Tx6Token;
1603
1604 if (HttpInstance->UseHttps) {
1605 Tx6Token->Packet.TxData->DataLength = Fragment.Len;
1606 Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;
1607 Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)Fragment.Bulk;
1608 } else {
1609 Tx6Token->Packet.TxData->DataLength = (UINT32)TxStringLen;
1610 Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)TxStringLen;
1611 Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)TxString;
1612 }
1613
1614 Tx6Token->CompletionToken.Status = EFI_NOT_READY;
1615
1616 Wrap->TcpWrap.IsTxDone = FALSE;
1617 Status = Tcp6->Transmit (Tcp6, Tx6Token);
1618 if (EFI_ERROR (Status)) {
1619 DEBUG ((DEBUG_ERROR, "Transmit failed: %r\n", Status));
1620 goto ON_ERROR;
1621 }
1622 }
1623
1624 return Status;
1625
1626ON_ERROR:
1627
1628 if (HttpInstance->UseHttps) {
1629 if (TlsRecord != NULL) {
1630 FreePool (TlsRecord);
1631 TlsRecord = NULL;
1632 }
1633
1634 if (Fragment.Bulk != NULL) {
1635 FreePool (Fragment.Bulk);
1636 Fragment.Bulk = NULL;
1637 }
1638 }
1639
1640 return Status;
1641}
1642
1658EFIAPI
1660 IN NET_MAP *Map,
1661 IN NET_MAP_ITEM *Item,
1662 IN VOID *Context
1663 )
1664{
1665 EFI_HTTP_TOKEN *Token;
1666 EFI_HTTP_TOKEN *TokenInItem;
1667
1668 Token = (EFI_HTTP_TOKEN *)Context;
1669 TokenInItem = (EFI_HTTP_TOKEN *)Item->Key;
1670
1671 if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
1672 return EFI_ACCESS_DENIED;
1673 }
1674
1675 return EFI_SUCCESS;
1676}
1677
1690EFIAPI
1692 IN NET_MAP *Map,
1693 IN NET_MAP_ITEM *Item,
1694 IN VOID *Context
1695 )
1696{
1697 HTTP_TOKEN_WRAP *ValueInItem;
1698
1699 ValueInItem = (HTTP_TOKEN_WRAP *)Item->Value;
1700
1701 if (!ValueInItem->TcpWrap.IsTxDone) {
1702 return EFI_NOT_READY;
1703 }
1704
1705 return EFI_SUCCESS;
1706}
1707
1721EFIAPI
1723 IN NET_MAP *Map,
1724 IN NET_MAP_ITEM *Item,
1725 IN VOID *Context
1726 )
1727{
1728 HTTP_TOKEN_WRAP *ValueInItem;
1729 EFI_STATUS Status;
1730 CHAR8 *RequestMsg;
1731 CHAR8 *Url;
1732 UINTN UrlSize;
1733 UINTN RequestMsgSize;
1734
1735 RequestMsg = NULL;
1736
1737 ValueInItem = (HTTP_TOKEN_WRAP *)Item->Value;
1738 if (ValueInItem->TcpWrap.IsTxDone) {
1739 return EFI_SUCCESS;
1740 }
1741
1742 //
1743 // Parse the URI of the remote host.
1744 //
1745 UrlSize = StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1;
1746 Url = AllocatePool (UrlSize);
1747 if (Url == NULL) {
1748 return EFI_OUT_OF_RESOURCES;
1749 }
1750
1751 UnicodeStrToAsciiStrS (ValueInItem->HttpToken->Message->Data.Request->Url, Url, UrlSize);
1752
1753 //
1754 // Create request message.
1755 //
1756 Status = HttpGenRequestMessage (
1757 ValueInItem->HttpToken->Message,
1758 Url,
1759 &RequestMsg,
1760 &RequestMsgSize
1761 );
1762 FreePool (Url);
1763
1764 if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
1765 return Status;
1766 }
1767
1768 ASSERT (RequestMsg != NULL);
1769
1770 //
1771 // Transmit the request message.
1772 //
1773 Status = HttpTransmitTcp (
1774 ValueInItem->HttpInstance,
1775 ValueInItem,
1776 (UINT8 *)RequestMsg,
1777 RequestMsgSize
1778 );
1779 FreePool (RequestMsg);
1780 return Status;
1781}
1782
1796EFIAPI
1798 IN NET_MAP *Map,
1799 IN NET_MAP_ITEM *Item,
1800 IN VOID *Context
1801 )
1802{
1803 //
1804 // Process the queued HTTP response.
1805 //
1806 return HttpResponseWorker ((HTTP_TOKEN_WRAP *)Item->Value);
1807}
1808
1823 IN HTTP_PROTOCOL *HttpInstance,
1824 IN OUT UINTN *SizeofHeaders,
1825 IN OUT UINTN *BufferSize,
1826 IN EFI_EVENT Timeout
1827 )
1828{
1829 EFI_STATUS Status;
1830 EFI_TCP4_IO_TOKEN *Rx4Token;
1831 EFI_TCP4_PROTOCOL *Tcp4;
1832 EFI_TCP6_IO_TOKEN *Rx6Token;
1833 EFI_TCP6_PROTOCOL *Tcp6;
1834 CHAR8 **EndofHeader;
1835 CHAR8 **HttpHeaders;
1836 CHAR8 *Buffer;
1837 NET_FRAGMENT Fragment;
1838
1839 ASSERT (HttpInstance != NULL);
1840
1841 EndofHeader = HttpInstance->EndofHeader;
1842 HttpHeaders = HttpInstance->HttpHeaders;
1843 Tcp4 = HttpInstance->Tcp4;
1844 Tcp6 = HttpInstance->Tcp6;
1845 Buffer = NULL;
1846 Rx4Token = NULL;
1847 Rx6Token = NULL;
1848 Fragment.Len = 0;
1849 Fragment.Bulk = NULL;
1850
1851 if (HttpInstance->LocalAddressIsIPv6) {
1852 ASSERT (Tcp6 != NULL);
1853 } else {
1854 ASSERT (Tcp4 != NULL);
1855 }
1856
1857 if (!HttpInstance->UseHttps) {
1858 Status = HttpCreateTcpRxEventForHeader (HttpInstance);
1859 if (EFI_ERROR (Status)) {
1860 return Status;
1861 }
1862 }
1863
1864 if (!HttpInstance->LocalAddressIsIPv6) {
1865 if (!HttpInstance->UseHttps) {
1866 Rx4Token = &HttpInstance->Rx4Token;
1867 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
1868 if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
1869 Status = EFI_OUT_OF_RESOURCES;
1870 return Status;
1871 }
1872 }
1873
1874 //
1875 // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
1876 //
1877 while (*EndofHeader == NULL) {
1878 if (!HttpInstance->UseHttps) {
1879 HttpInstance->IsRxDone = FALSE;
1880 Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
1881 Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
1882 Status = Tcp4->Receive (Tcp4, Rx4Token);
1883 if (EFI_ERROR (Status)) {
1884 DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
1885 return Status;
1886 }
1887
1888 while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
1889 Tcp4->Poll (Tcp4);
1890 }
1891
1892 if (!HttpInstance->IsRxDone) {
1893 //
1894 // Cancel the Token before close its Event.
1895 //
1896 Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
1897 gBS->CloseEvent (Rx4Token->CompletionToken.Event);
1898 Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
1899 }
1900
1901 Status = Rx4Token->CompletionToken.Status;
1902 if (EFI_ERROR (Status)) {
1903 return Status;
1904 }
1905
1906 Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
1907 Fragment.Bulk = (UINT8 *)Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
1908 } else {
1909 if (Fragment.Bulk != NULL) {
1910 FreePool (Fragment.Bulk);
1911 Fragment.Bulk = NULL;
1912 }
1913
1914 Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
1915 if (EFI_ERROR (Status)) {
1916 DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
1917 return Status;
1918 }
1919 }
1920
1921 //
1922 // Append the response string along with a Null-terminator.
1923 //
1924 *BufferSize = *SizeofHeaders + Fragment.Len;
1925 Buffer = AllocatePool (*BufferSize + 1);
1926 if (Buffer == NULL) {
1927 Status = EFI_OUT_OF_RESOURCES;
1928 return Status;
1929 }
1930
1931 if (*HttpHeaders != NULL) {
1932 CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
1933 FreePool (*HttpHeaders);
1934 }
1935
1936 CopyMem (
1937 Buffer + *SizeofHeaders,
1938 Fragment.Bulk,
1939 Fragment.Len
1940 );
1941 *(Buffer + *BufferSize) = '\0';
1942 *HttpHeaders = Buffer;
1943 *SizeofHeaders = *BufferSize;
1944
1945 //
1946 // Check whether we received end of HTTP headers.
1947 //
1948 *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
1949 }
1950
1951 //
1952 // Free the buffer.
1953 //
1954 if ((Rx4Token != NULL) && (Rx4Token->Packet.RxData != NULL) && (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL)) {
1955 FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
1956 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
1957 Fragment.Bulk = NULL;
1958 }
1959
1960 if (Fragment.Bulk != NULL) {
1961 FreePool (Fragment.Bulk);
1962 Fragment.Bulk = NULL;
1963 }
1964 } else {
1965 if (!HttpInstance->UseHttps) {
1966 Rx6Token = &HttpInstance->Rx6Token;
1967 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
1968 if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
1969 Status = EFI_OUT_OF_RESOURCES;
1970 return Status;
1971 }
1972 }
1973
1974 //
1975 // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
1976 //
1977 while (*EndofHeader == NULL) {
1978 if (!HttpInstance->UseHttps) {
1979 HttpInstance->IsRxDone = FALSE;
1980 Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
1981 Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
1982 Status = Tcp6->Receive (Tcp6, Rx6Token);
1983 if (EFI_ERROR (Status)) {
1984 DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
1985 return Status;
1986 }
1987
1988 while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
1989 Tcp6->Poll (Tcp6);
1990 }
1991
1992 if (!HttpInstance->IsRxDone) {
1993 //
1994 // Cancel the Token before close its Event.
1995 //
1996 Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
1997 gBS->CloseEvent (Rx6Token->CompletionToken.Event);
1998 Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
1999 }
2000
2001 Status = Rx6Token->CompletionToken.Status;
2002 if (EFI_ERROR (Status)) {
2003 return Status;
2004 }
2005
2006 Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
2007 Fragment.Bulk = (UINT8 *)Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
2008 } else {
2009 if (Fragment.Bulk != NULL) {
2010 FreePool (Fragment.Bulk);
2011 Fragment.Bulk = NULL;
2012 }
2013
2014 Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
2015 if (EFI_ERROR (Status)) {
2016 DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
2017 return Status;
2018 }
2019 }
2020
2021 //
2022 // Append the response string along with a Null-terminator.
2023 //
2024 *BufferSize = *SizeofHeaders + Fragment.Len;
2025 Buffer = AllocatePool (*BufferSize + 1);
2026 if (Buffer == NULL) {
2027 Status = EFI_OUT_OF_RESOURCES;
2028 return Status;
2029 }
2030
2031 if (*HttpHeaders != NULL) {
2032 CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
2033 FreePool (*HttpHeaders);
2034 }
2035
2036 CopyMem (
2037 Buffer + *SizeofHeaders,
2038 Fragment.Bulk,
2039 Fragment.Len
2040 );
2041 *(Buffer + *BufferSize) = '\0';
2042 *HttpHeaders = Buffer;
2043 *SizeofHeaders = *BufferSize;
2044
2045 //
2046 // Check whether we received end of HTTP headers.
2047 //
2048 *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
2049 }
2050
2051 //
2052 // Free the buffer.
2053 //
2054 if ((Rx6Token != NULL) && (Rx6Token->Packet.RxData != NULL) && (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL)) {
2055 FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
2056 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
2057 Fragment.Bulk = NULL;
2058 }
2059
2060 if (Fragment.Bulk != NULL) {
2061 FreePool (Fragment.Bulk);
2062 Fragment.Bulk = NULL;
2063 }
2064 }
2065
2066 //
2067 // Skip the CRLF after the HTTP headers.
2068 //
2069 *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);
2070
2071 *SizeofHeaders = *EndofHeader - *HttpHeaders;
2072
2073 return EFI_SUCCESS;
2074}
2075
2088 IN HTTP_TOKEN_WRAP *Wrap,
2089 IN EFI_HTTP_MESSAGE *HttpMsg
2090 )
2091{
2092 EFI_STATUS Status;
2093 HTTP_PROTOCOL *HttpInstance;
2094 EFI_TCP6_PROTOCOL *Tcp6;
2095 EFI_TCP6_IO_TOKEN *Rx6Token;
2096 EFI_TCP4_PROTOCOL *Tcp4;
2097 EFI_TCP4_IO_TOKEN *Rx4Token;
2098
2099 HttpInstance = Wrap->HttpInstance;
2100 Tcp4 = HttpInstance->Tcp4;
2101 Tcp6 = HttpInstance->Tcp6;
2102 Rx4Token = NULL;
2103 Rx6Token = NULL;
2104
2105 if (HttpInstance->LocalAddressIsIPv6) {
2106 ASSERT (Tcp6 != NULL);
2107 } else {
2108 ASSERT (Tcp4 != NULL);
2109 }
2110
2111 if (HttpInstance->LocalAddressIsIPv6) {
2112 Rx6Token = &Wrap->TcpWrap.Rx6Token;
2113 Rx6Token->Packet.RxData->DataLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
2114 Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
2115 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *)HttpMsg->Body;
2116 Rx6Token->CompletionToken.Status = EFI_NOT_READY;
2117
2118 Status = Tcp6->Receive (Tcp6, Rx6Token);
2119 if (EFI_ERROR (Status)) {
2120 DEBUG ((DEBUG_ERROR, "Tcp6 receive failed: %r\n", Status));
2121 return Status;
2122 }
2123 } else {
2124 Rx4Token = &Wrap->TcpWrap.Rx4Token;
2125 Rx4Token->Packet.RxData->DataLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
2126 Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32)MIN (MAX_UINT32, HttpMsg->BodyLength);
2127 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *)HttpMsg->Body;
2128
2129 Rx4Token->CompletionToken.Status = EFI_NOT_READY;
2130 Status = Tcp4->Receive (Tcp4, Rx4Token);
2131 if (EFI_ERROR (Status)) {
2132 DEBUG ((DEBUG_ERROR, "Tcp4 receive failed: %r\n", Status));
2133 return Status;
2134 }
2135 }
2136
2137 return EFI_SUCCESS;
2138}
2139
2146VOID
2148 IN HTTP_TOKEN_WRAP *Wrap
2149 )
2150{
2151 HTTP_PROTOCOL *HttpInstance;
2152 EFI_TCP4_IO_TOKEN *Rx4Token;
2153 EFI_TCP6_IO_TOKEN *Rx6Token;
2154
2155 ASSERT (Wrap != NULL);
2156 HttpInstance = Wrap->HttpInstance;
2157 Rx4Token = NULL;
2158 Rx6Token = NULL;
2159
2160 if (HttpInstance->LocalAddressIsIPv6) {
2161 Rx6Token = &Wrap->TcpWrap.Rx6Token;
2162
2163 if (Rx6Token->CompletionToken.Event != NULL) {
2164 gBS->CloseEvent (Rx6Token->CompletionToken.Event);
2165 Rx6Token->CompletionToken.Event = NULL;
2166 }
2167
2168 FreePool (Wrap);
2169
2170 Rx6Token = &HttpInstance->Rx6Token;
2171
2172 if (Rx6Token->CompletionToken.Event != NULL) {
2173 gBS->CloseEvent (Rx6Token->CompletionToken.Event);
2174 Rx6Token->CompletionToken.Event = NULL;
2175 }
2176
2177 if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
2178 FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
2179 Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
2180 }
2181 } else {
2182 Rx4Token = &Wrap->TcpWrap.Rx4Token;
2183
2184 if (Rx4Token->CompletionToken.Event != NULL) {
2185 gBS->CloseEvent (Rx4Token->CompletionToken.Event);
2186 Rx4Token->CompletionToken.Event = NULL;
2187 }
2188
2189 FreePool (Wrap);
2190
2191 Rx4Token = &HttpInstance->Rx4Token;
2192
2193 if (Rx4Token->CompletionToken.Event != NULL) {
2194 gBS->CloseEvent (Rx4Token->CompletionToken.Event);
2195 Rx4Token->CompletionToken.Event = NULL;
2196 }
2197
2198 if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
2199 FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
2200 Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
2201 }
2202 }
2203}
2204
2212VOID
2215 IN EFI_STATUS EventStatus
2216 )
2217{
2218 EFI_STATUS Status;
2219 EFI_HANDLE *Handles;
2220 UINTN Index;
2221 UINTN HandleCount;
2222 EFI_HANDLE Handle;
2223 EDKII_HTTP_CALLBACK_PROTOCOL *HttpCallback;
2224
2225 DEBUG ((DEBUG_INFO, "HttpNotify: Event - %d, EventStatus - %r\n", Event, EventStatus));
2226
2227 Handles = NULL;
2228 HandleCount = 0;
2229 Status = gBS->LocateHandleBuffer (
2230 ByProtocol,
2231 &gEdkiiHttpCallbackProtocolGuid,
2232 NULL,
2233 &HandleCount,
2234 &Handles
2235 );
2236 if (Status == EFI_SUCCESS) {
2237 for (Index = 0; Index < HandleCount; Index++) {
2238 Handle = Handles[Index];
2239 Status = gBS->HandleProtocol (
2240 Handle,
2241 &gEdkiiHttpCallbackProtocolGuid,
2242 (VOID **)&HttpCallback
2243 );
2244 if (Status == EFI_SUCCESS) {
2245 DEBUG ((DEBUG_INFO, "HttpNotify: Notifying %p\n", HttpCallback));
2246 HttpCallback->Callback (
2247 HttpCallback,
2248 Event,
2249 EventStatus
2250 );
2251 }
2252 }
2253
2254 FreePool (Handles);
2255 }
2256}
UINT64 UINTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2650
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR8 *EFIAPI AsciiStrStr(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString)
Definition: String.c:931
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI QueueDpc(IN EFI_TPL DpcTpl, IN EFI_DPC_PROCEDURE DpcProcedure, IN VOID *DpcContext OPTIONAL)
Definition: DpcLib.c:62
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EDKII_HTTP_CALLBACK_EVENT
Definition: HttpCallback.h:22
@ HttpEventTlsConfigured
Definition: HttpCallback.h:70
@ HttpEventTlsConnectSession
Definition: HttpCallback.h:51
@ HttpEventConnectTcp
Definition: HttpCallback.h:41
EFI_STATUS HttpResponseWorker(IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpImpl.c:966
EFI_STATUS EFIAPI HttpGenRequestMessage(IN CONST EFI_HTTP_MESSAGE *Message, IN CONST CHAR8 *Url, OUT CHAR8 **RequestMsg, OUT UINTN *RequestMsgSize)
Definition: DxeHttpLib.c:1775
EFI_STATUS EFIAPI HttpParseMessageBody(IN OUT VOID *MsgParser, IN UINTN BodyLength, IN CHAR8 *Body)
Definition: DxeHttpLib.c:1131
VOID EFIAPI HttpFreeMsgParser(IN VOID *MsgParser)
Definition: DxeHttpLib.c:1474
BOOLEAN EFIAPI HttpIsMessageComplete(IN VOID *MsgParser)
Definition: DxeHttpLib.c:1411
VOID HttpTcpTokenCleanup(IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:2147
EFI_STATUS HttpConfigureTcp4(IN HTTP_PROTOCOL *HttpInstance, IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:1048
EFI_STATUS HttpCreateTcpRxEvent(IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:524
EFI_STATUS HttpInitSession(IN HTTP_PROTOCOL *HttpInstance, IN HTTP_TOKEN_WRAP *Wrap, IN BOOLEAN Configure, IN BOOLEAN TlsConfigure)
Definition: HttpProto.c:1407
EFI_STATUS HttpCreateTcpConnCloseEvent(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:292
EFI_STATUS EFIAPI HttpTokenExist(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: HttpProto.c:1659
EFI_STATUS HttpInitProtocol(IN OUT HTTP_PROTOCOL *HttpInstance, IN BOOLEAN IpVersion)
Definition: HttpProto.c:617
VOID HttpCleanProtocol(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:820
EFI_STATUS HttpConnectTcp4(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:1221
EFI_STATUS HttpTcpReceiveBody(IN HTTP_TOKEN_WRAP *Wrap, IN EFI_HTTP_MESSAGE *HttpMsg)
Definition: HttpProto.c:2087
EFI_STATUS HttpConnectTcp6(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:1313
VOID EFIAPI HttpCommonNotify(IN EFI_EVENT Event, IN VOID *Context)
Definition: HttpProto.c:22
EFI_STATUS EFIAPI HttpTcpReceive(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: HttpProto.c:1797
EFI_STATUS HttpCloseConnection(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:1001
EFI_STATUS HttpCreateConnection(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:943
VOID HttpNotify(IN EDKII_HTTP_CALLBACK_EVENT Event, IN EFI_STATUS EventStatus)
Definition: HttpProto.c:2213
EFI_STATUS EFIAPI HttpTcpTransmit(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: HttpProto.c:1722
EFI_STATUS HttpTransmitTcp(IN HTTP_PROTOCOL *HttpInstance, IN HTTP_TOKEN_WRAP *Wrap, IN UINT8 *TxString, IN UINTN TxStringLen)
Definition: HttpProto.c:1483
VOID EFIAPI HttpTcpReceiveNotifyDpc(IN VOID *Context)
Definition: HttpProto.c:122
VOID EFIAPI HttpTcpTransmitNotify(IN EFI_EVENT Event, IN VOID *Context)
Definition: HttpProto.c:103
VOID EFIAPI HttpTcpReceiveNotify(IN EFI_EVENT Event, IN VOID *Context)
Definition: HttpProto.c:271
VOID EFIAPI HttpTcpTransmitNotifyDpc(IN VOID *Context)
Definition: HttpProto.c:42
EFI_STATUS HttpTcpReceiveHeader(IN HTTP_PROTOCOL *HttpInstance, IN OUT UINTN *SizeofHeaders, IN OUT UINTN *BufferSize, IN EFI_EVENT Timeout)
Definition: HttpProto.c:1822
EFI_STATUS HttpCreateTcpRxEventForHeader(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:473
EFI_STATUS EFIAPI HttpTcpNotReady(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: HttpProto.c:1691
VOID HttpCloseTcpConnCloseEvent(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpProto.c:374
EFI_STATUS HttpCreateTcpTxEvent(IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:413
VOID HttpCloseTcpRxEvent(IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:576
EFI_STATUS HttpConfigureTcp6(IN HTTP_PROTOCOL *HttpInstance, IN HTTP_TOKEN_WRAP *Wrap)
Definition: HttpProto.c:1137
EFI_STATUS EFIAPI HttpsReceive(IN HTTP_PROTOCOL *HttpInstance, IN OUT NET_FRAGMENT *Fragment, IN EFI_EVENT Timeout)
EFI_STATUS EFIAPI TlsProcessMessage(IN HTTP_PROTOCOL *HttpInstance, IN UINT8 *Message, IN UINTN MessageSize, IN EFI_TLS_CRYPT_MODE ProcessMode, IN OUT NET_FRAGMENT *Fragment)
EFI_STATUS EFIAPI TlsConnectSession(IN HTTP_PROTOCOL *HttpInstance, IN EFI_EVENT Timeout)
VOID EFIAPI TlsCloseTxRxEvent(IN HTTP_PROTOCOL *HttpInstance)
Definition: HttpsSupport.c:344
EFI_STATUS EFIAPI TlsConfigureSession(IN OUT HTTP_PROTOCOL *HttpInstance)
Definition: HttpsSupport.c:650
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID EFIAPI NetMapClean(IN OUT NET_MAP *Map)
Definition: DxeNetLib.c:1368
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
NET_MAP_ITEM *EFIAPI NetMapFindKey(IN NET_MAP *Map, IN VOID *Key)
Definition: DxeNetLib.c:1629
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
VOID *EFIAPI NetMapRemoveItem(IN OUT NET_MAP *Map, IN OUT NET_MAP_ITEM *Item, OUT VOID **Value OPTIONAL)
Definition: DxeNetLib.c:1671
EFI_STATUS EFIAPI NetMapIterate(IN NET_MAP *Map, IN NET_MAP_CALLBACK CallBack, IN VOID *Arg OPTIONAL)
Definition: DxeNetLib.c:1800
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_TCP4_CONNECTION_STATE
Definition: Tcp4.h:103
EFI_TCP6_CONNECTION_STATE
Definition: Tcp6.h:243
@ EfiTlsEncrypt
Definition: Tls.h:331
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ TimerCancel
Definition: UefiSpec.h:531
@ TimerRelative
Definition: UefiSpec.h:539
@ ByProtocol
Definition: UefiSpec.h:1518
UINTN BodyLength
Definition: Http.h:257
union EFI_HTTP_MESSAGE::@577 Data
VOID * Body
Definition: Http.h:262
EFI_HTTP_REQUEST_DATA * Request
Definition: Http.h:235
CHAR16 * Url
Definition: Http.h:194
EFI_EVENT Event
Definition: Http.h:274
EFI_HTTP_MESSAGE * Message
Definition: Http.h:290
EFI_STATUS Status
Definition: Http.h:286
EFI_TCP4_COMPLETION_TOKEN CompletionToken
Definition: Tcp4.h:205
EFI_TCP4_TRANSMIT_DATA * TxData
Definition: Tcp4.h:214
EFI_TCP4_RECEIVE_DATA * RxData
Definition: Tcp4.h:210
UINT16 RemotePort
Definition: Tcp6.h:114
BOOLEAN ActiveFlag
Definition: Tcp6.h:119
EFI_IPv6_ADDRESS RemoteAddress
Definition: Tcp6.h:105
UINT16 StationPort
Definition: Tcp6.h:93
EFI_IPv6_ADDRESS StationAddress
Definition: Tcp6.h:87
EFI_STATUS Status
Definition: Tcp6.h:270
EFI_TCP6_ACCESS_POINT AccessPoint
Definition: Tcp6.h:232
UINT8 TrafficClass
Definition: Tcp6.h:224
EFI_TCP6_OPTION * ControlOption
Definition: Tcp6.h:237
VOID * FragmentBuffer
Pointer to the data buffer in the fragment.
Definition: Tcp6.h:336
UINT32 FragmentLength
Length of data buffer in the fragment.
Definition: Tcp6.h:335
EFI_TCP6_RECEIVE_DATA * RxData
Definition: Tcp6.h:440
EFI_TCP6_TRANSMIT_DATA * TxData
Definition: Tcp6.h:445
EFI_TCP6_COMPLETION_TOKEN CompletionToken
Definition: Tcp6.h:434
UINT32 KeepAliveTime
Definition: Tcp6.h:180
UINT32 KeepAliveInterval
Definition: Tcp6.h:187
UINT32 KeepAliveProbes
Definition: Tcp6.h:173
UINT32 SendBufferSize
Definition: Tcp6.h:133
UINT32 DataRetries
Definition: Tcp6.h:150
BOOLEAN EnableWindowScaling
Definition: Tcp6.h:202
UINT32 ReceiveBufferSize
Definition: Tcp6.h:129
UINT32 MaxSynBackLog
Definition: Tcp6.h:138
UINT32 FinTimeout
Definition: Tcp6.h:160
UINT32 ConnectionTimeout
Definition: Tcp6.h:144
BOOLEAN EnableNagle
Definition: Tcp6.h:192
UINT32 FragmentCount
Definition: Tcp6.h:361
UINT32 DataLength
Definition: Tcp6.h:357
EFI_TCP6_FRAGMENT_DATA FragmentTable[1]
Definition: Tcp6.h:365
EFI_TCP6_FRAGMENT_DATA FragmentTable[1]
Definition: Tcp6.h:397
UINT32 FragmentCount
Definition: Tcp6.h:393