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