59 self.credentials = credentials |
59 self.credentials = credentials |
60 self.cookies = cookies |
60 self.cookies = cookies |
61 self.timeout = timeout |
61 self.timeout = timeout |
62 if self._connection_required_compat(): |
62 if self._connection_required_compat(): |
63 self.make_connection = self._make_connection_compat |
63 self.make_connection = self._make_connection_compat |
|
64 self.get_response = self._get_response_compat |
64 |
65 |
65 def _connection_required_compat(self): |
66 def _connection_required_compat(self): |
66 # Compatibility code copied from EULExistDB (https://github.com/emory-libraries/eulexistdb) |
67 # Compatibility code copied from EULExistDB (https://github.com/emory-libraries/eulexistdb) |
67 # UGLY HACK ALERT. Python 2.7 xmlrpclib caches connection objects in |
68 # UGLY HACK ALERT. Python 2.7 xmlrpclib caches connection objects in |
68 # self._connection (and sets self._connection in __init__). Python |
69 # self._connection (and sets self._connection in __init__). Python |
100 connection.putheader('Cookie', '%s=%s' % (cookie.name, cookie.value)) |
101 connection.putheader('Cookie', '%s=%s' % (cookie.name, cookie.value)) |
101 elif self.credentials: |
102 elif self.credentials: |
102 auth = 'Basic %s' % base64.encodestring("%s:%s" % self.credentials).strip() |
103 auth = 'Basic %s' % base64.encodestring("%s:%s" % self.credentials).strip() |
103 connection.putheader('Authorization', auth) |
104 connection.putheader('Authorization', auth) |
104 |
105 |
|
106 # dummy request class for extracting cookies |
|
107 class CookieRequest(urllib2.Request): |
|
108 pass |
|
109 |
|
110 # dummy response info headers helper |
|
111 class CookieResponseHelper: |
|
112 def __init__(self, response): |
|
113 self.response = response |
|
114 def getheaders(self, header): |
|
115 return self.response.msg.getallmatchingheaders(header) |
|
116 |
|
117 # dummy response class for extracting cookies |
|
118 class CookieResponse: |
|
119 def __init__(self, response): |
|
120 self.response = response |
|
121 def info(self): |
|
122 return XMLRPCCookieAuthTransport.CookieResponseHelper(self.response) |
|
123 |
|
124 # dummy compat response class for extracting cookies |
|
125 class CompatCookieResponse: |
|
126 def __init__(self, headers): |
|
127 self.headers = headers |
|
128 def info(self): |
|
129 return self.headers |
|
130 |
105 def request(self, host, handler, request_body, verbose=False): |
131 def request(self, host, handler, request_body, verbose=False): |
106 |
|
107 # dummy request class for extracting cookies |
|
108 class CookieRequest(urllib2.Request): |
|
109 pass |
|
110 |
|
111 # dummy response class for extracting cookies |
|
112 class CookieResponse: |
|
113 def __init__(self, headers): |
|
114 self.headers = headers |
|
115 def info(self): |
|
116 return self.headers |
|
117 |
|
118 # issue XML-RPC request |
132 # issue XML-RPC request |
119 connection = self.make_connection(host) |
133 connection = self.make_connection(host) |
120 self.verbose = verbose |
134 self.verbose = verbose |
121 if verbose: |
135 if verbose: |
122 connection.set_debuglevel(1) |
136 connection.set_debuglevel(1) |
123 self.send_request(connection, handler, request_body) |
137 self.send_request(connection, handler, request_body) |
124 self.send_host(connection, host) |
138 self.send_host(connection, host) |
125 self.send_user_agent(connection) |
139 self.send_user_agent(connection) |
126 self.send_content(connection, request_body) |
140 self.send_content(connection, request_body) |
127 # get response |
141 # get response |
|
142 return self.get_response(connection, host, handler) |
|
143 |
|
144 def get_response(self, connection, host, handler): |
|
145 response = connection.getresponse() |
|
146 # extract cookies from response headers |
|
147 if self.cookies is not None: |
|
148 crequest = XMLRPCCookieAuthTransport.CookieRequest('http://%s/' % host) |
|
149 cresponse = XMLRPCCookieAuthTransport.CookieResponse(response) |
|
150 self.cookies.extract_cookies(cresponse, crequest) |
|
151 if response.status != 200: |
|
152 raise xmlrpclib.ProtocolError(host + handler, response.status, response.reason, response.getheaders()) |
|
153 return self.parse_response(response) |
|
154 |
|
155 def _get_response_compat(self, connection, host, handler): |
128 errcode, errmsg, headers = connection.getreply() |
156 errcode, errmsg, headers = connection.getreply() |
129 # extract cookies from response headers |
157 # extract cookies from response headers |
130 crequest = CookieRequest('http://%s/' % host) |
|
131 cresponse = CookieResponse(headers) |
|
132 if self.cookies is not None: |
158 if self.cookies is not None: |
|
159 crequest = XMLRPCCookieAuthTransport.CookieRequest('http://%s/' % host) |
|
160 cresponse = XMLRPCCookieAuthTransport.CompatCookieResponse(headers) |
133 self.cookies.extract_cookies(cresponse, crequest) |
161 self.cookies.extract_cookies(cresponse, crequest) |
134 if errcode != 200: |
162 if errcode != 200: |
135 raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) |
163 raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers) |
136 try: |
164 try: |
137 sock = connection._conn.sock |
165 sock = connection._conn.sock |