91451a2d011bc54e49bc4b908e2e6e5138032685
[tools/mic.git] / mic / utils / proxy.py
1 #!/usr/bin/python -tt
2 #
3 # Copyright (c) 2010, 2011 Intel, Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the Free
7 # Software Foundation; version 2 of the License
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 # for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc., 59
16 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 import os
19 import urlparse
20
21 _my_proxies = {}
22 _my_noproxy = None
23 _my_noproxy_list = []
24
25 def set_proxy_environ():
26     global _my_noproxy, _my_proxies
27     if not _my_proxies:
28         return
29     for key in _my_proxies.keys():
30         os.environ[key + "_proxy"] = _my_proxies[key]
31     if not _my_noproxy:
32         return
33     os.environ["no_proxy"] = _my_noproxy
34
35 def unset_proxy_environ():
36     for env in ('http_proxy',
37                 'https_proxy',
38                 'ftp_proxy',
39                 'all_proxy'):
40         if env in os.environ:
41             del os.environ[env]
42
43         ENV=env.upper()
44         if ENV in os.environ:
45             del os.environ[ENV]
46
47 def _set_proxies(proxy = None, no_proxy = None):
48     """Return a dictionary of scheme -> proxy server URL mappings.
49     """
50
51     global _my_noproxy, _my_proxies
52     _my_proxies = {}
53     _my_noproxy = None
54     proxies = []
55     if proxy:
56         proxies.append(("http_proxy", proxy))
57     if no_proxy:
58         proxies.append(("no_proxy", no_proxy))
59
60     # Get proxy settings from environment if not provided
61     if not proxy and not no_proxy:
62         proxies = os.environ.items()
63
64         # Remove proxy env variables, urllib2 can't handle them correctly
65         unset_proxy_environ()
66
67     for name, value in proxies:
68         name = name.lower()
69         if value and name[-6:] == '_proxy':
70             if name[0:2] != "no":
71                 _my_proxies[name[:-6]] = value
72             else:
73                 _my_noproxy = value
74
75 def _ip_to_int(ip):
76     ipint=0
77     shift=24
78     for dec in ip.split("."):
79         ipint |= int(dec) << shift
80         shift -= 8
81     return ipint
82
83 def _int_to_ip(val):
84     ipaddr=""
85     shift=0
86     for i in range(4):
87         dec = val >> shift
88         dec &= 0xff
89         ipaddr = ".%d%s" % (dec, ipaddr)
90         shift += 8
91     return ipaddr[1:]
92
93 def _isip(host):
94     if host.replace(".", "").isdigit():
95         return True
96     return False
97
98 def _set_noproxy_list():
99     global _my_noproxy, _my_noproxy_list
100     _my_noproxy_list = []
101     if not _my_noproxy:
102         return
103     for item in _my_noproxy.split(","):
104         item = item.strip()
105         if not item:
106             continue
107
108         if item[0] != '.' and item.find("/") == -1:
109             # Need to match it
110             _my_noproxy_list.append({"match":0,"needle":item})
111
112         elif item[0] == '.':
113             # Need to match at tail
114             _my_noproxy_list.append({"match":1,"needle":item})
115
116         elif item.find("/") > 3:
117             # IP/MASK, need to match at head
118             needle = item[0:item.find("/")].strip()
119             ip = _ip_to_int(needle)
120             netmask = 0
121             mask = item[item.find("/")+1:].strip()
122
123             if mask.isdigit():
124                 netmask = int(mask)
125                 netmask = ~((1<<(32-netmask)) - 1)
126                 ip &= netmask
127             else:
128                 shift=24
129                 netmask=0
130                 for dec in mask.split("."):
131                     netmask |= int(dec) << shift
132                     shift -= 8
133                 ip &= netmask
134
135             _my_noproxy_list.append({"match":2,"needle":ip,"netmask":netmask})
136
137 def _isnoproxy(url):
138     (scheme, host, path, parm, query, frag) = urlparse.urlparse(url)
139
140     if '@' in host:
141         user_pass, host = host.split('@', 1)
142
143     if ':' in host:
144         host, port = host.split(':', 1)
145
146     hostisip = _isip(host)
147     for item in _my_noproxy_list:
148         if hostisip and item["match"] <= 1:
149             continue
150
151         if item["match"] == 2 and hostisip:
152             if (_ip_to_int(host) & item["netmask"]) == item["needle"]:
153                 return True
154
155         if item["match"] == 0:
156             if host == item["needle"]:
157                 return True
158
159         if item["match"] == 1:
160             if host.rfind(item["needle"]) > 0:
161                 return True
162
163     return False
164
165 def set_proxies(proxy = None, no_proxy = None):
166     _set_proxies(proxy, no_proxy)
167     _set_noproxy_list()
168     set_proxy_environ()
169
170 def get_proxy_for(url):
171     if url.startswith('file:') or _isnoproxy(url):
172         return None
173
174     type = url[0:url.index(":")]
175     proxy = None
176     if _my_proxies.has_key(type):
177         proxy = _my_proxies[type]
178     elif _my_proxies.has_key("http"):
179         proxy = _my_proxies["http"]
180     else:
181         proxy = None
182
183     return proxy