/*
* 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 mg_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 = mg_connect(&sj_mgr, url, ws_ev_handler);
    if (nc == NULL) v7_throw(v7, "error creating the connection");
#ifdef NS_ENABLE_SSL
    if (use_ssl) {
      mg_set_ssl(nc, NULL, NULL);
    }
#endif

    (void) use_ssl;
    mg_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 #2
0
int clubby_proto_connect(struct mg_mgr *mgr) {
  if (s_clubby_conn != NULL) {
    /* We support only one connection to cloud */
    LOG(LL_ERROR, ("Clubby already connected"));

    /* TODO(alashkin): handle this */
    return 1;
  }

  LOG(LL_DEBUG, ("Connecting to %s", get_cfg()->clubby.server_address));

  s_clubby_conn =
      mg_connect(mgr, get_cfg()->clubby.server_address, clubby_proto_handler);
  if (s_clubby_conn == NULL) {
    LOG(LL_DEBUG, ("Cannot connect to %s", get_cfg()->clubby.server_address));
    struct clubby_event evt;
    evt.ev = CLUBBY_CONNECT;
    evt.net_connect.success = 0;
    s_clubby_cb(&evt);
    return 0;
  }

#ifdef SSL_KRYPTON
  if (s_cfg->tls_ena) {
    char *ca_file =
        get_cfg()->tls->tls_ca_file[0] ? get_cfg()->tls->tls_ca_file : NULL;
    char *server_name = get_cfg()->tls->tls_server_name;
    mg_set_ssl(s_clubby_conn, NULL, ca_file);
    if (server_name[0] == '\0') {
      char *p;
      server_name = strdup(get_cfg()->tls->server_address);
      p = strchr(server_name, ':');
      if (p != NULL) *p = '\0';
    }
    SSL_CTX_kr_set_verify_name(s_clubby_conn->ssl_ctx, server_name);
    if (server_name != get_cfg()->tls->tls_server_name) free(server_name);
  }
#endif

  mg_set_protocol_http_websocket(s_clubby_conn);

  return 1;
}
Exemple #3
0
int main(int argc, char *argv[]) {
    struct mg_mgr mgr;
    struct mg_connection *nc;
    int i;
#ifdef MG_ENABLE_SSL
    const char *ssl_cert = NULL;
#endif

    mg_mgr_init(&mgr, NULL);
    s_http_server_opts.document_root = "web_root";

    /* Process command line options to customize HTTP server */
    for (i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-D") == 0 && i + 1 < argc) {
            mgr.hexdump_file = argv[++i];
        } else if (strcmp(argv[i], "-d") == 0 && i + 1 < argc) {
            s_http_server_opts.document_root = argv[++i];
        } else if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) {
            s_http_port = argv[++i];
        } else if (strcmp(argv[i], "-L") == 0 && i + 1 < argc) {
            s_http_server_opts.enable_directory_listing = argv[++i];
        } else if (strcmp(argv[i], "-a") == 0 && i + 1 < argc) {
            s_http_server_opts.auth_domain = argv[++i];
#ifdef MG_ENABLE_JAVASCRIPT
        } else if (strcmp(argv[i], "-j") == 0 && i + 1 < argc) {
            const char *init_file = argv[++i];
            mg_enable_javascript(&mgr, v7_create(), init_file);
#endif
        } else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) {
            s_http_server_opts.global_auth_file = argv[++i];
        } else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
            s_http_server_opts.per_directory_auth_file = argv[++i];
        } else if (strcmp(argv[i], "-r") == 0 && i + 1 < argc) {
            s_http_server_opts.url_rewrites = argv[++i];
#ifndef MG_DISABLE_CGI
        } else if (strcmp(argv[i], "-i") == 0 && i + 1 < argc) {
            s_http_server_opts.cgi_interpreter = argv[++i];
#endif
#ifdef MG_ENABLE_SSL
        } else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) {
            ssl_cert = argv[++i];
#endif
        } else {
            fprintf(stderr, "Unknown option: [%s]\n", argv[i]);
            exit(1);
        }
    }

    nc = mg_bind(&mgr, s_http_port, ev_handler);
    mg_set_protocol_http_websocket(nc);

    if (nc == NULL) {
        fprintf(stderr, "Error starting server on port %s\n", s_http_port);
        exit(1);
    }

#ifdef MG_ENABLE_SSL
    if (ssl_cert != NULL) {
        const char *err_str = mg_set_ssl(nc, ssl_cert, NULL);
        if (err_str != NULL) {
            fprintf(stderr, "Error loading SSL cert: %s\n", err_str);
            exit(1);
        }
    }
#endif

    printf("Starting RESTful webserver on port %s\n", s_http_port);
    for (;;) {
        mg_mgr_poll(&mgr, 1000);
    }
    mg_mgr_free(&mgr);

    return 0;
}
Exemple #4
0
/*
 * Make a new MQTT client.
 *
 * Arguments:
 * url: url where to connect to
 * opts: option object
 *
 * Recognized option object properties:
 *
 * - clientId: string; mqtt client id. defaults to
 *             Math.random().toString(16).substr(2, 10)
 *
 * Example:
 *
 * var client = MQTT.connect('mqtt://test.mosquitto.org');
 *
 * client.on('connect', function () {
 *   client.subscribe('presence');
 *   client.publish('presence', 'Hello mqtt');
 * });
 *
 * client.on('message', function (topic, message) {
 *   console.log(message);
 * });
 *
 * TLS can be enabled by choosing the `mqtts://` protocol. In that
 * case the default port is 8883 as defined by IANA.
 *
 * The API is modeled after https://www.npmjs.com/package/mqtt.
 *
 */
enum v7_err sj_mqtt_connect(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  const char *url;
  size_t len;
  struct mg_str host, scheme;
  unsigned int port;
  struct mg_connection *nc;
  struct user_data *ud;
  char *url_with_port = NULL;
  int use_ssl = 0;
  v7_val_t urlv = v7_arg(v7, 0), opts = v7_arg(v7, 1);
  v7_val_t client_id;
  v7_val_t proto =
      v7_get(v7, v7_get(v7, v7_get_global(v7), "MQTT", ~0), "proto", ~0);

  if (!v7_is_string(urlv)) {
    rcode = v7_throwf(v7, "Error", "invalid url string");
    goto clean;
  }

  url = v7_get_string(v7, &urlv, &len);

  if (mg_parse_uri(mg_mk_str(url), &scheme, NULL, &host, &port, NULL, NULL,
                   NULL) < 0) {
    rcode = v7_throwf(v7, "Error", "invalid url string");
    goto clean;
  }

  if (mg_vcmp(&scheme, "mqtt") == 0) {
    url += sizeof("mqtt://") - 1;
  } else if (mg_vcmp(&scheme, "mqtts") == 0) {
    url += sizeof("mqtts://") - 1;
    use_ssl = 1;
  } else {
    rcode = v7_throwf(v7, "Error", "unsupported protocol");
    goto clean;
  }

  client_id = v7_get(v7, opts, "clientId", ~0);
  if (v7_is_undefined(client_id)) {
    rcode = v7_exec(v7, "Math.random().toString(16).substr(2,8)", &client_id);
    if (rcode != V7_OK) {
      goto clean;
    }
  }

  if (port == 0) {
    if (asprintf(&url_with_port, "%.*s%s", (int) host.len, host.p,
                 (use_ssl ? ":8883" : ":1883")) < 0) {
      rcode = v7_throwf(v7, "Error", "Out of memory");
      goto clean;
    }
  }

  nc =
      mg_connect(&sj_mgr, url_with_port ? url_with_port : url, mqtt_ev_handler);
  if (nc == NULL) {
    rcode = v7_throwf(v7, "Error", "cannot create connection");
    goto clean;
  }

  if (use_ssl) {
#ifdef MG_ENABLE_SSL
    mg_set_ssl(nc, NULL, NULL);
#else
    rcode = v7_throwf(v7, "Error", "SSL not enabled");
    goto clean;
#endif
  }
  mg_set_protocol_mqtt(nc);

  *res = v7_mk_object(v7);
  v7_set_proto(v7, *res, proto);

  ud = calloc(1, sizeof(*ud));
  if (ud == NULL) {
    rcode = v7_throwf(v7, "Error", "Out of memory");
    goto clean;
  }
  ud->v7 = v7;
  ud->client = *res;
  ud->client_id = strdup(v7_get_cstring(v7, &client_id));
  if (ud->client_id == NULL) {
    free(ud);
    rcode = v7_throwf(v7, "Error", "Out of memory");
    goto clean;
  }
  nc->user_data = ud;
  v7_own(v7, &ud->client);

  v7_def(v7, *res, "_nc", ~0, _V7_DESC_HIDDEN(1), v7_mk_foreign(v7, nc));

clean:
  free(url_with_port);

  return rcode;
}
Exemple #5
0
int main(int argc, char *argv[]) {
  struct mg_mgr mgr;
  struct mg_connection *nc;
  int i, redirect = 0;
  const char *vhost = NULL;

  mg_mgr_init(&mgr, NULL);

  /* Parse command line arguments */
  for (i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-D") == 0) {
      mgr.hexdump_file = argv[i + 1];
      i++;
    } else if (strcmp(argv[i], "-k") == 0) {
      s_backend_keepalive = 1;
    } else if (strcmp(argv[i], "-l") == 0 && i + 1 < argc) {
      if (strcmp(argv[i + 1], "-") == 0) {
        s_log_file = stdout;
      } else {
        s_log_file = fopen(argv[i + 1], "a");
        if (s_log_file == NULL) {
          perror("fopen");
          exit(EXIT_FAILURE);
        }
      }
      i++;
    } else if (strcmp(argv[i], "-p") == 0) {
      s_http_port = argv[i + 1];
      i++;
    } else if (strcmp(argv[i], "-r") == 0 && i + 1 < argc) {
      redirect = 1;
    } else if (strcmp(argv[i], "-v") == 0 && i + 1 < argc) {
      if (strcmp(argv[i + 1], "") == 0) {
        vhost = NULL;
      } else {
        vhost = argv[i + 1];
      }
      i++;
    } else if (strcmp(argv[i], "-b") == 0 && i + 2 < argc) {
      struct http_backend *be =
          vhost != NULL ? &s_vhost_backends[s_num_vhost_backends++]
                        : &s_default_backends[s_num_default_backends++];
      STAILQ_INIT(&be->conns);
      char *r = NULL;
      be->vhost = vhost;
      be->uri_prefix = argv[i + 1];
      be->host_port = argv[i + 2];
      be->redirect = redirect;
      be->uri_prefix_replacement = be->uri_prefix;
      if ((r = strchr(be->uri_prefix, '=')) != NULL) {
        *r = '\0';
        be->uri_prefix_replacement = r + 1;
      }
      printf(
          "Adding backend for %s%s : %s "
          "[redirect=%d,prefix_replacement=%s]\n",
          be->vhost == NULL ? "" : be->vhost, be->uri_prefix, be->host_port,
          be->redirect, be->uri_prefix_replacement);
      vhost = NULL;
      redirect = 0;
      i += 2;
#if MG_ENABLE_SSL
    } else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) {
      s_ssl_cert = argv[++i];
#endif
    } else {
      print_usage_and_exit(argv[0]);
    }
  }

  /* Open listening socket */
  if ((nc = mg_bind(&mgr, s_http_port, ev_handler)) == NULL) {
    fprintf(stderr, "mg_bind(%s) failed\n", s_http_port);
    exit(EXIT_FAILURE);
  }

#if MG_ENABLE_SSL
  if (s_ssl_cert != NULL) {
    const char *err_str = mg_set_ssl(nc, s_ssl_cert, NULL);
    if (err_str != NULL) {
      fprintf(stderr, "Error loading SSL cert: %s\n", err_str);
      exit(1);
    }
  }
#endif
  mg_set_protocol_http_websocket(nc);

  if (s_num_vhost_backends + s_num_default_backends == 0) {
    print_usage_and_exit(argv[0]);
  }

  signal(SIGINT, signal_handler);
  signal(SIGTERM, signal_handler);

  /* Run event loop until signal is received */
  printf("Starting LB on port %s\n", s_http_port);
  while (s_sig_num == 0) {
    mg_mgr_poll(&mgr, 1000);
  }

  /* Cleanup */
  mg_mgr_free(&mgr);

  printf("Exiting on signal %d\n", s_sig_num);

  return EXIT_SUCCESS;
}
Exemple #6
0
Server::Server(ManagerConfig *config, const std::string &config_file) {
	srand((unsigned) time(0));
	m_config = config;
	m_user = CONFIG_STRING(m_config, "service.admin_username");
	m_password = CONFIG_STRING(m_config, "service.admin_password");

	mg_mgr_init(&m_mgr, this);

	struct mg_bind_opts opts;
	memset(&opts, 0, sizeof(opts));
	const char *error_string;
	opts.error_string = &error_string;
	m_nc = mg_bind_opt(&m_mgr, std::string(":" + boost::lexical_cast<std::string>(CONFIG_INT(m_config, "service.port"))).c_str(), &_event_handler, opts);
	if (!m_nc) {
		std::cerr << "Error creating server: " << error_string << "\n";
		exit(1);
	}

	if (!CONFIG_STRING(m_config, "service.cert").empty()) {
		const char *err_str = mg_set_ssl(m_nc, CONFIG_STRING(m_config, "service.cert").c_str(), NULL);
		if (err_str) {
			std::cerr << "Error setting SSL certificate: " << err_str << "\n";
			exit(1);
		}
	}
	mg_set_protocol_http_websocket(m_nc);

	s_http_server_opts.document_root = CONFIG_STRING(m_config, "service.data_dir").c_str();

	std::ifstream header(std::string(CONFIG_STRING(m_config, "service.data_dir") + "/header.html").c_str(), std::ios::in);
	if (header) {
		header.seekg(0, std::ios::end);
		m_header.resize(header.tellg());
		header.seekg(0, std::ios::beg);
		header.read(&m_header[0], m_header.size());
		header.close();
	}

	std::ifstream footer(std::string(CONFIG_STRING(m_config, "service.data_dir") + "/footer.html").c_str(), std::ios::in);
	if (footer) {
		footer.seekg(0, std::ios::end);
		m_footer.resize(footer.tellg());
		footer.seekg(0, std::ios::beg);
		footer.read(&m_footer[0], m_footer.size());
		footer.close();
	}

	m_storageCfg = new Config();
	m_storageCfg->load(config_file);
	
	Logging::initManagerLogging(m_storageCfg);
	std::string error;
	m_storage = StorageBackend::createBackend(m_storageCfg, error);
	if (m_storage == NULL) {
		std::cerr << "Error creating StorageBackend! " << error << "\n";
		std::cerr << "Registering new Spectrum 2 manager users won't work" << "\n";
	}
	else if (!m_storage->connect()) {
		delete m_storage;
		m_storage = NULL;
		std::cerr << "Can't connect to database!\n";
	}

	m_apiServer = new APIServer(config, m_storage);
}