static void tport_ws_deinit_secondary(tport_t *self) { tport_ws_t *wstp = (tport_ws_t *)self; if (wstp->ws_initialized == 1) { SU_DEBUG_1(("%p destroy ws%s transport %p.\n", (void *) self, wstp->ws_secure ? "s" : "", (void *) &wstp->ws)); ws_destroy(&wstp->ws); wstp->ws_initialized = -1; } }
// Handle correct exiting static void exit_handler(int sig) { // Stop webserver if (ws != NULL) { ws_stop(ws); ws_destroy(ws); } // Exit printf("Exiting....\n"); exit(sig); }
int TEST_ws_generate_handshake_key(int argc, char *argv[]) { int ret = 0; ws_base_t base = NULL; ws_t ws = NULL; libws_test_HEADLINE("TEST_ws_generate_handshake_key"); if (libws_test_init(argc, argv)) return -1; if (ws_global_init(&base)) { libws_test_FAILURE("Failed to init global state"); return -1; } if (ws_init(&ws, base)) { libws_test_FAILURE("Failed to init websocket state"); ret = -1; goto fail; } libws_test_STATUS("Run the same test twice to check for memory leaks"); ret |= do_test(ws, 1); ret |= do_test(ws, 1); #ifndef WIN32 libws_test_STATUS("Close file descriptor to random source and check fail"); if (close(base->random_fd)) { libws_test_FAILURE("Failed to close random source: %s (%d)", strerror(errno), errno); ret |= -1; } else { ret |= do_test(ws, 0); } #endif fail: ws_destroy(&ws); ws_global_destroy(&base); return ret; }
int tport_ws_init_secondary(tport_t *self, int socket, int accepted, char const **return_reason) { int one = 1; tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri; tport_ws_t *wstp = (tport_ws_t *)self; self->tp_has_connection = 1; /* override the default 30 minute timeout on tport connections */ self->tp_params->tpp_idle = UINT_MAX; if (setsockopt(socket, SOL_TCP, TCP_NODELAY, (void *)&one, sizeof one) == -1) return *return_reason = "TCP_NODELAY", -1; #if defined(SO_KEEPALIVE) setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, sizeof one); #endif one = 30; #if defined(TCP_KEEPIDLE) setsockopt(socket, SOL_TCP, TCP_KEEPIDLE, (void *)&one, sizeof one); #endif #if defined(TCP_KEEPINTVL) setsockopt(socket, SOL_TCP, TCP_KEEPINTVL, (void *)&one, sizeof one); #endif if (!accepted) tport_ws_setsndbuf(socket, 64 * 1024); if ( wspri->ws_secure ) wstp->ws_secure = 1; memset(&wstp->ws, 0, sizeof(wstp->ws)); if (ws_init(&wstp->ws, socket, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) { ws_destroy(&wstp->ws); wstp->ws_initialized = -1; return *return_reason = "WS_INIT", -1; } wstp->ws_initialized = 1; self->tp_pre_framed = 1; return 0; }
int main(int argc, char *argv[]) { int i; WsCompilerParams params; WsCompilerPtr compiler; WsResult result; int opt; program = strrchr(argv[0], '/'); if (program) program++; else program = argv[0]; /* Initialize the parameters structure. The command line options modify this directly. */ memset(¶ms, 0, sizeof(params)); /* Process command line arguments. */ while ((opt = getopt(argc, argv, "adhsv")) != EOF) { switch (opt) { case 'a': params.print_assembler = 1; break; case 'd': eval_data = 1; break; case 'h': usage(); exit(0); break; case 'l': params.use_latin1_strings = 1; break; case 'p': params.meta_name_cb = pragma_meta; params.meta_name_cb_context = "meta name"; params.meta_http_equiv_cb = pragma_meta; params.meta_http_equiv_cb_context = "meta http equiv"; break; case 's': params.print_symbolic_assembler = 1; break; case 'v': params.verbose = 1; break; case '?': printf("Try `%s -h' for a complete list of options.\n", program); exit(1); } } /* Create compiler. */ compiler = ws_create(¶ms); if (compiler == NULL) { fprintf(stderr, "wsc: could not create compiler\n"); exit(1); } for (i = optind; i < argc; i++) { FILE *ifp, *ofp; char *outname; ifp = fopen(argv[i], "rb"); if (ifp == NULL) { fprintf(stderr, "wsc: could not open input file `%s': %s'\n", argv[i], strerror(errno)); exit(1); } /* Create the output name. */ outname = malloc(strlen(argv[i]) + 1 + 1); if (outname == NULL) { fprintf(stderr, "wmlsc: could not create output file name: %s\n", strerror(errno)); exit(1); } strcpy(outname, argv[i]); strcat(outname, "c"); ofp = fopen(outname, "wb"); if (ofp == NULL) { fprintf(stderr, "wsc: could not create output file `%s': %s\n", outname, strerror(errno)); exit(1); } if (eval_data) { /* Use the ws_compile_data() interface. */ struct stat stat_st; unsigned char *data; unsigned char *output; size_t output_len; if (stat(argv[i], &stat_st) == -1) { fprintf(stderr, "wsc: could not stat input file `%s': %s\n", argv[i], strerror(errno)); exit(1); } /* Allocate the input buffer. */ data = malloc(stat_st.st_size); if (data == NULL) { fprintf(stderr, "wsc: could not allocate input buffer: %s\n", strerror(errno)); exit(1); } if (fread(data, 1, stat_st.st_size, ifp) < (size_t) stat_st.st_size) { fprintf(stderr, "wsc: could not read data: %s\n", strerror(errno)); exit(1); } result = ws_compile_data(compiler, argv[i], data, stat_st.st_size, &output, &output_len); if (result == WS_OK) { /* Save the output to `ofp'. */ if (fwrite(output, 1, output_len, ofp) != output_len) { fprintf(stderr, "wsc: could not save output to file `%s': %s\n", outname, strerror(errno)); exit(1); } } free(data); ws_free_byte_code(output); } else { /* Use the ws_compile_file() interface. */ result = ws_compile_file(compiler, argv[i], ifp, ofp); } /* Common cleanup. */ fclose(ifp); fclose(ofp); if (result != WS_OK) { remove(outname); fprintf(stderr, "wsc: compilation failed: %s\n", ws_result_to_string(result)); exit(1); } free(outname); } ws_destroy(compiler); return 0; }
int TEST_ws_read_server_handshake_reply(int argc, char *argv[]) { int ret = 0; ws_base_t base = NULL; ws_t ws = NULL; char key_hash[256]; struct evbuffer *in = evbuffer_new(); libws_test_HEADLINE("TEST_ws_read_server_handshake_reply"); if (libws_test_init(argc, argv)) return -1; if (!in) { libws_test_FAILURE("Failed to init evbuffer"); return -1; } if (ws_global_init(&base)) { libws_test_FAILURE("Failed to init global state"); return -1; } if (ws_init(&ws, base)) { libws_test_FAILURE("Failed to init websocket state"); ret = -1; goto fail; } if (ws_add_subprotocol(ws, "echo")) { libws_test_FAILURE("Failed to add sub protocol \"echo\""); ret = -1; goto fail; } if (_ws_generate_handshake_key(ws)) { libws_test_FAILURE("Failed to generate handshake base64 key"); ret = -1; goto fail; } else { libws_test_SUCCESS("Generated handshake base64 key: %s", ws->handshake_key_base64); } if (_ws_calculate_key_hash(ws->handshake_key_base64, key_hash, sizeof(key_hash))) { libws_test_FAILURE("Failed to calculate key hash"); ret = -1; goto fail; } else { libws_test_SUCCESS("Calculated key hash: %s", key_hash); } libws_test_STATUS("Test valid full response:"); { // Emulate having sent a request. ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); evbuffer_add_printf(in, "HTTP/1.1 101\r\n" "Upgrade: websocket\r\n" "Connection: upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n" "Sec-WebSocket-Protocol: echo\r\n" "\r\n", key_hash); ret |= run_header_test(" Valid full response", ws, in, WS_PARSE_STATE_SUCCESS); } libws_test_STATUS("Test valid partial response:"); { ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); // Part 1. evbuffer_add_printf(in, "HTTP/1.1 101\r\n" "Upgrade: websocket\r\n" "Connection: upg"); libws_test_STATUS(" Parse part 1:"); ret |= run_header_test(" Valid partial response, part 1", ws, in, WS_PARSE_STATE_NEED_MORE); // Part 2. evbuffer_add_printf(in, "rade\r\n" "Sec-WebSocket-Accept: %s\r\n" "Sec-WebSocket-Protocol: echo\r\n" "\r\n", key_hash); libws_test_STATUS(" Parse part 2:"); ret |= run_header_test(" Valid partial response, part 2", ws, in, WS_PARSE_STATE_SUCCESS); } libws_test_STATUS("Test invalid HTTP version:"); { // Emulate having sent a request. ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); evbuffer_add_printf(in, "HTTP/1.0 101\r\n" "Upgrade: websocket\r\n" "Connection: upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n" "Sec-WebSocket-Protocol: echo\r\n" "\r\n", key_hash); ret |= run_header_test("Invalid HTTP version response", ws, in, WS_PARSE_STATE_ERROR); } libws_test_STATUS("Test partial HTTP version:"); { // Emulate having sent a request. ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); evbuffer_add_printf(in, "HTTP/1."); ret |= run_header_test("Partial HTTP version response", ws, in, WS_PARSE_STATE_NEED_MORE); } libws_test_STATUS("Test invalid HTTP version line:"); { // Emulate having sent a request. ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); evbuffer_add_printf(in, "HTTP/1.1 abc\r\n"); ret |= run_header_test("Invalid HTTP version response", ws, in, WS_PARSE_STATE_ERROR); } libws_test_STATUS("Test empty buffer"); { // Emulate having sent a request. ws->connect_state = WS_CONNECT_STATE_SENT_REQ; evbuffer_drain(in, evbuffer_get_length(in)); ret |= run_header_test("Partial HTTP version response", ws, in, WS_PARSE_STATE_NEED_MORE); } fail: evbuffer_free(in); ws_destroy(&ws); ws_global_destroy(&base); return ret; }
int main(int argc, char **argv) { int ret = 0; int i; ws_base_t base = NULL; ws_t ws = NULL; int echo_count = 5; int ssl = 0; char *server = "localhost"; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--ssl")) { ssl = 1; } else { server = argv[i]; } } ws_set_log_cb(ws_default_log_cb); ws_set_log_level(-1); printf("Echo client\n\n"); if (ws_global_init(&base)) { fprintf(stderr, "Failed to init global state.\n"); return -1; } if (ws_init(&ws, base)) { fprintf(stderr, "Failed to init websocket state.\n"); ret = -1; goto fail; } ws_set_onmsg_cb(ws, onmsg, &echo_count); ws_set_onconnect_cb(ws, onconnect, NULL); ws_set_onclose_cb(ws, onclose, NULL); if (ssl) { ws_set_ssl_state(ws, LIBWS_SSL_SELFSIGNED); } printf("Connect to server %s\n", server); if (ws_connect(ws, server, 9500, "")) { ret = -1; goto fail; } ws_base_service_blocking(base); fail: ws_destroy(&ws); ws_global_destroy(&base); printf("Bye bye!\n"); return ret; }