Repository: conan-io/conan

Issue:
Accessing conan trough a proxy
In corperate environments it is frequently the case that internet connection must go trough a proxy server, sometimes even with authentication required.

It would be good if conan would at least support the following proxy scenarios:
1. Access the internet trough a HTTP/HTTPS proxy without authentication
2. Access the internet trough a HTTP/HTTPS proxy with authentication required
3. Access the internet trough a SOCKSv5 proxy (this allows using SSH tunnels)



Discussion:
Conan is using the python "requests" library. From the docs: http://docs.python-requests.org/en/latest/user/advanced/#proxies

It should be possible to define environment variables like:

```
$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"
```

or using user/pass urls in the form "http://user:pass@10.10.1.10:3128/"

I suggest doing a first try with environment variables to check if it works, as a temporary workaround while a proper solution is developed.

Indeed it is working with the solution proposed above.

I also got it working on windows using the following:

```
> set HTTP_PROXY=http://10.10.1.10:3128
> set HTTPS_PROXY=http://10.10.1.10:1080
```

Note  that you must not put `"` around the proxy otherwise it won't work.

I think it is worth to add this to the documentation.

great! I'm creating a new issue in conan docs repository to update it with this information.

Thanks


Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -11,7 +11,7 @@
 from conans.client.rest.rest_client import RestApiClient
 from conans.client.store.localdb import LocalDB
 from conans.util.log import logger
-from conans.model.ref import ConanFileReference, PackageReference
+from conans.model.ref import ConanFileReference
 from conans.client.manager import ConanManager
 from conans.paths import CONANFILE
 import requests
@@ -481,10 +481,17 @@ def main(args):
     user_io = UserIO(out=out)
 
     user_folder = os.path.expanduser("~")
-    paths = migrate_and_get_paths(user_folder, out)
-
+    try:
+        # To capture exceptions in conan.conf parsing
+        paths = migrate_and_get_paths(user_folder, out)
+    except Exception as e:
+        out.error(str(e))
+        sys.exit(True)
+
+    requester = requests.Session()
+    requester.proxies = paths.conan_config.proxies
     # Verify client version against remotes
-    version_checker_requester = VersionCheckerRequester(requests, Version(CLIENT_VERSION),
+    version_checker_requester = VersionCheckerRequester(requester, Version(CLIENT_VERSION),
                                                         Version(MIN_SERVER_COMPATIBLE_VERSION),
                                                         out)
     # To handle remote connections
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -5,6 +5,7 @@
 from conans.util.files import save, load
 from ConfigParser import NoSectionError, ConfigParser
 from conans.model.values import Values
+import urllib
 
 MIN_SERVER_COMPATIBLE_VERSION = '0.6.0'
 
@@ -35,6 +36,14 @@
 conan.io: https://server.conan.io
 local: http://localhost:9300
 
+[proxies]
+# Empty section will try to use system proxies.
+# If don't want proxy at all, remove section [proxies]
+# As documented in http://docs.python-requests.org/en/latest/user/advanced/#proxies
+# http: http://user:pass@10.10.1.10:3128/
+# http: http://10.10.1.10:3128
+# https: http://10.10.1.10:1080
+
 [settings_defaults]
 
 '''
@@ -70,6 +79,19 @@ def storage_path(self):
     def remotes(self):
         return self.get_conf("remotes")
 
+    @property
+    def proxies(self):
+        """ optional field, might not exist
+        """
+        try:
+            proxies = self.get_conf("proxies")
+            # If there is proxies section, but empty, it will try to use system proxy
+            if not proxies:
+                return urllib.getproxies()
+            return dict(proxies)
+        except:
+            return None
+
     @property
     def settings_defaults(self):
         default_settings = self.get_conf("settings_defaults")


Test patch: