libwebsockets
Lightweight C library for HTML5 websockets
lws-http.h
Go to the documentation of this file.
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
80//@}
81
82
85
89
94
113
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
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
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
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
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 */
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 */
218#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
220#endif
225#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
227#endif
229#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
231 WSI_TOKEN_KEY1, /* 10 */
236#endif
238#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
240#endif
242#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
244#endif
257#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
259#endif
260#if defined(LWS_ROLE_WS) || defined(LWS_HTTP_HEADERS_ALL)
264#endif
265#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
271#endif
272
273#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
275#endif
277#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
279#endif
297#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
301#endif
306#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
308#endif
310#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
315#endif
316#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
320#endif
321
323#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
326#endif
331#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) || defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
333 WSI_TOKEN_REPLAY_NONCE, /* ACME */
334#endif
335#if defined(LWS_ROLE_H2) || defined(LWS_HTTP_HEADERS_ALL)
337#endif
340
341 /****** add new things just above ---^ ******/
342
343 /* use token storage to stash these internally, not for
344 * user use */
345
355
356 /* always last real token index*/
358
359 /* parser state additions, no storage associated */
361#if defined(LWS_WITH_CUSTOM_HEADERS) || defined(LWS_HTTP_HEADERS_ALL)
363#endif
368};
369
371 unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */
372};
373
382 H2SET_ENABLE_CONNECT_PROTOCOL, /* defined in mcmanus-httpbis-h2-ws-02 */
383
384 H2SET_COUNT /* always last */
386
387/**
388 * lws_token_to_string() - returns a textual representation of a hdr token index
389 *
390 * \param token: token index
391 */
392LWS_VISIBLE LWS_EXTERN const unsigned char *
394
395/**
396 * lws_hdr_total_length: report length of all fragments of a header totalled up
397 * The returned length does not include the space for a
398 * terminating '\0'
399 *
400 * \param wsi: websocket connection
401 * \param h: which header index we are interested in
402 */
403LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
404lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
405
406/**
407 * lws_hdr_fragment_length: report length of a single fragment of a header
408 * The returned length does not include the space for a
409 * terminating '\0'
410 *
411 * \param wsi: websocket connection
412 * \param h: which header index we are interested in
413 * \param frag_idx: which fragment of h we want to get the length of
414 */
415LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
416lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h,
417 int frag_idx);
418
419/**
420 * lws_hdr_copy() - copy all fragments of the given header to a buffer
421 * The buffer length len must include space for an additional
422 * terminating '\0', or it will fail returning -1.
423 *
424 * \param wsi: websocket connection
425 * \param dest: destination buffer
426 * \param len: length of destination buffer
427 * \param h: which header index we are interested in
428 *
429 * copies the whole, aggregated header, even if it was delivered in
430 * several actual headers piece by piece. Returns -1 or length of the whole
431 * header.
432 */
433LWS_VISIBLE LWS_EXTERN int
434lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h);
435
436/**
437 * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer
438 * The buffer length len must include space for an additional
439 * terminating '\0', or it will fail returning -1.
440 * If the requested fragment index is not present, it fails
441 * returning -1.
442 *
443 * \param wsi: websocket connection
444 * \param dest: destination buffer
445 * \param len: length of destination buffer
446 * \param h: which header index we are interested in
447 * \param frag_idx: which fragment of h we want to copy
448 *
449 * Normally this is only useful
450 * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS
451 * fragment 0 will contain "x=1" and fragment 1 "y=2"
452 */
453LWS_VISIBLE LWS_EXTERN int
454lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len,
455 enum lws_token_indexes h, int frag_idx);
456
457/**
458 * lws_hdr_custom_length() - return length of a custom header
459 *
460 * \param wsi: websocket connection
461 * \param name: header string (including terminating :)
462 * \param nlen: length of name
463 *
464 * Lws knows about 100 common http headers, and parses them into indexes when
465 * it recognizes them. When it meets a header that it doesn't know, it stores
466 * the name and value directly, and you can look them up using
467 * lws_hdr_custom_length() and lws_hdr_custom_copy().
468 *
469 * This api returns -1, or the length of the value part of the header if it
470 * exists. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to
471 * use this api.
472 */
473LWS_VISIBLE LWS_EXTERN int
474lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen);
475
476/**
477 * lws_hdr_custom_copy() - copy value part of a custom header
478 *
479 * \param wsi: websocket connection
480 * \param dst: pointer to buffer to receive the copy
481 * \param len: number of bytes available at dst
482 * \param name: header string (including terminating :)
483 * \param nlen: length of name
484 *
485 * Lws knows about 100 common http headers, and parses them into indexes when
486 * it recognizes them. When it meets a header that it doesn't know, it stores
487 * the name and value directly, and you can look them up using
488 * lws_hdr_custom_length() and lws_hdr_custom_copy().
489 *
490 * This api returns -1, or the length of the string it copied into dst if it
491 * was big enough to contain both the string and an extra terminating NUL. Lws
492 * must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to use this api.
493 */
494LWS_VISIBLE LWS_EXTERN int
495lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name,
496 int nlen);
497
498typedef void (*lws_hdr_custom_fe_cb_t)(const char *name, int nlen, void *opaque);
499/**
500 * lws_hdr_custom_name_foreach() - Iterate the custom header names
501 *
502 * \param wsi: websocket connection
503 * \param cb: callback for each custom header name
504 * \param opaque: ignored by lws except to pass to callback
505 *
506 * Lws knows about 100 common http headers, and parses them into indexes when
507 * it recognizes them. When it meets a header that it doesn't know, it stores
508 * the name and value directly, and you can look them up using
509 * lws_hdr_custom_length() and lws_hdr_custom_copy().
510 *
511 * This api returns -1 on error else 0. Use lws_hdr_custom_copy() to get the
512 * values of headers. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by
513 * default) to use this api.
514 */
515LWS_VISIBLE LWS_EXTERN int
516lws_hdr_custom_name_foreach(struct lws *wsi, lws_hdr_custom_fe_cb_t cb, void *opaque);
517
518/**
519 * lws_get_urlarg_by_name_safe() - get copy and return length of y for x=y urlargs
520 *
521 * \param wsi: the connection to check
522 * \param name: the arg name, like "token" or "token="
523 * \param buf: the buffer to receive the urlarg (including the name= part)
524 * \param len: the length of the buffer to receive the urlarg
525 *
526 * Returns -1 if not present, else the length of y in the urlarg name=y. If
527 * zero or greater, then buf contains a copy of the string y. Any = after the
528 * name match is trimmed off if the name does not end with = itself.
529 *
530 * This returns the explicit length and so can deal with binary blobs that are
531 * percent-encoded. It also makes sure buf has a NUL just after the valid
532 * length so it can work with NUL-based apis if you don't care about truncation.
533 *
534 * buf may have been written even when -1 is returned indicating no match.
535 *
536 * Use this in place of lws_get_urlarg_by_name() that does not return an
537 * explicit length.
538 */
539LWS_VISIBLE LWS_EXTERN int
540lws_get_urlarg_by_name_safe(struct lws *wsi, const char *name, char *buf, int len);
541
542/**
543 * lws_get_urlarg_by_name() - return pointer to arg value if present
544 *
545 * \param wsi: the connection to check
546 * \param name: the arg name, like "token="
547 * \param buf: the buffer to receive the urlarg (including the name= part)
548 * \param len: the length of the buffer to receive the urlarg
549 *
550 * Returns NULL if not found or a pointer inside buf to just after the
551 * name= part.
552 *
553 * This assumed the argument can be represented with a NUL-terminated string.
554 * It can't correctly deal with binary values encoded with %XX, eg. %00 will
555 * be understood to terminate the string.
556 *
557 * Use lws_get_urlarg_by_name_safe() instead of this, which returns the length.
558 */
559LWS_VISIBLE LWS_EXTERN const char *
560lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)
561/* LWS_WARN_DEPRECATED */;
562///@}
563
564/*! \defgroup HTTP-headers-create HTTP headers: create
565 *
566 * ## HTTP headers: Create
567 *
568 * These apis allow you to create HTTP response headers in a way compatible with
569 * both HTTP/1.x and HTTP/2.
570 *
571 * They each append to a buffer taking care about the buffer end, which is
572 * passed in as a pointer. When data is written to the buffer, the current
573 * position p is updated accordingly.
574 *
575 * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space
576 * and fail with nonzero return.
577 */
578///@{
579
580#define LWSAHH_CODE_MASK ((1 << 16) - 1)
581#define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30)
582
583/**
584 * lws_add_http_header_status() - add the HTTP response status code
585 *
586 * \param wsi: the connection to check
587 * \param code: an HTTP code like 200, 404 etc (see enum http_status)
588 * \param p: pointer to current position in buffer pointer
589 * \param end: pointer to end of buffer
590 *
591 * Adds the initial response code, so should be called first.
592 *
593 * Code may additionally take OR'd flags:
594 *
595 * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time
596 */
597LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
598lws_add_http_header_status(struct lws *wsi,
599 unsigned int code, unsigned char **p,
600 unsigned char *end);
601/**
602 * lws_add_http_header_by_name() - append named header and value
603 *
604 * \param wsi: the connection to check
605 * \param name: the hdr name, like "my-header:"
606 * \param value: the value after the = for this header
607 * \param length: the length of the value
608 * \param p: pointer to current position in buffer pointer
609 * \param end: pointer to end of buffer
610 *
611 * Appends name: value to the headers
612 */
613LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
614lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name,
615 const unsigned char *value, int length,
616 unsigned char **p, unsigned char *end);
617/**
618 * lws_add_http_header_by_token() - append given header and value
619 *
620 * \param wsi: the connection to check
621 * \param token: the token index for the hdr
622 * \param value: the value after the = for this header
623 * \param length: the length of the value
624 * \param p: pointer to current position in buffer pointer
625 * \param end: pointer to end of buffer
626 *
627 * Appends name=value to the headers, but is able to take advantage of better
628 * HTTP/2 coding mechanisms where possible.
629 */
630LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
631lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token,
632 const unsigned char *value, int length,
633 unsigned char **p, unsigned char *end);
634/**
635 * lws_add_http_header_content_length() - append content-length helper
636 *
637 * \param wsi: the connection to check
638 * \param content_length: the content length to use
639 * \param p: pointer to current position in buffer pointer
640 * \param end: pointer to end of buffer
641 *
642 * Appends content-length: content_length to the headers
643 */
644LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
645lws_add_http_header_content_length(struct lws *wsi,
646 lws_filepos_t content_length,
647 unsigned char **p, unsigned char *end);
648/**
649 * lws_finalize_http_header() - terminate header block
650 *
651 * \param wsi: the connection to check
652 * \param p: pointer to current position in buffer pointer
653 * \param end: pointer to end of buffer
654 *
655 * Indicates no more headers will be added
656 */
657LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
658lws_finalize_http_header(struct lws *wsi, unsigned char **p,
659 unsigned char *end);
660
661/**
662 * lws_finalize_write_http_header() - Helper finializing and writing http headers
663 *
664 * \param wsi: the connection to check
665 * \param start: pointer to the start of headers in the buffer, eg &buf[LWS_PRE]
666 * \param p: pointer to current position in buffer pointer
667 * \param end: pointer to end of buffer
668 *
669 * Terminates the headers correctly accoring to the protocol in use (h1 / h2)
670 * and writes the headers. Returns nonzero for error.
671 */
672LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
673lws_finalize_write_http_header(struct lws *wsi, unsigned char *start,
674 unsigned char **p, unsigned char *end);
675
676#define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll)
677
678/**
679 * lws_add_http_common_headers() - Helper preparing common http headers
680 *
681 * \param wsi: the connection to check
682 * \param code: an HTTP code like 200, 404 etc (see enum http_status)
683 * \param content_type: the content type, like "text/html"
684 * \param content_len: the content length, in bytes
685 * \param p: pointer to current position in buffer pointer
686 * \param end: pointer to end of buffer
687 *
688 * Adds the initial response code, so should be called first.
689 *
690 * Code may additionally take OR'd flags:
691 *
692 * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time
693 *
694 * This helper just calls public apis to simplify adding headers that are
695 * commonly needed. If it doesn't fit your case, or you want to add additional
696 * headers just call the public apis directly yourself for what you want.
697 *
698 * You can miss out the content length header by providing the constant
699 * LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len.
700 *
701 * It does not call lws_finalize_http_header(), to allow you to add further
702 * headers after calling this. You will need to call that yourself at the end.
703 */
704LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
705lws_add_http_common_headers(struct lws *wsi, unsigned int code,
706 const char *content_type, lws_filepos_t content_len,
707 unsigned char **p, unsigned char *end);
708
709enum {
719};
720
721/**
722 * lws_http_get_uri_and_method() - Get information on method and url
723 *
724 * \param wsi: the connection to get information on
725 * \param puri_ptr: points to pointer to set to url
726 * \param puri_len: points to int to set to uri length
727 *
728 * Returns -1 or method index as one of the LWSHUMETH_ constants
729 *
730 * If returns method, *puri_ptr is set to the method's URI string and *puri_len
731 * to its length
732 */
733
734LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
735lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len);
736
737///@}
738
739/*! \defgroup urlendec Urlencode and Urldecode
740 * \ingroup http
741 *
742 * ##HTML chunked Substitution
743 *
744 * APIs for receiving chunks of text, replacing a set of variable names via
745 * a callback, and then prepending and appending HTML chunked encoding
746 * headers.
747 */
748//@{
749
750/**
751 * lws_urlencode() - like strncpy but with urlencoding
752 *
753 * \param escaped: output buffer
754 * \param string: input buffer ('/0' terminated)
755 * \param len: output buffer max length
756 *
757 * Because urlencoding expands the output string, it's not
758 * possible to do it in-place, ie, with escaped == string
759 */
760LWS_VISIBLE LWS_EXTERN const char *
761lws_urlencode(char *escaped, const char *string, int len);
762
763/*
764 * URLDECODE 1 / 2
765 *
766 * This simple urldecode only operates until the first '\0' and requires the
767 * data to exist all at once
768 */
769/**
770 * lws_urldecode() - like strncpy but with urldecoding
771 *
772 * \param string: output buffer
773 * \param escaped: input buffer ('\0' terminated)
774 * \param len: output buffer max length
775 *
776 * This is only useful for '\0' terminated strings
777 *
778 * Since urldecoding only shrinks the output string, it is possible to
779 * do it in-place, ie, string == escaped
780 *
781 * Returns 0 if completed OK or nonzero for urldecode violation (non-hex chars
782 * where hex required, etc)
783 */
784LWS_VISIBLE LWS_EXTERN int
785lws_urldecode(char *string, const char *escaped, int len);
786///@}
787
788/**
789 * lws_http_date_render_from_unix() - render unixtime as RFC7231 date string
790 *
791 * \param buf: Destination string buffer
792 * \param len: avilable length of dest string buffer in bytes
793 * \param t: pointer to the time_t to render
794 *
795 * Returns 0 if time_t is rendered into the string buffer successfully, else
796 * nonzero.
797 */
798LWS_VISIBLE LWS_EXTERN int
799lws_http_date_render_from_unix(char *buf, size_t len, const time_t *t);
800
801/**
802 * lws_http_date_parse_unix() - parse a RFC7231 date string into unixtime
803 *
804 * \param b: Source string buffer
805 * \param len: avilable length of source string buffer in bytes
806 * \param t: pointer to the destination time_t to set
807 *
808 * Returns 0 if string buffer parsed as RFC7231 time successfully, and
809 * *t set to the parsed unixtime, else return nonzero.
810 */
811LWS_VISIBLE LWS_EXTERN int
812lws_http_date_parse_unix(const char *b, size_t len, time_t *t);
813
814/**
815 * lws_http_check_retry_after() - increase a timeout if retry-after present
816 *
817 * \param wsi: http stream this relates to
818 * \param us_interval_in_out: default us retry interval on entry may be updated
819 *
820 * This function may extend the incoming retry interval if the server has
821 * requested that using retry-after: header. It won't reduce the incoming
822 * retry interval, only leave it alone or increase it.
823 *
824 * *us_interval_in_out should be set to a default retry interval on entry, if
825 * the wsi has a retry-after time or interval that resolves to an interval
826 * longer than the entry *us_interval_in_out, that will be updated to the longer
827 * interval and return 0.
828 *
829 * If no usable retry-after or the time is now or in the past,
830 * *us_interval_in_out is left alone and the function returns nonzero.
831 */
832LWS_VISIBLE LWS_EXTERN int
833lws_http_check_retry_after(struct lws *wsi, lws_usec_t *us_interval_in_out);
834
835/**
836 * lws_return_http_status() - Return simple http status
837 * \param wsi: Websocket instance (available from user callback)
838 * \param code: Status index, eg, 404
839 * \param html_body: User-readable HTML description < 1KB, or NULL
840 *
841 * Helper to report HTTP errors back to the client cleanly and
842 * consistently
843 */
844LWS_VISIBLE LWS_EXTERN int
845lws_return_http_status(struct lws *wsi, unsigned int code,
846 const char *html_body);
847
848/**
849 * lws_http_redirect() - write http redirect out on wsi
850 *
851 * \param wsi: websocket connection
852 * \param code: HTTP response code (eg, 301)
853 * \param loc: where to redirect to
854 * \param len: length of loc
855 * \param p: pointer current position in buffer (updated as we write)
856 * \param end: pointer to end of buffer
857 *
858 * Returns amount written, or < 0 indicating fatal write failure.
859 */
860LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
861lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
862 unsigned char **p, unsigned char *end);
863
864/**
865 * lws_http_transaction_completed() - wait for new http transaction or close
866 * \param wsi: websocket connection
867 *
868 * Returns nonzero if the HTTP connection must close now
869 * Returns 0 and resets connection to wait for new HTTP header /
870 * transaction if possible
871 */
872LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
873lws_http_transaction_completed(struct lws *wsi);
874
875/**
876 * lws_http_headers_detach() - drop the associated headers storage and allow
877 * it to be reused by another connection
878 * \param wsi: http connection
879 *
880 * If the wsi has an ah headers struct attached, detach it.
881 */
882LWS_VISIBLE LWS_EXTERN int
883lws_http_headers_detach(struct lws *wsi);
884
885/**
886 * lws_http_mark_sse() - called to indicate this http stream is now doing SSE
887 *
888 * \param wsi: http connection
889 *
890 * Cancel any timeout on the wsi, and for h2, mark the network connection as
891 * containing an immortal stream for the duration the SSE stream is open.
892 */
893LWS_VISIBLE LWS_EXTERN int
894lws_http_mark_sse(struct lws *wsi);
895
896/**
897 * lws_h2_client_stream_long_poll_rxonly() - h2 stream to immortal read-only
898 *
899 * \param wsi: h2 stream client wsi
900 *
901 * Send END_STREAM-flagged zero-length DATA frame to set client stream wsi into
902 * half-closed (local) and remote into half-closed (remote). Set the client
903 * stream wsi to be immortal (not subject to timeouts).
904 *
905 * Used if the remote server supports immortal long poll to put the stream into
906 * a read-only state where it can wait as long as needed for rx.
907 *
908 * Returns 0 if the process (which happens asynchronously) started or non-zero
909 * if it wasn't an h2 stream.
910 */
911LWS_VISIBLE LWS_EXTERN int
913
914/**
915 * lws_http_compression_apply() - apply an http compression transform
916 *
917 * \param wsi: the wsi to apply the compression transform to
918 * \param name: NULL, or the name of the compression transform, eg, "deflate"
919 * \param p: pointer to pointer to headers buffer
920 * \param end: pointer to end of headers buffer
921 * \param decomp: 0 = add compressor to wsi, 1 = add decompressor
922 *
923 * This allows transparent compression of dynamically generated HTTP. The
924 * requested compression (eg, "deflate") is only applied if the client headers
925 * indicated it was supported (and it has support in lws), otherwise it's a NOP.
926 *
927 * If the requested compression method is NULL, then the supported compression
928 * formats are tried, and for non-decompression (server) mode the first that's
929 * found on the client's accept-encoding header is chosen.
930 *
931 * NOTE: the compression transform, same as h2 support, relies on the user
932 * code using LWS_WRITE_HTTP and then LWS_WRITE_HTTP_FINAL on the last part
933 * written. The internal lws fileserving code already does this.
934 *
935 * If the library was built without the cmake option
936 * LWS_WITH_HTTP_STREAM_COMPRESSION set, then a NOP is provided for this api,
937 * allowing user code to build either way and use compression if available.
938 */
939LWS_VISIBLE LWS_EXTERN int
940lws_http_compression_apply(struct lws *wsi, const char *name,
941 unsigned char **p, unsigned char *end, char decomp);
942
943/**
944 * lws_http_is_redirected_to_get() - true if redirected to GET
945 *
946 * \param wsi: the wsi to check
947 *
948 * Check if the wsi is currently in GET mode, after, eg, doing a POST and
949 * receiving a 303.
950 */
951LWS_VISIBLE LWS_EXTERN int
953
954/**
955 * lws_http_cookie_get() - return copy of named cookie if present
956 *
957 * \param wsi: the wsi to check
958 * \param name: name of the cookie
959 * \param buf: buffer to store the cookie contents into
960 * \param max_len: on entry, maximum length of buf... on exit, used len of buf
961 *
962 * If no cookie header, or no cookie of the requested name, or the value is
963 * larger than can fit in buf, returns nonzero.
964 *
965 * If the cookie is found, copies its value into buf with a terminating NUL,
966 * sets *max_len to the used length, and returns 0.
967 *
968 * This handles the parsing of the possibly multi-cookie header string and
969 * terminating the requested cookie at the next ; if present.
970 */
971LWS_VISIBLE LWS_EXTERN int
972lws_http_cookie_get(struct lws *wsi, const char *name, char *buf, size_t *max);
973
974/**
975 * lws_http_client_http_error() - determine if the response code indicates an error
976 *
977 * \param code: the response code to test
978 *
979 * Returns nonzero if the code indicates an error, else zero if reflects a
980 * non-error condition
981 */
982#define lws_http_client_http_resp_is_error(code) (!(code < 400))
983
984/**
985 * lws_h2_update_peer_txcredit() - manually update stream peer tx credit
986 *
987 * \param wsi: the h2 child stream whose peer credit to change
988 * \param sid: the stream ID, or LWS_H2_STREAM_SID for the wsi stream ID
989 * \param bump: signed change to confer upon peer tx credit for sid
990 *
991 * In conjunction with LCCSCF_H2_MANUAL_RXFLOW flag, allows the user code to
992 * selectively starve the remote peer of the ability to send us data on a client
993 * connection.
994 *
995 * Normally lws sends an initial window size for the peer to send to it of 0,
996 * but during the header phase it sends a WINDOW_UPDATE to increase the amount
997 * available. LCCSCF_H2_MANUAL_RXFLOW restricts this initial increase in tx
998 * credit for the stream, before it has been asked to send us anything, to the
999 * amount specified in the client info .manual_initial_tx_credit member, and
1000 * this api can be called to send the other side permission to send us up to
1001 * \p bump additional bytes.
1002 *
1003 * The nwsi tx credit is updated automatically for exactly what was sent to us
1004 * on a stream with LCCSCF_H2_MANUAL_RXFLOW flag, but the stream's own tx credit
1005 * must be handled manually by user code via this api.
1006 *
1007 * Returns 0 for success or nonzero for failure.
1008 */
1009#define LWS_H2_STREAM_SID -1
1010LWS_VISIBLE LWS_EXTERN int
1011lws_h2_update_peer_txcredit(struct lws *wsi, unsigned int sid, int bump);
1012
1013
1014/**
1015 * lws_h2_get_peer_txcredit_estimate() - return peer tx credit estimate
1016 *
1017 * \param wsi: the h2 child stream whose peer credit estimate to return
1018 *
1019 * Returns the estimated amount of tx credit at the peer, in other words the
1020 * number of bytes the peer is authorized to send to us.
1021 *
1022 * It's an 'estimate' because we don't know how much is already in flight
1023 * towards us and actually already used.
1024 */
1025LWS_VISIBLE LWS_EXTERN int
1027
1028///@}
@ LWSHUMETH_CONNECT
Definition: lws-http.h:716
@ LWSHUMETH_HEAD
Definition: lws-http.h:717
@ LWSHUMETH_OPTIONS
Definition: lws-http.h:712
@ LWSHUMETH_COLON_PATH
Definition: lws-http.h:718
@ LWSHUMETH_PATCH
Definition: lws-http.h:714
@ LWSHUMETH_PUT
Definition: lws-http.h:713
@ LWSHUMETH_GET
Definition: lws-http.h:710
@ LWSHUMETH_POST
Definition: lws-http.h:711
@ LWSHUMETH_DELETE
Definition: lws-http.h:715
unsigned short token_limit[WSI_TOKEN_COUNT]
Definition: lws-http.h:371
unsigned char * token
Definition: lws-http.h:205
LWS_VISIBLE LWS_EXTERN int lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name, int nlen)
LWS_VISIBLE LWS_EXTERN int lws_hdr_custom_name_foreach(struct lws *wsi, lws_hdr_custom_fe_cb_t cb, void *opaque)
LWS_VISIBLE LWS_EXTERN int lws_get_urlarg_by_name_safe(struct lws *wsi, const char *name, char *buf, int len)
void(* lws_hdr_custom_fe_cb_t)(const char *name, int nlen, void *opaque)
Definition: lws-http.h:498
LWS_VISIBLE LWS_EXTERN int lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen)
LWS_VISIBLE LWS_EXTERN int lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h)
lws_token_indexes
Definition: lws-http.h:215
LWS_VISIBLE LWS_EXTERN const char * lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)
LWS_VISIBLE LWS_EXTERN int lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, enum lws_token_indexes h, int frag_idx)
LWS_VISIBLE LWS_EXTERN const unsigned char * lws_token_to_string(enum lws_token_indexes token)
lws_h2_settings
Definition: lws-http.h:374
@ WSI_TOKEN_HTTP_LAST_MODIFIED
Definition: lws-http.h:294
@ WSI_TOKEN_HTTP_CONTENT_LENGTH
Definition: lws-http.h:253
@ WSI_TOKEN_HTTP_CONTENT_LANGUAGE
Definition: lws-http.h:284
@ _WSI_TOKEN_CLIENT_ALPN
Definition: lws-http.h:354
@ _WSI_TOKEN_CLIENT_SENT_PROTOCOLS
Definition: lws-http.h:346
@ WSI_TOKEN_HTTP_EXPECT
Definition: lws-http.h:288
@ _WSI_TOKEN_CLIENT_LOCALPORT
Definition: lws-http.h:353
@ WSI_TOKEN_HTTP_FROM
Definition: lws-http.h:290
@ WSI_TOKEN_DSS_SIGNATURE
Definition: lws-http.h:339
@ _WSI_TOKEN_CLIENT_URI
Definition: lws-http.h:348
@ WSI_TOKEN_HTTP_ETAG
Definition: lws-http.h:287
@ _WSI_TOKEN_CLIENT_HOST
Definition: lws-http.h:349
@ WSI_TOKEN_HTTP_CONTENT_DISPOSITION
Definition: lws-http.h:282
@ WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE
Definition: lws-http.h:293
@ _WSI_TOKEN_CLIENT_METHOD
Definition: lws-http.h:351
@ WSI_TOKEN_HTTP_IF_MATCH
Definition: lws-http.h:291
@ WSI_TOKEN_HTTP_ACCEPT
Definition: lws-http.h:241
@ WSI_INIT_TOKEN_MUXURL
Definition: lws-http.h:367
@ WSI_PARSING_COMPLETE
Definition: lws-http.h:366
@ WSI_TOKEN_HTTP_SET_COOKIE
Definition: lws-http.h:305
@ WSI_TOKEN_X_AUTH_TOKEN
Definition: lws-http.h:338
@ WSI_TOKEN_HTTP_LINK
Definition: lws-http.h:295
@ WSI_TOKEN_HTTP_ACCEPT_LANGUAGE
Definition: lws-http.h:248
@ WSI_TOKEN_HTTP_SERVER
Definition: lws-http.h:304
@ WSI_TOKEN_HTTP_CONTENT_ENCODING
Definition: lws-http.h:283
@ WSI_TOKEN_HTTP_IF_NONE_MATCH
Definition: lws-http.h:246
@ WSI_TOKEN_HTTP_IF_RANGE
Definition: lws-http.h:292
@ _WSI_TOKEN_CLIENT_PEER_ADDRESS
Definition: lws-http.h:347
@ WSI_TOKEN_HTTP_ALLOW
Definition: lws-http.h:281
@ WSI_TOKEN_HTTP_CONTENT_LOCATION
Definition: lws-http.h:285
@ WSI_TOKEN_HTTP_ACCEPT_RANGES
Definition: lws-http.h:276
@ WSI_TOKEN_HOST
Definition: lws-http.h:221
@ WSI_TOKEN_HTTP_TRANSFER_ENCODING
Definition: lws-http.h:309
@ WSI_TOKEN_HTTP
Definition: lws-http.h:237
@ WSI_TOKEN_HTTP_URI_ARGS
Definition: lws-http.h:322
@ WSI_TOKEN_POST_URI
Definition: lws-http.h:217
@ WSI_TOKEN_HTTP_RETRY_AFTER
Definition: lws-http.h:303
@ WSI_TOKEN_HTTP_EXPIRES
Definition: lws-http.h:289
@ WSI_TOKEN_HTTP_IF_MODIFIED_SINCE
Definition: lws-http.h:245
@ WSI_TOKEN_HEAD_URI
Definition: lws-http.h:330
@ WSI_TOKEN_COUNT
Definition: lws-http.h:357
@ WSI_TOKEN_HTTP_COOKIE
Definition: lws-http.h:252
@ WSI_TOKEN_HTTP_CONTENT_RANGE
Definition: lws-http.h:286
@ WSI_TOKEN_HTTP_CACHE_CONTROL
Definition: lws-http.h:250
@ WSI_TOKEN_SKIPPING_SAW_CR
Definition: lws-http.h:365
@ WSI_TOKEN_HTTP_REFRESH
Definition: lws-http.h:302
@ WSI_TOKEN_HTTP_RANGE
Definition: lws-http.h:256
@ _WSI_TOKEN_CLIENT_ORIGIN
Definition: lws-http.h:350
@ WSI_TOKEN_NAME_PART
Definition: lws-http.h:360
@ WSI_TOKEN_UPGRADE
Definition: lws-http.h:223
@ WSI_TOKEN_X_FORWARDED_FOR
Definition: lws-http.h:328
@ WSI_TOKEN_SKIPPING
Definition: lws-http.h:364
@ WSI_TOKEN_CONNECT
Definition: lws-http.h:329
@ WSI_TOKEN_CONNECTION
Definition: lws-http.h:222
@ WSI_TOKEN_HTTP_ACCEPT_ENCODING
Definition: lws-http.h:247
@ WSI_TOKEN_ORIGIN
Definition: lws-http.h:224
@ WSI_TOKEN_HTTP_CONTENT_TYPE
Definition: lws-http.h:254
@ WSI_TOKEN_HTTP_LOCATION
Definition: lws-http.h:296
@ WSI_TOKEN_HTTP_AUTHORIZATION
Definition: lws-http.h:251
@ WSI_TOKEN_GET_URI
Definition: lws-http.h:216
@ WSI_TOKEN_HTTP_AGE
Definition: lws-http.h:280
@ WSI_TOKEN_HTTP_DATE
Definition: lws-http.h:255
@ WSI_TOKEN_HTTP_PRAGMA
Definition: lws-http.h:249
@ WSI_TOKEN_CHALLENGE
Definition: lws-http.h:228
@ WSI_TOKEN_HTTP1_0
Definition: lws-http.h:327
@ _WSI_TOKEN_CLIENT_IFACE
Definition: lws-http.h:352
@ H2SET_MAX_HEADER_LIST_SIZE
Definition: lws-http.h:380
@ H2SET_HEADER_TABLE_SIZE
Definition: lws-http.h:375
@ H2SET_MAX_CONCURRENT_STREAMS
Definition: lws-http.h:377
@ H2SET_INITIAL_WINDOW_SIZE
Definition: lws-http.h:378
@ H2SET_ENABLE_PUSH
Definition: lws-http.h:376
@ H2SET_MAX_FRAME_SIZE
Definition: lws-http.h:379
@ H2SET_COUNT
Definition: lws-http.h:384
@ H2SET_ENABLE_CONNECT_PROTOCOL
Definition: lws-http.h:382
@ H2SET_RESERVED7
Definition: lws-http.h:381
LWS_VISIBLE LWS_EXTERN const char * lws_get_mimetype(const char *file, const struct lws_http_mount *m)
LWS_VISIBLE LWS_EXTERN int lws_http_compression_apply(struct lws *wsi, const char *name, unsigned char **p, unsigned char *end, char decomp)
LWS_VISIBLE LWS_EXTERN int lws_http_mark_sse(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_http_date_parse_unix(const char *b, size_t len, time_t *t)
LWS_VISIBLE LWS_EXTERN int lws_serve_http_file_fragment(struct lws *wsi)
const char *const * vars
Definition: lws-http.h:148
LWS_VISIBLE LWS_EXTERN int lws_http_check_retry_after(struct lws *wsi, lws_usec_t *us_interval_in_out)
LWS_VISIBLE LWS_EXTERN int lws_chunked_html_process(struct lws_process_html_args *args, struct lws_process_html_state *s)
lws_process_html_state_cb replace
Definition: lws-http.h:151
LWS_VISIBLE LWS_EXTERN int lws_h2_get_peer_txcredit_estimate(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_http_date_render_from_unix(char *buf, size_t len, const time_t *t)
LWS_VISIBLE LWS_EXTERN int lws_urldecode(char *string, const char *escaped, int len)
LWS_VISIBLE LWS_EXTERN const char * lws_urlencode(char *escaped, const char *string, int len)
LWS_VISIBLE LWS_EXTERN int lws_h2_update_peer_txcredit(struct lws *wsi, unsigned int sid, int bump)
LWS_VISIBLE LWS_EXTERN int lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, const char *other_headers, int other_headers_len)
http_status
Definition: lws-http.h:83
@ HTTP_STATUS_EXPECTATION_FAILED
Definition: lws-http.h:112
@ HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE
Definition: lws-http.h:110
@ HTTP_STATUS_NOT_ACCEPTABLE
Definition: lws-http.h:101
@ HTTP_STATUS_REQ_URI_TOO_LONG
Definition: lws-http.h:109
@ HTTP_STATUS_INTERNAL_SERVER_ERROR
Definition: lws-http.h:114
@ HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE
Definition: lws-http.h:111
@ HTTP_STATUS_REQUEST_TIMEOUT
Definition: lws-http.h:103
@ HTTP_STATUS_PROXY_AUTH_REQUIRED
Definition: lws-http.h:102
@ HTTP_STATUS_FORBIDDEN
Definition: lws-http.h:98
@ HTTP_STATUS_BAD_REQUEST
Definition: lws-http.h:95
@ HTTP_STATUS_FOUND
Definition: lws-http.h:91
@ HTTP_STATUS_METHOD_NOT_ALLOWED
Definition: lws-http.h:100
@ HTTP_STATUS_GONE
Definition: lws-http.h:105
@ HTTP_STATUS_NOT_MODIFIED
Definition: lws-http.h:93
@ HTTP_STATUS_CONFLICT
Definition: lws-http.h:104
@ HTTP_STATUS_MOVED_PERMANENTLY
Definition: lws-http.h:90
@ HTTP_STATUS_PARTIAL_CONTENT
Definition: lws-http.h:88
@ HTTP_STATUS_REQ_ENTITY_TOO_LARGE
Definition: lws-http.h:108
@ HTTP_STATUS_SERVICE_UNAVAILABLE
Definition: lws-http.h:117
@ HTTP_STATUS_LENGTH_REQUIRED
Definition: lws-http.h:106
@ HTTP_STATUS_PRECONDITION_FAILED
Definition: lws-http.h:107
@ HTTP_STATUS_BAD_GATEWAY
Definition: lws-http.h:116
@ HTTP_STATUS_NOT_IMPLEMENTED
Definition: lws-http.h:115
@ HTTP_STATUS_NO_CONTENT
Definition: lws-http.h:87
@ HTTP_STATUS_OK
Definition: lws-http.h:86
@ HTTP_STATUS_CONTINUE
Definition: lws-http.h:84
@ HTTP_STATUS_UNAUTHORIZED
Definition: lws-http.h:96
@ HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED
Definition: lws-http.h:119
@ HTTP_STATUS_SEE_OTHER
Definition: lws-http.h:92
@ HTTP_STATUS_GATEWAY_TIMEOUT
Definition: lws-http.h:118
@ HTTP_STATUS_NOT_FOUND
Definition: lws-http.h:99
@ HTTP_STATUS_PAYMENT_REQUIRED
Definition: lws-http.h:97
LWS_VISIBLE LWS_EXTERN int lws_return_http_status(struct lws *wsi, unsigned int code, const char *html_body)
LWS_VISIBLE LWS_EXTERN int lws_http_is_redirected_to_get(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_http_cookie_get(struct lws *wsi, const char *name, char *buf, size_t *max)
LWS_VISIBLE LWS_EXTERN int lws_http_headers_detach(struct lws *wsi)
const char *(* lws_process_html_state_cb)(void *data, int index)
Definition: lws-http.h:141
LWS_VISIBLE LWS_EXTERN int lws_h2_client_stream_long_poll_rxonly(struct lws *wsi)