diff options
Diffstat (limited to 'methods')
-rw-r--r-- | methods/ftp.cc | 1 | ||||
-rw-r--r-- | methods/gpgv.cc | 17 | ||||
-rw-r--r-- | methods/http.cc | 55 | ||||
-rw-r--r-- | methods/http.h | 2 | ||||
-rw-r--r-- | methods/https.cc | 27 | ||||
-rw-r--r-- | methods/makefile | 2 | ||||
-rw-r--r-- | methods/mirror.cc | 3 | ||||
-rw-r--r-- | methods/rsh.cc | 2 |
8 files changed, 68 insertions, 41 deletions
diff --git a/methods/ftp.cc b/methods/ftp.cc index d55ac1224..979adca62 100644 --- a/methods/ftp.cc +++ b/methods/ftp.cc @@ -436,6 +436,7 @@ bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...) char S[400]; vsnprintf(S,sizeof(S) - 4,Fmt,args); strcat(S,"\r\n"); + va_end(args); if (Debug == true) cerr << "-> '" << QuoteString(S,"") << "'" << endl; diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 3f814b9f0..ea8a26fd4 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -55,9 +55,6 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, vector<string> &NoPubKeySigners) { bool const Debug = _config->FindB("Debug::Acquire::gpgv", false); - // setup a (empty) stringstream for formating the return value - std::stringstream ret; - ret.str(""); if (Debug == true) std::clog << "inside VerifyGetSigners" << std::endl; @@ -155,6 +152,7 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, } } fclose(pipein); + free(buffer); int status; waitpid(pid, &status, 0); @@ -170,18 +168,19 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, return ""; } else if (WEXITSTATUS(status) == 1) - { return _("At least one invalid signature was encountered."); - } else if (WEXITSTATUS(status) == 111) + return _("Could not execute 'gpgv' to verify signature (is gpgv installed?)"); + else if (WEXITSTATUS(status) == 112) { - ioprintf(ret, _("Could not execute 'gpgv' to verify signature (is gpgv installed?)")); - return ret.str(); + // acquire system checks for "NODATA" to generate GPG errors (the others are only warnings) + std::string errmsg; + //TRANSLATORS: %s is a single techy word like 'NODATA' + strprintf(errmsg, _("Clearsigned file isn't valid, got '%s' (does the network require authentication?)"), "NODATA"); + return errmsg; } else - { return _("Unknown error executing gpgv"); - } } bool GPGVMethod::Fetch(FetchItem *Itm) diff --git a/methods/http.cc b/methods/http.cc index fddf8a78e..278ddb290 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -667,7 +667,12 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) // The HTTP server expects a hostname with a trailing :port char Buf[1000]; - string ProperHost = Uri.Host; + string ProperHost; + + if (Uri.Host.find(':') != string::npos) + ProperHost = '[' + Uri.Host + ']'; + else + ProperHost = Uri.Host; if (Uri.Port != 0) { sprintf(Buf,":%u",Uri.Port); @@ -677,28 +682,27 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) // Just in case. if (Itm->Uri.length() >= sizeof(Buf)) abort(); - - /* Build the request. We include a keep-alive header only for non-proxy - requests. This is to tweak old http/1.0 servers that do support keep-alive - but not HTTP/1.1 automatic keep-alive. Doing this with a proxy server - will glitch HTTP/1.0 proxies because they do not filter it out and - pass it on, HTTP/1.1 says the connection should default to keep alive - and we expect the proxy to do this */ + + /* RFC 2616 ยง5.1.2 requires absolute URIs for requests to proxies, + but while its a must for all servers to accept absolute URIs, + it is assumed clients will sent an absolute path for non-proxies */ + std::string requesturi; if (Proxy.empty() == true || Proxy.Host.empty()) - { - // see LP bugs #1003633 and #1086997. The "+" is encoded as a workaround - // for a amazon S3 bug - sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n", - QuoteString(Uri.Path,"+~ ").c_str(),ProperHost.c_str()); - } + requesturi = Uri.Path; else - { - /* Generate a cache control header if necessary. We place a max - cache age on index files, optionally set a no-cache directive - and a no-store directive for archives. */ - sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n", - Itm->Uri.c_str(),ProperHost.c_str()); - } + requesturi = Itm->Uri; + + // The "+" is encoded as a workaround for a amazon S3 bug + // see LP bugs #1003633 and #1086997. + requesturi = QuoteString(requesturi, "+~ "); + + /* Build the request. No keep-alive is included as it is the default + in 1.1, can cause problems with proxies, and we are an HTTP/1.1 + client anyway. + C.f. https://tools.ietf.org/wg/httpbis/trac/ticket/158 */ + sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n", + requesturi.c_str(),ProperHost.c_str()); + // generate a cache control header (if needed) if (_config->FindB("Acquire::http::No-Cache",false) == true) { @@ -975,12 +979,7 @@ HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) { URI Uri = Queue->Uri; if (Uri.Host.empty() == false) - { - if (Uri.Port != 0) - strprintf(NextURI, "http://%s:%u", Uri.Host.c_str(), Uri.Port); - else - NextURI = "http://" + Uri.Host; - } + NextURI = URI::SiteOnly(Uri); else NextURI.clear(); NextURI.append(DeQuoteString(Srv->Location)); @@ -1401,7 +1400,7 @@ bool HttpMethod::AutoDetectProxy() char buf[512]; int InFd = Pipes[0]; close(Pipes[1]); - int res = read(InFd, buf, sizeof(buf)); + int res = read(InFd, buf, sizeof(buf)-1); ExecWait(Process, "ProxyAutoDetect", true); if (res < 0) diff --git a/methods/http.h b/methods/http.h index 7a3ccda54..7446119cd 100644 --- a/methods/http.h +++ b/methods/http.h @@ -158,7 +158,7 @@ class HttpMethod : public pkgAcqMethod ERROR_UNRECOVERABLE, /** \brief The server reported a error with a error content page */ ERROR_WITH_CONTENT_PAGE, - /** \brief A error on the client side */ + /** \brief An error on the client side */ ERROR_NOT_FROM_SERVER, /** \brief A redirect or retry request */ TRY_AGAIN_OR_REDIRECT diff --git a/methods/https.cc b/methods/https.cc index 11d4ba8aa..84ce2d68f 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -63,6 +63,12 @@ void HttpsMethod::SetupProxy() /*{{{*/ { URI ServerName = Queue->Uri; + // Curl should never read proxy settings from the environment, as + // we determine which proxy to use. Do this for consistency among + // methods and prevent an environment variable overriding a + // no-proxy ("DIRECT") setting in apt.conf. + curl_easy_setopt(curl, CURLOPT_PROXY, ""); + // Determine the proxy setting - try https first, fallback to http and use env at last string UseProxy = _config->Find("Acquire::https::Proxy::" + ServerName.Host, _config->Find("Acquire::http::Proxy::" + ServerName.Host).c_str()); @@ -81,7 +87,14 @@ void HttpsMethod::SetupProxy() /*{{{*/ if (getenv("no_proxy") != 0 && CheckDomainList(ServerName.Host,getenv("no_proxy")) == true) return; } else { - const char* result = getenv("http_proxy"); + const char* result = getenv("https_proxy"); + // FIXME: Fall back to http_proxy is to remain compatible with + // existing setups and behaviour of apt.conf. This should be + // deprecated in the future (including apt.conf). Most other + // programs do not fall back to http proxy settings and neither + // should Apt. + if (result == NULL) + result = getenv("http_proxy"); UseProxy = result == NULL ? "" : result; } @@ -92,6 +105,11 @@ void HttpsMethod::SetupProxy() /*{{{*/ if (Proxy.Port != 1) curl_easy_setopt(curl, CURLOPT_PROXYPORT, Proxy.Port); curl_easy_setopt(curl, CURLOPT_PROXY, Proxy.Host.c_str()); + if (Proxy.User.empty() == false || Proxy.Password.empty() == false) + { + curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, Proxy.User.c_str()); + curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, Proxy.Password.c_str()); + } } } /*}}}*/ // HttpsMethod::Fetch - Fetch an item /*{{{*/ @@ -285,6 +303,11 @@ bool HttpsMethod::Fetch(FetchItem *Itm) long curl_servdate; curl_easy_getinfo(curl, CURLINFO_FILETIME, &curl_servdate); + // If the server returns 200 OK but the If-Modified-Since condition is not + // met, CURLINFO_CONDITION_UNMET will be set to 1 + long curl_condition_unmet = 0; + curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &curl_condition_unmet); + File->Close(); // cleanup @@ -312,7 +335,7 @@ bool HttpsMethod::Fetch(FetchItem *Itm) Res.Filename = File->Name(); Res.LastModified = Buf.st_mtime; Res.IMSHit = false; - if (curl_responsecode == 304) + if (curl_responsecode == 304 || curl_condition_unmet) { unlink(File->Name().c_str()); Res.IMSHit = true; diff --git a/methods/makefile b/methods/makefile index a271aff5e..294c55d23 100644 --- a/methods/makefile +++ b/methods/makefile @@ -39,7 +39,7 @@ include $(PROGRAM_H) # The cdrom method PROGRAM=cdrom -SLIBS = -lapt-pkg -ldl $(INTLLIBS) +SLIBS = -lapt-pkg $(INTLLIBS) LIB_MAKES = apt-pkg/makefile SOURCE = cdrom.cc include $(PROGRAM_H) diff --git a/methods/mirror.cc b/methods/mirror.cc index d6c5ba955..854366318 100644 --- a/methods/mirror.cc +++ b/methods/mirror.cc @@ -311,6 +311,9 @@ bool MirrorMethod::InitMirrors() AllMirrors.push_back(s); } + if (AllMirrors.empty()) { + return _error->Error(_("No entry found in mirror file '%s'"), MirrorFile.c_str()); + } Mirror = AllMirrors[0]; UsedMirror = Mirror; return true; diff --git a/methods/rsh.cc b/methods/rsh.cc index fb3782314..d76dca6ef 100644 --- a/methods/rsh.cc +++ b/methods/rsh.cc @@ -218,6 +218,8 @@ bool RSHConn::WriteMsg(std::string &Text,bool Sync,const char *Fmt,...) // sprintf the description char S[512]; vsnprintf(S,sizeof(S) - 4,Fmt,args); + va_end(args); + if (Sync == true) strcat(S," 2> /dev/null || echo\n"); else |