[PATCH] add support for http+unix protocol

Konstantin Belyavskiy k.belyavskiy at tarantool.org
Thu Jan 25 13:49:59 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 | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/httpc.c b/src/httpc.c
index 84ea67aba..48934d1c5 100644
--- a/src/httpc.c
+++ b/src/httpc.c
@@ -36,6 +36,34 @@
 
 #include "fiber.h"
 
+static int
+ishex(int x)
+{
+	return (x >= '0' && x <= '9') ||
+	       (x >= 'a' && x <= 'f') ||
+	       (x >= 'A' && x <= 'F');
+}
+
+static int
+urldecode(const char *s, char *dec)
+{
+	char *o;
+	const char *end = s + strlen(s);
+	int c;
+
+	for (o = dec; s <= end; o++) {
+		c = *s++;
+		if (c == '+') c = ' ';
+		else if (c == '%' && (!ishex(*s++) ||
+				      !ishex(*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 +162,44 @@ 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 char prefix[] = "http+unix://";
+	int len = strlen(prefix);
+	if (strncmp(url, prefix, len) == 0) {
+		char *http_url = (char *) malloc(strlen("http://localhost") +
+						 strlen(url) - len + 1);
+
+		const char* beginning_of_socket_path = url + len;
+
+		const char* slash = strchr(beginning_of_socket_path, '/');
+		const char* rest = 0;
+
+		if (slash != NULL) {
+			rest = slash;
+		}
+		else {
+			rest = url + strlen(url);
+		}
+
+		len = rest - beginning_of_socket_path;
+		char *encoded_socket_path = (char *) malloc(len + 1);
+		char *socket_path = (char *) malloc(len + 1); // less or equal LEN(encoded)
+		strncpy(encoded_socket_path,
+			beginning_of_socket_path,
+			len);
+		encoded_socket_path[len] = '\0';
+
+		len = urldecode(encoded_socket_path, socket_path);
+		socket_path[len] = '\0';
+		sprintf(http_url, "http://localhost%s", rest);
+
+		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(encoded_socket_path);
+		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);
-- 
2.14.3 (Apple Git-98)




More information about the Tarantool-patches mailing list