/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#if defined(CONFIG_NET_DEBUG_HTTP)
#if defined(CONFIG_HTTPS)
#define SYS_LOG_DOMAIN "https/server"
#else
#define SYS_LOG_DOMAIN "http/server"
#endif
#define NET_LOG_ENABLED 1
#endif

#define RX_EXTRA_DEBUG 0

#include <misc/printk.h>

#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/net_context.h>

#include <net/http.h>

#if defined(CONFIG_HTTPS)
static void https_enable(struct http_server_ctx *ctx);
static void https_disable(struct http_server_ctx *ctx);

#if defined(MBEDTLS_DEBUG_C)
#include <mbedtls/debug.h>
/* - Debug levels (from ext/lib/crypto/mbedtls/include/mbedtls/debug.h)
 *    - 0 No debug
 *    - 1 Error
 *    - 2 State change
 *    - 3 Informational
 *    - 4 Verbose
 */
#define DEBUG_THRESHOLD 0
#endif

#endif /* CONFIG_HTTPS */

#define HTTP_DEFAULT_PORT  80
#define HTTPS_DEFAULT_PORT 443

#define RC_STR(rc)	(rc == 0 ? "OK" : "ERROR")

#define HTTP_STATUS_200_OK	"HTTP/1.1 200 OK\r\n" \
				"Content-Type: text/html\r\n" \
				"Transfer-Encoding: chunked\r\n" \
				"\r\n"

#define HTTP_STATUS_400_BR	"HTTP/1.1 400 Bad Request\r\n" \
				"\r\n"

#define HTTP_STATUS_403_FBD	"HTTP/1.1 403 Forbidden\r\n" \
				"\r\n"

#define HTTP_STATUS_404_NF	"HTTP/1.1 404 Not Found\r\n" \
				"\r\n"

#if defined(CONFIG_NET_DEBUG_HTTP_CONN)
/** List of HTTP connections */
static sys_slist_t http_conn;

static http_server_cb_t ctx_mon;
static void *mon_user_data;

static void http_server_conn_add(struct http_server_ctx *ctx)
{
	sys_slist_prepend(&http_conn, &ctx->node);

	if (ctx_mon) {
		ctx_mon(ctx, mon_user_data);
	}
}

static void http_server_conn_del(struct http_server_ctx *ctx)
{
	sys_slist_find_and_remove(&http_conn, &ctx->node);
}

void http_server_conn_foreach(http_server_cb_t cb, void *user_data)
{
	struct http_server_ctx *ctx;

	SYS_SLIST_FOR_EACH_CONTAINER(&http_conn, ctx, node) {
		cb(ctx, user_data);
	}
}

void http_server_conn_monitor(http_server_cb_t cb, void *user_data)
{
	ctx_mon = cb;
	mon_user_data = user_data;
}
#else
#define http_server_conn_add(...)
#define http_server_conn_del(...)
#endif /* CONFIG_NET_DEBUG_HTTP_CONN */

static inline u16_t http_strlen(const char *str)
{
	if (str) {
		return strlen(str);
	}

	return 0;
}

static int http_add_header(struct net_pkt *pkt, s32_t timeout, const char *str)
{
	if (net_pkt_append_all(pkt, strlen(str), (u8_t *)str, timeout)) {
		return 0;
	}

	return -ENOMEM;
}

static int http_add_chunk(struct net_pkt *pkt, s32_t timeout, const char *str)
{
	char chunk_header[16];
	u16_t str_len;
	bool ret;

	str_len = http_strlen(str);

	snprintk(chunk_header, sizeof(chunk_header), "%x\r\n", str_len);

	ret = net_pkt_append_all(pkt, strlen(chunk_header), chunk_header,
				 timeout);
	if (!ret) {
		return -ENOMEM;
	}

	if (str_len > 0) {
		ret = net_pkt_append_all(pkt, str_len, (u8_t *)str, timeout);
		if (!ret) {
			return -ENOMEM;
		}
	}

	ret = net_pkt_append_all(pkt, sizeof(HTTP_CRLF) - 1, HTTP_CRLF,
				 timeout);
	if (!ret) {
		return -ENOMEM;
	}

	return 0;
}

static void req_timer_cancel(struct http_server_ctx *ctx)
{
	k_delayed_work_cancel(&ctx->req.timer);

	NET_DBG("Context %p request timer cancelled", ctx);
}

static void req_timeout(struct k_work *work)
{
	struct http_server_ctx *ctx = CONTAINER_OF(work,
						   struct http_server_ctx,
						   req.timer);

	NET_DBG("Context %p request timeout", ctx);

	net_context_put(ctx->req.net_ctx);
	ctx->req.net_ctx = NULL;

	http_server_conn_del(ctx);
}

static void pkt_sent(struct net_context *context,
		     int status,
		     void *token,
		     void *user_data)
{
	s32_t timeout = POINTER_TO_INT(token);
	struct http_server_ctx *ctx = user_data;

	req_timer_cancel(ctx);

	if (timeout == K_NO_WAIT) {
		/* We can just close the context after the packet is sent. */
		net_context_put(context);
		http_server_conn_del(ctx);
	} else if (timeout > 0) {
		NET_DBG("Context %p starting timer", ctx);

		k_delayed_work_submit(&ctx->req.timer, timeout);
	}

	/* Note that if the timeout is K_FOREVER, we do not close
	 * the connection.
	 */
}

int http_response_wait(struct http_server_ctx *ctx, const char *http_header,
		       const char *html_payload, s32_t timeout)
{
	struct net_pkt *pkt;
	int ret = -EINVAL;

	pkt = net_pkt_get_tx(ctx->req.net_ctx, ctx->timeout);
	if (!pkt) {
		return ret;
	}

	ret = http_add_header(pkt, ctx->timeout, http_header);
	if (ret != 0) {
		goto exit_routine;
	}

	if (html_payload) {
		ret = http_add_chunk(pkt, ctx->timeout, html_payload);
		if (ret != 0) {
			goto exit_routine;
		}

		/* like EOF */
		ret = http_add_chunk(pkt, ctx->timeout, NULL);
		if (ret != 0) {
			goto exit_routine;
		}
	}

	net_pkt_set_appdatalen(pkt, net_buf_frags_len(pkt->frags));

	ret = ctx->send_data(pkt, pkt_sent, 0, INT_TO_POINTER(timeout), ctx);
	if (ret != 0) {
		goto exit_routine;
	}

	pkt = NULL;

exit_routine:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return ret;
}

int http_response(struct http_server_ctx *ctx, const char *http_header,
		  const char *html_payload)
{
	return http_response_wait(ctx, http_header, html_payload, K_NO_WAIT);
}

int http_response_400(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_400_BR, html_payload);
}

int http_response_403(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_403_FBD, html_payload);
}

int http_response_404(struct http_server_ctx *ctx, const char *html_payload)
{
	return http_response(ctx, HTTP_STATUS_404_NF, html_payload);
}

int http_response_send_data(struct http_server_ctx *ctx,
			    const char *http_header,
			    const char *html_payload,
			    s32_t timeout)
{
	struct net_pkt *pkt;
	int ret = -EINVAL;

	pkt = net_pkt_get_tx(ctx->req.net_ctx, ctx->timeout);
	if (!pkt) {
		return ret;
	}

	if (http_header) {
		ret = http_add_header(pkt, ctx->timeout, http_header);
		if (ret != 0) {
			goto exit_routine;
		}
	}

	ret = http_add_chunk(pkt, ctx->timeout, html_payload);
	if (ret != 0) {
		goto exit_routine;
	}

	net_pkt_set_appdatalen(pkt, net_buf_frags_len(pkt->frags));

	ret = ctx->send_data(pkt, pkt_sent, 0, INT_TO_POINTER(timeout), ctx);
	if (ret != 0) {
		goto exit_routine;
	}

	pkt = NULL;

	/* We must let the system to send the packet, otherwise TCP might
	 * timeout before the packet is actually sent. This is easily seen
	 * if the application calls this functions many times in a row.
	 */
	k_yield();

exit_routine:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return ret;
}

int http_server_set_local_addr(struct sockaddr *addr, const char *myaddr,
			       u16_t port)
{
	if (!addr) {
		return -EINVAL;
	}

	if (myaddr) {
		void *inaddr;

		if (addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
			inaddr = &net_sin(addr)->sin_addr;
			net_sin(addr)->sin_port = htons(port);
#else
			return -EPFNOSUPPORT;
#endif
		} else if (addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
			inaddr = &net_sin6(addr)->sin6_addr;
			net_sin6(addr)->sin6_port = htons(port);
#else
			return -EPFNOSUPPORT;
#endif
		} else {
			return -EAFNOSUPPORT;
		}

		return net_addr_pton(addr->sa_family, myaddr, inaddr);
	}

	/* If the caller did not supply the address where to bind, then
	 * try to figure it out ourselves.
	 */
	if (addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		net_ipaddr_copy(&net_sin6(addr)->sin6_addr,
				net_if_ipv6_select_src_addr(NULL,
					(struct in6_addr *)
					net_ipv6_unspecified_address()));
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		struct net_if *iface = net_if_get_default();

		/* For IPv4 we take the first address in the interface */
		net_ipaddr_copy(&net_sin(addr)->sin_addr,
				&iface->ipv4.unicast[0].address.in_addr);
#else
		return -EPFNOSUPPORT;
#endif
	}

	return 0;
}

struct http_root_url *http_server_add_url(struct http_server_urls *my,
					  const char *url, u8_t flags,
					  http_url_cb_t write_cb)
{
	int i;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		if (my->urls[i].is_used) {
			continue;
		}

		my->urls[i].is_used = true;
		my->urls[i].root = url;

		/* This will speed-up some future operations */
		my->urls[i].root_len = strlen(url);
		my->urls[i].flags = flags;
		my->urls[i].write_cb = write_cb;

		return &my->urls[i];
	}

	return NULL;
}

int http_server_del_url(struct http_server_urls *my, const char *url)
{
	int i;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		if (!my->urls[i].is_used) {
			continue;
		}

		if (strncmp(my->urls[i].root, url, my->urls[i].root_len)) {
			continue;
		}

		my->urls[i].is_used = false;
		my->urls[i].root = NULL;

		return 0;
	}

	return -ENOENT;
}

struct http_root_url *http_server_add_default(struct http_server_urls *my,
					      http_url_cb_t write_cb)
{
	if (my->default_url.is_used) {
		return NULL;
	}

	my->default_url.is_used = true;
	my->default_url.root = NULL;
	my->default_url.root_len = 0;
	my->default_url.flags = 0;
	my->default_url.write_cb = write_cb;

	return &my->default_url;
}

int http_server_del_default(struct http_server_urls *my)
{
	if (!my->default_url.is_used) {
		return -ENOENT;
	}

	my->default_url.is_used = false;

	return 0;
}

#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
static char *sprint_ipaddr(char *buf, int buflen, const struct sockaddr *addr)
{
	if (addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		char ipaddr[NET_IPV6_ADDR_LEN];

		net_addr_ntop(addr->sa_family,
			      &net_sin6(addr)->sin6_addr,
			      ipaddr, sizeof(ipaddr));
		snprintk(buf, buflen, "[%s]:%u", ipaddr,
			 ntohs(net_sin6(addr)->sin6_port));
#endif
	} else if (addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		char ipaddr[NET_IPV4_ADDR_LEN];

		net_addr_ntop(addr->sa_family,
			      &net_sin(addr)->sin_addr,
			      ipaddr, sizeof(ipaddr));
		snprintk(buf, buflen, "%s:%u", ipaddr,
			 ntohs(net_sin(addr)->sin_port));
#endif
	}

	return buf;
}
#endif /* CONFIG_NET_DEBUG_HTTP */

static inline void new_client(struct http_server_ctx *http_ctx,
			      struct net_context *net_ctx,
			      const struct sockaddr *addr)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof("[]:xxxxx")
	char buf[NET_IPV6_ADDR_LEN + PORT_STR];
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof(":xxxxx")
	char buf[NET_IPV4_ADDR_LEN + PORT_STR];
#endif

	NET_INFO("%s connection from %s (%p)",
		 http_ctx->is_https ? "HTTPS" : "HTTP",
		 sprint_ipaddr(buf, sizeof(buf), addr),
		 net_ctx);
#endif /* CONFIG_NET_DEBUG_HTTP */
}

static inline void new_server(struct http_server_ctx *ctx,
			      const char *server_banner,
			      const struct sockaddr *addr)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof("[]:xxxxx")
	char buf[NET_IPV6_ADDR_LEN + PORT_STR];
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
#define PORT_STR sizeof(":xxxxx")
	char buf[NET_IPV4_ADDR_LEN + PORT_STR];
#endif

	if (addr) {
		NET_INFO("%s %s (%p)", server_banner,
			 sprint_ipaddr(buf, sizeof(buf), addr), ctx);
	} else {
		NET_INFO("%s (%p)", server_banner, ctx);
	}
#endif /* CONFIG_NET_DEBUG_HTTP */
}

static int on_header_field(struct http_parser *parser,
			   const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	if (ctx->req.field_values_ctr >= CONFIG_HTTP_HEADER_FIELD_ITEMS) {
		return 0;
	}

	ctx->req.field_values[ctx->req.field_values_ctr].key = at;
	ctx->req.field_values[ctx->req.field_values_ctr].key_len = length;

	return 0;
}

static int on_header_value(struct http_parser *parser,
			   const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	if (ctx->req.field_values_ctr >= CONFIG_HTTP_HEADER_FIELD_ITEMS) {
		return 0;
	}

	ctx->req.field_values[ctx->req.field_values_ctr].value = at;
	ctx->req.field_values[ctx->req.field_values_ctr].value_len = length;

	ctx->req.field_values_ctr++;

	return 0;
}

static int on_url(struct http_parser *parser, const char *at, size_t length)
{
	struct http_server_ctx *ctx = parser->data;

	ctx->req.url = at;
	ctx->req.url_len = length;

	http_server_conn_add(ctx);

	return 0;
}

static int parser_init(struct http_server_ctx *ctx)
{
	memset(ctx->req.field_values, 0, sizeof(ctx->req.field_values));

	ctx->req.settings.on_header_field = on_header_field;
	ctx->req.settings.on_header_value = on_header_value;
	ctx->req.settings.on_url = on_url;

	http_parser_init(&ctx->req.parser, HTTP_REQUEST);

	ctx->req.parser.data = ctx;

	return 0;
}

static int http_url_cmp(const char *url, u16_t url_len,
			const char *root_url, u16_t root_url_len)
{
	if (url_len < root_url_len) {
		return -EINVAL;
	}

	if (memcmp(url, root_url, root_url_len) == 0) {
		if (url_len == root_url_len) {
			return 0;
		}

		/* Here we evaluate the following conditions:
		 * root_url = /images, url = /images/ -> OK
		 * root_url = /images/, url = /images/img.png -> OK
		 * root_url = /images/, url = /images_and_docs -> ERROR
		 */
		if (url_len > root_url_len) {
			if (root_url[root_url_len - 1] == '/') {
				return 0;
			}

			if (url[root_url_len] == '/') {
				return 0;
			}
		}
	}

	return -EINVAL;
}

static struct http_root_url *http_url_find(struct http_server_ctx *http_ctx)
{
	u16_t url_len = http_ctx->req.url_len;
	const char *url = http_ctx->req.url;
	struct http_root_url *root_url;
	u8_t i;
	int ret;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		root_url = &http_ctx->urls->urls[i];
		if (!root_url->is_used) {
			continue;
		}

		ret = http_url_cmp(url, url_len,
				   root_url->root, root_url->root_len);
		if (!ret) {
			return root_url;
		}
	}

	return NULL;
}

static int http_process_recv(struct http_server_ctx *http_ctx)
{
	struct http_root_url *root_url;
	int ret;

	root_url = http_url_find(http_ctx);
	if (!root_url) {
		root_url = &http_ctx->urls->default_url;
		if (!root_url->is_used) {
			NET_DBG("No default handler found (%p)", http_ctx);
			ret = -ENOENT;
			goto out;
		}
	}

	if (root_url->write_cb) {
		NET_DBG("Calling handler %p context %p",
			root_url->write_cb, http_ctx);
		ret = root_url->write_cb(http_ctx);
	} else {
		NET_ERR("No handler for %s", http_ctx->req.url);
		ret = -ENOENT;
	}

out:
	return ret;
}

static void http_recv(struct net_context *net_ctx,
		      struct net_pkt *pkt, int status,
		      void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;
	struct net_buf *frag;
	size_t start = http_ctx->req.data_len;
	int parsed_len;
	int header_len;
	u16_t len = 0, recv_len;

	if (!pkt) {
		NET_DBG("Connection closed by peer");
		return;
	}

	if (!http_ctx->enabled) {
		goto quit;
	}

	recv_len = net_pkt_appdatalen(pkt);
	if (recv_len == 0) {
		/* don't print info about zero-length app data buffers */
		goto quit;
	}

	if (status) {
		NET_DBG("Status %d <%s>", status, RC_STR(status));
		goto out;
	}

	/* Get rid of possible IP headers in the first fragment. */
	frag = pkt->frags;

	header_len = net_pkt_appdata(pkt) - frag->data;

	NET_DBG("Received %d bytes data", net_pkt_appdatalen(pkt));

	/* After this pull, the frag->data points directly to application data.
	 */
	net_buf_pull(frag, header_len);

	while (frag) {
		/* If this fragment cannot be copied to result buf,
		 * then parse what we have which will cause the callback to be
		 * called in function on_body(), and continue copying.
		 */
		if (http_ctx->req.data_len + frag->len >
		    http_ctx->req.request_buf_len) {

			/* If the caller has not supplied a callback, then
			 * we cannot really continue if the request buffer
			 * overflows. Set the data_len to mark how many bytes
			 * should be needed in the response_buf.
			 */
			if (http_process_recv(http_ctx) < 0) {
				http_ctx->req.data_len = net_pkt_get_len(pkt);
				goto out;
			}

			parsed_len =
				http_parser_execute(&http_ctx->req.parser,
						    &http_ctx->req.settings,
						    http_ctx->req.request_buf +
						    start,
						    len);
			if (parsed_len <= 0) {
				goto fail;
			}

			http_ctx->req.data_len = 0;
			len = 0;
			start = 0;
		}

		memcpy(http_ctx->req.request_buf + http_ctx->req.data_len,
		       frag->data, frag->len);

		http_ctx->req.data_len += frag->len;
		len += frag->len;
		frag = frag->frags;
	}

out:
	parsed_len = http_parser_execute(&http_ctx->req.parser,
					 &http_ctx->req.settings,
					 http_ctx->req.request_buf + start,
					 len);
	if (parsed_len < 0) {
fail:
		NET_DBG("Received %u bytes, only parsed %d bytes (%s %s)",
			recv_len, parsed_len,
			http_errno_name(http_ctx->req.parser.http_errno),
			http_errno_description(
				http_ctx->req.parser.http_errno));
	}

	if (http_ctx->req.parser.http_errno != HPE_OK) {
		http_response_400(http_ctx, NULL);
	} else {
		http_process_recv(http_ctx);
	}

quit:
	http_parser_init(&http_ctx->req.parser, HTTP_REQUEST);
	http_ctx->req.field_values_ctr = 0;
	http_ctx->req.data_len = 0;
	net_pkt_unref(pkt);
}

static void accept_cb(struct net_context *net_ctx,
		      struct sockaddr *addr, socklen_t addrlen,
		      int status, void *data)
{
	struct http_server_ctx *http_ctx = data;
	int ret;

	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	if (status != 0) {
		net_context_put(net_ctx);
		return;
	}

	/* If we receive a HTTP request and if the earlier context is still
	 * active and it is not the same as the new one, then close the earlier
	 * one. Otherwise it is possible that the context will be left into
	 * TCP ESTABLISHED state and would never be released. Example of this
	 * is that we had IPv4 connection active and then IPv6 connection is
	 * established, in this case we disconnect the IPv4 here.
	 */
	if (http_ctx->req.net_ctx && http_ctx->req.net_ctx != net_ctx &&
	    net_context_get_state(http_ctx->req.net_ctx) ==
						      NET_CONTEXT_CONNECTED) {
		net_context_put(http_ctx->req.net_ctx);
	}

	http_ctx->req.net_ctx = net_ctx;

	new_client(http_ctx, net_ctx, addr);

	ret = net_context_recv(net_ctx, http_ctx->recv_cb, K_NO_WAIT,
			       http_ctx);
	if (ret < 0) {
		NET_DBG("Cannot set recv_cb (%d)", ret);
	}
}

static int set_net_ctx(struct http_server_ctx *http_ctx,
		       struct net_context *ctx,
		       struct sockaddr *addr,
		       socklen_t socklen)
{
	int ret;

	ret = net_context_bind(ctx, addr, socklen);
	if (ret < 0) {
		NET_ERR("Cannot bind context (%d)", ret);
		goto out;
	}

	ret = net_context_listen(ctx, 0);
	if (ret < 0) {
		NET_ERR("Cannot listen context (%d)", ret);
		goto out;
	}

	ret = net_context_accept(ctx, accept_cb, K_NO_WAIT, http_ctx);
	if (ret < 0) {
		NET_ERR("Cannot accept context (%d)", ret);
		goto out;
	}

out:
	return ret;
}

#if defined(CONFIG_NET_IPV4)
static int setup_ipv4_ctx(struct http_server_ctx *http_ctx,
			  struct sockaddr *addr)
{
	socklen_t socklen;
	int ret;

	socklen = sizeof(struct sockaddr_in);

	ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP,
			      &http_ctx->net_ipv4_ctx);
	if (ret < 0) {
		NET_ERR("Cannot get network context (%d)", ret);
		http_ctx->net_ipv4_ctx = NULL;
		return ret;
	}

	net_context_setup_pools(http_ctx->net_ipv4_ctx, http_ctx->tx_slab,
				http_ctx->data_pool);

	if (addr->sa_family == AF_UNSPEC) {
		addr->sa_family = AF_INET;

		http_server_set_local_addr(addr, NULL,
					   net_sin(addr)->sin_port);
	}

	ret = set_net_ctx(http_ctx, http_ctx->net_ipv4_ctx,
			  addr, socklen);
	if (ret < 0) {
		net_context_put(http_ctx->net_ipv4_ctx);
		http_ctx->net_ipv4_ctx = NULL;
	}

	return ret;
}
#endif

#if defined(CONFIG_NET_IPV6)
int setup_ipv6_ctx(struct http_server_ctx *http_ctx, struct sockaddr *addr)
{
	socklen_t socklen;
	int ret;

	socklen = sizeof(struct sockaddr_in6);

	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP,
			      &http_ctx->net_ipv6_ctx);
	if (ret < 0) {
		NET_ERR("Cannot get network context (%d)", ret);
		http_ctx->net_ipv6_ctx = NULL;
		return ret;
	}

	net_context_setup_pools(http_ctx->net_ipv6_ctx, http_ctx->tx_slab,
				http_ctx->data_pool);

	if (addr->sa_family == AF_UNSPEC) {
		addr->sa_family = AF_INET6;

		http_server_set_local_addr(addr, NULL,
					   net_sin6(addr)->sin6_port);
	}

	ret = set_net_ctx(http_ctx, http_ctx->net_ipv6_ctx,
			  addr, socklen);
	if (ret < 0) {
		net_context_put(http_ctx->net_ipv6_ctx);
		http_ctx->net_ipv6_ctx = NULL;
	}

	return ret;
}
#endif

static int init_net(struct http_server_ctx *ctx,
		    struct sockaddr *server_addr,
		    u16_t port)
{
	struct sockaddr addr;
	int ret;

	memset(&addr, 0, sizeof(addr));

	if (server_addr) {
		memcpy(&addr, server_addr, sizeof(addr));
	} else {
		addr.sa_family = AF_UNSPEC;
		net_sin(&addr)->sin_port = htons(port);
	}

	if (addr.sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		ret = setup_ipv6_ctx(ctx, &addr);
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr.sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		ret = setup_ipv4_ctx(ctx, &addr);
#else
		return -EPFNOSUPPORT;
#endif
	} else if (addr.sa_family == AF_UNSPEC) {
#if defined(CONFIG_NET_IPV4)
		ret = setup_ipv4_ctx(ctx, &addr);
#endif
		/* We ignore the IPv4 error if IPv6 is enabled */
#if defined(CONFIG_NET_IPV6)
		memset(&addr, 0, sizeof(addr));
		addr.sa_family = AF_UNSPEC;
		net_sin6(&addr)->sin6_port = htons(port);

		ret = setup_ipv6_ctx(ctx, &addr);
#endif
	} else {
		return -EINVAL;
	}

	return ret;
}

bool http_server_enable(struct http_server_ctx *http_ctx)
{
	bool old;

	NET_ASSERT(http_ctx);

	old = http_ctx->enabled;

	http_ctx->enabled = true;

#if defined(CONFIG_HTTPS)
	if (http_ctx->is_https) {
		https_enable(http_ctx);
	}
#endif
	return old;
}

bool http_server_disable(struct http_server_ctx *http_ctx)
{
	bool old;

	NET_ASSERT(http_ctx);

	req_timer_cancel(http_ctx);

	old = http_ctx->enabled;

	http_ctx->enabled = false;

#if defined(CONFIG_HTTPS)
	if (http_ctx->is_https) {
		https_disable(http_ctx);
	}
#endif
	return old;
}

int http_server_init(struct http_server_ctx *http_ctx,
		     struct http_server_urls *urls,
		     struct sockaddr *server_addr,
		     u8_t *request_buf,
		     size_t request_buf_len,
		     const char *server_banner)
{
	int ret;

	if (http_ctx->urls) {
		NET_ERR("Server context %p already initialized", http_ctx);
		return -EINVAL;
	}

	if (!request_buf || request_buf_len == 0) {
		NET_ERR("Request buf must be set");
		return -EINVAL;
	}

	ret = init_net(http_ctx, server_addr, HTTP_DEFAULT_PORT);
	if (ret < 0) {
		return ret;
	}

	if (server_banner) {
		new_server(http_ctx, server_banner, server_addr);
	}

	http_ctx->req.request_buf = request_buf;
	http_ctx->req.request_buf_len = request_buf_len;
	http_ctx->req.data_len = 0;
	http_ctx->urls = urls;
	http_ctx->recv_cb = http_recv;
	http_ctx->send_data = net_context_send;

	k_delayed_work_init(&http_ctx->req.timer, req_timeout);

	parser_init(http_ctx);

	return 0;
}

void http_server_release(struct http_server_ctx *http_ctx)
{
	if (!http_ctx->urls) {
		return;
	}

	http_server_disable(http_ctx);

#if defined(CONFIG_NET_IPV4)
	if (http_ctx->net_ipv4_ctx) {
		net_context_put(http_ctx->net_ipv4_ctx);
		http_ctx->net_ipv4_ctx = NULL;
	}
#endif
#if defined(CONFIG_NET_IPV6)
	if (http_ctx->net_ipv6_ctx) {
		net_context_put(http_ctx->net_ipv6_ctx);
		http_ctx->net_ipv6_ctx = NULL;
	}
#endif

	http_ctx->req.net_ctx = NULL;
	http_ctx->urls = NULL;
}

#if defined(CONFIG_HTTPS)
struct rx_fifo_block {
	sys_snode_t snode;
	struct k_mem_block block;
	struct net_pkt *pkt;
};

#if defined(MBEDTLS_DEBUG_C) && defined(CONFIG_NET_DEBUG_HTTP)
static void my_debug(void *ctx, int level,
		     const char *file, int line, const char *str)
{
	const char *p, *basename;
	int len;

	ARG_UNUSED(ctx);

	/* Extract basename from file */
	for (p = basename = file; *p != '\0'; p++) {
		if (*p == '/' || *p == '\\') {
			basename = p + 1;
		}

	}

	/* Avoid printing double newlines */
	len = strlen(str);
	if (str[len - 1] == '\n') {
		((char *)str)[len - 1] = '\0';
	}

	NET_DBG("%s:%04d: |%d| %s", basename, line, level, str);
}
#endif /* MBEDTLS_DEBUG_C && CONFIG_NET_DEBUG_HTTP */

#if defined(MBEDTLS_ERROR_C)
#define print_error(fmt, ret)						\
	do {								\
		char error[64];						\
									\
		mbedtls_strerror(ret, error, sizeof(error));		\
									\
		NET_ERR(fmt " (%s)", -ret, error);			\
	} while (0)
#else
#define print_error(fmt, ret)						\
	do {								\
		NET_ERR(fmt, -ret);					\
	} while (0)
#endif

#define BUF_ALLOC_TIMEOUT 100

/* Receive encrypted data from network. Put that data into fifo
 * that will be read by https thread.
 */
static void ssl_received(struct net_context *context,
			 struct net_pkt *pkt,
			 int status,
			 void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;
	struct rx_fifo_block *rx_data = NULL;
	struct k_mem_block block;
	int ret;

	ARG_UNUSED(context);
	ARG_UNUSED(status);

	if (pkt && !net_pkt_appdatalen(pkt)) {
		net_pkt_unref(pkt);
		return;
	}

	ret = k_mem_pool_alloc(http_ctx->https.pool, &block,
			       sizeof(struct rx_fifo_block),
			       BUF_ALLOC_TIMEOUT);
	if (ret < 0) {
		net_pkt_unref(pkt);
		return;
	}

	rx_data = block.data;
	rx_data->pkt = pkt;

	/* For freeing memory later */
	memcpy(&rx_data->block, &block, sizeof(struct k_mem_block));

	k_fifo_put(&http_ctx->https.mbedtls.ssl_ctx.rx_fifo, (void *)rx_data);
}

/* This will copy data from received net_pkt buf into mbedtls internal buffers.
 */
static int ssl_rx(void *context, unsigned char *buf, size_t size)
{
	struct http_server_ctx *ctx = context;
	struct rx_fifo_block *rx_data;
	u16_t read_bytes;
	u8_t *ptr;
	int pos;
	int len;
	int ret = 0;

	if (!ctx->https.mbedtls.ssl_ctx.frag) {
		rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo,
				     K_FOREVER);
		if (!rx_data->pkt) {
			NET_DBG("Closing %p connection", ctx);
			k_mem_pool_free(&rx_data->block);
			return -EIO;
		}

		ctx->https.mbedtls.ssl_ctx.rx_pkt = rx_data->pkt;

		k_mem_pool_free(&rx_data->block);

		read_bytes = net_pkt_appdatalen(
					ctx->https.mbedtls.ssl_ctx.rx_pkt);

		ctx->https.mbedtls.ssl_ctx.remaining = read_bytes;
		ctx->https.mbedtls.ssl_ctx.frag =
			ctx->https.mbedtls.ssl_ctx.rx_pkt->frags;

		ptr = net_pkt_appdata(ctx->https.mbedtls.ssl_ctx.rx_pkt);
		len = ptr - ctx->https.mbedtls.ssl_ctx.frag->data;

		if (len > ctx->https.mbedtls.ssl_ctx.frag->size) {
			NET_ERR("Buf overflow (%d > %u)", len,
				ctx->https.mbedtls.ssl_ctx.frag->size);
			return -EINVAL;
		} else {
			/* This will get rid of IP header */
			net_buf_pull(ctx->https.mbedtls.ssl_ctx.frag, len);
		}
	} else {
		read_bytes = ctx->https.mbedtls.ssl_ctx.remaining;
		ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
	}

	len = ctx->https.mbedtls.ssl_ctx.frag->len;
	pos = 0;
	if (read_bytes > size) {
		while (ctx->https.mbedtls.ssl_ctx.frag) {
			read_bytes = len < (size - pos) ? len : (size - pos);

#if RX_EXTRA_DEBUG == 1
			NET_DBG("Copying %d bytes", read_bytes);
#endif

			memcpy(buf + pos, ptr, read_bytes);

			pos += read_bytes;
			if (pos < size) {
				ctx->https.mbedtls.ssl_ctx.frag =
					ctx->https.mbedtls.ssl_ctx.frag->frags;
				ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
				len = ctx->https.mbedtls.ssl_ctx.frag->len;
			} else {
				if (read_bytes == len) {
					ctx->https.mbedtls.ssl_ctx.frag =
					ctx->https.mbedtls.ssl_ctx.frag->frags;
				} else {
					net_buf_pull(
					       ctx->https.mbedtls.ssl_ctx.frag,
					       read_bytes);
				}

				ctx->https.mbedtls.ssl_ctx.remaining -= size;
				return size;
			}
		}
	} else {
		while (ctx->https.mbedtls.ssl_ctx.frag) {
#if RX_EXTRA_DEBUG == 1
			NET_DBG("Copying all %d bytes", len);
#endif

			memcpy(buf + pos, ptr, len);

			pos += len;
			ctx->https.mbedtls.ssl_ctx.frag =
				ctx->https.mbedtls.ssl_ctx.frag->frags;
			if (!ctx->https.mbedtls.ssl_ctx.frag) {
				break;
			}

			ptr = ctx->https.mbedtls.ssl_ctx.frag->data;
			len = ctx->https.mbedtls.ssl_ctx.frag->len;
		}

		net_pkt_unref(ctx->https.mbedtls.ssl_ctx.rx_pkt);
		ctx->https.mbedtls.ssl_ctx.rx_pkt = NULL;
		ctx->https.mbedtls.ssl_ctx.frag = NULL;
		ctx->https.mbedtls.ssl_ctx.remaining = 0;

		if (read_bytes != pos) {
			return -EIO;
		}

		ret = read_bytes;
	}

	return ret;
}

static void ssl_sent(struct net_context *context,
		     int status, void *token, void *user_data)
{
	struct http_server_ctx *http_ctx = user_data;

	k_sem_give(&http_ctx->https.mbedtls.ssl_ctx.tx_sem);
}

/* Send encrypted data */
static int ssl_tx(void *context, const unsigned char *buf, size_t size)
{
	struct http_server_ctx *ctx = context;
	struct net_pkt *send_buf;
	int ret, len;

	send_buf = net_pkt_get_tx(ctx->req.net_ctx, BUF_ALLOC_TIMEOUT);
	if (!send_buf) {
		return MBEDTLS_ERR_SSL_ALLOC_FAILED;
	}

	ret = net_pkt_append_all(send_buf, size, (u8_t *)buf,
				 BUF_ALLOC_TIMEOUT);
	if (!ret) {
		/* Cannot append data */
		net_pkt_unref(send_buf);
		return 0;
	}

	len = size;

	ret = net_context_send(send_buf, ssl_sent, K_NO_WAIT, NULL, ctx);
	if (ret < 0) {
		net_pkt_unref(send_buf);
		return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
	}

	k_sem_take(&ctx->https.mbedtls.ssl_ctx.tx_sem, K_FOREVER);

	return len;
}

static int entropy_source(void *data, unsigned char *output, size_t len,
			  size_t *olen)
{
	u32_t seed;

	ARG_UNUSED(data);

	seed = sys_rand32_get();

	if (len > sizeof(seed)) {
		len = sizeof(seed);
	}

	memcpy(output, &seed, len);

	*olen = len;
	return 0;
}

/* This gets plain data and it sends encrypted one to peer */
static int https_send(struct net_pkt *pkt,
		      net_context_send_cb_t cb,
		      s32_t timeout,
		      void *token,
		      void *user_data)
{
	struct http_server_ctx *ctx = user_data;
	int ret;
	u16_t len;

	len = net_pkt_appdatalen(pkt);

	ret = net_frag_linearize(ctx->req.request_buf,
				 ctx->req.request_buf_len,
				 pkt, net_pkt_ip_hdr_len(pkt),
				 len);
	if (ret < 0) {
		NET_DBG("Cannot linearize send data (%d)", ret);
		return ret;
	}

	if (ret != len) {
		NET_DBG("Linear copy error (%u vs %d)", len, ret);
		return -EINVAL;
	}

	do {
		ret = mbedtls_ssl_write(&ctx->https.mbedtls.ssl,
					ctx->req.request_buf, len);
		if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
			print_error("peer closed the connection -0x%x", ret);
			goto out;
		}

		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret < 0) {
				print_error("mbedtls_ssl_write returned "
					    "-0x%x", ret);
				goto out;
			}
		}
	} while (ret <= 0);

out:
	if (cb) {
		cb(net_pkt_context(pkt), ret, token, user_data);
	}

	return ret;
}

static void https_handler(struct http_server_ctx *ctx)
{
	size_t len;
	int ret;

	NET_DBG("HTTPS handler starting");

	mbedtls_platform_set_printf(printk);

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt_init(&ctx->https.mbedtls.srvcert);
#endif

	mbedtls_pk_init(&ctx->https.mbedtls.pkey);
	mbedtls_ssl_init(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_config_init(&ctx->https.mbedtls.conf);
	mbedtls_entropy_init(&ctx->https.mbedtls.entropy);
	mbedtls_ctr_drbg_init(&ctx->https.mbedtls.ctr_drbg);

#if defined(MBEDTLS_DEBUG_C) && defined(CONFIG_NET_DEBUG_HTTP)
	mbedtls_debug_set_threshold(DEBUG_THRESHOLD);
	mbedtls_ssl_conf_dbg(&ctx->https.mbedtls.conf, my_debug, NULL);
#endif

	/* Load the certificates and private RSA key. This needs to be done
	 * by the user so we call a callback that user must have provided.
	 */
	ret = ctx->https.mbedtls.cert_cb(ctx, &ctx->https.mbedtls.srvcert,
					 &ctx->https.mbedtls.pkey);
	if (ret != 0) {
		goto exit;
	}

	/* Seed the RNG */
	mbedtls_entropy_add_source(&ctx->https.mbedtls.entropy,
				   ctx->https.mbedtls.entropy_src_cb,
				   NULL,
				   MBEDTLS_ENTROPY_MAX_GATHER,
				   MBEDTLS_ENTROPY_SOURCE_STRONG);

	ret = mbedtls_ctr_drbg_seed(
		&ctx->https.mbedtls.ctr_drbg,
		mbedtls_entropy_func,
		&ctx->https.mbedtls.entropy,
		(const unsigned char *)ctx->https.mbedtls.personalization_data,
		ctx->https.mbedtls.personalization_data_len);
	if (ret != 0) {
		print_error("mbedtls_ctr_drbg_seed returned -0x%x", ret);
		goto exit;
	}

	/* Setup SSL defaults etc. */
	ret = mbedtls_ssl_config_defaults(&ctx->https.mbedtls.conf,
					  MBEDTLS_SSL_IS_SERVER,
					  MBEDTLS_SSL_TRANSPORT_STREAM,
					  MBEDTLS_SSL_PRESET_DEFAULT);
	if (ret != 0) {
		print_error("mbedtls_ssl_config_defaults returned -0x%x", ret);
		goto exit;
	}

	mbedtls_ssl_conf_rng(&ctx->https.mbedtls.conf,
			     mbedtls_ctr_drbg_random,
			     &ctx->https.mbedtls.ctr_drbg);

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_ssl_conf_ca_chain(&ctx->https.mbedtls.conf,
				  ctx->https.mbedtls.srvcert.next,
				  NULL);

	ret = mbedtls_ssl_conf_own_cert(&ctx->https.mbedtls.conf,
					&ctx->https.mbedtls.srvcert,
					&ctx->https.mbedtls.pkey);
	if (ret != 0) {
		print_error("mbedtls_ssl_conf_own_cert returned -0x%x", ret);
		goto exit;
	}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

	ret = mbedtls_ssl_setup(&ctx->https.mbedtls.ssl,
				&ctx->https.mbedtls.conf);
	if (ret != 0) {
		print_error("mbedtls_ssl_setup returned -0x%x", ret);
		goto exit;
	}

reset:
	mbedtls_ssl_session_reset(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_set_bio(&ctx->https.mbedtls.ssl, ctx, ssl_tx,
			    ssl_rx, NULL);

	/* SSL handshake. The ssl_rx() function will be called next by
	 * mbedtls library. The ssl_rx() will block and wait that data is
	 * received by ssl_received() and passed to it via fifo. After
	 * receiving the data, this function will then proceed with secure
	 * connection establishment.
	 */
	/* Waiting SSL handshake */
	do {
		ret = mbedtls_ssl_handshake(&ctx->https.mbedtls.ssl);
		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret < 0) {
				goto reset;
			}
		}
	} while (ret != 0);

	/* Read the HTTPS Request */
	NET_DBG("Read HTTPS request");
	do {
		len = ctx->req.request_buf_len - 1;
		memset(ctx->req.request_buf, 0, ctx->req.request_buf_len);

		ret = mbedtls_ssl_read(&ctx->https.mbedtls.ssl,
				       ctx->req.request_buf, len);
		if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
		    ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
			continue;
		}

		if (ret <= 0) {
			switch (ret) {
			case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
				NET_DBG("Connection was closed gracefully");
				goto close;

			case MBEDTLS_ERR_NET_CONN_RESET:
				NET_DBG("Connection was reset by peer");
				break;

			default:
				print_error("mbedtls_ssl_read returned "
					    "-0x%x", ret);
				break;
			}

			goto close;
		}

		ret = http_parser_execute(&ctx->req.parser,
					  &ctx->req.settings,
					  ctx->req.request_buf,
					  ret);
	} while (ret < 0);

	/* Write the Response */
	NET_DBG("Write HTTPS response");

	if (ctx->req.parser.http_errno != HPE_OK) {
		http_response_400(ctx, NULL);
	} else {
		http_process_recv(ctx);
	}

close:
	http_parser_init(&ctx->req.parser, HTTP_REQUEST);
	ctx->req.field_values_ctr = 0;

	mbedtls_ssl_close_notify(&ctx->https.mbedtls.ssl);

	goto reset;

exit:
	return;
}

static void https_enable(struct http_server_ctx *ctx)
{
	/* Start the thread that handles HTTPS traffic. */
	if (ctx->https.tid) {
		return;
	}

	ctx->https.tid = k_thread_create(&ctx->https.thread,
					 ctx->https.stack,
					 ctx->https.stack_size,
					 (k_thread_entry_t)https_handler,
					 ctx, NULL, NULL,
					 K_PRIO_COOP(7), 0, 0);
}

static void https_disable(struct http_server_ctx *ctx)
{
	if (!ctx->https.tid) {
		return;
	}

	mbedtls_ssl_free(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_config_free(&ctx->https.mbedtls.conf);
	mbedtls_ctr_drbg_free(&ctx->https.mbedtls.ctr_drbg);
	mbedtls_entropy_free(&ctx->https.mbedtls.entropy);

	/* Empty the fifo just in case there is any received packets
	 * still there.
	 */
	while (1) {
		struct rx_fifo_block *rx_data;

		rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo,
				     K_NO_WAIT);
		if (!rx_data) {
			break;
		}

		net_pkt_unref(rx_data->pkt);

		k_mem_pool_free(&rx_data->block);
	}

	NET_DBG("HTTPS thread %p stopped", ctx->https.tid);

	k_thread_abort(ctx->https.tid);
	ctx->https.tid = 0;
}

static int https_init(struct http_server_ctx *ctx)
{
	k_sem_init(&ctx->https.mbedtls.ssl_ctx.tx_sem, 0, UINT_MAX);
	k_fifo_init(&ctx->https.mbedtls.ssl_ctx.rx_fifo);

	/* Next we return to application which must then enable the HTTPS
	 * service. The enable function will then start the https thread and
	 * do what ever further configuration needed.
	 *
	 * We do the mbedtls initialization in its own thread because it uses
	 * of of stack and the main stack runs out of memory very easily.
	 *
	 * See https_handler() how the things proceed from now on.
	 */

	return 0;
}

int https_server_init(struct http_server_ctx *ctx,
		      struct http_server_urls *urls,
		      struct sockaddr *server_addr,
		      u8_t *request_buf,
		      size_t request_buf_len,
		      const char *server_banner,
		      u8_t *personalization_data,
		      size_t personalization_data_len,
		      https_server_cert_cb_t cert_cb,
		      https_entropy_src_cb_t entropy_src_cb,
		      struct k_mem_pool *pool,
		      k_thread_stack_t *https_stack,
		      size_t https_stack_size)
{
	int ret;

	if (ctx->urls) {
		NET_ERR("Server context %p already initialized", ctx);
		return -EALREADY;
	}

	if (!request_buf || request_buf_len == 0) {
		NET_ERR("Request buf must be set");
		return -EINVAL;
	}

	if (!cert_cb) {
		NET_ERR("Cert callback must be set");
		return -EINVAL;
	}

	ret = init_net(ctx, server_addr, HTTPS_DEFAULT_PORT);
	if (ret < 0) {
		return ret;
	}

	if (server_banner) {
		new_server(ctx, server_banner, server_addr);
	}

	ctx->req.request_buf = request_buf;
	ctx->req.request_buf_len = request_buf_len;
	ctx->req.data_len = 0;
	ctx->urls = urls;
	ctx->is_https = true;
	ctx->https.stack = https_stack;
	ctx->https.stack_size = https_stack_size;
	ctx->https.mbedtls.cert_cb = cert_cb;
	ctx->https.pool = pool;

	if (entropy_src_cb) {
		ctx->https.mbedtls.entropy_src_cb = entropy_src_cb;
	} else {
		ctx->https.mbedtls.entropy_src_cb = entropy_source;
	}

	ctx->https.mbedtls.personalization_data = personalization_data;
	ctx->https.mbedtls.personalization_data_len = personalization_data_len;
	ctx->send_data = https_send;
	ctx->recv_cb = ssl_received;

	k_delayed_work_init(&ctx->req.timer, req_timeout);

	parser_init(ctx);

	/* Then mbedtls specific initialization */
	return https_init(ctx);
}
#endif /* CONFIG_HTTPS */

#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
int http_server_set_net_pkt_pool(struct http_server_ctx *ctx,
				 net_pkt_get_slab_func_t tx_slab,
				 net_pkt_get_pool_func_t data_pool)
{
	ctx->tx_slab = tx_slab;
	ctx->data_pool = data_pool;

	return 0;
}
#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */
