HTTP_PROXY: make usable
[platform/upstream/libwebsockets.git] / lib / client-handshake.c
1 #include "private-libwebsockets.h"
2
3 struct lws *
4 lws_client_connect_2(struct lws *wsi)
5 {
6 #ifdef LWS_USE_IPV6
7         struct sockaddr_in6 server_addr6;
8         struct addrinfo hints, *result;
9 #endif
10         struct lws_context *context = wsi->context;
11         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
12         struct sockaddr_in server_addr4;
13         struct lws_pollfd pfd;
14         struct sockaddr *v;
15         const char *cce = "", *iface;
16         int n, plen = 0;
17         const char *ads;
18
19         lwsl_client("%s\n", __func__);
20
21         if (!wsi->u.hdr.ah) {
22                 cce = "ah was NULL at cc2";
23                 lwsl_err("%s\n", cce);
24                 goto oom4;
25         }
26
27         /* proxy? */
28
29         /* http proxy */
30         if (wsi->vhost->http_proxy_port) {
31                 plen = sprintf((char *)pt->serv_buf,
32                         "CONNECT %s:%u HTTP/1.0\x0d\x0a"
33                         "User-agent: libwebsockets\x0d\x0a",
34                         lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
35                         wsi->c_port);
36
37                 if (wsi->vhost->proxy_basic_auth_token[0])
38                         plen += sprintf((char *)pt->serv_buf + plen,
39                                         "Proxy-authorization: basic %s\x0d\x0a",
40                                         wsi->vhost->proxy_basic_auth_token);
41
42                 plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a");
43                 ads = wsi->vhost->http_proxy_address;
44
45 #ifdef LWS_USE_IPV6
46                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
47                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
48                         server_addr6.sin6_port = htons(wsi->vhost->http_proxy_port);
49                 } else
50 #endif
51                         server_addr4.sin_port = htons(wsi->vhost->http_proxy_port);
52
53         }
54 #if defined(LWS_WITH_SOCKS5)
55         /* socks proxy */
56         else if (wsi->vhost->socks_proxy_port) {
57                 socks_generate_msg(wsi, SOCKS_MSG_GREETING, (size_t *)&plen);
58                 lwsl_client("%s\n", "Sending SOCKS Greeting.");
59
60                 ads = wsi->vhost->socks_proxy_address;
61
62 #ifdef LWS_USE_IPV6
63                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
64                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
65                         server_addr6.sin6_port = htons(wsi->vhost->socks_proxy_port);
66                 } else
67 #endif
68                         server_addr4.sin_port = htons(wsi->vhost->socks_proxy_port);
69
70         }
71 #endif
72         else {
73                 ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
74 #ifdef LWS_USE_IPV6
75                 if (LWS_IPV6_ENABLED(wsi->vhost)) {
76                         memset(&server_addr6, 0, sizeof(struct sockaddr_in6));
77                         server_addr6.sin6_port = htons(wsi->c_port);
78                 } else
79 #endif
80                         server_addr4.sin_port = htons(wsi->c_port);
81         }
82
83         /*
84          * prepare the actual connection (to the proxy, if any)
85          */
86        lwsl_notice("%s: %p: address %s\n", __func__, wsi, ads);
87
88 #ifdef LWS_USE_IPV6
89         if (LWS_IPV6_ENABLED(wsi->vhost)) {
90                 memset(&hints, 0, sizeof(struct addrinfo));
91 #if !defined(__ANDROID__)
92                 hints.ai_family = AF_INET6;
93                 hints.ai_flags = AI_V4MAPPED;
94 #endif
95                 n = getaddrinfo(ads, NULL, &hints, &result);
96                 if (n) {
97 #ifdef _WIN32
98                         lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n));
99 #else
100                         lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
101 #endif
102                         cce = "getaddrinfo (ipv6) failed";
103                         goto oom4;
104                 }
105
106                 server_addr6.sin6_family = AF_INET6;
107                 switch (result->ai_family) {
108 #if defined(__ANDROID__)
109                 case AF_INET:
110                         /* map IPv4 to IPv6 */
111                         bzero((char *)&server_addr6.sin6_addr,
112                                                 sizeof(struct in6_addr));
113                         server_addr6.sin6_addr.s6_addr[10] = 0xff;
114                         server_addr6.sin6_addr.s6_addr[11] = 0xff;
115                         memcpy(&server_addr6.sin6_addr.s6_addr[12],
116                                 &((struct sockaddr_in *)result->ai_addr)->sin_addr,
117                                                         sizeof(struct in_addr));
118                         break;
119 #endif
120                 case AF_INET6:
121                         memcpy(&server_addr6.sin6_addr,
122                           &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
123                                                 sizeof(struct in6_addr));
124                         server_addr6.sin6_scope_id = ((struct sockaddr_in6 *)result->ai_addr)->sin6_scope_id;
125                         server_addr6.sin6_flowinfo = ((struct sockaddr_in6 *)result->ai_addr)->sin6_flowinfo;
126                         break;
127                 default:
128                         lwsl_err("Unknown address family\n");
129                         freeaddrinfo(result);
130                         cce = "unknown address family";
131                         goto oom4;
132                 }
133
134                 freeaddrinfo(result);
135         } else
136 #endif
137         {
138                 struct addrinfo ai, *res, *result = NULL;
139                 void *p = NULL;
140                 int addr_rv;
141
142                 memset (&ai, 0, sizeof ai);
143                 ai.ai_family = PF_UNSPEC;
144                 ai.ai_socktype = SOCK_STREAM;
145                 ai.ai_flags = AI_CANONNAME;
146
147                 addr_rv = getaddrinfo(ads, NULL, &ai, &result);
148                 if (!addr_rv) {
149                         res = result;
150                         while (!p && res) {
151                                 switch (res->ai_family) {
152                                 case AF_INET:
153                                         p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
154                                         break;
155                                 }
156
157                                 res = res->ai_next;
158                         }
159 #if defined(LWS_FALLBACK_GETHOSTBYNAME)
160                 } else if (addr_rv == EAI_SYSTEM) {
161                         struct hostent *host;
162
163                         lwsl_info("getaddrinfo (ipv4) failed, trying gethostbyname\n");
164                         host = gethostbyname(ads);
165                         if (host) {
166                                 p = host->h_addr;
167                         } else {
168                                 lwsl_err("gethostbyname failed\n");
169                                 cce = "gethostbyname (ipv4) failed";
170                                 goto oom4;
171                         }
172 #endif
173                 } else {
174                         lwsl_err("getaddrinfo failed\n");
175                         cce = "getaddrinfo (ipv4) failed";
176                         goto oom4;
177                 }
178
179                 if (!p) {
180                         if (result)
181                                 freeaddrinfo(result);
182                         lwsl_err("Couldn't identify address\n");
183                         cce = "unable to lookup address";
184                         goto oom4;
185                 }
186
187                 server_addr4.sin_family = AF_INET;
188                 server_addr4.sin_addr = *((struct in_addr *)p);
189                 bzero(&server_addr4.sin_zero, 8);
190                 if (result)
191                         freeaddrinfo(result);
192         }
193
194         if (!lws_socket_is_valid(wsi->desc.sockfd)) {
195
196 #ifdef LWS_USE_IPV6
197                 if (LWS_IPV6_ENABLED(wsi->vhost))
198                         wsi->desc.sockfd = socket(AF_INET6, SOCK_STREAM, 0);
199                 else
200 #endif
201                         wsi->desc.sockfd = socket(AF_INET, SOCK_STREAM, 0);
202
203                 if (!lws_socket_is_valid(wsi->desc.sockfd)) {
204                         lwsl_warn("Unable to open socket\n");
205                         cce = "unable to open socket";
206                         goto oom4;
207                 }
208
209                 if (lws_plat_set_socket_options(wsi->vhost, wsi->desc.sockfd)) {
210                         lwsl_err("Failed to set wsi socket options\n");
211                         compatible_close(wsi->desc.sockfd);
212                         cce = "set socket opts failed";
213                         goto oom4;
214                 }
215
216                 wsi->mode = LWSCM_WSCL_WAITING_CONNECT;
217
218                 lws_libev_accept(wsi, wsi->desc);
219                 lws_libuv_accept(wsi, wsi->desc);
220                 lws_libevent_accept(wsi, wsi->desc);
221                 if (insert_wsi_socket_into_fds(context, wsi)) {
222                         compatible_close(wsi->desc.sockfd);
223                         cce = "insert wsi failed";
224                         goto oom4;
225                 }
226
227                 lws_change_pollfd(wsi, 0, LWS_POLLIN);
228
229                 /*
230                  * past here, we can't simply free the structs as error
231                  * handling as oom4 does.  We have to run the whole close flow.
232                  */
233
234                 if (!wsi->protocol)
235                         wsi->protocol = &wsi->vhost->protocols[0];
236
237                 wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE,
238                                         wsi->user_space, NULL, 0);
239
240                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
241                                 AWAITING_TIMEOUT);
242
243                 iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE);
244
245                 if (iface) {
246                         n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, iface);
247                         if (n < 0) {
248                                 cce = "unable to bind socket";
249                                 goto failed;
250                         }
251                 }
252         }
253
254 #ifdef LWS_USE_IPV6
255         if (LWS_IPV6_ENABLED(wsi->vhost)) {
256                 v = (struct sockaddr *)&server_addr6;
257                 n = sizeof(struct sockaddr_in6);
258         } else
259 #endif
260         {
261                 v = (struct sockaddr *)&server_addr4;
262                 n = sizeof(struct sockaddr);
263         }
264
265         if (connect(wsi->desc.sockfd, v, n) == -1 ||
266             LWS_ERRNO == LWS_EISCONN) {
267                 if (LWS_ERRNO == LWS_EALREADY ||
268                     LWS_ERRNO == LWS_EINPROGRESS ||
269                     LWS_ERRNO == LWS_EWOULDBLOCK
270 #ifdef _WIN32
271                         || LWS_ERRNO == WSAEINVAL
272 #endif
273                 ) {
274                         lwsl_client("nonblocking connect retry (errno = %d)\n",
275                                     LWS_ERRNO);
276
277                         if (lws_plat_check_connection_error(wsi)) {
278                                 cce = "socket connect failed";
279                                 goto failed;
280                         }
281
282                         /*
283                          * must do specifically a POLLOUT poll to hear
284                          * about the connect completion
285                          */
286                         if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
287                                 cce = "POLLOUT set failed";
288                                 goto failed;
289                         }
290
291                         return wsi;
292                 }
293
294                 if (LWS_ERRNO != LWS_EISCONN) {
295                         lwsl_notice("Connect failed errno=%d\n", LWS_ERRNO);
296                         cce = "connect failed";
297                         goto failed;
298                 }
299         }
300
301         lwsl_client("connected\n");
302
303         /* we are connected to server, or proxy */
304
305         /* http proxy */
306         if (wsi->vhost->http_proxy_port) {
307
308                 /*
309                  * OK from now on we talk via the proxy, so connect to that
310                  *
311                  * (will overwrite existing pointer,
312                  * leaving old string/frag there but unreferenced)
313                  */
314                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
315                                           wsi->vhost->http_proxy_address))
316                         goto failed;
317                 wsi->c_port = wsi->vhost->http_proxy_port;
318
319                 n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
320                          MSG_NOSIGNAL);
321                 if (n < 0) {
322                         lwsl_debug("ERROR writing to proxy socket\n");
323                         cce = "proxy write failed";
324                         goto failed;
325                 }
326
327                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
328                                 AWAITING_TIMEOUT);
329
330                 wsi->mode = LWSCM_WSCL_WAITING_PROXY_REPLY;
331
332                 return wsi;
333         }
334 #if defined(LWS_WITH_SOCKS5)
335         /* socks proxy */
336         else if (wsi->vhost->socks_proxy_port) {
337                 n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen,
338                          MSG_NOSIGNAL);
339                 if (n < 0) {
340                         lwsl_debug("ERROR writing greeting to socks proxy"
341                                 "socket.\n");
342                         cce = "socks write failed";
343                         goto failed;
344                 }
345
346                 lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY,
347                                 AWAITING_TIMEOUT);
348
349                 wsi->mode = LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY;
350
351                 return wsi;
352         }
353 #endif
354
355         /*
356          * provoke service to issue the handshake directly
357          * we need to do it this way because in the proxy case, this is the
358          * next state and executed only if and when we get a good proxy
359          * response inside the state machine... but notice in SSL case this
360          * may not have sent anything yet with 0 return, and won't until some
361          * many retries from main loop.  To stop that becoming endless,
362          * cover with a timeout.
363          */
364
365         lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
366                         AWAITING_TIMEOUT);
367
368         wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE;
369         pfd.fd = wsi->desc.sockfd;
370         pfd.events = LWS_POLLIN;
371         pfd.revents = LWS_POLLIN;
372
373         n = lws_service_fd(context, &pfd);
374         if (n < 0) {
375                 cce = "first service failed";
376                 goto failed;
377         }
378         if (n) /* returns 1 on failure after closing wsi */
379                 return NULL;
380
381         return wsi;
382
383 oom4:
384         /* we're closing, losing some rx is OK */
385         if (wsi->u.hdr.ah)
386                 wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
387         if (wsi->mode == LWSCM_HTTP_CLIENT ||
388             wsi->mode == LWSCM_HTTP_CLIENT_ACCEPTED ||
389             wsi->mode == LWSCM_WSCL_WAITING_CONNECT) {
390                 wsi->vhost->protocols[0].callback(wsi,
391                         LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
392                         wsi->user_space, (void *)cce, strlen(cce));
393                 wsi->already_did_cce = 1;
394         }
395         /* take care that we might be inserted in fds already */
396         if (wsi->position_in_fds_table != -1)
397                 goto failed1;
398         lws_remove_from_timeout_list(wsi);
399         lws_header_table_detach(wsi, 0);
400         lws_free(wsi);
401
402         return NULL;
403
404 failed:
405         wsi->vhost->protocols[0].callback(wsi,
406                 LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
407                 wsi->user_space, (void *)cce, strlen(cce));
408         wsi->already_did_cce = 1;
409 failed1:
410         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
411
412         return NULL;
413 }
414
415 /**
416  * lws_client_reset() - retarget a connected wsi to start over with a new connection (ie, redirect)
417  *                      this only works if still in HTTP, ie, not upgraded yet
418  * wsi:         connection to reset
419  * address:     network address of the new server
420  * port:        port to connect to
421  * path:        uri path to connect to on the new server
422  * host:        host header to send to the new server
423  */
424 LWS_VISIBLE struct lws *
425 lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
426                  const char *path, const char *host)
427 {
428         char origin[300] = "", protocol[300] = "", method[32] = "", iface[16] = "", *p;
429         struct lws *wsi = *pwsi;
430
431         if (wsi->redirects == 3) {
432                 lwsl_err("%s: Too many redirects\n", __func__);
433                 return NULL;
434         }
435         wsi->redirects++;
436
437 #ifdef LWS_OPENSSL_SUPPORT
438         wsi->use_ssl = ssl;
439 #else
440         if (ssl) {
441                 lwsl_err("%s: not configured for ssl\n", __func__);
442                 return NULL;
443         }
444 #endif
445
446         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
447         if (p)
448                 strncpy(origin, p, sizeof(origin) - 1);
449
450         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
451         if (p)
452                 strncpy(protocol, p, sizeof(protocol) - 1);
453
454         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
455         if (p)
456                 strncpy(method, p, sizeof(method) - 1);
457
458         p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE);
459         if (p)
460                 strncpy(method, p, sizeof(iface) - 1);
461
462         lwsl_debug("redirect ads='%s', port=%d, path='%s', ssl = %d\n",
463                    address, port, path, ssl);
464
465         /* close the connection by hand */
466
467         compatible_close(wsi->desc.sockfd);
468         remove_wsi_socket_from_fds(wsi);
469
470         wsi->desc.sockfd = LWS_SOCK_INVALID;
471         wsi->state = LWSS_CLIENT_UNCONNECTED;
472         wsi->protocol = NULL;
473         wsi->pending_timeout = NO_PENDING_TIMEOUT;
474         wsi->c_port = port;
475         wsi->hdr_parsing_completed = 0;
476         _lws_header_table_reset(wsi->u.hdr.ah);
477
478         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
479                 return NULL;
480
481         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
482                 return NULL;
483
484         if (origin[0])
485                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
486                                           origin))
487                         return NULL;
488         if (protocol[0])
489                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
490                                           protocol))
491                         return NULL;
492         if (method[0])
493                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
494                                           method))
495                         return NULL;
496
497         if (iface[0])
498                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE,
499                                           iface))
500                         return NULL;
501
502         origin[0] = '/';
503         strncpy(&origin[1], path, sizeof(origin) - 2);
504         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin))
505                 return NULL;
506
507         *pwsi = lws_client_connect_2(wsi);
508
509         return *pwsi;
510 }
511
512 #ifdef LWS_WITH_HTTP_PROXY
513 static hubbub_error
514 html_parser_cb(const hubbub_token *token, void *pw)
515 {
516         struct lws_rewrite *r = (struct lws_rewrite *)pw;
517         char buf[1024], *start = buf + LWS_PRE, *p = start,
518              *end = &buf[sizeof(buf) - 1];
519         size_t i;
520
521         switch (token->type) {
522         case HUBBUB_TOKEN_DOCTYPE:
523
524                 p += lws_snprintf(p, end - p, "<!DOCTYPE %.*s %s ",
525                                 (int) token->data.doctype.name.len,
526                                 token->data.doctype.name.ptr,
527                                 token->data.doctype.force_quirks ?
528                                                 "(force-quirks) " : "");
529
530                 if (token->data.doctype.public_missing)
531                         lwsl_debug("\tpublic: missing\n");
532                 else
533                         p += lws_snprintf(p, end - p, "PUBLIC \"%.*s\"\n",
534                                 (int) token->data.doctype.public_id.len,
535                                 token->data.doctype.public_id.ptr);
536
537                 if (token->data.doctype.system_missing)
538                         lwsl_debug("\tsystem: missing\n");
539                 else
540                         p += lws_snprintf(p, end - p, " \"%.*s\">\n",
541                                 (int) token->data.doctype.system_id.len,
542                                 token->data.doctype.system_id.ptr);
543
544                 break;
545         case HUBBUB_TOKEN_START_TAG:
546                 p += lws_snprintf(p, end - p, "<%.*s", (int)token->data.tag.name.len,
547                                 token->data.tag.name.ptr);
548
549 /*                              (token->data.tag.self_closing) ?
550                                                 "(self-closing) " : "",
551                                 (token->data.tag.n_attributes > 0) ?
552                                                 "attributes:" : "");
553 */
554                 for (i = 0; i < token->data.tag.n_attributes; i++) {
555                         if (!hstrcmp(&token->data.tag.attributes[i].name, "href", 4) ||
556                             !hstrcmp(&token->data.tag.attributes[i].name, "action", 6) ||
557                             !hstrcmp(&token->data.tag.attributes[i].name, "src", 3)) {
558                                 const char *pp = (const char *)token->data.tag.attributes[i].value.ptr;
559                                 int plen = (int) token->data.tag.attributes[i].value.len;
560
561                                 if (strncmp(pp, "http:", 5) && strncmp(pp, "https:", 6)) {
562
563                                         if (!hstrcmp(&token->data.tag.attributes[i].value,
564                                                      r->from, r->from_len)) {
565                                                 pp += r->from_len;
566                                                 plen -= r->from_len;
567                                         }
568                                         p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"",
569                                                (int) token->data.tag.attributes[i].name.len,
570                                                token->data.tag.attributes[i].name.ptr,
571                                                r->to, plen, pp);
572                                         continue;
573                                 }
574                         }
575
576                         p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"",
577                                 (int) token->data.tag.attributes[i].name.len,
578                                 token->data.tag.attributes[i].name.ptr,
579                                 (int) token->data.tag.attributes[i].value.len,
580                                 token->data.tag.attributes[i].value.ptr);
581                 }
582                 p += lws_snprintf(p, end - p, ">");
583                 break;
584         case HUBBUB_TOKEN_END_TAG:
585                 p += lws_snprintf(p, end - p, "</%.*s", (int) token->data.tag.name.len,
586                                 token->data.tag.name.ptr);
587 /*
588                                 (token->data.tag.self_closing) ?
589                                                 "(self-closing) " : "",
590                                 (token->data.tag.n_attributes > 0) ?
591                                                 "attributes:" : "");
592 */
593                 for (i = 0; i < token->data.tag.n_attributes; i++) {
594                         p += lws_snprintf(p, end - p, " %.*s='%.*s'\n",
595                                 (int) token->data.tag.attributes[i].name.len,
596                                 token->data.tag.attributes[i].name.ptr,
597                                 (int) token->data.tag.attributes[i].value.len,
598                                 token->data.tag.attributes[i].value.ptr);
599                 }
600                 p += lws_snprintf(p, end - p, ">");
601                 break;
602         case HUBBUB_TOKEN_COMMENT:
603                 p += lws_snprintf(p, end - p, "<!-- %.*s -->\n",
604                                 (int) token->data.comment.len,
605                                 token->data.comment.ptr);
606                 break;
607         case HUBBUB_TOKEN_CHARACTER:
608                 if (token->data.character.len == 1) {
609                         if (*token->data.character.ptr == '<') {
610                                 p += lws_snprintf(p, end - p, "&lt;");
611                                 break;
612                         }
613                         if (*token->data.character.ptr == '>') {
614                                 p += lws_snprintf(p, end - p, "&gt;");
615                                 break;
616                         }
617                         if (*token->data.character.ptr == '&') {
618                                 p += lws_snprintf(p, end - p, "&amp;");
619                                 break;
620                         }
621                 }
622
623                 p += lws_snprintf(p, end - p, "%.*s", (int) token->data.character.len,
624                                 token->data.character.ptr);
625                 break;
626         case HUBBUB_TOKEN_EOF:
627                 p += lws_snprintf(p, end - p, "\n");
628                 break;
629         }
630
631         if (user_callback_handle_rxflow(r->wsi->protocol->callback,
632                         r->wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ,
633                         r->wsi->user_space, start, p - start))
634                 return -1;
635
636         return HUBBUB_OK;
637 }
638 #endif
639
640 LWS_VISIBLE struct lws *
641 lws_client_connect_via_info(struct lws_client_connect_info *i)
642 {
643         struct lws *wsi;
644         int v = SPEC_LATEST_SUPPORTED;
645         const struct lws_protocols *p;
646
647         if (i->context->requested_kill)
648                 return NULL;
649
650         if (!i->context->protocol_init_done)
651                 lws_protocol_init(i->context);
652
653         wsi = lws_zalloc(sizeof(struct lws));
654         if (wsi == NULL)
655                 goto bail;
656
657         wsi->context = i->context;
658         /* assert the mode and union status (hdr) clearly */
659         lws_union_transition(wsi, LWSCM_HTTP_CLIENT);
660         wsi->desc.sockfd = LWS_SOCK_INVALID;
661
662         /* 1) fill up the wsi with stuff from the connect_info as far as it
663          * can go.  It's because not only is our connection async, we might
664          * not even be able to get ahold of an ah at this point.
665          */
666
667         /* -1 means just use latest supported */
668         if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one)
669                 v = i->ietf_version_or_minus_one;
670
671         wsi->ietf_spec_revision = v;
672         wsi->user_space = NULL;
673         wsi->state = LWSS_CLIENT_UNCONNECTED;
674         wsi->pending_timeout = NO_PENDING_TIMEOUT;
675         wsi->position_in_fds_table = -1;
676         wsi->c_port = i->port;
677         wsi->vhost = i->vhost;
678         if (!wsi->vhost)
679                 wsi->vhost = i->context->vhost_list;
680
681         wsi->protocol = &wsi->vhost->protocols[0];
682
683         /* for http[s] connection, allow protocol selection by name */
684
685         if (i->method && i->vhost && i->protocol) {
686                 p = lws_vhost_name_to_protocol(i->vhost, i->protocol);
687                 if (p)
688                         wsi->protocol = p;
689         }
690
691         if (wsi && !wsi->user_space && i->userdata) {
692                 wsi->user_space_externally_allocated = 1;
693                 wsi->user_space = i->userdata;
694         } else
695                 /* if we stay in http, we can assign the user space now,
696                  * otherwise do it after the protocol negotiated
697                  */
698                 if (i->method)
699                         if (lws_ensure_user_space(wsi))
700                                 goto bail;
701
702 #ifdef LWS_OPENSSL_SUPPORT
703         wsi->use_ssl = i->ssl_connection;
704 #else
705         if (i->ssl_connection) {
706                 lwsl_err("libwebsockets not configured for ssl\n");
707                 goto bail;
708         }
709 #endif
710
711         /* 2) stash the things from connect_info that we can't process without
712          * an ah.  Because if no ah, we will go on the ah waiting list and
713          * process those things later (after the connect_info and maybe the
714          * things pointed to have gone out of scope.
715          */
716
717         wsi->u.hdr.stash = lws_malloc(sizeof(*wsi->u.hdr.stash));
718         if (!wsi->u.hdr.stash) {
719                 lwsl_err("%s: OOM\n", __func__);
720                 goto bail;
721         }
722
723         wsi->u.hdr.stash->origin[0] = '\0';
724         wsi->u.hdr.stash->protocol[0] = '\0';
725         wsi->u.hdr.stash->method[0] = '\0';
726         wsi->u.hdr.stash->iface[0] = '\0';
727
728         strncpy(wsi->u.hdr.stash->address, i->address,
729                 sizeof(wsi->u.hdr.stash->address) - 1);
730         strncpy(wsi->u.hdr.stash->path, i->path,
731                 sizeof(wsi->u.hdr.stash->path) - 1);
732         strncpy(wsi->u.hdr.stash->host, i->host,
733                 sizeof(wsi->u.hdr.stash->host) - 1);
734         if (i->origin)
735                 strncpy(wsi->u.hdr.stash->origin, i->origin,
736                         sizeof(wsi->u.hdr.stash->origin) - 1);
737         if (i->protocol)
738                 strncpy(wsi->u.hdr.stash->protocol, i->protocol,
739                         sizeof(wsi->u.hdr.stash->protocol) - 1);
740         if (i->method)
741                 strncpy(wsi->u.hdr.stash->method, i->method,
742                         sizeof(wsi->u.hdr.stash->method) - 1);
743         if (i->iface)
744                 strncpy(wsi->u.hdr.stash->iface, i->iface,
745                         sizeof(wsi->u.hdr.stash->iface) - 1);
746
747         wsi->u.hdr.stash->address[sizeof(wsi->u.hdr.stash->address) - 1] = '\0';
748         wsi->u.hdr.stash->path[sizeof(wsi->u.hdr.stash->path) - 1] = '\0';
749         wsi->u.hdr.stash->host[sizeof(wsi->u.hdr.stash->host) - 1] = '\0';
750         wsi->u.hdr.stash->origin[sizeof(wsi->u.hdr.stash->origin) - 1] = '\0';
751         wsi->u.hdr.stash->protocol[sizeof(wsi->u.hdr.stash->protocol) - 1] = '\0';
752         wsi->u.hdr.stash->method[sizeof(wsi->u.hdr.stash->method) - 1] = '\0';
753         wsi->u.hdr.stash->iface[sizeof(wsi->u.hdr.stash->iface) - 1] = '\0';
754
755         if (i->pwsi)
756                 *i->pwsi = wsi;
757
758         /* if we went on the waiting list, no probs just return the wsi
759          * when we get the ah, now or later, he will call
760          * lws_client_connect_via_info2() below.
761          */
762         if (lws_header_table_attach(wsi, 0) < 0) {
763                 /*
764                  * if we failed here, the connection is already closed
765                  * and freed.
766                  */
767                 goto bail1;
768         }
769
770         if (i->parent_wsi) {
771                 lwsl_info("%s: created child %p of parent %p\n", __func__,
772                                 wsi, i->parent_wsi);
773                 wsi->parent = i->parent_wsi;
774                 wsi->sibling_list = i->parent_wsi->child_list;
775                 i->parent_wsi->child_list = wsi;
776         }
777 #ifdef LWS_WITH_HTTP_PROXY
778         if (i->uri_replace_to)
779                 wsi->rw = lws_rewrite_create(wsi, html_parser_cb,
780                                              i->uri_replace_from,
781                                              i->uri_replace_to);
782 #endif
783
784         return wsi;
785
786 bail:
787         lws_free(wsi);
788
789 bail1:
790         if (i->pwsi)
791                 *i->pwsi = NULL;
792
793         return NULL;
794 }
795
796 struct lws *
797 lws_client_connect_via_info2(struct lws *wsi)
798 {
799         struct client_info_stash *stash = wsi->u.hdr.stash;
800
801         if (!stash)
802                 return wsi;
803
804         /*
805          * we're not necessarily in a position to action these right away,
806          * stash them... we only need during connect phase so u.hdr is fine
807          */
808         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
809                                   stash->address))
810                 goto bail1;
811
812         /* these only need u.hdr lifetime as well */
813
814         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path))
815                 goto bail1;
816
817         if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host))
818                 goto bail1;
819
820         if (stash->origin[0])
821                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN,
822                                           stash->origin))
823                         goto bail1;
824         /*
825          * this is a list of protocols we tell the server we're okay with
826          * stash it for later when we compare server response with it
827          */
828         if (stash->protocol[0])
829                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
830                                           stash->protocol))
831                         goto bail1;
832         if (stash->method[0])
833                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD,
834                                           stash->method))
835                         goto bail1;
836         if (stash->iface[0])
837                 if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE,
838                                           stash->iface))
839                         goto bail1;
840
841 #if defined(LWS_WITH_SOCKS5)
842         if (!wsi->vhost->socks_proxy_port)
843                 lws_free_set_NULL(wsi->u.hdr.stash);
844 #endif
845
846         /*
847          * Check with each extension if it is able to route and proxy this
848          * connection for us.  For example, an extension like x-google-mux
849          * can handle this and then we don't need an actual socket for this
850          * connection.
851          */
852
853         if (lws_ext_cb_all_exts(wsi->context, wsi,
854                                 LWS_EXT_CB_CAN_PROXY_CLIENT_CONNECTION,
855                                 (void *)stash->address,
856                                 wsi->c_port) > 0) {
857                 lwsl_client("lws_client_connect: ext handling conn\n");
858
859                 lws_set_timeout(wsi,
860                         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
861                                 AWAITING_TIMEOUT);
862
863                 wsi->mode = LWSCM_WSCL_WAITING_EXTENSION_CONNECT;
864                 return wsi;
865         }
866         lwsl_client("lws_client_connect: direct conn\n");
867         wsi->context->count_wsi_allocated++;
868
869         return lws_client_connect_2(wsi);
870
871 bail1:
872 #if defined(LWS_WITH_SOCKS5)
873         if (!wsi->vhost->socks_proxy_port)
874                 lws_free_set_NULL(wsi->u.hdr.stash);
875 #endif
876
877         return NULL;
878 }
879
880 LWS_VISIBLE struct lws *
881 lws_client_connect_extended(struct lws_context *context, const char *address,
882                             int port, int ssl_connection, const char *path,
883                             const char *host, const char *origin,
884                             const char *protocol, int ietf_version_or_minus_one,
885                             void *userdata)
886 {
887         struct lws_client_connect_info i;
888
889         memset(&i, 0, sizeof(i));
890
891         i.context = context;
892         i.address = address;
893         i.port = port;
894         i.ssl_connection = ssl_connection;
895         i.path = path;
896         i.host = host;
897         i.origin = origin;
898         i.protocol = protocol;
899         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
900         i.userdata = userdata;
901
902         return lws_client_connect_via_info(&i);
903 }
904
905 LWS_VISIBLE struct lws *
906 lws_client_connect(struct lws_context *context, const char *address,
907                             int port, int ssl_connection, const char *path,
908                             const char *host, const char *origin,
909                             const char *protocol, int ietf_version_or_minus_one)
910 {
911         struct lws_client_connect_info i;
912
913         memset(&i, 0, sizeof(i));
914
915         i.context = context;
916         i.address = address;
917         i.port = port;
918         i.ssl_connection = ssl_connection;
919         i.path = path;
920         i.host = host;
921         i.origin = origin;
922         i.protocol = protocol;
923         i.ietf_version_or_minus_one = ietf_version_or_minus_one;
924         i.userdata = NULL;
925
926         return lws_client_connect_via_info(&i);
927 }
928
929 #if defined(LWS_WITH_SOCKS5)
930 void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
931                         size_t *msg_len)
932 {
933         struct lws_context *context = wsi->context;
934         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
935         size_t len = 0;
936
937         if (type == SOCKS_MSG_GREETING) {
938                 /* socks version, version 5 only */
939                 pt->serv_buf[len++] = SOCKS_VERSION_5;
940                 /* number of methods */
941                 pt->serv_buf[len++] = 2;
942                 /* username password method */
943                 pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD;
944                 /* no authentication method */
945                 pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH;
946         }
947         else if (type == SOCKS_MSG_USERNAME_PASSWORD) {
948                 size_t user_len = 0;
949                 size_t passwd_len = 0;
950
951                 user_len = strlen(wsi->vhost->socks_user);
952                 passwd_len = strlen(wsi->vhost->socks_password);
953
954                 /* the subnegotiation version */
955                 pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1;
956                 /* length of the user name */
957                 pt->serv_buf[len++] = user_len;
958                 /* user name */
959                 strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user,
960                         context->pt_serv_buf_size - len);
961                 len += user_len;
962                 /* length of the password */
963                 pt->serv_buf[len++] = passwd_len;
964                 /* password */
965                 strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password,
966                         context->pt_serv_buf_size - len);
967                 len += passwd_len;
968         }
969         else if (type == SOCKS_MSG_CONNECT) {
970                 size_t len_index = 0;
971                 short net_num = 0;
972                 char *net_buf = (char*)&net_num;
973
974                 /* socks version */
975                 pt->serv_buf[len++] = SOCKS_VERSION_5;
976                 /* socks command */
977                 pt->serv_buf[len++] = SOCKS_COMMAND_CONNECT;
978                 /* reserved */
979                 pt->serv_buf[len++] = 0;
980                 /* address type */
981                 pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME;
982                 len_index = len;
983                 len++;
984                 /* the address we tell SOCKS proxy to connect to */
985                 strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address,
986                         context->pt_serv_buf_size - len);
987                 len += strlen(wsi->u.hdr.stash->address);
988                 net_num = htons((short)wsi->c_port);
989                 /* the port we tell SOCKS proxy to connect to */
990                 pt->serv_buf[len++] = net_buf[0];
991                 pt->serv_buf[len++] = net_buf[1];
992                 /* the length of the address, excluding port */
993                 pt->serv_buf[len_index] = strlen(wsi->u.hdr.stash->address);
994         }
995
996         *msg_len = len;
997 }
998 #endif