client: if get 417 HTTP status, switch to HTTP 1.0

417 (Expectation Failed) probably means we're talking to a 1.0 proxy
This commit is contained in:
David Anderson 2015-03-05 15:19:41 -08:00
parent 69aaf8adda
commit 7135f46c75
3 changed files with 21 additions and 9 deletions

View File

@ -63,6 +63,10 @@ static CURLM* g_curlMulti = NULL;
static char g_user_agent_string[256] = {""};
static const char g_content_type[] = {"Content-Type: application/x-www-form-urlencoded"};
static unsigned int g_trace_count = 0;
static bool got_expectation_failed = false;
// Whether we've got a 417 HTTP error.
// If we did, it's probably because we talked HTTP 1.1 to a 1.0 proxy;
// use 1.0 from now on.
char* get_user_agent_string() {
sprintf(g_user_agent_string, "BOINC client (%s %d.%d.%d)",
@ -557,7 +561,7 @@ int HTTP_OP::libcurl_exec(
// force curl to use HTTP/1.0 if config specifies it
// (curl uses 1.1 by default)
//
if (cc_config.http_1_0 || (cc_config.force_auth == "ntlm")) {
if (cc_config.http_1_0 || (cc_config.force_auth == "ntlm") || got_expectation_failed) {
curl_easy_setopt(curlEasy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
}
curl_easy_setopt(curlEasy, CURLOPT_MAXREDIRS, 50L);
@ -1011,6 +1015,9 @@ void HTTP_OP::handle_messages(CURLMsg *pcurlMsg) {
safe_strcpy(error_msg, boincerror(response));
break;
default: // 400
if (response == HTTP_STATUS_EXPECTATION_FAILED) {
got_expectation_failed = true;
}
http_op_retval = ERR_HTTP_PERMANENT;
safe_strcpy(error_msg, boincerror(response));
break;

View File

@ -59,8 +59,12 @@
#define HTTP_STATUS_NOT_FOUND 404
#define HTTP_STATUS_PROXY_AUTH_REQ 407
#define HTTP_STATUS_RANGE_REQUEST_ERROR 416
#define HTTP_STATUS_EXPECTATION_FAILED 417
#define HTTP_STATUS_INTERNAL_SERVER_ERROR 500
#define HTTP_STATUS_NOT_IMPLEMENTED 501
#define HTTP_STATUS_BAD_GATEWAY 502
#define HTTP_STATUS_SERVICE_UNAVAILABLE 503
#define HTTP_STATUS_GATEWAY_TIMEOUT 504
// graphics messages
//

View File

@ -534,14 +534,15 @@ const char* boincerror(int which_error) {
case ERR_PROC_PARSE: return "a /proc entry was not parsed correctly";
case ERR_PIPE: return "pipe() failed";
case ERR_NEED_HTTPS: return "HTTPS needed";
case 404: return "HTTP file not found";
case 407: return "HTTP proxy authentication failure";
case 416: return "HTTP range request error";
case 500: return "HTTP internal server error";
case 501: return "HTTP not implemented";
case 502: return "HTTP bad gateway";
case 503: return "HTTP service unavailable";
case 504: return "HTTP gateway timeout";
case HTTP_STATUS_NOT_FOUND: return "HTTP file not found";
case HTTP_STATUS_PROXY_AUTH_REQ: return "HTTP proxy authentication failure";
case HTTP_STATUS_RANGE_REQUEST_ERROR: return "HTTP range request error";
case HTTP_STATUS_EXPECTATION_FAILED: return "HTTP expectation failed";
case HTTP_STATUS_INTERNAL_SERVER_ERROR: return "HTTP internal server error";
case HTTP_STATUS_NOT_IMPLEMENTED: return "HTTP not implemented";
case HTTP_STATUS_BAD_GATEWAY: return "HTTP bad gateway";
case HTTP_STATUS_SERVICE_UNAVAILABLE: return "HTTP service unavailable";
case HTTP_STATUS_GATEWAY_TIMEOUT: return "HTTP gateway timeout";
}
static char buf[128];
sprintf(buf, "Error %d", which_error);