xref: /aosp_15_r20/external/libwebsockets/lib/secure-streams/protocols/ss-h1.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
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) 2019 - 2020 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  * This is the glue that wires up h1 to Secure Streams.
25*1c60b9acSAndroid Build Coastguard Worker  */
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
28*1c60b9acSAndroid Build Coastguard Worker 
29*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_PLAT_FREERTOS) || defined(LWS_ROLE_H2)
30*1c60b9acSAndroid Build Coastguard Worker #define LWS_WITH_SS_RIDESHARE
31*1c60b9acSAndroid Build Coastguard Worker #endif
32*1c60b9acSAndroid Build Coastguard Worker 
33*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
34*1c60b9acSAndroid Build Coastguard Worker static int
ss_http_multipart_parser(lws_ss_handle_t * h,void * in,size_t len)35*1c60b9acSAndroid Build Coastguard Worker ss_http_multipart_parser(lws_ss_handle_t *h, void *in, size_t len)
36*1c60b9acSAndroid Build Coastguard Worker {
37*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *q = (uint8_t *)in;
38*1c60b9acSAndroid Build Coastguard Worker 	int pending_issue = 0, n = 0;
39*1c60b9acSAndroid Build Coastguard Worker 
40*1c60b9acSAndroid Build Coastguard Worker 
41*1c60b9acSAndroid Build Coastguard Worker 	/* let's stick it in the boundary state machine first */
42*1c60b9acSAndroid Build Coastguard Worker 	while (n < (int)len) {
43*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.boundary_seq != h->u.http.boundary_len) {
44*1c60b9acSAndroid Build Coastguard Worker 			if (q[n] == h->u.http.boundary[h->u.http.boundary_seq])
45*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_seq++;
46*1c60b9acSAndroid Build Coastguard Worker 			else {
47*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_seq = 0;
48*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_dashes = 0;
49*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_post = 0;
50*1c60b9acSAndroid Build Coastguard Worker 			}
51*1c60b9acSAndroid Build Coastguard Worker 			goto around;
52*1c60b9acSAndroid Build Coastguard Worker 		}
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker 		/*
55*1c60b9acSAndroid Build Coastguard Worker 		 * We already matched the boundary string, now we're
56*1c60b9acSAndroid Build Coastguard Worker 		 * looking if there's a -- afterwards
57*1c60b9acSAndroid Build Coastguard Worker 		 */
58*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.boundary_dashes < 2) {
59*1c60b9acSAndroid Build Coastguard Worker 			if (q[n] == '-') {
60*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_dashes++;
61*1c60b9acSAndroid Build Coastguard Worker 				goto around;
62*1c60b9acSAndroid Build Coastguard Worker 			}
63*1c60b9acSAndroid Build Coastguard Worker 			/* there was no final -- ... */
64*1c60b9acSAndroid Build Coastguard Worker 		}
65*1c60b9acSAndroid Build Coastguard Worker 
66*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.boundary_dashes == 2) {
67*1c60b9acSAndroid Build Coastguard Worker 			/*
68*1c60b9acSAndroid Build Coastguard Worker 			 * It's an EOM boundary: issue pending + multipart EOP
69*1c60b9acSAndroid Build Coastguard Worker 			 */
70*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: seen EOP, n %d pi %d\n",
71*1c60b9acSAndroid Build Coastguard Worker 				    __func__, n, pending_issue);
72*1c60b9acSAndroid Build Coastguard Worker 			/*
73*1c60b9acSAndroid Build Coastguard Worker 			 * It's possible we already started the decode before
74*1c60b9acSAndroid Build Coastguard Worker 			 * the end of the last packet.  Then there is no
75*1c60b9acSAndroid Build Coastguard Worker 			 * remainder to send.
76*1c60b9acSAndroid Build Coastguard Worker 			 */
77*1c60b9acSAndroid Build Coastguard Worker 			if (n >= pending_issue + h->u.http.boundary_len +
78*1c60b9acSAndroid Build Coastguard Worker 			    (h->u.http.any ? 2 : 0) + 1) {
79*1c60b9acSAndroid Build Coastguard Worker 				h->info.rx(ss_to_userobj(h),
80*1c60b9acSAndroid Build Coastguard Worker 					   &q[pending_issue],
81*1c60b9acSAndroid Build Coastguard Worker 					   (unsigned int)(n - pending_issue -
82*1c60b9acSAndroid Build Coastguard Worker 					   h->u.http.boundary_len - 1 -
83*1c60b9acSAndroid Build Coastguard Worker 					   (h->u.http.any ? 2 : 0) /* crlf */),
84*1c60b9acSAndroid Build Coastguard Worker 				   (!h->u.http.som ? LWSSS_FLAG_SOM : 0) |
85*1c60b9acSAndroid Build Coastguard Worker 				   LWSSS_FLAG_EOM | LWSSS_FLAG_RELATED_END);
86*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.eom = 1;
87*1c60b9acSAndroid Build Coastguard Worker 			}
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker 			/*
90*1c60b9acSAndroid Build Coastguard Worker 			 * Peer may not END_STREAM us
91*1c60b9acSAndroid Build Coastguard Worker 			 */
92*1c60b9acSAndroid Build Coastguard Worker 			return 0;
93*1c60b9acSAndroid Build Coastguard Worker 			//return -1;
94*1c60b9acSAndroid Build Coastguard Worker 		}
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 		/* how about --boundaryCRLF */
97*1c60b9acSAndroid Build Coastguard Worker 
98*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.boundary_post < 2) {
99*1c60b9acSAndroid Build Coastguard Worker 			if ((!h->u.http.boundary_post && q[n] == '\x0d') ||
100*1c60b9acSAndroid Build Coastguard Worker 			    (h->u.http.boundary_post && q[n] == '\x0a')) {
101*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.boundary_post++;
102*1c60b9acSAndroid Build Coastguard Worker 				goto around;
103*1c60b9acSAndroid Build Coastguard Worker 			}
104*1c60b9acSAndroid Build Coastguard Worker 			/* there was no final CRLF ... it's wrong */
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 			return -1;
107*1c60b9acSAndroid Build Coastguard Worker 		}
108*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.boundary_post != 2)
109*1c60b9acSAndroid Build Coastguard Worker 			goto around;
110*1c60b9acSAndroid Build Coastguard Worker 
111*1c60b9acSAndroid Build Coastguard Worker 		/*
112*1c60b9acSAndroid Build Coastguard Worker 		 * We have a starting "--boundaryCRLF" or intermediate
113*1c60b9acSAndroid Build Coastguard Worker 		 * "CRLF--boundaryCRLF" boundary
114*1c60b9acSAndroid Build Coastguard Worker 		 */
115*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: b_post = 2 (pi %d)\n", __func__, pending_issue);
116*1c60b9acSAndroid Build Coastguard Worker 		h->u.http.boundary_seq = 0;
117*1c60b9acSAndroid Build Coastguard Worker 		h->u.http.boundary_post = 0;
118*1c60b9acSAndroid Build Coastguard Worker 
119*1c60b9acSAndroid Build Coastguard Worker 		if (n >= pending_issue && (h->u.http.any || !h->u.http.som)) {
120*1c60b9acSAndroid Build Coastguard Worker 			/* Intermediate... do the EOM */
121*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: seen interm EOP n %d pi %d\n", __func__,
122*1c60b9acSAndroid Build Coastguard Worker 				   n, pending_issue);
123*1c60b9acSAndroid Build Coastguard Worker 			/*
124*1c60b9acSAndroid Build Coastguard Worker 			 * It's possible we already started the decode before
125*1c60b9acSAndroid Build Coastguard Worker 			 * the end of the last packet.  Then there is no
126*1c60b9acSAndroid Build Coastguard Worker 			 * remainder to send.
127*1c60b9acSAndroid Build Coastguard Worker 			 */
128*1c60b9acSAndroid Build Coastguard Worker 			if (n >= pending_issue + h->u.http.boundary_len +
129*1c60b9acSAndroid Build Coastguard Worker 			    (h->u.http.any ? 2 : 0)) {
130*1c60b9acSAndroid Build Coastguard Worker 				h->info.rx(ss_to_userobj(h), &q[pending_issue],
131*1c60b9acSAndroid Build Coastguard Worker 					   (unsigned int)(n - pending_issue -
132*1c60b9acSAndroid Build Coastguard Worker 					       h->u.http.boundary_len -
133*1c60b9acSAndroid Build Coastguard Worker 					       (h->u.http.any ? 2 /* crlf */ : 0)),
134*1c60b9acSAndroid Build Coastguard Worker 					   (!h->u.http.som ? LWSSS_FLAG_SOM : 0) |
135*1c60b9acSAndroid Build Coastguard Worker 					   LWSSS_FLAG_EOM);
136*1c60b9acSAndroid Build Coastguard Worker 				h->u.http.eom = 1;
137*1c60b9acSAndroid Build Coastguard Worker 			}
138*1c60b9acSAndroid Build Coastguard Worker 		}
139*1c60b9acSAndroid Build Coastguard Worker 
140*1c60b9acSAndroid Build Coastguard Worker 		/* Next message starts after this boundary */
141*1c60b9acSAndroid Build Coastguard Worker 
142*1c60b9acSAndroid Build Coastguard Worker 		pending_issue = n;
143*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.eom) {
144*1c60b9acSAndroid Build Coastguard Worker 			/* reset only if we have sent eom */
145*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.som = 0;
146*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.eom = 0;
147*1c60b9acSAndroid Build Coastguard Worker 		}
148*1c60b9acSAndroid Build Coastguard Worker 
149*1c60b9acSAndroid Build Coastguard Worker around:
150*1c60b9acSAndroid Build Coastguard Worker 		n++;
151*1c60b9acSAndroid Build Coastguard Worker 	}
152*1c60b9acSAndroid Build Coastguard Worker 
153*1c60b9acSAndroid Build Coastguard Worker 	if (pending_issue != n) {
154*1c60b9acSAndroid Build Coastguard Worker 		uint8_t oh = 0;
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 		/*
157*1c60b9acSAndroid Build Coastguard Worker 		 * handle the first or last "--boundaryCRLF" case which is not captured in the
158*1c60b9acSAndroid Build Coastguard Worker 		 * previous loop, on the Bob downchannel (/directive)
159*1c60b9acSAndroid Build Coastguard Worker 		 *
160*1c60b9acSAndroid Build Coastguard Worker 		 * probably does not cover the case that one boundary term is separated in multipile
161*1c60b9acSAndroid Build Coastguard Worker 		 * one callbacks though never see such case
162*1c60b9acSAndroid Build Coastguard Worker 		 */
163*1c60b9acSAndroid Build Coastguard Worker 
164*1c60b9acSAndroid Build Coastguard Worker 		if ((n >= h->u.http.boundary_len) &&
165*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.boundary_seq == h->u.http.boundary_len &&
166*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.boundary_post == 2) {
167*1c60b9acSAndroid Build Coastguard Worker 
168*1c60b9acSAndroid Build Coastguard Worker 			oh = 1;
169*1c60b9acSAndroid Build Coastguard Worker 		}
170*1c60b9acSAndroid Build Coastguard Worker 
171*1c60b9acSAndroid Build Coastguard Worker 		h->info.rx(ss_to_userobj(h), &q[pending_issue],
172*1c60b9acSAndroid Build Coastguard Worker 				(unsigned int)(oh ?
173*1c60b9acSAndroid Build Coastguard Worker 				(n - pending_issue - h->u.http.boundary_len -
174*1c60b9acSAndroid Build Coastguard Worker 					(h->u.http.any ? 2 : 0)) :
175*1c60b9acSAndroid Build Coastguard Worker 				(n - pending_issue)),
176*1c60b9acSAndroid Build Coastguard Worker 			   (!h->u.http.som ? LWSSS_FLAG_SOM : 0) |
177*1c60b9acSAndroid Build Coastguard Worker 			     (oh && h->u.http.any ? LWSSS_FLAG_EOM : 0));
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 		if (oh && h->u.http.any)
180*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.eom = 1;
181*1c60b9acSAndroid Build Coastguard Worker 
182*1c60b9acSAndroid Build Coastguard Worker 		h->u.http.any = 1;
183*1c60b9acSAndroid Build Coastguard Worker 		h->u.http.som = 1;
184*1c60b9acSAndroid Build Coastguard Worker 	}
185*1c60b9acSAndroid Build Coastguard Worker 
186*1c60b9acSAndroid Build Coastguard Worker 	return 0;
187*1c60b9acSAndroid Build Coastguard Worker }
188*1c60b9acSAndroid Build Coastguard Worker #endif
189*1c60b9acSAndroid Build Coastguard Worker 
190*1c60b9acSAndroid Build Coastguard Worker /*
191*1c60b9acSAndroid Build Coastguard Worker  * Returns 0, or the ss state resp maps on to
192*1c60b9acSAndroid Build Coastguard Worker  */
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker static int
lws_ss_http_resp_to_state(lws_ss_handle_t * h,int resp)195*1c60b9acSAndroid Build Coastguard Worker lws_ss_http_resp_to_state(lws_ss_handle_t *h, int resp)
196*1c60b9acSAndroid Build Coastguard Worker {
197*1c60b9acSAndroid Build Coastguard Worker 	const lws_ss_http_respmap_t *r = h->policy->u.http.respmap;
198*1c60b9acSAndroid Build Coastguard Worker 	int n = h->policy->u.http.count_respmap;
199*1c60b9acSAndroid Build Coastguard Worker 
200*1c60b9acSAndroid Build Coastguard Worker 	while (n--)
201*1c60b9acSAndroid Build Coastguard Worker 		if (resp == r->resp)
202*1c60b9acSAndroid Build Coastguard Worker 			return r->state;
203*1c60b9acSAndroid Build Coastguard Worker 		else
204*1c60b9acSAndroid Build Coastguard Worker 			r++;
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	return 0; /* no hit */
207*1c60b9acSAndroid Build Coastguard Worker }
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker /*
210*1c60b9acSAndroid Build Coastguard Worker  * This converts any set metadata items into outgoing http headers
211*1c60b9acSAndroid Build Coastguard Worker  */
212*1c60b9acSAndroid Build Coastguard Worker 
213*1c60b9acSAndroid Build Coastguard Worker static int
lws_apply_metadata(lws_ss_handle_t * h,struct lws * wsi,uint8_t * buf,uint8_t ** pp,uint8_t * end)214*1c60b9acSAndroid Build Coastguard Worker lws_apply_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
215*1c60b9acSAndroid Build Coastguard Worker 		   uint8_t **pp, uint8_t *end)
216*1c60b9acSAndroid Build Coastguard Worker {
217*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *polmd = h->policy->metadata;
218*1c60b9acSAndroid Build Coastguard Worker 	int m = 0;
219*1c60b9acSAndroid Build Coastguard Worker 
220*1c60b9acSAndroid Build Coastguard Worker 	while (polmd) {
221*1c60b9acSAndroid Build Coastguard Worker 
222*1c60b9acSAndroid Build Coastguard Worker 		/* has to have a non-empty header string */
223*1c60b9acSAndroid Build Coastguard Worker 
224*1c60b9acSAndroid Build Coastguard Worker 		if (polmd->value__may_own_heap &&
225*1c60b9acSAndroid Build Coastguard Worker 		    ((uint8_t *)polmd->value__may_own_heap)[0] &&
226*1c60b9acSAndroid Build Coastguard Worker 		    h->metadata[m].value__may_own_heap) {
227*1c60b9acSAndroid Build Coastguard Worker 			if (lws_add_http_header_by_name(wsi,
228*1c60b9acSAndroid Build Coastguard Worker 					polmd->value__may_own_heap,
229*1c60b9acSAndroid Build Coastguard Worker 					h->metadata[m].value__may_own_heap,
230*1c60b9acSAndroid Build Coastguard Worker 					(int)h->metadata[m].length, pp, end))
231*1c60b9acSAndroid Build Coastguard Worker 			return -1;
232*1c60b9acSAndroid Build Coastguard Worker 
233*1c60b9acSAndroid Build Coastguard Worker 			/*
234*1c60b9acSAndroid Build Coastguard Worker 			 * Check for the case he's setting a non-zero
235*1c60b9acSAndroid Build Coastguard Worker 			 * content-length "via the backdoor" metadata-
236*1c60b9acSAndroid Build Coastguard Worker 			 * driven headers, and set the body_pending()
237*1c60b9acSAndroid Build Coastguard Worker 			 * state if so...
238*1c60b9acSAndroid Build Coastguard Worker 			 */
239*1c60b9acSAndroid Build Coastguard Worker 
240*1c60b9acSAndroid Build Coastguard Worker 			if (!strncmp(polmd->value__may_own_heap,
241*1c60b9acSAndroid Build Coastguard Worker 				     "content-length", 14) &&
242*1c60b9acSAndroid Build Coastguard Worker 			    atoi(h->metadata[m].value__may_own_heap))
243*1c60b9acSAndroid Build Coastguard Worker 				lws_client_http_body_pending(wsi, 1);
244*1c60b9acSAndroid Build Coastguard Worker 		}
245*1c60b9acSAndroid Build Coastguard Worker 
246*1c60b9acSAndroid Build Coastguard Worker 		m++;
247*1c60b9acSAndroid Build Coastguard Worker 		polmd = polmd->next;
248*1c60b9acSAndroid Build Coastguard Worker 	}
249*1c60b9acSAndroid Build Coastguard Worker 
250*1c60b9acSAndroid Build Coastguard Worker 	/*
251*1c60b9acSAndroid Build Coastguard Worker 	 * Content-length on POST / PUT if we have the length information
252*1c60b9acSAndroid Build Coastguard Worker 	 */
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->u.http.method && (
255*1c60b9acSAndroid Build Coastguard Worker 		(!strcmp(h->policy->u.http.method, "POST") ||
256*1c60b9acSAndroid Build Coastguard Worker 	         !strcmp(h->policy->u.http.method, "PUT"))) &&
257*1c60b9acSAndroid Build Coastguard Worker 	    wsi->http.writeable_len) {
258*1c60b9acSAndroid Build Coastguard Worker 		if (!(h->policy->flags &
259*1c60b9acSAndroid Build Coastguard Worker 			LWSSSPOLF_HTTP_NO_CONTENT_LENGTH)) {
260*1c60b9acSAndroid Build Coastguard Worker 			int n = lws_snprintf((char *)buf, 20, "%u",
261*1c60b9acSAndroid Build Coastguard Worker 				(unsigned int)wsi->http.writeable_len);
262*1c60b9acSAndroid Build Coastguard Worker 			if (lws_add_http_header_by_token(wsi,
263*1c60b9acSAndroid Build Coastguard Worker 					WSI_TOKEN_HTTP_CONTENT_LENGTH,
264*1c60b9acSAndroid Build Coastguard Worker 					buf, n, pp, end))
265*1c60b9acSAndroid Build Coastguard Worker 				return -1;
266*1c60b9acSAndroid Build Coastguard Worker 		}
267*1c60b9acSAndroid Build Coastguard Worker 		lws_client_http_body_pending(wsi, 1);
268*1c60b9acSAndroid Build Coastguard Worker 	}
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 	return 0;
271*1c60b9acSAndroid Build Coastguard Worker }
272*1c60b9acSAndroid Build Coastguard Worker 
273*1c60b9acSAndroid Build Coastguard Worker 
274*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
275*1c60b9acSAndroid Build Coastguard Worker static int
lws_apply_instant_metadata(lws_ss_handle_t * h,struct lws * wsi,uint8_t * buf,uint8_t ** pp,uint8_t * end)276*1c60b9acSAndroid Build Coastguard Worker lws_apply_instant_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
277*1c60b9acSAndroid Build Coastguard Worker 		   uint8_t **pp, uint8_t *end)
278*1c60b9acSAndroid Build Coastguard Worker {
279*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *imd = h->instant_metadata;
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 	while (imd) {
282*1c60b9acSAndroid Build Coastguard Worker 		if (imd->name && imd->value__may_own_heap) {
283*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s add header %s %s %d\n", __func__,
284*1c60b9acSAndroid Build Coastguard Worker 					           imd->name,
285*1c60b9acSAndroid Build Coastguard Worker 			                           (char *)imd->value__may_own_heap,
286*1c60b9acSAndroid Build Coastguard Worker 						   imd->length);
287*1c60b9acSAndroid Build Coastguard Worker 			if (lws_add_http_header_by_name(wsi,
288*1c60b9acSAndroid Build Coastguard Worker 					(const unsigned char *)imd->name,
289*1c60b9acSAndroid Build Coastguard Worker 					(const unsigned char *)imd->value__may_own_heap,
290*1c60b9acSAndroid Build Coastguard Worker 					(int)imd->length, pp, end))
291*1c60b9acSAndroid Build Coastguard Worker 			return -1;
292*1c60b9acSAndroid Build Coastguard Worker 
293*1c60b9acSAndroid Build Coastguard Worker 			/* it's possible user set content-length directly */
294*1c60b9acSAndroid Build Coastguard Worker 			if (!strncmp(imd->name,
295*1c60b9acSAndroid Build Coastguard Worker 				     "content-length", 14) &&
296*1c60b9acSAndroid Build Coastguard Worker 			    atoi(imd->value__may_own_heap))
297*1c60b9acSAndroid Build Coastguard Worker 				lws_client_http_body_pending(wsi, 1);
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker 		}
300*1c60b9acSAndroid Build Coastguard Worker 
301*1c60b9acSAndroid Build Coastguard Worker 		imd = imd->next;
302*1c60b9acSAndroid Build Coastguard Worker 	}
303*1c60b9acSAndroid Build Coastguard Worker 
304*1c60b9acSAndroid Build Coastguard Worker 	return 0;
305*1c60b9acSAndroid Build Coastguard Worker }
306*1c60b9acSAndroid Build Coastguard Worker #endif
307*1c60b9acSAndroid Build Coastguard Worker /*
308*1c60b9acSAndroid Build Coastguard Worker  * Check if any metadata headers present in the server headers, and record
309*1c60b9acSAndroid Build Coastguard Worker  * them into the associated metadata item if so.
310*1c60b9acSAndroid Build Coastguard Worker  */
311*1c60b9acSAndroid Build Coastguard Worker 
312*1c60b9acSAndroid Build Coastguard Worker static int
lws_extract_metadata(lws_ss_handle_t * h,struct lws * wsi)313*1c60b9acSAndroid Build Coastguard Worker lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
314*1c60b9acSAndroid Build Coastguard Worker {
315*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *polmd = h->policy->metadata, *omd;
316*1c60b9acSAndroid Build Coastguard Worker 	int n, m = 0;
317*1c60b9acSAndroid Build Coastguard Worker 
318*1c60b9acSAndroid Build Coastguard Worker 	while (polmd) {
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 		if (polmd->value_is_http_token != LWS_HTTP_NO_KNOWN_HEADER) {
321*1c60b9acSAndroid Build Coastguard Worker 
322*1c60b9acSAndroid Build Coastguard Worker 			/* it's a well-known header token */
323*1c60b9acSAndroid Build Coastguard Worker 
324*1c60b9acSAndroid Build Coastguard Worker 			n = lws_hdr_total_length(wsi, polmd->value_is_http_token);
325*1c60b9acSAndroid Build Coastguard Worker 			if (n) {
326*1c60b9acSAndroid Build Coastguard Worker 				const char *cp = lws_hdr_simple_ptr(wsi,
327*1c60b9acSAndroid Build Coastguard Worker 						polmd->value_is_http_token);
328*1c60b9acSAndroid Build Coastguard Worker 				omd = lws_ss_get_handle_metadata(h, polmd->name);
329*1c60b9acSAndroid Build Coastguard Worker 				if (!omd || !cp)
330*1c60b9acSAndroid Build Coastguard Worker 					return 1;
331*1c60b9acSAndroid Build Coastguard Worker 
332*1c60b9acSAndroid Build Coastguard Worker 				assert(!strcmp(omd->name, polmd->name));
333*1c60b9acSAndroid Build Coastguard Worker 
334*1c60b9acSAndroid Build Coastguard Worker 				/*
335*1c60b9acSAndroid Build Coastguard Worker 				 * it's present on the wsi, we want to
336*1c60b9acSAndroid Build Coastguard Worker 				 * set the related metadata name to it then
337*1c60b9acSAndroid Build Coastguard Worker 				 */
338*1c60b9acSAndroid Build Coastguard Worker 
339*1c60b9acSAndroid Build Coastguard Worker 				_lws_ss_alloc_set_metadata(omd, polmd->name, cp,
340*1c60b9acSAndroid Build Coastguard Worker 							   (unsigned int)n);
341*1c60b9acSAndroid Build Coastguard Worker 
342*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
343*1c60b9acSAndroid Build Coastguard Worker 				/*
344*1c60b9acSAndroid Build Coastguard Worker 				 * ...and because we are doing it from parsing
345*1c60b9acSAndroid Build Coastguard Worker 				 * onward rx, we want to mark the metadata as
346*1c60b9acSAndroid Build Coastguard Worker 				 * needing passing to the client
347*1c60b9acSAndroid Build Coastguard Worker 				 */
348*1c60b9acSAndroid Build Coastguard Worker 				omd->pending_onward = 1;
349*1c60b9acSAndroid Build Coastguard Worker #endif
350*1c60b9acSAndroid Build Coastguard Worker 			}
351*1c60b9acSAndroid Build Coastguard Worker 		}
352*1c60b9acSAndroid Build Coastguard Worker 
353*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CUSTOM_HEADERS)
354*1c60b9acSAndroid Build Coastguard Worker 		else
355*1c60b9acSAndroid Build Coastguard Worker 
356*1c60b9acSAndroid Build Coastguard Worker 			/* has to have a non-empty header string */
357*1c60b9acSAndroid Build Coastguard Worker 
358*1c60b9acSAndroid Build Coastguard Worker 			if (polmd->value__may_own_heap &&
359*1c60b9acSAndroid Build Coastguard Worker 			    ((uint8_t *)polmd->value__may_own_heap)[0]) {
360*1c60b9acSAndroid Build Coastguard Worker 				char *p;
361*1c60b9acSAndroid Build Coastguard Worker 
362*1c60b9acSAndroid Build Coastguard Worker 				/*
363*1c60b9acSAndroid Build Coastguard Worker 				 * Can it be a custom header?
364*1c60b9acSAndroid Build Coastguard Worker 				 */
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 				n = lws_hdr_custom_length(wsi, (const char *)
367*1c60b9acSAndroid Build Coastguard Worker 						    polmd->value__may_own_heap,
368*1c60b9acSAndroid Build Coastguard Worker 						    polmd->value_length);
369*1c60b9acSAndroid Build Coastguard Worker 				if (n > 0) {
370*1c60b9acSAndroid Build Coastguard Worker 
371*1c60b9acSAndroid Build Coastguard Worker 					p = lws_malloc((unsigned int)n + 1, __func__);
372*1c60b9acSAndroid Build Coastguard Worker 					if (!p)
373*1c60b9acSAndroid Build Coastguard Worker 						return 1;
374*1c60b9acSAndroid Build Coastguard Worker 
375*1c60b9acSAndroid Build Coastguard Worker 					/* if needed, free any previous value */
376*1c60b9acSAndroid Build Coastguard Worker 
377*1c60b9acSAndroid Build Coastguard Worker 					if (polmd->value_on_lws_heap) {
378*1c60b9acSAndroid Build Coastguard Worker 						lws_free(
379*1c60b9acSAndroid Build Coastguard Worker 						    polmd->value__may_own_heap);
380*1c60b9acSAndroid Build Coastguard Worker 						polmd->value_on_lws_heap = 0;
381*1c60b9acSAndroid Build Coastguard Worker 					}
382*1c60b9acSAndroid Build Coastguard Worker 
383*1c60b9acSAndroid Build Coastguard Worker 					/*
384*1c60b9acSAndroid Build Coastguard Worker 					 * copy the named custom header value
385*1c60b9acSAndroid Build Coastguard Worker 					 * into the malloc'd buffer
386*1c60b9acSAndroid Build Coastguard Worker 					 */
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker 					if (lws_hdr_custom_copy(wsi, p, n + 1,
389*1c60b9acSAndroid Build Coastguard Worker 						     (const char *)
390*1c60b9acSAndroid Build Coastguard Worker 						     polmd->value__may_own_heap,
391*1c60b9acSAndroid Build Coastguard Worker 						     polmd->value_length) < 0) {
392*1c60b9acSAndroid Build Coastguard Worker 						lws_free(p);
393*1c60b9acSAndroid Build Coastguard Worker 
394*1c60b9acSAndroid Build Coastguard Worker 						return 1;
395*1c60b9acSAndroid Build Coastguard Worker 					}
396*1c60b9acSAndroid Build Coastguard Worker 
397*1c60b9acSAndroid Build Coastguard Worker 					omd = lws_ss_get_handle_metadata(h,
398*1c60b9acSAndroid Build Coastguard Worker 								   polmd->name);
399*1c60b9acSAndroid Build Coastguard Worker 					if (omd) {
400*1c60b9acSAndroid Build Coastguard Worker 
401*1c60b9acSAndroid Build Coastguard Worker 						_lws_ss_set_metadata(omd,
402*1c60b9acSAndroid Build Coastguard Worker 							polmd->name, p, (size_t)n);
403*1c60b9acSAndroid Build Coastguard Worker 						omd->value_on_lws_heap = 1;
404*1c60b9acSAndroid Build Coastguard Worker 
405*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
406*1c60b9acSAndroid Build Coastguard Worker 						omd->pending_onward = 1;
407*1c60b9acSAndroid Build Coastguard Worker #endif
408*1c60b9acSAndroid Build Coastguard Worker 					}
409*1c60b9acSAndroid Build Coastguard Worker 				}
410*1c60b9acSAndroid Build Coastguard Worker 			}
411*1c60b9acSAndroid Build Coastguard Worker #endif
412*1c60b9acSAndroid Build Coastguard Worker 
413*1c60b9acSAndroid Build Coastguard Worker 		m++;
414*1c60b9acSAndroid Build Coastguard Worker 		polmd = polmd->next;
415*1c60b9acSAndroid Build Coastguard Worker 	}
416*1c60b9acSAndroid Build Coastguard Worker 
417*1c60b9acSAndroid Build Coastguard Worker 	return 0;
418*1c60b9acSAndroid Build Coastguard Worker }
419*1c60b9acSAndroid Build Coastguard Worker 
420*1c60b9acSAndroid Build Coastguard Worker static const uint8_t blob_idx[] = {
421*1c60b9acSAndroid Build Coastguard Worker 	LWS_SYSBLOB_TYPE_AUTH,
422*1c60b9acSAndroid Build Coastguard Worker 	LWS_SYSBLOB_TYPE_DEVICE_SERIAL,
423*1c60b9acSAndroid Build Coastguard Worker 	LWS_SYSBLOB_TYPE_DEVICE_FW_VERSION,
424*1c60b9acSAndroid Build Coastguard Worker 	LWS_SYSBLOB_TYPE_DEVICE_TYPE,
425*1c60b9acSAndroid Build Coastguard Worker };
426*1c60b9acSAndroid Build Coastguard Worker 
427*1c60b9acSAndroid Build Coastguard Worker int
secstream_h1(struct lws * wsi,enum lws_callback_reasons reason,void * user,void * in,size_t len)428*1c60b9acSAndroid Build Coastguard Worker secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
429*1c60b9acSAndroid Build Coastguard Worker 	     void *in, size_t len)
430*1c60b9acSAndroid Build Coastguard Worker {
431*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
432*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
433*1c60b9acSAndroid Build Coastguard Worker #endif
434*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = (lws_ss_handle_t *)lws_get_opaque_user_data(wsi);
435*1c60b9acSAndroid Build Coastguard Worker 	uint8_t buf[LWS_PRE + 1520], *p = &buf[LWS_PRE],
436*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
437*1c60b9acSAndroid Build Coastguard Worker 			*start = p,
438*1c60b9acSAndroid Build Coastguard Worker #endif
439*1c60b9acSAndroid Build Coastguard Worker 		*end = &buf[sizeof(buf) - 1];
440*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
441*1c60b9acSAndroid Build Coastguard Worker 	int f = 0, m, status;
442*1c60b9acSAndroid Build Coastguard Worker 	char conceal_eom = 0;
443*1c60b9acSAndroid Build Coastguard Worker 	lws_usec_t inter;
444*1c60b9acSAndroid Build Coastguard Worker 	size_t buflen;
445*1c60b9acSAndroid Build Coastguard Worker 
446*1c60b9acSAndroid Build Coastguard Worker 	switch (reason) {
447*1c60b9acSAndroid Build Coastguard Worker 
448*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
449*1c60b9acSAndroid Build Coastguard Worker 		if (!h) {
450*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: CCE with no ss handle %s\n", __func__, lws_wsi_tag(wsi));
451*1c60b9acSAndroid Build Coastguard Worker 			break;
452*1c60b9acSAndroid Build Coastguard Worker 		}
453*1c60b9acSAndroid Build Coastguard Worker 
454*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_assert_extant(wsi->a.context, wsi->tsi, h);
455*1c60b9acSAndroid Build Coastguard Worker 
456*1c60b9acSAndroid Build Coastguard Worker 		assert(h->policy);
457*1c60b9acSAndroid Build Coastguard Worker 
458*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CONMON)
459*1c60b9acSAndroid Build Coastguard Worker 		lws_conmon_ss_json(h);
460*1c60b9acSAndroid Build Coastguard Worker #endif
461*1c60b9acSAndroid Build Coastguard Worker 
462*1c60b9acSAndroid Build Coastguard Worker 		lws_metrics_caliper_report_hist(h->cal_txn, wsi);
463*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: %s CLIENT_CONNECTION_ERROR: %s\n", __func__,
464*1c60b9acSAndroid Build Coastguard Worker 			  h->lc.gutag, in ? (const char *)in : "none");
465*1c60b9acSAndroid Build Coastguard Worker 		if (h->ss_dangling_connected) {
466*1c60b9acSAndroid Build Coastguard Worker 			/* already disconnected, no action for DISCONNECT_ME */
467*1c60b9acSAndroid Build Coastguard Worker 			r = lws_ss_event_helper(h, LWSSSCS_DISCONNECTED);
468*1c60b9acSAndroid Build Coastguard Worker 			if (r != LWSSSSRET_OK)
469*1c60b9acSAndroid Build Coastguard Worker 				return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
470*1c60b9acSAndroid Build Coastguard Worker 		}
471*1c60b9acSAndroid Build Coastguard Worker 		/* already disconnected, no action for DISCONNECT_ME */
472*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE);
473*1c60b9acSAndroid Build Coastguard Worker 		if (r) {
474*1c60b9acSAndroid Build Coastguard Worker 			if (h->inside_connect) {
475*1c60b9acSAndroid Build Coastguard Worker 				h->pending_ret = r;
476*1c60b9acSAndroid Build Coastguard Worker 				break;
477*1c60b9acSAndroid Build Coastguard Worker 			}
478*1c60b9acSAndroid Build Coastguard Worker 
479*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
480*1c60b9acSAndroid Build Coastguard Worker 		}
481*1c60b9acSAndroid Build Coastguard Worker 
482*1c60b9acSAndroid Build Coastguard Worker 		h->wsi = NULL;
483*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_backoff(h);
484*1c60b9acSAndroid Build Coastguard Worker 		if (r != LWSSSSRET_OK) {
485*1c60b9acSAndroid Build Coastguard Worker 			if (h->inside_connect) {
486*1c60b9acSAndroid Build Coastguard Worker 				h->pending_ret = r;
487*1c60b9acSAndroid Build Coastguard Worker 				break;
488*1c60b9acSAndroid Build Coastguard Worker 			}
489*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
490*1c60b9acSAndroid Build Coastguard Worker 		}
491*1c60b9acSAndroid Build Coastguard Worker 		break;
492*1c60b9acSAndroid Build Coastguard Worker 
493*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLIENT_HTTP_REDIRECT:
494*1c60b9acSAndroid Build Coastguard Worker 
495*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
496*1c60b9acSAndroid Build Coastguard Worker 			return -1;
497*1c60b9acSAndroid Build Coastguard Worker 
498*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->u.http.fail_redirect)
499*1c60b9acSAndroid Build Coastguard Worker 			lws_system_cpd_set(lws_get_context(wsi),
500*1c60b9acSAndroid Build Coastguard Worker 					   LWS_CPD_CAPTIVE_PORTAL);
501*1c60b9acSAndroid Build Coastguard Worker 		/* unless it's explicitly allowed, reject to follow it */
502*1c60b9acSAndroid Build Coastguard Worker 		return !(h->policy->flags & LWSSSPOLF_ALLOW_REDIRECTS);
503*1c60b9acSAndroid Build Coastguard Worker 
504*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLOSED_HTTP: /* server */
505*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLOSED_CLIENT_HTTP:
506*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
507*1c60b9acSAndroid Build Coastguard Worker 			break;
508*1c60b9acSAndroid Build Coastguard Worker 
509*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&h->sul_timeout);
510*1c60b9acSAndroid Build Coastguard Worker 
511*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_assert_extant(wsi->a.context, wsi->tsi, h);
512*1c60b9acSAndroid Build Coastguard Worker 
513*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CONMON)
514*1c60b9acSAndroid Build Coastguard Worker 		if (wsi->conmon.pcol == LWSCONMON_PCOL_NONE) {
515*1c60b9acSAndroid Build Coastguard Worker 			wsi->conmon.pcol = LWSCONMON_PCOL_HTTP;
516*1c60b9acSAndroid Build Coastguard Worker 			wsi->conmon.protocol_specific.http.response =
517*1c60b9acSAndroid Build Coastguard Worker 					(int)lws_http_client_http_response(wsi);
518*1c60b9acSAndroid Build Coastguard Worker 		}
519*1c60b9acSAndroid Build Coastguard Worker 
520*1c60b9acSAndroid Build Coastguard Worker 		lws_conmon_ss_json(h);
521*1c60b9acSAndroid Build Coastguard Worker #endif
522*1c60b9acSAndroid Build Coastguard Worker 
523*1c60b9acSAndroid Build Coastguard Worker 		lws_metrics_caliper_report_hist(h->cal_txn, wsi);
524*1c60b9acSAndroid Build Coastguard Worker 		//lwsl_notice("%s: %s LWS_CALLBACK_CLOSED_CLIENT_HTTP\n",
525*1c60b9acSAndroid Build Coastguard Worker 		//		__func__, wsi->lc.gutag);
526*1c60b9acSAndroid Build Coastguard Worker 
527*1c60b9acSAndroid Build Coastguard Worker 		h->wsi = NULL;
528*1c60b9acSAndroid Build Coastguard Worker 		h->hanging_som = 0;
529*1c60b9acSAndroid Build Coastguard Worker 		h->subseq = 0;
530*1c60b9acSAndroid Build Coastguard Worker 
531*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
532*1c60b9acSAndroid Build Coastguard Worker 		lws_pt_lock(pt, __func__);
533*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_remove(&h->cli_list);
534*1c60b9acSAndroid Build Coastguard Worker 		lws_pt_unlock(pt);
535*1c60b9acSAndroid Build Coastguard Worker #endif
536*1c60b9acSAndroid Build Coastguard Worker 
537*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) &&
538*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
539*1c60b9acSAndroid Build Coastguard Worker 		    !(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not server */
540*1c60b9acSAndroid Build Coastguard Worker #endif
541*1c60b9acSAndroid Build Coastguard Worker 		    !h->txn_ok && !wsi->a.context->being_destroyed) {
542*1c60b9acSAndroid Build Coastguard Worker 			r = lws_ss_backoff(h);
543*1c60b9acSAndroid Build Coastguard Worker 			if (r != LWSSSSRET_OK)
544*1c60b9acSAndroid Build Coastguard Worker 				return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
545*1c60b9acSAndroid Build Coastguard Worker 			break;
546*1c60b9acSAndroid Build Coastguard Worker 		} else
547*1c60b9acSAndroid Build Coastguard Worker 			h->seqstate = SSSEQ_IDLE;
548*1c60b9acSAndroid Build Coastguard Worker 
549*1c60b9acSAndroid Build Coastguard Worker 		if (h->ss_dangling_connected) {
550*1c60b9acSAndroid Build Coastguard Worker 			/* already disconnected, no action for DISCONNECT_ME */
551*1c60b9acSAndroid Build Coastguard Worker 			r = lws_ss_event_helper(h, LWSSSCS_DISCONNECTED);
552*1c60b9acSAndroid Build Coastguard Worker 			if (r != LWSSSSRET_OK)
553*1c60b9acSAndroid Build Coastguard Worker 				return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
554*1c60b9acSAndroid Build Coastguard Worker 		}
555*1c60b9acSAndroid Build Coastguard Worker 		break;
556*1c60b9acSAndroid Build Coastguard Worker 
557*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP:
558*1c60b9acSAndroid Build Coastguard Worker 
559*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
560*1c60b9acSAndroid Build Coastguard Worker 			return -1;
561*1c60b9acSAndroid Build Coastguard Worker 
562*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_assert_extant(wsi->a.context, wsi->tsi, h);
563*1c60b9acSAndroid Build Coastguard Worker 
564*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CONMON)
565*1c60b9acSAndroid Build Coastguard Worker 		if (wsi->conmon.pcol == LWSCONMON_PCOL_NONE) {
566*1c60b9acSAndroid Build Coastguard Worker 			wsi->conmon.pcol = LWSCONMON_PCOL_HTTP;
567*1c60b9acSAndroid Build Coastguard Worker 			wsi->conmon.protocol_specific.http.response =
568*1c60b9acSAndroid Build Coastguard Worker 					(int)lws_http_client_http_response(wsi);
569*1c60b9acSAndroid Build Coastguard Worker 		}
570*1c60b9acSAndroid Build Coastguard Worker 
571*1c60b9acSAndroid Build Coastguard Worker 		lws_conmon_ss_json(h);
572*1c60b9acSAndroid Build Coastguard Worker #endif
573*1c60b9acSAndroid Build Coastguard Worker 
574*1c60b9acSAndroid Build Coastguard Worker 		status = (int)lws_http_client_http_response(wsi);
575*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: %d\n", __func__, status);
576*1c60b9acSAndroid Build Coastguard Worker 	//	if (!status)
577*1c60b9acSAndroid Build Coastguard Worker 			/* it's just telling use we connected / joined the nwsi */
578*1c60b9acSAndroid Build Coastguard Worker 	//		break;
579*1c60b9acSAndroid Build Coastguard Worker 
580*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
581*1c60b9acSAndroid Build Coastguard Worker 		if (status) {
582*1c60b9acSAndroid Build Coastguard Worker 			lws_snprintf((char *)buf, 10, "%d", status);
583*1c60b9acSAndroid Build Coastguard Worker 			lws_metrics_tag_ss_add(h, "http_resp", (char *)buf);
584*1c60b9acSAndroid Build Coastguard Worker 		}
585*1c60b9acSAndroid Build Coastguard Worker #endif
586*1c60b9acSAndroid Build Coastguard Worker 
587*1c60b9acSAndroid Build Coastguard Worker 		if (status == HTTP_STATUS_SERVICE_UNAVAILABLE /* 503 */ ||
588*1c60b9acSAndroid Build Coastguard Worker 		    status == 429 /* Too many requests */) {
589*1c60b9acSAndroid Build Coastguard Worker 			/*
590*1c60b9acSAndroid Build Coastguard Worker 			 * We understand this attempt failed, and that we should
591*1c60b9acSAndroid Build Coastguard Worker 			 * conceal this attempt.  If there's a specified
592*1c60b9acSAndroid Build Coastguard Worker 			 * retry-after, we should use that if larger than our
593*1c60b9acSAndroid Build Coastguard Worker 			 * computed backoff
594*1c60b9acSAndroid Build Coastguard Worker 			 */
595*1c60b9acSAndroid Build Coastguard Worker 
596*1c60b9acSAndroid Build Coastguard Worker 			inter = 0;
597*1c60b9acSAndroid Build Coastguard Worker 			lws_http_check_retry_after(wsi, &inter);
598*1c60b9acSAndroid Build Coastguard Worker 
599*1c60b9acSAndroid Build Coastguard Worker 			r = _lws_ss_backoff(h, inter);
600*1c60b9acSAndroid Build Coastguard Worker 			if (r != LWSSSSRET_OK)
601*1c60b9acSAndroid Build Coastguard Worker 				return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
602*1c60b9acSAndroid Build Coastguard Worker 
603*1c60b9acSAndroid Build Coastguard Worker 			return -1; /* end this stream */
604*1c60b9acSAndroid Build Coastguard Worker 		}
605*1c60b9acSAndroid Build Coastguard Worker 
606*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->u.http.resp_expect)
607*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.good_respcode =
608*1c60b9acSAndroid Build Coastguard Worker 					status == h->policy->u.http.resp_expect;
609*1c60b9acSAndroid Build Coastguard Worker 		else
610*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.good_respcode = (status >= 200 && status < 300);
611*1c60b9acSAndroid Build Coastguard Worker 		// lwsl_err("%s: good resp %d %d\n", __func__, status, h->u.http.good_respcode);
612*1c60b9acSAndroid Build Coastguard Worker 
613*1c60b9acSAndroid Build Coastguard Worker 		if (lws_extract_metadata(h, wsi)) {
614*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: rx metadata extract failed\n", __func__);
615*1c60b9acSAndroid Build Coastguard Worker 
616*1c60b9acSAndroid Build Coastguard Worker 			return -1;
617*1c60b9acSAndroid Build Coastguard Worker 		}
618*1c60b9acSAndroid Build Coastguard Worker 
619*1c60b9acSAndroid Build Coastguard Worker 		if (status) {
620*1c60b9acSAndroid Build Coastguard Worker 			/*
621*1c60b9acSAndroid Build Coastguard Worker 			 * Check and see if it's something from the response
622*1c60b9acSAndroid Build Coastguard Worker 			 * map, if so, generate the requested status.  If we're
623*1c60b9acSAndroid Build Coastguard Worker 			 * the proxy onward connection, metadata has priority
624*1c60b9acSAndroid Build Coastguard Worker 			 * over state updates on the serialization, so the
625*1c60b9acSAndroid Build Coastguard Worker 			 * state callback will see the right metadata.
626*1c60b9acSAndroid Build Coastguard Worker 			 */
627*1c60b9acSAndroid Build Coastguard Worker 			int n = lws_ss_http_resp_to_state(h, status);
628*1c60b9acSAndroid Build Coastguard Worker 			if (n) {
629*1c60b9acSAndroid Build Coastguard Worker 				r = lws_ss_event_helper(h, (lws_ss_constate_t)n);
630*1c60b9acSAndroid Build Coastguard Worker 				if (r != LWSSSSRET_OK)
631*1c60b9acSAndroid Build Coastguard Worker 					return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi,
632*1c60b9acSAndroid Build Coastguard Worker 									&h);
633*1c60b9acSAndroid Build Coastguard Worker 			}
634*1c60b9acSAndroid Build Coastguard Worker 		}
635*1c60b9acSAndroid Build Coastguard Worker 
636*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.http.good_respcode)
637*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: Connected streamtype %s, %d\n", __func__,
638*1c60b9acSAndroid Build Coastguard Worker 				  h->policy->streamtype, status);
639*1c60b9acSAndroid Build Coastguard Worker 		else
640*1c60b9acSAndroid Build Coastguard Worker 			if (h->u.http.good_respcode)
641*1c60b9acSAndroid Build Coastguard Worker 				lwsl_warn("%s: Connected streamtype %s, BAD %d\n",
642*1c60b9acSAndroid Build Coastguard Worker 					  __func__, h->policy->streamtype,
643*1c60b9acSAndroid Build Coastguard Worker 					  status);
644*1c60b9acSAndroid Build Coastguard Worker 
645*1c60b9acSAndroid Build Coastguard Worker 		h->hanging_som = 0;
646*1c60b9acSAndroid Build Coastguard Worker 
647*1c60b9acSAndroid Build Coastguard Worker 		h->retry = 0;
648*1c60b9acSAndroid Build Coastguard Worker 		h->seqstate = SSSEQ_CONNECTED;
649*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&h->sul);
650*1c60b9acSAndroid Build Coastguard Worker 
651*1c60b9acSAndroid Build Coastguard Worker 		if (h->prev_ss_state != LWSSSCS_CONNECTED) {
652*1c60b9acSAndroid Build Coastguard Worker 			wsi->client_suppress_CONNECTION_ERROR = 1;
653*1c60b9acSAndroid Build Coastguard Worker 			if (h->prev_ss_state != LWSSSCS_CONNECTED) {
654*1c60b9acSAndroid Build Coastguard Worker 				r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
655*1c60b9acSAndroid Build Coastguard Worker 				if (r != LWSSSSRET_OK)
656*1c60b9acSAndroid Build Coastguard Worker 					return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
657*1c60b9acSAndroid Build Coastguard Worker 			}
658*1c60b9acSAndroid Build Coastguard Worker 		}
659*1c60b9acSAndroid Build Coastguard Worker 
660*1c60b9acSAndroid Build Coastguard Worker 		/*
661*1c60b9acSAndroid Build Coastguard Worker 		 * Since it's an http transaction we initiated... this is
662*1c60b9acSAndroid Build Coastguard Worker 		 * proof of connection validity
663*1c60b9acSAndroid Build Coastguard Worker 		 */
664*1c60b9acSAndroid Build Coastguard Worker 		lws_validity_confirmed(wsi);
665*1c60b9acSAndroid Build Coastguard Worker 
666*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
667*1c60b9acSAndroid Build Coastguard Worker 
668*1c60b9acSAndroid Build Coastguard Worker 		/*
669*1c60b9acSAndroid Build Coastguard Worker 		 * There are two ways we might want to deal with multipart,
670*1c60b9acSAndroid Build Coastguard Worker 		 * one is pass it through raw (although the user code needs
671*1c60b9acSAndroid Build Coastguard Worker 		 * a helping hand for learning the boundary), and the other
672*1c60b9acSAndroid Build Coastguard Worker 		 * is to deframe it and provide basically submessages in the
673*1c60b9acSAndroid Build Coastguard Worker 		 * different parts.
674*1c60b9acSAndroid Build Coastguard Worker 		 */
675*1c60b9acSAndroid Build Coastguard Worker 
676*1c60b9acSAndroid Build Coastguard Worker 		if (lws_hdr_copy(wsi, (char *)buf, sizeof(buf),
677*1c60b9acSAndroid Build Coastguard Worker 				 WSI_TOKEN_HTTP_CONTENT_TYPE) > 0 &&
678*1c60b9acSAndroid Build Coastguard Worker 		/* multipart/form-data;
679*1c60b9acSAndroid Build Coastguard Worker 		 * boundary=----WebKitFormBoundarycc7YgAPEIHvgE9Bf */
680*1c60b9acSAndroid Build Coastguard Worker 
681*1c60b9acSAndroid Build Coastguard Worker 		    (!strncmp((char *)buf, "multipart/form-data", 19) ||
682*1c60b9acSAndroid Build Coastguard Worker 		     !strncmp((char *)buf, "multipart/related", 17))) {
683*1c60b9acSAndroid Build Coastguard Worker 			struct lws_tokenize ts;
684*1c60b9acSAndroid Build Coastguard Worker 			lws_tokenize_elem e;
685*1c60b9acSAndroid Build Coastguard Worker 
686*1c60b9acSAndroid Build Coastguard Worker 			// puts((const char *)buf);
687*1c60b9acSAndroid Build Coastguard Worker 
688*1c60b9acSAndroid Build Coastguard Worker 			memset(&ts, 0, sizeof(ts));
689*1c60b9acSAndroid Build Coastguard Worker 			ts.start = (char *)buf;
690*1c60b9acSAndroid Build Coastguard Worker 			ts.len = strlen(ts.start);
691*1c60b9acSAndroid Build Coastguard Worker 			ts.flags = LWS_TOKENIZE_F_RFC7230_DELIMS |
692*1c60b9acSAndroid Build Coastguard Worker 					LWS_TOKENIZE_F_SLASH_NONTERM |
693*1c60b9acSAndroid Build Coastguard Worker 					LWS_TOKENIZE_F_MINUS_NONTERM;
694*1c60b9acSAndroid Build Coastguard Worker 
695*1c60b9acSAndroid Build Coastguard Worker 			h->u.http.boundary[0] = '\0';
696*1c60b9acSAndroid Build Coastguard Worker 			do {
697*1c60b9acSAndroid Build Coastguard Worker 				e = lws_tokenize(&ts);
698*1c60b9acSAndroid Build Coastguard Worker 				if (e == LWS_TOKZE_TOKEN_NAME_EQUALS &&
699*1c60b9acSAndroid Build Coastguard Worker 				    !strncmp(ts.token, "boundary", 8) &&
700*1c60b9acSAndroid Build Coastguard Worker 				    ts.token_len == 8) {
701*1c60b9acSAndroid Build Coastguard Worker 					e = lws_tokenize(&ts);
702*1c60b9acSAndroid Build Coastguard Worker 					if (e != LWS_TOKZE_TOKEN)
703*1c60b9acSAndroid Build Coastguard Worker 						goto malformed;
704*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary[0] = '\x0d';
705*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary[1] = '\x0a';
706*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary[2] = '-';
707*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary[3] = '-';
708*1c60b9acSAndroid Build Coastguard Worker 					lws_strnncpy(h->u.http.boundary + 4,
709*1c60b9acSAndroid Build Coastguard Worker 						     ts.token, ts.token_len,
710*1c60b9acSAndroid Build Coastguard Worker 						     sizeof(h->u.http.boundary) - 4);
711*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary_len =
712*1c60b9acSAndroid Build Coastguard Worker 						(uint8_t)(ts.token_len + 4);
713*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary_seq = 2;
714*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary_dashes = 0;
715*1c60b9acSAndroid Build Coastguard Worker 				}
716*1c60b9acSAndroid Build Coastguard Worker 			} while (e > 0);
717*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: multipart boundary '%s' len %d\n", __func__,
718*1c60b9acSAndroid Build Coastguard Worker 					h->u.http.boundary, h->u.http.boundary_len);
719*1c60b9acSAndroid Build Coastguard Worker 
720*1c60b9acSAndroid Build Coastguard Worker 			/* inform the ss that a related message group begins */
721*1c60b9acSAndroid Build Coastguard Worker 
722*1c60b9acSAndroid Build Coastguard Worker 			if ((h->policy->flags & LWSSSPOLF_HTTP_MULTIPART_IN) &&
723*1c60b9acSAndroid Build Coastguard Worker 			    h->u.http.boundary[0])
724*1c60b9acSAndroid Build Coastguard Worker 				h->info.rx(ss_to_userobj(h), NULL, 0,
725*1c60b9acSAndroid Build Coastguard Worker 					   LWSSS_FLAG_RELATED_START);
726*1c60b9acSAndroid Build Coastguard Worker 
727*1c60b9acSAndroid Build Coastguard Worker 			// lws_header_table_detach(wsi, 0);
728*1c60b9acSAndroid Build Coastguard Worker 		}
729*1c60b9acSAndroid Build Coastguard Worker 		break;
730*1c60b9acSAndroid Build Coastguard Worker malformed:
731*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: malformed multipart header\n", __func__);
732*1c60b9acSAndroid Build Coastguard Worker 		return -1;
733*1c60b9acSAndroid Build Coastguard Worker #else
734*1c60b9acSAndroid Build Coastguard Worker 		break;
735*1c60b9acSAndroid Build Coastguard Worker #endif
736*1c60b9acSAndroid Build Coastguard Worker 
737*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
738*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
739*1c60b9acSAndroid Build Coastguard Worker 			return -1;
740*1c60b9acSAndroid Build Coastguard Worker 		if (h->writeable_len)
741*1c60b9acSAndroid Build Coastguard Worker 			wsi->http.writeable_len = h->writeable_len;
742*1c60b9acSAndroid Build Coastguard Worker 
743*1c60b9acSAndroid Build Coastguard Worker 		{
744*1c60b9acSAndroid Build Coastguard Worker 			uint8_t **p = (uint8_t **)in, *end = (*p) + len,
745*1c60b9acSAndroid Build Coastguard Worker 				*oin = *(uint8_t **)in;
746*1c60b9acSAndroid Build Coastguard Worker 
747*1c60b9acSAndroid Build Coastguard Worker 		/*
748*1c60b9acSAndroid Build Coastguard Worker 		 * blob-based headers
749*1c60b9acSAndroid Build Coastguard Worker 		 */
750*1c60b9acSAndroid Build Coastguard Worker 
751*1c60b9acSAndroid Build Coastguard Worker 		for (m = 0; m < _LWSSS_HBI_COUNT; m++) {
752*1c60b9acSAndroid Build Coastguard Worker 			lws_system_blob_t *ab;
753*1c60b9acSAndroid Build Coastguard Worker 			int o = 0, n;
754*1c60b9acSAndroid Build Coastguard Worker 
755*1c60b9acSAndroid Build Coastguard Worker 			if (!h->policy->u.http.blob_header[m])
756*1c60b9acSAndroid Build Coastguard Worker 				continue;
757*1c60b9acSAndroid Build Coastguard Worker 
758*1c60b9acSAndroid Build Coastguard Worker 			/*
759*1c60b9acSAndroid Build Coastguard Worker 			 * To be backward compatible, default is system-wide LWA auth,
760*1c60b9acSAndroid Build Coastguard Worker 			 * and "http_auth_header" is for default LWA auth, current users do not
761*1c60b9acSAndroid Build Coastguard Worker 			 * need any change in their policy.
762*1c60b9acSAndroid Build Coastguard Worker 			 * If user wants different auth/token, need to specify the "use_auth"
763*1c60b9acSAndroid Build Coastguard Worker 			 * and will be handled after metadata headers are applied.
764*1c60b9acSAndroid Build Coastguard Worker 			 */
765*1c60b9acSAndroid Build Coastguard Worker 
766*1c60b9acSAndroid Build Coastguard Worker 			if (m == LWSSS_HBI_AUTH &&
767*1c60b9acSAndroid Build Coastguard Worker 			    h->policy->u.http.auth_preamble)
768*1c60b9acSAndroid Build Coastguard Worker 				o = lws_snprintf((char *)buf, sizeof(buf), "%s",
769*1c60b9acSAndroid Build Coastguard Worker 					h->policy->u.http.auth_preamble);
770*1c60b9acSAndroid Build Coastguard Worker 
771*1c60b9acSAndroid Build Coastguard Worker 			if (o > (int)sizeof(buf) - 2)
772*1c60b9acSAndroid Build Coastguard Worker 				return -1;
773*1c60b9acSAndroid Build Coastguard Worker 
774*1c60b9acSAndroid Build Coastguard Worker 			ab = lws_system_get_blob(wsi->a.context, blob_idx[m], 0);
775*1c60b9acSAndroid Build Coastguard Worker 			if (!ab)
776*1c60b9acSAndroid Build Coastguard Worker 				return -1;
777*1c60b9acSAndroid Build Coastguard Worker 
778*1c60b9acSAndroid Build Coastguard Worker 			buflen = sizeof(buf) - (unsigned int)o - 2u;
779*1c60b9acSAndroid Build Coastguard Worker 			n = lws_system_blob_get(ab, buf + o, &buflen, 0);
780*1c60b9acSAndroid Build Coastguard Worker 			if (n < 0)
781*1c60b9acSAndroid Build Coastguard Worker 				return -1;
782*1c60b9acSAndroid Build Coastguard Worker 
783*1c60b9acSAndroid Build Coastguard Worker 			buf[(unsigned int)o + buflen] = '\0';
784*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: adding blob %d: %s\n", __func__, m, buf);
785*1c60b9acSAndroid Build Coastguard Worker 
786*1c60b9acSAndroid Build Coastguard Worker 			if (lws_add_http_header_by_name(wsi,
787*1c60b9acSAndroid Build Coastguard Worker 				 (uint8_t *)h->policy->u.http.blob_header[m],
788*1c60b9acSAndroid Build Coastguard Worker 				 buf, (int)((int)buflen + o), p, end))
789*1c60b9acSAndroid Build Coastguard Worker 				return -1;
790*1c60b9acSAndroid Build Coastguard Worker 		}
791*1c60b9acSAndroid Build Coastguard Worker 
792*1c60b9acSAndroid Build Coastguard Worker 		/*
793*1c60b9acSAndroid Build Coastguard Worker 		 * metadata-based headers
794*1c60b9acSAndroid Build Coastguard Worker 		 */
795*1c60b9acSAndroid Build Coastguard Worker 
796*1c60b9acSAndroid Build Coastguard Worker 		if (lws_apply_metadata(h, wsi, buf, p, end))
797*1c60b9acSAndroid Build Coastguard Worker 			return -1;
798*1c60b9acSAndroid Build Coastguard Worker 
799*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
800*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->flags & LWSSSPOLF_DIRECT_PROTO_STR) {
801*1c60b9acSAndroid Build Coastguard Worker 			if (lws_apply_instant_metadata(h, wsi, buf, p, end))
802*1c60b9acSAndroid Build Coastguard Worker 				return -1;
803*1c60b9acSAndroid Build Coastguard Worker 		}
804*1c60b9acSAndroid Build Coastguard Worker #endif
805*1c60b9acSAndroid Build Coastguard Worker 
806*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
807*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->auth && h->policy->auth->type &&
808*1c60b9acSAndroid Build Coastguard Worker 				!strcmp(h->policy->auth->type, "sigv4")) {
809*1c60b9acSAndroid Build Coastguard Worker 
810*1c60b9acSAndroid Build Coastguard Worker 			if (lws_ss_apply_sigv4(wsi, h, p, end))
811*1c60b9acSAndroid Build Coastguard Worker 				return -1;
812*1c60b9acSAndroid Build Coastguard Worker 		}
813*1c60b9acSAndroid Build Coastguard Worker #endif
814*1c60b9acSAndroid Build Coastguard Worker 
815*1c60b9acSAndroid Build Coastguard Worker 
816*1c60b9acSAndroid Build Coastguard Worker 		(void)oin;
817*1c60b9acSAndroid Build Coastguard Worker 		//if (*p != oin)
818*1c60b9acSAndroid Build Coastguard Worker 		//	lwsl_hexdump_notice(oin, lws_ptr_diff_size_t(*p, oin));
819*1c60b9acSAndroid Build Coastguard Worker 
820*1c60b9acSAndroid Build Coastguard Worker 		}
821*1c60b9acSAndroid Build Coastguard Worker 
822*1c60b9acSAndroid Build Coastguard Worker 		/*
823*1c60b9acSAndroid Build Coastguard Worker 		 * So when proxied, for POST we have to synthesize a CONNECTED
824*1c60b9acSAndroid Build Coastguard Worker 		 * state, so it can request a writeable and deliver the POST
825*1c60b9acSAndroid Build Coastguard Worker 		 * body
826*1c60b9acSAndroid Build Coastguard Worker 		 */
827*1c60b9acSAndroid Build Coastguard Worker 		if ((h->policy->protocol == LWSSSP_H1 ||
828*1c60b9acSAndroid Build Coastguard Worker 		     h->policy->protocol == LWSSSP_H2) &&
829*1c60b9acSAndroid Build Coastguard Worker 		     h->being_serialized && (
830*1c60b9acSAndroid Build Coastguard Worker 				!strcmp(h->policy->u.http.method, "PUT") ||
831*1c60b9acSAndroid Build Coastguard Worker 				!strcmp(h->policy->u.http.method, "POST"))) {
832*1c60b9acSAndroid Build Coastguard Worker 
833*1c60b9acSAndroid Build Coastguard Worker 			wsi->client_suppress_CONNECTION_ERROR = 1;
834*1c60b9acSAndroid Build Coastguard Worker 			if (h->prev_ss_state != LWSSSCS_CONNECTED) {
835*1c60b9acSAndroid Build Coastguard Worker 				r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
836*1c60b9acSAndroid Build Coastguard Worker 				if (r)
837*1c60b9acSAndroid Build Coastguard Worker 					return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
838*1c60b9acSAndroid Build Coastguard Worker 			}
839*1c60b9acSAndroid Build Coastguard Worker 		}
840*1c60b9acSAndroid Build Coastguard Worker 
841*1c60b9acSAndroid Build Coastguard Worker 		break;
842*1c60b9acSAndroid Build Coastguard Worker 
843*1c60b9acSAndroid Build Coastguard Worker 	/* chunks of chunked content, with header removed */
844*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_HTTP_BODY:
845*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
846*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: RECEIVE_CLIENT_HTTP_READ: read %d\n",
847*1c60b9acSAndroid Build Coastguard Worker 				__func__, (int)len);
848*1c60b9acSAndroid Build Coastguard Worker 		if (!h || !h->info.rx)
849*1c60b9acSAndroid Build Coastguard Worker 			return 0;
850*1c60b9acSAndroid Build Coastguard Worker 
851*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
852*1c60b9acSAndroid Build Coastguard Worker 		if ((h->policy->flags & LWSSSPOLF_HTTP_MULTIPART_IN) &&
853*1c60b9acSAndroid Build Coastguard Worker 		    h->u.http.boundary[0])
854*1c60b9acSAndroid Build Coastguard Worker 			return ss_http_multipart_parser(h, in, len);
855*1c60b9acSAndroid Build Coastguard Worker #endif
856*1c60b9acSAndroid Build Coastguard Worker 
857*1c60b9acSAndroid Build Coastguard Worker 		if (!h->subseq) {
858*1c60b9acSAndroid Build Coastguard Worker 			f |= LWSSS_FLAG_SOM;
859*1c60b9acSAndroid Build Coastguard Worker 			h->hanging_som = 1;
860*1c60b9acSAndroid Build Coastguard Worker 			h->subseq = 1;
861*1c60b9acSAndroid Build Coastguard Worker 		}
862*1c60b9acSAndroid Build Coastguard Worker 
863*1c60b9acSAndroid Build Coastguard Worker 	//	lwsl_notice("%s: HTTP_READ: client side sent len %d fl 0x%x\n",
864*1c60b9acSAndroid Build Coastguard Worker 	//		    __func__, (int)len, (int)f);
865*1c60b9acSAndroid Build Coastguard Worker 
866*1c60b9acSAndroid Build Coastguard Worker 		r = h->info.rx(ss_to_userobj(h), (const uint8_t *)in, len, f);
867*1c60b9acSAndroid Build Coastguard Worker 		if (r != LWSSSSRET_OK)
868*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
869*1c60b9acSAndroid Build Coastguard Worker 
870*1c60b9acSAndroid Build Coastguard Worker 		return 0; /* don't passthru */
871*1c60b9acSAndroid Build Coastguard Worker 
872*1c60b9acSAndroid Build Coastguard Worker 	/* uninterpreted http content */
873*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
874*1c60b9acSAndroid Build Coastguard Worker 		{
875*1c60b9acSAndroid Build Coastguard Worker 			char *px = (char *)buf + LWS_PRE; /* guarantees LWS_PRE */
876*1c60b9acSAndroid Build Coastguard Worker 			int lenx = sizeof(buf) - LWS_PRE;
877*1c60b9acSAndroid Build Coastguard Worker 
878*1c60b9acSAndroid Build Coastguard Worker 			m = lws_http_client_read(wsi, &px, &lenx);
879*1c60b9acSAndroid Build Coastguard Worker 			if (m < 0)
880*1c60b9acSAndroid Build Coastguard Worker 				return m;
881*1c60b9acSAndroid Build Coastguard Worker 		}
882*1c60b9acSAndroid Build Coastguard Worker 		lws_set_timeout(wsi, 99, 30);
883*1c60b9acSAndroid Build Coastguard Worker 
884*1c60b9acSAndroid Build Coastguard Worker 		return 0; /* don't passthru */
885*1c60b9acSAndroid Build Coastguard Worker 
886*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
887*1c60b9acSAndroid Build Coastguard Worker 		// lwsl_debug("%s: LWS_CALLBACK_COMPLETED_CLIENT_HTTP\n", __func__);
888*1c60b9acSAndroid Build Coastguard Worker 
889*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
890*1c60b9acSAndroid Build Coastguard Worker 			return -1;
891*1c60b9acSAndroid Build Coastguard Worker 
892*1c60b9acSAndroid Build Coastguard Worker 		if (h->hanging_som) {
893*1c60b9acSAndroid Build Coastguard Worker 			h->info.rx(ss_to_userobj(h), NULL, 0, LWSSS_FLAG_EOM);
894*1c60b9acSAndroid Build Coastguard Worker 			h->hanging_som = 0;
895*1c60b9acSAndroid Build Coastguard Worker 			h->subseq = 0;
896*1c60b9acSAndroid Build Coastguard Worker 		}
897*1c60b9acSAndroid Build Coastguard Worker 
898*1c60b9acSAndroid Build Coastguard Worker 		wsi->http.writeable_len = h->writeable_len = 0;
899*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&h->sul_timeout);
900*1c60b9acSAndroid Build Coastguard Worker 
901*1c60b9acSAndroid Build Coastguard Worker 		h->txn_ok = 1;
902*1c60b9acSAndroid Build Coastguard Worker 
903*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
904*1c60b9acSAndroid Build Coastguard Worker 		lws_metrics_tag_ss_add(h, "result",
905*1c60b9acSAndroid Build Coastguard Worker 				       h->u.http.good_respcode ?
906*1c60b9acSAndroid Build Coastguard Worker 				       "SS_ACK_REMOTE" : "SS_NACK_REMOTE");
907*1c60b9acSAndroid Build Coastguard Worker #endif
908*1c60b9acSAndroid Build Coastguard Worker 
909*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, h->u.http.good_respcode ?
910*1c60b9acSAndroid Build Coastguard Worker 						LWSSSCS_QOS_ACK_REMOTE :
911*1c60b9acSAndroid Build Coastguard Worker 						LWSSSCS_QOS_NACK_REMOTE);
912*1c60b9acSAndroid Build Coastguard Worker 		if (r != LWSSSSRET_OK)
913*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
914*1c60b9acSAndroid Build Coastguard Worker 
915*1c60b9acSAndroid Build Coastguard Worker 		lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */
916*1c60b9acSAndroid Build Coastguard Worker 		break;
917*1c60b9acSAndroid Build Coastguard Worker 
918*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_HTTP_WRITEABLE:
919*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_CLIENT_HTTP_WRITEABLE:
920*1c60b9acSAndroid Build Coastguard Worker 
921*1c60b9acSAndroid Build Coastguard Worker 		if (!h || !h->info.tx) {
922*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: no handle / tx\n", __func__);
923*1c60b9acSAndroid Build Coastguard Worker 			return 0;
924*1c60b9acSAndroid Build Coastguard Worker 		}
925*1c60b9acSAndroid Build Coastguard Worker 
926*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
927*1c60b9acSAndroid Build Coastguard Worker 		if (h->txn_resp_pending) {
928*1c60b9acSAndroid Build Coastguard Worker 			/*
929*1c60b9acSAndroid Build Coastguard Worker 			 * If we're going to start sending something, we need to
930*1c60b9acSAndroid Build Coastguard Worker 			 * to take care of the http response header for it first
931*1c60b9acSAndroid Build Coastguard Worker 			 */
932*1c60b9acSAndroid Build Coastguard Worker 			h->txn_resp_pending = 0;
933*1c60b9acSAndroid Build Coastguard Worker 
934*1c60b9acSAndroid Build Coastguard Worker 			if (lws_add_http_common_headers(wsi,
935*1c60b9acSAndroid Build Coastguard Worker 					(unsigned int)(h->txn_resp_set ?
936*1c60b9acSAndroid Build Coastguard Worker 						(h->txn_resp ? h->txn_resp : 200) :
937*1c60b9acSAndroid Build Coastguard Worker 						HTTP_STATUS_NOT_FOUND),
938*1c60b9acSAndroid Build Coastguard Worker 					NULL, h->wsi->http.writeable_len,
939*1c60b9acSAndroid Build Coastguard Worker 					&p, end))
940*1c60b9acSAndroid Build Coastguard Worker 				return 1;
941*1c60b9acSAndroid Build Coastguard Worker 
942*1c60b9acSAndroid Build Coastguard Worker 			/*
943*1c60b9acSAndroid Build Coastguard Worker 			 * metadata-based headers
944*1c60b9acSAndroid Build Coastguard Worker 			 */
945*1c60b9acSAndroid Build Coastguard Worker 
946*1c60b9acSAndroid Build Coastguard Worker 			if (lws_apply_metadata(h, wsi, buf, &p, end))
947*1c60b9acSAndroid Build Coastguard Worker 				return -1;
948*1c60b9acSAndroid Build Coastguard Worker 
949*1c60b9acSAndroid Build Coastguard Worker 			if (lws_finalize_write_http_header(wsi, start, &p, end))
950*1c60b9acSAndroid Build Coastguard Worker 				return 1;
951*1c60b9acSAndroid Build Coastguard Worker 
952*1c60b9acSAndroid Build Coastguard Worker 			/* write the body separately */
953*1c60b9acSAndroid Build Coastguard Worker 			lws_callback_on_writable(wsi);
954*1c60b9acSAndroid Build Coastguard Worker 
955*1c60b9acSAndroid Build Coastguard Worker 			return 0;
956*1c60b9acSAndroid Build Coastguard Worker 		}
957*1c60b9acSAndroid Build Coastguard Worker #endif
958*1c60b9acSAndroid Build Coastguard Worker 
959*1c60b9acSAndroid Build Coastguard Worker 		if (
960*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
961*1c60b9acSAndroid Build Coastguard Worker 		    !(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not accepted */
962*1c60b9acSAndroid Build Coastguard Worker #endif
963*1c60b9acSAndroid Build Coastguard Worker 		    !h->rideshare)
964*1c60b9acSAndroid Build Coastguard Worker 
965*1c60b9acSAndroid Build Coastguard Worker 			h->rideshare = h->policy;
966*1c60b9acSAndroid Build Coastguard Worker 
967*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
968*1c60b9acSAndroid Build Coastguard Worker 		if (
969*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
970*1c60b9acSAndroid Build Coastguard Worker 		    !(h->info.flags & LWSSSINFLAGS_ACCEPTED) && /* not accepted */
971*1c60b9acSAndroid Build Coastguard Worker #endif
972*1c60b9acSAndroid Build Coastguard Worker 		    !h->inside_msg && h->rideshare->u.http.multipart_name)
973*1c60b9acSAndroid Build Coastguard Worker 			lws_client_http_multipart(wsi,
974*1c60b9acSAndroid Build Coastguard Worker 				h->rideshare->u.http.multipart_name,
975*1c60b9acSAndroid Build Coastguard Worker 				h->rideshare->u.http.multipart_filename,
976*1c60b9acSAndroid Build Coastguard Worker 				h->rideshare->u.http.multipart_content_type,
977*1c60b9acSAndroid Build Coastguard Worker 				(char **)&p, (char *)end);
978*1c60b9acSAndroid Build Coastguard Worker 
979*1c60b9acSAndroid Build Coastguard Worker 		buflen = lws_ptr_diff_size_t(end, p);
980*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->u.http.multipart_name)
981*1c60b9acSAndroid Build Coastguard Worker 			buflen -= 24; /* allow space for end of multipart */
982*1c60b9acSAndroid Build Coastguard Worker #else
983*1c60b9acSAndroid Build Coastguard Worker 		buflen = lws_ptr_diff_size_t(end, p);
984*1c60b9acSAndroid Build Coastguard Worker #endif
985*1c60b9acSAndroid Build Coastguard Worker 		r = h->info.tx(ss_to_userobj(h), h->txord++, p, &buflen, &f);
986*1c60b9acSAndroid Build Coastguard Worker 		if (r == LWSSSSRET_TX_DONT_SEND)
987*1c60b9acSAndroid Build Coastguard Worker 			return 0;
988*1c60b9acSAndroid Build Coastguard Worker 		if (r < 0)
989*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
990*1c60b9acSAndroid Build Coastguard Worker 
991*1c60b9acSAndroid Build Coastguard Worker 		// lwsl_notice("%s: WRITEABLE: user tx says len %d fl 0x%x\n",
992*1c60b9acSAndroid Build Coastguard Worker 		//	    __func__, (int)buflen, (int)f);
993*1c60b9acSAndroid Build Coastguard Worker 
994*1c60b9acSAndroid Build Coastguard Worker 		p += buflen;
995*1c60b9acSAndroid Build Coastguard Worker 
996*1c60b9acSAndroid Build Coastguard Worker 		if (f & LWSSS_FLAG_EOM) {
997*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
998*1c60b9acSAndroid Build Coastguard Worker 		    if (!(h->info.flags & LWSSSINFLAGS_ACCEPTED)) {
999*1c60b9acSAndroid Build Coastguard Worker #endif
1000*1c60b9acSAndroid Build Coastguard Worker 			conceal_eom = 1;
1001*1c60b9acSAndroid Build Coastguard Worker 			/* end of rideshares */
1002*1c60b9acSAndroid Build Coastguard Worker 			if (!h->rideshare->rideshare_streamtype) {
1003*1c60b9acSAndroid Build Coastguard Worker 				lws_client_http_body_pending(wsi, 0);
1004*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
1005*1c60b9acSAndroid Build Coastguard Worker 				if (h->rideshare->u.http.multipart_name)
1006*1c60b9acSAndroid Build Coastguard Worker 					lws_client_http_multipart(wsi, NULL, NULL, NULL,
1007*1c60b9acSAndroid Build Coastguard Worker 						(char **)&p, (char *)end);
1008*1c60b9acSAndroid Build Coastguard Worker 				conceal_eom = 0;
1009*1c60b9acSAndroid Build Coastguard Worker #endif
1010*1c60b9acSAndroid Build Coastguard Worker 			} else {
1011*1c60b9acSAndroid Build Coastguard Worker 				h->rideshare = lws_ss_policy_lookup(wsi->a.context,
1012*1c60b9acSAndroid Build Coastguard Worker 						h->rideshare->rideshare_streamtype);
1013*1c60b9acSAndroid Build Coastguard Worker 				lws_callback_on_writable(wsi);
1014*1c60b9acSAndroid Build Coastguard Worker 			}
1015*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1016*1c60b9acSAndroid Build Coastguard Worker 		    }
1017*1c60b9acSAndroid Build Coastguard Worker #endif
1018*1c60b9acSAndroid Build Coastguard Worker 
1019*1c60b9acSAndroid Build Coastguard Worker 			h->inside_msg = 0;
1020*1c60b9acSAndroid Build Coastguard Worker 		} else {
1021*1c60b9acSAndroid Build Coastguard Worker 			/* otherwise we can spin with zero length writes */
1022*1c60b9acSAndroid Build Coastguard Worker 			if (!f && !lws_ptr_diff(p, buf + LWS_PRE))
1023*1c60b9acSAndroid Build Coastguard Worker 				break;
1024*1c60b9acSAndroid Build Coastguard Worker 			h->inside_msg = 1;
1025*1c60b9acSAndroid Build Coastguard Worker 			lws_callback_on_writable(wsi);
1026*1c60b9acSAndroid Build Coastguard Worker 		}
1027*1c60b9acSAndroid Build Coastguard Worker 
1028*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: lws_write %d %d\n", __func__,
1029*1c60b9acSAndroid Build Coastguard Worker 			  lws_ptr_diff(p, buf + LWS_PRE), f);
1030*1c60b9acSAndroid Build Coastguard Worker 
1031*1c60b9acSAndroid Build Coastguard Worker 		if (lws_write(wsi, buf + LWS_PRE, lws_ptr_diff_size_t(p, buf + LWS_PRE),
1032*1c60b9acSAndroid Build Coastguard Worker 			 (!conceal_eom && (f & LWSSS_FLAG_EOM)) ?
1033*1c60b9acSAndroid Build Coastguard Worker 				    LWS_WRITE_HTTP_FINAL : LWS_WRITE_HTTP) !=
1034*1c60b9acSAndroid Build Coastguard Worker 				(int)lws_ptr_diff(p, buf + LWS_PRE)) {
1035*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: write failed\n", __func__);
1036*1c60b9acSAndroid Build Coastguard Worker 			return -1;
1037*1c60b9acSAndroid Build Coastguard Worker 		}
1038*1c60b9acSAndroid Build Coastguard Worker 
1039*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1040*1c60b9acSAndroid Build Coastguard Worker 		if ((h->info.flags & LWSSSINFLAGS_ACCEPTED) /* server */ &&
1041*1c60b9acSAndroid Build Coastguard Worker 		    (f & LWSSS_FLAG_EOM) &&
1042*1c60b9acSAndroid Build Coastguard Worker 		     lws_http_transaction_completed(wsi))
1043*1c60b9acSAndroid Build Coastguard Worker 			return -1;
1044*1c60b9acSAndroid Build Coastguard Worker #else
1045*1c60b9acSAndroid Build Coastguard Worker 		lws_set_timeout(wsi, 0, 0);
1046*1c60b9acSAndroid Build Coastguard Worker #endif
1047*1c60b9acSAndroid Build Coastguard Worker 		break;
1048*1c60b9acSAndroid Build Coastguard Worker 
1049*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1050*1c60b9acSAndroid Build Coastguard Worker 	case LWS_CALLBACK_HTTP:
1051*1c60b9acSAndroid Build Coastguard Worker 
1052*1c60b9acSAndroid Build Coastguard Worker 		if (!h)
1053*1c60b9acSAndroid Build Coastguard Worker 			return -1;
1054*1c60b9acSAndroid Build Coastguard Worker 
1055*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: LWS_CALLBACK_HTTP\n", __func__);
1056*1c60b9acSAndroid Build Coastguard Worker 		{
1057*1c60b9acSAndroid Build Coastguard Worker 
1058*1c60b9acSAndroid Build Coastguard Worker 			h->txn_resp_set = 0;
1059*1c60b9acSAndroid Build Coastguard Worker 			h->txn_resp_pending = 1;
1060*1c60b9acSAndroid Build Coastguard Worker 			h->writeable_len = 0;
1061*1c60b9acSAndroid Build Coastguard Worker 
1062*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H2)
1063*1c60b9acSAndroid Build Coastguard Worker 			m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
1064*1c60b9acSAndroid Build Coastguard Worker 			if (m) {
1065*1c60b9acSAndroid Build Coastguard Worker 				if (lws_ss_alloc_set_metadata(h, "method",
1066*1c60b9acSAndroid Build Coastguard Worker 						    lws_hdr_simple_ptr(wsi,
1067*1c60b9acSAndroid Build Coastguard Worker 						     WSI_TOKEN_HTTP_COLON_METHOD), (unsigned int)m))
1068*1c60b9acSAndroid Build Coastguard Worker 					return -1;
1069*1c60b9acSAndroid Build Coastguard Worker 				m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
1070*1c60b9acSAndroid Build Coastguard Worker 				if (m && lws_ss_alloc_set_metadata(h, "path",
1071*1c60b9acSAndroid Build Coastguard Worker 						    lws_hdr_simple_ptr(wsi,
1072*1c60b9acSAndroid Build Coastguard Worker 						     WSI_TOKEN_HTTP_COLON_PATH), (unsigned int)m))
1073*1c60b9acSAndroid Build Coastguard Worker 					return -1;
1074*1c60b9acSAndroid Build Coastguard Worker 			} else
1075*1c60b9acSAndroid Build Coastguard Worker #endif
1076*1c60b9acSAndroid Build Coastguard Worker 			{
1077*1c60b9acSAndroid Build Coastguard Worker 				m = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
1078*1c60b9acSAndroid Build Coastguard Worker 				if (m) {
1079*1c60b9acSAndroid Build Coastguard Worker 					if (lws_ss_alloc_set_metadata(h, "path",
1080*1c60b9acSAndroid Build Coastguard Worker 							lws_hdr_simple_ptr(wsi,
1081*1c60b9acSAndroid Build Coastguard Worker 								WSI_TOKEN_GET_URI), (unsigned int)m))
1082*1c60b9acSAndroid Build Coastguard Worker 						return -1;
1083*1c60b9acSAndroid Build Coastguard Worker 					if (lws_ss_alloc_set_metadata(h, "method", "GET", 3))
1084*1c60b9acSAndroid Build Coastguard Worker 						return -1;
1085*1c60b9acSAndroid Build Coastguard Worker 				} else {
1086*1c60b9acSAndroid Build Coastguard Worker 					m = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI);
1087*1c60b9acSAndroid Build Coastguard Worker 					if (m) {
1088*1c60b9acSAndroid Build Coastguard Worker 						if (lws_ss_alloc_set_metadata(h, "path",
1089*1c60b9acSAndroid Build Coastguard Worker 								lws_hdr_simple_ptr(wsi,
1090*1c60b9acSAndroid Build Coastguard Worker 									WSI_TOKEN_POST_URI), (unsigned int)m))
1091*1c60b9acSAndroid Build Coastguard Worker 							return -1;
1092*1c60b9acSAndroid Build Coastguard Worker 						if (lws_ss_alloc_set_metadata(h, "method", "POST", 4))
1093*1c60b9acSAndroid Build Coastguard Worker 							return -1;
1094*1c60b9acSAndroid Build Coastguard Worker 					}
1095*1c60b9acSAndroid Build Coastguard Worker 				}
1096*1c60b9acSAndroid Build Coastguard Worker 			}
1097*1c60b9acSAndroid Build Coastguard Worker 		}
1098*1c60b9acSAndroid Build Coastguard Worker 
1099*1c60b9acSAndroid Build Coastguard Worker 		if (!h->ss_dangling_connected) {
1100*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
1101*1c60b9acSAndroid Build Coastguard Worker 			/*
1102*1c60b9acSAndroid Build Coastguard Worker 			 * If any hanging caliper measurement, dump it, and free any tags
1103*1c60b9acSAndroid Build Coastguard Worker 			 */
1104*1c60b9acSAndroid Build Coastguard Worker 			lws_metrics_caliper_report_hist(h->cal_txn, (struct lws *)NULL);
1105*1c60b9acSAndroid Build Coastguard Worker #endif
1106*1c60b9acSAndroid Build Coastguard Worker 			wsi->client_suppress_CONNECTION_ERROR = 1;
1107*1c60b9acSAndroid Build Coastguard Worker 			if (h->prev_ss_state != LWSSSCS_CONNECTED) {
1108*1c60b9acSAndroid Build Coastguard Worker 				r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
1109*1c60b9acSAndroid Build Coastguard Worker 				if (r)
1110*1c60b9acSAndroid Build Coastguard Worker 					return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
1111*1c60b9acSAndroid Build Coastguard Worker 			}
1112*1c60b9acSAndroid Build Coastguard Worker 		}
1113*1c60b9acSAndroid Build Coastguard Worker 
1114*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, LWSSSCS_SERVER_TXN);
1115*1c60b9acSAndroid Build Coastguard Worker 		if (r)
1116*1c60b9acSAndroid Build Coastguard Worker 			return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r,
1117*1c60b9acSAndroid Build Coastguard Worker 								wsi, &h);
1118*1c60b9acSAndroid Build Coastguard Worker 
1119*1c60b9acSAndroid Build Coastguard Worker 		return 0;
1120*1c60b9acSAndroid Build Coastguard Worker #endif
1121*1c60b9acSAndroid Build Coastguard Worker 
1122*1c60b9acSAndroid Build Coastguard Worker 	default:
1123*1c60b9acSAndroid Build Coastguard Worker 		break;
1124*1c60b9acSAndroid Build Coastguard Worker 	}
1125*1c60b9acSAndroid Build Coastguard Worker 
1126*1c60b9acSAndroid Build Coastguard Worker 	return lws_callback_http_dummy(wsi, reason, user, in, len);
1127*1c60b9acSAndroid Build Coastguard Worker }
1128*1c60b9acSAndroid Build Coastguard Worker 
1129*1c60b9acSAndroid Build Coastguard Worker const struct lws_protocols protocol_secstream_h1 = {
1130*1c60b9acSAndroid Build Coastguard Worker 	"lws-secstream-h1",
1131*1c60b9acSAndroid Build Coastguard Worker 	secstream_h1,
1132*1c60b9acSAndroid Build Coastguard Worker 	0, 0, 0, NULL, 0
1133*1c60b9acSAndroid Build Coastguard Worker };
1134*1c60b9acSAndroid Build Coastguard Worker 
1135*1c60b9acSAndroid Build Coastguard Worker /*
1136*1c60b9acSAndroid Build Coastguard Worker  * Munge connect info according to protocol-specific considerations... this
1137*1c60b9acSAndroid Build Coastguard Worker  * usually means interpreting aux in a protocol-specific way and using the
1138*1c60b9acSAndroid Build Coastguard Worker  * pieces at connection setup time, eg, http url pieces.
1139*1c60b9acSAndroid Build Coastguard Worker  *
1140*1c60b9acSAndroid Build Coastguard Worker  * len bytes of buf can be used for things with scope until after the actual
1141*1c60b9acSAndroid Build Coastguard Worker  * connect.
1142*1c60b9acSAndroid Build Coastguard Worker  */
1143*1c60b9acSAndroid Build Coastguard Worker 
1144*1c60b9acSAndroid Build Coastguard Worker static int
secstream_connect_munge_h1(lws_ss_handle_t * h,char * buf,size_t len,struct lws_client_connect_info * i,union lws_ss_contemp * ct)1145*1c60b9acSAndroid Build Coastguard Worker secstream_connect_munge_h1(lws_ss_handle_t *h, char *buf, size_t len,
1146*1c60b9acSAndroid Build Coastguard Worker 			   struct lws_client_connect_info *i,
1147*1c60b9acSAndroid Build Coastguard Worker 			   union lws_ss_contemp *ct)
1148*1c60b9acSAndroid Build Coastguard Worker {
1149*1c60b9acSAndroid Build Coastguard Worker 	const char *pbasis = h->policy->u.http.url;
1150*1c60b9acSAndroid Build Coastguard Worker 	size_t used_in, used_out;
1151*1c60b9acSAndroid Build Coastguard Worker 	lws_strexp_t exp;
1152*1c60b9acSAndroid Build Coastguard Worker 
1153*1c60b9acSAndroid Build Coastguard Worker 	/* i.path on entry is used to override the policy urlpath if not "" */
1154*1c60b9acSAndroid Build Coastguard Worker 
1155*1c60b9acSAndroid Build Coastguard Worker 	if (i->path[0])
1156*1c60b9acSAndroid Build Coastguard Worker 		pbasis = i->path;
1157*1c60b9acSAndroid Build Coastguard Worker 
1158*1c60b9acSAndroid Build Coastguard Worker 	if (!pbasis)
1159*1c60b9acSAndroid Build Coastguard Worker 		return 0;
1160*1c60b9acSAndroid Build Coastguard Worker 
1161*1c60b9acSAndroid Build Coastguard Worker 	/* uncomment to force h1 */
1162*1c60b9acSAndroid Build Coastguard Worker 	// i->alpn = "http/1.1";
1163*1c60b9acSAndroid Build Coastguard Worker 
1164*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_RIDESHARE)
1165*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_HTTP_MULTIPART)
1166*1c60b9acSAndroid Build Coastguard Worker 		i->ssl_connection |= LCCSCF_HTTP_MULTIPART_MIME;
1167*1c60b9acSAndroid Build Coastguard Worker 
1168*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_HTTP_X_WWW_FORM_URLENCODED)
1169*1c60b9acSAndroid Build Coastguard Worker 		i->ssl_connection |= LCCSCF_HTTP_X_WWW_FORM_URLENCODED;
1170*1c60b9acSAndroid Build Coastguard Worker #endif
1171*1c60b9acSAndroid Build Coastguard Worker 
1172*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_HTTP_CACHE_COOKIES)
1173*1c60b9acSAndroid Build Coastguard Worker 		i->ssl_connection |= LCCSCF_CACHE_COOKIES;
1174*1c60b9acSAndroid Build Coastguard Worker 
1175*1c60b9acSAndroid Build Coastguard Worker 	/* protocol aux is the path part */
1176*1c60b9acSAndroid Build Coastguard Worker 
1177*1c60b9acSAndroid Build Coastguard Worker 	i->path = buf;
1178*1c60b9acSAndroid Build Coastguard Worker 
1179*1c60b9acSAndroid Build Coastguard Worker 	/* skip the unnessary '/' */
1180*1c60b9acSAndroid Build Coastguard Worker 	if (*pbasis == '/')
1181*1c60b9acSAndroid Build Coastguard Worker 		pbasis = pbasis + 1;
1182*1c60b9acSAndroid Build Coastguard Worker 
1183*1c60b9acSAndroid Build Coastguard Worker 	buf[0] = '/';
1184*1c60b9acSAndroid Build Coastguard Worker 
1185*1c60b9acSAndroid Build Coastguard Worker 	lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, buf + 1, len - 1);
1186*1c60b9acSAndroid Build Coastguard Worker 
1187*1c60b9acSAndroid Build Coastguard Worker 	if (lws_strexp_expand(&exp, pbasis, strlen(pbasis),
1188*1c60b9acSAndroid Build Coastguard Worker 			      &used_in, &used_out) != LSTRX_DONE)
1189*1c60b9acSAndroid Build Coastguard Worker 		return 1;
1190*1c60b9acSAndroid Build Coastguard Worker 
1191*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1192*1c60b9acSAndroid Build Coastguard Worker }
1193*1c60b9acSAndroid Build Coastguard Worker 
1194*1c60b9acSAndroid Build Coastguard Worker 
1195*1c60b9acSAndroid Build Coastguard Worker const struct ss_pcols ss_pcol_h1 = {
1196*1c60b9acSAndroid Build Coastguard Worker 	"h1",
1197*1c60b9acSAndroid Build Coastguard Worker 	"http/1.1",
1198*1c60b9acSAndroid Build Coastguard Worker 	&protocol_secstream_h1,
1199*1c60b9acSAndroid Build Coastguard Worker 	secstream_connect_munge_h1,
1200*1c60b9acSAndroid Build Coastguard Worker 	NULL, NULL
1201*1c60b9acSAndroid Build Coastguard Worker };
1202