diff options
author | Lawrence Matthews <lmatthew@yelp.com> | 2016-12-01 04:05:04 -0800 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2018-03-17 11:50:06 +0100 |
commit | 6baeb6df35d24740c55239f24b5fc4ce86f375a5 (patch) | |
tree | 6a8ec40408e6827f40b750985517e575c89545fc /lib | |
parent | 9572831b0470378c2f45f2891feb91dea19c16d7 (diff) |
CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol
Add --haproxy-protocol for the command line tool
Closes #2162
Diffstat (limited to 'lib')
-rw-r--r-- | lib/http.c | 50 | ||||
-rw-r--r-- | lib/setopt.c | 7 | ||||
-rw-r--r-- | lib/urldata.h | 2 |
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; |