proxy authorization

This commit is contained in:
David Rose 2002-10-14 22:05:08 +00:00
parent 728a04401b
commit dba02d9705
4 changed files with 71 additions and 26 deletions

View File

@ -26,6 +26,7 @@
INLINE void HTTPClient::
set_proxy(const URLSpec &proxy) {
_proxy = proxy;
_proxy_authorization = string();
}
////////////////////////////////////////////////////////////////////

View File

@ -626,32 +626,60 @@ establish_https_proxy(const URLSpec &url) {
proxy_server << _proxy.get_server() << ":" << _proxy.get_port();
string proxy_server_str = proxy_server.str();
BIO *bio = BIO_new_connect((char *)proxy_server_str.c_str());
if (downloader_cat.is_debug()) {
downloader_cat.debug()
<< "connecting to proxy " << proxy_server_str << "\n";
}
if (BIO_do_connect(bio) <= 0) {
downloader_cat.info()
<< "Could not contact proxy " << proxy_server_str << "\n";
#ifdef REPORT_SSL_ERRORS
ERR_print_errors_fp(stderr);
#endif
return NULL;
}
ostringstream request;
request
<< "CONNECT " << url.get_server() << ":" << url.get_port()
<< " " << get_http_version_string() << "\r\n";
if (_http_version > HV_10) {
request
<< "Host: " << url.get_server() << "\r\n";
}
string connect_header = request.str();
BIO *bio = BIO_new_connect((char *)proxy_server_str.c_str());
if (BIO_do_connect(bio) <= 0) {
downloader_cat.info()
<< "Could not contact proxy " << proxy_server_str << ".\n";
#ifdef REPORT_SSL_ERRORS
ERR_print_errors_fp(stderr);
#endif
return NULL;
}
// Create a temporary HTTPDocument to issue the request and read the
// response from the proxy.
{
string old_proxy_authorization = _proxy_authorization;
PT(HTTPDocument) doc = new HTTPDocument(this, bio);
if (!doc->send_request(connect_header, string())) {
bool connected = doc->send_request(connect_header, string());
if (!connected && doc->get_status_code() == 407 &&
_proxy_authorization != old_proxy_authorization) {
// 407: Proxy Authentication Required. If this happened, maybe
// we got the authentication already (but the HTTPDocument was
// not allowed to try to reconnect automatically). Try it
// again, once.
BIO_free_all(bio);
BIO *bio = BIO_new_connect((char *)proxy_server_str.c_str());
if (BIO_do_connect(bio) <= 0) {
downloader_cat.info()
<< "Could not contact proxy " << proxy_server_str
<< " a second time.\n";
#ifdef REPORT_SSL_ERRORS
ERR_print_errors_fp(stderr);
#endif
return NULL;
}
doc = new HTTPDocument(this, bio);
connected = doc->send_request(connect_header, string());
}
if (!connected) {
downloader_cat.info()
<< "proxy would not open connection to " << url.get_authority()
<< ": " << doc->get_status_code() << " "
@ -712,7 +740,9 @@ make_https_connection(BIO *bio, const URLSpec &url) const {
#ifdef REPORT_SSL_ERRORS
ERR_print_errors_fp(stderr);
#endif
BIO_free_all(sbio);
// It seems to be an error to free sbio at this point; perhaps
// it's already been freed?
BIO_free(bio);
return NULL;
}

View File

@ -118,6 +118,7 @@ private:
#endif
URLSpec _proxy;
string _proxy_authorization;
HTTPVersion _http_version;
VerifySSL _verify_ssl;

View File

@ -127,19 +127,31 @@ send_request(const string &method, const URLSpec &url, const string &body) {
bool HTTPDocument::
send_request(const string &header, const string &body) {
if (prepare_for_next()) {
issue_request(header, body);
// Tack on a proxy authorization if it is called for. Assume we
// can use the same authorization we used last time.
string proxy_auth_header = header;
if (!_proxy.empty() && !_client->_proxy_authorization.empty()) {
proxy_auth_header += "Proxy-Authorization: ";
proxy_auth_header += _client->_proxy_authorization;
proxy_auth_header += "\r\n";
}
issue_request(proxy_auth_header, body);
if (get_status_code() == 407 && !_proxy.empty()) {
// 407: not authorized to proxy. Try to get the authorization.
string authenticate_request = get_header_value("Proxy-Authenticate");
string authorization;
if (get_authorization(authorization, authenticate_request, _proxy, true)) {
string new_header = header;
new_header += "Proxy-Authorization: ";
new_header += authorization;
new_header += "\r\n";
if (prepare_for_next()) {
issue_request(new_header, body);
if (_client->_proxy_authorization != authorization) {
// Change the authorization.
_client->_proxy_authorization = authorization;
proxy_auth_header = header;
proxy_auth_header += "Proxy-Authorization: ";
proxy_auth_header += _client->_proxy_authorization;
proxy_auth_header += "\r\n";
if (prepare_for_next()) {
issue_request(proxy_auth_header, body);
}
}
}
}
@ -149,12 +161,12 @@ send_request(const string &header, const string &body) {
string authenticate_request = get_header_value("WWW-Authenticate");
string authorization;
if (get_authorization(authorization, authenticate_request, _url, false)) {
string new_header = header;
new_header += "Authorization: ";
new_header += authorization;
new_header += "\r\n";
string web_auth_header = proxy_auth_header;
web_auth_header += "Authorization: ";
web_auth_header += authorization;
web_auth_header += "\r\n";
if (prepare_for_next()) {
issue_request(new_header, body);
issue_request(web_auth_header, body);
}
}
}
@ -966,8 +978,9 @@ get_basic_authorization(string &authorization, const HTTPDocument::Tokens &token
// Look in several places in order to find the matching username.
// Fist, if there's a username on the URL, that always wins.
if (url.has_username()) {
// Fist, if there's a username on the URL, that always wins (except
// when we are looking for a proxy username).
if (url.has_username() && !is_proxy) {
username = url.get_username();
}