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:: INLINE void HTTPClient::
set_proxy(const URLSpec &proxy) { set_proxy(const URLSpec &proxy) {
_proxy = 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(); proxy_server << _proxy.get_server() << ":" << _proxy.get_port();
string proxy_server_str = proxy_server.str(); string proxy_server_str = proxy_server.str();
BIO *bio = BIO_new_connect((char *)proxy_server_str.c_str());
if (downloader_cat.is_debug()) { if (downloader_cat.is_debug()) {
downloader_cat.debug() downloader_cat.debug()
<< "connecting to proxy " << proxy_server_str << "\n"; << "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; ostringstream request;
request request
<< "CONNECT " << url.get_server() << ":" << url.get_port() << "CONNECT " << url.get_server() << ":" << url.get_port()
<< " " << get_http_version_string() << "\r\n"; << " " << get_http_version_string() << "\r\n";
if (_http_version > HV_10) {
request
<< "Host: " << url.get_server() << "\r\n";
}
string connect_header = request.str(); 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 // Create a temporary HTTPDocument to issue the request and read the
// response from the proxy. // response from the proxy.
{ {
string old_proxy_authorization = _proxy_authorization;
PT(HTTPDocument) doc = new HTTPDocument(this, bio); 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() downloader_cat.info()
<< "proxy would not open connection to " << url.get_authority() << "proxy would not open connection to " << url.get_authority()
<< ": " << doc->get_status_code() << " " << ": " << doc->get_status_code() << " "
@ -712,7 +740,9 @@ make_https_connection(BIO *bio, const URLSpec &url) const {
#ifdef REPORT_SSL_ERRORS #ifdef REPORT_SSL_ERRORS
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
#endif #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; return NULL;
} }

View File

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

View File

@ -127,19 +127,31 @@ send_request(const string &method, const URLSpec &url, const string &body) {
bool HTTPDocument:: bool HTTPDocument::
send_request(const string &header, const string &body) { send_request(const string &header, const string &body) {
if (prepare_for_next()) { 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()) { if (get_status_code() == 407 && !_proxy.empty()) {
// 407: not authorized to proxy. Try to get the authorization. // 407: not authorized to proxy. Try to get the authorization.
string authenticate_request = get_header_value("Proxy-Authenticate"); string authenticate_request = get_header_value("Proxy-Authenticate");
string authorization; string authorization;
if (get_authorization(authorization, authenticate_request, _proxy, true)) { if (get_authorization(authorization, authenticate_request, _proxy, true)) {
string new_header = header; if (_client->_proxy_authorization != authorization) {
new_header += "Proxy-Authorization: "; // Change the authorization.
new_header += authorization; _client->_proxy_authorization = authorization;
new_header += "\r\n"; proxy_auth_header = header;
proxy_auth_header += "Proxy-Authorization: ";
proxy_auth_header += _client->_proxy_authorization;
proxy_auth_header += "\r\n";
if (prepare_for_next()) { if (prepare_for_next()) {
issue_request(new_header, body); 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 authenticate_request = get_header_value("WWW-Authenticate");
string authorization; string authorization;
if (get_authorization(authorization, authenticate_request, _url, false)) { if (get_authorization(authorization, authenticate_request, _url, false)) {
string new_header = header; string web_auth_header = proxy_auth_header;
new_header += "Authorization: "; web_auth_header += "Authorization: ";
new_header += authorization; web_auth_header += authorization;
new_header += "\r\n"; web_auth_header += "\r\n";
if (prepare_for_next()) { 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. // Look in several places in order to find the matching username.
// Fist, if there's a username on the URL, that always wins. // Fist, if there's a username on the URL, that always wins (except
if (url.has_username()) { // when we are looking for a proxy username).
if (url.has_username() && !is_proxy) {
username = url.get_username(); username = url.get_username();
} }