diff --git a/gweb/gweb.c b/gweb/gweb.c
index 5f09cb3a99cf..584f0106c5ee 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -75,6 +75,7 @@ struct web_session {
 	char *content_type;
 
 	GIOChannel *transport_channel;
+	guint connect_timeout;
 	guint transport_watch;
 	guint send_watch;
 
@@ -133,6 +134,8 @@ struct _GWeb {
 #define debug(web, format, arg...)				\
 	_debug(web, __FILE__, __func__, format, ## arg)
 
+static void close_session_transport(struct web_session *session);
+
 static void _debug(GWeb *web, const char *file, const char *caller,
 						const char *format, ...)
 {
@@ -154,6 +157,70 @@ static void _debug(GWeb *web, const char *file, const char *caller,
 	va_end(ap);
 }
 
+static inline void call_result_func(struct web_session *session, guint16 status)
+{
+
+	if (!session->result_func)
+		return;
+
+	if (status != GWEB_HTTP_STATUS_CODE_UNKNOWN)
+		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 gboolean connect_timeout_cb(gpointer user_data)
+{
+	struct web_session *session = user_data;
+
+	debug(session->web, "session %p connect timeout after %ums",
+			session, g_web_get_connect_timeout(session->web));
+
+	session->connect_timeout = 0;
+
+	close_session_transport(session);
+
+	session->result.buffer = NULL;
+	session->result.length = 0;
+
+	call_result_func(session, GWEB_HTTP_STATUS_CODE_REQUEST_TIMEOUT);
+
+	return G_SOURCE_REMOVE;
+}
+
+static void add_connect_timeout(struct web_session *session,
+						guint timeout_ms)
+{
+	if (!session || !timeout_ms)
+		return;
+
+	debug(session->web, "add connect timeout %u ms", timeout_ms);
+
+	session->connect_timeout = g_timeout_add(timeout_ms,
+				connect_timeout_cb, session);
+}
+
+static void cancel_connect_timeout(struct web_session *session)
+{
+	if (!session)
+		return;
+
+	if (session->connect_timeout > 0) {
+		g_source_remove(session->connect_timeout);
+		session->connect_timeout = 0;
+
+		debug(session->web, "cancelled connect timeout");
+	}
+}
+
 static void close_session_transport(struct web_session *session)
 {
 	if (!session)
@@ -194,6 +261,8 @@ static void free_session(struct web_session *session)
 	if (session->resolv_action > 0)
 		g_resolv_cancel_lookup(web->resolv, session->resolv_action);
 
+	cancel_connect_timeout(session);
+
 	close_session_transport(session);
 
 	g_free(session->result.last_key);
@@ -485,26 +554,6 @@ done:
 	return timeout_ms;
 }
 
-static inline void call_result_func(struct web_session *session, guint16 status)
-{
-
-	if (!session->result_func)
-		return;
-
-	if (status != GWEB_HTTP_STATUS_CODE_UNKNOWN)
-		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;
@@ -915,6 +964,8 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
 	gsize bytes_read;
 	GIOStatus status;
 
+	cancel_connect_timeout(session);
+
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
 		session->transport_watch = 0;
 		session->result.buffer = NULL;
@@ -1075,7 +1126,8 @@ static inline int bind_socket(int sk, int index, int family)
 	return err;
 }
 
-static int connect_session_transport(struct web_session *session)
+static int connect_session_transport(struct web_session *session,
+			guint connect_timeout_ms)
 {
 	GIOFlags flags;
 	int sk;
@@ -1133,6 +1185,8 @@ static int connect_session_transport(struct web_session *session)
 				G_IO_OUT | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
 						send_data, session);
 
+	add_connect_timeout(session, connect_timeout_ms);
+
 	return 0;
 }
 
@@ -1140,7 +1194,8 @@ static int create_transport(struct web_session *session)
 {
 	int err;
 
-	err = connect_session_transport(session);
+	err = connect_session_transport(session,
+			g_web_get_connect_timeout(session->web));
 	if (err < 0)
 		return err;
 
