Skip to content

Instantly share code, notes, and snippets.

@knazarov
Created January 12, 2018 05:54
Show Gist options
  • Save knazarov/fbf1c7b1ff2b6fc4acc171e11ea8e2bc to your computer and use it in GitHub Desktop.
Save knazarov/fbf1c7b1ff2b6fc4acc171e11ea8e2bc to your computer and use it in GitHub Desktop.
A PoC of http+unix:// support in the Tarantool http client
diff --git a/src/httpc.c b/src/httpc.c
index 84ea67aba..cecf30712 100644
--- a/src/httpc.c
+++ b/src/httpc.c
@@ -36,6 +36,33 @@
#include "fiber.h"
+int ishex(int x)
+{
+ return (x >= '0' && x <= '9') ||
+ (x >= 'a' && x <= 'f') ||
+ (x >= 'A' && x <= 'F');
+}
+
+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;
+
+ if (dec) *o = c;
+ }
+
+ return o - dec;
+}
+
/**
* libcurl callback for CURLOPT_WRITEFUNCTION
* @see https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html
@@ -134,7 +161,38 @@ httpc_request_new(struct httpc_env *env, const char *method,
curl_easy_setopt(req->curl_request.easy, CURLOPT_CUSTOMREQUEST, method);
}
+ if (strncmp(url, "http+unix://", 12) == 0) {
+ char http_url[256];
+ char encoded_socket_path[256];
+ char socket_path[256];
+
+
+ const char* beginning_of_socket_path = url + 12;
+
+ const char* slash = strchr(beginning_of_socket_path, '/');
+ const char* rest = 0;
+
+ if (slash != NULL) {
+ rest = slash;
+ }
+ else {
+ rest = url + strlen(url);
+ }
+
+ strncpy(encoded_socket_path,
+ beginning_of_socket_path,
+ rest - (beginning_of_socket_path));
+
+
+ urldecode(encoded_socket_path, socket_path);
+ 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);
+ }
+ 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment