• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 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  */
53 LWS_VISIBLE LWS_EXTERN const char *
54 lws_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  */
74 LWS_VISIBLE LWS_EXTERN int
75 lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
76 		    const char *other_headers, int other_headers_len);
77 
78 LWS_VISIBLE LWS_EXTERN int
79 lws_serve_http_file_fragment(struct lws *wsi);
80 //@}
81 
82 
83 enum 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 
132 struct 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 
141 typedef const char *(*lws_process_html_state_cb)(void *data, int index);
142 
143 struct 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  */
159 LWS_VISIBLE LWS_EXTERN int
160 lws_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  */
204 struct 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  */
215 enum lws_token_indexes {
216 	WSI_TOKEN_GET_URI, /* 0 */
217 	WSI_TOKEN_POST_URI,
218 #if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
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)
226 	WSI_TOKEN_DRAFT,
227 #endif
228 	WSI_TOKEN_CHALLENGE,
229 #if defined(LWS_ROLE_WS)
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)
239 	WSI_TOKEN_HTTP2_SETTINGS, /* 16 */
240 #endif
241 	WSI_TOKEN_HTTP_ACCEPT,
242 #if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
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)
258 	WSI_TOKEN_HTTP_REFERER,
259 #endif
260 #if defined(LWS_ROLE_WS)
261 	WSI_TOKEN_KEY,
262 	WSI_TOKEN_VERSION,
263 	WSI_TOKEN_SWORIGIN,
264 #endif
265 #if defined(LWS_ROLE_H2)
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)
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)
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)
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)
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)
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)
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)
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)
332 	WSI_TOKEN_TE,
333 	WSI_TOKEN_REPLAY_NONCE, /* ACME */
334 #endif
335 #if defined(LWS_ROLE_H2)
336 	WSI_TOKEN_COLON_PROTOCOL,
337 #endif
338 	WSI_TOKEN_X_AUTH_TOKEN,
339 
340 	/****** add new things just above ---^ ******/
341 
342 	/* use token storage to stash these internally, not for
343 	 * user use */
344 
345 	_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
346 	_WSI_TOKEN_CLIENT_PEER_ADDRESS,
347 	_WSI_TOKEN_CLIENT_URI,
348 	_WSI_TOKEN_CLIENT_HOST,
349 	_WSI_TOKEN_CLIENT_ORIGIN,
350 	_WSI_TOKEN_CLIENT_METHOD,
351 	_WSI_TOKEN_CLIENT_IFACE,
352 	_WSI_TOKEN_CLIENT_ALPN,
353 
354 	/* always last real token index*/
355 	WSI_TOKEN_COUNT,
356 
357 	/* parser state additions, no storage associated */
358 	WSI_TOKEN_NAME_PART,
359 #if defined(LWS_WITH_CUSTOM_HEADERS)
360 	WSI_TOKEN_UNKNOWN_VALUE_PART,
361 #endif
362 	WSI_TOKEN_SKIPPING,
363 	WSI_TOKEN_SKIPPING_SAW_CR,
364 	WSI_PARSING_COMPLETE,
365 	WSI_INIT_TOKEN_MUXURL,
366 };
367 
368 struct lws_token_limits {
369 	unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */
370 };
371 
372 enum lws_h2_settings {
373 	H2SET_HEADER_TABLE_SIZE = 1,
374 	H2SET_ENABLE_PUSH,
375 	H2SET_MAX_CONCURRENT_STREAMS,
376 	H2SET_INITIAL_WINDOW_SIZE,
377 	H2SET_MAX_FRAME_SIZE,
378 	H2SET_MAX_HEADER_LIST_SIZE,
379 	H2SET_RESERVED7,
380 	H2SET_ENABLE_CONNECT_PROTOCOL, /* defined in mcmanus-httpbis-h2-ws-02 */
381 
382 	H2SET_COUNT /* always last */
383 };
384 
385 /**
386  * lws_token_to_string() - returns a textual representation of a hdr token index
387  *
388  * \param token: token index
389  */
390 LWS_VISIBLE LWS_EXTERN const unsigned char *
391 lws_token_to_string(enum lws_token_indexes token);
392 
393 /**
394  * lws_hdr_total_length: report length of all fragments of a header totalled up
395  *		The returned length does not include the space for a
396  *		terminating '\0'
397  *
398  * \param wsi: websocket connection
399  * \param h: which header index we are interested in
400  */
401 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
402 lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h);
403 
404 /**
405  * lws_hdr_fragment_length: report length of a single fragment of a header
406  *		The returned length does not include the space for a
407  *		terminating '\0'
408  *
409  * \param wsi: websocket connection
410  * \param h: which header index we are interested in
411  * \param frag_idx: which fragment of h we want to get the length of
412  */
413 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
414 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h,
415 			int frag_idx);
416 
417 /**
418  * lws_hdr_copy() - copy all fragments of the given header to a buffer
419  *		The buffer length len must include space for an additional
420  *		terminating '\0', or it will fail returning -1.
421  *
422  * \param wsi: websocket connection
423  * \param dest: destination buffer
424  * \param len: length of destination buffer
425  * \param h: which header index we are interested in
426  *
427  * copies the whole, aggregated header, even if it was delivered in
428  * several actual headers piece by piece.  Returns -1 or length of the whole
429  * header.
430  */
431 LWS_VISIBLE LWS_EXTERN int
432 lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h);
433 
434 /**
435  * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer
436  *		The buffer length len must include space for an additional
437  *		terminating '\0', or it will fail returning -1.
438  *		If the requested fragment index is not present, it fails
439  *		returning -1.
440  *
441  * \param wsi: websocket connection
442  * \param dest: destination buffer
443  * \param len: length of destination buffer
444  * \param h: which header index we are interested in
445  * \param frag_idx: which fragment of h we want to copy
446  *
447  * Normally this is only useful
448  * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS
449  * fragment 0 will contain "x=1" and fragment 1 "y=2"
450  */
451 LWS_VISIBLE LWS_EXTERN int
452 lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len,
453 		      enum lws_token_indexes h, int frag_idx);
454 
455 /**
456  * lws_hdr_custom_length() - return length of a custom header
457  *
458  * \param wsi: websocket connection
459  * \param name: header string (including terminating :)
460  * \param nlen: length of name
461  *
462  * Lws knows about 100 common http headers, and parses them into indexes when
463  * it recognizes them.  When it meets a header that it doesn't know, it stores
464  * the name and value directly, and you can look them up using
465  * lws_hdr_custom_length() and lws_hdr_custom_copy().
466  *
467  * This api returns -1, or the length of the value part of the header if it
468  * exists.  Lws must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to
469  * use this api.
470  */
471 LWS_VISIBLE LWS_EXTERN int
472 lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen);
473 
474 /**
475  * lws_hdr_custom_copy() - copy value part of a custom header
476  *
477  * \param wsi: websocket connection
478  * \param dst: pointer to buffer to receive the copy
479  * \param len: number of bytes available at dst
480  * \param name: header string (including terminating :)
481  * \param nlen: length of name
482  *
483  * Lws knows about 100 common http headers, and parses them into indexes when
484  * it recognizes them.  When it meets a header that it doesn't know, it stores
485  * the name and value directly, and you can look them up using
486  * lws_hdr_custom_length() and lws_hdr_custom_copy().
487  *
488  * This api returns -1, or the length of the string it copied into dst if it
489  * was big enough to contain both the string and an extra terminating NUL. Lws
490  * must be built with LWS_WITH_CUSTOM_HEADERS (on by default) to use this api.
491  */
492 LWS_VISIBLE LWS_EXTERN int
493 lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name,
494 		    int nlen);
495 
496 /**
497  * lws_get_urlarg_by_name() - return pointer to arg value if present
498  * \param wsi: the connection to check
499  * \param name: the arg name, like "token="
500  * \param buf: the buffer to receive the urlarg (including the name= part)
501  * \param len: the length of the buffer to receive the urlarg
502  *
503  *     Returns NULL if not found or a pointer inside buf to just after the
504  *     name= part.
505  */
506 LWS_VISIBLE LWS_EXTERN const char *
507 lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len);
508 ///@}
509 
510 /*! \defgroup HTTP-headers-create HTTP headers: create
511  *
512  * ## HTTP headers: Create
513  *
514  * These apis allow you to create HTTP response headers in a way compatible with
515  * both HTTP/1.x and HTTP/2.
516  *
517  * They each append to a buffer taking care about the buffer end, which is
518  * passed in as a pointer.  When data is written to the buffer, the current
519  * position p is updated accordingly.
520  *
521  * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space
522  * and fail with nonzero return.
523  */
524 ///@{
525 
526 #define LWSAHH_CODE_MASK			((1 << 16) - 1)
527 #define LWSAHH_FLAG_NO_SERVER_NAME		(1 << 30)
528 
529 /**
530  * lws_add_http_header_status() - add the HTTP response status code
531  *
532  * \param wsi: the connection to check
533  * \param code: an HTTP code like 200, 404 etc (see enum http_status)
534  * \param p: pointer to current position in buffer pointer
535  * \param end: pointer to end of buffer
536  *
537  * Adds the initial response code, so should be called first.
538  *
539  * Code may additionally take OR'd flags:
540  *
541  *    LWSAHH_FLAG_NO_SERVER_NAME:  don't apply server name header this time
542  */
543 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
544 lws_add_http_header_status(struct lws *wsi,
545 			   unsigned int code, unsigned char **p,
546 			   unsigned char *end);
547 /**
548  * lws_add_http_header_by_name() - append named header and value
549  *
550  * \param wsi: the connection to check
551  * \param name: the hdr name, like "my-header"
552  * \param value: the value after the = for this header
553  * \param length: the length of the value
554  * \param p: pointer to current position in buffer pointer
555  * \param end: pointer to end of buffer
556  *
557  * Appends name: value to the headers
558  */
559 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
560 lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name,
561 			    const unsigned char *value, int length,
562 			    unsigned char **p, unsigned char *end);
563 /**
564  * lws_add_http_header_by_token() - append given header and value
565  *
566  * \param wsi: the connection to check
567  * \param token: the token index for the hdr
568  * \param value: the value after the = for this header
569  * \param length: the length of the value
570  * \param p: pointer to current position in buffer pointer
571  * \param end: pointer to end of buffer
572  *
573  * Appends name=value to the headers, but is able to take advantage of better
574  * HTTP/2 coding mechanisms where possible.
575  */
576 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
577 lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token,
578 			     const unsigned char *value, int length,
579 			     unsigned char **p, unsigned char *end);
580 /**
581  * lws_add_http_header_content_length() - append content-length helper
582  *
583  * \param wsi: the connection to check
584  * \param content_length: the content length to use
585  * \param p: pointer to current position in buffer pointer
586  * \param end: pointer to end of buffer
587  *
588  * Appends content-length: content_length to the headers
589  */
590 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
591 lws_add_http_header_content_length(struct lws *wsi,
592 				   lws_filepos_t content_length,
593 				   unsigned char **p, unsigned char *end);
594 /**
595  * lws_finalize_http_header() - terminate header block
596  *
597  * \param wsi: the connection to check
598  * \param p: pointer to current position in buffer pointer
599  * \param end: pointer to end of buffer
600  *
601  * Indicates no more headers will be added
602  */
603 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
604 lws_finalize_http_header(struct lws *wsi, unsigned char **p,
605 			 unsigned char *end);
606 
607 /**
608  * lws_finalize_write_http_header() - Helper finializing and writing http headers
609  *
610  * \param wsi: the connection to check
611  * \param start: pointer to the start of headers in the buffer, eg &buf[LWS_PRE]
612  * \param p: pointer to current position in buffer pointer
613  * \param end: pointer to end of buffer
614  *
615  * Terminates the headers correctly accoring to the protocol in use (h1 / h2)
616  * and writes the headers.  Returns nonzero for error.
617  */
618 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
619 lws_finalize_write_http_header(struct lws *wsi, unsigned char *start,
620 			       unsigned char **p, unsigned char *end);
621 
622 #define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll)
623 
624 /**
625  * lws_add_http_common_headers() - Helper preparing common http headers
626  *
627  * \param wsi: the connection to check
628  * \param code: an HTTP code like 200, 404 etc (see enum http_status)
629  * \param content_type: the content type, like "text/html"
630  * \param content_len: the content length, in bytes
631  * \param p: pointer to current position in buffer pointer
632  * \param end: pointer to end of buffer
633  *
634  * Adds the initial response code, so should be called first.
635  *
636  * Code may additionally take OR'd flags:
637  *
638  *    LWSAHH_FLAG_NO_SERVER_NAME:  don't apply server name header this time
639  *
640  * This helper just calls public apis to simplify adding headers that are
641  * commonly needed.  If it doesn't fit your case, or you want to add additional
642  * headers just call the public apis directly yourself for what you want.
643  *
644  * You can miss out the content length header by providing the constant
645  * LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len.
646  *
647  * It does not call lws_finalize_http_header(), to allow you to add further
648  * headers after calling this.  You will need to call that yourself at the end.
649  */
650 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
651 lws_add_http_common_headers(struct lws *wsi, unsigned int code,
652 			    const char *content_type, lws_filepos_t content_len,
653 			    unsigned char **p, unsigned char *end);
654 
655 enum {
656 	LWSHUMETH_GET,
657 	LWSHUMETH_POST,
658 	LWSHUMETH_OPTIONS,
659 	LWSHUMETH_PUT,
660 	LWSHUMETH_PATCH,
661 	LWSHUMETH_DELETE,
662 	LWSHUMETH_CONNECT,
663 	LWSHUMETH_HEAD,
664 	LWSHUMETH_COLON_PATH,
665 };
666 
667 /**
668  * lws_http_get_uri_and_method() - Get information on method and url
669  *
670  * \param wsi: the connection to get information on
671  * \param puri_ptr: points to pointer to set to url
672  * \param puri_len: points to int to set to uri length
673  *
674  * Returns -1 or method index as one of the LWSHUMETH_ constants
675  *
676  * If returns method, *puri_ptr is set to the method's URI string and *puri_len
677  * to its length
678  */
679 
680 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
681 lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len);
682 
683 ///@}
684 
685 /*! \defgroup urlendec Urlencode and Urldecode
686  * \ingroup http
687  *
688  * ##HTML chunked Substitution
689  *
690  * APIs for receiving chunks of text, replacing a set of variable names via
691  * a callback, and then prepending and appending HTML chunked encoding
692  * headers.
693  */
694 //@{
695 
696 /**
697  * lws_urlencode() - like strncpy but with urlencoding
698  *
699  * \param escaped: output buffer
700  * \param string: input buffer ('/0' terminated)
701  * \param len: output buffer max length
702  *
703  * Because urlencoding expands the output string, it's not
704  * possible to do it in-place, ie, with escaped == string
705  */
706 LWS_VISIBLE LWS_EXTERN const char *
707 lws_urlencode(char *escaped, const char *string, int len);
708 
709 /*
710  * URLDECODE 1 / 2
711  *
712  * This simple urldecode only operates until the first '\0' and requires the
713  * data to exist all at once
714  */
715 /**
716  * lws_urldecode() - like strncpy but with urldecoding
717  *
718  * \param string: output buffer
719  * \param escaped: input buffer ('\0' terminated)
720  * \param len: output buffer max length
721  *
722  * This is only useful for '\0' terminated strings
723  *
724  * Since urldecoding only shrinks the output string, it is possible to
725  * do it in-place, ie, string == escaped
726  *
727  * Returns 0 if completed OK or nonzero for urldecode violation (non-hex chars
728  * where hex required, etc)
729  */
730 LWS_VISIBLE LWS_EXTERN int
731 lws_urldecode(char *string, const char *escaped, int len);
732 ///@}
733 
734 /**
735  * lws_return_http_status() - Return simple http status
736  * \param wsi:		Websocket instance (available from user callback)
737  * \param code:		Status index, eg, 404
738  * \param html_body:		User-readable HTML description < 1KB, or NULL
739  *
740  *	Helper to report HTTP errors back to the client cleanly and
741  *	consistently
742  */
743 LWS_VISIBLE LWS_EXTERN int
744 lws_return_http_status(struct lws *wsi, unsigned int code,
745 		       const char *html_body);
746 
747 /**
748  * lws_http_redirect() - write http redirect out on wsi
749  *
750  * \param wsi:	websocket connection
751  * \param code:	HTTP response code (eg, 301)
752  * \param loc:	where to redirect to
753  * \param len:	length of loc
754  * \param p:	pointer current position in buffer (updated as we write)
755  * \param end:	pointer to end of buffer
756  *
757  * Returns amount written, or < 0 indicating fatal write failure.
758  */
759 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
760 lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
761 		  unsigned char **p, unsigned char *end);
762 
763 /**
764  * lws_http_transaction_completed() - wait for new http transaction or close
765  * \param wsi:	websocket connection
766  *
767  *	Returns 1 if the HTTP connection must close now
768  *	Returns 0 and resets connection to wait for new HTTP header /
769  *	  transaction if possible
770  */
771 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
772 lws_http_transaction_completed(struct lws *wsi);
773 
774 /**
775  * lws_http_headers_detach() - drop the associated headers storage and allow
776  *				it to be reused by another connection
777  * \param wsi:	http connection
778  *
779  * If the wsi has an ah headers struct attached, detach it.
780  */
781 LWS_VISIBLE LWS_EXTERN int
782 lws_http_headers_detach(struct lws *wsi);
783 
784 /**
785  * lws_http_mark_sse() - called to indicate this http stream is now doing SSE
786  *
787  * \param wsi:	http connection
788  *
789  * Cancel any timeout on the wsi, and for h2, mark the network connection as
790  * containing an immortal stream for the duration the SSE stream is open.
791  */
792 LWS_VISIBLE LWS_EXTERN int
793 lws_http_mark_sse(struct lws *wsi);
794 
795 /**
796  * lws_h2_client_stream_long_poll_rxonly() - h2 stream to immortal read-only
797  *
798  * \param wsi: h2 stream client wsi
799  *
800  * Send END_STREAM-flagged zero-length DATA frame to set client stream wsi into
801  * half-closed (local) and remote into half-closed (remote).  Set the client
802  * stream wsi to be immortal (not subject to timeouts).
803  *
804  * Used if the remote server supports immortal long poll to put the stream into
805  * a read-only state where it can wait as long as needed for rx.
806  *
807  * Returns 0 if the process (which happens asynchronously) started or non-zero
808  * if it wasn't an h2 stream.
809  */
810 LWS_VISIBLE LWS_EXTERN int
811 lws_h2_client_stream_long_poll_rxonly(struct lws *wsi);
812 
813 /**
814  * lws_http_compression_apply() - apply an http compression transform
815  *
816  * \param wsi: the wsi to apply the compression transform to
817  * \param name: NULL, or the name of the compression transform, eg, "deflate"
818  * \param p: pointer to pointer to headers buffer
819  * \param end: pointer to end of headers buffer
820  * \param decomp: 0 = add compressor to wsi, 1 = add decompressor
821  *
822  * This allows transparent compression of dynamically generated HTTP.  The
823  * requested compression (eg, "deflate") is only applied if the client headers
824  * indicated it was supported (and it has support in lws), otherwise it's a NOP.
825  *
826  * If the requested compression method is NULL, then the supported compression
827  * formats are tried, and for non-decompression (server) mode the first that's
828  * found on the client's accept-encoding header is chosen.
829  *
830  * NOTE: the compression transform, same as h2 support, relies on the user
831  * code using LWS_WRITE_HTTP and then LWS_WRITE_HTTP_FINAL on the last part
832  * written.  The internal lws fileserving code already does this.
833  *
834  * If the library was built without the cmake option
835  * LWS_WITH_HTTP_STREAM_COMPRESSION set, then a NOP is provided for this api,
836  * allowing user code to build either way and use compression if available.
837  */
838 LWS_VISIBLE LWS_EXTERN int
839 lws_http_compression_apply(struct lws *wsi, const char *name,
840 			   unsigned char **p, unsigned char *end, char decomp);
841 
842 /**
843  * lws_http_is_redirected_to_get() - true if redirected to GET
844  *
845  * \param wsi: the wsi to check
846  *
847  * Check if the wsi is currently in GET mode, after, eg, doing a POST and
848  * receiving a 303.
849  */
850 LWS_VISIBLE LWS_EXTERN int
851 lws_http_is_redirected_to_get(struct lws *wsi);
852 
853 /**
854  * lws_h2_update_peer_txcredit() - manually update stream peer tx credit
855  *
856  * \param wsi: the h2 child stream whose peer credit to change
857  * \param sid: the stream ID, or LWS_H2_STREAM_SID for the wsi stream ID
858  * \param bump: signed change to confer upon peer tx credit for sid
859  *
860  * In conjunction with LCCSCF_H2_MANUAL_RXFLOW flag, allows the user code to
861  * selectively starve the remote peer of the ability to send us data on a client
862  * connection.
863  *
864  * Normally lws sends an initial window size for the peer to send to it of 0,
865  * but during the header phase it sends a WINDOW_UPDATE to increase the amount
866  * available.  LCCSCF_H2_MANUAL_RXFLOW restricts this initial increase in tx
867  * credit for the stream, before it has been asked to send us anything, to the
868  * amount specified in the client info .manual_initial_tx_credit member, and
869  * this api can be called to send the other side permission to send us up to
870  * \p bump additional bytes.
871  *
872  * The nwsi tx credit is updated automatically for exactly what was sent to us
873  * on a stream with LCCSCF_H2_MANUAL_RXFLOW flag, but the stream's own tx credit
874  * must be handled manually by user code via this api.
875  *
876  * Returns 0 for success or nonzero for failure.
877  */
878 #define LWS_H2_STREAM_SID -1
879 LWS_VISIBLE LWS_EXTERN int
880 lws_h2_update_peer_txcredit(struct lws *wsi, int sid, int bump);
881 
882 
883 /**
884  * lws_h2_get_peer_txcredit_estimate() - return peer tx credit estimate
885  *
886  * \param wsi: the h2 child stream whose peer credit estimate to return
887  *
888  * Returns the estimated amount of tx credit at the peer, in other words the
889  * number of bytes the peer is authorized to send to us.
890  *
891  * It's an 'estimate' because we don't know how much is already in flight
892  * towards us and actually already used.
893  */
894 LWS_VISIBLE LWS_EXTERN int
895 lws_h2_get_peer_txcredit_estimate(struct lws *wsi);
896 
897 ///@}
898 
899