handshake.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010-2015 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. /*
  23. * -04 of the protocol (actually the 80th version) has a radically different
  24. * handshake. The 04 spec gives the following idea
  25. *
  26. * The handshake from the client looks as follows:
  27. *
  28. * GET /chat HTTP/1.1
  29. * Host: server.example.com
  30. * Upgrade: websocket
  31. * Connection: Upgrade
  32. * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  33. * Sec-WebSocket-Origin: http://example.com
  34. * Sec-WebSocket-Protocol: chat, superchat
  35. * Sec-WebSocket-Version: 4
  36. *
  37. * The handshake from the server looks as follows:
  38. *
  39. * HTTP/1.1 101 Switching Protocols
  40. * Upgrade: websocket
  41. * Connection: Upgrade
  42. * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
  43. * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
  44. * Sec-WebSocket-Protocol: chat
  45. */
  46. #ifndef min
  47. #define min(a, b) ((a) < (b) ? (a) : (b))
  48. #endif
  49. /*
  50. * We have to take care about parsing because the headers may be split
  51. * into multiple fragments. They may contain unknown headers with arbitrary
  52. * argument lengths. So, we parse using a single-character at a time state
  53. * machine that is completely independent of packet size.
  54. *
  55. * Returns <0 for error or length of chars consumed from buf (up to len)
  56. */
  57. LWS_VISIBLE int
  58. lws_read(struct lws *wsi, unsigned char *buf, size_t len)
  59. {
  60. unsigned char *last_char, *oldbuf = buf;
  61. int body_chunk_len;
  62. size_t n;
  63. lwsl_debug("%s: incoming len %d state %d\n", __func__, (int)len, wsi->state);
  64. switch (wsi->state) {
  65. #ifdef LWS_USE_HTTP2
  66. case LWSS_HTTP2_AWAIT_CLIENT_PREFACE:
  67. case LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS:
  68. case LWSS_HTTP2_ESTABLISHED:
  69. n = 0;
  70. while (n < len) {
  71. /*
  72. * we were accepting input but now we stopped doing so
  73. */
  74. if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) {
  75. lws_rxflow_cache(wsi, buf, n, len);
  76. return 1;
  77. }
  78. /* account for what we're using in rxflow buffer */
  79. if (wsi->rxflow_buffer)
  80. wsi->rxflow_pos++;
  81. if (lws_http2_parser(wsi, buf[n++])) {
  82. lwsl_debug("%s: http2_parser bailed\n", __func__);
  83. goto bail;
  84. }
  85. }
  86. break;
  87. #endif
  88. case LWSS_CLIENT_HTTP_ESTABLISHED:
  89. break;
  90. case LWSS_HTTP:
  91. wsi->hdr_parsing_completed = 0;
  92. /* fallthru */
  93. case LWSS_HTTP_ISSUING_FILE:
  94. wsi->state = LWSS_HTTP_HEADERS;
  95. wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
  96. wsi->u.hdr.lextable_pos = 0;
  97. /* fallthru */
  98. case LWSS_HTTP_HEADERS:
  99. if (!wsi->u.hdr.ah) {
  100. lwsl_err("%s: LWSS_HTTP_HEADERS: NULL ah\n", __func__);
  101. assert(0);
  102. }
  103. lwsl_parser("issuing %d bytes to parser\n", (int)len);
  104. if (lws_handshake_client(wsi, &buf, len))
  105. goto bail;
  106. last_char = buf;
  107. if (lws_handshake_server(wsi, &buf, len))
  108. /* Handshake indicates this session is done. */
  109. goto bail;
  110. /* we might have transitioned to RAW */
  111. if (wsi->mode == LWSCM_RAW)
  112. /* we gave the read buffer to RAW handler already */
  113. goto read_ok;
  114. /*
  115. * It's possible that we've exhausted our data already, or
  116. * rx flow control has stopped us dealing with this early,
  117. * but lws_handshake_server doesn't update len for us.
  118. * Figure out how much was read, so that we can proceed
  119. * appropriately:
  120. */
  121. len -= (buf - last_char);
  122. lwsl_debug("%s: thinks we have used %ld\n", __func__, (long)len);
  123. if (!wsi->hdr_parsing_completed)
  124. /* More header content on the way */
  125. goto read_ok;
  126. switch (wsi->state) {
  127. case LWSS_HTTP:
  128. case LWSS_HTTP_HEADERS:
  129. goto read_ok;
  130. case LWSS_HTTP_ISSUING_FILE:
  131. goto read_ok;
  132. case LWSS_HTTP_BODY:
  133. wsi->u.http.content_remain =
  134. wsi->u.http.content_length;
  135. if (wsi->u.http.content_remain)
  136. goto http_postbody;
  137. /* there is no POST content */
  138. goto postbody_completion;
  139. default:
  140. break;
  141. }
  142. break;
  143. case LWSS_HTTP_BODY:
  144. http_postbody:
  145. while (len && wsi->u.http.content_remain) {
  146. /* Copy as much as possible, up to the limit of:
  147. * what we have in the read buffer (len)
  148. * remaining portion of the POST body (content_remain)
  149. */
  150. body_chunk_len = min(wsi->u.http.content_remain,len);
  151. wsi->u.http.content_remain -= body_chunk_len;
  152. len -= body_chunk_len;
  153. #ifdef LWS_WITH_CGI
  154. if (wsi->cgi) {
  155. struct lws_cgi_args args;
  156. args.ch = LWS_STDIN;
  157. args.stdwsi = &wsi->cgi->stdwsi[0];
  158. args.data = buf;
  159. args.len = body_chunk_len;
  160. /* returns how much used */
  161. n = user_callback_handle_rxflow(
  162. wsi->protocol->callback,
  163. wsi, LWS_CALLBACK_CGI_STDIN_DATA,
  164. wsi->user_space,
  165. (void *)&args, 0);
  166. if ((int)n < 0)
  167. goto bail;
  168. } else {
  169. #endif
  170. n = wsi->protocol->callback(wsi,
  171. LWS_CALLBACK_HTTP_BODY, wsi->user_space,
  172. buf, body_chunk_len);
  173. if (n)
  174. goto bail;
  175. n = body_chunk_len;
  176. #ifdef LWS_WITH_CGI
  177. }
  178. #endif
  179. buf += n;
  180. if (wsi->u.http.content_remain) {
  181. lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
  182. wsi->context->timeout_secs);
  183. break;
  184. }
  185. /* he sent all the content in time */
  186. postbody_completion:
  187. #ifdef LWS_WITH_CGI
  188. /* if we're running a cgi, we can't let him off the hook just because he sent his POST data */
  189. if (wsi->cgi)
  190. lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, wsi->context->timeout_secs);
  191. else
  192. #endif
  193. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  194. #ifdef LWS_WITH_CGI
  195. if (!wsi->cgi)
  196. #endif
  197. {
  198. n = wsi->protocol->callback(wsi,
  199. LWS_CALLBACK_HTTP_BODY_COMPLETION,
  200. wsi->user_space, NULL, 0);
  201. if (n)
  202. goto bail;
  203. }
  204. break;
  205. }
  206. break;
  207. case LWSS_ESTABLISHED:
  208. case LWSS_AWAITING_CLOSE_ACK:
  209. case LWSS_SHUTDOWN:
  210. if (lws_handshake_client(wsi, &buf, len))
  211. goto bail;
  212. switch (wsi->mode) {
  213. case LWSCM_WS_SERVING:
  214. if (lws_interpret_incoming_packet(wsi, &buf, len) < 0) {
  215. lwsl_info("interpret_incoming_packet has bailed\n");
  216. goto bail;
  217. }
  218. break;
  219. }
  220. break;
  221. default:
  222. lwsl_err("%s: Unhandled state %d\n", __func__, wsi->state);
  223. break;
  224. }
  225. read_ok:
  226. /* Nothing more to do for now */
  227. lwsl_info("%s: read_ok, used %ld\n", __func__, (long)(buf - oldbuf));
  228. return buf - oldbuf;
  229. bail:
  230. //lwsl_notice("closing connection at lws_read bail:\n");
  231. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
  232. return -1;
  233. }