client.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation:
  9. * version 2.1 of the License.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301 USA
  20. */
  21. #include "private-libwebsockets.h"
  22. int
  23. lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len)
  24. {
  25. int m;
  26. switch (wsi->mode) {
  27. case LWSCM_WSCL_WAITING_PROXY_REPLY:
  28. case LWSCM_WSCL_ISSUE_HANDSHAKE:
  29. case LWSCM_WSCL_WAITING_SERVER_REPLY:
  30. case LWSCM_WSCL_WAITING_EXTENSION_CONNECT:
  31. case LWSCM_WS_CLIENT:
  32. while (len) {
  33. /*
  34. * we were accepting input but now we stopped doing so
  35. */
  36. if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) {
  37. lwsl_debug("%s: caching %ld\n", __func__, (long)len);
  38. lws_rxflow_cache(wsi, *buf, 0, len);
  39. return 0;
  40. }
  41. if (wsi->u.ws.rx_draining_ext) {
  42. m = lws_rx_sm(wsi, 0);
  43. if (m < 0)
  44. return -1;
  45. continue;
  46. }
  47. /* account for what we're using in rxflow buffer */
  48. if (wsi->rxflow_buffer)
  49. wsi->rxflow_pos++;
  50. if (lws_client_rx_sm(wsi, *(*buf)++)) {
  51. lwsl_debug("client_rx_sm exited\n");
  52. return -1;
  53. }
  54. len--;
  55. }
  56. lwsl_debug("%s: finished with %ld\n", __func__, (long)len);
  57. return 0;
  58. default:
  59. break;
  60. }
  61. return 0;
  62. }
  63. LWS_VISIBLE LWS_EXTERN void
  64. lws_client_http_body_pending(struct lws *wsi, int something_left_to_send)
  65. {
  66. wsi->client_http_body_pending = !!something_left_to_send;
  67. }
  68. int
  69. lws_client_socket_service(struct lws_context *context, struct lws *wsi,
  70. struct lws_pollfd *pollfd)
  71. {
  72. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  73. char *p = (char *)&pt->serv_buf[0];
  74. const char *cce = NULL;
  75. unsigned char c;
  76. char *sb = p;
  77. int n, len;
  78. switch (wsi->mode) {
  79. case LWSCM_WSCL_WAITING_CONNECT:
  80. /*
  81. * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
  82. * timeout protection set in client-handshake.c
  83. */
  84. if (!lws_client_connect_2(wsi)) {
  85. /* closed */
  86. lwsl_client("closed\n");
  87. return -1;
  88. }
  89. /* either still pending connection, or changed mode */
  90. return 0;
  91. case LWSCM_WSCL_WAITING_PROXY_REPLY:
  92. /* handle proxy hung up on us */
  93. if (pollfd->revents & LWS_POLLHUP) {
  94. lwsl_warn("Proxy connection %p (fd=%d) dead\n",
  95. (void *)wsi, pollfd->fd);
  96. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  97. return 0;
  98. }
  99. n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0);
  100. if (n < 0) {
  101. if (LWS_ERRNO == LWS_EAGAIN) {
  102. lwsl_debug("Proxy read returned EAGAIN... retrying\n");
  103. return 0;
  104. }
  105. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  106. lwsl_err("ERROR reading from proxy socket\n");
  107. return 0;
  108. }
  109. pt->serv_buf[13] = '\0';
  110. if (strcmp(sb, "HTTP/1.0 200 ") &&
  111. strcmp(sb, "HTTP/1.1 200 ")) {
  112. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  113. lwsl_err("ERROR proxy: %s\n", sb);
  114. return 0;
  115. }
  116. /* clear his proxy connection timeout */
  117. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  118. /* fallthru */
  119. case LWSCM_WSCL_ISSUE_HANDSHAKE:
  120. /*
  121. * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
  122. * timeout protection set in client-handshake.c
  123. *
  124. * take care of our lws_callback_on_writable
  125. * happening at a time when there's no real connection yet
  126. */
  127. if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
  128. return -1;
  129. #ifdef LWS_OPENSSL_SUPPORT
  130. /* we can retry this... just cook the SSL BIO the first time */
  131. if (wsi->use_ssl && !wsi->ssl) {
  132. if (lws_ssl_client_bio_create(wsi))
  133. return -1;
  134. }
  135. if (wsi->use_ssl) {
  136. n = lws_ssl_client_connect1(wsi);
  137. if (!n)
  138. return 0;
  139. if (n < 0) {
  140. cce = "lws_ssl_client_connect1 failed";
  141. goto bail3;
  142. }
  143. } else
  144. wsi->ssl = NULL;
  145. /* fallthru */
  146. case LWSCM_WSCL_WAITING_SSL:
  147. if (wsi->use_ssl) {
  148. n = lws_ssl_client_connect2(wsi);
  149. if (!n)
  150. return 0;
  151. if (n < 0) {
  152. cce = "lws_ssl_client_connect2 failed";
  153. goto bail3;
  154. }
  155. } else
  156. wsi->ssl = NULL;
  157. #endif
  158. wsi->mode = LWSCM_WSCL_ISSUE_HANDSHAKE2;
  159. lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
  160. context->timeout_secs);
  161. /* fallthru */
  162. case LWSCM_WSCL_ISSUE_HANDSHAKE2:
  163. p = lws_generate_client_handshake(wsi, p);
  164. if (p == NULL) {
  165. if (wsi->mode == LWSCM_RAW)
  166. return 0;
  167. lwsl_err("Failed to generate handshake for client\n");
  168. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  169. return 0;
  170. }
  171. /* send our request to the server */
  172. lws_latency_pre(context, wsi);
  173. n = lws_ssl_capable_write(wsi, (unsigned char *)sb, p - sb);
  174. lws_latency(context, wsi, "send lws_issue_raw", n,
  175. n == p - sb);
  176. switch (n) {
  177. case LWS_SSL_CAPABLE_ERROR:
  178. lwsl_debug("ERROR writing to client socket\n");
  179. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  180. return 0;
  181. case LWS_SSL_CAPABLE_MORE_SERVICE:
  182. lws_callback_on_writable(wsi);
  183. break;
  184. }
  185. if (wsi->client_http_body_pending) {
  186. wsi->mode = LWSCM_WSCL_ISSUE_HTTP_BODY;
  187. lws_set_timeout(wsi, PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD,
  188. context->timeout_secs);
  189. /* user code must ask for writable callback */
  190. break;
  191. }
  192. goto client_http_body_sent;
  193. case LWSCM_WSCL_ISSUE_HTTP_BODY:
  194. if (wsi->client_http_body_pending) {
  195. lws_set_timeout(wsi, PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD,
  196. context->timeout_secs);
  197. /* user code must ask for writable callback */
  198. break;
  199. }
  200. client_http_body_sent:
  201. wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
  202. wsi->u.hdr.lextable_pos = 0;
  203. wsi->mode = LWSCM_WSCL_WAITING_SERVER_REPLY;
  204. lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
  205. context->timeout_secs);
  206. break;
  207. case LWSCM_WSCL_WAITING_SERVER_REPLY:
  208. /* handle server hung up on us */
  209. if (pollfd->revents & LWS_POLLHUP) {
  210. lwsl_debug("Server connection %p (fd=%d) dead\n",
  211. (void *)wsi, pollfd->fd);
  212. cce = "Peer hung up";
  213. goto bail3;
  214. }
  215. if (!(pollfd->revents & LWS_POLLIN))
  216. break;
  217. /* interpret the server response */
  218. /*
  219. * HTTP/1.1 101 Switching Protocols
  220. * Upgrade: websocket
  221. * Connection: Upgrade
  222. * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
  223. * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
  224. * Sec-WebSocket-Protocol: chat
  225. */
  226. /*
  227. * we have to take some care here to only take from the
  228. * socket bytewise. The browser may (and has been seen to
  229. * in the case that onopen() performs websocket traffic)
  230. * coalesce both handshake response and websocket traffic
  231. * in one packet, since at that point the connection is
  232. * definitively ready from browser pov.
  233. */
  234. len = 1;
  235. while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE &&
  236. len > 0) {
  237. n = lws_ssl_capable_read(wsi, &c, 1);
  238. lws_latency(context, wsi, "send lws_issue_raw", n,
  239. n == 1);
  240. switch (n) {
  241. case 0:
  242. case LWS_SSL_CAPABLE_ERROR:
  243. cce = "read failed";
  244. goto bail3;
  245. case LWS_SSL_CAPABLE_MORE_SERVICE:
  246. return 0;
  247. }
  248. if (lws_parse(wsi, c)) {
  249. lwsl_warn("problems parsing header\n");
  250. goto bail3;
  251. }
  252. }
  253. /*
  254. * hs may also be coming in multiple packets, there is a 5-sec
  255. * libwebsocket timeout still active here too, so if parsing did
  256. * not complete just wait for next packet coming in this state
  257. */
  258. if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
  259. break;
  260. /*
  261. * otherwise deal with the handshake. If there's any
  262. * packet traffic already arrived we'll trigger poll() again
  263. * right away and deal with it that way
  264. */
  265. return lws_client_interpret_server_handshake(wsi);
  266. bail3:
  267. lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n");
  268. wsi->vhost->protocols[0].callback(wsi,
  269. LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  270. wsi->user_space, (void *)cce, cce ? strlen(cce) : 0);
  271. wsi->already_did_cce = 1;
  272. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  273. return -1;
  274. case LWSCM_WSCL_WAITING_EXTENSION_CONNECT:
  275. lwsl_ext("LWSCM_WSCL_WAITING_EXTENSION_CONNECT\n");
  276. break;
  277. case LWSCM_WSCL_PENDING_CANDIDATE_CHILD:
  278. lwsl_ext("LWSCM_WSCL_PENDING_CANDIDATE_CHILD\n");
  279. break;
  280. default:
  281. break;
  282. }
  283. return 0;
  284. }
  285. /*
  286. * In-place str to lower case
  287. */
  288. static void
  289. strtolower(char *s)
  290. {
  291. while (*s) {
  292. #ifdef LWS_PLAT_OPTEE
  293. int tolower_optee(int c);
  294. *s = tolower_optee((int)*s);
  295. #else
  296. *s = tolower((int)*s);
  297. #endif
  298. s++;
  299. }
  300. }
  301. int LWS_WARN_UNUSED_RESULT
  302. lws_http_transaction_completed_client(struct lws *wsi)
  303. {
  304. lwsl_debug("%s: wsi %p\n", __func__, wsi);
  305. /* if we can't go back to accept new headers, drop the connection */
  306. if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
  307. lwsl_info("%s: %p: close connection\n", __func__, wsi);
  308. return 1;
  309. }
  310. /* otherwise set ourselves up ready to go again */
  311. wsi->state = LWSS_CLIENT_HTTP_ESTABLISHED;
  312. wsi->mode = LWSCM_HTTP_CLIENT_ACCEPTED;
  313. wsi->u.http.content_length = 0;
  314. wsi->hdr_parsing_completed = 0;
  315. /* He asked for it to stay alive indefinitely */
  316. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  317. /*
  318. * As client, nothing new is going to come until we ask for it
  319. * we can drop the ah, if any
  320. */
  321. if (wsi->u.hdr.ah) {
  322. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  323. lws_header_table_detach(wsi, 0);
  324. }
  325. /* If we're (re)starting on headers, need other implied init */
  326. wsi->u.hdr.ues = URIES_IDLE;
  327. lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi);
  328. return 0;
  329. }
  330. LWS_VISIBLE LWS_EXTERN unsigned int
  331. lws_http_client_http_response(struct lws *wsi)
  332. {
  333. if (!wsi->u.http.ah)
  334. return 0;
  335. return wsi->u.http.ah->http_response;
  336. }
  337. int
  338. lws_client_interpret_server_handshake(struct lws *wsi)
  339. {
  340. int n, len, okay = 0, port = 0, ssl = 0;
  341. int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
  342. struct lws_context *context = wsi->context;
  343. const char *pc, *prot, *ads = NULL, *path, *cce = NULL;
  344. struct allocated_headers *ah = NULL;
  345. char *p, *q;
  346. char new_path[300];
  347. #ifndef LWS_NO_EXTENSIONS
  348. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  349. char *sb = (char *)&pt->serv_buf[0];
  350. const struct lws_ext_options *opts;
  351. const struct lws_extension *ext;
  352. char ext_name[128];
  353. const char *c, *a;
  354. char ignore;
  355. int more = 1;
  356. void *v;
  357. #endif
  358. ah = wsi->u.hdr.ah;
  359. if (!wsi->do_ws) {
  360. /* we are being an http client...
  361. */
  362. lws_union_transition(wsi, LWSCM_HTTP_CLIENT_ACCEPTED);
  363. wsi->state = LWSS_CLIENT_HTTP_ESTABLISHED;
  364. wsi->u.http.ah = ah;
  365. ah->http_response = 0;
  366. }
  367. /*
  368. * well, what the server sent looked reasonable for syntax.
  369. * Now let's confirm it sent all the necessary headers
  370. *
  371. * http (non-ws) client will expect something like this
  372. *
  373. * HTTP/1.0.200
  374. * server:.libwebsockets
  375. * content-type:.text/html
  376. * content-length:.17703
  377. * set-cookie:.test=LWS_1456736240_336776_COOKIE;Max-Age=360000
  378. *
  379. *
  380. *
  381. */
  382. wsi->u.http.connection_type = HTTP_CONNECTION_KEEP_ALIVE;
  383. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
  384. if (wsi->do_ws && !p) {
  385. lwsl_info("no URI\n");
  386. cce = "HS: URI missing";
  387. goto bail3;
  388. }
  389. if (!p) {
  390. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP1_0);
  391. wsi->u.http.connection_type = HTTP_CONNECTION_CLOSE;
  392. }
  393. if (!p) {
  394. cce = "HS: URI missing";
  395. lwsl_info("no URI\n");
  396. goto bail3;
  397. }
  398. n = atoi(p);
  399. if (ah)
  400. ah->http_response = n;
  401. if (n == 301 || n == 302 || n == 303 || n == 307 || n == 308) {
  402. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_LOCATION);
  403. if (!p) {
  404. cce = "HS: Redirect code but no Location";
  405. goto bail3;
  406. }
  407. /* Relative reference absolute path */
  408. if (p[0] == '/')
  409. {
  410. #ifdef LWS_OPENSSL_SUPPORT
  411. ssl = wsi->use_ssl;
  412. #endif
  413. ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
  414. port = wsi->c_port;
  415. path = p + 1; /* +1 as lws_client_reset expects leading / to be omitted */
  416. }
  417. /* Absolute (Full) URI */
  418. else if (strchr(p, ':'))
  419. {
  420. if (lws_parse_uri(p, &prot, &ads, &port, &path)) {
  421. cce = "HS: URI did not parse";
  422. goto bail3;
  423. }
  424. if (!strcmp(prot, "wss") || !strcmp(prot, "https"))
  425. ssl = 1;
  426. }
  427. /* Relative reference relative path */
  428. else
  429. {
  430. /* This doesn't try to calculate an absolute path, that will be left to the server */
  431. #ifdef LWS_OPENSSL_SUPPORT
  432. ssl = wsi->use_ssl;
  433. #endif
  434. ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
  435. port = wsi->c_port;
  436. path = new_path + 1; /* +1 as lws_client_reset expects leading / to be omitted */
  437. strncpy(new_path, lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI), sizeof(new_path));
  438. new_path[sizeof(new_path) - 1] = '\0';
  439. q = strrchr(new_path, '/');
  440. if (q)
  441. {
  442. strncpy(q + 1, p, sizeof(new_path) - (q - new_path) - 1);
  443. new_path[sizeof(new_path) - 1] = '\0';
  444. }
  445. else
  446. {
  447. path = p;
  448. }
  449. }
  450. #ifdef LWS_OPENSSL_SUPPORT
  451. if (wsi->use_ssl && !ssl) {
  452. cce = "HS: Redirect attempted SSL downgrade";
  453. goto bail3;
  454. }
  455. #endif
  456. if (!lws_client_reset(&wsi, ssl, ads, port, path, ads)) {
  457. /* there are two ways to fail out with NULL return...
  458. * simple, early problem where the wsi is intact, or
  459. * we went through with the reconnect attempt and the
  460. * wsi is already closed. In the latter case, the wsi
  461. * has beet set to NULL additionally.
  462. */
  463. lwsl_err("Redirect failed\n");
  464. cce = "HS: Redirect failed";
  465. if (wsi)
  466. goto bail3;
  467. return 1;
  468. }
  469. return 0;
  470. }
  471. if (!wsi->do_ws) {
  472. if (n != 200 && n != 304) {
  473. lwsl_notice("Connection failed with code %d\n", n);
  474. cce = "HS: Server did not return 200 or 304";
  475. goto bail2;
  476. }
  477. #ifdef LWS_WITH_HTTP_PROXY
  478. wsi->perform_rewrite = 0;
  479. if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
  480. if (!strncmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE),
  481. "text/html", 9))
  482. wsi->perform_rewrite = 1;
  483. }
  484. #endif
  485. /* allocate the per-connection user memory (if any) */
  486. if (lws_ensure_user_space(wsi)) {
  487. lwsl_err("Problem allocating wsi user mem\n");
  488. cce = "HS: OOM";
  489. goto bail2;
  490. }
  491. /* he may choose to send us stuff in chunked transfer-coding */
  492. wsi->chunked = 0;
  493. wsi->chunk_remaining = 0; /* ie, next thing is chunk size */
  494. if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_TRANSFER_ENCODING)) {
  495. wsi->chunked = !strcmp(lws_hdr_simple_ptr(wsi,
  496. WSI_TOKEN_HTTP_TRANSFER_ENCODING),
  497. "chunked");
  498. /* first thing is hex, after payload there is crlf */
  499. wsi->chunk_parser = ELCP_HEX;
  500. }
  501. if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
  502. wsi->u.http.content_length =
  503. atoi(lws_hdr_simple_ptr(wsi,
  504. WSI_TOKEN_HTTP_CONTENT_LENGTH));
  505. lwsl_notice("%s: incoming content length %d\n", __func__,
  506. wsi->u.http.content_length);
  507. wsi->u.http.content_remain = wsi->u.http.content_length;
  508. } else /* can't do 1.1 without a content length or chunked */
  509. if (!wsi->chunked)
  510. wsi->u.http.connection_type = HTTP_CONNECTION_CLOSE;
  511. /*
  512. * we seem to be good to go, give client last chance to check
  513. * headers and OK it
  514. */
  515. if (wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
  516. wsi->user_space, NULL, 0)) {
  517. cce = "HS: disallowed by client filter";
  518. goto bail2;
  519. }
  520. /* clear his proxy connection timeout */
  521. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  522. wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
  523. /* call him back to inform him he is up */
  524. if (wsi->protocol->callback(wsi,
  525. LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,
  526. wsi->user_space, NULL, 0)) {
  527. cce = "HS: disallowed at ESTABLISHED";
  528. goto bail3;
  529. }
  530. /* free up his parsing allocations */
  531. lws_header_table_detach(wsi, 0);
  532. lwsl_notice("%s: client connection up\n", __func__);
  533. return 0;
  534. }
  535. if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) {
  536. lwsl_info("no ACCEPT\n");
  537. cce = "HS: ACCEPT missing";
  538. goto bail3;
  539. }
  540. if (p && strncmp(p, "101", 3)) {
  541. lwsl_warn(
  542. "lws_client_handshake: got bad HTTP response '%s'\n", p);
  543. cce = "HS: ws upgrade response not 101";
  544. goto bail3;
  545. }
  546. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE);
  547. if (!p) {
  548. lwsl_info("no UPGRADE\n");
  549. cce = "HS: UPGRADE missing";
  550. goto bail3;
  551. }
  552. strtolower(p);
  553. if (strcmp(p, "websocket")) {
  554. lwsl_warn(
  555. "lws_client_handshake: got bad Upgrade header '%s'\n", p);
  556. cce = "HS: Upgrade to something other than websocket";
  557. goto bail3;
  558. }
  559. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION);
  560. if (!p) {
  561. lwsl_info("no Connection hdr\n");
  562. cce = "HS: CONNECTION missing";
  563. goto bail3;
  564. }
  565. strtolower(p);
  566. if (strcmp(p, "upgrade")) {
  567. lwsl_warn("lws_client_int_s_hs: bad header %s\n", p);
  568. cce = "HS: UPGRADE malformed";
  569. goto bail3;
  570. }
  571. pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
  572. if (!pc) {
  573. lwsl_parser("lws_client_int_s_hs: no protocol list\n");
  574. } else
  575. lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc);
  576. /*
  577. * confirm the protocol the server wants to talk was in the list
  578. * of protocols we offered
  579. */
  580. len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL);
  581. if (!len) {
  582. lwsl_info("lws_client_int_s_hs: WSI_TOKEN_PROTOCOL is null\n");
  583. /*
  584. * no protocol name to work from,
  585. * default to first protocol
  586. */
  587. n = 0;
  588. wsi->protocol = &wsi->vhost->protocols[0];
  589. goto check_extensions;
  590. }
  591. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL);
  592. len = strlen(p);
  593. while (pc && *pc && !okay) {
  594. if (!strncmp(pc, p, len) &&
  595. (pc[len] == ',' || pc[len] == '\0')) {
  596. okay = 1;
  597. continue;
  598. }
  599. while (*pc && *pc++ != ',')
  600. ;
  601. while (*pc && *pc == ' ')
  602. pc++;
  603. }
  604. if (!okay) {
  605. lwsl_err("lws_client_int_s_hs: got bad protocol %s\n", p);
  606. cce = "HS: PROTOCOL malformed";
  607. goto bail2;
  608. }
  609. /*
  610. * identify the selected protocol struct and set it
  611. */
  612. n = 0;
  613. wsi->protocol = NULL;
  614. while (wsi->vhost->protocols[n].callback && !wsi->protocol) {
  615. if (strcmp(p, wsi->vhost->protocols[n].name) == 0) {
  616. wsi->protocol = &wsi->vhost->protocols[n];
  617. break;
  618. }
  619. n++;
  620. }
  621. if (wsi->protocol == NULL) {
  622. lwsl_err("lws_client_int_s_hs: fail protocol %s\n", p);
  623. cce = "HS: Cannot match protocol";
  624. goto bail2;
  625. }
  626. check_extensions:
  627. /*
  628. * stitch protocol choice into the vh protocol linked list
  629. * We always insert ourselves at the start of the list
  630. *
  631. * X <-> B
  632. * X <-> pAn <-> pB
  633. */
  634. //lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
  635. // __func__,
  636. // wsi->vhost->same_vh_protocol_list[n],
  637. // wsi->same_vh_protocol_prev);
  638. wsi->same_vh_protocol_prev = /* guy who points to us */
  639. &wsi->vhost->same_vh_protocol_list[n];
  640. wsi->same_vh_protocol_next = /* old first guy is our next */
  641. wsi->vhost->same_vh_protocol_list[n];
  642. /* we become the new first guy */
  643. wsi->vhost->same_vh_protocol_list[n] = wsi;
  644. if (wsi->same_vh_protocol_next)
  645. /* old first guy points back to us now */
  646. wsi->same_vh_protocol_next->same_vh_protocol_prev =
  647. &wsi->same_vh_protocol_next;
  648. #ifndef LWS_NO_EXTENSIONS
  649. /* instantiate the accepted extensions */
  650. if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) {
  651. lwsl_ext("no client extensions allowed by server\n");
  652. goto check_accept;
  653. }
  654. /*
  655. * break down the list of server accepted extensions
  656. * and go through matching them or identifying bogons
  657. */
  658. if (lws_hdr_copy(wsi, sb, context->pt_serv_buf_size, WSI_TOKEN_EXTENSIONS) < 0) {
  659. lwsl_warn("ext list from server failed to copy\n");
  660. cce = "HS: EXT: list too big";
  661. goto bail2;
  662. }
  663. c = sb;
  664. n = 0;
  665. ignore = 0;
  666. a = NULL;
  667. while (more) {
  668. if (*c && (*c != ',' && *c != '\t')) {
  669. if (*c == ';') {
  670. ignore = 1;
  671. if (!a)
  672. a = c + 1;
  673. }
  674. if (ignore || *c == ' ') {
  675. c++;
  676. continue;
  677. }
  678. ext_name[n] = *c++;
  679. if (n < sizeof(ext_name) - 1)
  680. n++;
  681. continue;
  682. }
  683. ext_name[n] = '\0';
  684. ignore = 0;
  685. if (!*c)
  686. more = 0;
  687. else {
  688. c++;
  689. if (!n)
  690. continue;
  691. }
  692. /* check we actually support it */
  693. lwsl_notice("checking client ext %s\n", ext_name);
  694. n = 0;
  695. ext = wsi->vhost->extensions;
  696. while (ext && ext->callback) {
  697. if (strcmp(ext_name, ext->name)) {
  698. ext++;
  699. continue;
  700. }
  701. n = 1;
  702. lwsl_notice("instantiating client ext %s\n", ext_name);
  703. /* instantiate the extension on this conn */
  704. wsi->active_extensions[wsi->count_act_ext] = ext;
  705. /* allow him to construct his ext instance */
  706. if (ext->callback(lws_get_context(wsi), ext, wsi,
  707. LWS_EXT_CB_CLIENT_CONSTRUCT,
  708. (void *)&wsi->act_ext_user[wsi->count_act_ext],
  709. (void *)&opts, 0)) {
  710. lwsl_notice(" ext %s failed construction\n", ext_name);
  711. ext++;
  712. continue;
  713. }
  714. /*
  715. * allow the user code to override ext defaults if it
  716. * wants to
  717. */
  718. ext_name[0] = '\0';
  719. if (user_callback_handle_rxflow(wsi->protocol->callback,
  720. wsi, LWS_CALLBACK_WS_EXT_DEFAULTS,
  721. (char *)ext->name, ext_name,
  722. sizeof(ext_name))) {
  723. cce = "HS: EXT: failed setting defaults";
  724. goto bail2;
  725. }
  726. if (ext_name[0] &&
  727. lws_ext_parse_options(ext, wsi, wsi->act_ext_user[
  728. wsi->count_act_ext], opts, ext_name,
  729. strlen(ext_name))) {
  730. lwsl_err("%s: unable to parse user defaults '%s'",
  731. __func__, ext_name);
  732. cce = "HS: EXT: failed parsing defaults";
  733. goto bail2;
  734. }
  735. /*
  736. * give the extension the server options
  737. */
  738. if (a && lws_ext_parse_options(ext, wsi,
  739. wsi->act_ext_user[wsi->count_act_ext],
  740. opts, a, c - a)) {
  741. lwsl_err("%s: unable to parse remote def '%s'",
  742. __func__, a);
  743. cce = "HS: EXT: failed parsing options";
  744. goto bail2;
  745. }
  746. if (ext->callback(lws_get_context(wsi), ext, wsi,
  747. LWS_EXT_CB_OPTION_CONFIRM,
  748. wsi->act_ext_user[wsi->count_act_ext],
  749. NULL, 0)) {
  750. lwsl_err("%s: ext %s rejects server options %s",
  751. __func__, ext->name, a);
  752. cce = "HS: EXT: Rejects server options";
  753. goto bail2;
  754. }
  755. wsi->count_act_ext++;
  756. ext++;
  757. }
  758. if (n == 0) {
  759. lwsl_warn("Unknown ext '%s'!\n", ext_name);
  760. cce = "HS: EXT: unknown ext";
  761. goto bail2;
  762. }
  763. a = NULL;
  764. n = 0;
  765. }
  766. check_accept:
  767. #endif
  768. /*
  769. * Confirm his accept token is the one we precomputed
  770. */
  771. p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT);
  772. if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) {
  773. lwsl_warn("lws_client_int_s_hs: accept '%s' wrong vs '%s'\n", p,
  774. wsi->u.hdr.ah->initial_handshake_hash_base64);
  775. cce = "HS: Accept hash wrong";
  776. goto bail2;
  777. }
  778. /* allocate the per-connection user memory (if any) */
  779. if (lws_ensure_user_space(wsi)) {
  780. lwsl_err("Problem allocating wsi user mem\n");
  781. cce = "HS: OOM";
  782. goto bail2;
  783. }
  784. /*
  785. * we seem to be good to go, give client last chance to check
  786. * headers and OK it
  787. */
  788. if (wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
  789. wsi->user_space, NULL, 0)) {
  790. cce = "HS: Rejected by filter cb";
  791. goto bail2;
  792. }
  793. /* clear his proxy connection timeout */
  794. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  795. /* free up his parsing allocations */
  796. lws_header_table_detach(wsi, 0);
  797. lws_union_transition(wsi, LWSCM_WS_CLIENT);
  798. wsi->state = LWSS_ESTABLISHED;
  799. lws_restart_ws_ping_pong_timer(wsi);
  800. wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
  801. /*
  802. * create the frame buffer for this connection according to the
  803. * size mentioned in the protocol definition. If 0 there, then
  804. * use a big default for compatibility
  805. */
  806. n = wsi->protocol->rx_buffer_size;
  807. if (!n)
  808. n = context->pt_serv_buf_size;
  809. n += LWS_PRE;
  810. wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */);
  811. if (!wsi->u.ws.rx_ubuf) {
  812. lwsl_err("Out of Mem allocating rx buffer %d\n", n);
  813. cce = "HS: OOM";
  814. goto bail2;
  815. }
  816. wsi->u.ws.rx_ubuf_alloc = n;
  817. lwsl_info("Allocating client RX buffer %d\n", n);
  818. if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&n,
  819. sizeof n)) {
  820. lwsl_warn("Failed to set SNDBUF to %d", n);
  821. cce = "HS: SO_SNDBUF failed";
  822. goto bail3;
  823. }
  824. lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name);
  825. /* call him back to inform him he is up */
  826. if (wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_ESTABLISHED,
  827. wsi->user_space, NULL, 0)) {
  828. cce = "HS: Rejected at CLIENT_ESTABLISHED";
  829. goto bail3;
  830. }
  831. #ifndef LWS_NO_EXTENSIONS
  832. /*
  833. * inform all extensions, not just active ones since they
  834. * already know
  835. */
  836. ext = wsi->vhost->extensions;
  837. while (ext && ext->callback) {
  838. v = NULL;
  839. for (n = 0; n < wsi->count_act_ext; n++)
  840. if (wsi->active_extensions[n] == ext)
  841. v = wsi->act_ext_user[n];
  842. ext->callback(context, ext, wsi,
  843. LWS_EXT_CB_ANY_WSI_ESTABLISHED, v, NULL, 0);
  844. ext++;
  845. }
  846. #endif
  847. return 0;
  848. bail3:
  849. close_reason = LWS_CLOSE_STATUS_NOSTATUS;
  850. bail2:
  851. if (wsi->protocol)
  852. wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  853. wsi->user_space, (void *)cce,
  854. (unsigned int)strlen(cce));
  855. wsi->already_did_cce = 1;
  856. lwsl_info("closing connection due to bail2 connection error\n");
  857. /* closing will free up his parsing allocations */
  858. lws_close_free_wsi(wsi, close_reason);
  859. return 1;
  860. }
  861. char *
  862. lws_generate_client_handshake(struct lws *wsi, char *pkt)
  863. {
  864. char buf[128], hash[20], key_b64[40], *p = pkt;
  865. struct lws_context *context = wsi->context;
  866. const char *meth;
  867. int n;
  868. #ifndef LWS_NO_EXTENSIONS
  869. const struct lws_extension *ext;
  870. int ext_count = 0;
  871. #endif
  872. meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
  873. if (!meth) {
  874. meth = "GET";
  875. wsi->do_ws = 1;
  876. } else
  877. wsi->do_ws = 0;
  878. if (!strcmp(meth, "RAW")) {
  879. const char *pp = lws_hdr_simple_ptr(wsi,
  880. _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
  881. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  882. lwsl_notice("client transition to raw\n");
  883. if (pp) {
  884. const struct lws_protocols *pr;
  885. pr = lws_vhost_name_to_protocol(wsi->vhost, pp);
  886. if (!pr) {
  887. lwsl_err("protocol %s not enabled on vhost\n",
  888. pp);
  889. return NULL;
  890. }
  891. lws_bind_protocol(wsi, pr);
  892. }
  893. if ((wsi->protocol->callback)(wsi,
  894. LWS_CALLBACK_RAW_ADOPT,
  895. wsi->user_space, NULL, 0))
  896. return NULL;
  897. wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
  898. lws_union_transition(wsi, LWSCM_RAW);
  899. lws_header_table_detach(wsi, 1);
  900. return NULL;
  901. }
  902. if (wsi->do_ws) {
  903. /*
  904. * create the random key
  905. */
  906. n = lws_get_random(context, hash, 16);
  907. if (n != 16) {
  908. lwsl_err("Unable to read from random dev %s\n",
  909. SYSTEM_RANDOM_FILEPATH);
  910. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  911. return NULL;
  912. }
  913. lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64));
  914. }
  915. /*
  916. * 04 example client handshake
  917. *
  918. * GET /chat HTTP/1.1
  919. * Host: server.example.com
  920. * Upgrade: websocket
  921. * Connection: Upgrade
  922. * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  923. * Sec-WebSocket-Origin: http://example.com
  924. * Sec-WebSocket-Protocol: chat, superchat
  925. * Sec-WebSocket-Version: 4
  926. */
  927. p += sprintf(p, "%s %s HTTP/1.1\x0d\x0a", meth,
  928. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI));
  929. p += sprintf(p, "Pragma: no-cache\x0d\x0a"
  930. "Cache-Control: no-cache\x0d\x0a");
  931. p += sprintf(p, "Host: %s\x0d\x0a",
  932. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST));
  933. if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)) {
  934. if (lws_check_opt(context->options, LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN))
  935. p += sprintf(p, "Origin: %s\x0d\x0a",
  936. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
  937. else
  938. p += sprintf(p, "Origin: http://%s\x0d\x0a",
  939. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
  940. }
  941. if (wsi->do_ws) {
  942. p += sprintf(p, "Upgrade: websocket\x0d\x0a"
  943. "Connection: Upgrade\x0d\x0a"
  944. "Sec-WebSocket-Key: ");
  945. strcpy(p, key_b64);
  946. p += strlen(key_b64);
  947. p += sprintf(p, "\x0d\x0a");
  948. if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS))
  949. p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
  950. lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS));
  951. /* tell the server what extensions we could support */
  952. #ifndef LWS_NO_EXTENSIONS
  953. ext = wsi->vhost->extensions;
  954. while (ext && ext->callback) {
  955. n = lws_ext_cb_all_exts(context, wsi,
  956. LWS_EXT_CB_CHECK_OK_TO_PROPOSE_EXTENSION,
  957. (char *)ext->name, 0);
  958. if (n) { /* an extension vetos us */
  959. lwsl_ext("ext %s vetoed\n", (char *)ext->name);
  960. ext++;
  961. continue;
  962. }
  963. n = wsi->vhost->protocols[0].callback(wsi,
  964. LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
  965. wsi->user_space, (char *)ext->name, 0);
  966. /*
  967. * zero return from callback means
  968. * go ahead and allow the extension,
  969. * it's what we get if the callback is
  970. * unhandled
  971. */
  972. if (n) {
  973. ext++;
  974. continue;
  975. }
  976. /* apply it */
  977. if (ext_count)
  978. *p++ = ',';
  979. else
  980. p += sprintf(p, "Sec-WebSocket-Extensions: ");
  981. p += sprintf(p, "%s", ext->client_offer);
  982. ext_count++;
  983. ext++;
  984. }
  985. if (ext_count)
  986. p += sprintf(p, "\x0d\x0a");
  987. #endif
  988. if (wsi->ietf_spec_revision)
  989. p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a",
  990. wsi->ietf_spec_revision);
  991. /* prepare the expected server accept response */
  992. key_b64[39] = '\0'; /* enforce composed length below buf sizeof */
  993. n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key_b64);
  994. lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash);
  995. lws_b64_encode_string(hash, 20,
  996. wsi->u.hdr.ah->initial_handshake_hash_base64,
  997. sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64));
  998. }
  999. /* give userland a chance to append, eg, cookies */
  1000. wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
  1001. wsi->user_space, &p, (pkt + context->pt_serv_buf_size) - p - 12);
  1002. p += sprintf(p, "\x0d\x0a");
  1003. return p;
  1004. }