1# -*- coding: utf-8 -*- # 2# Copyright 2013 Google LLC. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16"""A module to get an http proxy information.""" 17 18 19from __future__ import absolute_import 20from __future__ import division 21from __future__ import unicode_literals 22 23from googlecloudsdk.core import properties 24from googlecloudsdk.core.util import http_proxy_types 25 26import httplib2 27from six.moves import urllib 28 29 30def GetDefaultProxyInfo(method='http'): 31 """Get ProxyInfo from environment. 32 33 This function is meant to mimic httplib2.proxy_info_from_environment, but get 34 the proxy information from urllib.getproxies instead. urllib can also get 35 proxy information from Windows Internet Explorer settings or MacOSX framework 36 SystemConfiguration. 37 38 Args: 39 method: protocol string 40 Returns: 41 httplib2 ProxyInfo object or None 42 """ 43 44 proxy_dict = urllib.request.getproxies() 45 proxy_url = proxy_dict.get(method, None) 46 if not proxy_url: 47 return None 48 49 pi = httplib2.proxy_info_from_url(proxy_url, method) 50 51 # The ProxyInfo object has a bypass_host method that takes the hostname as an 52 # argument and it returns 1 or 0 based on if the hostname should bypass the 53 # proxy or not. We could either build the bypassed hosts list and pass it to 54 # pi.bypass_hosts, or we can just replace the method with the function in 55 # urllib, and completely mimic urllib logic. We do the latter. 56 # Since the urllib.proxy_bypass _function_ (no self arg) is not "bound" to the 57 # class instance, it doesn't receive the self arg when its called. We don't 58 # need to "bind" it via types.MethodType(urllib.proxy_bypass, pi). 59 pi.bypass_host = urllib.request.proxy_bypass 60 61 # Modify proxy info object? 62 63 return pi 64 65 66def GetProxyProperties(): 67 """Get proxy information from cloud sdk properties in dictionary form.""" 68 proxy_type_map = http_proxy_types.PROXY_TYPE_MAP 69 proxy_type = properties.VALUES.proxy.proxy_type.Get() 70 proxy_address = properties.VALUES.proxy.address.Get() 71 proxy_port = properties.VALUES.proxy.port.GetInt() 72 73 proxy_prop_set = len( 74 [f for f in (proxy_type, proxy_address, proxy_port) if f]) 75 if proxy_prop_set > 0 and proxy_prop_set != 3: 76 raise properties.InvalidValueError( 77 'Please set all or none of the following properties: ' 78 'proxy/type, proxy/address and proxy/port') 79 80 if not proxy_prop_set: 81 return {} 82 83 proxy_rdns = properties.VALUES.proxy.rdns.GetBool() 84 proxy_user = properties.VALUES.proxy.username.Get() 85 proxy_pass = properties.VALUES.proxy.password.Get() 86 87 return { 88 'proxy_type': proxy_type_map[proxy_type], 89 'proxy_address': proxy_address, 90 'proxy_port': proxy_port, 91 'proxy_rdns': proxy_rdns, 92 'proxy_user': proxy_user, 93 'proxy_pass': proxy_pass, 94 } 95 96 97def GetHttpProxyInfo(): 98 """Get ProxyInfo object or callable to be passed to httplib2.Http. 99 100 httplib2.Http can issue requests through a proxy. That information is passed 101 via either ProxyInfo objects or a callback function that receives the protocol 102 the request is made on and returns the proxy address. If users set the gcloud 103 properties, we create a ProxyInfo object with those settings. If users do not 104 set gcloud properties, we return a function that can be called to get default 105 settings. 106 107 Returns: 108 httplib2 ProxyInfo object or callable function that returns a Proxy Info 109 object given the protocol (http, https) 110 """ 111 112 proxy_settings = GetProxyProperties() 113 114 if proxy_settings: 115 return httplib2.ProxyInfo( 116 proxy_settings['proxy_type'], 117 proxy_settings['proxy_address'], 118 proxy_settings['proxy_port'], 119 proxy_rdns=proxy_settings['proxy_rdns'], 120 proxy_user=proxy_settings['proxy_user'], 121 proxy_pass=proxy_settings['proxy_pass']) 122 123 return GetDefaultProxyInfo 124