mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Proxy system: ability to reconnect to the proxy server.
Another awkward thing that FreeProxy does is to slam the connection shut after sending its 407 response, at least in Basic auth mode. (It keeps the connection alive in digest mode, which makes sense to me, because that's a more stateful system.) It was surprisingly easy to make the proxy code able to tolerate this! I've set it up so that a ProxyNegotiator can just set its 'reconnect' flag on return from the negotiation coroutine, and the effect will be that proxy.c makes a new connection to the same proxy server before doing anything else. In particular, you can set that flag _and_ put data in the output bufchain, and there's no problem - the output data will be queued directly into the new socket.
This commit is contained in:
parent
099d00c4ac
commit
6c754822bc
@ -670,9 +670,9 @@ static void proxy_http_process_queue(ProxyNegotiator *pn)
|
|||||||
/* 407 is Proxy Authentication Required, which we may be
|
/* 407 is Proxy Authentication Required, which we may be
|
||||||
* able to do something about. */
|
* able to do something about. */
|
||||||
if (s->connection_close) {
|
if (s->connection_close) {
|
||||||
pn->error = dupprintf("HTTP proxy closed connection after "
|
/* If we got 407 + connection closed, reconnect before
|
||||||
"asking for authentication");
|
* sending our next request. */
|
||||||
crStopV;
|
pn->reconnect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the best we can do is report some kind of error from
|
/* If the best we can do is report some kind of error from
|
||||||
|
@ -99,6 +99,7 @@ static void sk_proxy_close (Socket *s)
|
|||||||
ProxySocket *ps = container_of(s, ProxySocket, sock);
|
ProxySocket *ps = container_of(s, ProxySocket, sock);
|
||||||
|
|
||||||
sk_close(ps->sub_socket);
|
sk_close(ps->sub_socket);
|
||||||
|
sk_addr_free(ps->proxy_addr);
|
||||||
sk_addr_free(ps->remote_addr);
|
sk_addr_free(ps->remote_addr);
|
||||||
proxy_negotiator_cleanup(ps);
|
proxy_negotiator_cleanup(ps);
|
||||||
bufchain_clear(&ps->output_from_negotiator);
|
bufchain_clear(&ps->output_from_negotiator);
|
||||||
@ -223,6 +224,16 @@ static void proxy_negotiate(ProxySocket *ps)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps->pn->reconnect) {
|
||||||
|
sk_close(ps->sub_socket);
|
||||||
|
SockAddr *proxy_addr = sk_addr_dup(ps->proxy_addr);
|
||||||
|
ps->sub_socket = sk_new(proxy_addr, ps->proxy_port,
|
||||||
|
ps->proxy_privport, ps->proxy_oobinline,
|
||||||
|
ps->proxy_nodelay, ps->proxy_keepalive,
|
||||||
|
&ps->plugimpl);
|
||||||
|
ps->pn->reconnect = false;
|
||||||
|
}
|
||||||
|
|
||||||
while (bufchain_size(&ps->output_from_negotiator)) {
|
while (bufchain_size(&ps->output_from_negotiator)) {
|
||||||
ptrlen data = bufchain_prefix(&ps->output_from_negotiator);
|
ptrlen data = bufchain_prefix(&ps->output_from_negotiator);
|
||||||
sk_write(ps->sub_socket, data.ptr, data.len);
|
sk_write(ps->sub_socket, data.ptr, data.len);
|
||||||
@ -601,10 +612,16 @@ Socket *new_connection(SockAddr *addr, const char *hostname,
|
|||||||
/* create the actual socket we will be using,
|
/* create the actual socket we will be using,
|
||||||
* connected to our proxy server and port.
|
* connected to our proxy server and port.
|
||||||
*/
|
*/
|
||||||
ps->sub_socket = sk_new(proxy_addr,
|
ps->proxy_addr = sk_addr_dup(proxy_addr);
|
||||||
conf_get_int(conf, CONF_proxy_port),
|
ps->proxy_port = conf_get_int(conf, CONF_proxy_port);
|
||||||
privport, oobinline,
|
ps->proxy_privport = privport;
|
||||||
nodelay, keepalive, &ps->plugimpl);
|
ps->proxy_oobinline = oobinline;
|
||||||
|
ps->proxy_nodelay = nodelay;
|
||||||
|
ps->proxy_keepalive = keepalive;
|
||||||
|
ps->sub_socket = sk_new(proxy_addr, ps->proxy_port,
|
||||||
|
ps->proxy_privport, ps->proxy_oobinline,
|
||||||
|
ps->proxy_nodelay, ps->proxy_keepalive,
|
||||||
|
&ps->plugimpl);
|
||||||
if (sk_socket_error(ps->sub_socket) != NULL)
|
if (sk_socket_error(ps->sub_socket) != NULL)
|
||||||
return &ps->sock;
|
return &ps->sock;
|
||||||
|
|
||||||
|
@ -22,6 +22,11 @@ struct ProxySocket {
|
|||||||
SockAddr *remote_addr;
|
SockAddr *remote_addr;
|
||||||
int remote_port;
|
int remote_port;
|
||||||
|
|
||||||
|
/* Parameters needed to make further connections to the proxy */
|
||||||
|
SockAddr *proxy_addr;
|
||||||
|
int proxy_port;
|
||||||
|
bool proxy_privport, proxy_oobinline, proxy_nodelay, proxy_keepalive;
|
||||||
|
|
||||||
bufchain pending_output_data;
|
bufchain pending_output_data;
|
||||||
bufchain pending_oob_output_data;
|
bufchain pending_oob_output_data;
|
||||||
bufchain pending_input_data;
|
bufchain pending_input_data;
|
||||||
@ -68,6 +73,11 @@ struct ProxyNegotiator {
|
|||||||
|
|
||||||
/* Set to report user abort during proxy negotiation. */
|
/* Set to report user abort during proxy negotiation. */
|
||||||
bool aborted;
|
bool aborted;
|
||||||
|
|
||||||
|
/* Set to request the centralised code to make a fresh connection
|
||||||
|
* to the proxy server, e.g. because an HTTP proxy slammed the
|
||||||
|
* connection shut after sending 407 Proxy Auth Required. */
|
||||||
|
bool reconnect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProxyNegotiatorVT {
|
struct ProxyNegotiatorVT {
|
||||||
|
Loading…
Reference in New Issue
Block a user