1 | /* |
2 | * libwebsockets - small server side websockets and web server implementation |
3 | * |
4 | * Copyright (C) 2010 - 2021 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 | /*! \defgroup client Client related functions |
26 | * ##Client releated functions |
27 | * \ingroup lwsapi |
28 | * |
29 | * */ |
30 | ///@{ |
31 | |
32 | /** enum lws_client_connect_ssl_connection_flags - flags that may be used |
33 | * with struct lws_client_connect_info ssl_connection member to control if |
34 | * and how SSL checks apply to the client connection being created |
35 | */ |
36 | |
37 | enum lws_client_connect_ssl_connection_flags { |
38 | LCCSCF_USE_SSL = (1 << 0), |
39 | LCCSCF_ALLOW_SELFSIGNED = (1 << 1), |
40 | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK = (1 << 2), |
41 | LCCSCF_ALLOW_EXPIRED = (1 << 3), |
42 | LCCSCF_ALLOW_INSECURE = (1 << 4), |
43 | LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM = (1 << 5), |
44 | LCCSCF_H2_QUIRK_OVERFLOWS_TXCR = (1 << 6), |
45 | LCCSCF_H2_AUTH_BEARER = (1 << 7), |
46 | LCCSCF_H2_HEXIFY_AUTH_TOKEN = (1 << 8), |
47 | LCCSCF_H2_MANUAL_RXFLOW = (1 << 9), |
48 | LCCSCF_HTTP_MULTIPART_MIME = (1 << 10), |
49 | LCCSCF_HTTP_X_WWW_FORM_URLENCODED = (1 << 11), |
50 | LCCSCF_HTTP_NO_FOLLOW_REDIRECT = (1 << 12), |
51 | |
52 | LCCSCF_PIPELINE = (1 << 16), |
53 | /**< Serialize / pipeline multiple client connections |
54 | * on a single connection where possible. |
55 | * |
56 | * HTTP/1.0: possible if Keep-Alive: yes sent by server |
57 | * HTTP/1.1: always possible... uses pipelining |
58 | * HTTP/2: always possible... uses parallel streams |
59 | */ |
60 | LCCSCF_MUXABLE_STREAM = (1 << 17), |
61 | LCCSCF_H2_PRIOR_KNOWLEDGE = (1 << 18), |
62 | LCCSCF_WAKE_SUSPEND__VALIDITY = (1 << 19), |
63 | /* our validity checks are important enough to wake from suspend */ |
64 | LCCSCF_PRIORITIZE_READS = (1 << 20), |
65 | /**< |
66 | * Normally lws balances reads and writes on all connections, so both |
67 | * are possible even on busy connections, and we go around the event |
68 | * loop more often to facilitate that, even if there is pending data. |
69 | * |
70 | * This flag indicates that you want to handle any pending reads on this |
71 | * connection without yielding the service loop for anything else. This |
72 | * means you may block other connection processing in favour of incoming |
73 | * data processing on this one if it receives back to back incoming rx. |
74 | */ |
75 | LCCSCF_SECSTREAM_CLIENT = (1 << 21), |
76 | /**< used to mark client wsi as bound to secure stream */ |
77 | LCCSCF_SECSTREAM_PROXY_LINK = (1 << 22), |
78 | /**< client is a link between SS client and SS proxy */ |
79 | LCCSCF_SECSTREAM_PROXY_ONWARD = (1 << 23), |
80 | /**< client the SS proxy's onward connection */ |
81 | |
82 | LCCSCF_IP_LOW_LATENCY = (1 << 24), |
83 | /**< set the "low delay" bit on the IP packets of this connection */ |
84 | LCCSCF_IP_HIGH_THROUGHPUT = (1 << 25), |
85 | /**< set the "high throughput" bit on the IP packets of this |
86 | * connection */ |
87 | LCCSCF_IP_HIGH_RELIABILITY = (1 << 26), |
88 | /**< set the "high reliability" bit on the IP packets of this |
89 | * connection */ |
90 | LCCSCF_IP_LOW_COST = (1 << 27), |
91 | /**< set the "minimize monetary cost" bit on the IP packets of this |
92 | * connection */ |
93 | LCCSCF_CONMON = (1 << 28), |
94 | /**< If LWS_WITH_CONMON enabled for build, keeps a copy of the |
95 | * getaddrinfo results so they can be queried subsequently */ |
96 | LCCSCF_ACCEPT_TLS_DOWNGRADE_REDIRECTS = (1 << 29), |
97 | /**< By default lws rejects https redirecting to http. Set this |
98 | * flag on the client connection to allow it. */ |
99 | LCCSCF_CACHE_COOKIES = (1 << 30), |
100 | /**< If built with -DLWS_WITH_CACHE_NSCOOKIEJAR, store and reapply |
101 | * http cookies in a Netscape Cookie Jar on this connection */ |
102 | }; |
103 | |
104 | /** struct lws_client_connect_info - parameters to connect with when using |
105 | * lws_client_connect_via_info() */ |
106 | |
107 | struct lws_client_connect_info { |
108 | struct lws_context *context; |
109 | /**< lws context to create connection in */ |
110 | const char *address; |
111 | /**< remote address to connect to */ |
112 | int port; |
113 | /**< remote port to connect to */ |
114 | int ssl_connection; |
115 | /**< 0, or a combination of LCCSCF_ flags */ |
116 | const char *path; |
117 | /**< URI path. Prefix with + for a UNIX socket. (+@ for |
118 | * a Linux abstract-namespace socket) */ |
119 | const char *host; |
120 | /**< content of host header */ |
121 | const char *origin; |
122 | /**< content of origin header */ |
123 | const char *protocol; |
124 | /**< list of ws protocols we could accept */ |
125 | int ietf_version_or_minus_one; |
126 | /**< deprecated: currently leave at 0 or -1 */ |
127 | void *userdata; |
128 | /**< if non-NULL, use this as wsi user_data instead of malloc it */ |
129 | const void *client_exts; |
130 | /**< UNUSED... provide in info.extensions at context creation time */ |
131 | const char *method; |
132 | /**< if non-NULL, do this http method instead of ws[s] upgrade. |
133 | * use "GET" to be a simple http client connection. "RAW" gets |
134 | * you a connected socket that lws itself will leave alone once |
135 | * connected. */ |
136 | struct lws *parent_wsi; |
137 | /**< if another wsi is responsible for this connection, give it here. |
138 | * this is used to make sure if the parent closes so do any |
139 | * child connections first. */ |
140 | const char *uri_replace_from; |
141 | /**< if non-NULL, when this string is found in URIs in |
142 | * text/html content-encoding, it's replaced with uri_replace_to */ |
143 | const char *uri_replace_to; |
144 | /**< see uri_replace_from */ |
145 | struct lws_vhost *vhost; |
146 | /**< vhost to bind to (used to determine related SSL_CTX) */ |
147 | struct lws **pwsi; |
148 | /**< if not NULL, store the new wsi here early in the connection |
149 | * process. Although we return the new wsi, the call to create the |
150 | * client connection does progress the connection somewhat and may |
151 | * meet an error that will result in the connection being scrubbed and |
152 | * NULL returned. While the wsi exists though, he may process a |
153 | * callback like CLIENT_CONNECTION_ERROR with his wsi: this gives the |
154 | * user callback a way to identify which wsi it is that faced the error |
155 | * even before the new wsi is returned and even if ultimately no wsi |
156 | * is returned. |
157 | */ |
158 | const char *iface; |
159 | /**< NULL to allow routing on any interface, or interface name or IP |
160 | * to bind the socket to */ |
161 | const char *local_protocol_name; |
162 | /**< NULL: .protocol is used both to select the local protocol handler |
163 | * to bind to and as the list of remote ws protocols we could |
164 | * accept. |
165 | * non-NULL: this protocol name is used to bind the connection to |
166 | * the local protocol handler. .protocol is used for the |
167 | * list of remote ws protocols we could accept */ |
168 | const char *alpn; |
169 | /**< NULL: allow lws default ALPN list, from vhost if present or from |
170 | * list of roles built into lws |
171 | * non-NULL: require one from provided comma-separated list of alpn |
172 | * tokens |
173 | */ |
174 | |
175 | struct lws_sequencer *seq; |
176 | /**< NULL, or an lws_seq_t that wants to be given messages about |
177 | * this wsi's lifecycle as it connects, errors or closes. |
178 | */ |
179 | |
180 | void *opaque_user_data; |
181 | /**< This data has no meaning to lws but is applied to the client wsi |
182 | * and can be retrieved by user code with lws_get_opaque_user_data(). |
183 | * It's also provided with sequencer messages if the wsi is bound to |
184 | * an lws_seq_t. |
185 | */ |
186 | |
187 | const lws_retry_bo_t *retry_and_idle_policy; |
188 | /**< optional retry and idle policy to apply to this connection. |
189 | * Currently only the idle parts are applied to the connection. |
190 | */ |
191 | |
192 | int manual_initial_tx_credit; |
193 | /**< if LCCSCF_H2_MANUAL_REFLOW is set, this becomes the initial tx |
194 | * credit for the stream. |
195 | */ |
196 | |
197 | uint8_t sys_tls_client_cert; |
198 | /**< 0 means no client cert. 1+ means apply lws_system client cert 0+ |
199 | * to the client connection. |
200 | */ |
201 | |
202 | uint8_t priority; |
203 | /**< 0 means normal priority... otherwise sets the IP priority on |
204 | * packets coming from this connection, from 1 - 7. Setting 7 |
205 | * (network management priority) requires CAP_NET_ADMIN capability but |
206 | * the others can be set by anyone. |
207 | */ |
208 | |
209 | #if defined(LWS_ROLE_MQTT) |
210 | const lws_mqtt_client_connect_param_t *mqtt_cp; |
211 | #else |
212 | void *mqtt_cp; |
213 | #endif |
214 | |
215 | #if defined(LWS_WITH_SYS_FAULT_INJECTION) |
216 | lws_fi_ctx_t fic; |
217 | /**< Attach external Fault Injection context to the client wsi, |
218 | * hierarchy is wsi -> vhost -> context */ |
219 | #endif |
220 | /* for convenience, available when FI disabled in build */ |
221 | const char *fi_wsi_name; |
222 | /**< specific Fault Injection namespace name for wsi created for this |
223 | * connection, allows targeting by "wsi=XXX/..." if you give XXX here. |
224 | */ |
225 | |
226 | uint16_t keep_warm_secs; |
227 | /**< 0 means 5s. If the client connection to the endpoint becomes idle, |
228 | * defer closing it for this many seconds in case another outgoing |
229 | * connection to the same endpoint turns up. |
230 | */ |
231 | |
232 | lws_log_cx_t *log_cx; |
233 | /**< NULL to use lws_context log context, else a pointer to a log |
234 | * context template to take a copy of for this wsi. Used to isolate |
235 | * wsi-specific logs into their own stream or file. |
236 | */ |
237 | |
238 | /* Add new things just above here ---^ |
239 | * This is part of the ABI, don't needlessly break compatibility |
240 | * |
241 | * The below is to ensure later library versions with new |
242 | * members added above will see 0 (default) even if the app |
243 | * was not built against the newer headers. |
244 | */ |
245 | |
246 | void *_unused[4]; /**< dummy */ |
247 | }; |
248 | |
249 | /** |
250 | * lws_client_connect_via_info() - Connect to another websocket server |
251 | * \param ccinfo: pointer to lws_client_connect_info struct |
252 | * |
253 | * This function creates a connection to a remote server using the |
254 | * information provided in ccinfo. |
255 | */ |
256 | LWS_VISIBLE LWS_EXTERN struct lws * |
257 | lws_client_connect_via_info(const struct lws_client_connect_info *ccinfo); |
258 | |
259 | /** |
260 | * lws_init_vhost_client_ssl() - also enable client SSL on an existing vhost |
261 | * |
262 | * \param info: client ssl related info |
263 | * \param vhost: which vhost to initialize client ssl operations on |
264 | * |
265 | * You only need to call this if you plan on using SSL client connections on |
266 | * the vhost. For non-SSL client connections, it's not necessary to call this. |
267 | * |
268 | * The following members of info are used during the call |
269 | * |
270 | * - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set, |
271 | * otherwise the call does nothing |
272 | * - provided_client_ssl_ctx must be NULL to get a generated client |
273 | * ssl context, otherwise you can pass a prepared one in by setting it |
274 | * - ssl_cipher_list may be NULL or set to the client valid cipher list |
275 | * - ssl_ca_filepath may be NULL or client cert filepath |
276 | * - ssl_cert_filepath may be NULL or client cert filepath |
277 | * - ssl_private_key_filepath may be NULL or client cert private key |
278 | * |
279 | * You must create your vhost explicitly if you want to use this, so you have |
280 | * a pointer to the vhost. Create the context first with the option flag |
281 | * LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with |
282 | * the same info struct. |
283 | */ |
284 | LWS_VISIBLE LWS_EXTERN int |
285 | lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, |
286 | struct lws_vhost *vhost); |
287 | /** |
288 | * lws_http_client_read() - consume waiting received http client data |
289 | * |
290 | * \param wsi: client connection |
291 | * \param buf: pointer to buffer pointer - fill with pointer to your buffer |
292 | * \param len: pointer to chunk length - fill with max length of buffer |
293 | * |
294 | * This is called when the user code is notified client http data has arrived. |
295 | * The user code may choose to delay calling it to consume the data, for example |
296 | * waiting until an onward connection is writeable. |
297 | * |
298 | * For non-chunked connections, up to len bytes of buf are filled with the |
299 | * received content. len is set to the actual amount filled before return. |
300 | * |
301 | * For chunked connections, the linear buffer content contains the chunking |
302 | * headers and it cannot be passed in one lump. Instead, this function will |
303 | * call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the |
304 | * chunk start and len set to the chunk length. There will be as many calls |
305 | * as there are chunks or partial chunks in the buffer. |
306 | */ |
307 | LWS_VISIBLE LWS_EXTERN int |
308 | lws_http_client_read(struct lws *wsi, char **buf, int *len); |
309 | |
310 | /** |
311 | * lws_http_client_http_response() - get last HTTP response code |
312 | * |
313 | * \param wsi: client connection |
314 | * |
315 | * Returns the last server response code, eg, 200 for client http connections. |
316 | * If there is no valid response, it will return 0. |
317 | * |
318 | * You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP |
319 | * callback, because after that the memory reserved for storing the related |
320 | * headers is freed and this value is lost. |
321 | */ |
322 | LWS_VISIBLE LWS_EXTERN unsigned int |
323 | lws_http_client_http_response(struct lws *wsi); |
324 | |
325 | /** |
326 | * lws_tls_client_vhost_extra_cert_mem() - add more certs to vh client tls ctx |
327 | * |
328 | * \param vh: the vhost to give more client certs to |
329 | * \param der: pointer to der format additional cert |
330 | * \param der_len: size in bytes of der |
331 | * |
332 | * After the vhost is created with one cert for client verification, you |
333 | * can add additional, eg, intermediate, certs to the client tls context |
334 | * of the vhost, for use with validating the incoming server cert(s). |
335 | */ |
336 | LWS_VISIBLE LWS_EXTERN int |
337 | (struct lws_vhost *vh, |
338 | const uint8_t *der, size_t der_len); |
339 | |
340 | /** |
341 | * lws_client_http_body_pending() - control if client connection needs to send body |
342 | * |
343 | * \param wsi: client connection |
344 | * \param something_left_to_send: nonzero if need to send more body, 0 (default) |
345 | * if nothing more to send |
346 | * |
347 | * If you will send payload data with your HTTP client connection, eg, for POST, |
348 | * when you set the related http headers in |
349 | * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call |
350 | * this API with something_left_to_send nonzero, and call |
351 | * lws_callback_on_writable(wsi); |
352 | * |
353 | * After sending the headers, lws will call your callback with |
354 | * LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send the |
355 | * next part of the http body payload, calling lws_callback_on_writable(wsi); |
356 | * if there is more to come, or lws_client_http_body_pending(wsi, 0); to |
357 | * let lws know the last part is sent and the connection can move on. |
358 | */ |
359 | LWS_VISIBLE LWS_EXTERN void |
360 | lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); |
361 | |
362 | /** |
363 | * lws_client_http_multipart() - issue appropriate multipart header or trailer |
364 | * |
365 | * \param wsi: client connection |
366 | * \param name: multipart header name field, or NULL if end of multipart |
367 | * \param filename: multipart header filename field, or NULL if none |
368 | * \param content_type: multipart header content-type part, or NULL if none |
369 | * \param p: pointer to position in buffer |
370 | * \param end: end of buffer |
371 | * |
372 | * This issues a multipart mime boundary, or terminator if name = NULL. |
373 | * |
374 | * Returns 0 if OK or nonzero if couldn't fit in buffer |
375 | */ |
376 | LWS_VISIBLE LWS_EXTERN int |
377 | lws_client_http_multipart(struct lws *wsi, const char *name, |
378 | const char *filename, const char *content_type, |
379 | char **p, char *end); |
380 | |
381 | /** |
382 | * lws_http_basic_auth_gen() - helper to encode client basic auth string |
383 | * |
384 | * \param user: user name |
385 | * \param pw: password |
386 | * \param buf: where to store base64 result |
387 | * \param len: max usable size of buf |
388 | * |
389 | * Encodes a username and password in Basic Auth format for use with the |
390 | * Authorization header. On return, buf is filled with something like |
391 | * "Basic QWxhZGRpbjpPcGVuU2VzYW1l". |
392 | */ |
393 | LWS_VISIBLE LWS_EXTERN int |
394 | lws_http_basic_auth_gen(const char *user, const char *pw, char *buf, size_t len); |
395 | |
396 | /** |
397 | * lws_tls_session_is_reused() - returns nonzero if tls session was cached |
398 | * |
399 | * \param wsi: the wsi |
400 | * |
401 | * Returns zero if the tls session is fresh, else nonzero if the tls session was |
402 | * taken from the cache. If lws is built with LWS_WITH_TLS_SESSIONS and the vhost |
403 | * was created with the option LWS_SERVER_OPTION_ENABLE_TLS_SESSION_CACHE, then |
404 | * on full tls session establishment of a client connection, the session is added |
405 | * to the tls cache. |
406 | * |
407 | * This lets you find out if your session was new (0) or from the cache (nonzero), |
408 | * it'a mainly useful for stats and testing. |
409 | */ |
410 | LWS_VISIBLE LWS_EXTERN int |
411 | lws_tls_session_is_reused(struct lws *wsi); |
412 | |
413 | ///@} |
414 | |