1717 from urllib .request import ProxyHandler
1818 from urllib .request import install_opener
1919 from urllib .request import urlopen
20- from http .client import HTTPConnection
20+ from http .client import HTTPSConnection
2121 from http .client import HTTPS_PORT
2222 from urllib .request import HTTPSHandler
2323 from urllib .parse import quote_plus
2929 from urllib2 import ProxyHandler
3030 from urllib2 import install_opener
3131 from urllib2 import urlopen
32- from httplib import HTTPConnection
32+ from httplib import HTTPSConnection
3333 from httplib import HTTPS_PORT
3434 from urllib2 import HTTPSHandler
3535 from urllib import quote_plus
4141import socket
4242import os
4343import ssl
44- import copy
44+ import copy
4545
4646from hashlib import sha1
4747from base64 import b64decode , b64encode
@@ -68,7 +68,7 @@ def __str__(self):
6868
6969class GSRequest ():
7070 DEFAULT_API_DOMAIN = "us1.gigya.com"
71- VERSION = "3.5.0 "
71+ VERSION = "3.5.1 "
7272 caCertsPath = os .path .join (os .path .dirname (__file__ ), "cacert.pem" )
7373
7474 _domain = ""
@@ -85,7 +85,7 @@ class GSRequest():
8585 _useHTTPS = False
8686 _apiDomain = DEFAULT_API_DOMAIN
8787
88- def __init__ (self , apiKey = None , secretKey = None , apiMethod = None , params = None , useHTTPS = False , userKey = None ):
88+ def __init__ (self , apiKey = None , secretKey = None , apiMethod = None , params = None , useHTTPS = False , userKey = None , enable_host_check = True ):
8989 """
9090 Constructs a request using the apiKey and secretKey.
9191 @param apiKey
@@ -95,6 +95,7 @@ def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, use
9595 @param params the request parameters
9696 @param useHTTPS useHTTPS set this to true if you want to use HTTPS.
9797 @param userKey A key of an admin user with extra permissions.
98+ @param enable_host_check Hostcheck can be disabled by passing enable_host_check=false when using HTTPS. Can be necessary when using proxy. Default is True
9899 If this parameter is provided, then the secretKey parameter is assumed to be the admin user's secret key and not the site's secret key.
99100 """
100101
@@ -118,6 +119,7 @@ def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, use
118119 self ._secretKey = secretKey
119120 self ._userKey = userKey
120121 self ._traceLog = list ()
122+ self ._enableHostCheck = enable_host_check
121123 self .traceField ("apiMethod" , apiMethod )
122124 self .traceField ("apiKey" , apiKey )
123125
@@ -188,7 +190,7 @@ def send(self, timeout=None):
188190
189191 return GSResponse (self ._method , None , self ._params , errCode , errMsg , self ._traceLog )
190192
191- def sendRequest (self , httpMethod , domain , path , params , token , secret = None , useHTTPS = False , timeout = None , userKey = None ):
193+ def sendRequest (self , httpMethod , domain , path , params , token , secret = None , useHTTPS = False , timeout = None , userKey = None , enable_host_check = True ):
192194
193195 params ["sdk" ] = "python_" + self .VERSION
194196 # prepare query params
@@ -216,16 +218,15 @@ def sendRequest(self, httpMethod, domain, path, params, token, secret=None, useH
216218 params ["oauth_token" ] = token
217219
218220 # get rest response.
219- res = self .curl (resourceURI , params , timeout )
221+ res = self .curl (resourceURI , params , timeout , enable_host_check )
220222
221223 return res
222224
223225
224- def curl (self , url , params = None , timeout = None ):
226+ def curl (self , url , params = None , timeout = None , enable_host_check = True ):
225227
226228 queryString = self .buildQS (params )
227229
228-
229230 self .traceField ("URL" , url )
230231 self .traceField ("postData" , queryString )
231232
@@ -234,12 +235,12 @@ def curl(self, url, params=None, timeout=None):
234235 if self ._proxy :
235236 opener = build_opener (
236237 HTTPHandler (),
237- ValidHTTPSHandler (),
238+ ValidHTTPSHandler (enable_host_check ), # maybe always send False???
238239 ProxyHandler ({proto : self ._proxy }))
239240 else :
240241 opener = build_opener (
241242 HTTPHandler (),
242- ValidHTTPSHandler ())
243+ ValidHTTPSHandler (enable_host_check ))
243244
244245 queryString = queryString .encode ('utf-8' )
245246
@@ -440,11 +441,12 @@ def __str__(self):
440441 return sb
441442
442443
443- class ValidHTTPSConnection (HTTPConnection ):
444+ class ValidHTTPSConnection (HTTPSConnection ):
444445 default_port = HTTPS_PORT
445446
446447 def __init__ (self , * args , ** kwargs ):
447- HTTPConnection .__init__ (self , * args , ** kwargs )
448+ HTTPSConnection .__init__ (self , * args , ** kwargs )
449+ self ._context = kwargs .get ('context' )
448450
449451 def connect (self ):
450452 sock = socket .create_connection ((self .host , self .port ), self .timeout , self .source_address )
@@ -453,18 +455,28 @@ def connect(self):
453455 self .sock = sock
454456 self ._tunnel ()
455457
456- context = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
457- context .minumum_version = ssl .TLSVersion .TLSv1_2
458- context .load_verify_locations (GSRequest .caCertsPath )
459- context .verify_mode = ssl .CERT_REQUIRED
460- context .check_hostname = True
461-
462- self .sock = context .wrap_socket (sock , server_hostname = self .host )
458+ self .sock = self ._context .wrap_socket (sock , server_hostname = self .host )
463459
464460
465461class ValidHTTPSHandler (HTTPSHandler ):
462+ def __init__ (self , enable_host_check = True ):
463+ super ().__init__ ()
464+ self ._enableHostCheck = enable_host_check
465+
466466 def https_open (self , req ):
467- return self .do_open (ValidHTTPSConnection , req )
467+ return self .do_open (self .get_connection , req )
468+
469+ def get_connection (self , host , timeout ):
470+ return ValidHTTPSConnection (host , timeout = timeout , context = self .create_context ())
471+
472+ def create_context (self ):
473+ context = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
474+ context .minimum_version = ssl .TLSVersion .TLSv1_2
475+ context .load_verify_locations (GSRequest .caCertsPath )
476+ context .verify_mode = ssl .CERT_REQUIRED
477+ context .check_hostname = self ._enableHostCheck
478+
479+ return context
468480
469481
470482class SigUtils ():
@@ -483,7 +495,7 @@ def validateUserSignature(UID, timestamp, secret, signature, expiration=None):
483495 def validateUserSignatureWithExpiration (UID , timestamp , secret , signature , expiration ):
484496 expired = SigUtils .signatureTimestampExpired (timestamp , expiration )
485497 signatureValidated = SigUtils .validateUserSignature (UID , timestamp , secret , signature )
486- return not expired and signatureValidated
498+ return not expired and signatureValidated
487499
488500 @staticmethod
489501 def validateFriendSignature (UID , timestamp , friendUID , secret , signature , expiration = None ):
@@ -493,7 +505,7 @@ def validateFriendSignature(UID, timestamp, friendUID, secret, signature, expira
493505 return expectedSig == signature
494506 else :
495507 expired = SigUtils .signatureTimestampExpired (timestamp , expiration )
496- return not expired and expectedSig == signature
508+ return not expired and expectedSig == signature
497509
498510 @staticmethod
499511 def validateFriendSignatureWithExpiration (UID , timestamp , friendUID , secret , signature , expiration ):
0 commit comments