diff options
Diffstat (limited to 'lib/http.c')
-rw-r--r-- | lib/http.c | 50 |
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) { |