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