VLC  4.0.0-dev
message.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * message.h: HTTP request/response
3  *****************************************************************************
4  * Copyright (C) 2015 RĂ©mi Denis-Courmont
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20 
21 #include <stdint.h>
22 
23 /**
24  * \defgroup http_msg Messages
25  * HTTP messages, header formatting and parsing
26  * \ingroup http
27  * @{
28  * \file message.h
29  */
30 
31 struct vlc_http_msg;
33 
34 /**
35  * Creates an HTTP request.
36  *
37  * Allocates an HTTP request message.
38  *
39  * @param method request method (e.g. "GET")
40  * @param scheme protocol scheme (e.g. "https")
41  * @param authority target host (e.g. "www.example.com:8080")
42  * @param path request path (e.g. "/dir/page.html")
43  * @return an HTTP stream or NULL on allocation failure
44  */
45 struct vlc_http_msg *
46 vlc_http_req_create(const char *method, const char *scheme,
47  const char *authority, const char *path) VLC_USED;
48 
49 /**
50  * Creates an HTTP response.
51  *
52  * Allocates an HTTP response message.
53  *
54  * @param status HTTP status code
55  * @return an HTTP stream or NULL on allocation failure
56  */
58 
59 /**
60  * Destroys an HTTP message.
61  */
62 void vlc_http_msg_destroy(struct vlc_http_msg *);
63 
64 /**
65  * Formats a header field.
66  *
67  * Adds an HTTP message header to an HTTP request or response.
68  * All headers must be formatted before the message is sent.
69  *
70  * @param name header field name
71  * @param fmt printf-style format string
72  * @return 0 on success, -1 on error (out of memory)
73  */
74 int vlc_http_msg_add_header(struct vlc_http_msg *, const char *name,
75  const char *fmt, ...) VLC_FORMAT(3,4);
76 
77 /**
78  * Formats an authority.
79  *
80  * @param host host name (cannot be NULL)
81  * @param port port number (0 for unspecified)
82  * @return the formatted authority as a heap-allocated nul-terminated string,
83  * or NULL on allocation failure
84  */
85 char *vlc_http_authority(const char *host, unsigned port);
86 
87 /**
88  * Sets the agent field.
89  *
90  * Sets the User-Agent or Server header field.
91  */
92 int vlc_http_msg_add_agent(struct vlc_http_msg *, const char *);
93 
94 /**
95  * Gets the agent field.
96  *
97  * Gets the User-Agent or Server header field.
98  */
99 const char *vlc_http_msg_get_agent(const struct vlc_http_msg *);
100 
101 /**
102  * Parses a timestamp header field.
103  *
104  * @param name header field name
105  * @return a timestamp value, or -1 on error.
106  */
107 time_t vlc_http_msg_get_time(const struct vlc_http_msg *, const char *name);
108 
109 /**
110  * Adds a timestamp header field.
111  *
112  * @param name header field name
113  * @param t pointer to timestamp
114  * @return 0 on success, -1 on error (errno is set accordingly)
115  */
116 int vlc_http_msg_add_time(struct vlc_http_msg *, const char *name,
117  const time_t *t);
118 
119 /**
120  * Adds a Date header field.
121  */
123 
124 /**
125  * Gets message date.
126  *
127  * Extracts the original date of the message from the HTTP Date header.
128  *
129  * @return a time value on success, -1 on error.
130  */
131 time_t vlc_http_msg_get_atime(const struct vlc_http_msg *);
132 
133 /**
134  * Gets resource date.
135  *
136  * Extracts the last modification date of the message content from the HTTP
137  * Last-Modified header.
138  *
139  * @return a time value on success, -1 on error.
140  */
141 time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *);
142 
143 /**
144  * Gets retry timeout.
145  *
146  * Extracts the time (in seconds) until the expiration of the "retry-after"
147  * time-out in the HTTP message. If the header value is an absolute date, it
148  * is converted relative to the current time.
149  *
150  * @return the time in seconds, zero if the date is overdue or on error.
151  */
152 unsigned vlc_http_msg_get_retry_after(const struct vlc_http_msg *);
153 
154 void vlc_http_msg_get_cookies(const struct vlc_http_msg *,
155  struct vlc_http_cookie_jar_t *,
156  const char *host, const char *path);
158  struct vlc_http_cookie_jar_t *);
159 
160 char *vlc_http_msg_get_basic_realm(const struct vlc_http_msg *);
161 
162 /**
163  * Adds Basic credentials.
164  *
165  * Formats a plain username and password pair using HTTP Basic (RFC7617)
166  * syntax.
167  *
168  * @param proxy true for proxy authentication,
169  * false for origin server authentication
170  * @param username null-terminated username
171  * @param password null-terminated password
172  * @return 0 on success, -1 on out-of-memory (ENOMEM) or if username or
173  * password are invalid (EINVAL).
174  */
175 int vlc_http_msg_add_creds_basic(struct vlc_http_msg *, bool proxy,
176  const char *username, const char *password);
177 
178 
179 /**
180  * Looks up an header field.
181  *
182  * Finds an HTTP header field by (case-insensitive) name inside an HTTP
183  * message header. If the message has more than one matching field, their value
184  * are folded (as permitted by protocol specifications).
185  *
186  * @return header field value (valid until message is destroyed),
187  * or NULL if no fields matched
188  */
189 const char *vlc_http_msg_get_header(const struct vlc_http_msg *,
190  const char *name);
191 
192 /**
193  * Gets response status code.
194  *
195  * @return status code (e.g. 404), or negative if request
196  */
197 int vlc_http_msg_get_status(const struct vlc_http_msg *m);
198 
199 /**
200  * Gets request method.
201  *
202  * @return request method (e.g. "GET"), or NULL if response
203  */
204 const char *vlc_http_msg_get_method(const struct vlc_http_msg *);
205 
206 /**
207  * Gets request scheme.
208  *
209  * @return request scheme (e.g. "https"), or NULL if absent
210  */
211 const char *vlc_http_msg_get_scheme(const struct vlc_http_msg *);
212 
213 /**
214  * Gets request authority.
215  *
216  * @return request authority (e.g. "www.example.com:8080"),
217  * or NULL if response
218  */
219 const char *vlc_http_msg_get_authority(const struct vlc_http_msg *);
220 
221 /**
222  * Gets request absolute path.
223  *
224  * @return request absolute path (e.g. "/index.html"), or NULL if absent
225  */
226 const char *vlc_http_msg_get_path(const struct vlc_http_msg *);
227 
228 /**
229  * Looks up a token in a header field.
230  *
231  * Finds the first occurrence of a token within a HTTP field header.
232  *
233  * @param field HTTP header field name
234  * @param token HTTP token name
235  * @return the first byte of the token if found, NULL if not found.
236  */
237 const char *vlc_http_msg_get_token(const struct vlc_http_msg *,
238  const char *field, const char *token);
239 
240 /**
241  * Finds next token.
242  *
243  * Finds the following token in a HTTP header field value.
244  *
245  * @return First character of the following token,
246  * or NULL if there are no further tokens
247  */
248 const char *vlc_http_next_token(const char *);
249 
250 /**
251  * Gets HTTP payload length.
252  *
253  * Determines the total length (in bytes) of the payload associated with the
254  * HTTP message.
255  *
256  * @return byte length, or (uintmax_t)-1 if unknown.
257  */
258 uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *);
259 
260 /**
261  * Gets next response headers.
262  *
263  * Discards the current response headers and gets the next set of response
264  * headers for the same request. This is intended for HTTP 1xx continuation
265  * responses and for message trailers.
266  *
267  * @param m current response headers (destroyed by the call)
268  *
269  * @return next response headers or NULL on error
270  */
272 
273 /**
274  * Gets final response headers.
275  *
276  * Skips HTTP 1xx continue headers until a final set of response headers is
277  * received. This is a convenience wrapper around vlc_http_msg_iterate() for
278  * use when continuation headers are not useful (e.g. GET or CONNECT).
279  *
280  * @param m current response headers or NULL
281  *
282  * @return the final response headers (m if it was already final),
283  * NULL if the parameter was NULL, or NULL on error
284  */
286 
287 /**
288  * Receives HTTP data.
289  *
290  * Dequeues the next block of data from an HTTP message. If no pending data has
291  * been received, waits until data is received, the stream ends or the
292  * underlying connection fails.
293  *
294  * @return data block
295  * @retval NULL on end-of-stream
296  * @retval vlc_http_error on fatal error
297  */
299 
300 /**
301  * Sends HTTP data.
302  *
303  * Queues the next block of data for an HTTP message payload.
304  *
305  * @note This function takes ownership of the passed data block(s).
306  *
307  * @param b chain of block of data to be sent
308  * @param eos true to indicate the end of the payload
309  * @retval 0 success
310  * @retval -1 fatal error
311  */
312 int vlc_http_msg_write(struct vlc_http_msg *, block_t *b, bool eos);
313 
314 /** @} */
315 
316 /**
317  * \defgroup http_stream Streams
318  * \ingroup http_connmgr
319  *
320  * HTTP request/response streams
321  *
322  * A stream is initiated by a client-side request header. It includes a
323  * final response header, possibly preceded by one or more continuation
324  * response headers. After the response header, a stream usually carries
325  * a response payload.
326  *
327  * A stream may also carry a request payload (this is not supported so far).
328  *
329  * The HTTP stream constitutes the interface between an HTTP connection and
330  * the higher-level HTTP messages layer.
331  * @{
332  */
333 
334 struct vlc_http_stream;
335 
336 /**
337  * Error pointer value
338  *
339  * This is an error value for some HTTP functions that can return NULL in
340  * non-error circumstances. Another return value is necessary to express
341  * error/failure, which this is.
342  * This compares different to NULL and to any valid pointer.
343  *
344  * @warning Dereferencing this pointer is undefined.
345  */
346 extern void *const vlc_http_error;
347 
348 void vlc_http_msg_attach(struct vlc_http_msg *m, struct vlc_http_stream *s);
350 VLC_USED;
351 
352 /** HTTP stream callbacks
353  *
354  * Connection-specific callbacks for stream manipulation
355  */
357 {
358  struct vlc_http_msg *(*read_headers)(struct vlc_http_stream *);
359  ssize_t (*write)(struct vlc_http_stream *, const void *, size_t, bool eos);
360  block_t *(*read)(struct vlc_http_stream *);
361  void (*close)(struct vlc_http_stream *, bool abort);
362 };
363 
364 /** HTTP stream */
366 {
367  const struct vlc_http_stream_cbs *cbs;
368 };
369 
370 /**
371  * Reads one message header.
372  *
373  * Reads the next message header of an HTTP stream from the network.
374  * There is always exactly one request header per stream. There is usually
375  * one response header per stream, except for continuation (1xx) headers.
376  *
377  * @warning The caller is responsible for reading headers at appropriate
378  * times as intended by the protocol. Failure to do so may result in protocol
379  * dead lock, and/or (HTTP 1.x) connection failure.
380  */
381 static inline
383 {
384  return s->cbs->read_headers(s);
385 }
386 
387 /**
388  * Write message payload data.
389  *
390  * Writes data as message payload of an HTTP stream.
391  *
392  * @todo Take a block structure rather than a byte array.
393  *
394  * @param base start address of data to write
395  * @param length length in bytes of data to write
396  * @param eos whether this is the last write on the stream
397  * @retval len success
398  * @retval -1 error
399  */
400 static inline ssize_t vlc_http_stream_write(struct vlc_http_stream *s,
401  const void *base, size_t length,
402  bool eos)
403 {
404  return s->cbs->write(s, base, length, eos);
405 }
406 
407 /**
408  * Reads message payload data.
409  *
410  * Reads the next block of data from the message payload of an HTTP stream.
411  *
412  * @return a block of data (use block_Release() to free it)
413  * @retval NULL The end of the stream was reached.
414  * @retval vlc_http_error The stream encountered a fatal error.
415  */
417 {
418  return s->cbs->read(s);
419 }
420 
421 /**
422  * Closes an HTTP stream.
423  *
424  * Releases all resources associated or held by an HTTP stream. Any unread
425  * header or data is discarded.
426  */
427 static inline void vlc_http_stream_close(struct vlc_http_stream *s, bool abort)
428 {
429  s->cbs->close(s, abort);
430 }
431 
432 /** @} */
433 
434 /**
435  * Formats an HTTP 1.1 message header.
436  *
437  * Formats an message header in HTTP 1.x format, using HTTP version 1.1.
438  *
439  * @param m message to format/serialize
440  * @param lenp location to write the length of the formatted message in bytes
441  * [OUT]
442  * @param proxied whether the message is meant for sending to a proxy rather
443  * than an origin (only relevant for requests)
444  * @param chunked whether to append a chunked transfer encoding header line
445  * @return A heap-allocated nul-terminated string or *lenp bytes,
446  * or NULL on error
447  */
448 char *vlc_http_msg_format(const struct vlc_http_msg *m, size_t *restrict lenp,
449  bool proxied, bool chunked) VLC_USED;
450 
451 /**
452  * Parses an HTTP 1.1 message header.
453  */
454 struct vlc_http_msg *vlc_http_msg_headers(const char *msg) VLC_USED;
455 
456 struct vlc_h2_frame;
457 
458 /**
459  * Formats an HTTP 2.0 HEADER frame.
460  */
461 struct vlc_h2_frame *vlc_http_msg_h2_frame(const struct vlc_http_msg *m,
462  uint_fast32_t stream_id, bool eos);
463 
464 /**
465  * Parses an HTTP 2.0 header table.
466  */
468  const char *const headers[][2]);
size_t count
Definition: core.c:397
#define VLC_USED
Definition: fourcc_gen.c:32
#define VLC_FORMAT(x, y)
String format function annotation.
Definition: vlc_common.h:142
const char * vlc_http_msg_get_token(const struct vlc_http_msg *, const char *field, const char *token)
Looks up a token in a header field.
Definition: message.c:709
void vlc_http_msg_get_cookies(const struct vlc_http_msg *, struct vlc_http_cookie_jar_t *, const char *host, const char *path)
Definition: message.c:934
int vlc_http_msg_add_creds_basic(struct vlc_http_msg *, bool proxy, const char *username, const char *password)
Adds Basic credentials.
Definition: message.c:1005
time_t vlc_http_msg_get_atime(const struct vlc_http_msg *)
Gets message date.
Definition: message.c:872
int vlc_http_msg_add_header(struct vlc_http_msg *, const char *name, const char *fmt,...) VLC_FORMAT(3
Formats a header field.
const char * vlc_http_msg_get_path(const struct vlc_http_msg *)
Gets request absolute path.
Definition: message.c:188
const char * vlc_http_msg_get_method(const struct vlc_http_msg *)
Gets request method.
Definition: message.c:173
char * vlc_http_msg_get_basic_realm(const struct vlc_http_msg *)
Definition: message.c:987
void vlc_http_msg_destroy(struct vlc_http_msg *)
Destroys an HTTP message.
Definition: message.c:193
const char * vlc_http_msg_get_agent(const struct vlc_http_msg *)
Gets the agent field.
Definition: message.c:795
struct vlc_http_msg * vlc_http_msg_get_final(struct vlc_http_msg *) VLC_USED
Gets final response headers.
Definition: message.c:284
int char * vlc_http_authority(const char *host, unsigned port)
Formats an authority.
Definition: message.c:573
const char * vlc_http_msg_get_header(const struct vlc_http_msg *, const char *name)
Looks up an header field.
Definition: message.c:156
int vlc_http_msg_add_agent(struct vlc_http_msg *, const char *)
Sets the agent field.
Definition: message.c:783
int vlc_http_msg_write(struct vlc_http_msg *, block_t *b, bool eos)
Sends HTTP data.
Definition: message.c:299
time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *)
Gets resource date.
Definition: message.c:877
struct vlc_http_msg * vlc_http_msg_iterate(struct vlc_http_msg *) VLC_USED
Gets next response headers.
Definition: message.c:265
struct vlc_http_msg * vlc_http_resp_create(unsigned status) VLC_USED
Creates an HTTP response.
Definition: message.c:241
time_t vlc_http_msg_get_time(const struct vlc_http_msg *, const char *name)
Parses a timestamp header field.
Definition: message.c:864
uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *)
Gets HTTP payload length.
Definition: message.c:905
unsigned vlc_http_msg_get_retry_after(const struct vlc_http_msg *)
Gets retry timeout.
Definition: message.c:882
int vlc_http_msg_add_time(struct vlc_http_msg *, const char *name, const time_t *t)
Adds a timestamp header field.
Definition: message.c:811
int vlc_http_msg_add_atime(struct vlc_http_msg *)
Adds a Date header field.
Definition: message.c:826
int vlc_http_msg_add_cookies(struct vlc_http_msg *, struct vlc_http_cookie_jar_t *)
Definition: message.c:946
const char * vlc_http_next_token(const char *)
Finds next token.
Definition: message.c:642
const char * vlc_http_msg_get_authority(const struct vlc_http_msg *)
Gets request authority.
Definition: message.c:183
int vlc_http_msg_get_status(const struct vlc_http_msg *m)
Gets response status code.
Definition: message.c:168
block_t * vlc_http_msg_read(struct vlc_http_msg *) VLC_USED
Receives HTTP data.
Definition: message.c:291
struct vlc_http_msg * vlc_http_req_create(const char *method, const char *scheme, const char *authority, const char *path) VLC_USED
Creates an HTTP request.
Definition: message.c:213
const char * vlc_http_msg_get_scheme(const struct vlc_http_msg *)
Gets request scheme.
Definition: message.c:178
static struct vlc_http_msg * vlc_http_stream_read_headers(struct vlc_http_stream *s)
Reads one message header.
Definition: message.h:382
void vlc_http_msg_attach(struct vlc_http_msg *m, struct vlc_http_stream *s)
Definition: message.c:259
static void vlc_http_stream_close(struct vlc_http_stream *s, bool abort)
Closes an HTTP stream.
Definition: message.h:427
struct vlc_http_msg * vlc_http_msg_get_initial(struct vlc_http_stream *s) VLC_USED
Definition: message.c:276
static ssize_t vlc_http_stream_write(struct vlc_http_stream *s, const void *base, size_t length, bool eos)
Write message payload data.
Definition: message.h:400
void *const vlc_http_error
Error pointer value.
Definition: message.c:57
static block_t * vlc_http_stream_read(struct vlc_http_stream *s)
Reads message payload data.
Definition: message.h:416
const char name[16]
Definition: httpd.c:1268
struct vlc_http_msg * vlc_http_msg_h2_headers(unsigned count, const char *const headers[][2])
Parses an HTTP 2.0 header table.
Definition: message.c:487
struct vlc_h2_frame * vlc_http_msg_h2_frame(const struct vlc_http_msg *m, uint_fast32_t stream_id, bool eos)
Formats an HTTP 2.0 HEADER frame.
Definition: message.c:425
struct vlc_http_msg * vlc_http_msg_headers(const char *msg) VLC_USED
Parses an HTTP 1.1 message header.
Definition: message.c:366
char * vlc_http_msg_format(const struct vlc_http_msg *m, size_t *restrict lenp, bool proxied, bool chunked) VLC_USED
Formats an HTTP 1.1 message header.
Definition: message.c:331
Definition: vlc_frame.h:123
Definition: h2frame.h:31
Definition: message.c:43
char * path
Definition: message.c:48
char * scheme
Definition: message.c:46
char *(* headers)[2]
Definition: message.c:49
short status
Definition: message.c:44
char * method
Definition: message.c:45
char * authority
Definition: message.c:47
HTTP stream callbacks.
Definition: message.h:357
struct vlc_http_msg *(* read_headers)(struct vlc_http_stream *)
Definition: message.h:358
ssize_t(* write)(struct vlc_http_stream *, const void *, size_t, bool eos)
Definition: message.h:359
block_t *(* read)(struct vlc_http_stream *)
Definition: message.h:360
void(* close)(struct vlc_http_stream *, bool abort)
Definition: message.h:361
HTTP stream.
Definition: message.h:366
const struct vlc_http_stream_cbs * cbs
Definition: message.h:367