cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

lws-http.h (36543B)


      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