Viewing file: lws-http.h (26.31 KB) -rw-rw-r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* * libwebsockets - small server side websockets and web server implementation * * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation: * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * included from libwebsockets.h */
/* minimal space for typical headers and CSP stuff */
#define LWS_RECOMMENDED_MIN_HEADER_SPACE 2048
/*! \defgroup http HTTP
Modules related to handling HTTP */ //@{
/*! \defgroup httpft HTTP File transfer * \ingroup http
APIs for sending local files in response to HTTP requests */ //@{
/** * lws_get_mimetype() - Determine mimetype to use from filename * * \param file: filename * \param m: NULL, or mount context * * This uses a canned list of known filetypes first, if no match and m is * non-NULL, then tries a list of per-mount file suffix to mimtype mappings. * * Returns either NULL or a pointer to the mimetype matching the file. */ LWS_VISIBLE LWS_EXTERN const char * lws_get_mimetype(const char *file, const struct lws_http_mount *m);
/** * lws_serve_http_file() - Send a file back to the client using http * \param wsi: Websocket instance (available from user callback) * \param file: The file to issue over http * \param content_type: The http content type, eg, text/html * \param other_headers: NULL or pointer to header string * \param other_headers_len: length of the other headers if non-NULL * * This function is intended to be called from the callback in response * to http requests from the client. It allows the callback to issue * local files down the http link in a single step. * * Returning <0 indicates error and the wsi should be closed. Returning * >0 indicates the file was completely sent and * lws_http_transaction_completed() called on the wsi (and close if != 0) * ==0 indicates the file transfer is started and needs more service later, * the wsi should be left alone. */ 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);
LWS_VISIBLE LWS_EXTERN int lws_serve_http_file_fragment(struct lws *wsi); //@}
enum http_status { HTTP_STATUS_CONTINUE = 100,
HTTP_STATUS_OK = 200, HTTP_STATUS_NO_CONTENT = 204, HTTP_STATUS_PARTIAL_CONTENT = 206,
HTTP_STATUS_MOVED_PERMANENTLY = 301, HTTP_STATUS_FOUND = 302, HTTP_STATUS_SEE_OTHER = 303, HTTP_STATUS_NOT_MODIFIED = 304,
HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_UNAUTHORIZED, HTTP_STATUS_PAYMENT_REQUIRED, HTTP_STATUS_FORBIDDEN, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_METHOD_NOT_ALLOWED, HTTP_STATUS_NOT_ACCEPTABLE, HTTP_STATUS_PROXY_AUTH_REQUIRED, HTTP_STATUS_REQUEST_TIMEOUT, HTTP_STATUS_CONFLICT, HTTP_STATUS_GONE, HTTP_STATUS_LENGTH_REQUIRED, HTTP_STATUS_PRECONDITION_FAILED, HTTP_STATUS_REQ_ENTITY_TOO_LARGE, HTTP_STATUS_REQ_URI_TOO_LONG, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, HTTP_STATUS_EXPECTATION_FAILED,
HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, HTTP_STATUS_NOT_IMPLEMENTED, HTTP_STATUS_BAD_GATEWAY, HTTP_STATUS_SERVICE_UNAVAILABLE, HTTP_STATUS_GATEWAY_TIMEOUT, HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, }; /*! \defgroup html-chunked-substitution HTML Chunked Substitution * \ingroup http * * ##HTML chunked Substitution * * APIs for receiving chunks of text, replacing a set of variable names via * a callback, and then prepending and appending HTML chunked encoding * headers. */ //@{
struct lws_process_html_args { char *p; /**< pointer to the buffer containing the data */ int len; /**< length of the original data at p */ int max_len; /**< maximum length we can grow the data to */ int final; /**< set if this is the last chunk of the file */ int chunked; /**< 0 == unchunked, 1 == produce chunk headers (incompatible with HTTP/2) */ };
typedef const char *(*lws_process_html_state_cb)(void *data, int index);
struct lws_process_html_state { char *start; /**< pointer to start of match */ char swallow[16]; /**< matched character buffer */ int pos; /**< position in match */ void *data; /**< opaque pointer */ const char * const *vars; /**< list of variable names */ int count_vars; /**< count of variable names */
lws_process_html_state_cb replace; /**< called on match to perform substitution */ };
/*! lws_chunked_html_process() - generic chunked substitution * \param args: buffer to process using chunked encoding * \param s: current processing state */ LWS_VISIBLE LWS_EXTERN int lws_chunked_html_process(struct lws_process_html_args *args, struct lws_process_html_state *s); //@}
/** \defgroup HTTP-headers-read HTTP headers: read * \ingroup http * * ##HTTP header releated functions * * In lws the client http headers are temporarily stored in a pool, only for the * duration of the http part of the handshake. It's because in most cases, * the header content is ignored for the whole rest of the connection lifetime * and would then just be taking up space needlessly. * * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time * the http headers are still allocated, you can use these apis then to * look at and copy out interesting header content (cookies, etc) * * Notice that the header total length reported does not include a terminating * '\0', however you must allocate for it when using the _copy apis. So the * length reported for a header containing "123" is 3, but you must provide * a buffer of length 4 so that "123\0" may be copied into it, or the copy * will fail with a nonzero return code. * * In the special case of URL arguments, like ?x=1&y=2, the arguments are * stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it * was a GET or WSI_TOKEN_POST_URI if POST. You can check the total * length to confirm the method. * * For URL arguments, each argument is stored urldecoded in a "fragment", so * you can use the fragment-aware api lws_hdr_copy_fragment() to access each * argument in turn: the fragments contain urldecoded strings like x=1 or y=2. * * As a convenience, lws has an api that will find the fragment with a * given name= part, lws_get_urlarg_by_name(). */ ///@{
/** struct lws_tokens * you need these to look at headers that have been parsed if using the * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum * list below is absent, .token = NULL and len = 0. Otherwise .token * points to .len chars containing that header content. */ struct lws_tokens { unsigned char *token; /**< pointer to start of the token */ int len; /**< length of the token's value */ };
/* enum lws_token_indexes * these have to be kept in sync with lextable.h / minilex.c * * NOTE: These public enums are part of the abi. If you want to add one, * add it at where specified so existing users are unaffected. */ enum lws_token_indexes { WSI_TOKEN_GET_URI = 0, WSI_TOKEN_POST_URI = 1, WSI_TOKEN_OPTIONS_URI = 2, WSI_TOKEN_HOST = 3, WSI_TOKEN_CONNECTION = 4, WSI_TOKEN_UPGRADE = 5, WSI_TOKEN_ORIGIN = 6, WSI_TOKEN_DRAFT = 7, WSI_TOKEN_CHALLENGE = 8, WSI_TOKEN_EXTENSIONS = 9, WSI_TOKEN_KEY1 = 10, WSI_TOKEN_KEY2 = 11, WSI_TOKEN_PROTOCOL = 12, WSI_TOKEN_ACCEPT = 13, WSI_TOKEN_NONCE = 14, WSI_TOKEN_HTTP = 15, WSI_TOKEN_HTTP2_SETTINGS = 16, WSI_TOKEN_HTTP_ACCEPT = 17, WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, WSI_TOKEN_HTTP_PRAGMA = 23, WSI_TOKEN_HTTP_CACHE_CONTROL = 24, WSI_TOKEN_HTTP_AUTHORIZATION = 25, WSI_TOKEN_HTTP_COOKIE = 26, WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, WSI_TOKEN_HTTP_CONTENT_TYPE = 28, WSI_TOKEN_HTTP_DATE = 29, WSI_TOKEN_HTTP_RANGE = 30, WSI_TOKEN_HTTP_REFERER = 31, WSI_TOKEN_KEY = 32, WSI_TOKEN_VERSION = 33, WSI_TOKEN_SWORIGIN = 34,
WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, WSI_TOKEN_HTTP_COLON_METHOD = 36, WSI_TOKEN_HTTP_COLON_PATH = 37, WSI_TOKEN_HTTP_COLON_SCHEME = 38, WSI_TOKEN_HTTP_COLON_STATUS = 39,
WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, WSI_TOKEN_HTTP_AGE = 43, WSI_TOKEN_HTTP_ALLOW = 44, WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, WSI_TOKEN_HTTP_CONTENT_RANGE = 49, WSI_TOKEN_HTTP_ETAG = 50, WSI_TOKEN_HTTP_EXPECT = 51, WSI_TOKEN_HTTP_EXPIRES = 52, WSI_TOKEN_HTTP_FROM = 53, WSI_TOKEN_HTTP_IF_MATCH = 54, WSI_TOKEN_HTTP_IF_RANGE = 55, WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, WSI_TOKEN_HTTP_LAST_MODIFIED = 57, WSI_TOKEN_HTTP_LINK = 58, WSI_TOKEN_HTTP_LOCATION = 59, WSI_TOKEN_HTTP_MAX_FORWARDS = 60, WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, WSI_TOKEN_HTTP_REFRESH = 63, WSI_TOKEN_HTTP_RETRY_AFTER = 64, WSI_TOKEN_HTTP_SERVER = 65, WSI_TOKEN_HTTP_SET_COOKIE = 66, WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, WSI_TOKEN_HTTP_USER_AGENT = 69, WSI_TOKEN_HTTP_VARY = 70, WSI_TOKEN_HTTP_VIA = 71, WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72,
WSI_TOKEN_PATCH_URI = 73, WSI_TOKEN_PUT_URI = 74, WSI_TOKEN_DELETE_URI = 75,
WSI_TOKEN_HTTP_URI_ARGS = 76, WSI_TOKEN_PROXY = 77, WSI_TOKEN_HTTP_X_REAL_IP = 78, WSI_TOKEN_HTTP1_0 = 79, WSI_TOKEN_X_FORWARDED_FOR = 80, WSI_TOKEN_CONNECT = 81, WSI_TOKEN_HEAD_URI = 82, WSI_TOKEN_TE = 83, WSI_TOKEN_REPLAY_NONCE = 84, WSI_TOKEN_COLON_PROTOCOL = 85, WSI_TOKEN_X_AUTH_TOKEN = 86,
/****** add new things just above ---^ ******/
/* use token storage to stash these internally, not for * user use */
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS, _WSI_TOKEN_CLIENT_PEER_ADDRESS, _WSI_TOKEN_CLIENT_URI, _WSI_TOKEN_CLIENT_HOST, _WSI_TOKEN_CLIENT_ORIGIN, _WSI_TOKEN_CLIENT_METHOD, _WSI_TOKEN_CLIENT_IFACE, _WSI_TOKEN_CLIENT_ALPN,
/* always last real token index*/ WSI_TOKEN_COUNT,
/* parser state additions, no storage associated */ WSI_TOKEN_NAME_PART, #if defined(LWS_WITH_CUSTOM_HEADERS) WSI_TOKEN_UNKNOWN_VALUE_PART, #endif WSI_TOKEN_SKIPPING, WSI_TOKEN_SKIPPING_SAW_CR, WSI_PARSING_COMPLETE, WSI_INIT_TOKEN_MUXURL, };
struct lws_token_limits { unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */ };
/** * lws_token_to_string() - returns a textual representation of a hdr token index * * \param token: token index */ LWS_VISIBLE LWS_EXTERN const unsigned char * lws_token_to_string(enum lws_token_indexes token);
/** * lws_hdr_total_length: report length of all fragments of a header totalled up * The returned length does not include the space for a * terminating '\0' * * \param wsi: websocket connection * \param h: which header index we are interested in */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
/** * lws_hdr_fragment_length: report length of a single fragment of a header * The returned length does not include the space for a * terminating '\0' * * \param wsi: websocket connection * \param h: which header index we are interested in * \param frag_idx: which fragment of h we want to get the length of */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx);
/** * lws_hdr_copy() - copy all fragments of the given header to a buffer * The buffer length len must include space for an additional * terminating '\0', or it will fail returning -1. * * \param wsi: websocket connection * \param dest: destination buffer * \param len: length of destination buffer * \param h: which header index we are interested in * * copies the whole, aggregated header, even if it was delivered in * several actual headers piece by piece. Returns -1 or length of the whole * header. */ LWS_VISIBLE LWS_EXTERN int lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h);
/** * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer * The buffer length len must include space for an additional * terminating '\0', or it will fail returning -1. * If the requested fragment index is not present, it fails * returning -1. * * \param wsi: websocket connection * \param dest: destination buffer * \param len: length of destination buffer * \param h: which header index we are interested in * \param frag_idx: which fragment of h we want to copy * * Normally this is only useful * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS * fragment 0 will contain "x=1" and fragment 1 "y=2" */ 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_hdr_custom_length() - return length of a custom header * * \param wsi: websocket connection * \param name: header string (including terminating :) * \param nlen: length of name * * Lws knows about 100 common http headers, and parses them into indexes when * it recognizes them. When it meets a header that it doesn't know, it stores * the name and value directly, and you can look them up using * lws_hdr_custom_length() and lws_hdr_custom_copy(). * * This api returns -1, or the length of the value part of the header if it * exists. Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to * use this api. */ LWS_VISIBLE LWS_EXTERN int lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen);
/** * lws_hdr_custom_copy() - copy value part of a custom header * * \param wsi: websocket connection * \param dst: pointer to buffer to receive the copy * \param len: number of bytes available at dst * \param name: header string (including terminating :) * \param nlen: length of name * * Lws knows about 100 common http headers, and parses them into indexes when * it recognizes them. When it meets a header that it doesn't know, it stores * the name and value directly, and you can look them up using * lws_hdr_custom_length() and lws_hdr_custom_copy(). * * This api returns -1, or the length of the string it copied into dst if it * was big enough to contain both the string and an extra terminating NUL. Lws * must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to use this api. */ LWS_VISIBLE LWS_EXTERN int lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name, int nlen);
/** * lws_get_urlarg_by_name() - return pointer to arg value if present * \param wsi: the connection to check * \param name: the arg name, like "token=" * \param buf: the buffer to receive the urlarg (including the name= part) * \param len: the length of the buffer to receive the urlarg * * Returns NULL if not found or a pointer inside buf to just after the * name= part. */ LWS_VISIBLE LWS_EXTERN const char * lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len); ///@}
/*! \defgroup HTTP-headers-create HTTP headers: create * * ## HTTP headers: Create * * These apis allow you to create HTTP response headers in a way compatible with * both HTTP/1.x and HTTP/2. * * They each append to a buffer taking care about the buffer end, which is * passed in as a pointer. When data is written to the buffer, the current * position p is updated accordingly. * * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space * and fail with nonzero return. */ ///@{
#define LWSAHH_CODE_MASK ((1 << 16) - 1) #define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30)
/** * lws_add_http_header_status() - add the HTTP response status code * * \param wsi: the connection to check * \param code: an HTTP code like 200, 404 etc (see enum http_status) * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Adds the initial response code, so should be called first. * * Code may additionally take OR'd flags: * * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_add_http_header_status(struct lws *wsi, unsigned int code, unsigned char **p, unsigned char *end); /** * lws_add_http_header_by_name() - append named header and value * * \param wsi: the connection to check * \param name: the hdr name, like "my-header" * \param value: the value after the = for this header * \param length: the length of the value * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Appends name: value to the headers */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, const unsigned char *value, int length, unsigned char **p, unsigned char *end); /** * lws_add_http_header_by_token() - append given header and value * * \param wsi: the connection to check * \param token: the token index for the hdr * \param value: the value after the = for this header * \param length: the length of the value * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Appends name=value to the headers, but is able to take advantage of better * HTTP/2 coding mechanisms where possible. */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, const unsigned char *value, int length, unsigned char **p, unsigned char *end); /** * lws_add_http_header_content_length() - append content-length helper * * \param wsi: the connection to check * \param content_length: the content length to use * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Appends content-length: content_length to the headers */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_add_http_header_content_length(struct lws *wsi, lws_filepos_t content_length, unsigned char **p, unsigned char *end); /** * lws_finalize_http_header() - terminate header block * * \param wsi: the connection to check * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Indicates no more headers will be added */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_finalize_http_header(struct lws *wsi, unsigned char **p, unsigned char *end);
/** * lws_finalize_write_http_header() - Helper finializing and writing http headers * * \param wsi: the connection to check * \param start: pointer to the start of headers in the buffer, eg &buf[LWS_PRE] * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Terminates the headers correctly accoring to the protocol in use (h1 / h2) * and writes the headers. Returns nonzero for error. */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_finalize_write_http_header(struct lws *wsi, unsigned char *start, unsigned char **p, unsigned char *end);
#define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll)
/** * lws_add_http_common_headers() - Helper preparing common http headers * * \param wsi: the connection to check * \param code: an HTTP code like 200, 404 etc (see enum http_status) * \param content_type: the content type, like "text/html" * \param content_len: the content length, in bytes * \param p: pointer to current position in buffer pointer * \param end: pointer to end of buffer * * Adds the initial response code, so should be called first. * * Code may additionally take OR'd flags: * * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time * * This helper just calls public apis to simplify adding headers that are * commonly needed. If it doesn't fit your case, or you want to add additional * headers just call the public apis directly yourself for what you want. * * You can miss out the content length header by providing the constant * LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len. * * It does not call lws_finalize_http_header(), to allow you to add further * headers after calling this. You will need to call that yourself at the end. */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_add_http_common_headers(struct lws *wsi, unsigned int code, const char *content_type, lws_filepos_t content_len, unsigned char **p, unsigned char *end);
/** * lws_http_get_uri_and_method() - Get information on method and url * * \param wsi: the connection to get information on * \param puri_ptr: points to pointer to set to url * \param puri_len: points to int to set to uri length * * Returns -1 or method index * * GET 0 * POST 1 * OPTIONS 2 * PUT 3 * PATCH 4 * DELETE 5 * CONNECT 6 * HEAD 7 * :path 8 * * If returns method, *puri_ptr is set to the method's URI string and *puri_len * to its length */
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len);
///@}
/*! \defgroup urlendec Urlencode and Urldecode * \ingroup http * * ##HTML chunked Substitution * * APIs for receiving chunks of text, replacing a set of variable names via * a callback, and then prepending and appending HTML chunked encoding * headers. */ //@{
/** * lws_urlencode() - like strncpy but with urlencoding * * \param escaped: output buffer * \param string: input buffer ('/0' terminated) * \param len: output buffer max length * * Because urlencoding expands the output string, it's not * possible to do it in-place, ie, with escaped == string */ LWS_VISIBLE LWS_EXTERN const char * lws_urlencode(char *escaped, const char *string, int len);
/* * URLDECODE 1 / 2 * * This simple urldecode only operates until the first '\0' and requires the * data to exist all at once */ /** * lws_urldecode() - like strncpy but with urldecoding * * \param string: output buffer * \param escaped: input buffer ('\0' terminated) * \param len: output buffer max length * * This is only useful for '\0' terminated strings * * Since urldecoding only shrinks the output string, it is possible to * do it in-place, ie, string == escaped * * Returns 0 if completed OK or nonzero for urldecode violation (non-hex chars * where hex required, etc) */ LWS_VISIBLE LWS_EXTERN int lws_urldecode(char *string, const char *escaped, int len); ///@}
/** * lws_return_http_status() - Return simple http status * \param wsi: Websocket instance (available from user callback) * \param code: Status index, eg, 404 * \param html_body: User-readable HTML description < 1KB, or NULL * * Helper to report HTTP errors back to the client cleanly and * consistently */ LWS_VISIBLE LWS_EXTERN int lws_return_http_status(struct lws *wsi, unsigned int code, const char *html_body);
/** * lws_http_redirect() - write http redirect out on wsi * * \param wsi: websocket connection * \param code: HTTP response code (eg, 301) * \param loc: where to redirect to * \param len: length of loc * \param p: pointer current position in buffer (updated as we write) * \param end: pointer to end of buffer * * Returns amount written, or < 0 indicating fatal write failure. */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, unsigned char **p, unsigned char *end);
/** * lws_http_transaction_completed() - wait for new http transaction or close * \param wsi: websocket connection * * Returns 1 if the HTTP connection must close now * Returns 0 and resets connection to wait for new HTTP header / * transaction if possible */ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_http_transaction_completed(struct lws *wsi);
/** * lws_http_headers_detach() - drop the associated headers storage and allow * it to be reused by another connection * \param wsi: http connection * * If the wsi has an ah headers struct attached, detach it. */ LWS_VISIBLE LWS_EXTERN int lws_http_headers_detach(struct lws *wsi);
/** * lws_http_mark_sse() - called to indicate this http stream is now doing SSE * * \param wsi: http connection * * Cancel any timeout on the wsi, and for h2, mark the network connection as * containing an immortal stream for the duration the SSE stream is open. */ LWS_VISIBLE LWS_EXTERN int lws_http_mark_sse(struct lws *wsi);
/** * lws_http_compression_apply() - apply an http compression transform * * \param wsi: the wsi to apply the compression transform to * \param name: NULL, or the name of the compression transform, eg, "deflate" * \param p: pointer to pointer to headers buffer * \param end: pointer to end of headers buffer * \param decomp: 0 = add compressor to wsi, 1 = add decompressor * * This allows transparent compression of dynamically generated HTTP. The * requested compression (eg, "deflate") is only applied if the client headers * indicated it was supported (and it has support in lws), otherwise it's a NOP. * * If the requested compression method is NULL, then the supported compression * formats are tried, and for non-decompression (server) mode the first that's * found on the client's accept-encoding header is chosen. * * NOTE: the compression transform, same as h2 support, relies on the user * code using LWS_WRITE_HTTP and then LWS_WRITE_HTTP_FINAL on the last part * written. The internal lws fileserving code already does this. * * If the library was built without the cmake option * LWS_WITH_HTTP_STREAM_COMPRESSION set, then a NOP is provided for this api, * allowing user code to build either way and use compression if available. */ LWS_VISIBLE int lws_http_compression_apply(struct lws *wsi, const char *name, unsigned char **p, unsigned char *end, char decomp); ///@}
|