/*
 * 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_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

#include <zephyr.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <stdlib.h>
#include <version.h>

#include <net/net_core.h>
#include <net/net_ip.h>
#include <net/http.h>

#define BUF_ALLOC_TIMEOUT 100

#define HTTP_DEFAULT_PORT  80
#define HTTPS_DEFAULT_PORT 443

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

/* Max length of the error description in HTTP error reply */
#define MAX_DESCRIPTION_LEN 20

#define HTTP_STATUS_400_BR	"Bad Request"

#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;

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

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

void http_server_conn_del(struct http_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_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;
}
#endif /* CONFIG_NET_DEBUG_HTTP_CONN */

const char * const http_state_str(enum http_state state)
{
#if defined(CONFIG_NET_DEBUG_HTTP)
	switch (state) {
	case HTTP_STATE_CLOSED:
		return "CLOSED";
	case HTTP_STATE_WAITING_HEADER:
		return "WAITING_HEADER";
	case HTTP_STATE_RECEIVING_HEADER:
		return "RECEIVING HEADER";
	case HTTP_STATE_HEADER_RECEIVED:
		return "HEADER_RECEIVED";
	case HTTP_STATE_OPEN:
		return "OPEN";
	}
#else /* CONFIG_NET_DEBUG_HTTP */
	ARG_UNUSED(state);
#endif /* CONFIG_NET_DEBUG_HTTP */

	return "";
}

#if defined(CONFIG_NET_DEBUG_HTTP)
static void validate_state_transition(struct http_ctx *ctx,
				      enum http_state current,
				      enum http_state new)
{
	static const u16_t valid_transitions[] = {
		[HTTP_STATE_CLOSED] = 1 << HTTP_STATE_WAITING_HEADER,
		[HTTP_STATE_WAITING_HEADER] =
					1 << HTTP_STATE_RECEIVING_HEADER |
					1 << HTTP_STATE_CLOSED,
		[HTTP_STATE_RECEIVING_HEADER] =
					1 << HTTP_STATE_HEADER_RECEIVED |
					1 << HTTP_STATE_CLOSED |
					1 << HTTP_STATE_OPEN,
		[HTTP_STATE_HEADER_RECEIVED] =
					1 << HTTP_STATE_OPEN |
					1 << HTTP_STATE_CLOSED,
		[HTTP_STATE_OPEN] = 1 << HTTP_STATE_CLOSED,
	};

	if (!(valid_transitions[current] & 1 << new)) {
		NET_DBG("[%p] Invalid state transition: %s (%d) => %s (%d)",
			ctx, http_state_str(current), current,
			http_state_str(new), new);
	}
}
#endif /* CONFIG_NET_DEBUG_HTTP */

void _http_change_state(struct http_ctx *ctx,
			enum http_state new_state,
			const char *func, int line)
{
	if (ctx->state == new_state) {
		return;
	}

	NET_ASSERT(new_state >= HTTP_STATE_CLOSED &&
		   new_state <= HTTP_STATE_OPEN);

	NET_DBG("[%p] state %s (%d) => %s (%d) [%s():%d]",
		ctx, http_state_str(ctx->state), ctx->state,
		http_state_str(new_state), new_state,
		func, line);

#if defined(CONFIG_NET_DEBUG_HTTP)
	validate_state_transition(ctx, ctx->state, new_state);
#endif /* CONFIG_NET_DEBUG_HTTP */

	ctx->state = new_state;
}

static void http_data_sent(struct net_app_ctx *app_ctx,
			   int status,
			   void *user_data_send,
			   void *user_data)
{
	struct http_ctx *ctx = user_data;

	if (!user_data_send) {
		/* This is the token field in the net_context_send().
		 * If this is not set, then it is TCP ACK messages
		 * that are generated by the stack. We just ignore those.
		 */
		return;
	}

	if (ctx->state == HTTP_STATE_OPEN && ctx->cb.send) {
		ctx->cb.send(ctx, status, user_data_send, ctx->user_data);
	}
}

int http_send_error(struct http_ctx *ctx, int code, const char *description,
		    u8_t *html_payload, size_t html_len)
{
	char msg[sizeof(HTTP_PROTOCOL " xxx " HTTP_CRLF HTTP_CRLF) +
		 MAX_DESCRIPTION_LEN];
	int ret;

	if (ctx->pending) {
		net_pkt_unref(ctx->pending);
		ctx->pending = NULL;
	}

	if (code < 100 || code > 999) {
		return -EINVAL;
	}

	snprintk(msg, sizeof(msg), "%s %d %s%s%s", HTTP_PROTOCOL, code,
		 description, HTTP_CRLF, HTTP_CRLF);

	ret = http_add_header(ctx, msg, NULL);
	if (ret < 0) {
		goto quit;
	}

	if (html_payload) {
		ret = http_prepare_and_send(ctx, html_payload, html_len, NULL);
		if (ret < 0) {
			goto quit;
		}
	}

	ret = http_send_flush(ctx, NULL);

quit:
	if (ret < 0) {
		net_pkt_unref(ctx->pending);
		ctx->pending = NULL;
	}

	return ret;
}

#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
	} else {
		snprintk(buf, buflen, "<AF_UNSPEC %d>", addr->sa_family);
	}

	return buf;
}

static struct net_context *get_server_ctx(struct net_app_ctx *ctx,
					  const struct sockaddr *dst)
{
	int i;

	if (!dst) {
		return NULL;
	}

	for (i = 0; i < CONFIG_NET_APP_SERVER_NUM_CONN; i++) {
		struct net_context *tmp;
		u16_t port, rport;

		if (!ctx->server.net_ctxs[i]) {
			continue;
		}

		tmp = ctx->server.net_ctxs[i];

		if (IS_ENABLED(CONFIG_NET_IPV4) &&
		    tmp->remote.sa_family == AF_INET &&
		    dst->sa_family == AF_INET) {
			struct in_addr *addr4 = &net_sin(dst)->sin_addr;
			struct in_addr *remote4;

			remote4 = &net_sin(&tmp->remote)->sin_addr;
			rport = net_sin(&tmp->remote)->sin_port;
			port = net_sin(dst)->sin_port;

			if (net_ipv4_addr_cmp(addr4, remote4) &&
			    port == rport) {
				return tmp;
			}

		} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
			   tmp->remote.sa_family == AF_INET6 &&
			   dst->sa_family == AF_INET6) {
			struct in6_addr *addr6 = &net_sin6(dst)->sin6_addr;
			struct in6_addr *remote6;

			remote6 = &net_sin6(&tmp->remote)->sin6_addr;
			rport = net_sin6(&tmp->remote)->sin6_port;
			port = net_sin6(dst)->sin6_port;

			if (net_ipv6_addr_cmp(addr6, remote6) &&
			    port == rport) {
				return tmp;
			}
		}
	}

	return NULL;
}
#endif /* CONFIG_NET_DEBUG_HTTP */

static inline void new_client(struct http_ctx *ctx,
			      enum http_connection_type type,
			      struct net_app_ctx *app_ctx)
{
#if defined(CONFIG_NET_DEBUG_HTTP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
#define PORT_LEN sizeof("[]:xxxxx")
#define ADDR_LEN NET_IPV6_ADDR_LEN
#elif defined(CONFIG_NET_IPV4)
#define PORT_LEN sizeof(":xxxxx")
#define ADDR_LEN NET_IPV4_ADDR_LEN
#endif
	char buf[ADDR_LEN + PORT_LEN];
	struct net_context *net_ctx;
	const char *type_str = "HTTP";

	net_ctx = get_server_ctx(app_ctx, ctx->addr);
	if (net_ctx) {
		NET_INFO("[%p] %s connection from %s (%p)", ctx, type_str,
			 sprint_ipaddr(buf, sizeof(buf), &net_ctx->remote),
			 net_ctx);
	} else {
		NET_INFO("[%p] %s connection", ctx, type_str);
	}
#endif /* CONFIG_NET_DEBUG_HTTP */
}

static void url_connected(struct http_ctx *ctx,
			  enum http_connection_type type)
{
	new_client(ctx, type, &ctx->app_ctx);

	if (ctx->cb.connect) {
		ctx->cb.connect(ctx, type, ctx->user_data);
	}
}

struct http_root_url *http_server_add_url(struct http_server_urls *my,
					  const char *url, u8_t flags)
{
	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;

		NET_DBG("[%d] %s URL %s", i,
			flags == HTTP_URL_STANDARD ? "HTTP" :
			(flags == HTTP_URL_WEBSOCKET ? "WS" : "<unknown>"),
			url);

		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 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_cb = 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;
}

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) {
			/* Do not match root_url = / and url = /foobar */
			if (root_url_len > 1 &&
			    root_url[root_url_len - 1] == '/') {
				return 0;
			}

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

	return -EINVAL;
}

struct http_root_url *http_url_find(struct http_ctx *ctx,
				    enum http_url_flags flags)
{
	u16_t url_len = ctx->http.url_len;
	const char *url = ctx->http.url;
	struct http_root_url *root_url;
	u8_t i;
	int ret;

	for (i = 0; i < CONFIG_HTTP_SERVER_NUM_URLS; i++) {
		if (!ctx->http.urls) {
			continue;
		}

		root_url = &ctx->http.urls->urls[i];
		if (!root_url || !root_url->is_used) {
			continue;
		}

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

	return NULL;
}

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

	root_url = http_url_find(ctx, HTTP_URL_STANDARD);
	if (!root_url) {
		if (!ctx->http.urls) {
			NET_DBG("[%p] No URL handlers found", ctx);
			ret = -ENOENT;
			goto out;
		}

		root_url = &ctx->http.urls->default_url;
		if (!root_url || !root_url->is_used) {
			NET_DBG("[%p] No default handler found", ctx);
			ret = -ENOENT;
			goto out;
		}

		if (ctx->http.urls->default_cb) {
			ret = ctx->http.urls->default_cb(ctx,
							 HTTP_CONNECTION);
			if (ret != HTTP_VERDICT_ACCEPT) {
				ret = -ECONNREFUSED;
				goto out;
			}
		}
	}

	http_change_state(ctx, HTTP_STATE_OPEN);
	url_connected(ctx, HTTP_CONNECTION);

	ret = 0;

out:
	return ret;
}

static void http_closed(struct net_app_ctx *app_ctx,
			int status,
			void *user_data)
{
	struct http_ctx *ctx = user_data;

	ARG_UNUSED(app_ctx);
	ARG_UNUSED(status);

	http_change_state(ctx, HTTP_STATE_CLOSED);

	NET_DBG("[%p] http closed", ctx);

	http_server_conn_del(ctx);

	if (ctx->cb.close) {
		ctx->cb.close(ctx, 0, ctx->user_data);
	}
}

static void http_received(struct net_app_ctx *app_ctx,
			  struct net_pkt *pkt,
			  int status,
			  void *user_data)
{
	struct http_ctx *ctx = user_data;
	size_t start = ctx->http.data_len;
	u16_t len = 0;
	struct net_buf *frag;
	int parsed_len;
	size_t recv_len;
	size_t pkt_len;

	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("[%p] Status %d <%s>", ctx, status, RC_STR(status));
		goto out;
	}

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

	pkt_len = net_pkt_get_len(pkt);

	if (recv_len < pkt_len) {
		net_buf_pull(frag, pkt_len - recv_len);
		net_pkt_set_appdata(pkt, frag->data);
	}

	NET_DBG("[%p] Received %zd bytes http data", ctx, recv_len);

	if (ctx->state == HTTP_STATE_OPEN) {
		/* We have active websocket session and there is no longer
		 * any HTTP traffic in the connection. Give the data to
		 * application to send.
		 */
		goto http_only;
	}

	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 ((ctx->http.data_len + frag->len) >
		    ctx->http.request_buf_len) {

			if (ctx->state == HTTP_STATE_HEADER_RECEIVED) {
				goto http_ready;
			}

			/* 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(ctx) < 0) {
				ctx->http.data_len = recv_len;
				goto out;
			}

			parsed_len =
				http_parser_execute(&ctx->http.parser,
						    &ctx->http.parser_settings,
						    ctx->http.request_buf +
						    start,
						    len);
			if (parsed_len <= 0) {
				goto fail;
			}

			ctx->http.data_len = 0;
			len = 0;
			start = 0;
		}

		memcpy(ctx->http.request_buf + ctx->http.data_len,
		       frag->data, frag->len);

		ctx->http.data_len += frag->len;
		len += frag->len;
		frag = frag->frags;
	}

out:
	parsed_len = http_parser_execute(&ctx->http.parser,
					 &ctx->http.parser_settings,
					 ctx->http.request_buf + start,
					 len);
	if (parsed_len < 0) {
fail:
		NET_DBG("[%p] Received %zd bytes, only parsed %d "
			"bytes (%s %s)",
			ctx, recv_len, parsed_len,
			http_errno_name(ctx->http.parser.http_errno),
			http_errno_description(
				ctx->http.parser.http_errno));
	}

	if (ctx->http.parser.http_errno != HPE_OK) {
		http_send_error(ctx, 400, HTTP_STATUS_400_BR, NULL, 0);
	} else {
		if (ctx->state == HTTP_STATE_HEADER_RECEIVED) {
			goto http_ready;
		}

		http_process_recv(ctx);
	}

quit:
	http_parser_init(&ctx->http.parser, HTTP_REQUEST);
	ctx->http.data_len = 0;
	ctx->http.field_values_ctr = 0;
	net_pkt_unref(pkt);

	return;

http_only:
	if (ctx->cb.recv) {
		ctx->cb.recv(ctx, pkt, 0, 0, ctx->user_data);
	}

	return;

http_ready:
	http_change_state(ctx, HTTP_STATE_OPEN);
	url_connected(ctx, HTTP_CONNECT);
	net_pkt_unref(pkt);
}

#if defined(CONFIG_HTTPS)
int http_server_set_tls(struct http_ctx *ctx,
			const char *server_banner,
			u8_t *personalization_data,
			size_t personalization_data_len,
			net_app_cert_cb_t cert_cb,
			net_app_entropy_src_cb_t entropy_src_cb,
			struct k_mem_pool *pool,
			k_thread_stack_t *stack,
			size_t stack_len)
{
	int ret;

	if (!ctx->is_tls) {
		/* Change the default port if user did not set it */
		if (!ctx->server_addr) {
			net_sin(&ctx->local)->sin_port =
				htons(HTTPS_DEFAULT_PORT);

#if defined(CONFIG_NET_IPV6)
			net_sin6(&ctx->app_ctx.ipv6.local)->sin6_port =
				htons(HTTPS_DEFAULT_PORT);
#endif
#if defined(CONFIG_NET_IPV4)
			net_sin(&ctx->app_ctx.ipv4.local)->sin_port =
				htons(HTTPS_DEFAULT_PORT);
#endif
		}

		ret = net_app_server_tls(&ctx->app_ctx,
					 ctx->http.request_buf,
					 ctx->http.request_buf_len,
					 server_banner,
					 personalization_data,
					 personalization_data_len,
					 cert_cb,
					 entropy_src_cb,
					 pool,
					 stack,
					 stack_len);
		if (ret < 0) {
			NET_ERR("Cannot init TLS (%d)", ret);
			goto quit;
		}

		ctx->is_tls = true;
		return 0;
	}

	return -EALREADY;

quit:
	net_app_release(&ctx->app_ctx);
	return ret;
}
#endif

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

	if (ctx->http.field_values_ctr >= CONFIG_HTTP_HEADERS) {
		return 0;
	}

	http_change_state(ctx, HTTP_STATE_RECEIVING_HEADER);

	ctx->http.field_values[ctx->http.field_values_ctr].key = at;
	ctx->http.field_values[ctx->http.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_ctx *ctx = parser->data;

	if (ctx->http.field_values_ctr >= CONFIG_HTTP_HEADERS) {
		return 0;
	}

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

	ctx->http.field_values_ctr++;

	return 0;
}

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

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

	http_change_state(ctx, HTTP_STATE_WAITING_HEADER);

	http_server_conn_add(ctx);

	return 0;
}

static int on_headers_complete(struct http_parser *parser)
{
	ARG_UNUSED(parser);

	return 0;
}

static int init_http_parser(struct http_ctx *ctx)
{
	memset(ctx->http.field_values, 0, sizeof(ctx->http.field_values));

	ctx->http.parser_settings.on_header_field = on_header_field;
	ctx->http.parser_settings.on_header_value = on_header_value;
	ctx->http.parser_settings.on_url = on_url;
	ctx->http.parser_settings.on_headers_complete = on_headers_complete;

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

	ctx->http.parser.data = ctx;

	return 0;
}

static inline void new_server(struct http_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 void init_net(struct http_ctx *ctx,
		     struct sockaddr *server_addr,
		     u16_t port)
{
	memset(&ctx->local, 0, sizeof(ctx->local));

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

int http_server_init(struct http_ctx *ctx,
		     struct http_server_urls *urls,
		     struct sockaddr *server_addr,
		     u8_t *request_buf,
		     size_t request_buf_len,
		     const char *server_banner,
		     void *user_data)
{
	int ret = 0;

	if (!ctx) {
		return -EINVAL;
	}

	if (ctx->is_init) {
		return -EALREADY;
	}

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

	memset(ctx, 0, sizeof(*ctx));

	init_net(ctx, server_addr, HTTP_DEFAULT_PORT);

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

	/* Timeout for network buffer allocations */
	ctx->timeout = BUF_ALLOC_TIMEOUT;

	ctx->http.request_buf = request_buf;
	ctx->http.request_buf_len = request_buf_len;
	ctx->http.urls = urls;
	ctx->http.data_len = 0;
	ctx->user_data = user_data;
	ctx->server_addr = server_addr;

	ret = net_app_init_tcp_server(&ctx->app_ctx,
				      &ctx->local,
				      HTTP_DEFAULT_PORT,
				      ctx);
	if (ret < 0) {
		NET_ERR("Cannot create http server (%d)", ret);
		return ret;
	}

	ret = net_app_set_cb(&ctx->app_ctx, NULL, http_received,
			     http_data_sent, http_closed);
	if (ret < 0) {
		NET_ERR("Cannot set callbacks (%d)", ret);
		goto quit;
	}

	init_http_parser(ctx);

	ctx->is_init = true;
	return 0;

quit:
	net_app_release(&ctx->app_ctx);
	return ret;
}

int http_server_enable(struct http_ctx *ctx)
{
	int ret;

	NET_ASSERT(ctx);

	net_app_server_enable(&ctx->app_ctx);

	ret = net_app_listen(&ctx->app_ctx);
	if (ret < 0) {
		NET_ERR("Cannot wait connection (%d)", ret);
		return false;
	}

	return 0;
}

int http_server_disable(struct http_ctx *ctx)
{
	NET_ASSERT(ctx);

	net_app_server_disable(&ctx->app_ctx);

	return 0;
}
