1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include <private-lib-core.h> 26d4afb5ceSopenharmony_ci 27d4afb5ceSopenharmony_cistatic int 28d4afb5ceSopenharmony_cirops_handle_POLLIN_cgi(struct lws_context_per_thread *pt, struct lws *wsi, 29d4afb5ceSopenharmony_ci struct lws_pollfd *pollfd) 30d4afb5ceSopenharmony_ci{ 31d4afb5ceSopenharmony_ci struct lws_cgi_args args; 32d4afb5ceSopenharmony_ci 33d4afb5ceSopenharmony_ci assert(wsi->role_ops == &role_ops_cgi); 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_ci if (wsi->lsp_channel >= LWS_STDOUT && 36d4afb5ceSopenharmony_ci !(pollfd->revents & pollfd->events & LWS_POLLIN)) 37d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 38d4afb5ceSopenharmony_ci 39d4afb5ceSopenharmony_ci if (wsi->lsp_channel == LWS_STDIN && 40d4afb5ceSopenharmony_ci !(pollfd->revents & pollfd->events & LWS_POLLOUT)) 41d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 42d4afb5ceSopenharmony_ci 43d4afb5ceSopenharmony_ci if (wsi->lsp_channel == LWS_STDIN && 44d4afb5ceSopenharmony_ci lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { 45d4afb5ceSopenharmony_ci lwsl_wsi_info(wsi, "failed at set pollfd"); 46d4afb5ceSopenharmony_ci return LWS_HPI_RET_WSI_ALREADY_DIED; 47d4afb5ceSopenharmony_ci } 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_ci if (!wsi->parent) { 50d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "stdwsi content with parent"); 51d4afb5ceSopenharmony_ci 52d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 53d4afb5ceSopenharmony_ci } 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_ci if (!wsi->parent->http.cgi) { 56d4afb5ceSopenharmony_ci lwsl_wsi_notice(wsi, "stdwsi content with deleted cgi object"); 57d4afb5ceSopenharmony_ci 58d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 59d4afb5ceSopenharmony_ci } 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci if (!wsi->parent->http.cgi->lsp) { 62d4afb5ceSopenharmony_ci lwsl_wsi_notice(wsi, "stdwsi content with reaped lsp"); 63d4afb5ceSopenharmony_ci 64d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 65d4afb5ceSopenharmony_ci } 66d4afb5ceSopenharmony_ci 67d4afb5ceSopenharmony_ci args.ch = wsi->lsp_channel; 68d4afb5ceSopenharmony_ci args.stdwsi = &wsi->parent->http.cgi->lsp->stdwsi[0]; 69d4afb5ceSopenharmony_ci args.hdr_state = (enum lws_cgi_hdr_state)wsi->hdr_state; 70d4afb5ceSopenharmony_ci 71d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "CGI LWS_STDOUT %p wsistate 0x%x", 72d4afb5ceSopenharmony_ci wsi->parent, wsi->wsistate); 73d4afb5ceSopenharmony_ci 74d4afb5ceSopenharmony_ci if (user_callback_handle_rxflow(wsi->parent->a.protocol->callback, 75d4afb5ceSopenharmony_ci wsi->parent, LWS_CALLBACK_CGI, 76d4afb5ceSopenharmony_ci wsi->parent->user_space, 77d4afb5ceSopenharmony_ci (void *)&args, 0)) 78d4afb5ceSopenharmony_ci return 1; 79d4afb5ceSopenharmony_ci 80d4afb5ceSopenharmony_ci return LWS_HPI_RET_HANDLED; 81d4afb5ceSopenharmony_ci} 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_cistatic int 84d4afb5ceSopenharmony_cirops_handle_POLLOUT_cgi(struct lws *wsi) 85d4afb5ceSopenharmony_ci{ 86d4afb5ceSopenharmony_ci return LWS_HP_RET_USER_SERVICE; 87d4afb5ceSopenharmony_ci} 88d4afb5ceSopenharmony_ci 89d4afb5ceSopenharmony_cistatic int 90d4afb5ceSopenharmony_cirops_destroy_role_cgi(struct lws *wsi) 91d4afb5ceSopenharmony_ci{ 92d4afb5ceSopenharmony_ci#if defined(LWS_WITH_ZLIB) 93d4afb5ceSopenharmony_ci if (!wsi->http.cgi) 94d4afb5ceSopenharmony_ci return 0; 95d4afb5ceSopenharmony_ci if (!wsi->http.cgi->gzip_init) 96d4afb5ceSopenharmony_ci return 0; 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_ci inflateEnd(&wsi->http.cgi->inflate); 99d4afb5ceSopenharmony_ci wsi->http.cgi->gzip_init = 0; 100d4afb5ceSopenharmony_ci#endif 101d4afb5ceSopenharmony_ci 102d4afb5ceSopenharmony_ci return 0; 103d4afb5ceSopenharmony_ci} 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_civoid 106d4afb5ceSopenharmony_cilws_cgi_sul_cb(lws_sorted_usec_list_t *sul) 107d4afb5ceSopenharmony_ci{ 108d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = lws_container_of(sul, 109d4afb5ceSopenharmony_ci struct lws_context_per_thread, sul_cgi); 110d4afb5ceSopenharmony_ci 111d4afb5ceSopenharmony_ci lws_cgi_kill_terminated(pt); 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci if (pt->http.cgi_list) 114d4afb5ceSopenharmony_ci lws_sul_schedule(pt->context, (int)(pt - pt->context->pt), 115d4afb5ceSopenharmony_ci &pt->sul_cgi, lws_cgi_sul_cb, 3 * LWS_US_PER_SEC); 116d4afb5ceSopenharmony_ci} 117d4afb5ceSopenharmony_ci 118d4afb5ceSopenharmony_cistatic int 119d4afb5ceSopenharmony_cirops_pt_init_destroy_cgi(struct lws_context *context, 120d4afb5ceSopenharmony_ci const struct lws_context_creation_info *info, 121d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt, int destroy) 122d4afb5ceSopenharmony_ci{ 123d4afb5ceSopenharmony_ci 124d4afb5ceSopenharmony_ci lws_sul_cancel(&pt->sul_cgi); 125d4afb5ceSopenharmony_ci 126d4afb5ceSopenharmony_ci return 0; 127d4afb5ceSopenharmony_ci} 128d4afb5ceSopenharmony_ci 129d4afb5ceSopenharmony_cistatic int 130d4afb5ceSopenharmony_cirops_close_role_cgi(struct lws_context_per_thread *pt, struct lws *wsi) 131d4afb5ceSopenharmony_ci{ 132d4afb5ceSopenharmony_ci if (wsi->parent && wsi->parent->http.cgi && wsi->parent->http.cgi->lsp) 133d4afb5ceSopenharmony_ci lws_spawn_stdwsi_closed(wsi->parent->http.cgi->lsp, wsi); 134d4afb5ceSopenharmony_ci 135d4afb5ceSopenharmony_ci return 0; 136d4afb5ceSopenharmony_ci} 137d4afb5ceSopenharmony_ci 138d4afb5ceSopenharmony_cistatic const lws_rops_t rops_table_cgi[] = { 139d4afb5ceSopenharmony_ci /* 1 */ { .pt_init_destroy = rops_pt_init_destroy_cgi }, 140d4afb5ceSopenharmony_ci /* 2 */ { .handle_POLLIN = rops_handle_POLLIN_cgi }, 141d4afb5ceSopenharmony_ci /* 3 */ { .handle_POLLOUT = rops_handle_POLLOUT_cgi }, 142d4afb5ceSopenharmony_ci /* 4 */ { .close_role = rops_close_role_cgi }, 143d4afb5ceSopenharmony_ci /* 5 */ { .destroy_role = rops_destroy_role_cgi }, 144d4afb5ceSopenharmony_ci}; 145d4afb5ceSopenharmony_ci 146d4afb5ceSopenharmony_ciconst struct lws_role_ops role_ops_cgi = { 147d4afb5ceSopenharmony_ci /* role name */ "cgi", 148d4afb5ceSopenharmony_ci /* alpn id */ NULL, 149d4afb5ceSopenharmony_ci 150d4afb5ceSopenharmony_ci /* rops_table */ rops_table_cgi, 151d4afb5ceSopenharmony_ci /* rops_idx */ { 152d4afb5ceSopenharmony_ci /* LWS_ROPS_check_upgrades */ 153d4afb5ceSopenharmony_ci /* LWS_ROPS_pt_init_destroy */ 0x01, 154d4afb5ceSopenharmony_ci /* LWS_ROPS_init_vhost */ 155d4afb5ceSopenharmony_ci /* LWS_ROPS_destroy_vhost */ 0x00, 156d4afb5ceSopenharmony_ci /* LWS_ROPS_service_flag_pending */ 157d4afb5ceSopenharmony_ci /* LWS_ROPS_handle_POLLIN */ 0x02, 158d4afb5ceSopenharmony_ci /* LWS_ROPS_handle_POLLOUT */ 159d4afb5ceSopenharmony_ci /* LWS_ROPS_perform_user_POLLOUT */ 0x30, 160d4afb5ceSopenharmony_ci /* LWS_ROPS_callback_on_writable */ 161d4afb5ceSopenharmony_ci /* LWS_ROPS_tx_credit */ 0x00, 162d4afb5ceSopenharmony_ci /* LWS_ROPS_write_role_protocol */ 163d4afb5ceSopenharmony_ci /* LWS_ROPS_encapsulation_parent */ 0x00, 164d4afb5ceSopenharmony_ci /* LWS_ROPS_alpn_negotiated */ 165d4afb5ceSopenharmony_ci /* LWS_ROPS_close_via_role_protocol */ 0x00, 166d4afb5ceSopenharmony_ci /* LWS_ROPS_close_role */ 167d4afb5ceSopenharmony_ci /* LWS_ROPS_close_kill_connection */ 0x40, 168d4afb5ceSopenharmony_ci /* LWS_ROPS_destroy_role */ 169d4afb5ceSopenharmony_ci /* LWS_ROPS_adoption_bind */ 0x50, 170d4afb5ceSopenharmony_ci /* LWS_ROPS_client_bind */ 171d4afb5ceSopenharmony_ci /* LWS_ROPS_issue_keepalive */ 0x00, 172d4afb5ceSopenharmony_ci }, 173d4afb5ceSopenharmony_ci 174d4afb5ceSopenharmony_ci /* adoption_cb clnt, srv */ { 0, 0 }, 175d4afb5ceSopenharmony_ci /* rx_cb clnt, srv */ { 0, 0 }, 176d4afb5ceSopenharmony_ci /* writeable cb clnt, srv */ { 0, 0 }, 177d4afb5ceSopenharmony_ci /* close cb clnt, srv */ { 0, 0 }, 178d4afb5ceSopenharmony_ci /* protocol_bind_cb c,s */ { 0, 0 }, 179d4afb5ceSopenharmony_ci /* protocol_unbind_cb c,s */ { 0, 0 }, 180d4afb5ceSopenharmony_ci 181d4afb5ceSopenharmony_ci /* file_handle */ 0, 182d4afb5ceSopenharmony_ci}; 183