[PATCH] add support for http+unix protocol

Konstantin Belyavskiy k.belyavskiy at tarantool.org
Fri Jan 26 11:51:14 MSK 2018


The http+unix:// is http protocol over unix domain sockets.
implementation based on original racktear proposal
decided to support only http+unix format
decided not to use our uri parser

closes #3040
---
branch: gh-3040-unix-domain-sockets-orig-fix-formatting
 src/httpc.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/httpc.h |  1 +
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/src/httpc.c b/src/httpc.c
index 84ea67aba..d5ad1164b 100644
--- a/src/httpc.c
+++ b/src/httpc.c
@@ -36,6 +36,31 @@
 
 #include "fiber.h"
 
+static const char *HTTP_LOCALHOST = "http://localhost";
+static const char *HTTP_UNIX_PREFIX = "http+unix://";
+
+/**
+ * function to decode encoded symbols in http url
+ */
+static int
+urldecode(const char *s, const char *end, char *dec)
+{
+	char *o;
+	int c;
+
+	for (o = dec; s <= end; o++) {
+		c = *s++;
+		if (c == '+') c = ' ';
+		else if (c == '%' && (!isxdigit(*s++) ||
+				      !isxdigit(*s++) ||
+				      !sscanf(s - 2, "%2x", &c)))
+			return -1;
+		*o = c;
+	}
+
+	return o - dec;
+}
+
 /**
  * libcurl callback for CURLOPT_WRITEFUNCTION
  * @see https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html
@@ -134,7 +159,29 @@ httpc_request_new(struct httpc_env *env, const char *method,
 		curl_easy_setopt(req->curl_request.easy, CURLOPT_CUSTOMREQUEST, method);
 	}
 
-	curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);
+	const int prefix_len = strlen(HTTP_UNIX_PREFIX);
+	if (strncmp(url, HTTP_UNIX_PREFIX, prefix_len) == 0) {
+		const int url_len = strlen(url);
+		char *http_url = (char *) malloc(strlen(HTTP_LOCALHOST) +
+						 url_len - prefix_len + 1);
+
+		const char *socket_path_start = url + prefix_len;
+		const char *socket_path_end = strchr(socket_path_start, '/');
+		if (socket_path_end == NULL)
+			socket_path_end = url + url_len;
+
+		char *socket_path = (char *) malloc(socket_path_end - socket_path_start + 1);
+		urldecode(socket_path_start, socket_path_end, socket_path);
+		sprintf(http_url, "http://localhost%s", socket_path_end);
+
+		curl_easy_setopt(req->curl_request.easy, CURLOPT_UNIX_SOCKET_PATH, socket_path);
+		curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, http_url);
+
+		free(http_url);
+		free(socket_path);
+	} else {
+		curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);
+	}
 
 	curl_easy_setopt(req->curl_request.easy, CURLOPT_FOLLOWLOCATION, 1);
 	curl_easy_setopt(req->curl_request.easy, CURLOPT_SSL_VERIFYPEER, 1);
diff --git a/src/httpc.h b/src/httpc.h
index 3358fd914..8c3e75f75 100644
--- a/src/httpc.h
+++ b/src/httpc.h
@@ -34,6 +34,7 @@
 #include <small/region.h>
 #include <small/mempool.h>
 #include <tarantool_ev.h>
+#include <ctype.h>
 
 #include "diag.h"
 
-- 
2.14.3 (Apple Git-98)




More information about the Tarantool-patches mailing list