1 /** @file
2   HttpIoLib.h.
3 
4 (C) Copyright 2020 Hewlett-Packard Development Company, L.P.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef HTTP_IO_LIB_H_
10 #define HTTP_IO_LIB_H_
11 
12 #include <IndustryStandard/Http11.h>
13 
14 #include <Library/DpcLib.h>
15 #include <Library/HttpLib.h>
16 #include <Library/NetLib.h>
17 
18 #define HTTP_IO_MAX_SEND_PAYLOAD                    1024
19 #define HTTP_IO_CHUNK_SIZE_STRING_LEN               50
20 #define HTTP_IO_CHUNKED_TRANSFER_CODING_DATA_LENGTH 256
21 
22 ///
23 /// HTTP_IO_CALLBACK_EVENT
24 ///
25 typedef enum {
26   HttpIoRequest,
27   HttpIoResponse
28 } HTTP_IO_CALLBACK_EVENT;
29 
30 /**
31   HttpIo Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened.
32 
33   @param[in]    EventType      Indicate the Event type that occurs in the current callback.
34   @param[in]    Message        HTTP message which will be send to, or just received from HTTP server.
35   @param[in]    Context        The Callback Context pointer.
36 
37   @retval EFI_SUCCESS          Tells the HttpIo to continue the HTTP process.
38   @retval Others               Tells the HttpIo to abort the current HTTP process.
39 **/
40 typedef
41 EFI_STATUS
42 (EFIAPI * HTTP_IO_CALLBACK) (
43   IN  HTTP_IO_CALLBACK_EVENT    EventType,
44   IN  EFI_HTTP_MESSAGE          *Message,
45   IN  VOID                      *Context
46   );
47 
48 ///
49 /// A wrapper structure to hold the received HTTP response data.
50 ///
51 typedef struct {
52   EFI_HTTP_RESPONSE_DATA      Response;
53   UINTN                       HeaderCount;
54   EFI_HTTP_HEADER             *Headers;
55   UINTN                       BodyLength;
56   CHAR8                       *Body;
57   EFI_STATUS                  Status;
58 } HTTP_IO_RESPONSE_DATA;
59 
60 ///
61 /// HTTP_IO configuration data for IPv4
62 ///
63 typedef struct {
64   EFI_HTTP_VERSION          HttpVersion;
65   UINT32                    RequestTimeOut;  ///< In milliseconds.
66   UINT32                    ResponseTimeOut; ///< In milliseconds.
67   BOOLEAN                   UseDefaultAddress;
68   EFI_IPv4_ADDRESS          LocalIp;
69   EFI_IPv4_ADDRESS          SubnetMask;
70   UINT16                    LocalPort;
71 } HTTP4_IO_CONFIG_DATA;
72 
73 ///
74 /// HTTP_IO configuration data for IPv6
75 ///
76 typedef struct {
77   EFI_HTTP_VERSION          HttpVersion;
78   UINT32                    RequestTimeOut;  ///< In milliseconds.
79   BOOLEAN                   UseDefaultAddress;
80   EFI_IPv6_ADDRESS          LocalIp;
81   UINT16                    LocalPort;
82 } HTTP6_IO_CONFIG_DATA;
83 
84 ///
85 /// HTTP_IO configuration
86 ///
87 typedef union {
88   HTTP4_IO_CONFIG_DATA       Config4;
89   HTTP6_IO_CONFIG_DATA       Config6;
90 } HTTP_IO_CONFIG_DATA;
91 
92 ///
93 /// HTTP_IO wrapper of the EFI HTTP service.
94 ///
95 typedef struct {
96   UINT8                     IpVersion;
97   EFI_HANDLE                Image;
98   EFI_HANDLE                Controller;
99   EFI_HANDLE                Handle;
100 
101   EFI_HTTP_PROTOCOL         *Http;
102 
103   HTTP_IO_CALLBACK          Callback;
104   VOID                      *Context;
105 
106   EFI_HTTP_TOKEN            ReqToken;
107   EFI_HTTP_MESSAGE          ReqMessage;
108   EFI_HTTP_TOKEN            RspToken;
109   EFI_HTTP_MESSAGE          RspMessage;
110 
111   BOOLEAN                   IsTxDone;
112   BOOLEAN                   IsRxDone;
113 
114   EFI_EVENT                 TimeoutEvent;
115   UINT32                    Timeout;
116 } HTTP_IO;
117 
118 ///
119 /// Process code of HTTP chunk transfer.
120 ///
121 typedef enum  {
122   HttpIoSendChunkNone = 0,
123   HttpIoSendChunkHeaderZeroContent,
124   HttpIoSendChunkContent,
125   HttpIoSendChunkEndChunk,
126   HttpIoSendChunkFinish
127 } HTTP_IO_SEND_CHUNK_PROCESS;
128 
129 ///
130 /// Process code of HTTP non chunk transfer.
131 ///
132 typedef enum  {
133   HttpIoSendNonChunkNone = 0,
134   HttpIoSendNonChunkHeaderZeroContent,
135   HttpIoSendNonChunkContent,
136   HttpIoSendNonChunkFinish
137 } HTTP_IO_SEND_NON_CHUNK_PROCESS;
138 
139 ///
140 /// Chunk links for HTTP chunked transfer coding.
141 ///
142 typedef struct {
143   LIST_ENTRY  NextChunk;
144   UINTN       Length;
145   CHAR8       *Data;
146 } HTTP_IO_CHUNKS;
147 
148 /**
149   Notify the callback function when an event is triggered.
150 
151   @param[in]  Context         The opaque parameter to the function.
152 
153 **/
154 VOID
155 EFIAPI
156 HttpIoNotifyDpc (
157   IN VOID                *Context
158   );
159 
160 /**
161   Request HttpIoNotifyDpc as a DPC at TPL_CALLBACK.
162 
163   @param[in]  Event                 The event signaled.
164   @param[in]  Context               The opaque parameter to the function.
165 
166 **/
167 VOID
168 EFIAPI
169 HttpIoNotify (
170   IN EFI_EVENT              Event,
171   IN VOID                   *Context
172   );
173 
174 /**
175   Destroy the HTTP_IO and release the resources.
176 
177   @param[in]  HttpIo          The HTTP_IO which wraps the HTTP service to be destroyed.
178 
179 **/
180 VOID
181 HttpIoDestroyIo (
182   IN HTTP_IO                *HttpIo
183   );
184 
185 /**
186   Create a HTTP_IO to access the HTTP service. It will create and configure
187   a HTTP child handle.
188 
189   @param[in]  Image          The handle of the driver image.
190   @param[in]  Controller     The handle of the controller.
191   @param[in]  IpVersion      IP_VERSION_4 or IP_VERSION_6.
192   @param[in]  ConfigData     The HTTP_IO configuration data.
193   @param[in]  Callback       Callback function which will be invoked when specified
194                              HTTP_IO_CALLBACK_EVENT happened.
195   @param[in]  Context        The Context data which will be passed to the Callback function.
196   @param[out] HttpIo         The HTTP_IO.
197 
198   @retval EFI_SUCCESS            The HTTP_IO is created and configured.
199   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
200   @retval EFI_UNSUPPORTED        One or more of the control options are not
201                                  supported in the implementation.
202   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
203   @retval Others                 Failed to create the HTTP_IO or configure it.
204 
205 **/
206 EFI_STATUS
207 HttpIoCreateIo (
208   IN EFI_HANDLE             Image,
209   IN EFI_HANDLE             Controller,
210   IN UINT8                  IpVersion,
211   IN HTTP_IO_CONFIG_DATA    *ConfigData,
212   IN HTTP_IO_CALLBACK       Callback,
213   IN VOID                   *Context,
214   OUT HTTP_IO               *HttpIo
215   );
216 
217 /**
218   Synchronously send a HTTP REQUEST message to the server.
219 
220   @param[in]   HttpIo           The HttpIo wrapping the HTTP service.
221   @param[in]   Request          A pointer to storage such data as URL and HTTP method.
222   @param[in]   HeaderCount      Number of HTTP header structures in Headers list.
223   @param[in]   Headers          Array containing list of HTTP headers.
224   @param[in]   BodyLength       Length in bytes of the HTTP body.
225   @param[in]   Body             Body associated with the HTTP request.
226 
227   @retval EFI_SUCCESS            The HTTP request is transmitted.
228   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
229   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
230   @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.
231   @retval Others                 Other errors as indicated.
232 
233 **/
234 EFI_STATUS
235 HttpIoSendRequest (
236   IN  HTTP_IO                *HttpIo,
237   IN  EFI_HTTP_REQUEST_DATA  *Request,      OPTIONAL
238   IN  UINTN                  HeaderCount,
239   IN  EFI_HTTP_HEADER        *Headers,      OPTIONAL
240   IN  UINTN                  BodyLength,
241   IN  VOID                   *Body          OPTIONAL
242   );
243 
244 /**
245   Synchronously receive a HTTP RESPONSE message from the server.
246 
247   @param[in]   HttpIo           The HttpIo wrapping the HTTP service.
248   @param[in]   RecvMsgHeader    TRUE to receive a new HTTP response (from message header).
249                                 FALSE to continue receive the previous response message.
250   @param[out]  ResponseData     Point to a wrapper of the received response data.
251 
252   @retval EFI_SUCCESS            The HTTP response is received.
253   @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
254   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
255   @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.
256   @retval Others                 Other errors as indicated.
257 
258 **/
259 EFI_STATUS
260 HttpIoRecvResponse (
261   IN      HTTP_IO                  *HttpIo,
262   IN      BOOLEAN                  RecvMsgHeader,
263   OUT     HTTP_IO_RESPONSE_DATA    *ResponseData
264   );
265 
266 /**
267   Get the value of the content length if there is a "Content-Length" header.
268 
269   @param[in]    HeaderCount        Number of HTTP header structures in Headers.
270   @param[in]    Headers            Array containing list of HTTP headers.
271   @param[out]   ContentLength      Pointer to save the value of the content length.
272 
273   @retval EFI_SUCCESS              Successfully get the content length.
274   @retval EFI_NOT_FOUND            No "Content-Length" header in the Headers.
275 
276 **/
277 EFI_STATUS
278 HttpIoGetContentLength (
279   IN     UINTN                HeaderCount,
280   IN     EFI_HTTP_HEADER      *Headers,
281   OUT    UINTN                *ContentLength
282   );
283 
284 /**
285   Synchronously receive a HTTP RESPONSE message from the server.
286 
287   @param[in]   HttpIo           The HttpIo wrapping the HTTP service.
288   @param[in]   HeaderCount      Number of headers in Headers.
289   @param[in]   Headers          Array containing list of HTTP headers.
290   @param[out]  ChunkListHead    A pointer to receivce list head of chunked data.
291                                 Caller has to release memory of ChunkListHead
292                                 and all list entries.
293   @param[out]  ContentLength    Total content length
294 
295   @retval EFI_SUCCESS            The HTTP chunked transfer is received.
296   @retval EFI_NOT_FOUND          No chunked transfer coding header found.
297   @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
298   @retval EFI_INVALID_PARAMETER  Improper parameters.
299   @retval Others                 Other errors as indicated.
300 
301 **/
302 EFI_STATUS
303 HttpIoGetChunkedTransferContent (
304   IN     HTTP_IO              *HttpIo,
305   IN     UINTN                HeaderCount,
306   IN     EFI_HTTP_HEADER      *Headers,
307   OUT    LIST_ENTRY           **ChunkListHead,
308   OUT    UINTN                *ContentLength
309   );
310 
311 /**
312   Send HTTP request in chunks.
313 
314   @param[in]   HttpIo             The HttpIo wrapping the HTTP service.
315   @param[in]   SendChunkProcess   Pointer to current chunk process status.
316   @param[out]  RequestMessage     Request to send.
317 
318   @retval EFI_SUCCESS             Successfully to send chunk data according to SendChunkProcess.
319   @retval Other                   Other errors.
320 
321 **/
322 EFI_STATUS
323 HttpIoSendChunkedTransfer (
324   IN  HTTP_IO                    *HttpIo,
325   IN  HTTP_IO_SEND_CHUNK_PROCESS *SendChunkProcess,
326   IN  EFI_HTTP_MESSAGE           *RequestMessage
327 );
328 #endif
329