source: sasview/src/sas/sasgui/guiframe/proxy.py @ 9592c6f

Last change on this file since 9592c6f was 20fa5fe, checked in by Stuart Prescott <stuart@…>, 7 years ago

Fix lots more typos in comments and docs

  • Property mode set to 100644
File size: 6.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3from __future__ import print_function
4
5import urllib2
6import sys
7import json
8import logging
9import re
10
11
12logger = logging.getLogger(__name__)
13
14'''
15HTTP Proxy parser and Connection
16
17connect() function:
18    - auto detects proxy in windows, osx
19    - in ux systems, the http_proxy environment variable must be set
20    - if it fails, try to find the proxy.pac address.
21      - parses the file, and looks up for all possible proxies
22'''
23
24
25class Connection(object):
26
27    def __init__(self, url, timeout):
28        self.url = url
29        self.timeout = timeout
30
31    def _get_addresses_of_proxy_pac(self):
32        """
33        Return a list of possible auto proxy .pac files being used,
34        based on the system registry (win32) or system preferences (OSX).
35        @return: list of urls
36        """
37        pac_files = []
38        if sys.platform == 'win32':
39            try:
40                import _winreg as winreg  # used from python 2.0-2.6
41            except:
42                import winreg  # used from python 2.7 onwards
43            net = winreg.OpenKey(
44                winreg.HKEY_CURRENT_USER,
45                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
46            )
47            n_subs, n_vals, last_mod = winreg.QueryInfoKey(net)
48            subkeys = {}
49            for i in range(n_vals):
50                this_name, this_val, this_type = winreg.EnumValue(net, i)
51                subkeys[this_name] = this_val
52            if 'AutoConfigURL' in subkeys.keys() and len(subkeys['AutoConfigURL']) > 0:
53                pac_files.append(subkeys['AutoConfigURL'])
54        elif sys.platform == 'darwin':
55            import plistlib
56            sys_prefs = plistlib.readPlist(
57                '/Library/Preferences/SystemConfiguration/preferences.plist')
58            networks = sys_prefs['NetworkServices']
59            # loop through each possible network (e.g. Ethernet, Airport...)
60            for network in networks.items():
61                # the first part is a long identifier
62                net_key, network = network
63                if 'ProxyAutoConfigURLString' in network['Proxies'].keys():
64                    pac_files.append(
65                        network['Proxies']['ProxyAutoConfigURLString'])
66        return list(set(pac_files))  # remove redundant ones
67
68    def _parse_proxy_pac(self, pac_urls_list):
69        '''
70        For every pac file url in pac_urls_list, it tryes to connect.
71        If the connection is successful parses the file in search for
72        http proxies.
73        @param pac_urls_list: List with urls for the pac files
74        @return: list with all found http proxies
75        '''
76        proxy_url_list = []
77        for this_pac_url in pac_urls_list:
78            logger.debug('Trying pac file (%s)...' % this_pac_url)
79            try:
80                response = urllib2.urlopen(
81                    this_pac_url, timeout=self.timeout)
82                logger.debug('Succeeded (%s)...' % this_pac_url)
83            except Exception:
84                logger.debug('Failled (%s)...' % this_pac_url)
85                continue
86            pacStr = response.read()
87            possProxies = re.findall(
88                r"PROXY\s([^\s;,:]+:[0-9]{1,5})[^0-9]", pacStr + '\n')
89            for thisPoss in possProxies:
90                prox_url = 'http://' + thisPoss
91                proxy_dic = {'http': prox_url}
92                proxy_url_list.append(proxy_dic)
93        return proxy_url_list
94
95    def _set_proxy(self,proxy_dic=None):
96        '''
97        Sets connection proxy.
98        if proxy_dic is None get's teh proxy from the system.
99        To disable autodetected proxy pass an empty dictionary: {}
100        @param proxy_dic: format: {'http': 'http://www.example.com:3128/'}               
101        '''
102        if proxy_dic is None:
103            # The default is to read the list of proxies from the environment variables <protocol>_proxy.
104            # If no proxy environment variables are set, then in a Windows environment proxy settings are
105            # obtained from the registry's Internet Settings section, and in a Mac OS X environment proxy
106            # information is retrieved from the OS X System Configuration
107            # Framework.
108            proxy = urllib2.ProxyHandler()
109        else:
110            # If proxies is given, it must be a dictionary mapping protocol names to
111            # URLs of proxies.
112            proxy = urllib2.ProxyHandler(proxy_dic)
113        opener = urllib2.build_opener(proxy)
114        urllib2.install_opener(opener)
115   
116   
117   
118   
119    def connect(self):
120        '''
121        Performs the request and gets a response from self.url
122        @return: response object from urllib2.urlopen
123        '''
124        req = urllib2.Request(self.url)
125        response = None
126        try:
127            logger.debug("Trying Direct connection to %s..."%self.url)
128            response = urllib2.urlopen(req, timeout=self.timeout)
129        except Exception, e:
130            logger.debug("Failed!")
131            logger.debug(e)
132            try:
133                logger.debug("Trying to use system proxy if it exists...")
134                self._set_proxy()
135                response = urllib2.urlopen(req, timeout=self.timeout)
136            except Exception, e:
137                logger.debug("Failed!")
138                logger.debug(e)
139                pac_urls = self._get_addresses_of_proxy_pac()
140                proxy_urls = self._parse_proxy_pac(pac_urls)
141                for proxy in proxy_urls:
142                    try:
143                        logger.debug("Trying to use the proxy %s found in proxy.pac configuration"%proxy)
144                        self._set_proxy(proxy)
145                        response = urllib2.urlopen(req, timeout=self.timeout)
146                    except Exception, e:
147                        logger.debug("Failed!")
148                        logger.debug(e)
149        if response is not None:
150            logger.debug("The connection to %s was successful."%self.url)
151        else:
152            logger.warning("Connection to %s failed..."%self.url)
153        return response
154
155
156if __name__ == "__main__":
157    from pprint import pprint
158    c = Connection()
159    response = c.connect()
160    if response is not None:
161        print(50 * '-')
162        content = json.loads(response.read().strip())
163        pprint(content)
Note: See TracBrowser for help on using the repository browser.