<HTML><BODY>Revert back version with malloc<br><br><p>diff --git a/src/httpc.c b/src/httpc.c<br>index 84ea67aba..b3849699b 100644<br>--- a/src/httpc.c<br>+++ b/src/httpc.c<br>@@ -32,10 +32,36 @@<br> #include "httpc.h"<br> <br> #include <assert.h><br>+#include <ctype.h><br> #include <curl/curl.h><br> <br> #include "fiber.h"<br> <br>+static const char *HTTP_LOCALHOST = "http://localhost";<br>+static const char *HTTP_UNIX_PREFIX = "http+unix://";<br>+<br>+/**<br>+ * Function to decode encoded symbols in http url.<br>+ */<br>+static int<br>+urldecode(const char *s, const char *end, char *dec)<br>+{<br>+ char *o;<br>+ int c;<br>+<br>+ for (o = dec; s != end; o++) {<br>+ c = *s++;<br>+ if (c == '+') c = ' ';<br>+ else if (c == '%' && (!isxdigit(*s++) ||<br>+ !isxdigit(*s++) ||<br>+ !sscanf(s - 2, "%2x", &c)))<br>+ return -1;<br>+ *o = c;<br>+ }<br>+ *o = '\0';<br>+ return o - dec;<br>+}<br>+<br> /**<br> * libcurl callback for CURLOPT_WRITEFUNCTION<br> * @see https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html<br>@@ -134,7 +160,29 @@ httpc_request_new(struct httpc_env *env, const char *method,<br> curl_easy_setopt(req->curl_request.easy, CURLOPT_CUSTOMREQUEST, method);<br> }<br> <br>- curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>+ const int prefix_len = strlen(HTTP_UNIX_PREFIX);<br>+ if (strncmp(url, HTTP_UNIX_PREFIX, prefix_len) == 0) {<br>+ const int url_len = strlen(url);<br>+ char *http_url = (char *) malloc(strlen(HTTP_LOCALHOST) +<br>+ url_len - prefix_len + 1);<br>+<br>+ const char *socket_path_start = url + prefix_len;<br>+ const char *socket_path_end = strchr(socket_path_start, '/');<br>+ if (socket_path_end == NULL)<br>+ socket_path_end = url + url_len;<br>+<br>+ char *socket_path = (char *) malloc(socket_path_end - socket_path_start + 1);<br>+ urldecode(socket_path_start, socket_path_end, socket_path);<br>+ sprintf(http_url, "%s%s", HTTP_LOCALHOST, socket_path_end);<br>+<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_UNIX_SOCKET_PATH, socket_path);<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, http_url);<br>+<br>+ free(http_url);<br>+ free(socket_path);<br>+ } else {<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>+ }<br> <br> curl_easy_setopt(req->curl_request.easy, CURLOPT_FOLLOWLOCATION, 1);<br> curl_easy_setopt(req->curl_request.easy, CURLOPT_SSL_VERIFYPEER, 1);</p><br><br><br><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">
        Пятница, 26 января 2018, 16:50 +03:00 от Konstantin Belyavskiy <k.belyavskiy@tarantool.org>:<br>
        <br>
        <div id="">




























<div class="js-helper js-readmsg-msg">
        <style type="text/css"></style>
        <div>
                <base target="_self" href="https://e.mail.ru/">
                
            <div id="style_15169746520000000359_BODY"><div class="class_1517000367">
<p><br></p><p> src/httpc.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-<br> 1 file changed, 52 insertions(+), 1 deletion(-)</p><p>diff --git a/src/httpc.c b/src/httpc.c<br>index 84ea67aba..885ce1b98 100644<br>--- a/src/httpc.c<br>+++ b/src/httpc.c<br>@@ -32,10 +32,36 @@<br> #include "httpc.h"<br> <br> #include <assert.h><br>+#include <ctype.h><br> #include <curl/curl.h><br> <br> #include "fiber.h"<br> <br>+static const char *HTTP_LOCALHOST = "http://localhost";<br>+static const char *HTTP_UNIX_PREFIX = "http+unix://";<br>+<br>+/**<br>+ * Function to decode encoded symbols in http url.<br>+ */<br>+static int<br>+urldecode(const char *s, const char *end, char *dec)<br>+{<br>+ char *o;<br>+ int c;<br>+<br>+ for (o = dec; s != end; o++) {<br>+ c = *s++;<br>+ if (c == '+') c = ' ';<br>+ else if (c == '%' && (!isxdigit(*s++) ||<br>+ !isxdigit(*s++) ||<br>+ !sscanf(s - 2, "%2x", &c)))<br>+ return -1;<br>+ *o = c;<br>+ }<br>+ *o = '\0';<br>+ return o - dec;<br>+}<br>+<br> /**<br> * libcurl callback for CURLOPT_WRITEFUNCTION<br> * @see <a href="https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html" target="_blank">https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html</a><br>@@ -134,7 +160,32 @@ httpc_request_new(struct httpc_env *env, const char *method,<br> curl_easy_setopt(req->curl_request.easy, CURLOPT_CUSTOMREQUEST, method);<br> }<br> <br>- curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>+ const int prefix_len = strlen(HTTP_UNIX_PREFIX);<br>+ if (strncmp(url, HTTP_UNIX_PREFIX, prefix_len) == 0) {<br>+ const int url_len = strlen(url);<br>+ struct region region;<br>+ struct slab_cache cache;<br>+ region_create(&region, &cache);<br>+ char *http_url = (char *) region_alloc(&region,<br>+ strlen(HTTP_LOCALHOST) + url_len - prefix_len + 1);<br>+<br>+ const char *socket_path_start = url + prefix_len;<br>+ const char *socket_path_end = strchr(socket_path_start, '/');<br>+ if (socket_path_end == NULL)<br>+ socket_path_end = url + url_len;<br>+<br>+ char *socket_path = (char *) region_alloc(&region,<br>+ socket_path_end - socket_path_start + 1);<br>+ urldecode(socket_path_start, socket_path_end, socket_path);<br>+ sprintf(http_url, "%s%s", HTTP_LOCALHOST, socket_path_end);<br>+<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_UNIX_SOCKET_PATH, socket_path);<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, http_url);<br>+<br>+ region_free(&region);<br>+ } else {<br>+ curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>+ }<br> <br> curl_easy_setopt(req->curl_request.easy, CURLOPT_FOLLOWLOCATION, 1);<br> curl_easy_setopt(req->curl_request.easy, CURLOPT_SSL_VERIFYPEER, 1);<br><br></p><p> </p><br><br><br><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px;">
        Пятница, 26 января 2018, 14:19 +03:00 от Vladimir Davydov <<a href="mailto:vdavydov.dev@gmail.com">vdavydov.dev@gmail.com</a>>:<br>
        <br>
        <div id="">




























<div class="js-helper_mailru_css_attribute_postfix js-readmsg-msg_mailru_css_attribute_postfix">
        <style></style>
        <div>
                
                
            <div id="style_15169655540000000367_BODY_mailru_css_attribute_postfix">Style: Would be nice to add 'httpc: ' to the commit message subject:<br>
<br>
  httpc: add support for unix protocol<br>
<br>
On Fri, Jan 26, 2018 at 11:51:14AM +0300, Konstantin Belyavskiy wrote:<br>
                                 > The http+unix:// is http protocol over unix domain sockets.<br>
> implementation based on original racktear proposal<br>
> decided to support only http+unix format<br>
> decided not to use our uri parser<br>
      <br>
Style: I don't think it's worth enumerating what we decided NOT to do.<br>
<br>
> <br>
> closes #3040<br>
<br>
Style: Should start with a capital letter.<br>
<br>
> ---<br>
> branch: gh-3040-unix-domain-sockets-orig-fix-formatting<br>
>  src/httpc.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-<br>
>  src/httpc.h |  1 +<br>
<br>
Please add a test.<br>
<br>
>  2 files changed, 49 insertions(+), 1 deletion(-)<br>
> <br>
> diff --git a/src/httpc.c b/src/httpc.c<br>
> index 84ea67aba..d5ad1164b 100644<br>
> --- a/src/httpc.c<br>
> +++ b/src/httpc.c<br>
> @@ -36,6 +36,31 @@<br>
>  <br>
>  #include "fiber.h"<br>
>  <br>
> +static const char *HTTP_LOCALHOST = "http://localhost";<br>
> +static const char *HTTP_UNIX_PREFIX = "http+unix://";<br>
> +<br>
> +/**<br>
> + * function to decode encoded symbols in http url<br>
<br>
Style: Start sentences with a capital letter and end with a dot.<br>
<br>
> + */<br>
> +static int<br>
> +urldecode(const char *s, const char *end, char *dec)<br>
> +{<br>
> +  char *o;<br>
> +  int c;<br>
> +<br>
> +  for (o = dec; s <= end; o++) {<br>
<br>
In our code, 'end' usually points to the entry following the last one in<br>
a set (just like in STL) and this is actually true in your case. So this<br>
should be:<br>
<br>
  for (o = dec; s != end; o++)<br>
<br>
> +          c = *s++;<br>
> +          if (c == '+') c = ' ';<br>
> +          else if (c == '%' && (!isxdigit(*s++) ||<br>
> +                                !isxdigit(*s++) ||<br>
> +                                !sscanf(s - 2, "%2x", &c)))<br>
> +                  return -1;<br>
> +          *o = c;<br>
> +  }<br>
<br>
I think this function should set the terminating nul.<br>
<br>
> +<br>
> +  return o - dec;<br>
> +}<br>
> +<br>
>  /**<br>
>   * libcurl callback for CURLOPT_WRITEFUNCTION<br>
>   * @see <a href="https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html" target="_blank" rel=" noopener noreferrer">https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html</a><br>
> @@ -134,7 +159,29 @@ httpc_request_new(struct httpc_env *env, const char *method,<br>
>            curl_easy_setopt(req->curl_request.easy, CURLOPT_CUSTOMREQUEST, method);<br>
>    }<br>
>  <br>
> -  curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>
> +  const int prefix_len = strlen(HTTP_UNIX_PREFIX);<br>
> +  if (strncmp(url, HTTP_UNIX_PREFIX, prefix_len) == 0) {<br>
> +          const int url_len = strlen(url);<br>
> +          char *http_url = (char *) malloc(strlen(HTTP_LOCALHOST) +<br>
> +                                           url_len - prefix_len + 1);<br>
<br>
Please consider using the region allocator instead of malloc if<br>
possible - it is much more efficient in terms of performance.<br>
And don't forget to handle allocation failures.<br>
<br>
> +<br>
> +          const char *socket_path_start = url + prefix_len;<br>
> +          const char *socket_path_end = strchr(socket_path_start, '/');<br>
> +          if (socket_path_end == NULL)<br>
> +                  socket_path_end = url + url_len;<br>
> +<br>
> +          char *socket_path = (char *) malloc(socket_path_end - socket_path_start + 1);<br>
> +          urldecode(socket_path_start, socket_path_end, socket_path);<br>
> +          sprintf(http_url, "http://localhost%s", socket_path_end);<br>
<br>
Please reuse HTTP_LOCALHOST here:<br>
<br>
  sprintf(http_url, HTTP_LOCALHOST "%s", socket_path_end);<br>
<br>
> +<br>
> +          curl_easy_setopt(req->curl_request.easy, CURLOPT_UNIX_SOCKET_PATH, socket_path);<br>
> +          curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, http_url);<br>
> +<br>
> +          free(http_url);<br>
> +          free(socket_path);<br>
> +  } else {<br>
> +          curl_easy_setopt(req->curl_request.easy, CURLOPT_URL, url);<br>
> +  }<br>
>  <br>
>    curl_easy_setopt(req->curl_request.easy, CURLOPT_FOLLOWLOCATION, 1);<br>
>    curl_easy_setopt(req->curl_request.easy, CURLOPT_SSL_VERIFYPEER, 1);<br>
> diff --git a/src/httpc.h b/src/httpc.h<br>
> index 3358fd914..8c3e75f75 100644<br>
> --- a/src/httpc.h<br>
> +++ b/src/httpc.h<br>
> @@ -34,6 +34,7 @@<br>
>  #include <small/region.h><br>
>  #include <small/mempool.h><br>
>  #include <tarantool_ev.h><br>
> +#include <ctype.h><br>
<br>
Please avoid including in headers - this slows down compilation.<br>
Include in C files if possible.<br>
</div>
            
        
                
        </div>

        
</div>


</div>
</blockquote></div>
<br>
<br>С уважением,<br>Konstantin Belyavskiy<br><a href="mailto:k.belyavskiy@tarantool.org">k.belyavskiy@tarantool.org</a><br>
</div></div>
            
        
                <base target="_self" href="https://e.mail.ru/">
        </div>

        
</div>


</div>
</blockquote>
<br>
<br>С уважением,<br>Konstantin Belyavskiy<br>k.belyavskiy@tarantool.org<br></BODY></HTML>