aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/http.c50
-rw-r--r--lib/setopt.c7
-rw-r--r--lib/urldata.h2
3 files changed, 59 insertions, 0 deletions
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;