Skip to content
Snippets Groups Projects
context.c 45.4 KiB
Newer Older
/*
 * libwebsockets - small server side websockets and web server implementation
 *
 * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation:
 *  version 2.1 of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA  02110-1301  USA
 */


#ifndef LWS_BUILD_HASH
#define LWS_BUILD_HASH "unknown-build-hash"
#endif

const struct lws_role_ops *available_roles[] = {
#if defined(LWS_ROLE_H2)
	&role_ops_h2,
#endif
#if defined(LWS_ROLE_H1)
	&role_ops_h1,
#endif
#if defined(LWS_ROLE_WS)
	&role_ops_ws,
Andy Green's avatar
Andy Green committed
#endif
#if defined(LWS_ROLE_DBUS)
	&role_ops_dbus,
const struct lws_event_loop_ops *available_event_libs[] = {
#if defined(LWS_WITH_POLL)
	&event_loop_ops_poll,
#endif
#if defined(LWS_WITH_LIBUV)
	&event_loop_ops_uv,
#endif
#if defined(LWS_WITH_LIBEVENT)
	&event_loop_ops_event,
#endif
#if defined(LWS_WITH_LIBEV)
	&event_loop_ops_ev,
#endif
	NULL
};

static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH;

/**
 * lws_get_library_version: get version and git hash library built from
 *
 *	returns a const char * to a string like "1.1 178d78c"
 *	representing the library version followed by the git head hash it
 *	was built from
 */
LWS_VISIBLE const char *
lws_get_library_version(void)
{
	return library_version;
}

int
lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn)
{
#if defined(LWS_WITH_TLS)
	if (!alpn)
		return 0;

	lwsl_info("%s: '%s'\n", __func__, alpn);

	LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
		if (ar->alpn && !strcmp(ar->alpn, alpn) && ar->alpn_negotiated)
			return ar->alpn_negotiated(wsi, alpn);
	LWS_FOR_EVERY_AVAILABLE_ROLE_END;
#if !defined(LWS_WITHOUT_SERVER)
int
lws_role_call_adoption_bind(struct lws *wsi, int type, const char *prot)
{
	LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
		if (ar->adoption_bind)
			if (ar->adoption_bind(wsi, type, prot))
				return 0;
	LWS_FOR_EVERY_AVAILABLE_ROLE_END;

	/* fall back to raw socket role if, eg, h1 not configured */

	if (role_ops_raw_skt.adoption_bind &&
	    role_ops_raw_skt.adoption_bind(wsi, type, prot))
		return 0;

	/* fall back to raw file role if, eg, h1 not configured */

	if (role_ops_raw_file.adoption_bind &&
	    role_ops_raw_file.adoption_bind(wsi, type, prot))
		return 0;

	return 1;
}
#endif

#if !defined(LWS_WITHOUT_CLIENT)
int
lws_role_call_client_bind(struct lws *wsi,
			  const struct lws_client_connect_info *i)
{
	LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
		if (ar->client_bind) {
			int m = ar->client_bind(wsi, i);
			if (m < 0)
				return m;
			if (m)
				return 0;
		}
	LWS_FOR_EVERY_AVAILABLE_ROLE_END;

	/* fall back to raw socket role if, eg, h1 not configured */

	if (role_ops_raw_skt.client_bind &&
	    role_ops_raw_skt.client_bind(wsi, i))
		return 0;

	return 1;
}
#endif

Andy Green's avatar
Andy Green committed
static const char * const mount_protocols[] = {
	"http://",
	"https://",
	"file://",
	"cgi://",
	">http://",
	">https://",
	"callback://"
Andy Green's avatar
Andy Green committed
};

Andy Green's avatar
Andy Green committed
LWS_VISIBLE void *
Andy Green's avatar
Andy Green committed
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
			    const struct lws_protocols *prot, int size)
Andy Green's avatar
Andy Green committed
{
	int n = 0;

	/* allocate the vh priv array only on demand */
	if (!vhost->protocol_vh_privs) {
		vhost->protocol_vh_privs = (void **)lws_zalloc(
Andy Green's avatar
Andy Green committed
				vhost->count_protocols * sizeof(void *),
				"protocol_vh_privs");
Andy Green's avatar
Andy Green committed
		if (!vhost->protocol_vh_privs)
			return NULL;
	}

	while (n < vhost->count_protocols && &vhost->protocols[n] != prot)
		n++;

Andy Green's avatar
Andy Green committed
	if (n == vhost->count_protocols) {
		n = 0;
		while (n < vhost->count_protocols &&
		       strcmp(vhost->protocols[n].name, prot->name))
			n++;

		if (n == vhost->count_protocols)
			return NULL;
	}
Andy Green's avatar
Andy Green committed

Andy Green's avatar
Andy Green committed
	vhost->protocol_vh_privs[n] = lws_zalloc(size, "vh priv");
Andy Green's avatar
Andy Green committed
	return vhost->protocol_vh_privs[n];
}

LWS_VISIBLE void *
Andy Green's avatar
Andy Green committed
lws_protocol_vh_priv_get(struct lws_vhost *vhost,
			 const struct lws_protocols *prot)
Andy Green's avatar
Andy Green committed
{
	int n = 0;

	if (!vhost || !vhost->protocol_vh_privs || !prot)
Andy Green's avatar
Andy Green committed
		return NULL;

	while (n < vhost->count_protocols && &vhost->protocols[n] != prot)
		n++;

	if (n == vhost->count_protocols) {
Andy Green's avatar
Andy Green committed
		n = 0;
		while (n < vhost->count_protocols &&
		       strcmp(vhost->protocols[n].name, prot->name))
Loading
Loading full blame...