This commit is contained in:
Hiroki Ohtani
2014-11-25 10:47:12 +09:00
parent 3ddf80c019
commit 67c871869d
4 changed files with 61 additions and 23 deletions

View File

@@ -7,6 +7,7 @@ ChangeLog
- Try to get proxy info from environment if not explicitly provided (#124) - Try to get proxy info from environment if not explicitly provided (#124)
- support proxy basic authenticaiton. (#125) - support proxy basic authenticaiton. (#125)
- Fix NoneType exception at WebsocketApp.send (#126) - Fix NoneType exception at WebsocketApp.send (#126)
- not use proxy for localhost (#132)
- 0.21.0 - 0.21.0

View File

@@ -112,7 +112,7 @@ class WebSocketApp(object):
self.sock.ping() self.sock.ping()
def run_forever(self, sockopt=None, sslopt=None, ping_interval=0, ping_timeout=None, def run_forever(self, sockopt=None, sslopt=None, ping_interval=0, ping_timeout=None,
http_proxy_host=None, http_proxy_port=None): http_proxy_host=None, http_proxy_port=None, http_no_proxy=None):
""" """
run event loop for WebSocket framework. run event loop for WebSocket framework.
This loop is infinite loop and is alive during websocket is available. This loop is infinite loop and is alive during websocket is available.
@@ -124,6 +124,7 @@ class WebSocketApp(object):
ping_timeout: timeout(second) if the pong message is not recieved. ping_timeout: timeout(second) if the pong message is not recieved.
http_proxy_host: http proxy host name. http_proxy_host: http proxy host name.
http_proxy_port: http proxy port. If not set, set to 80. http_proxy_port: http proxy port. If not set, set to 80.
http_no_proxy: host names, which doesn't use proxy.
""" """
if not ping_timeout or ping_timeout<=0: if not ping_timeout or ping_timeout<=0:
@@ -143,6 +144,7 @@ class WebSocketApp(object):
self.sock.settimeout(getdefaulttimeout()) self.sock.settimeout(getdefaulttimeout())
self.sock.connect(self.url, header=self.header, cookie=self.cookie, self.sock.connect(self.url, header=self.header, cookie=self.cookie,
http_proxy_host=http_proxy_host, http_proxy_port=http_proxy_port, http_proxy_host=http_proxy_host, http_proxy_port=http_proxy_port,
http_no_proxy = http_no_proxy,
subprotocols=self.subprotocols) subprotocols=self.subprotocols)
self._callback(self.on_open) self._callback(self.on_open)

View File

@@ -169,20 +169,37 @@ def _parse_url(url):
return (hostname, port, resource, is_secure) return (hostname, port, resource, is_secure)
def _get_proxy_info(is_secure, **options): DEFAULT_NO_PROXY_HOST = ["localhost", "127.0.0.1"]
def _is_no_proxy_host(hostname, no_proxy):
if not no_proxy:
v = os.environ.get("no_proxy", "").replace(" ", "")
no_proxy = v.split(",")
if not no_proxy:
no_proxy = DEFAULT_NO_PROXY_HOST
return hostname in no_proxy
def _get_proxy_info(hostname, is_secure, **options):
""" """
try to retrieve proxy host and port from environment if not provided in options. try to retrieve proxy host and port from environment if not provided in options.
result is (proxy_host, proxy_port, proxy_auth). result is (proxy_host, proxy_port, proxy_auth).
proxy_auth is tuple of username and password of proxy authentication information. proxy_auth is tuple of username and password of proxy authentication information.
hostname: websocket server name.
is_secure: is the connection secure? (wss) is_secure: is the connection secure? (wss)
looks for "https_proxy" in env before falling back to "http_proxy" looks for "https_proxy" in env before falling back to "http_proxy"
options: "http_proxy_host" - http proxy host name. options: "http_proxy_host" - http proxy host name.
"http_proxy_port" - http proxy port. "http_proxy_port" - http proxy port.
"http_no_proxy" - host names, which doesn't use proxy.
"http_proxy_auth" - http proxy auth infomation. tuple of username and password. "http_proxy_auth" - http proxy auth infomation. tuple of username and password.
defualt is None defualt is None
""" """
if _is_no_proxy_host(hostname, options.get("http_no_proxy", None)):
return None, 0, None
http_proxy_host = options.get("http_proxy_host", None) http_proxy_host = options.get("http_proxy_host", None)
if http_proxy_host: if http_proxy_host:
return http_proxy_host, options.get("http_proxy_port", 0), options.get("http_proxy_auth", None) return http_proxy_host, options.get("http_proxy_port", 0), options.get("http_proxy_auth", None)
@@ -224,6 +241,7 @@ def create_connection(url, timeout=None, **options):
"cookie" -> cookie value. "cookie" -> cookie value.
"http_proxy_host" - http proxy host name. "http_proxy_host" - http proxy host name.
"http_proxy_port" - http proxy port. If not set, set to 80. "http_proxy_port" - http proxy port. If not set, set to 80.
"http_no_proxy" - host names, which doesn't use proxy.
"http_proxy_auth" - http proxy auth infomation. tuple of username and password. "http_proxy_auth" - http proxy auth infomation. tuple of username and password.
defualt is None defualt is None
"enable_multithread" -> enable lock for multithread. "enable_multithread" -> enable lock for multithread.
@@ -434,6 +452,7 @@ class WebSocket(object):
"cookie" -> cookie value. "cookie" -> cookie value.
"http_proxy_host" - http proxy host name. "http_proxy_host" - http proxy host name.
"http_proxy_port" - http proxy port. If not set, set to 80. "http_proxy_port" - http proxy port. If not set, set to 80.
"http_no_proxy" - host names, which doesn't use proxy.
"http_proxy_auth" - http proxy auth infomation. tuple of username and password. "http_proxy_auth" - http proxy auth infomation. tuple of username and password.
defualt is None defualt is None
"subprotocols" - array of available sub protocols. default is None. "subprotocols" - array of available sub protocols. default is None.
@@ -441,7 +460,7 @@ class WebSocket(object):
""" """
hostname, port, resource, is_secure = _parse_url(url) hostname, port, resource, is_secure = _parse_url(url)
proxy_host, proxy_port, proxy_auth = _get_proxy_info(is_secure, **options) proxy_host, proxy_port, proxy_auth = _get_proxy_info(hostname, is_secure, **options)
if not proxy_host: if not proxy_host:
addrinfo_list = socket.getaddrinfo(hostname, port, 0, 0, socket.SOL_TCP) addrinfo_list = socket.getaddrinfo(hostname, port, 0, 0, socket.SOL_TCP)
else: else:

View File

@@ -557,60 +557,76 @@ class ProxyInfoTest(unittest.TestCase):
def testProxyFromArgs(self): def testProxyFromArgs(self):
self.assertEqual(_get_proxy_info(False, http_proxy_host="localhost"), ("localhost", 0, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False, http_proxy_host="localhost"), ("localhost", 0, None))
self.assertEqual(_get_proxy_info(False, http_proxy_host="localhost", http_proxy_port=3128), ("localhost", 3128, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False, http_proxy_host="localhost", http_proxy_port=3128), ("localhost", 3128, None))
self.assertEqual(_get_proxy_info(True, http_proxy_host="localhost"), ("localhost", 0, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost"), ("localhost", 0, None))
self.assertEqual(_get_proxy_info(True, http_proxy_host="localhost", http_proxy_port=3128), ("localhost", 3128, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost", http_proxy_port=3128), ("localhost", 3128, None))
self.assertEqual(_get_proxy_info(False, http_proxy_host="localhost", http_proxy_auth=("a", "b")), self.assertEqual(_get_proxy_info("echo.websocket.org", False, http_proxy_host="localhost", http_proxy_auth=("a", "b")),
("localhost", 0, ("a", "b"))) ("localhost", 0, ("a", "b")))
self.assertEqual(_get_proxy_info(False, http_proxy_host="localhost", http_proxy_port=3128, http_proxy_auth=("a", "b")), self.assertEqual(_get_proxy_info("echo.websocket.org", False, http_proxy_host="localhost", http_proxy_port=3128, http_proxy_auth=("a", "b")),
("localhost", 3128, ("a", "b"))) ("localhost", 3128, ("a", "b")))
self.assertEqual(_get_proxy_info(True, http_proxy_host="localhost", http_proxy_auth=("a", "b")), self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost", http_proxy_auth=("a", "b")),
("localhost", 0, ("a", "b"))) ("localhost", 0, ("a", "b")))
self.assertEqual(_get_proxy_info(True, http_proxy_host="localhost", http_proxy_port=3128, http_proxy_auth=("a", "b")), self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost", http_proxy_port=3128, http_proxy_auth=("a", "b")),
("localhost", 3128, ("a", "b"))) ("localhost", 3128, ("a", "b")))
self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost", http_proxy_port=3128, http_no_proxy=["example.com"], http_proxy_auth=("a", "b")),
("localhost", 3128, ("a", "b")))
self.assertEqual(_get_proxy_info("echo.websocket.org", True, http_proxy_host="localhost", http_proxy_port=3128, http_no_proxy=["echo.websocket.org"], http_proxy_auth=("a", "b")),
(None, 0, None))
def testProxyFromEnv(self): def testProxyFromEnv(self):
os.environ["http_proxy"] = "http://localhost/" os.environ["http_proxy"] = "http://localhost/"
self.assertEqual(_get_proxy_info(False), ("localhost", None, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
os.environ["http_proxy"] = "http://localhost:3128/" os.environ["http_proxy"] = "http://localhost:3128/"
self.assertEqual(_get_proxy_info(False), ("localhost", 3128, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
os.environ["http_proxy"] = "http://localhost/" os.environ["http_proxy"] = "http://localhost/"
os.environ["https_proxy"] = "http://localhost2/" os.environ["https_proxy"] = "http://localhost2/"
self.assertEqual(_get_proxy_info(False), ("localhost", None, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
os.environ["http_proxy"] = "http://localhost:3128/" os.environ["http_proxy"] = "http://localhost:3128/"
os.environ["https_proxy"] = "http://localhost2:3128/" os.environ["https_proxy"] = "http://localhost2:3128/"
self.assertEqual(_get_proxy_info(False), ("localhost", 3128, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
os.environ["http_proxy"] = "http://localhost/" os.environ["http_proxy"] = "http://localhost/"
os.environ["https_proxy"] = "http://localhost2/" os.environ["https_proxy"] = "http://localhost2/"
self.assertEqual(_get_proxy_info(True), ("localhost2", None, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", True), ("localhost2", None, None))
os.environ["http_proxy"] = "http://localhost:3128/" os.environ["http_proxy"] = "http://localhost:3128/"
os.environ["https_proxy"] = "http://localhost2:3128/" os.environ["https_proxy"] = "http://localhost2:3128/"
self.assertEqual(_get_proxy_info(True), ("localhost2", 3128, None)) self.assertEqual(_get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, None))
os.environ["http_proxy"] = "http://a:b@localhost/" os.environ["http_proxy"] = "http://a:b@localhost/"
self.assertEqual(_get_proxy_info(False), ("localhost", None, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost:3128/" os.environ["http_proxy"] = "http://a:b@localhost:3128/"
self.assertEqual(_get_proxy_info(False), ("localhost", 3128, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost/" os.environ["http_proxy"] = "http://a:b@localhost/"
os.environ["https_proxy"] = "http://a:b@localhost2/" os.environ["https_proxy"] = "http://a:b@localhost2/"
self.assertEqual(_get_proxy_info(False), ("localhost", None, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost:3128/" os.environ["http_proxy"] = "http://a:b@localhost:3128/"
os.environ["https_proxy"] = "http://a:b@localhost2:3128/" os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
self.assertEqual(_get_proxy_info(False), ("localhost", 3128, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost/" os.environ["http_proxy"] = "http://a:b@localhost/"
os.environ["https_proxy"] = "http://a:b@localhost2/" os.environ["https_proxy"] = "http://a:b@localhost2/"
self.assertEqual(_get_proxy_info(True), ("localhost2", None, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", True), ("localhost2", None, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost:3128/" os.environ["http_proxy"] = "http://a:b@localhost:3128/"
os.environ["https_proxy"] = "http://a:b@localhost2:3128/" os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
self.assertEqual(_get_proxy_info(True), ("localhost2", 3128, ("a", "b"))) self.assertEqual(_get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost/"
os.environ["https_proxy"] = "http://a:b@localhost2/"
os.environ["no_proxy"] = "example1.com,example2.com"
self.assertEqual(_get_proxy_info("example.1.com", True), ("localhost2", None, ("a", "b")))
os.environ["http_proxy"] = "http://a:b@localhost:3128/"
os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
os.environ["no_proxy"] = "example1.com,example2.com, echo.websocket.org"
self.assertEqual(_get_proxy_info("echo.websocket.org", True), (None, 0, None))