aboutsummaryrefslogtreecommitdiff
path: root/lib/http.c
diff options
context:
space:
mode:
authorLawrence Matthews <lmatthew@yelp.com>2016-12-01 04:05:04 -0800
committerDaniel Stenberg <daniel@haxx.se>2018-03-17 11:50:06 +0100
commit6baeb6df35d24740c55239f24b5fc4ce86f375a5 (patch)
tree6a8ec40408e6827f40b750985517e575c89545fc /lib/http.c
parent9572831b0470378c2f45f2891feb91dea19c16d7 (diff)
CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol
Add --haproxy-protocol for the command line tool Closes #2162
Diffstat (limited to 'lib/http.c')
-rw-r--r--lib/http.c50
1 files changed, 50 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)
{