From 7936e47e9561da35d5a448c6ac96f7d495aa0d14 Mon Sep 17 00:00:00 2001 From: Walt Gribben Date: Tue, 21 Mar 2006 07:37:42 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=9693 --- checkin_notes | 14 ++++++++++++++ client/http_curl.C | 37 ++++++++++++++++++++++++++++++++++--- client/http_curl.h | 1 + client/net_xfer_curl.C | 14 +++++++++++--- client/net_xfer_curl.h | 4 ++++ 5 files changed, 64 insertions(+), 6 deletions(-) diff --git a/checkin_notes b/checkin_notes index bc166baf85..88d289a66f 100755 --- a/checkin_notes +++ b/checkin_notes @@ -3039,3 +3039,17 @@ David 20 Mar 2005 html/user/ get_project_config.php + +Walt 20 Mar 2005 + - Bug fix: Fix issues with proxy authorization: + -libcurl resends 'post' requests when negotiating authorization + type with the proxy server, needed curl callback function to + rewind the data. + -add variables to NET_XFER to save proxy server authorization type. + NET_XFER::auth_flag is BOOL, TRUE = proxy server uses authorization + NET_XFER::auth_type: 0 = libcurl negotiates auth type + ~0 = authorization type libcurl used with proxy + + client/ + http_xfer.C,h + net_xfer_curl.C,h \ No newline at end of file diff --git a/client/http_curl.C b/client/http_curl.C index bda801a58c..fdbc8c41c8 100644 --- a/client/http_curl.C +++ b/client/http_curl.C @@ -414,6 +414,10 @@ The checking this option controls is of the identity that the server claims. The // note that in my lib_write I'm sending in a pointer to this instance of HTTP_OP curlErr = curl_easy_setopt(curlEasy, CURLOPT_READDATA, this); + // callback function to rewind input file + curlErr = curl_easy_setopt(curlEasy, CURLOPT_IOCTLFUNCTION, libcurl_ioctl); + curlErr = curl_easy_setopt(curlEasy, CURLOPT_IOCTLDATA, this); + curlErr = curl_easy_setopt(curlEasy, CURLOPT_POST, 1L); } else { // GET want_upload = false; @@ -618,6 +622,23 @@ size_t libcurl_read( void *ptr, size_t size, size_t nmemb, HTTP_OP* phop) { return stRead; } +curlioerr libcurl_ioctl(CURL *handle, curliocmd cmd, HTTP_OP* phop) { + // reset input stream to beginning - resends header + // and restarts data back to starting point + + switch(cmd) { + case CURLIOCMD_RESTARTREAD: + phop->lSeek = 0; + phop->bytes_xferred = phop->file_offset; + phop->bSentHeader = FALSE; + break; + default: // should never get here + return CURLIOE_UNKNOWNCMD; + } + return CURLIOE_OK; +} + + void HTTP_OP::setupProxyCurl() { // CMC: use the libcurl proxy routines with this object's proxy information struct /* PROXY_INFO pi useful members: @@ -665,8 +686,13 @@ void HTTP_OP::setupProxyCurl() { pi.http_server_name, pi.http_server_port, pi.http_user_name, pi.http_user_passwd); */ + auth_flag = TRUE; + if (auth_type) { + curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, auth_type); + } else { + curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + } sprintf(szCurlProxyUserPwd, "%s:%s", pi.http_user_name, pi.http_user_passwd); - curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, CURLAUTH_ANY); curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYUSERPWD, szCurlProxyUserPwd); } } else { @@ -680,8 +706,13 @@ void HTTP_OP::setupProxyCurl() { strlen(pi.socks5_user_passwd)>0 || strlen(pi.socks5_user_name)>0 ) { sprintf(szCurlProxyUserPwd, "%s:%s", pi.socks5_user_name, pi.socks5_user_passwd); - curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, CURLAUTH_ANY); - curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYUSERPWD, szCurlProxyUserPwd); + curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYUSERPWD, szCurlProxyUserPwd); + auth_flag = TRUE; + if (auth_type) { + curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, auth_type); + } else { + curlErr = curl_easy_setopt(curlEasy, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + } } } } diff --git a/client/http_curl.h b/client/http_curl.h index bab936e17b..2daeb7370d 100644 --- a/client/http_curl.h +++ b/client/http_curl.h @@ -101,6 +101,7 @@ private: // global function used by libcurl to write http replies to disk size_t libcurl_write(void *ptr, size_t size, size_t nmemb, HTTP_OP* phop); size_t libcurl_read( void *ptr, size_t size, size_t nmemb, HTTP_OP* phop); +curlioerr libcurl_ioctl(CURL *handle, curliocmd cmd, HTTP_OP* phop); // represents a set of HTTP requests in progress // diff --git a/client/net_xfer_curl.C b/client/net_xfer_curl.C index 1d4e05a934..7b601f51c7 100644 --- a/client/net_xfer_curl.C +++ b/client/net_xfer_curl.C @@ -115,6 +115,8 @@ NET_XFER::NET_XFER() { pcurlFormEnd = NULL; pByte = NULL; lSeek = 0; + auth_flag = FALSE; + auth_type = 0; reset(); } @@ -273,16 +275,22 @@ void NET_XFER_SET::got_select(FDSET_GROUP&, double timeout) { ); } if (nxf->want_upload) { - bytes_up += nxf->bytes_xferred; + bytes_up += nxf->bytes_xferred; curlErr = curl_easy_getinfo(nxf->curlEasy, CURLINFO_SPEED_UPLOAD, &nxf->xfer_speed ); } + // if proxy/socks server uses authentication and its not set yet, + // get what last transfer used + if (nxf->auth_flag && !nxf->auth_type) { + curlErr = curl_easy_getinfo(nxf->curlEasy, + CURLINFO_PROXYAUTH_AVAIL, &nxf->auth_type); + } + // the op is done if curl_multi_msg_read gave us a msg for this http_op // - nxf->http_op_state = HTTP_STATE_DONE; - + nxf->http_op_state = HTTP_STATE_DONE; nxf->CurlResult = pcurlMsg->data.result; if (nxf->CurlResult == CURLE_OK) { diff --git a/client/net_xfer_curl.h b/client/net_xfer_curl.h index 8f31ff9640..0f61b3b862 100644 --- a/client/net_xfer_curl.h +++ b/client/net_xfer_curl.h @@ -103,6 +103,10 @@ public: int http_op_type; int http_op_retval; + // save authorization types supported by proxy/socks server + bool auth_flag; // TRUE = server uses authorization + long auth_type; // 0 = haven't contacted server yet. + NET_XFER(); ~NET_XFER(); void reset();