Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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);
    }
  }
}
Exemple #4
0
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();
}
Exemple #6
0
/* 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 = &params;
  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 = &params;
  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;
}
Exemple #7
0
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);
  }
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #11
0
/*
 * 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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;

}