15 # FOR A PARTICULAR PURPOSE. |
15 # FOR A PARTICULAR PURPOSE. |
16 # |
16 # |
17 ############################################################################## |
17 ############################################################################## |
18 |
18 |
19 |
19 |
20 # import standard packages |
|
21 import base64 |
20 import base64 |
22 import cookielib |
21 import cookielib |
23 import httplib |
22 import httplib |
24 import socket |
23 import socket |
25 import urllib2 |
24 import urllib2 |
26 import xmlrpclib |
25 import xmlrpclib |
27 |
26 |
28 # import Zope3 interfaces |
|
29 |
|
30 # import local interfaces |
|
31 |
|
32 # import Zope3 packages |
|
33 |
|
34 # import local packages |
|
35 |
|
36 |
27 |
37 class TimeoutHTTP(httplib.HTTP): |
28 class TimeoutHTTP(httplib.HTTP): |
38 def __init__(self, host='', port=None, strict=None, timeout=None): |
29 def __init__(self, host='', port=None, strict=None, timeout=None): |
39 if port == 0: |
30 if port == 0: |
40 port = None |
31 port = None |
41 self._setup(self._connection_class(host, port, strict, timeout)) |
32 self._setup(self._connection_class(host, port, strict, timeout)) |
42 |
33 |
|
34 |
43 class TimeoutHTTPS(httplib.HTTPS): |
35 class TimeoutHTTPS(httplib.HTTPS): |
44 def __init__(self, host='', port=None, strict=None, timeout=None): |
36 def __init__(self, host='', port=None, strict=None, timeout=None): |
45 if port == 0: |
37 if port == 0: |
46 port = None |
38 port = None |
47 self._setup(self._connection_class(host, port, strict, timeout)) |
39 self._setup(self._connection_class(host, port, strict, timeout)) |
51 """An XML-RPC transport handling authentication via cookies""" |
43 """An XML-RPC transport handling authentication via cookies""" |
52 |
44 |
53 _http_connection = httplib.HTTPConnection |
45 _http_connection = httplib.HTTPConnection |
54 _http_connection_compat = TimeoutHTTP |
46 _http_connection_compat = TimeoutHTTP |
55 |
47 |
56 def __init__(self, user_agent, credentials=(), cookies=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None): |
48 def __init__(self, user_agent, credentials=(), cookies=None, |
|
49 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None): |
57 xmlrpclib.Transport.__init__(self) |
50 xmlrpclib.Transport.__init__(self) |
58 self.user_agent = user_agent |
51 self.user_agent = user_agent |
59 self.credentials = credentials |
52 self.credentials = credentials |
60 self.cookies = cookies |
53 self.cookies = cookies |
61 self.timeout = timeout |
54 self.timeout = timeout |
156 cresponse = XMLRPCCookieAuthTransport.CookieResponse(response) |
149 cresponse = XMLRPCCookieAuthTransport.CookieResponse(response) |
157 for cookie in self.cookies.make_cookies(cresponse, crequest): |
150 for cookie in self.cookies.make_cookies(cresponse, crequest): |
158 if cookie.name.startswith('Set-Cookie'): |
151 if cookie.name.startswith('Set-Cookie'): |
159 cookie.name = cookie.name.split(': ', 1)[1] |
152 cookie.name = cookie.name.split(': ', 1)[1] |
160 self.cookies.set_cookie(cookie) |
153 self.cookies.set_cookie(cookie) |
161 if response.status != 200: |
154 if response.status >= 300: |
162 raise xmlrpclib.ProtocolError(host + handler, response.status, response.reason, response.getheaders()) |
155 raise xmlrpclib.ProtocolError(host + handler, response.status, |
|
156 response.reason, response.getheaders()) |
163 return self.parse_response(response) |
157 return self.parse_response(response) |
164 |
158 |
165 def _get_response_compat(self, connection, host, handler): |
159 def _get_response_compat(self, connection, host, handler): |
166 errcode, errmsg, headers = connection.getreply() |
160 errcode, errmsg, headers = connection.getreply() |
167 # extract cookies from response headers |
161 # extract cookies from response headers |
168 if self.cookies is not None: |
162 if self.cookies is not None: |
169 crequest = XMLRPCCookieAuthTransport.CookieRequest('http://%s/' % host) |
163 crequest = XMLRPCCookieAuthTransport.CookieRequest('http://%s/' % host) |
170 cresponse = XMLRPCCookieAuthTransport.CompatCookieResponse(headers) |
164 cresponse = XMLRPCCookieAuthTransport.CompatCookieResponse(headers) |
171 self.cookies.extract_cookies(cresponse, crequest) |
165 self.cookies.extract_cookies(cresponse, crequest) |
172 if errcode != 200: |
166 if errcode >= 300: |
173 raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) |
167 raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) |
174 try: |
168 try: |
175 sock = connection._conn.sock |
169 sock = connection._conn.sock |
176 except AttributeError: |
170 except AttributeError: |
177 sock = None |
171 sock = None |
183 |
177 |
184 _http_connection = httplib.HTTPSConnection |
178 _http_connection = httplib.HTTPSConnection |
185 _http_connection_compat = TimeoutHTTPS |
179 _http_connection_compat = TimeoutHTTPS |
186 |
180 |
187 |
181 |
188 def getClient(uri, credentials=(), verbose=False, allow_none=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None): |
182 def getClient(uri, credentials=(), verbose=False, allow_none=0, |
|
183 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None): |
189 """Get an XML-RPC client which supports basic authentication""" |
184 """Get an XML-RPC client which supports basic authentication""" |
190 if uri.startswith('https:'): |
185 if uri.startswith('https:'): |
191 transport = SecureXMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY secure transport)', credentials, timeout=timeout, headers=headers) |
186 transport = SecureXMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY secure transport)', |
|
187 credentials, timeout=timeout, headers=headers) |
192 else: |
188 else: |
193 transport = XMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY basic transport)', credentials, timeout=timeout, headers=headers) |
189 transport = XMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY basic transport)', |
|
190 credentials, timeout=timeout, headers=headers) |
194 return xmlrpclib.Server(uri, transport=transport, verbose=verbose, allow_none=allow_none) |
191 return xmlrpclib.Server(uri, transport=transport, verbose=verbose, allow_none=allow_none) |
195 |
192 |
196 |
193 |
197 def getClientWithCookies(uri, credentials=(), verbose=False, allow_none=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, |
194 def getClientWithCookies(uri, credentials=(), verbose=False, allow_none=0, |
198 headers=None, cookies=None): |
195 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None, cookies=None): |
199 """Get an XML-RPC client which supports authentication through cookies""" |
196 """Get an XML-RPC client which supports authentication through cookies""" |
200 if cookies is None: |
197 if cookies is None: |
201 cookies = cookielib.CookieJar() |
198 cookies = cookielib.CookieJar() |
202 if uri.startswith('https:'): |
199 if uri.startswith('https:'): |
203 transport = SecureXMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY secure cookie transport)', |
200 transport = SecureXMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY secure ' |
|
201 'cookie transport)', |
204 credentials, cookies, timeout, headers) |
202 credentials, cookies, timeout, headers) |
205 else: |
203 else: |
206 transport = XMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY basic cookie transport)', |
204 transport = XMLRPCCookieAuthTransport('Python XML-RPC Client/0.1 (ZTFY basic ' |
|
205 'cookie transport)', |
207 credentials, cookies, timeout, headers) |
206 credentials, cookies, timeout, headers) |
208 return xmlrpclib.Server(uri, transport=transport, verbose=verbose, allow_none=allow_none) |
207 return xmlrpclib.Server(uri, transport=transport, verbose=verbose, allow_none=allow_none) |