3434try :
3535 # python 3
3636 from urllib .parse import urlsplit , urlunsplit , SplitResult
37+ from http import cookiejar
3738except ImportError :
3839 # python 2
3940 from urlparse import urlsplit , urlunsplit , SplitResult
41+ import cookielib as cookiejar
4042from urllib3 import poolmanager
4143from xml .etree import cElementTree as ElementTree
4244
@@ -228,17 +230,28 @@ class RESTService(object):
228230 undesired dependency between that module and the calling script.
229231 """
230232
231- def __init__ (self , name , baseurl , codec = RESTEncoding .LLSD , authenticated = True , username = None , password = None , proxy_hostport = None , cert = None , basepath = '' , ** session_params ):
233+ def __init__ (self , name , baseurl , codec = RESTEncoding .LLSD , authenticated = True ,
234+ username = None , password = None , proxy_hostport = None , cert = None , basepath = '' ,
235+ cookie_policy = None , ** session_params ):
232236 """
233237 Parameters:
234238 name: used in generating error messages
235- baseurl: a url prefix used for all requests to the service; may be an empty string
239+ baseurl: a url prefix used for all requests to the service; may be an
240+ empty string
236241 basepath: a url path that overrides the path part of baseurl
237- codec: one of the constants defined by the RESTEncoding class - determines expected request/response encoding
238- authenticated: a boolean: whether or not the service expects HTTP authentication (see get_credentials)
242+ codec: one of the constants defined by the RESTEncoding class -
243+ determines expected request/response encoding
244+ authenticated: a boolean: whether or not the service expects HTTP
245+ authentication (see get_credentials)
239246 username: the username to be used for HTTP authentication
240247 password: the password to be used for HTTP authentication
241- proxy_hostport: an HTTP proxy hostname and port number (host:port) through which requests should be routed
248+ proxy_hostport: an HTTP proxy hostname and port number (host:port)
249+ through which requests should be routed
250+ cert: string .pem pathname or (cert, key) pathname pair
251+ https://2.python-requests.org/en/master/api/#requests.Session.cert
252+ cookie_policy: http.cookiejar.CookiePolicy subclass for the session
253+ https://docs.python.org/3/library/http.cookiejar.html#http.cookiejar.CookiePolicy
254+ Special value cookie_policy=False blocks all cookies.
242255
243256 Any other keyword parameters are passed through to the requests.Session()
244257 """
@@ -260,7 +273,15 @@ def __init__(self, name, baseurl, codec=RESTEncoding.LLSD, authenticated=True, u
260273 'https' :'http://%s' % proxy_hostport } \
261274 if proxy_hostport else None
262275 if cert :
263- self .session .cert = cert
276+ self .session .cert = cert
277+ if cookie_policy is not None :
278+ if cookie_policy == False :
279+ # request implicit blocking
280+ cookie_policy = _BlockAllCookies ()
281+ elif issubclass (cookie_policy , cookiejar .CookiePolicy ):
282+ # set_policy() wants an instance, not a class
283+ cookie_policy = cookie_policy ()
284+ self .session .cookies .set_policy (cookie_policy )
264285
265286 # defer setting the Session credentials to the request methods,
266287 # so that the _get_credentials method can provide prompting for them
@@ -655,13 +676,32 @@ def init_poolmanager(self, connections, maxsize, block=False):
655676 """Create and initialize the urllib3 PoolManager."""
656677 ctx = ssl .create_default_context ()
657678 ctx .set_ciphers ('DEFAULT@SECLEVEL=1' )
679+ # https://stackoverflow.com/a/59059052
680+ ctx .check_hostname = False
681+ ctx .verify_mode = ssl .CERT_NONE
658682 self .poolmanager = poolmanager .PoolManager (
659683 num_pools = connections ,
660684 maxsize = maxsize ,
661685 block = block ,
662686 ssl_version = ssl .PROTOCOL_TLS ,
663687 ssl_context = ctx )
664688
689+ class _BlockAllCookies (cookiejar .CookiePolicy ):
690+ """
691+ Helper for RESTService(cookie_policy=False), derived from
692+ https://stackoverflow.com/a/21714597
693+ """
694+ netscape = True
695+ rfc2965 = False
696+ hide_cookie2 = False
697+
698+ def return_ok (self , * args , ** kwds ):
699+ return False
700+
701+ set_ok = return_ok
702+ domain_return_ok = return_ok
703+ path_return_ok = return_ok
704+
665705class SimpleRESTService (RESTService ):
666706 """
667707 Subclass wrapper around RESTService to use the right defaults
0 commit comments