mirror of
https://github.com/curl/curl.git
synced 2025-09-16 17:12:43 +03:00
proxy: refactor haproxy protocol handling as connection filter
Closes #9893
This commit is contained in:
parent
6967571bf2
commit
a8e6351e12
|
@ -328,6 +328,15 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
|
|||
#else
|
||||
(void)ssl_mode;
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(data->set.haproxyprotocol) {
|
||||
result = Curl_cfilter_haproxy_add(data, conn, sockindex);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
#endif /* !CURL_DISABLE_PROXY */
|
||||
|
||||
}
|
||||
DEBUGASSERT(conn->cfilter[sockindex]);
|
||||
cf = data->conn->cfilter[sockindex];
|
||||
|
|
59
lib/http.c
59
lib/http.c
|
@ -102,10 +102,6 @@ static int http_getsock_do(struct Curl_easy *data,
|
|||
curl_socket_t *socks);
|
||||
static bool http_should_fail(struct Curl_easy *data);
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
static CURLcode http_setup_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
#ifdef USE_WEBSOCKETS
|
||||
|
@ -1532,30 +1528,13 @@ Curl_compareheader(const char *headerline, /* line to check */
|
|||
*/
|
||||
CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
/* We default to persistent connections. We set this already in this connect
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
connkeep(conn, "HTTP default");
|
||||
|
||||
result = Curl_cfilter_connect(data, conn, FIRSTSOCKET, FALSE, done);
|
||||
if(result || !*done)
|
||||
return result;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(data->set.haproxyprotocol && !data->state.is_haproxy_hdr_sent) {
|
||||
/* add HAProxy PROXY protocol header */
|
||||
result = add_haproxy_protocol_header(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* do not send the header again after successful try */
|
||||
data->state.is_haproxy_hdr_sent = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
return Curl_cfilter_connect(data, conn, FIRSTSOCKET, FALSE, done);
|
||||
}
|
||||
|
||||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
|
@ -1571,42 +1550,6 @@ static int http_getsock_do(struct Curl_easy *data,
|
|||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
|
||||
{
|
||||
struct dynbuf req;
|
||||
CURLcode result;
|
||||
const char *tcp_version;
|
||||
DEBUGASSERT(data->conn);
|
||||
Curl_dyn_init(&req, DYN_HAXPROXY);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(data->conn->unix_domain_socket)
|
||||
/* the buffer is large enough to hold this! */
|
||||
result = Curl_dyn_addn(&req, STRCONST("PROXY UNKNOWN\r\n"));
|
||||
else {
|
||||
#endif
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
tcp_version = data->conn->bits.ipv6 ? "TCP6" : "TCP4";
|
||||
|
||||
result = Curl_dyn_addf(&req, "PROXY %s %s %s %i %i\r\n",
|
||||
tcp_version,
|
||||
data->info.conn_local_ip,
|
||||
data->info.conn_primary_ip,
|
||||
data->info.conn_local_port,
|
||||
data->info.conn_primary_port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!result)
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size,
|
||||
0, FIRSTSOCKET);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_http_done() gets called after a single HTTP request has been
|
||||
* performed.
|
||||
|
|
|
@ -1188,4 +1188,91 @@ CURLcode Curl_cfilter_http_proxy_add(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY && !defined(CURL_DISABLE_HTTP) */
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
static CURLcode send_haproxy_header(struct Curl_cfilter*cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct dynbuf req;
|
||||
CURLcode result;
|
||||
const char *tcp_version;
|
||||
Curl_dyn_init(&req, DYN_HAXPROXY);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(cf->conn->unix_domain_socket)
|
||||
/* the buffer is large enough to hold this! */
|
||||
result = Curl_dyn_addn(&req, STRCONST("PROXY UNKNOWN\r\n"));
|
||||
else {
|
||||
#endif
|
||||
/* Emit the correct prefix for IPv6 */
|
||||
tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
|
||||
|
||||
result = Curl_dyn_addf(&req, "PROXY %s %s %s %i %i\r\n",
|
||||
tcp_version,
|
||||
data->info.conn_local_ip,
|
||||
data->info.conn_primary_ip,
|
||||
data->info.conn_local_port,
|
||||
data->info.conn_primary_port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!result)
|
||||
result = Curl_buffer_send(&req, data, &data->info.request_size,
|
||||
0, FIRSTSOCKET);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode haproxy_cf_connect(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool blocking, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
if(cf->connected) {
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
result = cf->next->cft->connect(cf->next, data, blocking, done);
|
||||
if(result || !*done)
|
||||
return result;
|
||||
|
||||
result = send_haproxy_header(cf, data);
|
||||
*done = (!result);
|
||||
cf->connected = *done;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct Curl_cftype cft_haproxy = {
|
||||
"HAPROXY",
|
||||
Curl_cf_def_destroy,
|
||||
Curl_cf_def_attach_data,
|
||||
Curl_cf_def_detach_data,
|
||||
Curl_cf_def_setup,
|
||||
Curl_cf_def_close,
|
||||
haproxy_cf_connect,
|
||||
Curl_cf_def_get_select_socks,
|
||||
Curl_cf_def_data_pending,
|
||||
Curl_cf_def_send,
|
||||
Curl_cf_def_recv,
|
||||
};
|
||||
|
||||
CURLcode Curl_cfilter_haproxy_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_cfilter_create(&cf, data, conn, sockindex,
|
||||
&cft_haproxy, NULL);
|
||||
if(!result)
|
||||
Curl_cfilter_add(data, conn, sockindex, cf);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY */
|
||||
|
|
|
@ -38,4 +38,12 @@ CURLcode Curl_cfilter_http_proxy_add(struct Curl_easy *data,
|
|||
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
CURLcode Curl_cfilter_haproxy_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
|
|
@ -1427,10 +1427,6 @@ struct UrlState {
|
|||
trailers_state trailers_state; /* whether we are sending trailers
|
||||
and what stage are we at */
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* to keep track whether we already sent PROXY header or not */
|
||||
BIT(is_haproxy_hdr_sent);
|
||||
#endif
|
||||
#ifdef USE_HYPER
|
||||
bool hconnect; /* set if a CONNECT request */
|
||||
CURLcode hresult; /* used to pass return codes back from hyper callbacks */
|
||||
|
|
Loading…
Reference in New Issue
Block a user