gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 14/178: CURLOPT_HAPROXYPROTOCOL: support the HAProx


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 14/178: CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol
Date: Wed, 23 May 2018 12:24:09 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 6baeb6df35d24740c55239f24b5fc4ce86f375a5
Author: Lawrence Matthews <address@hidden>
AuthorDate: Thu Dec 1 04:05:04 2016 -0800

    CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol
    
    Add --haproxy-protocol for the command line tool
    
    Closes #2162
---
 docs/cmdline-opts/haproxy-protocol.d        | 11 ++++++
 docs/libcurl/curl_easy_setopt.3             |  2 +
 docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 | 57 ++++++++++++++++++++++++++++
 docs/libcurl/opts/Makefile.inc              |  1 +
 docs/libcurl/symbols-in-versions            |  1 +
 include/curl/curl.h                         |  3 ++
 lib/http.c                                  | 50 ++++++++++++++++++++++++
 lib/setopt.c                                |  7 ++++
 lib/urldata.h                               |  2 +
 src/tool_cfgable.h                          |  1 +
 src/tool_getparam.c                         |  4 ++
 src/tool_help.c                             |  2 +
 src/tool_operate.c                          |  4 ++
 tests/data/Makefile.inc                     |  2 +-
 tests/data/test1455                         | 56 +++++++++++++++++++++++++++
 tests/data/test1456                         | 59 +++++++++++++++++++++++++++++
 16 files changed, 261 insertions(+), 1 deletion(-)

diff --git a/docs/cmdline-opts/haproxy-protocol.d 
b/docs/cmdline-opts/haproxy-protocol.d
new file mode 100644
index 000000000..52e156058
--- /dev/null
+++ b/docs/cmdline-opts/haproxy-protocol.d
@@ -0,0 +1,11 @@
+Long: haproxy-protocol
+Help: Send HAProxy PROXY protocol header
+Protocols: HTTP
+Added: 7.60.0
+---
+Send a HAProxy PROXY protocol header at the beginning of the connection. This
+is used by some load balancers and reverse proxies to indicate the client's
+true IP address and port.
+
+This option is primarily useful when sending test requests to a service that
+expects this header.
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 1efb467e6..b7d67f360 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -185,6 +185,8 @@ Socks5 GSSAPI service name. 
\fICURLOPT_SOCKS5_GSSAPI_SERVICE(3)\fP
 Socks5 GSSAPI NEC mode. See \fICURLOPT_SOCKS5_GSSAPI_NEC(3)\fP
 .IP CURLOPT_PROXY_SERVICE_NAME
 Proxy authentication service name. \fICURLOPT_PROXY_SERVICE_NAME(3)\fP
+.IP CURLOPT_HAPROXYPROTOCOL
+Send an HAProxy PROXY protocol header. See \fICURLOPT_HAPROXYPROTOCOL(3)\fP
 .IP CURLOPT_SERVICE_NAME
 Authentication service name. \fICURLOPT_SERVICE_NAME(3)\fP
 .IP CURLOPT_INTERFACE
diff --git a/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 
b/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3
new file mode 100644
index 000000000..01e667d16
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3
@@ -0,0 +1,57 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HAPROXYPROTOCOL 3 "5 Feb 2018" "libcurl 7.60.0" "curl_easy_setopt 
options"
+.SH NAME
+CURLOPT_HAPROXYPROTOCOL \- send HAProxy PROXY protocol header
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HAPROXYPROTOCOL,
+                          long haproxy_protocol);
+.SH DESCRIPTION
+A long parameter set to 1 tells the library to send an HAProxy PROXY
+protocol header at beginning of the connection. The default action is not to
+send this header.
+
+This option is primarily useful when sending test requests to a service that
+expects this header.
+
+Most applications do not need this option.
+.SH DEFAULT
+0, do not send HAProxy PROXY protocol header
+.SH PROTOCOLS
+HTTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  CURLcode ret;
+  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/";);
+  curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L);
+  ret = curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Along with HTTP. Added in 7.60.0.
+.SH RETURN VALUE
+Returns CURLE_OK if HTTP is enabled, and CURLE_UNKNOWN_OPTION if not.
diff --git a/docs/libcurl/opts/Makefile.inc b/docs/libcurl/opts/Makefile.inc
index 2aa1acf33..b370082d6 100644
--- a/docs/libcurl/opts/Makefile.inc
+++ b/docs/libcurl/opts/Makefile.inc
@@ -137,6 +137,7 @@ man_MANS =                                      \
   CURLOPT_FTP_USE_PRET.3                        \
   CURLOPT_GSSAPI_DELEGATION.3                   \
   CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3           \
+  CURLOPT_HAPROXYPROTOCOL.3                     \
   CURLOPT_HEADER.3                              \
   CURLOPT_HEADERDATA.3                          \
   CURLOPT_HEADERFUNCTION.3                      \
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index c58086fb7..2877de7f1 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -404,6 +404,7 @@ CURLOPT_FTP_USE_EPSV            7.9.2
 CURLOPT_FTP_USE_PRET            7.20.0
 CURLOPT_GSSAPI_DELEGATION       7.22.0
 CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS 7.59.0
+CURLOPT_HAPROXYPROTOCOL         7.60.0
 CURLOPT_HEADER                  7.1
 CURLOPT_HEADERDATA              7.10
 CURLOPT_HEADERFUNCTION          7.7.2
diff --git a/include/curl/curl.h b/include/curl/curl.h
index fa019eca9..43d5e031f 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1841,6 +1841,9 @@ typedef enum {
   /* User data to pass to the resolver start callback. */
   CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273),
 
+  /* send HAProxy PROXY protocol header? */
+  CINIT(HAPROXYPROTOCOL, LONG, 274),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
diff --git a/lib/http.c b/lib/http.c
index 841f6cc0b..29dcf6562 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -92,6 +92,8 @@ static int http_getsock_do(struct connectdata *conn,
                            int numsocks);
 static int http_should_fail(struct connectdata *conn);
 
+static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
+
 #ifdef USE_SSL
 static CURLcode https_connecting(struct connectdata *conn, bool *done);
 static int https_getsock(struct connectdata *conn,
@@ -1358,6 +1360,13 @@ CURLcode Curl_http_connect(struct connectdata *conn, 
bool *done)
     /* nothing else to do except wait right now - we're not done here. */
     return CURLE_OK;
 
+  if(conn->data->set.haproxyprotocol) {
+    /* add HAProxy PROXY protocol header */
+    result = add_haproxy_protocol_header(conn);
+    if(result)
+      return result;
+  }
+
   if(conn->given->protocol & CURLPROTO_HTTPS) {
     /* perform SSL initialization */
     result = https_connecting(conn, done);
@@ -1383,6 +1392,47 @@ static int http_getsock_do(struct connectdata *conn,
   return GETSOCK_WRITESOCK(0);
 }
 
+static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
+{
+  char proxy_header[128];
+  Curl_send_buffer *req_buffer;
+  CURLcode result;
+  char tcp_version[5];
+
+  /* Emit the correct prefix for IPv6 */
+  if(conn->bits.ipv6) {
+    strcpy(tcp_version, "TCP6");
+  }
+  else {
+    strcpy(tcp_version, "TCP4");
+  }
+
+  snprintf(proxy_header,
+           sizeof proxy_header,
+           "PROXY %s %s %s %i %i\r\n",
+           tcp_version,
+           conn->data->info.conn_local_ip,
+           conn->data->info.conn_primary_ip,
+           conn->data->info.conn_local_port,
+           conn->data->info.conn_primary_port);
+
+  req_buffer = Curl_add_buffer_init();
+  if(!req_buffer)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = Curl_add_bufferf(req_buffer, proxy_header);
+  if(result)
+    return result;
+
+  result = Curl_add_buffer_send(req_buffer,
+                                conn,
+                                &conn->data->info.request_size,
+                                0,
+                                FIRSTSOCKET);
+
+  return result;
+}
+
 #ifdef USE_SSL
 static CURLcode https_connecting(struct connectdata *conn, bool *done)
 {
diff --git a/lib/setopt.c b/lib/setopt.c
index 9c96eb358..737a60f85 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -1603,6 +1603,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption 
option,
     data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
 
+  case CURLOPT_HAPROXYPROTOCOL:
+    /*
+     * Set to send the HAProxy Proxy Protocol header
+     */
+    data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
   case CURLOPT_INTERFACE:
     /*
      * Set what interface or address/hostname to bind the socket to when
diff --git a/lib/urldata.h b/lib/urldata.h
index 0da5fbce0..dad31cd4e 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1678,6 +1678,8 @@ struct UserDefined {
   bool stream_depends_e; /* set or don't set the Exclusive bit */
   int stream_weight;
 
+  bool haproxyprotocol; /* whether to send HAProxy PROXY protocol header */
+
   struct Curl_http2_dep *stream_dependents;
 
   bool abstract_unix_socket;
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 743ce725d..9abaa9d39 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -252,6 +252,7 @@ struct OperationConfig {
   bool ssh_compression;           /* enable/disable SSH compression */
   long happy_eyeballs_timeout_ms; /* happy eyeballs timeout in milliseconds.
                                      0 is valid. default: CURL_HET_DEFAULT. */
+  bool haproxy_protocol;          /* whether to send HAProxy PROXY protocol */
   struct GlobalConfig *global;
   struct OperationConfig *prev;
   struct OperationConfig *next;   /* Always last in the struct */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 7ce9c28c7..19454c84a 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -112,6 +112,7 @@ static const struct LongShort aliases[]= {
   {"*x", "krb",                      ARG_STRING},
   {"*x", "krb4",                     ARG_STRING},
          /* 'krb4' is the previous name */
+  {"*X", "haproxy-protocol",         ARG_BOOL},
   {"*y", "max-filesize",             ARG_STRING},
   {"*z", "disable-eprt",             ARG_BOOL},
   {"*Z", "eprt",                     ARG_BOOL},
@@ -779,6 +780,9 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
         else
           return PARAM_LIBCURL_DOESNT_SUPPORT;
         break;
+      case 'X': /* --haproxy-protocol */
+        config->haproxy_protocol = toggle;
+        break;
       case 'y': /* --max-filesize */
         {
           curl_off_t value;
diff --git a/src/tool_help.c b/src/tool_help.c
index 9796b7e87..4bd65269a 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -164,6 +164,8 @@ static const struct helptxt helptext[] = {
    "How long to wait in milliseconds for IPv6 before trying IPv4"},
   {"-I, --head",
    "Show document info only"},
+  {"    --haproxy-protocol",
+   "Send HAProxy PROXY protocol header"},
   {"-H, --header <header/@file>",
    "Pass custom header(s) to server"},
   {"-h, --help",
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 15cdc13da..0aad54282 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1445,6 +1445,10 @@ static CURLcode operate_do(struct GlobalConfig *global,
           my_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
                     config->happy_eyeballs_timeout_ms);
 
+        /* new in 7.60.0 */
+        if(config->haproxy_protocol)
+          my_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L);
+
         /* initialize retry vars for loop below */
         retry_sleep_default = (config->retry_delay) ?
           config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 5fcffc6eb..ca0c7edd1 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -165,7 +165,7 @@ test1424 test1425 test1426 test1427 \
 test1428 test1429 test1430 test1431 test1432 test1433 test1434 test1435 \
 test1436 test1437 test1438 test1439 test1440 test1441 test1442 test1443 \
 test1444 test1445 test1446 test1447 test1448 test1449 test1450 test1451 \
-test1452 test1453 test1454 \
+test1452 test1453 test1454 test1455 test1456 \
 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
 test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
 test1516 test1517 \
diff --git a/tests/data/test1455 b/tests/data/test1455
new file mode 100644
index 000000000..7768a1f89
--- /dev/null
+++ b/tests/data/test1455
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply name="1455">
+<data nocheck=yes>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: barkbark
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP GET when PROXY Protocol enabled
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol --local-port 37756
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+PROXY TCP4 %CLIENTIP %HOSTIP 37756 %HTTPPORT
+GET /1455 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1456 b/tests/data/test1456
new file mode 100644
index 000000000..07a6e7c03
--- /dev/null
+++ b/tests/data/test1456
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+IPv6
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck=yes>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+ipv6
+</features>
+<server>
+http-ipv6
+</server>
+ <name>
+HTTP-IPv6 GET with PROXY protocol
+ </name>
+ <command>
+-g "http://%HOST6IP:%HTTP6PORT/1456"; --local-port 44444 --haproxy-protocol
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:
+</strip>
+<protocol>
+PROXY TCP6 ::1 ::1 44444 %HTTP6PORT
+GET /1456 HTTP/1.1
+Host: %HOST6IP:%HTTP6PORT
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]