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 #include "private-lib-core.h"
26 
27 void
lws_client_http_body_pending(struct lws * wsi,int something_left_to_send)28 lws_client_http_body_pending(struct lws *wsi, int something_left_to_send)
29 {
30 	wsi->client_http_body_pending = !!something_left_to_send;
31 }
32 
33 int
lws_http_client_socket_service(struct lws * wsi,struct lws_pollfd * pollfd)34 lws_http_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd)
35 {
36 	struct lws_context *context = wsi->a.context;
37 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
38 	char *p = (char *)&pt->serv_buf[0];
39 #if defined(LWS_WITH_TLS)
40 	char ebuf[128];
41 #endif
42 	const char *cce = NULL;
43 	char *sb = p;
44 	int n = 0;
45 
46 	switch (lwsi_state(wsi)) {
47 
48 	case LRS_WAITING_DNS:
49 		/*
50 		 * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
51 		 * timeout protection set in client-handshake.c
52 		 */
53 		lwsl_err("%s: %s: WAITING_DNS\n", __func__, lws_wsi_tag(wsi));
54 		if (!lws_client_connect_2_dnsreq(wsi)) {
55 			/* closed */
56 			lwsl_client("closed\n");
57 			return -1;
58 		}
59 
60 		/* either still pending connection, or changed mode */
61 		return 0;
62 
63 	case LRS_WAITING_CONNECT:
64 
65 		/*
66 		 * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
67 		 * timeout protection set in client-handshake.c
68 		 */
69 		if (pollfd->revents & LWS_POLLOUT)
70 			if (lws_client_connect_3_connect(wsi, NULL, NULL, 0, NULL) == NULL) {
71 				lwsl_client("closed\n");
72 				return -1;
73 			}
74 		break;
75 
76 #if defined(LWS_WITH_SOCKS5)
77 	/* SOCKS Greeting Reply */
78 	case LRS_WAITING_SOCKS_GREETING_REPLY:
79 	case LRS_WAITING_SOCKS_AUTH_REPLY:
80 	case LRS_WAITING_SOCKS_CONNECT_REPLY:
81 
82 		switch (lws_socks5c_handle_state(wsi, pollfd, &cce)) {
83 		case LW5CHS_RET_RET0:
84 			return 0;
85 		case LW5CHS_RET_BAIL3:
86 			goto bail3;
87 		case LW5CHS_RET_STARTHS:
88 			goto start_ws_handshake;
89 		default:
90 			break;
91 		}
92 		break;
93 #endif
94 
95 #if defined(LWS_CLIENT_HTTP_PROXYING) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2))
96 
97 	case LRS_WAITING_PROXY_REPLY:
98 
99 		/* handle proxy hung up on us */
100 
101 		if (pollfd->revents & LWS_POLLHUP) {
102 
103 			lwsl_warn("Proxy conn %s (fd=%d) dead\n",
104 				  lws_wsi_tag(wsi), pollfd->fd);
105 
106 			cce = "proxy conn dead";
107 			goto bail3;
108 		}
109 
110 		n = (int)recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
111 		if (n < 0) {
112 			if (LWS_ERRNO == LWS_EAGAIN) {
113 				lwsl_debug("Proxy read EAGAIN... retrying\n");
114 				return 0;
115 			}
116 			lwsl_err("ERROR reading from proxy socket\n");
117 			cce = "proxy read err";
118 			goto bail3;
119 		}
120 
121 		/* sanity check what we were sent... */
122 
123 		pt->serv_buf[13] = '\0';
124 		if (n < 13 || strncmp(sb, "HTTP/1.", 7) ||
125 			      (sb[7] != '0' && sb[7] != '1') || sb[8] != ' ') {
126 			/* lwsl_hexdump_notice(sb, n); */
127 			cce = "http_proxy fail";
128 			goto bail3;
129 		}
130 
131 		/* it's h1 alright... what's his logical response code? */
132 		n = atoi(&sb[9]);
133 		if (n != 200) {
134 			lws_snprintf(sb, 20, "http_proxy -> %u",
135 				     (unsigned int)n);
136 			cce = sb;
137 			goto bail3;
138 		}
139 
140 		lwsl_info("%s: proxy connection extablished\n", __func__);
141 
142 		/* clear his proxy connection timeout */
143 
144 		lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
145 
146                /* fallthru */
147 
148 #endif
149 
150                /* dummy fallthru to satisfy compiler */
151                /* fallthru */
152 	case LRS_H1C_ISSUE_HANDSHAKE:
153 
154 		lwsl_debug("%s: LRS_H1C_ISSUE_HANDSHAKE\n", __func__);
155 
156 		/*
157 		 * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
158 		 * timeout protection set in client-handshake.c
159 		 *
160 		 * take care of our lws_callback_on_writable
161 		 * happening at a time when there's no real connection yet
162 		 */
163 #if defined(LWS_WITH_SOCKS5)
164 start_ws_handshake:
165 #endif
166 		if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
167 			return -1;
168 
169 #if defined(LWS_ROLE_H2) || defined(LWS_WITH_TLS)
170 		if (
171 #if defined(LWS_WITH_TLS)
172 		    !(wsi->tls.use_ssl & LCCSCF_USE_SSL)
173 #endif
174 #if defined(LWS_ROLE_H2) && defined(LWS_WITH_TLS)
175 		    &&
176 #endif
177 #if defined(LWS_ROLE_H2)
178 		    !(wsi->flags & LCCSCF_H2_PRIOR_KNOWLEDGE)
179 #endif
180 		    )
181 			goto hs2;
182 #endif
183 
184 #if defined(LWS_WITH_TLS)
185 		n = lws_client_create_tls(wsi, &cce, 1);
186 		if (n == CCTLS_RETURN_ERROR)
187 			goto bail3;
188 		if (n == CCTLS_RETURN_RETRY)
189 			return 0;
190 
191 		/*
192 		 * lws_client_create_tls() can already have done the
193 		 * whole tls setup and preface send... if so he set our state
194 		 * to LRS_H1C_ISSUE_HANDSHAKE2... let's proceed but be prepared
195 		 * to notice our state and not resend the preface...
196 		 */
197 
198 		lwsl_debug("%s: LRS_H1C_ISSUE_HANDSHAKE fallthru\n", __func__);
199 
200 		/* fallthru */
201 
202 	case LRS_WAITING_SSL:
203 
204 		if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
205 			n = lws_ssl_client_connect2(wsi, ebuf, sizeof(ebuf));
206 			if (!n)
207 				return 0;
208 			if (n < 0) {
209 				cce = ebuf;
210 				goto bail3;
211 			}
212 		} else {
213 			wsi->tls.ssl = NULL;
214 			if (wsi->flags & LCCSCF_H2_PRIOR_KNOWLEDGE) {
215 				lwsl_info("h2 prior knowledge\n");
216 				lws_role_call_alpn_negotiated(wsi, "h2");
217 			}
218 		}
219 #endif
220 
221 #if defined (LWS_WITH_HTTP2)
222 		if (wsi->client_h2_alpn && lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2) {
223 			/*
224 			 * We connected to the server and set up tls and
225 			 * negotiated "h2" or connected as clear text
226 			 * with http/2 prior knowledge.
227 			 *
228 			 * So this is it, we are an h2 nwsi client connection
229 			 * now, not an h1 client connection.
230 			 */
231 
232 #if defined(LWS_WITH_TLS)
233 			if (wsi->tls.use_ssl & LCCSCF_USE_SSL)
234 				lws_tls_server_conn_alpn(wsi);
235 #endif
236 
237 			/* send the H2 preface to legitimize the connection */
238 			if (lws_h2_issue_preface(wsi)) {
239 				cce = "error sending h2 preface";
240 				goto bail3;
241 			}
242 
243 		//	lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
244 			lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
245 					(int)context->timeout_secs);
246 
247 			break;
248 		}
249 #endif
250 
251 		/* fallthru */
252 
253 	case LRS_H1C_ISSUE_HANDSHAKE2:
254 
255 hs2:
256 
257 		p = lws_generate_client_handshake(wsi, p);
258 		if (p == NULL) {
259 			if (wsi->role_ops == &role_ops_raw_skt
260 #if defined(LWS_ROLE_RAW_FILE)
261 				|| wsi->role_ops == &role_ops_raw_file
262 #endif
263 			    )
264 				return 0;
265 
266 			lwsl_err("Failed to generate handshake for client\n");
267 			lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
268 					   "chs");
269 			return 0;
270 		}
271 
272 		/* send our request to the server */
273 
274 		lwsl_info("%s: HANDSHAKE2: %s: sending headers "
275 			  "(wsistate 0x%lx), w sock %d\n",
276 			  __func__, lws_wsi_tag(wsi),
277 			  (unsigned long)wsi->wsistate, wsi->desc.sockfd);
278 
279 		n = lws_ssl_capable_write(wsi, (unsigned char *)sb, lws_ptr_diff_size_t(p, sb));
280 		switch (n) {
281 		case LWS_SSL_CAPABLE_ERROR:
282 			lwsl_debug("ERROR writing to client socket\n");
283 			lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
284 					   "cws");
285 			return 0;
286 		case LWS_SSL_CAPABLE_MORE_SERVICE:
287 			lws_callback_on_writable(wsi);
288 			break;
289 		}
290 
291 		if (wsi->client_http_body_pending || lws_has_buffered_out(wsi)) {
292 			lwsl_debug("body pending\n");
293 			lwsi_set_state(wsi, LRS_ISSUE_HTTP_BODY);
294 			lws_set_timeout(wsi,
295 					PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD,
296 					(int)context->timeout_secs);
297 
298 			if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED)
299 				lws_callback_on_writable(wsi);
300 #if defined(LWS_WITH_HTTP_PROXY)
301 			if (wsi->http.proxy_clientside && wsi->parent &&
302 			    wsi->parent->http.buflist_post_body)
303 				lws_callback_on_writable(wsi);
304 #endif
305 			/* user code must ask for writable callback */
306 			break;
307 		}
308 
309 		lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY);
310 		wsi->hdr_parsing_completed = 0;
311 
312 		if (lwsi_state(wsi) == LRS_IDLING) {
313 			lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY);
314 			wsi->hdr_parsing_completed = 0;
315 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
316 			wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART;
317 			wsi->http.ah->lextable_pos = 0;
318 			wsi->http.ah->unk_pos = 0;
319 			/* If we're (re)starting on hdr, need other implied init */
320 			wsi->http.ah->ues = URIES_IDLE;
321 #endif
322 		}
323 
324 		lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
325 				(int)wsi->a.context->timeout_secs);
326 
327 		lws_callback_on_writable(wsi);
328 
329 		goto client_http_body_sent;
330 
331 	case LRS_ISSUE_HTTP_BODY:
332 #if defined(LWS_WITH_HTTP_PROXY)
333 			if (wsi->http.proxy_clientside && wsi->parent &&
334 			    wsi->parent->http.buflist_post_body)
335 				lws_callback_on_writable(wsi);
336 #endif
337 		if (wsi->client_http_body_pending || lws_has_buffered_out(wsi)) {
338 			//lws_set_timeout(wsi,
339 			//		PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD,
340 			//		context->timeout_secs);
341 			/* user code must ask for writable callback */
342 			break;
343 		}
344 client_http_body_sent:
345 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
346 		/* prepare ourselves to do the parsing */
347 		wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART;
348 		wsi->http.ah->lextable_pos = 0;
349 		wsi->http.ah->unk_pos = 0;
350 #endif
351 		lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY);
352 		lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
353 				(int)context->timeout_secs);
354 		break;
355 
356 	case LRS_WAITING_SERVER_REPLY:
357 		/*
358 		 * handle server hanging up on us...
359 		 * but if there is POLLIN waiting, handle that first
360 		 */
361 		if ((pollfd->revents & (LWS_POLLIN | LWS_POLLHUP)) ==
362 								LWS_POLLHUP) {
363 
364 			if (lws_buflist_total_len(&wsi->buflist))
365 				lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_ACK, 3);
366 			else {
367 				lwsl_debug("Server conn %s (fd=%d) dead\n",
368 						lws_wsi_tag(wsi), pollfd->fd);
369 				cce = "Peer hung up";
370 				goto bail3;
371 			}
372 		}
373 
374 		if (pollfd->revents & LWS_POLLOUT)
375 			if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
376 				return -1;
377 
378 		if (!(pollfd->revents & LWS_POLLIN))
379 			break;
380 
381 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
382 		/* interpret the server response
383 		 *
384 		 *  HTTP/1.1 101 Switching Protocols
385 		 *  Upgrade: websocket
386 		 *  Connection: Upgrade
387 		 *  Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
388 		 *  Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
389 		 *  Sec-WebSocket-Protocol: chat
390 		 *
391 		 * we have to take some care here to only take from the
392 		 * socket bytewise.  The browser may (and has been seen to
393 		 * in the case that onopen() performs websocket traffic)
394 		 * coalesce both handshake response and websocket traffic
395 		 * in one packet, since at that point the connection is
396 		 * definitively ready from browser pov.
397 		 */
398 		while (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE) {
399 			struct lws_tokens eb;
400 			int n, m, buffered;
401 
402 			eb.token = NULL;
403 			eb.len = 0;
404 			buffered = lws_buflist_aware_read(pt, wsi, &eb, 0, __func__);
405 			lwsl_debug("%s: buflist-aware-read %d %d\n", __func__,
406 					buffered, eb.len);
407 			if (eb.len == LWS_SSL_CAPABLE_MORE_SERVICE)
408 				return 0;
409 			if (buffered < 0 || eb.len < 0) {
410 				cce = "read failed";
411 				goto bail3;
412 			}
413 			if (!eb.len)
414 				return 0;
415 
416 			n = eb.len;
417 			if (lws_parse(wsi, eb.token, &n)) {
418 				lwsl_warn("problems parsing header\n");
419 				cce = "problems parsing header";
420 				goto bail3;
421 			}
422 
423 			m = eb.len - n;
424 			if (lws_buflist_aware_finished_consuming(wsi, &eb, m,
425 								 buffered,
426 								 __func__))
427 			        return -1;
428 
429 			/*
430 			 * coverity: uncomment if extended
431 			 *
432 			 * eb.token += m;
433 			 * eb.len -= m;
434 			 */
435 
436 			if (n) {
437 				assert(wsi->http.ah->parser_state ==
438 						WSI_PARSING_COMPLETE);
439 
440 				break;
441 			}
442 		}
443 
444 		/*
445 		 * hs may also be coming in multiple packets, there is a 5-sec
446 		 * libwebsocket timeout still active here too, so if parsing did
447 		 * not complete just wait for next packet coming in this state
448 		 */
449 		if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE)
450 			break;
451 #endif
452 
453 		/*
454 		 * otherwise deal with the handshake.  If there's any
455 		 * packet traffic already arrived we'll trigger poll() again
456 		 * right away and deal with it that way
457 		 */
458 		return lws_client_interpret_server_handshake(wsi);
459 
460 bail3:
461 		lwsl_info("%s: closing conn at LWS_CONNMODE...SERVER_REPLY, %s, state 0x%x\n",
462 				__func__, lws_wsi_tag(wsi), lwsi_state(wsi));
463 		if (cce)
464 			lwsl_info("reason: %s\n", cce);
465 		else
466 			cce = "unknown";
467 		lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce));
468 
469 		lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "cbail3");
470 		return -1;
471 
472 	default:
473 		break;
474 	}
475 
476 	return 0;
477 }
478 
479 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
480 
481 int LWS_WARN_UNUSED_RESULT
lws_http_transaction_completed_client(struct lws * wsi)482 lws_http_transaction_completed_client(struct lws *wsi)
483 {
484 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
485 	int n;
486 
487 	lwsl_info("%s: %s (%s)\n", __func__, lws_wsi_tag(wsi),
488 			wsi->a.protocol->name);
489 
490 	// if (wsi->http.ah && wsi->http.ah->http_response)
491 	/* we're only judging if any (200, or 500 etc) http txn completed */
492 	lws_metrics_caliper_report(wsi->cal_conn, METRES_GO);
493 
494 	if (user_callback_handle_rxflow(wsi->a.protocol->callback, wsi,
495 					LWS_CALLBACK_COMPLETED_CLIENT_HTTP,
496 					wsi->user_space, NULL, 0)) {
497 		lwsl_debug("%s: Completed call returned nonzero (role 0x%lx)\n",
498 			   __func__, (unsigned long)lwsi_role(wsi));
499 		return -1;
500 	}
501 
502 	wsi->http.rx_content_length = 0;
503 
504 	/*
505 	 * For h1, wsi may pass some assets on to a queued child and be
506 	 * destroyed during this.
507 	 */
508 	lws_pt_lock(pt, __func__);
509 	n = _lws_generic_transaction_completed_active_conn(&wsi, 1);
510 	lws_pt_unlock(pt);
511 
512 	if (wsi->http.ah) {
513 		if (wsi->client_mux_substream)
514 			/*
515 			 * As an h2 client, once we did our transaction, that is
516 			 * it for us.  Further transactions will happen as new
517 			 * SIDs on the connection.
518 			 */
519 			__lws_header_table_detach(wsi, 0);
520 		else
521 			if (!n)
522 				_lws_header_table_reset(wsi->http.ah);
523 	}
524 
525 	if (!n || !wsi->http.ah)
526 		return 0;
527 
528 	/*
529 	 * H1: we can serialize the queued guys into the same ah
530 	 * H2: everybody needs their own ah until their own STREAM_END
531 	 */
532 
533 	/* otherwise set ourselves up ready to go again */
534 	lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY);
535 
536 	wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART;
537 	wsi->http.ah->lextable_pos = 0;
538 	wsi->http.ah->unk_pos = 0;
539 
540 	lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
541 			(int)wsi->a.context->timeout_secs);
542 
543 	/* If we're (re)starting on headers, need other implied init */
544 	wsi->http.ah->ues = URIES_IDLE;
545 	lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
546 
547 	lwsl_info("%s: %s: new queued transaction\n", __func__, lws_wsi_tag(wsi));
548 	lws_callback_on_writable(wsi);
549 
550 	return 0;
551 }
552 
553 unsigned int
lws_http_client_http_response(struct lws * wsi)554 lws_http_client_http_response(struct lws *wsi)
555 {
556 	if (wsi->http.ah && wsi->http.ah->http_response)
557 		return wsi->http.ah->http_response;
558 
559 	return 0;
560 }
561 #endif
562 
563 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
564 
565 int
lws_http_is_redirected_to_get(struct lws * wsi)566 lws_http_is_redirected_to_get(struct lws *wsi)
567 {
568 	return wsi->redirected_to_get;
569 }
570 
571 int
lws_client_interpret_server_handshake(struct lws * wsi)572 lws_client_interpret_server_handshake(struct lws *wsi)
573 {
574 	int n, port = 0, ssl = 0;
575 	int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
576 	const char *prot, *ads = NULL, *path, *cce = NULL;
577 	struct allocated_headers *ah, *ah1;
578 	struct lws *nwsi = lws_get_network_wsi(wsi);
579 	char *p = NULL, *q, *simp;
580 	char new_path[300];
581 
582 	// lws_free_set_NULL(wsi->stash);
583 
584 #if defined(LWS_WITH_CONMON)
585 	wsi->conmon.ciu_txn_resp = (lws_conmon_interval_us_t)
586 					(lws_now_usecs() - wsi->conmon_datum);
587 #endif
588 
589 	ah = wsi->http.ah;
590 	if (!wsi->do_ws) {
591 		/* we are being an http client...
592 		 */
593 #if defined(LWS_ROLE_H2)
594 		if (wsi->client_h2_alpn || wsi->client_mux_substream) {
595 			lwsl_debug("%s: %s: transitioning to h2 client\n",
596 				   __func__, lws_wsi_tag(wsi));
597 			lws_role_transition(wsi, LWSIFR_CLIENT,
598 					    LRS_ESTABLISHED, &role_ops_h2);
599 		} else
600 #endif
601 		{
602 #if defined(LWS_ROLE_H1)
603 			{
604 			lwsl_debug("%s: %s: transitioning to h1 client\n",
605 				   __func__, lws_wsi_tag(wsi));
606 			lws_role_transition(wsi, LWSIFR_CLIENT,
607 					    LRS_ESTABLISHED, &role_ops_h1);
608 			}
609 #else
610 			return -1;
611 #endif
612 		}
613 
614 		wsi->http.ah = ah;
615 		ah->http_response = 0;
616 	}
617 
618 	/*
619 	 * well, what the server sent looked reasonable for syntax.
620 	 * Now let's confirm it sent all the necessary headers
621 	 *
622 	 * http (non-ws) client will expect something like this
623 	 *
624 	 * HTTP/1.0.200
625 	 * server:.libwebsockets
626 	 * content-type:.text/html
627 	 * content-length:.17703
628 	 * set-cookie:.test=LWS_1456736240_336776_COOKIE;Max-Age=360000
629 	 */
630 
631 	wsi->http.conn_type = HTTP_CONNECTION_KEEP_ALIVE;
632 	if (!wsi->client_mux_substream) {
633 		p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
634 		/*
635 		if (wsi->do_ws && !p) {
636 			lwsl_info("no URI\n");
637 			cce = "HS: URI missing";
638 			goto bail3;
639 		}
640 		*/
641 		if (!p) {
642 			p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP1_0);
643 			wsi->http.conn_type = HTTP_CONNECTION_CLOSE;
644 		}
645 		if (!p) {
646 			cce = "HS: URI missing";
647 			lwsl_info("no URI\n");
648 			goto bail3;
649 		}
650 #if defined(LWS_ROLE_H2)
651 	} else {
652 		p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_STATUS);
653 		if (!p) {
654 			cce = "HS: :status missing";
655 			lwsl_info("no status\n");
656 			goto bail3;
657 		}
658 #endif
659 	}
660 #if !defined(LWS_ROLE_H2)
661 	if (!p) {
662 		cce = "HS: :status missing";
663 		lwsl_info("no status\n");
664 		goto bail3;
665 	}
666 #endif
667 	n = atoi(p);
668 	if (ah)
669 		ah->http_response = (unsigned int)n;
670 
671 	if (!wsi->client_no_follow_redirect &&
672 #if defined(LWS_WITH_HTTP_PROXY)
673 	    !wsi->http.proxy_clientside &&
674 #endif
675 	    (n == 301 || n == 302 || n == 303 || n == 307 || n == 308)) {
676 		p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_LOCATION);
677 		if (!p) {
678 			cce = "HS: Redirect code but no Location";
679 			goto bail3;
680 		}
681 
682 		/* let's let the user code know, if he cares */
683 
684 		if (wsi->a.protocol->callback(wsi,
685 					    LWS_CALLBACK_CLIENT_HTTP_REDIRECT,
686 					    wsi->user_space, p, (unsigned int)n)) {
687 			cce = "HS: user code rejected redirect";
688 			goto bail3;
689 		}
690 
691 		/*
692 		 * Some redirect codes imply we have to change the method
693 		 * used for the subsequent transaction, commonly POST ->
694 		 * 303 -> GET.
695 		 */
696 
697 		if (n == 303) {
698 			char *mp = lws_hdr_simple_ptr(wsi,_WSI_TOKEN_CLIENT_METHOD);
699 			int ml = lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_METHOD);
700 
701 			if (ml >= 3 && mp) {
702 				lwsl_info("%s: 303 switching to GET\n", __func__);
703 				memcpy(mp, "GET", 4);
704 				wsi->redirected_to_get = 1;
705 				wsi->http.ah->frags[wsi->http.ah->frag_index[
706 				             _WSI_TOKEN_CLIENT_METHOD]].len = 3;
707 			}
708 		}
709 
710 		/* Relative reference absolute path */
711 		if (p[0] == '/' || !strchr(p, ':')) {
712 #if defined(LWS_WITH_TLS)
713 			ssl = nwsi->tls.use_ssl & LCCSCF_USE_SSL;
714 #endif
715 			ads = lws_hdr_simple_ptr(wsi,
716 						 _WSI_TOKEN_CLIENT_PEER_ADDRESS);
717 			port = nwsi->c_port;
718 			path = p;
719 			/* lws_client_reset expects leading / omitted */
720 			if (*path == '/')
721 				path++;
722 		}
723 		/* Absolute (Full) URI */
724 		else if (strchr(p, ':')) {
725 			if (lws_parse_uri(p, &prot, &ads, &port, &path)) {
726 				cce = "HS: URI did not parse";
727 				goto bail3;
728 			}
729 
730 			if (!strcmp(prot, "wss") || !strcmp(prot, "https"))
731 				ssl = LCCSCF_USE_SSL;
732 		}
733 		/* Relative reference relative path */
734 		else {
735 			/* This doesn't try to calculate an absolute path,
736 			 * that will be left to the server */
737 #if defined(LWS_WITH_TLS)
738 			ssl = nwsi->tls.use_ssl & LCCSCF_USE_SSL;
739 #endif
740 			ads = lws_hdr_simple_ptr(wsi,
741 						 _WSI_TOKEN_CLIENT_PEER_ADDRESS);
742 			port = wsi->c_port;
743 			/* +1 as lws_client_reset expects leading / omitted */
744 			path = new_path + 1;
745 			if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI))
746 				lws_strncpy(new_path, lws_hdr_simple_ptr(wsi,
747 				   _WSI_TOKEN_CLIENT_URI), sizeof(new_path));
748 			else {
749 				new_path[0] = '/';
750 				new_path[1] = '\0';
751 			}
752 			q = strrchr(new_path, '/');
753 			if (q)
754 				lws_strncpy(q + 1, p, sizeof(new_path) -
755 							(unsigned int)(q - new_path) - 1);
756 			else
757 				path = p;
758 		}
759 
760 #if defined(LWS_WITH_TLS)
761 		if ((wsi->tls.use_ssl & LCCSCF_USE_SSL) && !ssl) {
762 			cce = "HS: Redirect attempted SSL downgrade";
763 			goto bail3;
764 		}
765 #endif
766 
767 		if (!ads) /* make coverity happy */ {
768 			cce = "no ads";
769 			goto bail3;
770 		}
771 
772 		if (!lws_client_reset(&wsi, ssl, ads, port, path, ads, 1)) {
773 			/*
774 			 * There are two ways to fail out with NULL return...
775 			 * simple, early problem where the wsi is intact, or
776 			 * we went through with the reconnect attempt and the
777 			 * wsi is already closed.  In the latter case, the wsi
778 			 * has been set to NULL additionally.
779 			 */
780 			lwsl_err("Redirect failed\n");
781 			cce = "HS: Redirect failed";
782 			/* coverity[reverse_inull] */
783 			if (wsi)
784 				goto bail3;
785 
786 			/* wsi has closed */
787 			return 1;
788 		}
789 		return 0;
790 	}
791 
792 	/* if h1 KA is allowed, enable the queued pipeline guys */
793 
794 	if (!wsi->client_h2_alpn && !wsi->client_mux_substream) {
795 		/* ie, coming to this for the first time */
796 		if (wsi->http.conn_type == HTTP_CONNECTION_KEEP_ALIVE)
797 			wsi->keepalive_active = 1;
798 		else {
799 			/*
800 			 * Ugh... now the main http connection has seen
801 			 * both sides, we learn the server doesn't
802 			 * support keepalive.
803 			 *
804 			 * That means any guys queued on us are going
805 			 * to have to be restarted from connect2 with
806 			 * their own connections.
807 			 */
808 
809 			/*
810 			 * stick around telling any new guys they can't
811 			 * pipeline to this server
812 			 */
813 			wsi->keepalive_rejected = 1;
814 
815 			lws_vhost_lock(wsi->a.vhost);
816 			lws_start_foreach_dll_safe(struct lws_dll2 *,
817 						   d, d1,
818 			  wsi->dll2_cli_txn_queue_owner.head) {
819 				struct lws *ww = lws_container_of(d,
820 					struct lws,
821 					dll2_cli_txn_queue);
822 
823 				/* remove him from our queue */
824 				lws_dll2_remove(&ww->dll2_cli_txn_queue);
825 				/* give up on pipelining */
826 				ww->client_pipeline = 0;
827 
828 				/* go back to "trying to connect" state */
829 				lws_role_transition(ww, LWSIFR_CLIENT,
830 						    LRS_UNCONNECTED,
831 #if defined(LWS_ROLE_H1)
832 						    &role_ops_h1);
833 #else
834 #if defined (LWS_ROLE_H2)
835 						    &role_ops_h2);
836 #else
837 						    &role_ops_raw);
838 #endif
839 #endif
840 				ww->user_space = NULL;
841 			} lws_end_foreach_dll_safe(d, d1);
842 			lws_vhost_unlock(wsi->a.vhost);
843 		}
844 	}
845 
846 #ifdef LWS_WITH_HTTP_PROXY
847 	wsi->http.perform_rewrite = 0;
848 	if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
849 		if (!strncmp(lws_hdr_simple_ptr(wsi,
850 					WSI_TOKEN_HTTP_CONTENT_TYPE),
851 					"text/html", 9))
852 			wsi->http.perform_rewrite = 0;
853 	}
854 #endif
855 
856 	/* he may choose to send us stuff in chunked transfer-coding */
857 	wsi->chunked = 0;
858 	wsi->chunk_remaining = 0; /* ie, next thing is chunk size */
859 	if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_TRANSFER_ENCODING)) {
860 		simp = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_TRANSFER_ENCODING);
861 
862 		/* cannot be NULL, since it has nonzero length... coverity */
863 		if (!simp)
864 			goto bail2;
865 		wsi->chunked = !strcmp(simp, "chunked");
866 		/* first thing is hex, after payload there is crlf */
867 		wsi->chunk_parser = ELCP_HEX;
868 	}
869 
870 	wsi->http.content_length_given = 0;
871 	if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
872 		simp = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH);
873 
874 		/* cannot be NULL, since it has nonzero length... coverity */
875 		if (!simp)
876 			goto bail2;
877 
878 		wsi->http.rx_content_length = (lws_filepos_t)atoll(simp);
879 		lwsl_info("%s: incoming content length %llu\n",
880 			    __func__, (unsigned long long)
881 				    wsi->http.rx_content_length);
882 		wsi->http.rx_content_remain =
883 				wsi->http.rx_content_length;
884 		wsi->http.content_length_given = 1;
885 	} else { /* can't do 1.1 without a content length or chunked */
886 		if (!wsi->chunked)
887 			wsi->http.conn_type = HTTP_CONNECTION_CLOSE;
888 		lwsl_debug("%s: no content length\n", __func__);
889 	}
890 
891 	if (wsi->do_ws) {
892 		/*
893 		 * Give one last opportunity to ws protocols to inspect server reply
894 		 * before the ws upgrade code discard it. ie: download reply body in case
895 		 * of any other response code than 101.
896 		 */
897 		if (wsi->a.protocol->callback(wsi,
898 					  LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,
899 					  wsi->user_space, NULL, 0)) {
900 
901 			cce = "HS: disallowed by client filter";
902 			goto bail2;
903 		}
904 	} else {
905 		/* allocate the per-connection user memory (if any) */
906 		if (lws_ensure_user_space(wsi)) {
907 			lwsl_err("Problem allocating wsi user mem\n");
908 			cce = "HS: OOM";
909 			goto bail2;
910 		}
911 
912 
913 		/*
914 		 * we seem to be good to go, give client last chance to check
915 		 * headers and OK it
916 		 */
917 		ah1 = wsi->http.ah;
918 		wsi->http.ah = ah;
919 		if (wsi->a.protocol->callback(wsi,
920 				LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
921 					    wsi->user_space, NULL, 0)) {
922 			wsi->http.ah = ah1;
923 			cce = "HS: disallowed by client filter";
924 			goto bail2;
925 		}
926 
927 		/* clear his proxy connection timeout */
928 		lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
929 
930 		wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
931 
932 		/* call him back to inform him he is up */
933 		if (wsi->a.protocol->callback(wsi,
934 					    LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,
935 					    wsi->user_space, NULL, 0)) {
936 			wsi->http.ah = ah1;
937 			cce = "HS: disallowed at ESTABLISHED";
938 			goto bail3;
939 		}
940 
941 		wsi->http.ah = ah1;
942 
943 		lwsl_info("%s: %s: client conn up\n", __func__, lws_wsi_tag(wsi));
944 
945 		/*
946 		 * Did we get a response from the server with an explicit
947 		 * content-length of zero?  If so, and it's not H2 which will
948 		 * notice it via END_STREAM, this transaction is already
949 		 * completed at the end of the header processing...
950 		 */
951 		if (!wsi->mux_substream && !wsi->client_mux_substream &&
952 		    lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH) &&
953 		    !wsi->http.rx_content_length)
954 		        return !!lws_http_transaction_completed_client(wsi);
955 
956 		/*
957 		 * We can also get a case where it's http/1 and there's no
958 		 * content-length at all, so anything that comes is the body
959 		 * until it hangs up on us.  With that situation, hanging up
960 		 * on us past this point should generate a valid
961 		 * LWS_CALLBACK_COMPLETED_CLIENT_HTTP.
962 		 *
963 		 * In that situation, he can't pipeline because in h1 there's
964 		 * no post-header in-band way to signal the end of the
965 		 * transaction except hangup.
966 		 *
967 		 * lws_http_transaction_completed_client() is the right guy to
968 		 * issue it when we see the peer has hung up on us.
969 		 */
970 
971 		return 0;
972 	}
973 
974 #if defined(LWS_ROLE_WS)
975 	switch (lws_client_ws_upgrade(wsi, &cce)) {
976 	case 2:
977 		goto bail2;
978 	case 3:
979 		goto bail3;
980 	}
981 
982 	return 0;
983 #endif
984 
985 bail3:
986 	close_reason = LWS_CLOSE_STATUS_NOSTATUS;
987 
988 bail2:
989 	if (wsi->a.protocol) {
990 		n = 0;
991 		if (cce)
992 			n = (int)strlen(cce);
993 
994 		lws_inform_client_conn_fail(wsi, (void *)cce, (unsigned int)n);
995 	}
996 
997 	lwsl_info("closing connection (prot %s) "
998 		  "due to bail2 connection error: %s\n", wsi->a.protocol ?
999 				  wsi->a.protocol->name : "unknown", cce);
1000 
1001 	/* closing will free up his parsing allocations */
1002 	lws_close_free_wsi(wsi, (enum lws_close_status)close_reason, "c hs interp");
1003 
1004 	return 1;
1005 }
1006 #endif
1007 
1008 /*
1009  * set the boundary string and the content-type for client multipart mime
1010  */
1011 
1012 uint8_t *
lws_http_multipart_headers(struct lws * wsi,uint8_t * p)1013 lws_http_multipart_headers(struct lws *wsi, uint8_t *p)
1014 {
1015 	char buf[10], arg[48];
1016 	int n;
1017 
1018 	if (lws_get_random(wsi->a.context, (uint8_t *)buf, sizeof(buf)) !=
1019 			sizeof(buf))
1020 		return NULL;
1021 
1022 	lws_b64_encode_string(buf, sizeof(buf),
1023 			       wsi->http.multipart_boundary,
1024 			       sizeof(wsi->http.multipart_boundary));
1025 
1026 	n = lws_snprintf(arg, sizeof(arg), "multipart/form-data; boundary=\"%s\"",
1027 			 wsi->http.multipart_boundary);
1028 
1029 	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
1030 					 (uint8_t *)arg, n, &p, p + 100))
1031 		return NULL;
1032 
1033 	wsi->http.multipart = wsi->http.multipart_issue_boundary = 1;
1034 	lws_client_http_body_pending(wsi, 1);
1035 
1036 	return p;
1037 }
1038 
1039 int
lws_client_http_multipart(struct lws * wsi,const char * name,const char * filename,const char * content_type,char ** p,char * end)1040 lws_client_http_multipart(struct lws *wsi, const char *name,
1041 			  const char *filename, const char *content_type,
1042 			  char **p, char *end)
1043 {
1044 	/*
1045 	 * Client conn must have been created with LCCSCF_HTTP_MULTIPART_MIME
1046 	 * flag to use this api
1047 	 */
1048 	assert(wsi->http.multipart);
1049 
1050 	if (!name) {
1051 		*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p),
1052 					"\xd\xa--%s--\xd\xa",
1053 					wsi->http.multipart_boundary);
1054 
1055 		return 0;
1056 	}
1057 
1058 	if (wsi->client_subsequent_mime_part)
1059 		*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p), "\xd\xa");
1060 	wsi->client_subsequent_mime_part = 1;
1061 
1062 	*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p), "--%s\xd\xa"
1063 				    "Content-Disposition: form-data; "
1064 				      "name=\"%s\"",
1065 				      wsi->http.multipart_boundary, name);
1066 	if (filename)
1067 		*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p),
1068 				   "; filename=\"%s\"", filename);
1069 
1070 	if (content_type)
1071 		*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p), "\xd\xa"
1072 				"Content-Type: %s", content_type);
1073 
1074 	*p += lws_snprintf((char *)(*p), lws_ptr_diff_size_t(end, *p), "\xd\xa\xd\xa");
1075 
1076 	return *p == end;
1077 }
1078 
1079 char *
lws_generate_client_handshake(struct lws * wsi,char * pkt)1080 lws_generate_client_handshake(struct lws *wsi, char *pkt)
1081 {
1082 	const char *meth, *pp = lws_hdr_simple_ptr(wsi,
1083 				_WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
1084 	char *p = pkt, *p1, *end = p + wsi->a.context->pt_serv_buf_size;
1085 
1086 	meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
1087 	if (!meth) {
1088 		meth = "GET";
1089 		wsi->do_ws = 1;
1090 	} else {
1091 		wsi->do_ws = 0;
1092 	}
1093 
1094 	if (!strcmp(meth, "RAW")) {
1095 		lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
1096 		lwsl_notice("client transition to raw\n");
1097 
1098 		if (pp) {
1099 			const struct lws_protocols *pr;
1100 
1101 			pr = lws_vhost_name_to_protocol(wsi->a.vhost, pp);
1102 
1103 			if (!pr) {
1104 				lwsl_err("protocol %s not enabled on vhost\n",
1105 					 pp);
1106 				return NULL;
1107 			}
1108 
1109 			lws_bind_protocol(wsi, pr, __func__);
1110 		}
1111 
1112 		if ((wsi->a.protocol->callback)(wsi, LWS_CALLBACK_RAW_ADOPT,
1113 					      wsi->user_space, NULL, 0))
1114 			return NULL;
1115 
1116 		lws_role_transition(wsi, LWSIFR_CLIENT, LRS_ESTABLISHED,
1117 				    &role_ops_raw_skt);
1118 		lws_header_table_detach(wsi, 1);
1119 
1120 		return NULL;
1121 	}
1122 
1123 	/*
1124 	 * 04 example client handshake
1125 	 *
1126 	 * GET /chat HTTP/1.1
1127 	 * Host: server.example.com
1128 	 * Upgrade: websocket
1129 	 * Connection: Upgrade
1130 	 * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
1131 	 * Sec-WebSocket-Origin: http://example.com
1132 	 * Sec-WebSocket-Protocol: chat, superchat
1133 	 * Sec-WebSocket-Version: 4
1134 	 */
1135 
1136 	p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
1137 			  "%s %s HTTP/1.1\x0d\x0a", meth,
1138 		          lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI));
1139 
1140 	p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p),
1141 			  "Pragma: no-cache\x0d\x0a"
1142 			  "Cache-Control: no-cache\x0d\x0a");
1143 
1144 	p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p),
1145 			  "Host: %s\x0d\x0a",
1146 			  lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST));
1147 
1148 	if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)) {
1149 		if (lws_check_opt(wsi->a.context->options,
1150 				  LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN))
1151 			p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p),
1152 					  "Origin: %s\x0d\x0a",
1153 					  lws_hdr_simple_ptr(wsi,
1154 						     _WSI_TOKEN_CLIENT_ORIGIN));
1155 		else
1156 			p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p),
1157 					  "Origin: http://%s\x0d\x0a",
1158 					  lws_hdr_simple_ptr(wsi,
1159 						     _WSI_TOKEN_CLIENT_ORIGIN));
1160 	}
1161 
1162 	if (wsi->flags & LCCSCF_HTTP_MULTIPART_MIME) {
1163 		p1 = (char *)lws_http_multipart_headers(wsi, (uint8_t *)p);
1164 		if (!p1)
1165 			return NULL;
1166 		p = p1;
1167 	}
1168 
1169 #if defined(LWS_WITH_HTTP_PROXY)
1170 	if (wsi->parent &&
1171 	    lws_hdr_total_length(wsi->parent, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
1172 		p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
1173 				  "Content-Length: %s\x0d\x0a",
1174 			lws_hdr_simple_ptr(wsi->parent, WSI_TOKEN_HTTP_CONTENT_LENGTH));
1175 		if (atoi(lws_hdr_simple_ptr(wsi->parent, WSI_TOKEN_HTTP_CONTENT_LENGTH)))
1176 			wsi->client_http_body_pending = 1;
1177 	}
1178 	if (wsi->parent &&
1179 	    lws_hdr_total_length(wsi->parent, WSI_TOKEN_HTTP_AUTHORIZATION)) {
1180 		p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
1181 				  "Authorization: %s\x0d\x0a",
1182 			lws_hdr_simple_ptr(wsi->parent, WSI_TOKEN_HTTP_AUTHORIZATION));
1183 	}
1184 	if (wsi->parent &&
1185 	    lws_hdr_total_length(wsi->parent, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
1186 		p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
1187 				  "Content-Type: %s\x0d\x0a",
1188 			lws_hdr_simple_ptr(wsi->parent, WSI_TOKEN_HTTP_CONTENT_TYPE));
1189 	}
1190 #endif
1191 
1192 #if defined(LWS_ROLE_WS)
1193 	if (wsi->do_ws) {
1194 		const char *conn1 = "";
1195 	//	if (!wsi->client_pipeline)
1196 	//		conn1 = "close, ";
1197 		p = lws_generate_client_ws_handshake(wsi, p, conn1);
1198 	} else
1199 #endif
1200 	{
1201 		if (!wsi->client_pipeline)
1202 			p += lws_snprintf(p, 64, "connection: close\x0d\x0a");
1203 	}
1204 
1205 	/* give userland a chance to append, eg, cookies */
1206 
1207 	if (wsi->a.protocol->callback(wsi,
1208 			LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
1209 			wsi->user_space, &p,
1210 			(unsigned int)((pkt + wsi->a.context->pt_serv_buf_size) - p - 12)))
1211 		return NULL;
1212 
1213 	if (wsi->flags & LCCSCF_HTTP_X_WWW_FORM_URLENCODED) {
1214 		p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), "Content-Type: application/x-www-form-urlencoded\x0d\x0a");
1215 		p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p), "Content-Length: %lu\x0d\x0a", wsi->http.writeable_len);
1216 		lws_client_http_body_pending(wsi, 1);
1217 	}
1218 
1219 	p += lws_snprintf(p,  lws_ptr_diff_size_t(end, p), "\x0d\x0a");
1220 
1221 	if (wsi->client_http_body_pending || lws_has_buffered_out(wsi))
1222 		lws_callback_on_writable(wsi);
1223 
1224 	lws_metrics_caliper_bind(wsi->cal_conn, wsi->a.context->mt_http_txn);
1225 #if defined(LWS_WITH_CONMON)
1226 	wsi->conmon_datum = lws_now_usecs();
1227 #endif
1228 
1229 	// puts(pkt);
1230 
1231 	return p;
1232 }
1233 
1234 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
1235 #if defined(LWS_WITH_HTTP_BASIC_AUTH)
1236 
1237 int
lws_http_basic_auth_gen(const char * user,const char * pw,char * buf,size_t len)1238 lws_http_basic_auth_gen(const char *user, const char *pw, char *buf, size_t len)
1239 {
1240 	size_t n = strlen(user), m = strlen(pw);
1241 	char b[128];
1242 
1243 	if (len < 6 + ((4 * (n + m + 1)) / 3) + 1)
1244 		return 1;
1245 
1246 	memcpy(buf, "Basic ", 6);
1247 
1248 	n = (unsigned int)lws_snprintf(b, sizeof(b), "%s:%s", user, pw);
1249 	if (n >= sizeof(b) - 2)
1250 		return 2;
1251 
1252 	lws_b64_encode_string(b, (int)n, buf + 6, (int)len - 6);
1253 	buf[len - 1] = '\0';
1254 
1255 	return 0;
1256 }
1257 
1258 #endif
1259 
1260 int
lws_http_client_read(struct lws * wsi,char ** buf,int * len)1261 lws_http_client_read(struct lws *wsi, char **buf, int *len)
1262 {
1263 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
1264 	struct lws_tokens eb;
1265 	int buffered, n, consumed = 0;
1266 
1267 	/*
1268 	 * If the caller provided a non-NULL *buf and nonzero *len, we should
1269 	 * use that as the buffer for the read action, limititing it to *len
1270 	 * (actual payload will be less if chunked headers inside).
1271 	 *
1272 	 * If it's NULL / 0 length, buflist_aware_read will use the pt_serv_buf
1273 	 */
1274 
1275 	eb.token = (unsigned char *)*buf;
1276 	eb.len = *len;
1277 
1278 	buffered = lws_buflist_aware_read(pt, wsi, &eb, 0, __func__);
1279 	*buf = (char *)eb.token; /* may be pointing to buflist or pt_serv_buf */
1280 	*len = 0;
1281 
1282 	/*
1283 	 * we're taking on responsibility for handling used / unused eb
1284 	 * when we leave, via lws_buflist_aware_finished_consuming()
1285 	 */
1286 
1287 //	lwsl_notice("%s: eb.len %d ENTRY chunk remaining %d\n", __func__, eb.len,
1288 //			wsi->chunk_remaining);
1289 
1290 	/* allow the source to signal he has data again next time */
1291 	if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
1292 		return -1;
1293 
1294 	if (buffered < 0) {
1295 		lwsl_debug("%s: SSL capable error\n", __func__);
1296 
1297 		if (wsi->http.ah &&
1298 		    wsi->http.ah->parser_state == WSI_PARSING_COMPLETE &&
1299 		    !lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH))
1300 			/*
1301 			 * We had the headers from this stream, but as there
1302 			 * was no content-length: we had to wait until the
1303 			 * stream ended to inform the user code the transaction
1304 			 * has completed to the best of our knowledge
1305 			 */
1306 			if (lws_http_transaction_completed_client(wsi))
1307 				/*
1308 				 * We're going to close anyway, but that api has
1309 				 * warn_unused_result
1310 				 */
1311 				return -1;
1312 
1313 		return -1;
1314 	}
1315 
1316 	if (eb.len <= 0)
1317 		return 0;
1318 
1319 	*len = eb.len;
1320 	wsi->client_rx_avail = 0;
1321 
1322 	/*
1323 	 * server may insist on transfer-encoding: chunked,
1324 	 * so http client must deal with it
1325 	 */
1326 spin_chunks:
1327 	//lwsl_notice("%s: len %d SPIN chunk remaining %d\n", __func__, *len,
1328 	//		wsi->chunk_remaining);
1329 	while (wsi->chunked && (wsi->chunk_parser != ELCP_CONTENT) && *len) {
1330 		switch (wsi->chunk_parser) {
1331 		case ELCP_HEX:
1332 			if ((*buf)[0] == '\x0d') {
1333 				wsi->chunk_parser = ELCP_CR;
1334 				break;
1335 			}
1336 			n = char_to_hex((*buf)[0]);
1337 			if (n < 0) {
1338 				lwsl_err("%s: chunking failure A\n", __func__);
1339 				return -1;
1340 			}
1341 			wsi->chunk_remaining <<= 4;
1342 			wsi->chunk_remaining |= n;
1343 			break;
1344 		case ELCP_CR:
1345 			if ((*buf)[0] != '\x0a') {
1346 				lwsl_err("%s: chunking failure B\n", __func__);
1347 				return -1;
1348 			}
1349 			if (wsi->chunk_remaining) {
1350 				wsi->chunk_parser = ELCP_CONTENT;
1351 				//lwsl_notice("starting chunk size %d (block rem %d)\n",
1352 				//		wsi->chunk_remaining, *len);
1353 				break;
1354 			}
1355 
1356 			wsi->chunk_parser = ELCP_TRAILER_CR;
1357 			break;
1358 
1359 		case ELCP_CONTENT:
1360 			break;
1361 
1362 		case ELCP_POST_CR:
1363 			if ((*buf)[0] != '\x0d') {
1364 				lwsl_err("%s: chunking failure C\n", __func__);
1365 				lwsl_hexdump_err(*buf, (unsigned int)*len);
1366 
1367 				return -1;
1368 			}
1369 
1370 			wsi->chunk_parser = ELCP_POST_LF;
1371 			break;
1372 
1373 		case ELCP_POST_LF:
1374 			if ((*buf)[0] != '\x0a') {
1375 				lwsl_err("%s: chunking failure D\n", __func__);
1376 
1377 				return -1;
1378 			}
1379 
1380 			wsi->chunk_parser = ELCP_HEX;
1381 			wsi->chunk_remaining = 0;
1382 			break;
1383 
1384 		case ELCP_TRAILER_CR:
1385 			if ((*buf)[0] != '\x0d') {
1386 				lwsl_err("%s: chunking failure F\n", __func__);
1387 				lwsl_hexdump_err(*buf, (unsigned int)*len);
1388 
1389 				return -1;
1390 			}
1391 
1392 			wsi->chunk_parser = ELCP_TRAILER_LF;
1393 			break;
1394 
1395 		case ELCP_TRAILER_LF:
1396 			if ((*buf)[0] != '\x0a') {
1397 				lwsl_err("%s: chunking failure F\n", __func__);
1398 				lwsl_hexdump_err(*buf, (unsigned int)*len);
1399 
1400 				return -1;
1401 			}
1402 
1403 			(*buf)++;
1404 			(*len)--;
1405 			consumed++;
1406 
1407 			lwsl_info("final chunk\n");
1408 			goto completed;
1409 		}
1410 		(*buf)++;
1411 		(*len)--;
1412 		consumed++;
1413 	}
1414 
1415 	if (wsi->chunked && !wsi->chunk_remaining)
1416 		goto account_and_ret;
1417 
1418 	if (wsi->http.rx_content_remain &&
1419 	    wsi->http.rx_content_remain < (unsigned int)*len)
1420 		n = (int)wsi->http.rx_content_remain;
1421 	else
1422 		n = *len;
1423 
1424 	if (wsi->chunked && wsi->chunk_remaining &&
1425 	    wsi->chunk_remaining < n)
1426 		n = wsi->chunk_remaining;
1427 
1428 #if defined(LWS_WITH_HTTP_PROXY) && defined(LWS_WITH_HUBBUB)
1429 	/* hubbub */
1430 	if (wsi->http.perform_rewrite)
1431 		lws_rewrite_parse(wsi->http.rw, (unsigned char *)*buf, n);
1432 	else
1433 #endif
1434 	{
1435 		if (
1436 #if defined(LWS_WITH_HTTP_PROXY)
1437 		    !wsi->protocol_bind_balance ==
1438 		    !!wsi->http.proxy_clientside
1439 #else
1440 		    !!wsi->protocol_bind_balance
1441 #endif
1442 		  ) {
1443 			int q;
1444 
1445 			q = user_callback_handle_rxflow(wsi->a.protocol->callback,
1446 				wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
1447 				wsi->user_space, *buf, (unsigned int)n);
1448 			if (q) {
1449 				lwsl_info("%s: RECEIVE_CLIENT_HTTP_READ returned %d\n",
1450 						__func__, q);
1451 
1452 				return q;
1453 			}
1454 		} else
1455 			lwsl_notice("%s: swallowed read (%d)\n", __func__, n);
1456 	}
1457 
1458 	(*buf) += n;
1459 	*len -= n;
1460 	if (wsi->chunked && wsi->chunk_remaining)
1461 		wsi->chunk_remaining -= n;
1462 
1463 	//lwsl_notice("chunk_remaining <- %d, block remaining %d\n",
1464 	//		wsi->chunk_remaining, *len);
1465 
1466 	consumed += n;
1467 	//eb.token += n;
1468 	//eb.len -= n;
1469 
1470 	if (wsi->chunked && !wsi->chunk_remaining)
1471 		wsi->chunk_parser = ELCP_POST_CR;
1472 
1473 	if (wsi->chunked && *len)
1474 		goto spin_chunks;
1475 
1476 	if (wsi->chunked)
1477 		goto account_and_ret;
1478 
1479 	/* if we know the content length, decrement the content remaining */
1480 	if (wsi->http.rx_content_length > 0)
1481 		wsi->http.rx_content_remain -= (unsigned int)n;
1482 
1483 	// lwsl_notice("rx_content_remain %lld, rx_content_length %lld, giv %d\n",
1484 	//	    wsi->http.rx_content_remain, wsi->http.rx_content_length,
1485 	//	    wsi->http.content_length_given);
1486 
1487 	if (wsi->http.rx_content_remain || !wsi->http.content_length_given)
1488 		goto account_and_ret;
1489 
1490 completed:
1491 
1492 	if (lws_http_transaction_completed_client(wsi)) {
1493 		lwsl_info("%s: transaction completed says -1\n", __func__);
1494 		return -1;
1495 	}
1496 
1497 account_and_ret:
1498 //	lwsl_warn("%s: on way out, consuming %d / %d\n", __func__, consumed, eb.len);
1499 	if (lws_buflist_aware_finished_consuming(wsi, &eb, consumed, buffered,
1500 							__func__))
1501 		return -1;
1502 
1503 	return 0;
1504 }
1505 
1506 #endif
1507 
1508 static uint8_t hnames2[] = {
1509 	_WSI_TOKEN_CLIENT_ORIGIN,
1510 	_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
1511 	_WSI_TOKEN_CLIENT_METHOD,
1512 	_WSI_TOKEN_CLIENT_IFACE,
1513 	_WSI_TOKEN_CLIENT_ALPN
1514 };
1515 
1516 /**
1517  * lws_client_reset() - retarget a connected wsi to start over with a new
1518  * 			connection (ie, redirect)
1519  *			this only works if still in HTTP, ie, not upgraded yet
1520  * wsi:		connection to reset
1521  * address:	network address of the new server
1522  * port:	port to connect to
1523  * path:	uri path to connect to on the new server
1524  * host:	host header to send to the new server
1525  */
1526 struct lws *
lws_client_reset(struct lws ** pwsi,int ssl,const char * address,int port,const char * path,const char * host,char weak)1527 lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
1528 		 const char *path, const char *host, char weak)
1529 {
1530 	struct lws_context_per_thread *pt;
1531 #if defined(LWS_ROLE_WS)
1532 	struct _lws_websocket_related *ws;
1533 #endif
1534 	char *stash, *p;
1535 	struct lws *wsi;
1536 	size_t size = 0;
1537 	int n;
1538 
1539 	if (!pwsi)
1540 		return NULL;
1541 
1542 	wsi = *pwsi;
1543 	pt = &wsi->a.context->pt[(int)wsi->tsi];
1544 
1545 	lwsl_debug("%s: %s: redir %d: %s\n", __func__, lws_wsi_tag(wsi),
1546 			wsi->redirects, address);
1547 
1548 	if (wsi->redirects == 3) {
1549 		lwsl_err("%s: Too many redirects\n", __func__);
1550 		return NULL;
1551 	}
1552 	wsi->redirects++;
1553 
1554 	/*
1555 	 * goal is to close our role part, close the sockfd, detach the ah
1556 	 * but leave our wsi extant and still bound to whatever vhost it was
1557 	 */
1558 
1559 	for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++)
1560 		size += (unsigned int)lws_hdr_total_length(wsi, hnames2[n]) + 1u;
1561 
1562 	if (size < (size_t)lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI) + 1)
1563 		size = (unsigned int)lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI) + 1u;
1564 
1565 	/*
1566 	 * The incoming address and host can be from inside the existing ah
1567 	 * we are going to detach and reattch
1568 	 */
1569 
1570 	size += strlen(path) + 1 + strlen(address) + 1 + strlen(host) + 1 + 1;
1571 
1572 	p = stash = lws_malloc(size, __func__);
1573 	if (!stash)
1574 		return NULL;
1575 
1576 	/*
1577 	 * _WSI_TOKEN_CLIENT_ORIGIN,
1578 	 * _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
1579 	 * _WSI_TOKEN_CLIENT_METHOD,
1580 	 * _WSI_TOKEN_CLIENT_IFACE,
1581 	 * _WSI_TOKEN_CLIENT_ALPN
1582 	 * address
1583 	 * host
1584 	 * path
1585 	 */
1586 
1587 	for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++)
1588 		if (lws_hdr_total_length(wsi, hnames2[n]) &&
1589 		    lws_hdr_simple_ptr(wsi, hnames2[n])) {
1590 			memcpy(p, lws_hdr_simple_ptr(wsi, hnames2[n]), (size_t)(
1591 			       lws_hdr_total_length(wsi, hnames2[n]) + 1));
1592 			p += (size_t)(lws_hdr_total_length(wsi, hnames2[n]) + 1);
1593 		} else
1594 			*p++ = '\0';
1595 
1596 	memcpy(p, address, strlen(address) + (size_t)1);
1597 	address = p;
1598 	p += strlen(address) + 1;
1599 	memcpy(p, host, strlen(host) + (size_t)1);
1600 	host = p;
1601 	p += strlen(host) + 1;
1602 	memcpy(p, path, strlen(path) + (size_t)1);
1603 	path = p;
1604 
1605 	if (!port) {
1606 		lwsl_info("%s: forcing port 443\n", __func__);
1607 
1608 		port = 443;
1609 		ssl = 1;
1610 	}
1611 
1612 	lwsl_info("redirect ads='%s', port=%d, path='%s', ssl = %d, pifds %d\n",
1613 		   address, port, path, ssl, wsi->position_in_fds_table);
1614 
1615 	lws_pt_lock(pt, __func__);
1616 	__remove_wsi_socket_from_fds(wsi);
1617 	lws_pt_unlock(pt);
1618 
1619 #if defined(LWS_ROLE_WS)
1620 	if (weak) {
1621 		ws = wsi->ws;
1622 		wsi->ws = NULL;
1623 	}
1624 #endif
1625 	__lws_reset_wsi(wsi); /* detaches ah here */
1626 #if defined(LWS_ROLE_WS)
1627 	if (weak)
1628 		wsi->ws = ws;
1629 #endif
1630 	wsi->client_pipeline = 1;
1631 
1632 	/* close the connection by hand */
1633 
1634 #if defined(LWS_WITH_TLS)
1635 	lws_ssl_close(wsi);
1636 #endif
1637 
1638 	if (wsi->role_ops &&
1639 	    lws_rops_fidx(wsi->role_ops, LWS_ROPS_close_kill_connection))
1640 		lws_rops_func_fidx(wsi->role_ops, LWS_ROPS_close_kill_connection).
1641 						close_kill_connection(wsi, 1);
1642 
1643 	if (wsi->a.context->event_loop_ops->close_handle_manually)
1644 		wsi->a.context->event_loop_ops->close_handle_manually(wsi);
1645 	else
1646 		if (wsi->desc.sockfd != LWS_SOCK_INVALID)
1647 			compatible_close(wsi->desc.sockfd);
1648 
1649 #if defined(LWS_WITH_TLS)
1650 	if (!ssl)
1651 		wsi->tls.use_ssl &= (unsigned int)~LCCSCF_USE_SSL;
1652 	else
1653 		wsi->tls.use_ssl |= LCCSCF_USE_SSL;
1654 #else
1655 	if (ssl) {
1656 		lwsl_err("%s: not configured for ssl\n", __func__);
1657 		goto bail;
1658 	}
1659 #endif
1660 
1661 	if (wsi->a.protocol && wsi->role_ops && wsi->protocol_bind_balance) {
1662 		wsi->a.protocol->callback(wsi,
1663 				wsi->role_ops->protocol_unbind_cb[
1664 				       !!lwsi_role_server(wsi)],
1665 				       wsi->user_space, (void *)__func__, 0);
1666 
1667 		wsi->protocol_bind_balance = 0;
1668 	}
1669 
1670 	wsi->desc.sockfd = LWS_SOCK_INVALID;
1671 	lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_h1);
1672 //	wsi->a.protocol = NULL;
1673 	if (wsi->a.protocol)
1674 		lws_bind_protocol(wsi, wsi->a.protocol, "client_reset");
1675 	wsi->pending_timeout = NO_PENDING_TIMEOUT;
1676 	wsi->c_port = (uint16_t)port;
1677 	wsi->hdr_parsing_completed = 0;
1678 
1679 	if (lws_header_table_attach(wsi, 0)) {
1680 		lwsl_err("%s: failed to get ah\n", __func__);
1681 		goto bail;
1682 	}
1683 	//_lws_header_table_reset(wsi->http.ah);
1684 
1685 	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
1686 		goto bail;
1687 
1688 	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
1689 		goto bail;
1690 
1691 	/*
1692 	 * _WSI_TOKEN_CLIENT_ORIGIN,
1693 	 * _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
1694 	 * _WSI_TOKEN_CLIENT_METHOD,
1695 	 * _WSI_TOKEN_CLIENT_IFACE,
1696 	 * _WSI_TOKEN_CLIENT_ALPN
1697 	 * address
1698 	 * host
1699 	 * path
1700 	 */
1701 
1702 	p = stash;
1703 	for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++) {
1704 		if (lws_hdr_simple_create(wsi, hnames2[n], p))
1705 			goto bail;
1706 		p += lws_hdr_total_length(wsi, hnames2[n]) + 1;
1707 	}
1708 
1709 	stash[0] = '/';
1710 	memmove(&stash[1], path, size - 1 < strlen(path) + 1 ?
1711 					size - 1 : strlen(path) + (size_t)1);
1712 	if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash))
1713 		goto bail;
1714 
1715 	lws_free_set_NULL(stash);
1716 
1717 #if defined(LWS_WITH_HTTP2)
1718 	if (wsi->client_mux_substream)
1719 		wsi->h2.END_STREAM = wsi->h2.END_HEADERS = 0;
1720 #endif
1721 
1722 	*pwsi = lws_client_connect_2_dnsreq(wsi);
1723 
1724 	return *pwsi;
1725 
1726 bail:
1727 	lws_free_set_NULL(stash);
1728 
1729 	return NULL;
1730 }
1731