static const char *test_http_errors(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *local_addr = "127.0.0.1:7777"; char status[40] = ""; ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_bind(&mgr, local_addr, cb1)) != NULL); ns_set_protocol_http_websocket(nc); /* Test file which exists but cannot be opened */ ASSERT((nc = ns_connect(&mgr, local_addr, cb8)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = status; system("touch test_unreadable; chmod 000 test_unreadable"); ns_printf(nc, "GET /%s HTTP/1.0\n\n", "../test_unreadable"); /* Run event loop. Use more cycles to let file download complete. */ poll_mgr(&mgr, 200); system("rm -f test_unreadable"); /* Check that it failed */ ASSERT(strncmp(status, "HTTP/1.1 500", strlen("HTTP/1.1 500")) == 0); /* Test non existing file */ ASSERT((nc = ns_connect(&mgr, local_addr, cb8)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = status; ns_printf(nc, "GET /%s HTTP/1.0\n\n", "/please_dont_create_this_file_srsly"); /* Run event loop. Use more cycles to let file download complete. */ poll_mgr(&mgr, 200); /* Check that it failed */ ASSERT(strncmp(status, "HTTP/1.1 404", strlen("HTTP/1.1 404")) == 0); /* Test directory without index.html */ ASSERT((nc = ns_connect(&mgr, local_addr, cb8)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = status; ns_printf(nc, "GET /%s HTTP/1.0\n\n", "/"); /* Run event loop. Use more cycles to let file download complete. */ poll_mgr(&mgr, 200); /* Check that it failed */ ASSERT(strncmp(status, "HTTP/1.1 403", strlen("HTTP/1.1 403")) == 0); /* Cleanup */ ns_mgr_free(&mgr); return NULL; }
static const char *test_http_index(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *local_addr = "127.0.0.1:7777"; char buf[20] = ""; ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_bind(&mgr, local_addr, cb1)) != NULL); ns_set_protocol_http_websocket(nc); /* Test directory. */ ASSERT((nc = ns_connect(&mgr, local_addr, cb9)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = buf; ns_printf(nc, "GET /%s HTTP/1.0\n\n", "/"); system("echo testdata >index.html"); /* Run event loop. Use more cycles to let file download complete. */ poll_mgr(&mgr, 200); ns_mgr_free(&mgr); system("rm index.html"); /* Check that test buffer has been filled by the callback properly. */ ASSERT(strcmp(buf, "testdata\n") == 0); return NULL; }
static void choose_backend(struct ns_connection *nc) { struct http_message hm; struct iobuf *io = &nc->recv_iobuf; int req_len = ns_parse_http(io->buf, io->len, &hm); if (req_len < 0 || (req_len == 0 && io->len >= NS_MAX_HTTP_REQUEST_SIZE)) { /* Invalid, or too large request */ nc->flags |= NSF_CLOSE_IMMEDIATELY; } else if (req_len == 0) { /* Do nothing, request is not yet fully buffered */ } else { /* * Got HTTP request, look which backend to use. Round-robin over the * backends with the same uri_prefix and vhost. */ struct ns_str vhost = *ns_get_http_header(&hm, "host"); const char *vhost_end = vhost.p; while(vhost_end < vhost.p + vhost.len && *vhost_end != ':') { vhost_end++; } vhost.len = vhost_end - vhost.p; int i, chosen = -1; for (i = 0; i < s_num_http_backends; i++) { if (has_prefix(&hm.uri, s_http_backends[i].uri_prefix) && matches_vhost(&vhost, s_http_backends[i].vhost) && (chosen == -1 || s_http_backends[i].usage_counter < s_http_backends[chosen].usage_counter)) { chosen = i; } } if (chosen == -1) { /* No backend with given uri_prefix found, bail out */ ns_printf(nc, "%s%s\r\n", s_error_404, s_content_len_0); } else if (s_http_backends[chosen].redirect != 0) { ns_printf(nc, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\n", s_http_backends[chosen].host_port); nc->flags |= NSF_SEND_AND_CLOSE; } else if ((nc->proto_data = ns_connect(nc->mgr, s_http_backends[chosen].host_port, ev_handler)) == NULL) { /* Connection to backend failed */ ns_printf(nc, "%s%s\r\n", s_error_500, s_content_len_0); } else { /* * Forward request to the backend. Note that we can insert extra headers * to pass information to the backend. * Store backend index as user_data for the backend connection. */ ((struct ns_connection *) nc->proto_data)->proto_data = nc; ((struct ns_connection *) nc->proto_data)->user_data = (void *) (long) chosen; s_http_backends[chosen].usage_counter++; ns_send(nc->proto_data, io->buf, io->len); iobuf_remove(io, io->len); } } }
static const char *test_http(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *local_addr = "127.0.0.1:7777"; char buf[20] = "", status[20] = "", mime[20] = ""; ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_bind(&mgr, local_addr, cb1)) != NULL); ns_set_protocol_http_websocket(nc); /* Valid HTTP request. Pass test buffer to the callback. */ ASSERT((nc = ns_connect(&mgr, local_addr, cb2)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = buf; ns_printf(nc, "%s", "POST /foo HTTP/1.0\nContent-Length: 10\n\n" "0123456789"); /* Invalid HTTP request */ ASSERT((nc = ns_connect(&mgr, local_addr, cb2)) != NULL); ns_set_protocol_http_websocket(nc); ns_printf(nc, "%s", "bl\x03\n\n"); /* Test static file download by downloading this executable, argv[0] */ ASSERT((nc = ns_connect(&mgr, local_addr, cb7)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = status; ns_printf(nc, "GET /%s HTTP/1.0\n\n", s_argv_0); /* Test mime type for static file */ ASSERT((nc = ns_connect(&mgr, local_addr, cb10)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = mime; ns_printf(nc, "%s", "GET /data/dummy.xml HTTP/1.0\n\n"); /* Run event loop. Use more cycles to let file download complete. */ poll_mgr(&mgr, 200); ns_mgr_free(&mgr); /* Check that test buffer has been filled by the callback properly. */ ASSERT(strcmp(buf, "[/foo 10]") == 0); ASSERT(strcmp(status, "success") == 0); ASSERT(strcmp(mime, "text/xml") == 0); return NULL; }
/* * Construct a new WebSocket object: * * url: url where to connect to * protocol: websocket subprotocol * * Example: * ws = new WebSocket('wss://localhost:1234'); * ws.onopen = function(ev) { * print("ON OPEN", ev); * } * * ws.onclose = function(ev) { * print("ON CLOSE", ev); * } * * ws.onmessage = function(ev) { * print("ON MESSAGE", ev); * } * * ws.onerror = function(ev) { * print("ON ERROR", ev); * } * */ static v7_val_t sj_ws_ctor(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { struct ns_connection *nc; struct user_data *ud; v7_val_t urlv = v7_array_get(v7, args, 0); v7_val_t subprotov = v7_array_get(v7, args, 1); (void) this_obj; (void) args; if (!v7_is_string(urlv)) { v7_throw(v7, "invalid ws url string"); } if (v7_is_object(this_obj) && this_obj != v7_get_global_object(v7)) { int use_ssl = 0; size_t len; const char *url = v7_to_string(v7, &urlv, &len); if (strncmp(url, "ws://", 5) == 0) { url += 5; } else if (strncmp(url, "wss://", 6) == 0) { url += 6; use_ssl = 1; } nc = ns_connect(&sj_mgr, url, ws_ev_handler); if (nc == NULL) v7_throw(v7, "error creating the connection"); #ifdef NS_ENABLE_SSL if (use_ssl) { ns_set_ssl(nc, NULL, NULL); } #endif ns_set_protocol_http_websocket(nc); ud = calloc(1, sizeof(*ud)); ud->v7 = v7; ud->ws = this_obj; nc->user_data = ud; v7_own(v7, &ud->ws); if (v7_is_string(subprotov)) { size_t len; const char *proto = v7_to_string(v7, &subprotov, &len); ud->proto = strdup(proto); } } else { v7_throw(v7, "WebSocket ctor called without new"); } return v7_create_undefined(); }
/* Big payloads follow a different code path because it will use the extended * length field and possibly ns_avprintf will need to reallocate the buffer. */ static const char *test_websocket_big(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *local_addr = "127.0.0.1:7778"; char buf[20] = ""; struct big_payload_params params; params.buf = buf; ns_mgr_init(&mgr, NULL); /* mgr.hexdump_file = "/dev/stdout"; */ ASSERT((nc = ns_bind(&mgr, local_addr, cb3_big)) != NULL); ns_set_protocol_http_websocket(nc); /* Websocket request */ ASSERT((nc = ns_connect(&mgr, local_addr, cb4_big)) != NULL); ns_set_protocol_http_websocket(nc); params.size = 8192; nc->user_data = ¶ms; ns_send_websocket_handshake(nc, "/ws", NULL); poll_mgr(&mgr, 50); /* Check that test buffer has been filled by the callback properly. */ ASSERT(strcmp(buf, "success") == 0); /* Websocket request */ ASSERT((nc = ns_connect(&mgr, local_addr, cb4_big)) != NULL); ns_set_protocol_http_websocket(nc); params.size = 65535; nc->user_data = ¶ms; ns_send_websocket_handshake(nc, "/ws", NULL); poll_mgr(&mgr, 50); ns_mgr_free(&mgr); /* Check that test buffer has been filled by the callback properly. */ ASSERT(strcmp(buf, "success") == 0); return NULL; }
int main(void) { struct ns_mgr mgr; const char *address = "localhost:1883"; ns_mgr_init(&mgr, NULL); if (ns_connect(&mgr, address, ev_handler) == NULL) { fprintf(stderr, "ns_connect(%s) failed\n", address); exit(EXIT_FAILURE); } for(;;) { ns_mgr_poll(&mgr, 1000); } }
static const char *test_connect_fail(void) { struct ns_mgr mgr; struct ns_connection *nc; char buf[100] = "0"; ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_connect(&mgr, "127.0.0.1:33211", cb5)) != NULL); nc->user_data = buf; poll_mgr(&mgr, 50); ns_mgr_free(&mgr); /* printf("failed connect status: [%s]\n", buf); */ ASSERT(strcmp(buf, "0") != 0); return NULL; }
static const char *test_udp(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *address = "udp://127.0.0.1:7878"; char buf[20] = ""; ns_mgr_init(&mgr, buf); ASSERT(ns_bind(&mgr, address, eh3) != NULL); ASSERT((nc = ns_connect(&mgr, address, eh3)) != NULL); ns_printf(nc, "%s", "boo!"); { int i; for (i = 0; i < 50; i++) ns_mgr_poll(&mgr, 1); } ASSERT(memcmp(buf, "boo!", 4) == 0); ns_mgr_free(&mgr); return NULL; }
int main(int argc, char *argv[]) { struct ns_mgr mgr; if (argc != 3) { fprintf(stderr, "Usage: %s <port> <client|server>\n", argv[0]); exit(EXIT_FAILURE); } else if (strcmp(argv[2], "client") == 0) { int fds[2]; struct ns_connection *ioconn, *server_conn; ns_mgr_init(&mgr, NULL, client_handler); // Connect to the pubsub server server_conn = ns_connect(&mgr, argv[1], NULL); if (server_conn == NULL) { fprintf(stderr, "Cannot connect to port %s\n", argv[1]); exit(EXIT_FAILURE); } // Create a socketpair and give one end to the thread that reads stdin ns_socketpair(fds); ns_start_thread(stdin_thread, &fds[1]); // The other end of a pair goes inside the server ioconn = ns_add_sock(&mgr, fds[0], NULL); ioconn->flags |= NSF_USER_1; // Mark this so we know this is a stdin ioconn->user_data = server_conn; } else { // Server code path ns_mgr_init(&mgr, NULL, server_handler); ns_bind(&mgr, argv[1], NULL); printf("Starting pubsub server on port %s\n", argv[1]); } for (;;) { ns_mgr_poll(&mgr, 1000); } ns_mgr_free(&mgr); return EXIT_SUCCESS; }
/* * choose_backend parses incoming HTTP request and routes it to the appropriate * backend. It assumes that clients don't do HTTP pipelining, handling only * one request request for each connection. To give a hint to backend about * this it inserts "Connection: close" header into each forwarded request. */ static int connect_backend(struct conn_data *conn, struct http_message *hm) { struct ns_connection *nc = conn->client.nc; struct http_backend *be = choose_backend(hm); write_log("%.*s %.*s backend=%s\n", (int) hm->method.len, hm->method.p, (int) hm->uri.len, hm->uri.p, be->host_port); if (be == NULL) return 0; if (be->redirect != 0) { ns_printf(nc, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\n", be->host_port); return 1; } struct be_conn *bec = get_conn(be); if (bec != NULL) { bec->nc->handler = ev_handler; #ifdef DEBUG write_log("conn=%p to %p (%s) reusing bec=%p\n", conn, be, be->host_port, bec); #endif } else { bec = malloc(sizeof(*conn->be_conn)); memset(bec, 0, sizeof(*bec)); bec->nc = ns_connect(nc->mgr, be->host_port, ev_handler); #ifdef DEBUG write_log("conn=%p new conn to %p (%s) bec=%p\n", conn, be, be->host_port, bec); #endif if (bec->nc == NULL) { free(bec); write_log("Connection to [%s] failed\n", be->host_port); return 0; } } bec->be = be; conn->be_conn = bec; conn->backend.nc = bec->nc; conn->backend.nc->user_data = conn; ns_set_protocol_http_websocket(conn->backend.nc); return 1; }
static const char *test_mgr_with_ssl(int use_ssl) { char addr[100] = "127.0.0.1:0", ip[sizeof(addr)], buf[100] = ""; struct ns_mgr mgr; struct ns_connection *nc; int port, port2; #ifndef NS_ENABLE_SSL (void)use_ssl; #endif ns_mgr_init(&mgr, NULL); /* mgr.hexdump_file = "/dev/stdout"; */ ASSERT((nc = ns_bind(&mgr, addr, eh1)) != NULL); port2 = htons(nc->sa.sin.sin_port); ASSERT(port2 > 0); #ifdef NS_ENABLE_SSL if (use_ssl) { ASSERT(ns_set_ssl(nc, S_PEM, CA_PEM) == NULL); } #endif ns_sock_to_str(nc->sock, addr, sizeof(addr), 3); ASSERT(sscanf(addr, "%[^:]:%d", ip, &port) == 2); ASSERT(strcmp(ip, "127.0.0.1") == 0); ASSERT(port == port2); ASSERT((nc = ns_connect(&mgr, addr, eh1)) != NULL); #ifdef NS_ENABLE_SSL if (use_ssl) { ASSERT(ns_set_ssl(nc, C_PEM, CA_PEM) == NULL); } #endif nc->user_data = buf; poll_mgr(&mgr, 50); ASSERT(strcmp(buf, "ok!") == 0); ns_mgr_free(&mgr); return NULL; }
static const char *test_rpc(void) { struct ns_mgr mgr; struct ns_connection *nc; const char *local_addr = "127.0.0.1:7779"; char buf[100] = ""; ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_bind(&mgr, local_addr, rpc_server)) != NULL); ns_set_protocol_http_websocket(nc); ASSERT((nc = ns_connect(&mgr, local_addr, rpc_client)) != NULL); ns_set_protocol_http_websocket(nc); nc->user_data = buf; poll_mgr(&mgr, 50); ns_mgr_free(&mgr); ASSERT(strcmp(buf, "1 1 16") == 0); return NULL; }
void * CWrkThread::Entry() { wxString str; struct ns_connection *nc; struct ns_mgr mgr; const char *address = "192.168.1.9:1883"; mgr.user_data = m_pObj; ns_mgr_init( &mgr, m_pObj ); if ( NULL == ( nc = ns_connect( &mgr, (const char *)m_pObj->m_hostMQTT.mbc_str(), ev_handler ) ) ) { fprintf( stderr, "ns_connect(%s) failed\n", address ); return NULL; } if (m_pObj->m_bSubscribe) { while (!TestDestroy() && !m_pObj->m_bQuit) { ns_mgr_poll( &mgr, 100 ); } } // Publish else { while ( !TestDestroy() && !m_pObj->m_bQuit ) { ns_mgr_poll( &mgr, 100 ); // Wait for connection if ( !m_pObj->m_bConnected ) { continue; } if ( wxSEMA_TIMEOUT == m_pObj->m_semSendQueue.WaitTimeout( 10 ) ) continue; if ( m_pObj->m_sendList.size() ) { m_pObj->m_mutexSendQueue.Lock(); vscpEvent *pEvent = m_pObj->m_sendList.front(); m_pObj->m_sendList.pop_front(); m_pObj->m_mutexSendQueue.Unlock(); if (NULL == pEvent) continue; if (m_pObj->m_bSimplify) { ; } else { vscp_writeVscpEventToString( pEvent, str ); ns_mqtt_publish( nc, "/vscp1", 65, NS_MQTT_QOS( 0 ), (const char *)str.mbc_str(), str.Length() ); } // We are done with the event - remove data if any if (NULL != pEvent->pdata) { delete [] pEvent->pdata; pEvent->pdata = NULL; } } // Event received ::wxMilliSleep(50); } } // Disconnect if we are connected. if ( m_pObj->m_bConnected ) { ns_mqtt_disconnect( nc ); } return NULL; }