VLC 4.0.0-dev
Loading...
Searching...
No Matches
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
31struct 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 */
45struct vlc_http_msg *
46vlc_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 */
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 */
74int 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 */
85char *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 */
92int 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 */
99const char *vlc_http_msg_get_agent(const struct vlc_http_msg *);
100
101/**
102 * Parses a timestamp header field.
103 *
104w* @param msg the response to get the timestamp header from
105 * @param name header field name
106 * @return a timestamp value, or -1 on error.
107 */
108time_t vlc_http_msg_get_time(const struct vlc_http_msg *msg, const char *name);
109
110/**
111 * Parses an HTTP-date string.
112 *
113 * Accepts the three formats defined by RFC 7231 §7.1.1.1 (IMF-fixdate,
114 * obsolete RFC 850, and ANSI C asctime()).
115 *
116 * @param str NULL-terminated date string
117 * @return a timestamp value, or -1 on error.
118 */
119time_t vlc_http_mktime(const char *str);
120
121/**
122 * Adds a timestamp header field.
123 *
124 * @param msg the request to add the header to
125 * @param name header field name
126 * @param t pointer to timestamp
127 * @return 0 on success, -1 on error (errno is set accordingly)
128 */
129int vlc_http_msg_add_time(struct vlc_http_msg *msg, const char *name,
130 const time_t *t);
131
132/**
133 * Adds a Date header field.
134 */
136
137/**
138 * Gets message date.
139 *
140 * Extracts the original date of the message from the HTTP Date header.
141 *
142 * @return a time value on success, -1 on error.
143 */
144time_t vlc_http_msg_get_atime(const struct vlc_http_msg *);
145
146/**
147 * Gets resource date.
148 *
149 * Extracts the last modification date of the message content from the HTTP
150 * Last-Modified header.
151 *
152 * @return a time value on success, -1 on error.
153 */
154time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *);
155
156/**
157 * Gets retry timeout.
158 *
159 * Extracts the time (in seconds) until the expiration of the "retry-after"
160 * time-out in the HTTP message. If the header value is an absolute date, it
161 * is converted relative to the current time.
162 *
163 * @return the time in seconds, zero if the date is overdue or on error.
164 */
165unsigned vlc_http_msg_get_retry_after(const struct vlc_http_msg *);
166
167void vlc_http_msg_get_cookies(const struct vlc_http_msg *,
168 struct vlc_http_cookie_jar_t *,
169 const char *host, const char *path);
171 struct vlc_http_cookie_jar_t *);
172
173char *vlc_http_msg_get_basic_realm(const struct vlc_http_msg *);
174
175/**
176 * Adds Basic credentials.
177 *
178 * Formats a plain username and password pair using HTTP Basic (RFC7617)
179 * syntax.
180 *
181 * @param msg the request to add the credentials to
182 * @param proxy true for proxy authentication,
183 * false for origin server authentication
184 * @param username null-terminated username
185 * @param password null-terminated password
186 * @return 0 on success, -1 on out-of-memory (ENOMEM) or if username or
187 * password are invalid (EINVAL).
188 */
189int vlc_http_msg_add_creds_basic(struct vlc_http_msg *msg, bool proxy,
190 const char *username, const char *password);
191
192
193/**
194 * Looks up an header field.
195 *
196 * Finds an HTTP header field by (case-insensitive) name inside an HTTP
197 * message header. If the message has more than one matching field, their value
198 * are folded (as permitted by protocol specifications).
199 *
200 * @return header field value (valid until message is destroyed),
201 * or NULL if no fields matched
202 */
203const char *vlc_http_msg_get_header(const struct vlc_http_msg *,
204 const char *name);
205
206/**
207 * Gets response status code.
208 *
209 * @return status code (e.g. 404), or negative if request
210 */
211int vlc_http_msg_get_status(const struct vlc_http_msg *m);
212
213/**
214 * Gets request method.
215 *
216 * @return request method (e.g. "GET"), or NULL if response
217 */
218const char *vlc_http_msg_get_method(const struct vlc_http_msg *);
219
220/**
221 * Gets request scheme.
222 *
223 * @return request scheme (e.g. "https"), or NULL if absent
224 */
225const char *vlc_http_msg_get_scheme(const struct vlc_http_msg *);
226
227/**
228 * Gets request authority.
229 *
230 * @return request authority (e.g. "www.example.com:8080"),
231 * or NULL if response
232 */
233const char *vlc_http_msg_get_authority(const struct vlc_http_msg *);
234
235/**
236 * Gets request absolute path.
237 *
238 * @return request absolute path (e.g. "/index.html"), or NULL if absent
239 */
240const char *vlc_http_msg_get_path(const struct vlc_http_msg *);
241
242/**
243 * Looks up a token in a header field.
244 *
245 * Finds the first occurrence of a token within a HTTP field header.
246 *
247 * @param msg the request to get the token from
248 * @param field HTTP header field name
249 * @param token HTTP token name
250 * @return the first byte of the token if found, NULL if not found.
251 */
252const char *vlc_http_msg_get_token(const struct vlc_http_msg *msg,
253 const char *field, const char *token);
254
255/**
256 * Finds next token.
257 *
258 * Finds the following token in a HTTP header field value.
259 *
260 * @return First character of the following token,
261 * or NULL if there are no further tokens
262 */
263const char *vlc_http_next_token(const char *);
264
265/**
266 * Gets HTTP payload length.
267 *
268 * Determines the total length (in bytes) of the payload associated with the
269 * HTTP message.
270 *
271 * @return byte length, or (uintmax_t)-1 if unknown.
272 */
273uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *);
274
275/**
276 * Gets next response headers.
277 *
278 * Discards the current response headers and gets the next set of response
279 * headers for the same request. This is intended for HTTP 1xx continuation
280 * responses and for message trailers.
281 *
282 * @param m current response headers (destroyed by the call)
283 *
284 * @return next response headers or NULL on error
285 */
287
288/**
289 * Gets final response headers.
290 *
291 * Skips HTTP 1xx continue headers until a final set of response headers is
292 * received. This is a convenience wrapper around vlc_http_msg_iterate() for
293 * use when continuation headers are not useful (e.g. GET or CONNECT).
294 *
295 * @param m current response headers or NULL
296 *
297 * @return the final response headers (m if it was already final),
298 * NULL if the parameter was NULL, or NULL on error
299 */
301
302/**
303 * Receives HTTP data.
304 *
305 * Dequeues the next block of data from an HTTP message. If no pending data has
306 * been received, waits until data is received, the stream ends or the
307 * underlying connection fails.
308 *
309 * @return data block
310 * @retval NULL on end-of-stream
311 * @retval vlc_http_error on fatal error
312 */
314
315/**
316 * Sends HTTP data.
317 *
318 * Queues the next block of data for an HTTP message payload.
319 *
320 * @note This function takes ownership of the passed data block(s).
321 *
322 * @param msg the request to append the data block to
323 * @param b chain of block of data to be sent
324 * @param eos true to indicate the end of the payload
325 * @retval 0 success
326 * @retval -1 fatal error
327 */
328int vlc_http_msg_write(struct vlc_http_msg *msg, block_t *b, bool eos);
329
330/** @} */
331
332/**
333 * \defgroup http_stream Streams
334 * \ingroup http_connmgr
335 *
336 * HTTP request/response streams
337 *
338 * A stream is initiated by a client-side request header. It includes a
339 * final response header, possibly preceded by one or more continuation
340 * response headers. After the response header, a stream usually carries
341 * a response payload.
342 *
343 * A stream may also carry a request payload (this is not supported so far).
344 *
345 * The HTTP stream constitutes the interface between an HTTP connection and
346 * the higher-level HTTP messages layer.
347 * @{
348 */
349
350struct vlc_http_stream;
351
352/**
353 * Error pointer value
354 *
355 * This is an error value for some HTTP functions that can return NULL in
356 * non-error circumstances. Another return value is necessary to express
357 * error/failure, which this is.
358 * This compares different to NULL and to any valid pointer.
359 *
360 * @warning Dereferencing this pointer is undefined.
361 */
362extern void *const vlc_http_error;
363
364void vlc_http_msg_attach(struct vlc_http_msg *m, struct vlc_http_stream *s);
367
368/** HTTP stream callbacks
369 *
370 * Connection-specific callbacks for stream manipulation
371 */
373{
374 struct vlc_http_msg *(*read_headers)(struct vlc_http_stream *);
375 ssize_t (*write)(struct vlc_http_stream *, const void *, size_t, bool eos);
376 block_t *(*read)(struct vlc_http_stream *);
377 void (*close)(struct vlc_http_stream *, bool abort);
378};
379
380/** HTTP stream */
382{
384};
385
386/**
387 * Reads one message header.
388 *
389 * Reads the next message header of an HTTP stream from the network.
390 * There is always exactly one request header per stream. There is usually
391 * one response header per stream, except for continuation (1xx) headers.
392 *
393 * @warning The caller is responsible for reading headers at appropriate
394 * times as intended by the protocol. Failure to do so may result in protocol
395 * dead lock, and/or (HTTP 1.x) connection failure.
396 *
397 * @param s HTTP stream to read from
398 *
399 */
400static inline
402{
403 return s->cbs->read_headers(s);
404}
405
406/**
407 * Write message payload data.
408 *
409 * Writes data as message payload of an HTTP stream.
410 *
411 * @todo Take a block structure rather than a byte array.
412 *
413 * @param s HTTP stream to write to
414 * @param base start address of data to write
415 * @param length length in bytes of data to write
416 * @param eos whether this is the last write on the stream
417 * @retval len success
418 * @retval -1 error
419 */
420static inline ssize_t vlc_http_stream_write(struct vlc_http_stream *s,
421 const void *base, size_t length,
422 bool eos)
423{
424 return s->cbs->write(s, base, length, eos);
425}
426
427/**
428 * Reads message payload data.
429 *
430 * Reads the next block of data from the message payload of an HTTP stream.
431 *
432 * @param s HTTP stream to read from
433 * @return a block of data (use block_Release() to free it)
434 * @retval NULL The end of the stream was reached.
435 * @retval vlc_http_error The stream encountered a fatal error.
436 */
438{
439 return s->cbs->read(s);
440}
441
442/**
443 * Closes an HTTP stream.
444 *
445 * Releases all resources associated or held by an HTTP stream. Any unread
446 * header or data is discarded.
447 *
448 * @param s HTTP stream to close
449 * @param abort whether to close the connection and prevent re-use
450 */
451static inline void vlc_http_stream_close(struct vlc_http_stream *s, bool abort)
452{
453 s->cbs->close(s, abort);
454}
455
456/** @} */
457
458/**
459 * Formats an HTTP 1.1 message header.
460 *
461 * Formats an message header in HTTP 1.x format, using HTTP version 1.1.
462 *
463 * @param m message to format/serialize
464 * @param lenp location to write the length of the formatted message in bytes
465 * [OUT]
466 * @param proxied whether the message is meant for sending to a proxy rather
467 * than an origin (only relevant for requests)
468 * @param chunked whether to append a chunked transfer encoding header line
469 * @return A heap-allocated nul-terminated string or *lenp bytes,
470 * or NULL on error
471 */
472char *vlc_http_msg_format(const struct vlc_http_msg *m, size_t *restrict lenp,
473 bool proxied, bool chunked) VLC_USED VLC_MALLOC;
474
475/**
476 * Parses an HTTP 1.1 message header.
477 */
478struct vlc_http_msg *vlc_http_msg_headers(const char *msg) VLC_USED;
479
480struct vlc_h2_frame;
481
482/**
483 * Formats an HTTP 2.0 HEADER frame.
484 */
485struct vlc_h2_frame *vlc_http_msg_h2_frame(const struct vlc_http_msg *m,
486 uint_fast32_t stream_id, bool eos);
487
488/**
489 * Parses an HTTP 2.0 header table.
490 */
492 const char *const headers[][2]);
size_t count
Definition core.c:403
#define VLC_USED
Definition fourcc_gen.c:32
#define VLC_MALLOC
Definition vlc_common.h:157
#define VLC_FORMAT(x, y)
String format function annotation.
Definition vlc_common.h:193
const char * vlc_http_msg_get_header(const struct vlc_http_msg *m, const char *name)
Looks up an header field.
Definition message.c:156
time_t vlc_http_mktime(const char *str)
Parses an HTTP-date string.
Definition message.c:834
void vlc_http_msg_get_cookies(const struct vlc_http_msg *m, vlc_http_cookie_jar_t *jar, const char *host, const char *path)
Definition message.c:934
struct vlc_http_msg * vlc_http_msg_get_final(struct vlc_http_msg *m)
Gets final response headers.
Definition message.c:284
int vlc_http_msg_add_time(struct vlc_http_msg *m, const char *hname, const time_t *t)
Adds a timestamp header field.
Definition message.c:811
time_t vlc_http_msg_get_atime(const struct vlc_http_msg *m)
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.
char * vlc_http_authority(const char *host, unsigned port)
Formats an authority.
Definition message.c:573
const char * vlc_http_msg_get_method(const struct vlc_http_msg *m)
Gets request method.
Definition message.c:173
block_t * vlc_http_msg_read(struct vlc_http_msg *m)
Receives HTTP data.
Definition message.c:291
void vlc_http_msg_destroy(struct vlc_http_msg *)
Destroys an HTTP message.
Definition message.c:193
const char * vlc_http_msg_get_scheme(const struct vlc_http_msg *m)
Gets request scheme.
Definition message.c:178
int vlc_http_msg_add_agent(struct vlc_http_msg *m, const char *str)
Sets the agent field.
Definition message.c:783
time_t vlc_http_msg_get_mtime(const struct vlc_http_msg *m)
Gets resource date.
Definition message.c:877
const char * vlc_http_msg_get_agent(const struct vlc_http_msg *m)
Gets the agent field.
Definition message.c:795
const char * vlc_http_msg_get_authority(const struct vlc_http_msg *m)
Gets request authority.
Definition message.c:183
const char * vlc_http_msg_get_path(const struct vlc_http_msg *m)
Gets request absolute path.
Definition message.c:188
const char * vlc_http_msg_get_token(const struct vlc_http_msg *msg, const char *field, const char *token)
Looks up a token in a header field.
Definition message.c:709
int vlc_http_msg_write(struct vlc_http_msg *m, block_t *block, bool eos)
Sends HTTP data.
Definition message.c:299
uintmax_t vlc_http_msg_get_size(const struct vlc_http_msg *m)
Gets HTTP payload length.
Definition message.c:905
const char * vlc_http_next_token(const char *value)
Finds next token.
Definition message.c:642
unsigned vlc_http_msg_get_retry_after(const struct vlc_http_msg *m)
Gets retry timeout.
Definition message.c:882
struct vlc_http_msg * vlc_http_msg_iterate(struct vlc_http_msg *m)
Gets next response headers.
Definition message.c:265
int vlc_http_msg_add_creds_basic(struct vlc_http_msg *m, bool proxy, const char *username, const char *password)
Adds Basic credentials.
Definition message.c:1005
int vlc_http_msg_add_atime(struct vlc_http_msg *m)
Adds a Date header field.
Definition message.c:826
int vlc_http_msg_add_cookies(struct vlc_http_msg *m, vlc_http_cookie_jar_t *jar)
Definition message.c:946
int vlc_http_msg_get_status(const struct vlc_http_msg *m)
Gets response status code.
Definition message.c:168
time_t vlc_http_msg_get_time(const struct vlc_http_msg *m, const char *name)
Parses a timestamp header field.
Definition message.c:864
char * vlc_http_msg_get_basic_realm(const struct vlc_http_msg *m)
Definition message.c:987
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
struct vlc_http_msg * vlc_http_resp_create(unsigned status) VLC_USED
Creates an HTTP response.
Definition message.c:241
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:451
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:420
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:437
struct vlc_http_msg * vlc_http_msg_get_initial(struct vlc_http_stream *s)
Definition message.c:276
static struct vlc_http_msg * vlc_http_stream_read_headers(struct vlc_http_stream *s)
Reads one message header.
Definition message.h:401
const char name[16]
Definition httpd.c:1298
struct vlc_http_msg * vlc_http_msg_headers(const char *msg) VLC_USED
Parses an HTTP 1.1 message header.
Definition message.c:366
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
char * vlc_http_msg_format(const struct vlc_http_msg *m, size_t *restrict lenp, bool proxied, bool chunked) VLC_USED VLC_MALLOC
Formats an HTTP 1.1 message header.
Definition message.c:331
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
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:373
struct vlc_http_msg *(* read_headers)(struct vlc_http_stream *)
Definition message.h:374
block_t *(* read)(struct vlc_http_stream *)
Definition message.h:376
ssize_t(* write)(struct vlc_http_stream *, const void *, size_t, bool eos)
Definition message.h:375
void(* close)(struct vlc_http_stream *, bool abort)
Definition message.h:377
HTTP stream.
Definition message.h:382
const struct vlc_http_stream_cbs * cbs
Definition message.h:383
struct vlc_frame_t block_t
Definition vlc_common.h:447