1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-minimal-secure-streams-cpp
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2020 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  *
9*1c60b9acSAndroid Build Coastguard Worker  * This demonstrates a minimal http client using secure streams C++ api to
10*1c60b9acSAndroid Build Coastguard Worker  * fetch files over https to the local filesystem
11*1c60b9acSAndroid Build Coastguard Worker  */
12*1c60b9acSAndroid Build Coastguard Worker 
13*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.hxx>
14*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
15*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
16*1c60b9acSAndroid Build Coastguard Worker 
17*1c60b9acSAndroid Build Coastguard Worker static int interrupted, bad = 1, concurrent = 1, completed;
18*1c60b9acSAndroid Build Coastguard Worker 
19*1c60b9acSAndroid Build Coastguard Worker static int
lss_completion(lss * lss,lws_ss_constate_t state,void * arg)20*1c60b9acSAndroid Build Coastguard Worker lss_completion(lss *lss, lws_ss_constate_t state, void *arg)
21*1c60b9acSAndroid Build Coastguard Worker {
22*1c60b9acSAndroid Build Coastguard Worker 	lssFile *lf = (lssFile *)lss;
23*1c60b9acSAndroid Build Coastguard Worker 
24*1c60b9acSAndroid Build Coastguard Worker 	if (state == LWSSSCS_QOS_ACK_REMOTE) {
25*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: %s: len %llu, done OK %dms\n", __func__,
26*1c60b9acSAndroid Build Coastguard Worker 			    lf->path.c_str(), (unsigned long long)lf->rxlen,
27*1c60b9acSAndroid Build Coastguard Worker 			    (int)((lws_now_usecs() - lf->us_start) / 1000));
28*1c60b9acSAndroid Build Coastguard Worker 	} else
29*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: %s: failed\n", __func__, lf->path.c_str());
30*1c60b9acSAndroid Build Coastguard Worker 
31*1c60b9acSAndroid Build Coastguard Worker 	if (++completed == concurrent) {
32*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
33*1c60b9acSAndroid Build Coastguard Worker 		bad = 0;
34*1c60b9acSAndroid Build Coastguard Worker 	}
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker 	return 0;
37*1c60b9acSAndroid Build Coastguard Worker }
38*1c60b9acSAndroid Build Coastguard Worker 
39*1c60b9acSAndroid Build Coastguard Worker static void
sigint_handler(int sig)40*1c60b9acSAndroid Build Coastguard Worker sigint_handler(int sig)
41*1c60b9acSAndroid Build Coastguard Worker {
42*1c60b9acSAndroid Build Coastguard Worker 	interrupted = 1;
43*1c60b9acSAndroid Build Coastguard Worker }
44*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)45*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
46*1c60b9acSAndroid Build Coastguard Worker {
47*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_creation_info info;
48*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context;
49*1c60b9acSAndroid Build Coastguard Worker 	const char *p;
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	signal(SIGINT, sigint_handler);
52*1c60b9acSAndroid Build Coastguard Worker 
53*1c60b9acSAndroid Build Coastguard Worker 	memset(&info, 0, sizeof info);
54*1c60b9acSAndroid Build Coastguard Worker 	lws_cmdline_option_handle_builtin(argc, argv, &info);
55*1c60b9acSAndroid Build Coastguard Worker 
56*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-c")))
57*1c60b9acSAndroid Build Coastguard Worker 		concurrent = atoi(p);
58*1c60b9acSAndroid Build Coastguard Worker 
59*1c60b9acSAndroid Build Coastguard Worker 	if (concurrent > 12)
60*1c60b9acSAndroid Build Coastguard Worker 		concurrent = 12;
61*1c60b9acSAndroid Build Coastguard Worker 
62*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS secure streams cpp test client "
63*1c60b9acSAndroid Build Coastguard Worker 			"[-d<verb>] [-c<concurrent>]\n");
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker 	info.fd_limit_per_thread = 1 + 12 + 1;
66*1c60b9acSAndroid Build Coastguard Worker 	info.port = CONTEXT_PORT_NO_LISTEN;
67*1c60b9acSAndroid Build Coastguard Worker 	info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
68*1c60b9acSAndroid Build Coastguard Worker 
69*1c60b9acSAndroid Build Coastguard Worker 	/* create the context */
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	context = lws_create_context(&info);
72*1c60b9acSAndroid Build Coastguard Worker 	if (!context) {
73*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws init failed\n");
74*1c60b9acSAndroid Build Coastguard Worker 		return 1;
75*1c60b9acSAndroid Build Coastguard Worker 	}
76*1c60b9acSAndroid Build Coastguard Worker 
77*1c60b9acSAndroid Build Coastguard Worker 	try {
78*1c60b9acSAndroid Build Coastguard Worker 
79*1c60b9acSAndroid Build Coastguard Worker 		for (int n = 0; n < concurrent; n++) {
80*1c60b9acSAndroid Build Coastguard Worker 			std::string url, filepath;
81*1c60b9acSAndroid Build Coastguard Worker 
82*1c60b9acSAndroid Build Coastguard Worker 			url = "https://warmcat.com/test-";
83*1c60b9acSAndroid Build Coastguard Worker 			url += ('a' + n);
84*1c60b9acSAndroid Build Coastguard Worker 			url += ".bin";
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker 			filepath = "/tmp/test-";
87*1c60b9acSAndroid Build Coastguard Worker 			filepath += ('a' + n);
88*1c60b9acSAndroid Build Coastguard Worker 			filepath += ".bin";
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker 			new lssFile(context, url, filepath, lss_completion, 0);
91*1c60b9acSAndroid Build Coastguard Worker 		}
92*1c60b9acSAndroid Build Coastguard Worker 	} catch (std::exception &e) {
93*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: failed to create ss: %s\n", __func__, e.what());
94*1c60b9acSAndroid Build Coastguard Worker 		interrupted = 1;
95*1c60b9acSAndroid Build Coastguard Worker 	}
96*1c60b9acSAndroid Build Coastguard Worker 
97*1c60b9acSAndroid Build Coastguard Worker 	/* the event loop */
98*1c60b9acSAndroid Build Coastguard Worker 
99*1c60b9acSAndroid Build Coastguard Worker 	while (!interrupted && lws_service(context, 0) >= 0)
100*1c60b9acSAndroid Build Coastguard Worker 		;
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 	lws_context_destroy(context);
103*1c60b9acSAndroid Build Coastguard Worker 
104*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("Completed: %s\n", bad ? "failed" : "OK");
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 	return bad;
107*1c60b9acSAndroid Build Coastguard Worker }
108