2 Miscellaneous routines for HttpDxe driver.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "HttpDriver.h"
18 The common notify function used in HTTP driver.
20 @param[in] Event The event signaled.
21 @param[in] Context The context.
31 if ((Event
== NULL
) || (Context
== NULL
)) {
35 *((BOOLEAN
*) Context
) = TRUE
;
39 The notify function associated with TxToken for Tcp4->Transmit().
41 @param[in] Event The event signaled.
42 @param[in] Context The context.
47 HttpTcpTransmitNotify (
52 HTTP_TOKEN_WRAP
*Wrap
;
54 if ((Event
== NULL
) || (Context
== NULL
)) {
58 Wrap
= (HTTP_TOKEN_WRAP
*) Context
;
59 Wrap
->HttpToken
->Status
= Wrap
->TcpWrap
.TxToken
.CompletionToken
.Status
;
60 gBS
->SignalEvent (Wrap
->HttpToken
->Event
);
65 if (Wrap
->TcpWrap
.TxToken
.Packet
.TxData
->FragmentTable
[0].FragmentBuffer
!= NULL
) {
66 FreePool (Wrap
->TcpWrap
.TxToken
.Packet
.TxData
->FragmentTable
[0].FragmentBuffer
);
69 if (Wrap
->TcpWrap
.TxToken
.CompletionToken
.Event
!= NULL
) {
70 gBS
->CloseEvent (Wrap
->TcpWrap
.TxToken
.CompletionToken
.Event
);
73 Wrap
->TcpWrap
.IsTxDone
= TRUE
;
76 // Check pending TxTokens and sent out.
78 NetMapIterate (&Wrap
->HttpInstance
->TxTokens
, HttpTcpTransmit
, NULL
);
83 The notify function associated with RxToken for Tcp4->Receive ().
85 @param[in] Event The event signaled.
86 @param[in] Context The context.
91 HttpTcpReceiveNotify (
96 HTTP_TOKEN_WRAP
*Wrap
;
100 HTTP_PROTOCOL
*HttpInstance
;
102 if ((Event
== NULL
) || (Context
== NULL
)) {
106 Wrap
= (HTTP_TOKEN_WRAP
*) Context
;
107 gBS
->CloseEvent (Wrap
->TcpWrap
.RxToken
.CompletionToken
.Event
);
108 if (EFI_ERROR (Wrap
->TcpWrap
.RxToken
.CompletionToken
.Status
)) {
112 HttpInstance
= Wrap
->HttpInstance
;
115 // Check whether we receive a complete HTTP message.
117 ASSERT (HttpInstance
->MsgParser
!= NULL
);
119 Length
= (UINTN
) Wrap
->TcpWrap
.RxData
.FragmentTable
[0].FragmentLength
;
120 Status
= HttpParseMessageBody (
121 HttpInstance
->MsgParser
,
123 Wrap
->HttpToken
->Message
->Body
125 if (EFI_ERROR (Status
)) {
129 if (HttpIsMessageComplete (HttpInstance
->MsgParser
)) {
131 // Free the MsgParse since we already have a full HTTP message.
133 HttpFreeMsgParser (HttpInstance
->MsgParser
);
134 HttpInstance
->MsgParser
= NULL
;
137 Wrap
->HttpToken
->Message
->BodyLength
= Length
;
138 ASSERT (HttpInstance
->CacheBody
== NULL
);
140 // We receive part of header of next HTTP msg.
142 if (HttpInstance
->NextMsg
!= NULL
) {
143 Wrap
->HttpToken
->Message
->BodyLength
= HttpInstance
->NextMsg
-
144 (CHAR8
*) Wrap
->HttpToken
->Message
->Body
;
145 HttpInstance
->CacheLen
= Length
- Wrap
->HttpToken
->Message
->BodyLength
;
146 if (HttpInstance
->CacheLen
!= 0) {
147 HttpInstance
->CacheBody
= AllocateZeroPool (HttpInstance
->CacheLen
);
148 if (HttpInstance
->CacheBody
== NULL
) {
151 CopyMem (HttpInstance
->CacheBody
, HttpInstance
->NextMsg
, HttpInstance
->CacheLen
);
152 HttpInstance
->NextMsg
= HttpInstance
->CacheBody
;
153 HttpInstance
->CacheOffset
= 0;
157 Item
= NetMapFindKey (&Wrap
->HttpInstance
->RxTokens
, Wrap
->HttpToken
);
159 NetMapRemoveItem (&Wrap
->HttpInstance
->RxTokens
, Item
, NULL
);
163 Wrap
->TcpWrap
.IsRxDone
= TRUE
;
164 Wrap
->HttpToken
->Status
= Wrap
->TcpWrap
.RxToken
.CompletionToken
.Status
;
166 gBS
->SignalEvent (Wrap
->HttpToken
->Event
);
169 // Check pending RxTokens and receive the HTTP message.
171 NetMapIterate (&Wrap
->HttpInstance
->RxTokens
, HttpTcpReceive
, NULL
);
177 Create events for the TCP4 connection token and TCP4 close token.
179 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
181 @retval EFI_SUCCESS The events are created successfully.
182 @retval others Other error as indicated.
186 HttpCreateTcp4ConnCloseEvent (
187 IN HTTP_PROTOCOL
*HttpInstance
192 // Create events for variuos asynchronous operations.
194 Status
= gBS
->CreateEvent (
198 &HttpInstance
->IsConnDone
,
199 &HttpInstance
->ConnToken
.CompletionToken
.Event
201 if (EFI_ERROR (Status
)) {
206 // Initialize CloseToken
208 Status
= gBS
->CreateEvent (
212 &HttpInstance
->IsCloseDone
,
213 &HttpInstance
->CloseToken
.CompletionToken
.Event
215 if (EFI_ERROR (Status
)) {
226 HttpCloseTcp4ConnCloseEvent (HttpInstance
);
233 Close events in the TCP4 connection token and TCP4 close token.
235 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
239 HttpCloseTcp4ConnCloseEvent (
240 IN HTTP_PROTOCOL
*HttpInstance
243 ASSERT (HttpInstance
!= NULL
);
245 if (NULL
!= HttpInstance
->ConnToken
.CompletionToken
.Event
) {
246 gBS
->CloseEvent (HttpInstance
->ConnToken
.CompletionToken
.Event
);
247 HttpInstance
->ConnToken
.CompletionToken
.Event
= NULL
;
250 if (NULL
!= HttpInstance
->CloseToken
.CompletionToken
.Event
) {
251 gBS
->CloseEvent(HttpInstance
->CloseToken
.CompletionToken
.Event
);
252 HttpInstance
->CloseToken
.CompletionToken
.Event
= NULL
;
257 Create event for the TCP4 transmit token.
259 @param[in] Wrap Point to HTTP token's wrap data.
261 @retval EFI_SUCCESS The events is created successfully.
262 @retval others Other error as indicated.
266 HttpCreateTcp4TxEvent (
267 IN HTTP_TOKEN_WRAP
*Wrap
271 HTTP_PROTOCOL
*HttpInstance
;
272 HTTP_TCP_TOKEN_WRAP
*TcpWrap
;
274 HttpInstance
= Wrap
->HttpInstance
;
275 TcpWrap
= &Wrap
->TcpWrap
;
277 Status
= gBS
->CreateEvent (
280 HttpTcpTransmitNotify
,
282 &TcpWrap
->TxToken
.CompletionToken
.Event
284 if (EFI_ERROR (Status
)) {
288 TcpWrap
->TxData
.Push
= TRUE
;
289 TcpWrap
->TxData
.Urgent
= FALSE
;
290 TcpWrap
->TxData
.FragmentCount
= 1;
291 TcpWrap
->TxToken
.Packet
.TxData
= &Wrap
->TcpWrap
.TxData
;
292 TcpWrap
->TxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
298 Create event for the TCP4 receive token which is used to receive HTTP header.
300 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
302 @retval EFI_SUCCESS The events is created successfully.
303 @retval others Other error as indicated.
307 HttpCreateTcp4RxEventForHeader (
308 IN HTTP_PROTOCOL
*HttpInstance
314 Status
= gBS
->CreateEvent (
318 &HttpInstance
->IsRxDone
,
319 &HttpInstance
->RxToken
.CompletionToken
.Event
321 if (EFI_ERROR (Status
)) {
325 HttpInstance
->RxData
.FragmentCount
= 1;
326 HttpInstance
->RxToken
.Packet
.RxData
= &HttpInstance
->RxData
;
327 HttpInstance
->RxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
333 Create event for the TCP4 receive token which is used to receive HTTP body.
335 @param[in] Wrap Point to HTTP token's wrap data.
337 @retval EFI_SUCCESS The events is created successfully.
338 @retval others Other error as indicated.
342 HttpCreateTcp4RxEvent (
343 IN HTTP_TOKEN_WRAP
*Wrap
347 HTTP_PROTOCOL
*HttpInstance
;
348 HTTP_TCP_TOKEN_WRAP
*TcpWrap
;
350 HttpInstance
= Wrap
->HttpInstance
;
351 TcpWrap
= &Wrap
->TcpWrap
;
353 Status
= gBS
->CreateEvent (
356 HttpTcpReceiveNotify
,
358 &TcpWrap
->RxToken
.CompletionToken
.Event
360 if (EFI_ERROR (Status
)) {
364 TcpWrap
->RxData
.FragmentCount
= 1;
365 TcpWrap
->RxToken
.Packet
.RxData
= &Wrap
->TcpWrap
.RxData
;
366 TcpWrap
->RxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
372 Intiialize the HTTP_PROTOCOL structure to the unconfigured state.
374 @param[in] HttpSb The HTTP service private instance.
375 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
377 @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully.
378 @retval Others Other error as indicated.
383 IN HTTP_SERVICE
*HttpSb
,
384 IN OUT HTTP_PROTOCOL
*HttpInstance
390 ASSERT ((HttpSb
!= NULL
) && (HttpInstance
!= NULL
));
392 HttpInstance
->Signature
= HTTP_PROTOCOL_SIGNATURE
;
393 CopyMem (&HttpInstance
->Http
, &mEfiHttpTemplate
, sizeof (HttpInstance
->Http
));
394 HttpInstance
->Service
= HttpSb
;
399 Status
= NetLibCreateServiceChild (
400 HttpInstance
->Service
->ControllerHandle
,
401 HttpInstance
->Service
->ImageHandle
,
402 &gEfiTcp4ServiceBindingProtocolGuid
,
403 &HttpInstance
->TcpChildHandle
406 if (EFI_ERROR (Status
)) {
410 Status
= gBS
->OpenProtocol (
411 HttpInstance
->TcpChildHandle
,
412 &gEfiTcp4ProtocolGuid
,
413 (VOID
**) &Interface
,
414 HttpInstance
->Service
->ImageHandle
,
415 HttpInstance
->Service
->ControllerHandle
,
416 EFI_OPEN_PROTOCOL_BY_DRIVER
419 if (EFI_ERROR (Status
)) {
423 Status
= gBS
->OpenProtocol (
424 HttpInstance
->TcpChildHandle
,
425 &gEfiTcp4ProtocolGuid
,
426 (VOID
**) &HttpInstance
->Tcp4
,
427 HttpInstance
->Service
->ImageHandle
,
428 HttpInstance
->Handle
,
429 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
431 if (EFI_ERROR(Status
)) {
435 HttpInstance
->Url
= AllocateZeroPool (HTTP_URL_BUFFER_LEN
);
436 if (HttpInstance
->Url
== NULL
) {
437 Status
= EFI_OUT_OF_RESOURCES
;
441 NetMapInit (&HttpInstance
->TxTokens
);
442 NetMapInit (&HttpInstance
->RxTokens
);
448 if (HttpInstance
->TcpChildHandle
!= NULL
) {
450 HttpInstance
->TcpChildHandle
,
451 &gEfiTcp4ProtocolGuid
,
452 HttpInstance
->Service
->ImageHandle
,
453 HttpInstance
->Service
->ControllerHandle
457 HttpInstance
->TcpChildHandle
,
458 &gEfiTcp4ProtocolGuid
,
459 HttpInstance
->Service
->ImageHandle
,
463 NetLibDestroyServiceChild (
464 HttpInstance
->Service
->ControllerHandle
,
465 HttpInstance
->Service
->ImageHandle
,
466 &gEfiTcp4ServiceBindingProtocolGuid
,
467 HttpInstance
->TcpChildHandle
476 Clean up the HTTP child, release all the resources used by it.
478 @param[in] HttpInstance The HTTP child to clean up.
483 IN HTTP_PROTOCOL
*HttpInstance
486 HttpCloseConnection (HttpInstance
);
488 HttpCloseTcp4ConnCloseEvent (HttpInstance
);
490 if (HttpInstance
->CacheBody
!= NULL
) {
491 FreePool (HttpInstance
->CacheBody
);
492 HttpInstance
->CacheBody
= NULL
;
493 HttpInstance
->NextMsg
= NULL
;
496 if (HttpInstance
->RemoteHost
!= NULL
) {
497 FreePool (HttpInstance
->RemoteHost
);
498 HttpInstance
->RemoteHost
= NULL
;
501 if (HttpInstance
->MsgParser
!= NULL
) {
502 HttpFreeMsgParser (HttpInstance
->MsgParser
);
503 HttpInstance
->MsgParser
= NULL
;
506 if (HttpInstance
->Url
!= NULL
) {
507 FreePool (HttpInstance
->Url
);
508 HttpInstance
->Url
= NULL
;
511 NetMapClean (&HttpInstance
->TxTokens
);
512 NetMapClean (&HttpInstance
->RxTokens
);
514 if (HttpInstance
->TcpChildHandle
!= NULL
) {
516 HttpInstance
->TcpChildHandle
,
517 &gEfiTcp4ProtocolGuid
,
518 HttpInstance
->Service
->ImageHandle
,
519 HttpInstance
->Service
->ControllerHandle
523 HttpInstance
->TcpChildHandle
,
524 &gEfiTcp4ProtocolGuid
,
525 HttpInstance
->Service
->ImageHandle
,
529 NetLibDestroyServiceChild (
530 HttpInstance
->Service
->ControllerHandle
,
531 HttpInstance
->Service
->ImageHandle
,
532 &gEfiTcp4ServiceBindingProtocolGuid
,
533 HttpInstance
->TcpChildHandle
539 Establish TCP connection with HTTP server.
541 @param[in] HttpInstance The HTTP instance private data.
543 @retval EFI_SUCCESS The TCP connection is established.
544 @retval Others Other error as indicated.
548 HttpCreateConnection (
549 IN HTTP_PROTOCOL
*HttpInstance
555 // Create events for variuos asynchronous operations.
557 HttpInstance
->IsConnDone
= FALSE
;
560 // Connect to Http server
562 HttpInstance
->ConnToken
.CompletionToken
.Status
= EFI_NOT_READY
;
563 Status
= HttpInstance
->Tcp4
->Connect (HttpInstance
->Tcp4
, &HttpInstance
->ConnToken
);
564 if (EFI_ERROR (Status
)) {
565 DEBUG ((EFI_D_ERROR
, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status
));
569 while (!HttpInstance
->IsConnDone
) {
570 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
573 Status
= HttpInstance
->ConnToken
.CompletionToken
.Status
;
575 if (!EFI_ERROR (Status
)) {
576 HttpInstance
->State
= HTTP_STATE_TCP_CONNECTED
;
583 Close existing TCP connection.
585 @param[in] HttpInstance The HTTP instance private data.
587 @retval EFI_SUCCESS The TCP connection is closed.
588 @retval Others Other error as indicated.
592 HttpCloseConnection (
593 IN HTTP_PROTOCOL
*HttpInstance
598 if (HttpInstance
->State
== HTTP_STATE_TCP_CONNECTED
) {
599 HttpInstance
->CloseToken
.AbortOnClose
= TRUE
;
600 HttpInstance
->IsCloseDone
= FALSE
;
602 Status
= HttpInstance
->Tcp4
->Close (HttpInstance
->Tcp4
, &HttpInstance
->CloseToken
);
603 if (EFI_ERROR (Status
)) {
607 while (!HttpInstance
->IsCloseDone
) {
608 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
612 HttpInstance
->State
= HTTP_STATE_TCP_CLOSED
;
617 Configure TCP4 protocol child.
619 @param[in] HttpInstance The HTTP instance private data.
620 @param[in] Wrap The HTTP token's wrap data.
622 @retval EFI_SUCCESS The TCP4 protocol child is configured.
623 @retval Others Other error as indicated.
628 IN HTTP_PROTOCOL
*HttpInstance
,
629 IN HTTP_TOKEN_WRAP
*Wrap
633 EFI_TCP4_CONFIG_DATA
*Tcp4CfgData
;
634 EFI_TCP4_ACCESS_POINT
*Tcp4AP
;
635 EFI_TCP4_OPTION
*Tcp4Option
;
636 HTTP_TCP_TOKEN_WRAP
*TcpWrap
;
638 ASSERT (HttpInstance
!= NULL
);
639 TcpWrap
= &Wrap
->TcpWrap
;
642 Tcp4CfgData
= &HttpInstance
->Tcp4CfgData
;
643 ZeroMem (Tcp4CfgData
, sizeof (EFI_TCP4_CONFIG_DATA
));
645 Tcp4CfgData
->TypeOfService
= HTTP_TOS_DEAULT
;
646 Tcp4CfgData
->TimeToLive
= HTTP_TTL_DEAULT
;
647 Tcp4CfgData
->ControlOption
= &HttpInstance
->Tcp4Option
;
649 Tcp4AP
= &Tcp4CfgData
->AccessPoint
;
650 Tcp4AP
->UseDefaultAddress
= HttpInstance
->IPv4Node
.UseDefaultAddress
;
651 if (!Tcp4AP
->UseDefaultAddress
) {
652 IP4_COPY_ADDRESS (&Tcp4AP
->StationAddress
, &HttpInstance
->IPv4Node
.LocalAddress
);
653 IP4_COPY_ADDRESS (&Tcp4AP
->SubnetMask
, &HttpInstance
->IPv4Node
.LocalSubnet
);
656 Tcp4AP
->StationPort
= HttpInstance
->IPv4Node
.LocalPort
;
657 Tcp4AP
->RemotePort
= HttpInstance
->RemotePort
;
658 Tcp4AP
->ActiveFlag
= TRUE
;
659 IP4_COPY_ADDRESS (&Tcp4AP
->RemoteAddress
, &HttpInstance
->RemoteAddr
);
661 Tcp4Option
= Tcp4CfgData
->ControlOption
;
662 Tcp4Option
->ReceiveBufferSize
= HTTP_BUFFER_SIZE_DEAULT
;
663 Tcp4Option
->SendBufferSize
= HTTP_BUFFER_SIZE_DEAULT
;
664 Tcp4Option
->MaxSynBackLog
= HTTP_MAX_SYN_BACK_LOG
;
665 Tcp4Option
->ConnectionTimeout
= HTTP_CONNECTION_TIMEOUT
;
666 Tcp4Option
->DataRetries
= HTTP_DATA_RETRIES
;
667 Tcp4Option
->FinTimeout
= HTTP_FIN_TIMEOUT
;
668 Tcp4Option
->KeepAliveProbes
= HTTP_KEEP_ALIVE_PROBES
;
669 Tcp4Option
->KeepAliveTime
= HTTP_KEEP_ALIVE_TIME
;
670 Tcp4Option
->KeepAliveInterval
= HTTP_KEEP_ALIVE_INTERVAL
;
671 Tcp4Option
->EnableNagle
= TRUE
;
672 Tcp4CfgData
->ControlOption
= Tcp4Option
;
674 Status
= HttpInstance
->Tcp4
->Configure (HttpInstance
->Tcp4
, Tcp4CfgData
);
675 if (EFI_ERROR (Status
)) {
676 DEBUG ((EFI_D_ERROR
, "HttpConfigureTcp4 - %r\n", Status
));
680 Status
= HttpCreateTcp4ConnCloseEvent (HttpInstance
);
681 if (EFI_ERROR (Status
)) {
685 Status
= HttpCreateTcp4TxEvent (Wrap
);
686 if (EFI_ERROR (Status
)) {
690 HttpInstance
->State
= HTTP_STATE_TCP_CONFIGED
;
696 Check existing TCP connection, if in error state, receover TCP4 connection.
698 @param[in] HttpInstance The HTTP instance private data.
700 @retval EFI_SUCCESS The TCP connection is established.
701 @retval EFI_NOT_READY TCP4 protocol child is not created or configured.
702 @retval Others Other error as indicated.
707 IN HTTP_PROTOCOL
*HttpInstance
711 EFI_TCP4_CONNECTION_STATE Tcp4State
;
714 if (HttpInstance
->State
!= HTTP_STATE_TCP_CONFIGED
|| HttpInstance
->Tcp4
== NULL
) {
715 return EFI_NOT_READY
;
718 Status
= HttpInstance
->Tcp4
->GetModeData(
726 if (EFI_ERROR(Status
)){
727 DEBUG ((EFI_D_ERROR
, "Tcp4 GetModeData fail - %x\n", Status
));
731 if (Tcp4State
> Tcp4StateEstablished
) {
732 HttpCloseConnection(HttpInstance
);
735 return HttpCreateConnection (HttpInstance
);
739 Send the HTTP message through TCP4.
741 @param[in] HttpInstance The HTTP instance private data.
742 @param[in] Wrap The HTTP token's wrap data.
743 @param[in] TxString Buffer containing the HTTP message string.
744 @param[in] TxStringLen Length of the HTTP message string in bytes.
746 @retval EFI_SUCCESS The HTTP message is queued into TCP transmit queue.
747 @retval Others Other error as indicated.
752 IN HTTP_PROTOCOL
*HttpInstance
,
753 IN HTTP_TOKEN_WRAP
*Wrap
,
759 EFI_TCP4_IO_TOKEN
*TxToken
;
760 EFI_TCP4_PROTOCOL
*Tcp4
;
762 Tcp4
= HttpInstance
->Tcp4
;
763 TxToken
= &Wrap
->TcpWrap
.TxToken
;
765 TxToken
->Packet
.TxData
->DataLength
= (UINT32
) TxStringLen
;
766 TxToken
->Packet
.TxData
->FragmentTable
[0].FragmentLength
= (UINT32
) TxStringLen
;
767 TxToken
->Packet
.TxData
->FragmentTable
[0].FragmentBuffer
= (VOID
*) TxString
;
768 TxToken
->CompletionToken
.Status
= EFI_NOT_READY
;
770 Wrap
->TcpWrap
.IsTxDone
= FALSE
;
771 Status
= Tcp4
->Transmit (Tcp4
, TxToken
);
772 if (EFI_ERROR (Status
)) {
773 DEBUG ((EFI_D_ERROR
, "Transmit failed: %r\n", Status
));
781 Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
782 in UEFI 2.5 specification.
784 @param[in] StatusCode The status code value in HTTP message.
786 @return Value defined in EFI_HTTP_STATUS_CODE .
790 HttpMappingToStatusCode (
794 switch (StatusCode
) {
796 return HTTP_STATUS_100_CONTINUE
;
798 return HTTP_STATUS_101_SWITCHING_PROTOCOLS
;
800 return HTTP_STATUS_200_OK
;
802 return HTTP_STATUS_201_CREATED
;
804 return HTTP_STATUS_202_ACCEPTED
;
806 return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION
;
808 return HTTP_STATUS_204_NO_CONTENT
;
810 return HTTP_STATUS_205_RESET_CONTENT
;
812 return HTTP_STATUS_206_PARTIAL_CONTENT
;
814 return HTTP_STATUS_300_MULTIPLE_CHIOCES
;
816 return HTTP_STATUS_301_MOVED_PERMANENTLY
;
818 return HTTP_STATUS_302_FOUND
;
820 return HTTP_STATUS_303_SEE_OTHER
;
822 return HTTP_STATUS_304_NOT_MODIFIED
;
824 return HTTP_STATUS_305_USE_PROXY
;
826 return HTTP_STATUS_307_TEMPORARY_REDIRECT
;
828 return HTTP_STATUS_400_BAD_REQUEST
;
830 return HTTP_STATUS_401_UNAUTHORIZED
;
832 return HTTP_STATUS_402_PAYMENT_REQUIRED
;
834 return HTTP_STATUS_403_FORBIDDEN
;
836 return HTTP_STATUS_404_NOT_FOUND
;
838 return HTTP_STATUS_405_METHOD_NOT_ALLOWED
;
840 return HTTP_STATUS_406_NOT_ACCEPTABLE
;
842 return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED
;
844 return HTTP_STATUS_408_REQUEST_TIME_OUT
;
846 return HTTP_STATUS_409_CONFLICT
;
848 return HTTP_STATUS_410_GONE
;
850 return HTTP_STATUS_411_LENGTH_REQUIRED
;
852 return HTTP_STATUS_412_PRECONDITION_FAILED
;
854 return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE
;
856 return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE
;
858 return HTTP_STATUS_415_UNSUPPORETD_MEDIA_TYPE
;
860 return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED
;
862 return HTTP_STATUS_417_EXPECTATION_FAILED
;
864 return HTTP_STATUS_500_INTERNAL_SERVER_ERROR
;
866 return HTTP_STATUS_501_NOT_IMIPLEMENTED
;
868 return HTTP_STATUS_502_BAD_GATEWAY
;
870 return HTTP_STATUS_503_SERVICE_UNAVAILABLE
;
872 return HTTP_STATUS_504_GATEWAY_TIME_OUT
;
874 return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED
;
877 return HTTP_STATUS_UNSUPPORTED_STATUS
;
882 Check whether the user's token or event has already
883 been enqueue on HTTP TxToken or RxToken list.
885 @param[in] Map The container of either user's transmit or receive
887 @param[in] Item Current item to check against.
888 @param[in] Context The Token to check againist.
890 @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP
891 @retval EFI_SUCCESS The current item isn't the same token/event as the
899 IN NET_MAP_ITEM
*Item
,
903 EFI_HTTP_TOKEN
*Token
;
904 EFI_HTTP_TOKEN
*TokenInItem
;
906 Token
= (EFI_HTTP_TOKEN
*) Context
;
907 TokenInItem
= (EFI_HTTP_TOKEN
*) Item
->Key
;
909 if (Token
== TokenInItem
|| Token
->Event
== TokenInItem
->Event
) {
910 return EFI_ACCESS_DENIED
;
917 Check whether the HTTP message associated with TxToken is already sent out.
919 @param[in] Map The container of TxToken.
920 @param[in] Item Current item to check against.
921 @param[in] Context The Token to check againist.
923 @retval EFI_NOT_READY The HTTP message is still queued in the list.
924 @retval EFI_SUCCESS The HTTP message has been sent out.
931 IN NET_MAP_ITEM
*Item
,
935 HTTP_TOKEN_WRAP
*ValueInItem
;
937 ValueInItem
= (HTTP_TOKEN_WRAP
*) Item
->Value
;
939 if (!ValueInItem
->TcpWrap
.IsTxDone
) {
940 return EFI_NOT_READY
;
947 Transmit the HTTP mssage by processing the associated HTTP token.
949 @param[in] Map The container of TxToken.
950 @param[in] Item Current item to check against.
951 @param[in] Context The Token to check againist.
953 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
954 @retval EFI_SUCCESS The HTTP message is queued into TCP transmit
962 IN NET_MAP_ITEM
*Item
,
966 HTTP_TOKEN_WRAP
*ValueInItem
;
971 ValueInItem
= (HTTP_TOKEN_WRAP
*) Item
->Value
;
972 if (ValueInItem
->TcpWrap
.IsTxDone
) {
977 // Parse the URI of the remote host.
979 Url
= AllocatePool (StrLen (ValueInItem
->HttpToken
->Message
->Data
.Request
->Url
) + 1);
981 return EFI_OUT_OF_RESOURCES
;
984 UnicodeStrToAsciiStr (ValueInItem
->HttpToken
->Message
->Data
.Request
->Url
, Url
);
987 // Create request message.
989 RequestStr
= HttpGenRequestString (
990 ValueInItem
->HttpInstance
,
991 ValueInItem
->HttpToken
->Message
,
995 if (RequestStr
== NULL
) {
996 return EFI_OUT_OF_RESOURCES
;
1000 // Transmit the request message.
1002 Status
= HttpTransmitTcp4 (
1003 ValueInItem
->HttpInstance
,
1005 (UINT8
*) RequestStr
,
1006 AsciiStrLen (RequestStr
)
1008 FreePool (RequestStr
);
1013 Receive the HTTP response by processing the associated HTTP token.
1015 @param[in] Map The container of RxToken.
1016 @param[in] Item Current item to check against.
1017 @param[in] Context The Token to check againist.
1019 @retval EFI_SUCCESS The HTTP response is queued into TCP receive
1021 @retval Others Other error as indicated.
1028 IN NET_MAP_ITEM
*Item
,
1033 // Process the queued HTTP response.
1035 return HttpResponseWorker ((HTTP_TOKEN_WRAP
*) Item
->Value
);
1039 Generate HTTP request string.
1041 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1042 @param[in] Message Pointer to storage containing HTTP message data.
1043 @param[in] Url The URL of a remote host.
1045 @return Pointer to the created HTTP request string.
1046 @return NULL if any error occured.
1050 HttpGenRequestString (
1051 IN HTTP_PROTOCOL
*HttpInstance
,
1052 IN EFI_HTTP_MESSAGE
*Message
,
1064 EFI_HTTP_HEADER
**AppendList
;
1067 ASSERT (HttpInstance
!= NULL
);
1068 ASSERT (Message
!= NULL
);
1070 DEBUG ((EFI_D_ERROR
, "HttpMethod - %x\n", Message
->Data
.Request
->Method
));
1080 AppendList
= AllocateZeroPool (sizeof (EFI_HTTP_HEADER
*) * (Message
->HeaderCount
));
1081 if (AppendList
== NULL
) {
1085 for(Index
= 0; Index
< Message
->HeaderCount
; Index
++){
1086 AppendList
[Index
] = &Message
->Headers
[Index
];
1090 // Check whether the EFI_HTTP_UTILITIES_PROTOCOL is available.
1092 if (mHttpUtilities
== NULL
) {
1097 // Build raw unformatted HTTP headers.
1099 Status
= mHttpUtilities
->Build (
1105 Message
->HeaderCount
,
1110 FreePool (AppendList
);
1111 if (EFI_ERROR (Status
) || HttpHdr
== NULL
) {
1116 // Calculate HTTP message length.
1118 MsgSize
= Message
->BodyLength
+ HTTP_MAXIMUM_METHOD_LEN
+ AsciiStrLen (Url
) +
1119 AsciiStrLen (HTTP_VERSION_CRLF_STR
) + HttpHdrSize
;
1120 Request
= AllocateZeroPool (MsgSize
);
1121 if (Request
== NULL
) {
1125 RequestPtr
= Request
;
1127 // Construct header request
1129 switch (Message
->Data
.Request
->Method
) {
1131 StrLength
= sizeof (HTTP_GET_STR
) - 1;
1132 CopyMem (RequestPtr
, HTTP_GET_STR
, StrLength
);
1133 RequestPtr
+= StrLength
;
1135 case HttpMethodHead
:
1136 StrLength
= sizeof (HTTP_HEAD_STR
) - 1;
1137 CopyMem (RequestPtr
, HTTP_HEAD_STR
, StrLength
);
1138 RequestPtr
+= StrLength
;
1145 StrLength
= AsciiStrLen (Url
);
1146 CopyMem (RequestPtr
, Url
, StrLength
);
1147 RequestPtr
+= StrLength
;
1149 StrLength
= sizeof (HTTP_VERSION_CRLF_STR
) - 1;
1150 CopyMem (RequestPtr
, HTTP_VERSION_CRLF_STR
, StrLength
);
1151 RequestPtr
+= StrLength
;
1156 CopyMem (RequestPtr
, HttpHdr
, HttpHdrSize
);
1157 RequestPtr
+= HttpHdrSize
;
1162 if (Message
->Body
!= NULL
) {
1163 CopyMem (RequestPtr
, Message
->Body
, Message
->BodyLength
);
1164 RequestPtr
+= Message
->BodyLength
;
1176 if (Request
!= NULL
) {
1183 if (HttpHdr
!= NULL
) {
1187 return (CHAR8
*) Request
;