">https://",
};
-LWS_VISIBLE LWS_EXTERN int
-lws_write_http_mount(struct lws_http_mount *next, struct lws_http_mount **res,
- void *store, const char *mountpoint, const char *origin,
- const char *def)
-{
- struct lws_http_mount *m;
- void *orig = store;
- unsigned long l = (unsigned long)store;
- int n;
-
- if (l & 15)
- l += 16 - (l & 15);
-
- store = (void *)l;
- m = (struct lws_http_mount *)store;
- *res = m;
-
- m->def = def;
- m->mountpoint = mountpoint;
- m->mountpoint_len = (unsigned char)strlen(mountpoint);
- m->mount_next = NULL;
- if (next)
- next->mount_next = m;
-
- for (n = 0; n < ARRAY_SIZE(mount_protocols); n++)
- if (!strncmp(origin, mount_protocols[n],
- strlen(mount_protocols[n]))) {
- m->origin_protocol = n;
- m->origin = origin + strlen(mount_protocols[n]);
- break;
- }
-
- if (n == ARRAY_SIZE(mount_protocols)) {
- lwsl_err("unsupported protocol://\n");
- return 0; /* ie, fail */
- }
-
- return ((char *)store + sizeof(*m)) - (char *)orig;
-}
-
LWS_VISIBLE void *
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot,
int size)
return vhost->protocol_vh_privs[n];
}
-static struct lws_protocol_vhost_options *
+static const struct lws_protocol_vhost_options *
lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)
{
- struct lws_protocol_vhost_options *pvo = vh->pvo;
+ const struct lws_protocol_vhost_options *pvo = vh->pvo;
while (pvo) {
// lwsl_notice("%s: '%s' '%s'\n", __func__, pvo->name, name);
lws_protocol_init(struct lws_context *context)
{
struct lws_vhost *vh = context->vhost_list;
- struct lws_protocol_vhost_options *pvo;
+ const struct lws_protocol_vhost_options *pvo;
struct lws wsi;
int n;
* protocol ptrs so lws_get_context(wsi) etc can work
*/
vh->protocols[n].callback(&wsi,
- LWS_CALLBACK_PROTOCOL_INIT, NULL, pvo, 0);
+ LWS_CALLBACK_PROTOCOL_INIT, NULL,
+ (void *)pvo, 0);
}
vh = vh->vhost_next;
return 0;
}
+static int callback_http_dummy(
+ struct lws *wsi, enum lws_callback_reasons reason, void *user,
+ void *in, size_t len)
+{
+ return 0;
+}
+
+/* list of supported protocols and callbacks */
+
+static const struct lws_protocols protocols_dummy[] = {
+ /* first protocol must always be HTTP handler */
+
+ {
+ "http-only", /* name */
+ callback_http_dummy, /* callback */
+ 0, /* per_session_data_size */
+ 0, /* max frame size / rx buffer */
+ },
+ /*
+ * the other protocols are provided by lws plugins
+ */
+ { NULL, NULL, 0, 0 } /* terminator */
+};
+
LWS_VISIBLE struct lws_vhost *
lws_create_vhost(struct lws_context *context,
- struct lws_context_creation_info *info,
- struct lws_http_mount *mounts)
+ struct lws_context_creation_info *info)
{
struct lws_vhost *vh = lws_zalloc(sizeof(*vh)),
**vh1 = &context->vhost_list;
+ const struct lws_http_mount *mounts;
#ifdef LWS_WITH_PLUGINS
struct lws_plugin *plugin = context->plugin_list;
struct lws_protocols *lwsp;
- int m, n;
+ int m, n, f = !info->pvo;
#endif
char *p;
if (!vh)
return NULL;
+ if (!info->protocols)
+ info->protocols = &protocols_dummy[0];
+
vh->context = context;
if (!info->vhost_name)
vh->name = "default";
vh->count_protocols++)
;
+ vh->options = info->options;
vh->pvo = info->pvo;
+ vh->keepalive_timeout = info->keepalive_timeout;
#ifdef LWS_WITH_PLUGINS
if (plugin) {
memcpy(lwsp, info->protocols,
sizeof(struct lws_protocols) * m);
+ /* for compatibility, all protocols enabled on vhost if only
+ * the default vhost exists. Otherwise only vhosts who ask
+ * for a protocol get it enabled.
+ */
+
+ if (info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
+ f = 0;
+
while (plugin) {
for (n = 0; n < plugin->caps.count_protocols; n++) {
/*
* for compatibility's sake, no pvo implies
* allow all protocols
*/
- if (!info->pvo || lws_vhost_protocol_options(vh,
+ if (f || lws_vhost_protocol_options(vh,
plugin->caps.protocols[n].name)) {
memcpy(&lwsp[m],
&plugin->caps.protocols[n],
#endif
vh->protocols = info->protocols;
- vh->mount_list = mounts;
+ vh->same_vh_protocol_list = (struct lws **)
+ lws_zalloc(sizeof(struct lws *) * vh->count_protocols);
+
+ vh->mount_list = info->mounts;
+#ifdef LWS_USE_UNIX_SOCK
+ if (LWS_UNIX_SOCK_ENABLED(context)) {
+ lwsl_notice("Creating Vhost '%s' path \"%s\", %d protocols\n",
+ vh->name, info->iface, vh->count_protocols);
+ } else
+#endif
lwsl_notice("Creating Vhost '%s' port %d, %d protocols\n",
vh->name, info->port, vh->count_protocols);
+ mounts = info->mounts;
while (mounts) {
lwsl_notice(" mounting %s%s to %s\n",
mount_protocols[mounts->origin_protocol],
memcpy((struct lws_extension *)vh->extensions, info->extensions,
sizeof(struct lws_extension) * m);
+ plugin = context->plugin_list;
while (plugin) {
- memcpy((struct lws_extension *)&vh->extensions[m], plugin->caps.extensions,
+ memcpy((struct lws_extension *)&vh->extensions[m],
+ plugin->caps.extensions,
sizeof(struct lws_extension) *
plugin->caps.count_extensions);
m += plugin->caps.count_extensions;
vh->ka_interval = info->ka_interval;
vh->ka_probes = info->ka_probes;
+ if (vh->options & LWS_SERVER_OPTION_STS)
+ lwsl_notice(" STS enabled\n");
+
+#ifdef LWS_WITH_ACCESS_LOG
+ if (info->log_filepath) {
+ vh->log_fd = open(info->log_filepath, O_CREAT | O_APPEND | O_RDWR, 0600);
+ if (vh->log_fd == LWS_INVALID_FILE) {
+ lwsl_err("unable to open log filepath %s\n",
+ info->log_filepath);
+ goto bail;
+ }
+ if (context->uid != -1)
+ if (chown(info->log_filepath, context->uid,
+ context->gid) == -1)
+ lwsl_err("unable to chown log file %s\n",
+ info->log_filepath);
+ } else
+ vh->log_fd = LWS_INVALID_FILE;
+#endif
+
if (lws_context_init_server_ssl(info, vh))
goto bail;
struct rlimit rt;
#endif
-
lwsl_notice("Initial logging level %d\n", log_level);
lwsl_notice("Libwebsockets version: %s\n", library_version);
#if LWS_POSIX
lwsl_err("No memory for websocket context\n");
return NULL;
}
+
+ context->time_up = time(NULL);
#ifndef LWS_NO_DAEMONIZE
if (pid_daemon) {
context->started_with_parent = pid_daemon;
}
lwsl_info(" mem: pollfd map: %5u\n", n);
+ if (info->server_string) {
+ context->server_string = info->server_string;
+ context->server_string_len = (short)
+ strlen(context->server_string);
+ } else {
+ context->server_string = "libwebsockets";
+ context->server_string_len = 13;
+ }
+
#if LWS_MAX_SMP > 1
/* each thread serves his own chunk of fds */
for (n = 1; n < (int)info->count_threads; n++)
lws_context_init_ssl_library(info);
+ context->user_space = info->user;
+
/*
* if he's not saying he'll make his own vhosts later then act
* compatibly and make a default vhost using the data in the info
*/
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
- if (!lws_create_vhost(context, info, NULL)) {
+ if (!lws_create_vhost(context, info)) {
lwsl_err("Failed to create default vhost\n");
return NULL;
}
lws_context_init_extensions(info, context);
- context->user_space = info->user;
-
lwsl_notice(" mem: per-conn: %5u bytes + protocol rx buf\n",
sizeof(struct lws));
if (vh->protocol_vh_privs)
lws_free(vh->protocol_vh_privs);
lws_ssl_SSL_CTX_destroy(vh);
+ lws_free(vh->same_vh_protocol_list);
#ifdef LWS_WITH_PLUGINS
if (context->plugin_list)
lws_free((void *)vh->protocols);
lws_free((void *)vh->extensions);
#endif
#endif
+#ifdef LWS_WITH_ACCESS_LOG
+ if (vh->log_fd != LWS_INVALID_FILE)
+ close(vh->log_fd);
+#endif
+
vh1 = vh->vhost_next;
lws_free(vh);
vh = vh1;