Lines Matching refs:wsi
66 struct lws *wsi = lws_container_of(d, struct lws, listen_list);
69 if (!lws_vhost_compare_listen(wsi->a.vhost, a->vhost))
72 if (wsi->af != a ->af)
75 lwsl_notice(" using listen skt from vhost %s\n", wsi->a.vhost->name);
91 struct lws *wsi;
299 * Create the listen wsi and customize it
303 wsi = __lws_wsi_create_with_role(cx, m, &role_ops_listen, NULL);
305 if (wsi == NULL) {
310 wsi->af = (uint8_t)a->af;
316 wsi->unix_skt = 1;
322 wsi->desc.sockfd = sockfd;
323 wsi->a.protocol = a->vhost->protocols;
324 lws_vhost_bind_wsi(a->vhost, wsi);
325 wsi->listener = 1;
327 if (wsi->a.context->event_loop_ops->init_vhost_listen_wsi)
328 wsi->a.context->event_loop_ops->init_vhost_listen_wsi(wsi);
333 if (__insert_wsi_socket_into_fds(cx, wsi)) {
334 lwsl_notice("inserting wsi socket into fds failed\n");
339 lws_dll2_add_tail(&wsi->listen_list, &a->vhost->listen_wsi);
345 if (setsockopt(wsi->desc.sockfd, IPPROTO_TCP,
358 if (setsockopt(wsi->desc.sockfd, SOL_TCP, TCP_FASTOPEN,
365 n = listen(wsi->desc.sockfd, LWS_SOMAXCONN);
368 lws_dll2_remove(&wsi->listen_list);
369 __remove_wsi_socket_from_fds(wsi);
373 if (wsi)
376 &wsi->lc, "listen|%s|%s|%d",
638 lws_vfs_prepare_flags(struct lws *wsi)
642 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING))
645 if (strstr(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING),
655 lws_http_serve(struct lws *wsi, char *uri, const char *origin,
680 wsi->handling_404 = 0;
681 if (!wsi->a.vhost)
685 if (wsi->a.vhost->http.error_document_404 &&
686 !strcmp(uri, wsi->a.vhost->http.error_document_404))
687 wsi->handling_404 = 1;
694 fflags |= lws_vfs_prepare_flags(wsi);
698 fops = lws_vfs_select_fops(wsi->a.context->fops, path, &vpath);
700 if (wsi->http.fop_fd)
701 lws_vfs_file_close(&wsi->http.fop_fd);
703 wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->a.context->fops,
705 if (!wsi->http.fop_fd) {
719 if (fstat(wsi->http.fop_fd->fd, &st)) {
741 wsi->http.fop_fd->mod_time = (uint32_t)st.st_mtime;
768 (unsigned long long)lws_vfs_get_length(wsi->http.fop_fd),
769 (unsigned long)lws_vfs_get_mod_time(wsi->http.fop_fd));
773 if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_RANGE))
774 if (strcmp(sym, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_IF_RANGE)))
776 wsi->http.ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0;
778 if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) {
783 if (!strcmp(sym, lws_hdr_simple_ptr(wsi,
793 if (lws_add_http_header_status(wsi,
800 if (lws_add_http_header_by_token(wsi,
812 intermediates[wsi->cache_intermediaries],
818 intermediates[wsi->cache_intermediaries],
823 if (lws_add_http_header_by_token(wsi,
828 if (lws_finalize_http_header(wsi, &p, end))
831 n = lws_write(wsi, start, lws_ptr_diff_size_t(p, start),
840 lws_vfs_file_close(&wsi->http.fop_fd);
842 if (lws_http_transaction_completed(wsi))
849 if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG,
857 if (lws_return_http_status(wsi,
859 lws_http_transaction_completed(wsi))
867 wsi->sending_chunked = 0;
868 wsi->interpreting = 0;
878 wsi->interpreting = 1;
879 if (!wsi->mux_substream)
880 wsi->sending_chunked = 1;
882 wsi->protocol_interpret_idx = (char)(
883 lws_vhost_name_to_protocol(wsi->a.vhost,
885 &lws_get_vhost(wsi)->protocols[0]);
888 wsi->a.vhost->protocols[
889 (int)wsi->protocol_interpret_idx].name,
890 wsi->a.protocol->name);
891 if (lws_bind_protocol(wsi, &wsi->a.vhost->protocols[
892 (int)wsi->protocol_interpret_idx], __func__))
895 if (lws_ensure_user_space(wsi))
902 if (wsi->sending_chunked) {
903 if (lws_add_http_header_by_token(wsi,
912 wsi->a.vhost, m->protocol);
914 if (lws_bind_protocol(wsi, pp, __func__))
918 if (pp->callback(wsi, LWS_CALLBACK_ADD_HEADERS,
919 wsi->user_space, &args, 0))
925 n = lws_serve_http_file(wsi, path, mimetype, (char *)start,
928 if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi)))
941 lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len)
946 hm = wsi->a.vhost->http.mount_list;
955 lws_metrics_tag_wsi_add(wsi, "mnt", hm->mountpoint);
960 lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) ||
961 lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) ||
963 lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI) ||
964 lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) ||
965 lws_hdr_total_length(wsi, WSI_TOKEN_DELETE_URI) ||
967 lws_hdr_total_length(wsi, WSI_TOKEN_HEAD_URI) ||
969 (wsi->mux_substream &&
970 lws_hdr_total_length(wsi,
1035 lws_unauthorised_basic_auth(struct lws *wsi)
1037 struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
1045 if (lws_add_http_header_status(wsi, HTTP_STATUS_UNAUTHORIZED, &p, end))
1049 if (lws_add_http_header_by_token(wsi,
1054 if (lws_add_http_header_content_length(wsi, 0, &p, end))
1057 if (lws_finalize_http_header(wsi, &p, end))
1060 n = lws_write(wsi, start, lws_ptr_diff_size_t(p, start), LWS_WRITE_HTTP_HEADERS |
1065 return lws_http_transaction_completed(wsi);
1116 lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len)
1121 if (lws_hdr_total_length(wsi, methods[n]))
1129 !((wsi->mux_substream || wsi->h2_stream_carries_ws)
1132 lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH)
1140 if (lws_hdr_total_length(wsi, methods[n])) {
1141 *puri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
1142 *puri_len = lws_hdr_total_length(wsi, methods[n]);
1152 lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file,
1163 ml = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_AUTHORIZATION);
1169 fi = wsi->http.ah->frag_index[WSI_TOKEN_HTTP_AUTHORIZATION];
1170 if (wsi->http.ah->frags[fi].nfrag) {
1175 m = lws_hdr_copy(wsi, b64, sizeof(b64),
1211 bar = wsi->a.protocol->callback(wsi,
1213 wsi->user_space, plain, (unsigned int)m);
1228 wsi->http.ah->frags[fi].len = (uint16_t)lws_ptr_diff_size_t(pcolon, &plain[0]);
1229 pcolon = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_AUTHORIZATION);
1233 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_AUTHORIZATION));
1252 lws_http_proxy_start(struct lws *wsi, const struct lws_http_mount *hit,
1259 unsigned int max_http_header_data = wsi->a.context->max_http_header_data > 256 ?
1260 wsi->a.context->max_http_header_data : 256;
1279 lws_bind_protocol(wsi, &lws_ws_proxy, __func__);
1282 i.context = lws_get_context(wsi);
1341 na = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_URI_ARGS);
1360 budg = lws_hdr_copy(wsi, p,
1378 n = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_AUTHORITY);
1380 i.host = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_AUTHORITY);
1384 n = lws_hdr_total_length(wsi, WSI_TOKEN_HOST);
1386 i.host = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST);
1391 !lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST))
1394 i.host = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST);
1398 if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI)
1401 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD) &&
1402 !strcmp(lws_hdr_simple_ptr(wsi,
1408 else if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PUT_URI)
1411 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD) &&
1412 !strcmp(lws_hdr_simple_ptr(wsi,
1418 else if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PATCH_URI)
1421 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD) &&
1422 !strcmp(lws_hdr_simple_ptr(wsi,
1428 else if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_DELETE_URI)
1431 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD) &&
1432 !strcmp(lws_hdr_simple_ptr(wsi,
1444 wsi->a.vhost->listen_port);
1451 i.parent_wsi = wsi;
1454 i.protocol = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL);
1474 lws_return_http_status(wsi,
1490 wsi->proxied_ws_parent = 1;
1509 lws_http_redirect_hit(struct lws_context_per_thread *pt, struct lws *wsi,
1543 *end = p + wsi->a.context->pt_serv_buf_size -
1557 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
1559 if (!lws_hdr_total_length(wsi,
1565 "%s%s%s/", oprot[!!lws_is_ssl(wsi)],
1566 lws_hdr_simple_ptr(wsi,
1574 "%s%s%s/", oprot[!!lws_is_ssl(wsi)],
1575 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST),
1580 n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
1585 return lws_http_transaction_completed(wsi);
1591 lws_header_table_detach(wsi, 1);
1597 lws_http_action(struct lws *wsi)
1599 struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
1614 meth = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
1618 lws_metrics_tag_wsi_add(wsi, "vh", wsi->a.vhost->name);
1619 lws_metrics_tag_wsi_add(wsi, "meth", method_names[meth]);
1624 lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
1632 if (wsi->role_ops &&
1633 lws_rops_fidx(wsi->role_ops, LWS_ROPS_check_upgrades))
1634 switch (lws_rops_func_fidx(wsi->role_ops,
1636 check_upgrades(wsi)) {
1645 if (lws_ensure_user_space(wsi))
1650 wsi->http.rx_content_length = 0;
1651 wsi->http.content_length_explicitly_zero = 0;
1652 if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)
1655 lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) ||
1656 lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI)
1659 wsi->http.rx_content_length = 100 * 1024 * 1024;
1661 if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH) &&
1662 lws_hdr_copy(wsi, content_length_str,
1665 wsi->http.rx_content_remain = wsi->http.rx_content_length =
1667 if (!wsi->http.rx_content_length) {
1668 wsi->http.content_length_explicitly_zero = 1;
1673 if (wsi->mux_substream) {
1674 wsi->http.request_version = HTTP_VERSION_2;
1680 http_version_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP);
1682 lws_hdr_copy(wsi, http_version_str,
1688 wsi->http.request_version = request_version;
1697 if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION) &&
1698 lws_hdr_copy(wsi, http_conn_str, sizeof(http_conn_str) - 1,
1707 wsi->http.conn_type = conn_type;
1710 n = (unsigned int)wsi->a.protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION,
1711 wsi->user_space, uri_ptr, (unsigned int)uri_len);
1721 if (!wsi->mux_stream_immortal)
1722 lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
1723 (int)wsi->a.context->timeout_secs);
1725 if (wsi->tls.redirect_to_https) {
1733 *end = p + wsi->a.context->pt_serv_buf_size -
1736 n = (unsigned int)lws_hdr_total_length(wsi, WSI_TOKEN_HOST);
1740 if (!lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST))
1744 memcpy(p, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST), n);
1756 while (lws_hdr_copy_fragment(wsi, (char *)p + 1,
1769 n = (unsigned int)lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
1774 return lws_http_transaction_completed(wsi);
1779 lws_prepare_access_log_info(wsi, uri_ptr, uri_len, meth);
1784 hit = lws_find_mount(wsi, uri_ptr, uri_len);
1790 if (lws_bind_protocol(wsi, &wsi->a.vhost->protocols[0],
1794 lwsi_set_state(wsi, LRS_DOING_TRANSACTION);
1796 m = wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP,
1797 wsi->user_space, uri_ptr, (unsigned int)uri_len);
1805 n = (unsigned int)lws_http_redirect_hit(pt, wsi, hit, uri_ptr, uri_len, &ha);
1813 switch (lws_check_basic_auth(wsi, hit->basic_auth_login_file,
1818 return lws_unauthorised_basic_auth(wsi);
1820 lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
1821 return lws_http_transaction_completed(wsi);
1837 n = (unsigned int)lws_http_proxy_start(wsi, hit, uri_ptr, 0);
1858 pp = lws_vhost_name_to_protocol(wsi->a.vhost, name);
1865 if (lws_bind_protocol(wsi, pp, "http action CALLBACK bind"))
1877 n = (unsigned int)wsi->a.protocol->callback(wsi,
1879 wsi->user_space, &args, 0);
1881 lws_return_http_status(wsi, HTTP_STATUS_UNAUTHORIZED,
1888 if (hit->cgienv && wsi->a.protocol->callback(wsi,
1890 wsi->user_space, (void *)hit->cgienv, 0))
1893 if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
1894 m = wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP,
1895 wsi->user_space,
1917 n = (unsigned int)lws_cgi(wsi, cmd, hit->mountpoint_len, (int)n,
1936 wsi->cache_secs = (unsigned int)hit->cache_max_age;
1937 wsi->cache_reuse = hit->cache_reusable;
1938 wsi->cache_revalidate = hit->cache_revalidate;
1939 wsi->cache_intermediaries = hit->cache_intermediaries;
1944 m = lws_http_serve(wsi, s, hit->origin, hit);
1950 * lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
1955 wsi->a.vhost, hit->protocol);
1961 lwsi_set_state(wsi, LRS_DOING_TRANSACTION);
1963 if (lws_bind_protocol(wsi, pp, "http_action HTTP"))
1966 m = pp->callback(wsi, LWS_CALLBACK_HTTP,
1967 wsi->user_space,
1971 m = wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP,
1972 wsi->user_space, uri_ptr, (size_t)uri_len);
1993 if (lwsi_state(wsi) == LRS_ISSUING_FILE)
1997 lwsl_debug("wsi->http.rx_content_length %lld %d %d\n",
1998 (long long)wsi->http.rx_content_length,
1999 wsi->upgraded_to_http2, wsi->mux_substream);
2001 if (wsi->http.content_length_explicitly_zero &&
2002 lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
2015 if (wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP_BODY,
2016 wsi->user_space, NULL, 0))
2018 if (wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP_BODY_COMPLETION,
2019 wsi->user_space, NULL, 0))
2025 if (wsi->http.rx_content_length <= 0)
2028 if (lwsi_state(wsi) != LRS_DISCARD_BODY) {
2029 lwsi_set_state(wsi, LRS_BODY);
2031 lws_wsi_tag(wsi), (int)wsi->wsistate);
2033 wsi->http.rx_content_remain = wsi->http.rx_content_length;
2037 * action to expecting BODY on the stream wsi, if it's
2038 * in a bundle like h2. So if the stream wsi has its
2046 ebuf.len = (int)lws_buflist_next_segment_len(&wsi->buflist,
2052 m = lws_read_h1(wsi, ebuf.token, (lws_filepos_t)ebuf.len);
2056 if (lws_buflist_aware_finished_consuming(wsi, &ebuf, m, 1,
2064 lws_header_table_detach(wsi, 1);
2070 lws_confirm_host_header(struct lws *wsi)
2082 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
2089 if (wsi->tls.ssl)
2093 n = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_HOST);
2106 if (strncmp(ts.token, wsi->a.vhost->name, ts.token_len)) {
2109 __func__, ts.token, wsi->a.vhost->name);
2123 if (wsi->a.vhost->listen_port != port) {
2125 __func__, port, wsi->a.vhost->listen_port);
2141 lws_http_to_fallback(struct lws *wsi, unsigned char *obuf, size_t olen)
2145 &wsi->a.vhost->protocols[wsi->a.vhost->raw_protocol_index];
2149 if (wsi->a.vhost->listen_accept_role &&
2150 lws_role_by_name(wsi->a.vhost->listen_accept_role))
2151 role = lws_role_by_name(wsi->a.vhost->listen_accept_role);
2153 if (wsi->a.vhost->listen_accept_protocol) {
2154 p1 = lws_vhost_name_to_protocol(wsi->a.vhost,
2155 wsi->a.vhost->listen_accept_protocol);
2160 lws_bind_protocol(wsi, protocol, __func__);
2162 lws_role_transition(wsi, LWSIFR_SERVER, LRS_ESTABLISHED, role);
2164 lws_header_table_detach(wsi, 0);
2165 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
2168 if (wsi->role_ops->adoption_cb[1])
2169 n = wsi->role_ops->adoption_cb[1];
2173 lws_get_peer_simple(wsi, ipbuf, sizeof(ipbuf));
2177 "protocol %s, cb %d, ah %p\n", __func__, wsi->a.vhost->name,
2179 wsi->http.ah);
2181 if ((wsi->a.protocol->callback)(wsi, (enum lws_callback_reasons)n, wsi->user_space, NULL, 0))
2185 if (wsi->role_ops->rx_cb[lwsi_role_server(wsi)])
2186 n = wsi->role_ops->rx_cb[lwsi_role_server(wsi)];
2187 if (wsi->a.protocol->callback(wsi, (enum lws_callback_reasons)n, wsi->user_space, obuf, olen))
2194 lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
2196 struct lws_context *context = lws_get_context(wsi);
2197 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
2213 if (!wsi->http.ah) {
2219 if (!lwsi_role_server(wsi) || !lwsi_role_http(wsi)) {
2220 lwsl_err("%s: bad wsi role 0x%x\n", __func__,
2221 (int)lwsi_role(wsi));
2226 m = lws_parse(wsi, *buf, &i);
2245 if (lws_http_to_fallback(wsi, obuf, olen)) {
2260 if (!wsi->http.ah)
2263 if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE)
2270 if (wsi->a.vhost->listen_port &&
2271 lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
2273 context, wsi->a.vhost->listen_port,
2274 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
2277 lws_vhost_bind_wsi(vhost, wsi);
2281 if ((!lwsi_role_h2(wsi) || !lwsi_role_server(wsi)) &&
2282 (!wsi->conn_stat_done))
2283 wsi->conn_stat_done = 1;
2287 if (wsi->a.context->reject_service_keywords) {
2289 wsi->a.context->reject_service_keywords;
2292 if (lws_hdr_copy(wsi, ua, sizeof(ua) - 1,
2308 lws_return_http_status(wsi,
2311 meth = lws_http_get_uri_and_method(wsi,
2314 lws_prepare_access_log_info(wsi,
2317 /* wsi close will do the log */
2343 n = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
2345 hit = lws_find_mount(wsi, uri_ptr, uri_len);
2347 n = lws_http_redirect_hit(pt, wsi, hit, uri_ptr,
2357 if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECT)) {
2362 lwsi_set_state(wsi, LRS_PRE_WS_SERVING_ACCEPT);
2363 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
2365 if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
2367 const char *up = lws_hdr_simple_ptr(wsi,
2374 if (lws_return_http_status(wsi,
2376 lws_http_transaction_completed(wsi))
2380 n = user_callback_handle_rxflow(wsi->a.protocol->callback,
2381 wsi, LWS_CALLBACK_HTTP_CONFIRM_UPGRADE,
2382 wsi->user_space, (char *)up, 0);
2392 if (lws_http_transaction_completed(wsi))
2402 if (wsi->a.vhost->options &
2404 lws_confirm_host_header(wsi))
2409 lws_metrics_tag_wsi_add(wsi, "upg", "ws");
2416 lws_metrics_tag_wsi_add(wsi, "upg", "h2c");
2425 lwsl_info("%s: %s: No upgrade\n", __func__, lws_wsi_tag(wsi));
2427 lwsi_set_state(wsi, LRS_ESTABLISHED);
2429 wsi->http.fop_fd = NULL;
2433 lws_http_compression_validate(wsi);
2436 lwsl_debug("%s: %s: ah %p\n", __func__, lws_wsi_tag(wsi),
2437 (void *)wsi->http.ah);
2439 n = lws_http_action(wsi);
2445 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP2_SETTINGS)) {
2452 p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS);
2460 wsi->upgraded_to_http2 = 1;
2464 ah = wsi->http.ah;
2465 lws_role_transition(wsi, LWSIFR_SERVER, LRS_H2_AWAIT_PREFACE,
2469 wsi->http.ah = ah;
2471 if (!wsi->h2.h2n) {
2472 wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), "h2n");
2473 if (!wsi->h2.h2n)
2477 lws_h2_init(wsi);
2481 lws_h2_settings(wsi, &wsi->h2.h2n->peer_set, (uint8_t *)tbuf, n);
2483 if (lws_hpack_dynamic_size(wsi, (int)wsi->h2.h2n->peer_set.s[
2491 n = lws_issue_raw(wsi, (unsigned char *)tbuf, (unsigned int)m);
2501 if (lws_process_ws_upgrade(wsi))
2512 lws_header_table_detach(wsi, 1);
2519 lws_http_transaction_completed(struct lws *wsi)
2523 if (wsi->http.cgi_transaction_complete)
2526 if (lws_has_buffered_out(wsi)
2528 || wsi->http.comp_ctx.buflist_comp ||
2529 wsi->http.comp_ctx.may_have_more
2541 lws_wsi_tag(wsi));
2542 wsi->http.deferred_transaction_completed = 1;
2543 lws_callback_on_writable(wsi);
2554 if (wsi->http.rx_content_length && wsi->http.rx_content_remain) {
2559 if (lwsi_state(wsi) == LRS_DISCARD_BODY)
2565 lwsi_set_state(wsi, LRS_DISCARD_BODY);
2574 lws_snprintf(tmp, sizeof(tmp), "%u", wsi->http.response_code);
2575 lws_metrics_tag_wsi_add(wsi, "status", tmp);
2579 lwsl_info("%s: %s\n", __func__, lws_wsi_tag(wsi));
2582 lws_http_compression_destroy(wsi);
2584 lws_access_log(wsi);
2586 if (!wsi->hdr_parsing_completed
2588 && !wsi->http.cgi
2594 lws_get_peer_simple(wsi, peer, sizeof(peer) - 1);
2605 if (wsi->http.cgi) {
2607 wsi->http.cgi_transaction_complete = 1;
2608 lws_cgi_remove_and_kill(wsi);
2609 lws_spawn_piped_destroy(&wsi->http.cgi->lsp);
2610 lws_sul_cancel(&wsi->http.cgi->sul_grace);
2612 lws_free_set_NULL(wsi->http.cgi);
2613 wsi->http.cgi_transaction_complete = 0;
2618 if (wsi->mux_substream)
2621 if (wsi->seen_zero_length_recv)
2624 if (wsi->http.conn_type != HTTP_CONNECTION_KEEP_ALIVE) {
2625 lwsl_info("%s: %s: close connection\n", __func__, lws_wsi_tag(wsi));
2629 if (lws_bind_protocol(wsi, &wsi->a.vhost->protocols[0], __func__))
2634 * idea about the wsi writability, we make put it in a holding state
2639 lws_wsi_tag(wsi), (int)wsi->wsistate, wsi->buflist);
2640 lwsi_set_state(wsi, LRS_DEFERRING_ACTION);
2641 wsi->http.tx_content_length = 0;
2642 wsi->http.tx_content_remain = 0;
2643 wsi->hdr_parsing_completed = 0;
2644 wsi->sending_chunked = 0;
2646 wsi->http.access_log.sent = 0;
2649 if (lwsi_role_http(wsi) && lwsi_role_server(wsi) &&
2650 wsi->http.fop_fd != NULL)
2651 lws_vfs_file_close(&wsi->http.fop_fd);
2655 if (wsi->a.vhost->keepalive_timeout)
2657 lws_set_timeout(wsi, (enum pending_timeout)n, wsi->a.vhost->keepalive_timeout);
2671 if (wsi->http.ah) {
2672 // lws_buflist_describe(&wsi->buflist, wsi, __func__);
2673 if (!lws_buflist_next_segment_len(&wsi->buflist, NULL)) {
2675 __func__, lws_wsi_tag(wsi));
2676 lws_header_table_detach(wsi, 1);
2684 if (wsi->a.vhost->tls.use_ssl &&
2685 wsi->a.context->simultaneous_ssl_restriction &&
2686 wsi->a.context->simultaneous_ssl ==
2687 wsi->a.context->simultaneous_ssl_restriction) {
2695 __func__, lws_wsi_tag(wsi));
2696 lws_header_table_reset(wsi, 0);
2703 lws_set_timeout(wsi, PENDING_TIMEOUT_HOLDING_AH,
2704 wsi->a.vhost->keepalive_timeout);
2707 if (wsi->http.ah)
2708 wsi->http.ah->ues = URIES_IDLE;
2710 //lwsi_set_state(wsi, LRS_ESTABLISHED); // !!!
2712 if (lws_buflist_next_segment_len(&wsi->buflist, NULL))
2713 if (lws_header_table_attach(wsi, 0))
2717 __func__, lws_wsi_tag(wsi), (int)wsi->wsistate);
2718 lws_callback_on_writable(wsi);
2725 lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
2728 struct lws_context *context = lws_get_context(wsi);
2729 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
2732 struct lws_range_parsing *rp = &wsi->http.range;
2746 if (wsi->handling_404)
2754 * If wsi->http.fop_fd is already set, the caller already opened it
2756 if (!wsi->http.fop_fd) {
2757 fops = lws_vfs_select_fops(wsi->a.context->fops, file, &vpath);
2758 fflags |= lws_vfs_prepare_flags(wsi);
2759 wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->a.context->fops,
2761 if (!wsi->http.fop_fd) {
2764 if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND,
2767 return !wsi->mux_substream;
2772 * Caution... wsi->http.fop_fd is live from here
2775 wsi->http.filelen = lws_vfs_get_length(wsi->http.fop_fd);
2776 total_content_length = wsi->http.filelen;
2779 ranges = lws_ranges_init(wsi, rp, wsi->http.filelen);
2791 lws_return_http_status(wsi,
2793 if (lws_http_transaction_completed(wsi))
2796 lws_vfs_file_close(&wsi->http.fop_fd);
2804 if (lws_add_http_header_status(wsi, (unsigned int)n, &p, end))
2807 if ((wsi->http.fop_fd->flags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP |
2810 if (lws_add_http_header_by_token(wsi,
2824 if (!wsi->interpreting && (
2828 lws_http_compression_apply(wsi, NULL, &p, end, 0);
2837 if (lws_add_http_header_by_token(wsi,
2846 lws_strncpy(wsi->http.multipart_content_type, content_type,
2847 sizeof(wsi->http.multipart_content_type));
2849 if (lws_add_http_header_by_token(wsi,
2898 if (lws_add_http_header_by_token(wsi,
2905 wsi->http.range.inside = 0;
2907 if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ACCEPT_RANGES,
2912 if (!wsi->mux_substream) {
2914 if (!wsi->sending_chunked
2916 && !wsi->http.lcs
2923 if (lws_add_http_header_content_length(wsi,
2929 if (wsi->http.lcs) {
2939 if (lws_add_http_header_by_token(wsi,
2954 wsi->http.comp_ctx.chunking = 1;
2960 if (wsi->cache_secs && wsi->cache_reuse) {
2961 if (!wsi->cache_revalidate) {
2964 intermediates[wsi->cache_intermediaries],
2965 wsi->cache_secs);
2970 intermediates[wsi->cache_intermediaries],
2971 wsi->cache_secs);
2980 if (lws_add_http_header_by_token(wsi,
2993 if (lws_finalize_http_header(wsi, &p, end))
2996 ret = lws_write(wsi, response, lws_ptr_diff_size_t(p, response), LWS_WRITE_HTTP_HEADERS);
3003 wsi->http.filepos = 0;
3004 lwsi_set_state(wsi, LRS_ISSUING_FILE);
3006 if (lws_hdr_total_length(wsi, WSI_TOKEN_HEAD_URI)) {
3008 lws_vfs_file_close(&wsi->http.fop_fd);
3009 if (lws_http_transaction_completed(wsi))
3015 lws_callback_on_writable(wsi);
3020 lws_vfs_file_close(&wsi->http.fop_fd);
3028 int lws_serve_http_file_fragment(struct lws *wsi)
3030 struct lws_context *context = wsi->a.context;
3031 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
3043 lwsl_debug("wsi->mux_substream %d\n", wsi->mux_substream);
3049 if (lws_has_buffered_out(wsi)) {
3050 if (lws_issue_raw(wsi, NULL, 0) < 0) {
3060 if (wsi->http.comp_ctx.buflist_comp ||
3061 wsi->http.comp_ctx.may_have_more) {
3065 __func__, wsi->http.comp_ctx.buflist_comp,
3066 wsi->http.comp_ctx.may_have_more);
3068 if (lws_rops_fidx(wsi->role_ops, LWS_ROPS_write_role_protocol) &&
3069 lws_rops_func_fidx(wsi->role_ops, LWS_ROPS_write_role_protocol).
3070 write_role_protocol(wsi, NULL, 0, &wp) < 0) {
3074 lws_callback_on_writable(wsi);
3080 if (wsi->http.filepos == wsi->http.filelen)
3087 if (wsi->http.range.count_ranges && !wsi->http.range.inside) {
3090 wsi->http.range.start);
3092 if ((long long)lws_vfs_file_seek_cur(wsi->http.fop_fd,
3093 (lws_fileofs_t)wsi->http.range.start -
3094 (lws_fileofs_t)wsi->http.filepos) < 0)
3097 wsi->http.filepos = wsi->http.range.start;
3099 if (wsi->http.range.count_ranges > 1) {
3108 wsi->http.multipart_content_type,
3109 wsi->http.range.start,
3110 wsi->http.range.end,
3111 wsi->http.range.extent);
3115 wsi->http.range.budget = wsi->http.range.end -
3116 wsi->http.range.start + 1;
3117 wsi->http.range.inside = 1;
3129 nwsi = lws_get_network_wsi(wsi);
3136 if (wsi->http.tx_content_length)
3137 if (poss > wsi->http.tx_content_remain)
3138 poss = wsi->http.tx_content_remain;
3144 if (wsi->a.protocol->tx_packet_size &&
3145 poss > wsi->a.protocol->tx_packet_size)
3146 poss = wsi->a.protocol->tx_packet_size;
3148 if (lws_rops_fidx(wsi->role_ops, LWS_ROPS_tx_credit)) {
3149 lws_filepos_t txc = (unsigned int)lws_rops_func_fidx(wsi->role_ops,
3151 tx_credit(wsi, LWSTXCR_US_TO_PEER, 0);
3159 lws_wsi_tag(wsi));
3173 if (wsi->http.range.count_ranges) {
3174 if (wsi->http.range.count_ranges > 1)
3176 if (poss > wsi->http.range.budget)
3177 poss = wsi->http.range.budget;
3180 if (wsi->sending_chunked) {
3188 if (lws_vfs_file_read(wsi->http.fop_fd, &amount, p, poss) < 0)
3191 if (wsi->sending_chunked)
3199 lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
3202 if (wsi->interpreting) {
3206 args.final = wsi->http.filepos + (unsigned int)n ==
3207 wsi->http.filelen;
3208 args.chunked = wsi->sending_chunked;
3210 wsi->a.vhost->protocols[
3211 (int)wsi->protocol_interpret_idx].callback,
3212 wsi, LWS_CALLBACK_PROCESS_HTML,
3213 wsi->user_space, &args, 0) < 0)
3221 if (wsi->http.range.send_ctr + 1 ==
3222 wsi->http.range.count_ranges && // last range
3223 wsi->http.range.count_ranges > 1 && // was 2+ ranges (ie, multipart)
3224 wsi->http.range.budget - amount == 0) {// final part
3230 m = lws_write(wsi, p, (unsigned int)n, wsi->http.filepos + amount ==
3231 wsi->http.filelen ?
3236 wsi->http.filepos += amount;
3239 if (wsi->http.range.count_ranges >= 1) {
3240 wsi->http.range.budget -= amount;
3241 if (wsi->http.range.budget == 0) {
3243 wsi->http.range.inside = 0;
3244 wsi->http.range.send_ctr++;
3246 if (lws_ranges_next(&wsi->http.range) < 1) {
3256 if (lws_vfs_file_seek_cur(wsi->http.fop_fd,
3264 if ((!lws_has_buffered_out(wsi)
3266 && !wsi->http.comp_ctx.buflist_comp &&
3267 !wsi->http.comp_ctx.may_have_more
3269 ) && (wsi->http.filepos >= wsi->http.filelen
3276 lwsi_set_state(wsi, LRS_ESTABLISHED);
3278 lws_vfs_file_close(&wsi->http.fop_fd);
3282 if (wsi->a.protocol->callback &&
3283 user_callback_handle_rxflow(wsi->a.protocol->callback,
3284 wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION,
3285 wsi->user_space, NULL, 0) < 0) {
3300 if (wsi->mux_substream)
3313 } while (!lws_send_pipe_choked(wsi));
3315 lws_callback_on_writable(wsi);
3320 lws_vfs_file_close(&wsi->http.fop_fd);