On Mon, Aug 25, 2014 at 07:17:18PM -0700, Michael Vogt wrote:
> > It would be useful to support PAC (proxy autoconfiguration files) with
> > apt. Specifically, PAC files are simple javascript files that given a
> > URL and HOST output a proxy setting. This can be trivially hooked up
> > with Acquire::http::Proxy-Auto-Detect, however Proxy-Auto-Detect is
> > called only once, instead of per-host, hence one cannot easily mix
> > repositories that require different proxies or proxy only for some
> > repositories. Extending Proxy-Auto-Detect to pass host parameter and
> > calling that for each host/repository would be beneficial to integrate
> > (optionally) pac file support with apt. (Similar to how deb squid proxy
> > support is done).
>
> Attached is a (untested) patch that make the Proxy-Auto-Detect a
> per-host thing. If this looks vaguely like what you need we need to
> add a testcase before it can go in.
Looks like I forgot to attach the patch. I attach it now, Raphael
Geissert pointed out that by using command "proxy" from the
libproxy-tools package your use-case should be solved.
Along the way I added the auto-detect to https as well. If you could
give it a test-run, that would be awesome.
Cheers,
Michael
diff --git a/apt-pkg/contrib/proxy.cc b/apt-pkg/contrib/proxy.cc
index b68a053..d1f8274 100644
--- a/apt-pkg/contrib/proxy.cc
+++ b/apt-pkg/contrib/proxy.cc
@@ -1,9 +1,18 @@
+#include<apt-pkg/configuration.h>
+#include<apt-pkg/error.h>
+#include<apt-pkg/fileutl.h>
+
+#include<iostream>
+#include <unistd.h>
+
#include "proxy.h"
+
+
// AutoDetectProxy - auto detect proxy /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool AutoDetectProxy(const URI &URL)
+bool AutoDetectProxy(URI &URL)
{
bool Debug = _config->FindB("Debug::Acquire::http",false);
// option is "Acquire::http::Proxy-Auto-Detect" but we allow the old
@@ -15,7 +24,7 @@ bool AutoDetectProxy(const URI &URL)
return true;
if (Debug)
- clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << endl;
+ std::clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << std::endl;
int Pipes[2] = {-1,-1};
if (pipe(Pipes) != 0)
@@ -30,10 +39,10 @@ bool AutoDetectProxy(const URI &URL)
const char *Args[4];
Args[0] = AutoDetectProxyCmd.c_str();
- Args[1] = URL.c_str();
+ Args[1] = string(URL).c_str();
Args[2] = 0;
execv(Args[0],(char **)Args);
- cerr << "Failed to exec method " << Args[0] << endl;
+ std::cerr << "Failed to exec method " << Args[0] << std::endl;
_exit(100);
}
char buf[512];
@@ -51,7 +60,7 @@ bool AutoDetectProxy(const URI &URL)
buf[res] = 0;
if (Debug)
- clog << "auto detect command returned: '" << buf << "'" << endl;
+ std::clog << "auto detect command returned: '" << buf << "'" << std::endl;
URI Tmp(URL);
if (strstr(buf, "http://") == buf)
diff --git a/apt-pkg/contrib/proxy.h b/apt-pkg/contrib/proxy.h
index b7ebf61..be31791 100644
--- a/apt-pkg/contrib/proxy.h
+++ b/apt-pkg/contrib/proxy.h
@@ -11,7 +11,7 @@
#include <apt-pkg/strutl.h>
-bool AutoDetectProxy(const URI &URL);
+bool AutoDetectProxy(URI &URL);
#endif
diff --git a/methods/http.cc b/methods/http.cc
index 7c7949e..06325e9 100644
--- a/methods/http.cc
+++ b/methods/http.cc
@@ -34,6 +34,7 @@
#include <apt-pkg/hashes.h>
#include <apt-pkg/netrc.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/proxy.h>
#include <stddef.h>
#include <stdlib.h>
@@ -51,6 +52,7 @@
#include "connect.h"
#include "http.h"
+
#include <apti18n.h>
/*}}}*/
using namespace std;
@@ -60,6 +62,7 @@ unsigned long long CircleBuf::BwTickReadData=0;
struct timeval CircleBuf::BwReadTick={0,0};
const unsigned int CircleBuf::BW_HZ=10;
+
// CircleBuf::CircleBuf - Circular input buffer /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -304,8 +307,10 @@ bool HttpServerState::Open()
Persistent = true;
// Determine the proxy setting
+ AutoDetectProxy(ServerName);
+
string SpecificProxy = _config->Find("Acquire::http::Proxy::" + ServerName.Host);
- if (!SpecificProxy.empty())
+ if (SpecificProxy != "")
{
if (SpecificProxy == "DIRECT")
Proxy = "";
@@ -762,66 +767,6 @@ bool HttpMethod::Configuration(string Message)
PipelineDepth);
Debug = _config->FindB("Debug::Acquire::http",false);
- // Get the proxy to use
- AutoDetectProxy();
-
- return true;
-}
- /*}}}*/
-// HttpMethod::AutoDetectProxy - auto detect proxy /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool HttpMethod::AutoDetectProxy()
-{
- // option is "Acquire::http::Proxy-Auto-Detect" but we allow the old
- // name without the dash ("-")
- AutoDetectProxyCmd = _config->Find("Acquire::http::Proxy-Auto-Detect",
- _config->Find("Acquire::http::ProxyAutoDetect"));
-
- if (AutoDetectProxyCmd.empty())
- return true;
-
- if (Debug)
- clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << endl;
-
- int Pipes[2] = {-1,-1};
- if (pipe(Pipes) != 0)
- return _error->Errno("pipe", "Failed to create Pipe");
-
- pid_t Process = ExecFork();
- if (Process == 0)
- {
- close(Pipes[0]);
- dup2(Pipes[1],STDOUT_FILENO);
- SetCloseExec(STDOUT_FILENO,false);
-
- const char *Args[2];
- Args[0] = AutoDetectProxyCmd.c_str();
- Args[1] = 0;
- execv(Args[0],(char **)Args);
- cerr << "Failed to exec method " << Args[0] << endl;
- _exit(100);
- }
- char buf[512];
- int InFd = Pipes[0];
- close(Pipes[1]);
- int res = read(InFd, buf, sizeof(buf)-1);
- ExecWait(Process, "ProxyAutoDetect", true);
-
- if (res < 0)
- return _error->Errno("read", "Failed to read");
- if (res == 0)
- return _error->Warning("ProxyAutoDetect returned no data");
-
- // add trailing \0
- buf[res] = 0;
-
- if (Debug)
- clog << "auto detect command returned: '" << buf << "'" << endl;
-
- if (strstr(buf, "http://") == buf)
- _config->Set("Acquire::http::proxy", _strstrip(buf));
-
return true;
}
/*}}}*/
diff --git a/methods/http.h b/methods/http.h
index 5406ce4..1df9fa0 100644
--- a/methods/http.h
+++ b/methods/http.h
@@ -124,9 +124,6 @@ class HttpMethod : public ServerMethod
public:
virtual void SendReq(FetchItem *Itm);
- /** \brief Try to AutoDetect the proxy */
- bool AutoDetectProxy();
-
virtual bool Configuration(std::string Message);
virtual ServerState * CreateServerState(URI uri);
diff --git a/methods/https.cc b/methods/https.cc
index e0348ab..0499af0 100644
--- a/methods/https.cc
+++ b/methods/https.cc
@@ -20,6 +20,7 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/macros.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/proxy.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -107,6 +108,9 @@ void HttpsMethod::SetupProxy() /*{{{*/
{
URI ServerName = Queue->Uri;
+ // Determine the proxy setting
+ AutoDetectProxy(ServerName);
+
// 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