/*
 *
 *  Web service library with GLib integration
 *
 *  Copyright (C) 2009-2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <ifaddrs.h>

#include "giognutls.h"
#include "gresolv.h"
#include "gweb.h"

#define DEFAULT_BUFFER_SIZE  2048

#define SESSION_FLAG_USE_TLS	(1 << 0)

enum chunk_state {
	CHUNK_SIZE,
	CHUNK_R_BODY,
	CHUNK_N_BODY,
	CHUNK_DATA,
};

struct _GWebResult {
	guint16 status;
	const guint8 *buffer;
	gsize length;
	bool use_chunk;
	gchar *last_key;
	GHashTable *headers;
};

struct web_session {
	GWeb *web;

	char *address;
	char *host;
	uint16_t port;
	unsigned long flags;
	struct addrinfo *addr;

	char *content_type;

	GIOChannel *transport_channel;
	guint transport_watch;
	guint send_watch;

	guint resolv_action;
	guint address_action;
	char *request;

	guint8 *receive_buffer;
	gsize receive_space;
	GString *send_buffer;
	GString *current_header;
	bool header_done;
	bool body_done;
	bool more_data;
	bool request_started;

	enum chunk_state chunck_state;
	gsize chunk_size;
	gsize chunk_left;
	gsize total_len;

	GWebResult result;

	GWebResultFunc result_func;
	GWebRouteFunc route_func;
	GWebInputFunc input_func;
	int fd;
	gsize length;
	gsize offset;
	gpointer user_data;
};

struct _GWeb {
	int ref_count;

	guint next_query_id;

	int family;

	int index;
	GList *session_list;

	GResolv *resolv;
	char *proxy;
	char *accept_option;
	char *user_agent;
	char *user_agent_profile;
	char *http_version;
	bool close_connection;

	GWebDebugFunc debug_func;
	gpointer debug_data;
};

#define debug(web, format, arg...)				\
	_debug(web, strrchr("/" __FILE__, '/') + 1, __func__, format, ## arg)

static void _debug(GWeb *web, const char *file, const char *caller,
						const char *format, ...)
{
	char str[256];
	va_list ap;
	int len;

	if (!web->debug_func)
		return;

	va_start(ap, format);

	if ((len = snprintf(str, sizeof(str), "%s:%s() web %p ",
						file, caller, web)) > 0) {
		if (vsnprintf(str + len, sizeof(str) - len, format, ap) > 0)
			web->debug_func(str, web->debug_data);
	}

	va_end(ap);
}

static void free_session(struct web_session *session)
{
	GWeb *web;

	if (!session)
		return;

	g_free(session->request);

	web = session->web;

	if (session->address_action > 0)
		g_source_remove(session->address_action);

	if (session->resolv_action > 0)
		g_resolv_cancel_lookup(web->resolv, session->resolv_action);

	if (session->transport_watch > 0)
		g_source_remove(session->transport_watch);

	if (session->send_watch > 0)
		g_source_remove(session->send_watch);

	if (session->transport_channel)
		g_io_channel_unref(session->transport_channel);

	g_free(session->result.last_key);

	if (session->result.headers)
		g_hash_table_destroy(session->result.headers);

	if (session->send_buffer)
		g_string_free(session->send_buffer, TRUE);

	if (session->current_header)
		g_string_free(session->current_header, TRUE);

	g_free(session->receive_buffer);

	g_free(session->content_type);

	g_free(session->host);
	g_free(session->address);
	if (session->addr)
		freeaddrinfo(session->addr);

	g_free(session);
}

static void flush_sessions(GWeb *web)
{
	GList *list;

	for (list = g_list_first(web->session_list);
					list; list = g_list_next(list))
		free_session(list->data);

	g_list_free(web->session_list);
	web->session_list = NULL;
}

GWeb *g_web_new(int index)
{
	GWeb *web;

	if (index < 0)
		return NULL;

	web = g_try_new0(GWeb, 1);
	if (!web)
		return NULL;

	web->ref_count = 1;

	web->next_query_id = 1;

	web->family = AF_UNSPEC;

	web->index = index;
	web->session_list = NULL;

	web->resolv = g_resolv_new(index);
	if (!web->resolv) {
		debug(web, "can't allocate resolv struct");
		g_free(web);
		return NULL;
	}

	web->accept_option = g_strdup("*/*");
	web->user_agent = g_strdup_printf("GWeb/%s", VERSION);
	web->close_connection = false;

	return web;
}

GWeb *g_web_ref(GWeb *web)
{
	if (!web)
		return NULL;

	__sync_fetch_and_add(&web->ref_count, 1);

	return web;
}

void g_web_unref(GWeb *web)
{
	if (!web)
		return;

	if (__sync_fetch_and_sub(&web->ref_count, 1) != 1)
		return;

	flush_sessions(web);

	g_resolv_unref(web->resolv);

	g_free(web->proxy);

	g_free(web->accept_option);
	g_free(web->user_agent);
	g_free(web->user_agent_profile);
	g_free(web->http_version);

	g_free(web);
}

bool g_web_supports_tls(void)
{
	return g_io_channel_supports_tls();
}

void g_web_set_debug(GWeb *web, GWebDebugFunc func, gpointer user_data)
{
	if (!web)
		return;

	web->debug_func = func;
	web->debug_data = user_data;

	g_resolv_set_debug(web->resolv, func, user_data);
}

bool g_web_set_proxy(GWeb *web, const char *proxy)
{
	if (!web)
		return false;

	g_free(web->proxy);

	if (!proxy) {
		web->proxy = NULL;
		debug(web, "clearing proxy");
	} else {
		web->proxy = g_strdup(proxy);
		debug(web, "setting proxy %s", web->proxy);
	}

	return true;
}

bool g_web_set_address_family(GWeb *web, int family)
{
	if (!web)
		return false;

	if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6)
		return false;

	web->family = family;

	g_resolv_set_address_family(web->resolv, family);

	return true;
}

bool g_web_add_nameserver(GWeb *web, const char *address)
{
	if (!web)
		return false;

	g_resolv_add_nameserver(web->resolv, address, 53, 0);

	return true;
}

static bool set_accept_option(GWeb *web, const char *format, va_list args)
{
	g_free(web->accept_option);

	if (!format) {
		web->accept_option = NULL;
		debug(web, "clearing accept option");
	} else {
		web->accept_option = g_strdup_vprintf(format, args);
		debug(web, "setting accept %s", web->accept_option);
	}

	return true;
}

bool g_web_set_accept(GWeb *web, const char *format, ...)
{
	va_list args;
	bool result;

	if (!web)
		return false;

	va_start(args, format);
	result = set_accept_option(web, format, args);
	va_end(args);

	return result;
}

static bool set_user_agent(GWeb *web, const char *format, va_list args)
{
	g_free(web->user_agent);

	if (!format) {
		web->user_agent = NULL;
		debug(web, "clearing user agent");
	} else {
		web->user_agent = g_strdup_vprintf(format, args);
		debug(web, "setting user agent %s", web->user_agent);
	}

	return true;
}

bool g_web_set_user_agent(GWeb *web, const char *format, ...)
{
	va_list args;
	bool result;

	if (!web)
		return false;

	va_start(args, format);
	result = set_user_agent(web, format, args);
	va_end(args);

	return result;
}

bool g_web_set_ua_profile(GWeb *web, const char *profile)
{
	if (!web)
		return false;

	g_free(web->user_agent_profile);

	web->user_agent_profile = g_strdup(profile);
	debug(web, "setting user agent profile %s", web->user_agent);

	return true;
}

bool g_web_set_http_version(GWeb *web, const char *version)
{
	if (!web)
		return false;

	g_free(web->http_version);

	if (!version) {
		web->http_version = NULL;
		debug(web, "clearing HTTP version");
	} else {
		web->http_version = g_strdup(version);
		debug(web, "setting HTTP version %s", web->http_version);
	}

	return true;
}

void g_web_set_close_connection(GWeb *web, bool enabled)
{
	if (!web)
		return;

	web->close_connection = enabled;
}

bool g_web_get_close_connection(GWeb *web)
{
	if (!web)
		return false;

	return web->close_connection;
}

static inline void call_result_func(struct web_session *session, guint16 status)
{

	if (!session->result_func)
		return;

	if (status != 0)
		session->result.status = status;

	session->result_func(&session->result, session->user_data);

}

static inline void call_route_func(struct web_session *session)
{
	if (session->route_func)
		session->route_func(session->address, session->addr->ai_family,
				session->web->index, session->user_data);
}

static bool process_send_buffer(struct web_session *session)
{
	GString *buf;
	gsize count, bytes_written;
	GIOStatus status;

	if (!session)
		return false;

	buf = session->send_buffer;
	count = buf->len;

	if (count == 0) {
		if (session->request_started &&
					!session->more_data &&
					session->fd == -1)
			session->body_done = true;

		return false;
	}

	status = g_io_channel_write_chars(session->transport_channel,
					buf->str, count, &bytes_written, NULL);

	debug(session->web, "status %u bytes to write %zu bytes written %zu",
					status, count, bytes_written);

	if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN)
		return false;

	g_string_erase(buf, 0, bytes_written);

	return true;
}

static bool process_send_file(struct web_session *session)
{
	int sk;
	off_t offset;
	ssize_t bytes_sent;

	if (session->fd == -1)
		return false;

	if (!session->request_started || session->more_data)
		return false;

	sk = g_io_channel_unix_get_fd(session->transport_channel);
	if (sk < 0)
		return false;

	offset = session->offset;

	bytes_sent = sendfile(sk, session->fd, &offset, session->length);

	debug(session->web, "errno: %d, bytes to send %zu / bytes sent %zu",
			errno, session->length, bytes_sent);

	if (bytes_sent < 0 && errno != EAGAIN)
		return false;

	session->offset = offset;
	session->length -= bytes_sent;

	if (session->length == 0) {
		session->body_done = true;
		return false;
	}

	return true;
}

static void process_next_chunk(struct web_session *session)
{
	GString *buf = session->send_buffer;
	const guint8 *body;
	gsize length;

	if (!session->input_func) {
		session->more_data = false;
		return;
	}

	session->more_data = session->input_func(&body, &length,
						session->user_data);

	if (length > 0) {
		g_string_append_printf(buf, "%zx\r\n", length);
		g_string_append_len(buf, (char *) body, length);
		g_string_append(buf, "\r\n");
	}

	if (!session->more_data)
		g_string_append(buf, "0\r\n\r\n");
}

static void start_request(struct web_session *session)
{
	GString *buf = session->send_buffer;
	const char *version;
	const guint8 *body;
	gsize length;

	debug(session->web, "request %s from %s",
					session->request, session->host);

	g_string_truncate(buf, 0);

	if (!session->web->http_version)
		version = "1.1";
	else
		version = session->web->http_version;

	if (!session->content_type)
		g_string_append_printf(buf, "GET %s HTTP/%s\r\n",
						session->request, version);
	else
		g_string_append_printf(buf, "POST %s HTTP/%s\r\n",
						session->request, version);

	g_string_append_printf(buf, "Host: %s\r\n", session->host);

	if (session->web->user_agent)
		g_string_append_printf(buf, "User-Agent: %s\r\n",
						session->web->user_agent);

	if (session->web->user_agent_profile) {
		g_string_append_printf(buf, "x-wap-profile: %s\r\n",
				       session->web->user_agent_profile);
	}

	if (session->web->accept_option)
		g_string_append_printf(buf, "Accept: %s\r\n",
						session->web->accept_option);

	if (session->content_type) {
		g_string_append_printf(buf, "Content-Type: %s\r\n",
							session->content_type);
		if (!session->input_func) {
			session->more_data = false;
			length = session->length;
		} else
			session->more_data = session->input_func(&body, &length,
							session->user_data);
		if (!session->more_data)
			g_string_append_printf(buf, "Content-Length: %zu\r\n",
									length);
		else
			g_string_append(buf, "Transfer-Encoding: chunked\r\n");
	}

	if (session->web->close_connection)
		g_string_append(buf, "Connection: close\r\n");

	g_string_append(buf, "\r\n");

	if (session->content_type && length > 0) {
		if (session->more_data) {
			g_string_append_printf(buf, "%zx\r\n", length);
			g_string_append_len(buf, (char *) body, length);
			g_string_append(buf, "\r\n");
		} else if (session->fd == -1)
			g_string_append_len(buf, (char *) body, length);
	}
}

static gboolean send_data(GIOChannel *channel, GIOCondition cond,
						gpointer user_data)
{
	struct web_session *session = user_data;

	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		debug(session->web, "cond 0x%x", cond);
		session->send_watch = 0;
		return FALSE;
	}

	if (process_send_buffer(session)) {
		debug(session->web, "buffer sent");
		return TRUE;
	}

	if (process_send_file(session)) {
		debug(session->web, "file sent");
		return TRUE;
	}

	if (!session->request_started) {
		session->request_started = true;
		start_request(session);
	} else if (session->more_data)
		process_next_chunk(session);

	process_send_buffer(session);

	if (session->body_done) {
		session->send_watch = 0;
		return FALSE;
	}

	return TRUE;
}

static int decode_chunked(struct web_session *session,
					const guint8 *buf, gsize len)
{
	const guint8 *ptr = buf;
	gsize counter;

	while (len > 0) {
		guint8 *pos;
		gsize count;
		char *str;

		switch (session->chunck_state) {
		case CHUNK_SIZE:
			pos = memchr(ptr, '\n', len);
			if (!pos) {
				g_string_append_len(session->current_header,
						(gchar *) ptr, len);
				return 0;
			}

			count = pos - ptr;
			if (count < 1 || ptr[count - 1] != '\r')
				return -EILSEQ;

			g_string_append_len(session->current_header,
						(gchar *) ptr, count);

			len -= count + 1;
			ptr = pos + 1;

			str = session->current_header->str;

			counter = strtoul(str, NULL, 16);
			if ((counter == 0 && errno == EINVAL) ||
						counter == ULONG_MAX)
				return -EILSEQ;

			session->chunk_size = counter;
			session->chunk_left = counter;

			session->chunck_state = CHUNK_DATA;
			break;
		case CHUNK_R_BODY:
			if (*ptr != '\r')
				return -EILSEQ;
			ptr++;
			len--;
			session->chunck_state = CHUNK_N_BODY;
			break;
		case CHUNK_N_BODY:
			if (*ptr != '\n')
				return -EILSEQ;
			ptr++;
			len--;
			session->chunck_state = CHUNK_SIZE;
			break;
		case CHUNK_DATA:
			if (session->chunk_size == 0) {
				debug(session->web, "Download Done in chunk");
				g_string_truncate(session->current_header, 0);
				return 0;
			}

			if (session->chunk_left <= len) {
				session->result.buffer = ptr;
				session->result.length = session->chunk_left;
				call_result_func(session, 0);

				len -= session->chunk_left;
				ptr += session->chunk_left;

				session->total_len += session->chunk_left;
				session->chunk_left = 0;

				g_string_truncate(session->current_header, 0);
				session->chunck_state = CHUNK_R_BODY;
				break;
			}
			/* more data */
			session->result.buffer = ptr;
			session->result.length = len;
			call_result_func(session, 0);

			session->chunk_left -= len;
			session->total_len += len;

			len -= len;
			ptr += len;
			break;
		}
	}

	return 0;
}

static int handle_body(struct web_session *session,
				const guint8 *buf, gsize len)
{
	int err;

#ifdef OC_VERBOSE
	debug(session->web, "[body] length %zu", len);
#endif

	if (!session->result.use_chunk) {
		if (len > 0) {
			session->result.buffer = buf;
			session->result.length = len;
			call_result_func(session, 0);
		}
		return 0;
	}

	err = decode_chunked(session, buf, len);
	if (err < 0) {
		debug(session->web, "Error in chunk decode %d", err);

		session->result.buffer = NULL;
		session->result.length = 0;
		call_result_func(session, 400);
	}

	return err;
}

static void handle_multi_line(struct web_session *session)
{
	gsize count;
	char *str;
	gchar *value;

	str = session->current_header->str;

	if (str[0] != ' ' && str[0] != '\t')
		return;

	while (str[0] == ' ' || str[0] == '\t')
		str++;

	count = str - session->current_header->str;
	if (count > 0) {
		g_string_erase(session->current_header, 0, count);
		g_string_insert_c(session->current_header, 0, ' ');
	}

	value = g_hash_table_lookup(session->result.headers,
					session->result.last_key);
	if (value) {
		g_string_insert(session->current_header, 0, value);

		str = session->current_header->str;

		g_hash_table_replace(session->result.headers,
					g_strdup(session->result.last_key),
					g_strdup(str));
	}
}

static void add_header_field(struct web_session *session)
{
	gsize count;
	guint8 *pos;
	char *str;
	gchar *value;
	gchar *key;

	str = session->current_header->str;

	pos = memchr(str, ':', session->current_header->len);
	if (pos) {
		*pos = '\0';
		pos++;

		key = g_strdup(str);

		/* remove preceding white spaces */
		while (*pos == ' ')
			pos++;

		count = (char *) pos - str;

		g_string_erase(session->current_header, 0, count);

		value = g_hash_table_lookup(session->result.headers, key);
		if (value) {
			g_string_insert_c(session->current_header, 0, ' ');
			g_string_insert_c(session->current_header, 0, ';');

			g_string_insert(session->current_header, 0, value);
		}

		str = session->current_header->str;
		g_hash_table_replace(session->result.headers, key,
							g_strdup(str));

		g_free(session->result.last_key);
		session->result.last_key = g_strdup(key);
	}
}

static gboolean received_data(GIOChannel *channel, GIOCondition cond,
							gpointer user_data)
{
	struct web_session *session = user_data;
	guint8 *ptr = session->receive_buffer;
	gsize bytes_read;
	GIOStatus status;

	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		session->transport_watch = 0;
		session->result.buffer = NULL;
		session->result.length = 0;
		call_result_func(session, 400);
		return FALSE;
	}

	status = g_io_channel_read_chars(channel,
				(gchar *) session->receive_buffer,
				session->receive_space - 1, &bytes_read, NULL);

	debug(session->web, "bytes read %zu", bytes_read);

	if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
		session->transport_watch = 0;
		session->result.buffer = NULL;
		session->result.length = 0;
		call_result_func(session, 0);
		return FALSE;
	}

	session->receive_buffer[bytes_read] = '\0';

	if (session->header_done) {
		if (handle_body(session, session->receive_buffer,
							bytes_read) < 0) {
			session->transport_watch = 0;
			return FALSE;
		}
		return TRUE;
	}

	while (bytes_read > 0) {
		guint8 *pos;
		gsize count;
		char *str;

		pos = memchr(ptr, '\n', bytes_read);
		if (!pos) {
			g_string_append_len(session->current_header,
						(gchar *) ptr, bytes_read);
			return TRUE;
		}

		*pos = '\0';
		count = strlen((char *) ptr);
		if (count > 0 && ptr[count - 1] == '\r') {
			ptr[--count] = '\0';
			bytes_read--;
		}

		g_string_append_len(session->current_header,
						(gchar *) ptr, count);

		bytes_read -= count + 1;
		if (bytes_read > 0)
			ptr = pos + 1;
		else
			ptr = NULL;

		if (session->current_header->len == 0) {
			char *val;

			session->header_done = true;

			val = g_hash_table_lookup(session->result.headers,
							"Transfer-Encoding");
			if (val) {
				val = g_strrstr(val, "chunked");
				if (val) {
					session->result.use_chunk = true;

					session->chunck_state = CHUNK_SIZE;
					session->chunk_left = 0;
					session->total_len = 0;
				}
			}

			if (handle_body(session, ptr, bytes_read) < 0) {
				session->transport_watch = 0;
				return FALSE;
			}
			break;
		}

		str = session->current_header->str;

		if (session->result.status == 0) {
			unsigned int code;

			if (sscanf(str, "HTTP/%*s %u %*s", &code) == 1)
				session->result.status = code;
		}

#ifdef OC_VERBOSE
		debug(session->web, "[header] %s", str);
#endif

		/* handle multi-line header */
		if (str[0] == ' ' || str[0] == '\t')
			handle_multi_line(session);
		else
			add_header_field(session);

		g_string_truncate(session->current_header, 0);
	}

	return TRUE;
}

static int bind_to_address(int sk, const char *interface, int family)
{
	struct ifaddrs *ifaddr_list, *ifaddr;
	int size, err = -1;

	if (getifaddrs(&ifaddr_list) < 0)
		return err;

	for (ifaddr = ifaddr_list; ifaddr; ifaddr = ifaddr->ifa_next) {
		if (g_strcmp0(ifaddr->ifa_name, interface) != 0)
			continue;

		if (!ifaddr->ifa_addr ||
				ifaddr->ifa_addr->sa_family != family)
			continue;

		switch (family) {
		case AF_INET:
			size = sizeof(struct sockaddr_in);
			break;
		case AF_INET6:
			size = sizeof(struct sockaddr_in6);
			break;
		default:
			continue;
		}

		err = bind(sk, (struct sockaddr *) ifaddr->ifa_addr, size);
		break;
	}

	freeifaddrs(ifaddr_list);
	return err;
}

static inline int bind_socket(int sk, int index, int family)
{
	char interface[IF_NAMESIZE];
	int err;

	if (!if_indextoname(index, interface))
		return -1;

	err = setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
					interface, IF_NAMESIZE);
	if (err < 0)
		err = bind_to_address(sk, interface, family);

	return err;
}

static int connect_session_transport(struct web_session *session)
{
	GIOFlags flags;
	int sk, opt = 1/* boolean */;

	sk = socket(session->addr->ai_family, SOCK_STREAM | SOCK_CLOEXEC,
			IPPROTO_TCP);
	if (sk < 0)
		return -EIO;

	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
		debug(session->web, "set SO_REUSEADDR failed");
		close(sk);
		return -EIO;
	}

	debug(session->web, "created sk %d for server %s", sk, session->address);
	if (session->web->index > 0) {
		debug(session->web, "binding to interface %d", session->web->index);
		if (bind_socket(sk, session->web->index,
					session->addr->ai_family) < 0) {
			debug(session->web, "bind() %s", strerror(errno));
			close(sk);
			return -EIO;
		}
	}

	if (session->flags & SESSION_FLAG_USE_TLS) {
		debug(session->web, "using TLS encryption");
		session->transport_channel = g_io_channel_gnutls_new(sk);
	} else {
		debug(session->web, "no encryption");
		session->transport_channel = g_io_channel_unix_new(sk);
	}

	if (!session->transport_channel) {
		debug(session->web, "channel missing");
		close(sk);
		return -ENOMEM;
	}

	flags = g_io_channel_get_flags(session->transport_channel);
	g_io_channel_set_flags(session->transport_channel,
					flags | G_IO_FLAG_NONBLOCK, NULL);

	g_io_channel_set_encoding(session->transport_channel, NULL, NULL);
	g_io_channel_set_buffered(session->transport_channel, FALSE);

	g_io_channel_set_close_on_unref(session->transport_channel, TRUE);

	if (connect(sk, session->addr->ai_addr,
			session->addr->ai_addrlen) < 0) {
		if (errno != EINPROGRESS) {
			debug(session->web, "connect() %s", strerror(errno));
			return -EIO;
		}
	}

	session->transport_watch = g_io_add_watch(session->transport_channel,
				G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
						received_data, session);

	session->send_watch = g_io_add_watch(session->transport_channel,
				G_IO_OUT | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
						send_data, session);

	return 0;
}

static int create_transport(struct web_session *session)
{
	int err;

	err = connect_session_transport(session);
	if (err < 0)
		return err;

	debug(session->web, "creating session %s:%u",
					session->address, session->port);

	return 0;
}

static int parse_url(struct web_session *session,
				const char *url, const char *proxy)
{
	char *scheme, *host, *port, *path;

	scheme = g_strdup(url);
	if (!scheme)
		return -EINVAL;

	host = strstr(scheme, "://");
	if (host) {
		*host = '\0';
		host += 3;

		if (strcasecmp(scheme, "https") == 0) {
			session->port = 443;
			session->flags |= SESSION_FLAG_USE_TLS;
		} else if (strcasecmp(scheme, "http") == 0) {
			session->port = 80;
		} else {
			g_free(scheme);
			return -EINVAL;
		}
	} else {
		host = scheme;
		session->port = 80;
	}

	path = strchr(host, '/');
	if (path)
		*(path++) = '\0';

	if (!proxy)
		session->request = g_strdup_printf("/%s", path ? path : "");
	else
		session->request = g_strdup(url);

	port = strrchr(host, ':');
	if (port) {
		char *end;
		int tmp = strtol(port + 1, &end, 10);

		if (*end == '\0') {
			*port = '\0';
			session->port = tmp;
		}

		if (!proxy)
			session->host = g_strdup(host);
		else
			session->host = g_strdup_printf("%s:%u", host, tmp);
	} else
		session->host = g_strdup(host);

	g_free(scheme);

	if (!proxy)
		return 0;

	scheme = g_strdup(proxy);
	if (!scheme)
		return -EINVAL;

	host = strstr(proxy, "://");
	if (host) {
		*host = '\0';
		host += 3;

		if (strcasecmp(scheme, "http") != 0) {
			g_free(scheme);
			return -EINVAL;
		}
	} else
		host = scheme;

	path = strchr(host, '/');
	if (path)
		*(path++) = '\0';

	port = strrchr(host, ':');
	if (port) {
		char *end;
		int tmp = strtol(port + 1, &end, 10);

		if (*end == '\0') {
			*port = '\0';
			session->port = tmp;
		}
	}

	session->address = g_strdup(host);

	g_free(scheme);

	return 0;
}

static void handle_resolved_address(struct web_session *session)
{
	struct addrinfo hints;
	char *port;
	int ret;

	debug(session->web, "address %s", session->address);

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_NUMERICHOST;
	hints.ai_family = session->web->family;

	if (session->addr) {
		freeaddrinfo(session->addr);
		session->addr = NULL;
	}

	port = g_strdup_printf("%u", session->port);
	ret = getaddrinfo(session->address, port, &hints, &session->addr);
	g_free(port);
	if (ret != 0 || !session->addr) {
		debug(session->web, "getaddrinfo for address %s failed, ret %d", session->address, ret);
		call_result_func(session, 400);
		return;
	}

	call_route_func(session);

	ret = create_transport(session);
	if (ret < 0) {
		debug(session->web, "create_transport for address %s failed, ret %d", session->address, ret);
		call_result_func(session, 409);
		return;
	}
}

static gboolean already_resolved(gpointer data)
{
	struct web_session *session = data;

	session->address_action = 0;
	handle_resolved_address(session);

	return FALSE;
}

static void resolv_result(GResolvResultStatus status,
					char **results, gpointer user_data)
{
	struct web_session *session = user_data;

	if (!results || !results[0]) {
		debug(session->web, "dns resolve failed");
		call_result_func(session, 9002);
		return;
	}

	g_free(session->address);
	session->address = g_strdup(results[0]);

	handle_resolved_address(session);
}

static bool is_ip_address(const char *host)
{
	struct addrinfo hints;
	struct addrinfo *addr;
	int result;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_NUMERICHOST;
	addr = NULL;

	result = getaddrinfo(host, NULL, &hints, &addr);
	freeaddrinfo(addr);

	return result == 0;
}

static guint do_request(GWeb *web, const char *url,
				const char *type, GWebInputFunc input,
				int fd, gsize length, GWebResultFunc func,
				GWebRouteFunc route, gpointer user_data)
{
	struct web_session *session;
	const gchar *host;

	if (!web || !url)
		return 0;

	debug(web, "request %s", url);

	session = g_try_new0(struct web_session, 1);
	if (!session)
		return 0;

	if (parse_url(session, url, web->proxy) < 0) {
		debug(web, "parse_url failed");
		free_session(session);
		return 0;
	}

#ifdef OC_VERBOSE
	debug(web, "proxy host %s", session->address);
	debug(web, "port %u", session->port);
	debug(web, "host %s", session->host);
	debug(web, "flags %lu", session->flags);
	debug(web, "request %s", session->request);
#endif

	if (type) {
		session->content_type = g_strdup(type);

		debug(web, "content-type %s", session->content_type);
	}

	session->web = web;

	session->result_func = func;
	session->route_func = route;
	session->input_func = input;
	session->fd = fd;
	session->length = length;
	session->offset = 0;
	session->user_data = user_data;

	session->receive_buffer = g_try_malloc(DEFAULT_BUFFER_SIZE);
	if (!session->receive_buffer) {
		debug(web, "allocate receive_buffer failed");
		free_session(session);
		return 0;
	}

	session->result.headers = g_hash_table_new_full(g_str_hash, g_str_equal,
							g_free, g_free);
	if (!session->result.headers) {
		debug(web, "new hash table failed");
		free_session(session);
		return 0;
	}

	session->receive_space = DEFAULT_BUFFER_SIZE;
	session->send_buffer = g_string_sized_new(0);
	session->current_header = g_string_sized_new(0);
	session->header_done = false;
	session->body_done = false;

	host = session->address ? session->address : session->host;
	if (is_ip_address(host)) {
		if (session->address != host) {
			g_free(session->address);
			session->address = g_strdup(host);
		}
		session->address_action = g_timeout_add(0, already_resolved,
							session);
	} else {
		session->resolv_action = g_resolv_lookup_hostname(web->resolv,
					host, resolv_result, session);
		if (session->resolv_action == 0) {
			debug(web, "g_resolv_lookup_hostname failed");
			free_session(session);
			return 0;
		}
	}

	web->session_list = g_list_append(web->session_list, session);

	return web->next_query_id++;
}

guint g_web_request_get(GWeb *web, const char *url, GWebResultFunc func,
		GWebRouteFunc route, gpointer user_data)
{
	return do_request(web, url, NULL, NULL, -1, 0, func, route, user_data);
}

guint g_web_request_post(GWeb *web, const char *url,
				const char *type, GWebInputFunc input,
				GWebResultFunc func, gpointer user_data)
{
	return do_request(web, url, type, input, -1, 0, func, NULL, user_data);
}

guint g_web_request_post_file(GWeb *web, const char *url,
				const char *type, const char *file,
				GWebResultFunc func, gpointer user_data)
{
	struct stat st;
	int fd;
	guint ret;

	if (stat(file, &st) < 0)
		return 0;

	fd = open(file, O_RDONLY);
	if (fd < 0)
		return 0;

	ret = do_request(web, url, type, NULL, fd, st.st_size, func, NULL,
			user_data);
	if (ret == 0)
		close(fd);

	return ret;
}

bool g_web_cancel_request(GWeb *web, guint id)
{
	if (!web)
		return false;

	return true;
}

guint16 g_web_result_get_status(GWebResult *result)
{
	if (!result)
		return 0;

	return result->status;
}

bool g_web_result_get_chunk(GWebResult *result,
				const guint8 **chunk, gsize *length)
{
	if (!result)
		return false;

	if (!chunk)
		return false;

	*chunk = result->buffer;

	if (length)
		*length = result->length;

	return true;
}

bool g_web_result_get_header(GWebResult *result,
				const char *header, const char **value)
{
	if (!result)
		return false;

	if (!value)
		return false;

	*value = g_hash_table_lookup(result->headers, header);

	if (!*value)
		return false;

	return true;
}

struct _GWebParser {
	gint ref_count;
	char *begin_token;
	char *end_token;
	const char *token_str;
	size_t token_len;
	size_t token_pos;
	bool intoken;
	GString *content;
	GWebParserFunc func;
	gpointer user_data;
};

GWebParser *g_web_parser_new(const char *begin, const char *end,
				GWebParserFunc func, gpointer user_data)
{
	GWebParser *parser;

	parser = g_try_new0(GWebParser, 1);
	if (!parser)
		return NULL;

	parser->ref_count = 1;

	parser->begin_token = g_strdup(begin);
	parser->end_token = g_strdup(end);

	if (!parser->begin_token) {
		g_free(parser);
		return NULL;
	}

	parser->func = func;
	parser->user_data = user_data;

	parser->token_str = parser->begin_token;
	parser->token_len = strlen(parser->token_str);
	parser->token_pos = 0;

	parser->intoken = false;
	parser->content = g_string_sized_new(0);

	return parser;
}

GWebParser *g_web_parser_ref(GWebParser *parser)
{
	if (!parser)
		return NULL;

	__sync_fetch_and_add(&parser->ref_count, 1);

	return parser;
}

void g_web_parser_unref(GWebParser *parser)
{
	if (!parser)
		return;

	if (__sync_fetch_and_sub(&parser->ref_count, 1) != 1)
		return;

	g_string_free(parser->content, TRUE);

	g_free(parser->begin_token);
	g_free(parser->end_token);
	g_free(parser);
}

void g_web_parser_feed_data(GWebParser *parser,
				const guint8 *data, gsize length)
{
	const guint8 *ptr = data;

	if (!parser)
		return;

	while (length > 0) {
		guint8 chr = parser->token_str[parser->token_pos];

		if (parser->token_pos == 0) {
			guint8 *pos;

			pos = memchr(ptr, chr, length);
			if (!pos) {
				if (parser->intoken)
					g_string_append_len(parser->content,
							(gchar *) ptr, length);
				break;
			}

			if (parser->intoken)
				g_string_append_len(parser->content,
						(gchar *) ptr, (pos - ptr) + 1);

			length -= (pos - ptr) + 1;
			ptr = pos + 1;

			parser->token_pos++;
			continue;
		}

		if (parser->intoken)
			g_string_append_c(parser->content, ptr[0]);

		if (ptr[0] != chr) {
			length--;
			ptr++;

			parser->token_pos = 0;
			continue;
		}

		length--;
		ptr++;

		parser->token_pos++;

		if (parser->token_pos == parser->token_len) {
			if (!parser->intoken) {
				g_string_append(parser->content,
							parser->token_str);

				parser->intoken = true;
				parser->token_str = parser->end_token;
				parser->token_len = strlen(parser->end_token);
				parser->token_pos = 0;
			} else {
				char *str;
				str = g_string_free(parser->content, FALSE);
				parser->content = g_string_sized_new(0);
				if (parser->func)
					parser->func(str, parser->user_data);
				g_free(str);

				parser->intoken = false;
				parser->token_str = parser->begin_token;
				parser->token_len = strlen(parser->begin_token);
				parser->token_pos = 0;
			}
		}
	}
}

void g_web_parser_end_data(GWebParser *parser)
{
	if (!parser)
		return;
}
