1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25/* minimal space for typical headers and CSP stuff */
26
27#define LWS_RECOMMENDED_MIN_HEADER_SPACE 2048
28
29/*! \defgroup http HTTP
30
31 Modules related to handling HTTP
32*/
33//@{
34
35/*! \defgroup httpft HTTP File transfer
36 * \ingroup http
37
38 APIs for sending local files in response to HTTP requests
39*/
40//@{
41
42/**
43 * lws_get_mimetype() - Determine mimetype to use from filename
44 *
45 * \param file: filename
46 * \param m: NULL, or mount context
47 *
48 * This uses a canned list of known filetypes first, if no match and m is
49 * non-NULL, then tries a list of per-mount file suffix to mimtype mappings.
50 *
51 * Returns either NULL or a pointer to the mimetype matching the file.
52 */
53LWS_VISIBLE LWS_EXTERN const char *
54lws_get_mimetype(const char *file, const struct lws_http_mount *m);
55
56/**
57 * lws_serve_http_file() - Send a file back to the client using http
58 * \param wsi: Websocket instance (available from user callback)
59 * \param file: The file to issue over http
60 * \param content_type: The http content type, eg, text/html
61 * \param other_headers: NULL or pointer to header string
62 * \param other_headers_len: length of the other headers if non-NULL
63 *
64 * This function is intended to be called from the callback in response
65 * to http requests from the client. It allows the callback to issue
66 * local files down the http link in a single step.
67 *
68 * Returning <0 indicates error and the wsi should be closed. Returning
69 * >0 indicates the file was completely sent and
70 * lws_http_transaction_completed() called on the wsi (and close if != 0)
71 * ==0 indicates the file transfer is started and needs more service later,
72 * the wsi should be left alone.
73 */
74LWS_VISIBLE LWS_EXTERN int
75lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
76 const char *other_headers, int other_headers_len);
77
78LWS_VISIBLE LWS_EXTERN int
79lws_serve_http_file_fragment(struct lws *wsi);
80//@}
81
82
83enum http_status {
84 HTTP_STATUS_CONTINUE = 100,
85
86 HTTP_STATUS_OK = 200,
87 HTTP_STATUS_NO_CONTENT = 204,
88 HTTP_STATUS_PARTIAL_CONTENT = 206,
89
90 HTTP_STATUS_MOVED_PERMANENTLY = 301,
91 HTTP_STATUS_FOUND = 302,
92 HTTP_STATUS_SEE_OTHER = 303,
93 HTTP_STATUS_NOT_MODIFIED = 304,
94
95 HTTP_STATUS_BAD_REQUEST = 400,
96 HTTP_STATUS_UNAUTHORIZED,
97 HTTP_STATUS_PAYMENT_REQUIRED,
98 HTTP_STATUS_FORBIDDEN,
99 HTTP_STATUS_NOT_FOUND,
100 HTTP_STATUS_METHOD_NOT_ALLOWED,
101 HTTP_STATUS_NOT_ACCEPTABLE,
102 HTTP_STATUS_PROXY_AUTH_REQUIRED,
103 HTTP_STATUS_REQUEST_TIMEOUT,
104 HTTP_STATUS_CONFLICT,
105 HTTP_STATUS_GONE,
106 HTTP_STATUS_LENGTH_REQUIRED,
107 HTTP_STATUS_PRECONDITION_FAILED,
108 HTTP_STATUS_REQ_ENTITY_TOO_LARGE,
109 HTTP_STATUS_REQ_URI_TOO_LONG,
110 HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE,
111 HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE,
112 HTTP_STATUS_EXPECTATION_FAILED,
113
114 HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
115 HTTP_STATUS_NOT_IMPLEMENTED,
116 HTTP_STATUS_BAD_GATEWAY,
117 HTTP_STATUS_SERVICE_UNAVAILABLE,
118 HTTP_STATUS_GATEWAY_TIMEOUT,
119 HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED,
120};
121/*! \defgroup html-chunked-substitution HTML Chunked Substitution
122 * \ingroup http
123 *
124 * ##HTML chunked Substitution
125 *
126 * APIs for receiving chunks of text, replacing a set of variable names via
127 * a callback, and then prepending and appending HTML chunked encoding
128 * headers.
129 */
130//@{
131
132struct lws_process_html_args {
133 char *p; /**< pointer to the buffer containing the data */
134 int len; /**< length of the original data at p */
135 int max_len; /**< maximum length we can grow the data to */
136 int final; /**< set if this is the last chunk of the file */
137 int chunked; /**< 0 == unchunked, 1 == produce chunk headers
138 (incompatible with HTTP/2) */
139};
140
141typedef const char *(*lws_process_html_state_cb)(void *data, int index);
142
143struct lws_process_html_state {
144 char *start; /**< pointer to start of match */
145 char swallow[16]; /**< matched character buffer */
146 int pos; /**< position in match */
147 void *data; /**< opaque pointer */
148 const char * const *vars; /**< list of variable names */
149 int count_vars; /**< count of variable names */
150
151 lws_process_html_state_cb replace;
152 /**< called on match to perform substitution */
153};
154
155/*! lws_chunked_html_process() - generic chunked substitution
156 * \param args: buffer to process using chunked encoding
157 * \param s: current processing state
158 */
159LWS_VISIBLE LWS_EXTERN int
160lws_chunked_html_process(struct lws_process_html_args *args,
161 struct lws_process_html_state *s);
162//@}
163
164/** \defgroup HTTP-headers-read HTTP headers: read
165 * \ingroup http
166 *
167 * ##HTTP header releated functions
168 *
169 * In lws the client http headers are temporarily stored in a pool, only for the
170 * duration of the http part of the handshake. It's because in most cases,
171 * the header content is ignored for the whole rest of the connection lifetime
172 * and would then just be taking up space needlessly.
173 *
174 * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time
175 * the http headers are still allocated, you can use these apis then to
176 * look at and copy out interesting header content (cookies, etc)
177 *
178 * Notice that the header total length reported does not include a terminating
179 * '\0', however you must allocate for it when using the _copy apis. So the
180 * length reported for a header containing "123" is 3, but you must provide
181 * a buffer of length 4 so that "123\0" may be copied into it, or the copy
182 * will fail with a nonzero return code.
183 *
184 * In the special case of URL arguments, like ?x=1&y=2, the arguments are
185 * stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it
186 * was a GET or WSI_TOKEN_POST_URI if POST. You can check the total
187 * length to confirm the method.
188 *
189 * For URL arguments, each argument is stored urldecoded in a "fragment", so
190 * you can use the fragment-aware api lws_hdr_copy_fragment() to access each
191 * argument in turn: the fragments contain urldecoded strings like x=1 or y=2.
192 *
193 * As a convenience, lws has an api that will find the fragment with a
194 * given name= part, lws_get_urlarg_by_name().
195 */
196///@{
197
198/** struct lws_tokens
199 * you need these to look at headers that have been parsed if using the
200 * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum
201 * list below is absent, .token = NULL and len = 0. Otherwise .token
202 * points to .len chars containing that header content.
203 */
204struct lws_tokens {
205 unsigned char *token; /**< pointer to start of the token */
206 int len; /**< length of the token's value */
207};
208
209/* enum lws_token_indexes
210 * these have to be kept in sync with lextable.h / minilex.c
211 *
212 * NOTE: These public enums are part of the abi. If you want to add one,
213 * add it at where specified so existing users are unaffected.
214 */
215enum lws_token_indexes {
216 WSI_TOKEN_GET_URI, /* 0 */
217 WSI_TOKEN_POST_URI,
218#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
219 WSI_TOKEN_OPTIONS_URI,
220#endif
221 WSI_TOKEN_HOST,
222 WSI_TOKEN_CONNECTION,
223 WSI_TOKEN_UPGRADE, /* 5 */
224 WSI_TOKEN_ORIGIN,
225#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
226 WSI_TOKEN_DRAFT,
227#endif
228 WSI_TOKEN_CHALLENGE,
229#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
230 WSI_TOKEN_EXTENSIONS,
231 WSI_TOKEN_KEY1, /* 10 */
232 WSI_TOKEN_KEY2,
233 WSI_TOKEN_PROTOCOL,
234 WSI_TOKEN_ACCEPT,
235 WSI_TOKEN_NONCE,
236#endif
237 WSI_TOKEN_HTTP,
238#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
239 WSI_TOKEN_HTTP2_SETTINGS, /* 16 */
240#endif
241 WSI_TOKEN_HTTP_ACCEPT,
242#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
243 WSI_TOKEN_HTTP_AC_REQUEST_HEADERS,
244#endif
245 WSI_TOKEN_HTTP_IF_MODIFIED_SINCE,
246 WSI_TOKEN_HTTP_IF_NONE_MATCH, /* 20 */
247 WSI_TOKEN_HTTP_ACCEPT_ENCODING,
248 WSI_TOKEN_HTTP_ACCEPT_LANGUAGE,
249 WSI_TOKEN_HTTP_PRAGMA,
250 WSI_TOKEN_HTTP_CACHE_CONTROL,
251 WSI_TOKEN_HTTP_AUTHORIZATION,
252 WSI_TOKEN_HTTP_COOKIE,
253 WSI_TOKEN_HTTP_CONTENT_LENGTH, /* 27 */
254 WSI_TOKEN_HTTP_CONTENT_TYPE,
255 WSI_TOKEN_HTTP_DATE,
256 WSI_TOKEN_HTTP_RANGE,
257#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
258 WSI_TOKEN_HTTP_REFERER,
259#endif
260#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
261 WSI_TOKEN_KEY,
262 WSI_TOKEN_VERSION,
263 WSI_TOKEN_SWORIGIN,
264#endif
265#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
266 WSI_TOKEN_HTTP_COLON_AUTHORITY,
267 WSI_TOKEN_HTTP_COLON_METHOD,
268 WSI_TOKEN_HTTP_COLON_PATH,
269 WSI_TOKEN_HTTP_COLON_SCHEME,
270 WSI_TOKEN_HTTP_COLON_STATUS,
271#endif
272
273#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
274 WSI_TOKEN_HTTP_ACCEPT_CHARSET,
275#endif
276 WSI_TOKEN_HTTP_ACCEPT_RANGES,
277#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
278 WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN,
279#endif
280 WSI_TOKEN_HTTP_AGE,
281 WSI_TOKEN_HTTP_ALLOW,
282 WSI_TOKEN_HTTP_CONTENT_DISPOSITION,
283 WSI_TOKEN_HTTP_CONTENT_ENCODING,
284 WSI_TOKEN_HTTP_CONTENT_LANGUAGE,
285 WSI_TOKEN_HTTP_CONTENT_LOCATION,
286 WSI_TOKEN_HTTP_CONTENT_RANGE,
287 WSI_TOKEN_HTTP_ETAG,
288 WSI_TOKEN_HTTP_EXPECT,
289 WSI_TOKEN_HTTP_EXPIRES,
290 WSI_TOKEN_HTTP_FROM,
291 WSI_TOKEN_HTTP_IF_MATCH,
292 WSI_TOKEN_HTTP_IF_RANGE,
293 WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE,
294 WSI_TOKEN_HTTP_LAST_MODIFIED,
295 WSI_TOKEN_HTTP_LINK,
296 WSI_TOKEN_HTTP_LOCATION,
297#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
298 WSI_TOKEN_HTTP_MAX_FORWARDS,
299 WSI_TOKEN_HTTP_PROXY_AUTHENTICATE,
300 WSI_TOKEN_HTTP_PROXY_AUTHORIZATION,
301#endif
302 WSI_TOKEN_HTTP_REFRESH,
303 WSI_TOKEN_HTTP_RETRY_AFTER,
304 WSI_TOKEN_HTTP_SERVER,
305 WSI_TOKEN_HTTP_SET_COOKIE,
306#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
307 WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY,
308#endif
309 WSI_TOKEN_HTTP_TRANSFER_ENCODING,
310#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
311 WSI_TOKEN_HTTP_USER_AGENT,
312 WSI_TOKEN_HTTP_VARY,
313 WSI_TOKEN_HTTP_VIA,
314 WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
315#endif
316#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
317 WSI_TOKEN_PATCH_URI,
318 WSI_TOKEN_PUT_URI,
319 WSI_TOKEN_DELETE_URI,
320#endif
321
322 WSI_TOKEN_HTTP_URI_ARGS,
323#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
324 WSI_TOKEN_PROXY,
325 WSI_TOKEN_HTTP_X_REAL_IP,
326#endif
327 WSI_TOKEN_HTTP1_0,
328 WSI_TOKEN_X_FORWARDED_FOR,
329 WSI_TOKEN_CONNECT,
330 WSI_TOKEN_HEAD_URI,
331#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
332 WSI_TOKEN_TE,
333 WSI_TOKEN_REPLAY_NONCE, /* ACME */
334#endif
335#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
336 WSI_TOKEN_COLON_PROTOCOL,
337#endif
338 WSI_TOKEN_X_AUTH_TOKEN,
339 WSI_TOKEN_DSS_SIGNATURE,
340
341 /****** add new things just above ---^ ******/
342
343 /* use token storage to stash these internally, not for
344 * user use */
345
346 _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
347 _WSI_TOKEN_CLIENT_PEER_ADDRESS,
348 _WSI_TOKEN_CLIENT_URI,
349 _WSI_TOKEN_CLIENT_HOST,
350 _WSI_TOKEN_CLIENT_ORIGIN,
351 _WSI_TOKEN_CLIENT_METHOD,
352 _WSI_TOKEN_CLIENT_IFACE,
353 _WSI_TOKEN_CLIENT_ALPN,
354
355 /* always last real token index*/
356 WSI_TOKEN_COUNT,
357
358 /* parser state additions, no storage associated */
359 WSI_TOKEN_NAME_PART,
360#if defined(LWS_WITH_CUSTOM_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
361 WSI_TOKEN_UNKNOWN_VALUE_PART,
362#endif
363 WSI_TOKEN_SKIPPING,
364 WSI_TOKEN_SKIPPING_SAW_CR,
365 WSI_PARSING_COMPLETE,
366 WSI_INIT_TOKEN_MUXURL,
367};
368
369struct lws_token_limits {
370 unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */
371};
372
373enum lws_h2_settings {
374 H2SET_HEADER_TABLE_SIZE = 1,
375 H2SET_ENABLE_PUSH,
376 H2SET_MAX_CONCURRENT_STREAMS,
377 H2SET_INITIAL_WINDOW_SIZE,
378 H2SET_MAX_FRAME_SIZE,
379 H2SET_MAX_HEADER_LIST_SIZE,
380 H2SET_RESERVED7,
381 H2SET_ENABLE_CONNECT_PROTOCOL, /* defined in mcmanus-httpbis-h2-ws-02 */
382
383 H2SET_COUNT /* always last */
384};
385
386/**
387 * lws_token_to_string() - returns a textual representation of a hdr token index
388 *
389 * \param token: token index
390 */
391LWS_VISIBLE LWS_EXTERN const unsigned char *
392lws_token_to_string(enum lws_token_indexes token);
393
394/**
395 * lws_hdr_total_length: report length of all fragments of a header totalled up
396 * The returned length does not include the space for a
397 * terminating '\0'
398 *
399 * \param wsi: websocket connection
400 * \param h: which header index we are interested in
401 */
402LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
403lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
404
405/**
406 * lws_hdr_fragment_length: report length of a single fragment of a header
407 * The returned length does not include the space for a
408 * terminating '\0'
409 *
410 * \param wsi: websocket connection
411 * \param h: which header index we are interested in
412 * \param frag_idx: which fragment of h we want to get the length of
413 */
414LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
415lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h,
416 int frag_idx);
417
418/**
419 * lws_hdr_copy() - copy all fragments of the given header to a buffer
420 * The buffer length len must include space for an additional
421 * terminating '\0', or it will fail returning -1.
422 *
423 * \param wsi: websocket connection
424 * \param dest: destination buffer
425 * \param len: length of destination buffer
426 * \param h: which header index we are interested in
427 *
428 * copies the whole, aggregated header, even if it was delivered in
429 * several actual headers piece by piece. Returns -1 or length of the whole
430 * header.
431 */
432LWS_VISIBLE LWS_EXTERN int
433lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h);
434
435/**
436 * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer
437 * The buffer length len must include space for an additional
438 * terminating '\0', or it will fail returning -1.
439 * If the requested fragment index is not present, it fails
440 * returning -1.
441 *
442 * \param wsi: websocket connection
443 * \param dest: destination buffer
444 * \param len: length of destination buffer
445 * \param h: which header index we are interested in
446 * \param frag_idx: which fragment of h we want to copy
447 *
448 * Normally this is only useful
449 * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS
450 * fragment 0 will contain "x=1" and fragment 1 "y=2"
451 */
452LWS_VISIBLE LWS_EXTERN int
453lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len,
454 enum lws_token_indexes h, int frag_idx);
455
456/**
457 * lws_hdr_custom_length() - return length of a custom header
458 *
459 * \param wsi: websocket connection
460 * \param name: header string (including terminating :)
461 * \param nlen: length of name
462 *
463 * Lws knows about 100 common http headers, and parses them into indexes when
464 * it recognizes them. When it meets a header that it doesn't know, it stores
465 * the name and value directly, and you can look them up using
466 * lws_hdr_custom_length() and lws_hdr_custom_copy().
467 *
468 * This api returns -1, or the length of the value part of the header if it
469 * exists. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to
470 * use this api.
471 */
472LWS_VISIBLE LWS_EXTERN int
473lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen);
474
475/**
476 * lws_hdr_custom_copy() - copy value part of a custom header
477 *
478 * \param wsi: websocket connection
479 * \param dst: pointer to buffer to receive the copy
480 * \param len: number of bytes available at dst
481 * \param name: header string (including terminating :)
482 * \param nlen: length of name
483 *
484 * Lws knows about 100 common http headers, and parses them into indexes when
485 * it recognizes them. When it meets a header that it doesn't know, it stores
486 * the name and value directly, and you can look them up using
487 * lws_hdr_custom_length() and lws_hdr_custom_copy().
488 *
489 * This api returns -1, or the length of the string it copied into dst if it
490 * was big enough to contain both the string and an extra terminating NUL. Lws
491 * must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to use this api.
492 */
493LWS_VISIBLE LWS_EXTERN int
494lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name,
495 int nlen);
496
497typedef void (*lws_hdr_custom_fe_cb_t)(const char *name, int nlen, void *opaque);
498/**
499 * lws_hdr_custom_name_foreach() - Iterate the custom header names
500 *
501 * \param wsi: websocket connection
502 * \param cb: callback for each custom header name
503 * \param opaque: ignored by lws except to pass to callback
504 *
505 * Lws knows about 100 common http headers, and parses them into indexes when
506 * it recognizes them. When it meets a header that it doesn't know, it stores
507 * the name and value directly, and you can look them up using
508 * lws_hdr_custom_length() and lws_hdr_custom_copy().
509 *
510 * This api returns -1 on error else 0. Use lws_hdr_custom_copy() to get the
511 * values of headers. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by
512 * default) to use this api.
513 */
514LWS_VISIBLE LWS_EXTERN int
515lws_hdr_custom_name_foreach(struct lws *wsi, lws_hdr_custom_fe_cb_t cb, void *opaque);
516
517/**
518 * lws_get_urlarg_by_name_safe() - get copy and return length of y for x=y urlargs
519 *
520 * \param wsi: the connection to check
521 * \param name: the arg name, like "token" or "token="
522 * \param buf: the buffer to receive the urlarg (including the name= part)
523 * \param len: the length of the buffer to receive the urlarg
524 *
525 * Returns -1 if not present, else the length of y in the urlarg name=y. If
526 * zero or greater, then buf contains a copy of the string y. Any = after the
527 * name match is trimmed off if the name does not end with = itself.
528 *
529 * This returns the explicit length and so can deal with binary blobs that are
530 * percent-encoded. It also makes sure buf has a NUL just after the valid
531 * length so it can work with NUL-based apis if you don't care about truncation.
532 *
533 * buf may have been written even when -1 is returned indicating no match.
534 *
535 * Use this in place of lws_get_urlarg_by_name() that does not return an
536 * explicit length.
537 */
538LWS_VISIBLE LWS_EXTERN int
539lws_get_urlarg_by_name_safe(struct lws *wsi, const char *name, char *buf, int len);
540
541/**
542 * lws_get_urlarg_by_name() - return pointer to arg value if present
543 *
544 * \param wsi: the connection to check
545 * \param name: the arg name, like "token="
546 * \param buf: the buffer to receive the urlarg (including the name= part)
547 * \param len: the length of the buffer to receive the urlarg
548 *
549 * Returns NULL if not found or a pointer inside buf to just after the
550 * name= part.
551 *
552 * This assumed the argument can be represented with a NUL-terminated string.
553 * It can't correctly deal with binary values encoded with %XX, eg. %00 will
554 * be understood to terminate the string.
555 *
556 * Use lws_get_urlarg_by_name_safe() instead of this, which returns the length.
557 */
558LWS_VISIBLE LWS_EXTERN const char *
559lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)
560/* LWS_WARN_DEPRECATED */;
561///@}
562
563/*! \defgroup HTTP-headers-create HTTP headers: create
564 *
565 * ## HTTP headers: Create
566 *
567 * These apis allow you to create HTTP response headers in a way compatible with
568 * both HTTP/1.x and HTTP/2.
569 *
570 * They each append to a buffer taking care about the buffer end, which is
571 * passed in as a pointer. When data is written to the buffer, the current
572 * position p is updated accordingly.
573 *
574 * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space
575 * and fail with nonzero return.
576 */
577///@{
578
579#define LWSAHH_CODE_MASK ((1 << 16) - 1)
580#define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30)
581
582/**
583 * lws_add_http_header_status() - add the HTTP response status code
584 *
585 * \param wsi: the connection to check
586 * \param code: an HTTP code like 200, 404 etc (see enum http_status)
587 * \param p: pointer to current position in buffer pointer
588 * \param end: pointer to end of buffer
589 *
590 * Adds the initial response code, so should be called first.
591 *
592 * Code may additionally take OR'd flags:
593 *
594 * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time
595 */
596LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
597lws_add_http_header_status(struct lws *wsi,
598 unsigned int code, unsigned char **p,
599 unsigned char *end);
600/**
601 * lws_add_http_header_by_name() - append named header and value
602 *
603 * \param wsi: the connection to check
604 * \param name: the hdr name, like "my-header:"
605 * \param value: the value after the = for this header
606 * \param length: the length of the value
607 * \param p: pointer to current position in buffer pointer
608 * \param end: pointer to end of buffer
609 *
610 * Appends name: value to the headers
611 */
612LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
613lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name,
614 const unsigned char *value, int length,
615 unsigned char **p, unsigned char *end);
616/**
617 * lws_add_http_header_by_token() - append given header and value
618 *
619 * \param wsi: the connection to check
620 * \param token: the token index for the hdr
621 * \param value: the value after the = for this header
622 * \param length: the length of the value
623 * \param p: pointer to current position in buffer pointer
624 * \param end: pointer to end of buffer
625 *
626 * Appends name=value to the headers, but is able to take advantage of better
627 * HTTP/2 coding mechanisms where possible.
628 */
629LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
630lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token,
631 const unsigned char *value, int length,
632 unsigned char **p, unsigned char *end);
633/**
634 * lws_add_http_header_content_length() - append content-length helper
635 *
636 * \param wsi: the connection to check
637 * \param content_length: the content length to use
638 * \param p: pointer to current position in buffer pointer
639 * \param end: pointer to end of buffer
640 *
641 * Appends content-length: content_length to the headers
642 */
643LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
644lws_add_http_header_content_length(struct lws *wsi,
645 lws_filepos_t content_length,
646 unsigned char **p, unsigned char *end);
647/**
648 * lws_finalize_http_header() - terminate header block
649 *
650 * \param wsi: the connection to check
651 * \param p: pointer to current position in buffer pointer
652 * \param end: pointer to end of buffer
653 *
654 * Indicates no more headers will be added
655 */
656LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
657lws_finalize_http_header(struct lws *wsi, unsigned char **p,
658 unsigned char *end);
659
660/**
661 * lws_finalize_write_http_header() - Helper finializing and writing http headers
662 *
663 * \param wsi: the connection to check
664 * \param start: pointer to the start of headers in the buffer, eg &buf[LWS_PRE]
665 * \param p: pointer to current position in buffer pointer
666 * \param end: pointer to end of buffer
667 *
668 * Terminates the headers correctly accoring to the protocol in use (h1 / h2)
669 * and writes the headers. Returns nonzero for error.
670 */
671LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
672lws_finalize_write_http_header(struct lws *wsi, unsigned char *start,
673 unsigned char **p, unsigned char *end);
674
675#define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll)
676
677/**
678 * lws_add_http_common_headers() - Helper preparing common http headers
679 *
680 * \param wsi: the connection to check
681 * \param code: an HTTP code like 200, 404 etc (see enum http_status)
682 * \param content_type: the content type, like "text/html"
683 * \param content_len: the content length, in bytes
684 * \param p: pointer to current position in buffer pointer
685 * \param end: pointer to end of buffer
686 *
687 * Adds the initial response code, so should be called first.
688 *
689 * Code may additionally take OR'd flags:
690 *
691 * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time
692 *
693 * This helper just calls public apis to simplify adding headers that are
694 * commonly needed. If it doesn't fit your case, or you want to add additional
695 * headers just call the public apis directly yourself for what you want.
696 *
697 * You can miss out the content length header by providing the constant
698 * LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len.
699 *
700 * It does not call lws_finalize_http_header(), to allow you to add further
701 * headers after calling this. You will need to call that yourself at the end.
702 */
703LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
704lws_add_http_common_headers(struct lws *wsi, unsigned int code,
705 const char *content_type, lws_filepos_t content_len,
706 unsigned char **p, unsigned char *end);
707
708enum {
709 LWSHUMETH_GET,
710 LWSHUMETH_POST,
711 LWSHUMETH_OPTIONS,
712 LWSHUMETH_PUT,
713 LWSHUMETH_PATCH,
714 LWSHUMETH_DELETE,
715 LWSHUMETH_CONNECT,
716 LWSHUMETH_HEAD,
717 LWSHUMETH_COLON_PATH,
718};
719
720/**
721 * lws_http_get_uri_and_method() - Get information on method and url
722 *
723 * \param wsi: the connection to get information on
724 * \param puri_ptr: points to pointer to set to url
725 * \param puri_len: points to int to set to uri length
726 *
727 * Returns -1 or method index as one of the LWSHUMETH_ constants
728 *
729 * If returns method, *puri_ptr is set to the method's URI string and *puri_len
730 * to its length
731 */
732
733LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
734lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len);
735
736///@}
737
738/*! \defgroup urlendec Urlencode and Urldecode
739 * \ingroup http
740 *
741 * ##HTML chunked Substitution
742 *
743 * APIs for receiving chunks of text, replacing a set of variable names via
744 * a callback, and then prepending and appending HTML chunked encoding
745 * headers.
746 */
747//@{
748
749/**
750 * lws_urlencode() - like strncpy but with urlencoding
751 *
752 * \param escaped: output buffer
753 * \param string: input buffer ('/0' terminated)
754 * \param len: output buffer max length
755 *
756 * Because urlencoding expands the output string, it's not
757 * possible to do it in-place, ie, with escaped == string
758 */
759LWS_VISIBLE LWS_EXTERN const char *
760lws_urlencode(char *escaped, const char *string, int len);
761
762/*
763 * URLDECODE 1 / 2
764 *
765 * This simple urldecode only operates until the first '\0' and requires the
766 * data to exist all at once
767 */
768/**
769 * lws_urldecode() - like strncpy but with urldecoding
770 *
771 * \param string: output buffer
772 * \param escaped: input buffer ('\0' terminated)
773 * \param len: output buffer max length
774 *
775 * This is only useful for '\0' terminated strings
776 *
777 * Since urldecoding only shrinks the output string, it is possible to
778 * do it in-place, ie, string == escaped
779 *
780 * Returns 0 if completed OK or nonzero for urldecode violation (non-hex chars
781 * where hex required, etc)
782 */
783LWS_VISIBLE LWS_EXTERN int
784lws_urldecode(char *string, const char *escaped, int len);
785///@}
786
787/**
788 * lws_http_date_render_from_unix() - render unixtime as RFC7231 date string
789 *
790 * \param buf: Destination string buffer
791 * \param len: avilable length of dest string buffer in bytes
792 * \param t: pointer to the time_t to render
793 *
794 * Returns 0 if time_t is rendered into the string buffer successfully, else
795 * nonzero.
796 */
797LWS_VISIBLE LWS_EXTERN int
798lws_http_date_render_from_unix(char *buf, size_t len, const time_t *t);
799
800/**
801 * lws_http_date_parse_unix() - parse a RFC7231 date string into unixtime
802 *
803 * \param b: Source string buffer
804 * \param len: avilable length of source string buffer in bytes
805 * \param t: pointer to the destination time_t to set
806 *
807 * Returns 0 if string buffer parsed as RFC7231 time successfully, and
808 * *t set to the parsed unixtime, else return nonzero.
809 */
810LWS_VISIBLE LWS_EXTERN int
811lws_http_date_parse_unix(const char *b, size_t len, time_t *t);
812
813/**
814 * lws_http_check_retry_after() - increase a timeout if retry-after present
815 *
816 * \param wsi: http stream this relates to
817 * \param us_interval_in_out: default us retry interval on entry may be updated
818 *
819 * This function may extend the incoming retry interval if the server has
820 * requested that using retry-after: header. It won't reduce the incoming
821 * retry interval, only leave it alone or increase it.
822 *
823 * *us_interval_in_out should be set to a default retry interval on entry, if
824 * the wsi has a retry-after time or interval that resolves to an interval
825 * longer than the entry *us_interval_in_out, that will be updated to the longer
826 * interval and return 0.
827 *
828 * If no usable retry-after or the time is now or in the past,
829 * *us_interval_in_out is left alone and the function returns nonzero.
830 */
831LWS_VISIBLE LWS_EXTERN int
832lws_http_check_retry_after(struct lws *wsi, lws_usec_t *us_interval_in_out);
833
834/**
835 * lws_return_http_status() - Return simple http status
836 * \param wsi: Websocket instance (available from user callback)
837 * \param code: Status index, eg, 404
838 * \param html_body: User-readable HTML description < 1KB, or NULL
839 *
840 * Helper to report HTTP errors back to the client cleanly and
841 * consistently
842 */
843LWS_VISIBLE LWS_EXTERN int
844lws_return_http_status(struct lws *wsi, unsigned int code,
845 const char *html_body);
846
847/**
848 * lws_http_redirect() - write http redirect out on wsi
849 *
850 * \param wsi: websocket connection
851 * \param code: HTTP response code (eg, 301)
852 * \param loc: where to redirect to
853 * \param len: length of loc
854 * \param p: pointer current position in buffer (updated as we write)
855 * \param end: pointer to end of buffer
856 *
857 * Returns amount written, or < 0 indicating fatal write failure.
858 */
859LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
860lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
861 unsigned char **p, unsigned char *end);
862
863/**
864 * lws_http_transaction_completed() - wait for new http transaction or close
865 * \param wsi: websocket connection
866 *
867 * Returns nonzero if the HTTP connection must close now
868 * Returns 0 and resets connection to wait for new HTTP header /
869 * transaction if possible
870 */
871LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
872lws_http_transaction_completed(struct lws *wsi);
873
874/**
875 * lws_http_headers_detach() - drop the associated headers storage and allow
876 * it to be reused by another connection
877 * \param wsi: http connection
878 *
879 * If the wsi has an ah headers struct attached, detach it.
880 */
881LWS_VISIBLE LWS_EXTERN int
882lws_http_headers_detach(struct lws *wsi);
883
884/**
885 * lws_http_mark_sse() - called to indicate this http stream is now doing SSE
886 *
887 * \param wsi: http connection
888 *
889 * Cancel any timeout on the wsi, and for h2, mark the network connection as
890 * containing an immortal stream for the duration the SSE stream is open.
891 */
892LWS_VISIBLE LWS_EXTERN int
893lws_http_mark_sse(struct lws *wsi);
894
895/**
896 * lws_h2_client_stream_long_poll_rxonly() - h2 stream to immortal read-only
897 *
898 * \param wsi: h2 stream client wsi
899 *
900 * Send END_STREAM-flagged zero-length DATA frame to set client stream wsi into
901 * half-closed (local) and remote into half-closed (remote). Set the client
902 * stream wsi to be immortal (not subject to timeouts).
903 *
904 * Used if the remote server supports immortal long poll to put the stream into
905 * a read-only state where it can wait as long as needed for rx.
906 *
907 * Returns 0 if the process (which happens asynchronously) started or non-zero
908 * if it wasn't an h2 stream.
909 */
910LWS_VISIBLE LWS_EXTERN int
911lws_h2_client_stream_long_poll_rxonly(struct lws *wsi);
912
913/**
914 * lws_http_compression_apply() - apply an http compression transform
915 *
916 * \param wsi: the wsi to apply the compression transform to
917 * \param name: NULL, or the name of the compression transform, eg, "deflate"
918 * \param p: pointer to pointer to headers buffer
919 * \param end: pointer to end of headers buffer
920 * \param decomp: 0 = add compressor to wsi, 1 = add decompressor
921 *
922 * This allows transparent compression of dynamically generated HTTP. The
923 * requested compression (eg, "deflate") is only applied if the client headers
924 * indicated it was supported (and it has support in lws), otherwise it's a NOP.
925 *
926 * If the requested compression method is NULL, then the supported compression
927 * formats are tried, and for non-decompression (server) mode the first that's
928 * found on the client's accept-encoding header is chosen.
929 *
930 * NOTE: the compression transform, same as h2 support, relies on the user
931 * code using LWS_WRITE_HTTP and then LWS_WRITE_HTTP_FINAL on the last part
932 * written. The internal lws fileserving code already does this.
933 *
934 * If the library was built without the cmake option
935 * LWS_WITH_HTTP_STREAM_COMPRESSION set, then a NOP is provided for this api,
936 * allowing user code to build either way and use compression if available.
937 */
938LWS_VISIBLE LWS_EXTERN int
939lws_http_compression_apply(struct lws *wsi, const char *name,
940 unsigned char **p, unsigned char *end, char decomp);
941
942/**
943 * lws_http_is_redirected_to_get() - true if redirected to GET
944 *
945 * \param wsi: the wsi to check
946 *
947 * Check if the wsi is currently in GET mode, after, eg, doing a POST and
948 * receiving a 303.
949 */
950LWS_VISIBLE LWS_EXTERN int
951lws_http_is_redirected_to_get(struct lws *wsi);
952
953/**
954 * lws_http_cookie_get() - return copy of named cookie if present
955 *
956 * \param wsi: the wsi to check
957 * \param name: name of the cookie
958 * \param buf: buffer to store the cookie contents into
959 * \param max_len: on entry, maximum length of buf... on exit, used len of buf
960 *
961 * If no cookie header, or no cookie of the requested name, or the value is
962 * larger than can fit in buf, returns nonzero.
963 *
964 * If the cookie is found, copies its value into buf with a terminating NUL,
965 * sets *max_len to the used length, and returns 0.
966 *
967 * This handles the parsing of the possibly multi-cookie header string and
968 * terminating the requested cookie at the next ; if present.
969 */
970LWS_VISIBLE LWS_EXTERN int
971lws_http_cookie_get(struct lws *wsi, const char *name, char *buf, size_t *max);
972
973/**
974 * lws_http_client_http_error() - determine if the response code indicates an error
975 *
976 * \param code: the response code to test
977 *
978 * Returns nonzero if the code indicates an error, else zero if reflects a
979 * non-error condition
980 */
981#define lws_http_client_http_resp_is_error(code) (!(code < 400))
982
983/**
984 * lws_h2_update_peer_txcredit() - manually update stream peer tx credit
985 *
986 * \param wsi: the h2 child stream whose peer credit to change
987 * \param sid: the stream ID, or LWS_H2_STREAM_SID for the wsi stream ID
988 * \param bump: signed change to confer upon peer tx credit for sid
989 *
990 * In conjunction with LCCSCF_H2_MANUAL_RXFLOW flag, allows the user code to
991 * selectively starve the remote peer of the ability to send us data on a client
992 * connection.
993 *
994 * Normally lws sends an initial window size for the peer to send to it of 0,
995 * but during the header phase it sends a WINDOW_UPDATE to increase the amount
996 * available. LCCSCF_H2_MANUAL_RXFLOW restricts this initial increase in tx
997 * credit for the stream, before it has been asked to send us anything, to the
998 * amount specified in the client info .manual_initial_tx_credit member, and
999 * this api can be called to send the other side permission to send us up to
1000 * \p bump additional bytes.
1001 *
1002 * The nwsi tx credit is updated automatically for exactly what was sent to us
1003 * on a stream with LCCSCF_H2_MANUAL_RXFLOW flag, but the stream's own tx credit
1004 * must be handled manually by user code via this api.
1005 *
1006 * Returns 0 for success or nonzero for failure.
1007 */
1008#define LWS_H2_STREAM_SID -1
1009LWS_VISIBLE LWS_EXTERN int
1010lws_h2_update_peer_txcredit(struct lws *wsi, unsigned int sid, int bump);
1011
1012
1013/**
1014 * lws_h2_get_peer_txcredit_estimate() - return peer tx credit estimate
1015 *
1016 * \param wsi: the h2 child stream whose peer credit estimate to return
1017 *
1018 * Returns the estimated amount of tx credit at the peer, in other words the
1019 * number of bytes the peer is authorized to send to us.
1020 *
1021 * It's an 'estimate' because we don't know how much is already in flight
1022 * towards us and actually already used.
1023 */
1024LWS_VISIBLE LWS_EXTERN int
1025lws_h2_get_peer_txcredit_estimate(struct lws *wsi);
1026
1027///@}
1028
1029