CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol

Add --haproxy-protocol for the command line tool

Closes #2162
This commit is contained in:
Lawrence Matthews 2016-12-01 04:05:04 -08:00 committed by Daniel Stenberg
parent 9572831b04
commit 6baeb6df35
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
16 changed files with 261 additions and 1 deletions

View file

@ -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)
{

View file

@ -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

View file

@ -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;