def testSerialisingDict(): inputValues = {'a': 'b', 'c': 1, 'e': 2} assert u'{"a": "b", "c": 1, "e": 2}' == toJson(inputValues) assert inputValues == fromJson(toJson(inputValues)) inputValues = {'a': 'b', 'c': 1, 'e': 2.3} assert u'{"a": "b", "c": 1, "e": 2.3}' == toJson(inputValues)
def testSerialisingDictsInList(): inputValues = [ {'a': 'b', 'c': 1}, {'a': 'b', 'c': 1}, ] output = toJson(inputValues) assert u'[{"a": "b", "c": 1}, {"a": "b", "c": 1}]' == output
def testSerialisingDictsInListWithFloat(): inputValues = [ {'a': 'b', 'c': 1, 'e': 2.3}, {'g': 'h', 'i': 4, 'k': 5.6}, ] output = toJson(inputValues) assert u'[{"a": "b", "c": 1, "e": 2.3}, {"i": 4, "k": 5.6, "g": "h"}]' == output
def testSerialisingGeneratorFunction(): def gen(): yield 1 yield 2 yield 3 yield u"a" obj = toJson(gen()) assert u'[1, 2, 3, "a"]' == obj
def _renderError(self, failure): result = http.Response() result.headers.setHeader( 'content-type', http_headers.MimeType("text", "html", {"charset": "utf-8"})) error = u'Unknown error' try: failure.raiseException() except Exception as err: error = {'class': err.__class__.__name__, 'message': unicode(err)} error = toJson({"id": None, "result": None, "error": error}) result.stream = stream.IByteStream(error.encode('utf-8')) return result
def processIncomingRpc(self, rpc): try: rpc = fromJson(rpc) if rpc.get("method") == "registerClient": # New client protocol self.clientInfo = rpc.get("params", []) self.login_capable = True logger.info("Client %s info set to: %s", self, self.clientInfo) return toJson({ "id": rpc.get("id"), "result": f"client {'/'.join(self.clientInfo)}/{self.client_id} registered", "error": None }) jsonrpc = JsonRpc( instance=self._controller._opsiclientdRpcInterface, # pylint: disable=protected-access interface=self._controller._opsiclientdRpcInterface. getInterface(), # pylint: disable=protected-access rpc=rpc) jsonrpc.execute() return toJson(jsonrpc.getResponse()) except Exception as rpc_error: # pylint: disable=broad-except logger.error(rpc_error, exc_info=True) return toJson({"id": None, "error": str(rpc_error)})
def run(self): self.started = time.time() timeout = self.hostControlBackend._hostRpcTimeout if timeout < 0: timeout = 0 try: query = toJson({ 'id': 1, 'method': self.method, 'params': self.params }).encode('utf-8') connection = HTTPSConnection(host=self.address, port=self.hostPort, timeout=timeout) with closingConnection(connection) as connection: non_blocking_connect_https(connection, timeout) connection.putrequest('POST', '/opsiclientd') connection.putheader('User-Agent', self._USER_AGENT) connection.putheader('content-type', 'application/json') connection.putheader('content-length', str(len(query))) auth = u'{0}:{1}'.format(self.username, self.password) connection.putheader( 'Authorization', 'Basic ' + base64.b64encode(auth.encode('latin-1'))) connection.endheaders() connection.send(query) response = connection.getresponse() response = response.read() response = fromJson(unicode(response, 'utf-8')) if response and isinstance(response, dict): self.error = response.get('error') self.result = response.get('result') else: self.error = u"Bad response from client: %s" % forceUnicode( response) except Exception as e: self.error = forceUnicode(e) finally: self.ended = time.time()
def executeRpc(self, method, params=None, with_lock=True): params = params or [] with log_context({'instance': 'control pipe'}): rpc_id = 1 if not self.clientInfo: return { "id": rpc_id, "error": f"Cannot execute rpc, not supported by client {self}", "result": None } request = {"id": rpc_id, "method": method, "params": params} try: if with_lock: self.comLock.acquire() # pylint: disable=consider-using-with try: request_json = toJson(request) logger.info("Sending request '%s' to client %s", request_json, self) self.write(request_json) response_json = self.read() if not response_json: logger.warning( "No response for method '%s' received from client %s", request["method"], self) return {"id": rpc_id, "error": None, "result": None} logger.info("Received response '%s' from client %s", response_json, self) response = fromJson(response_json) if method == "loginUser" and response.get("result"): # Credential provider can only handle one successful login. # Ensure, that the credential provider is not used for a # second login if it keeps the pipe connection open. self.login_capable = False return response finally: if with_lock: self.comLock.release() except Exception as client_err: # pylint: disable=broad-except logger.error(client_err, exc_info=True) return {"id": rpc_id, "error": str(client_err), "result": None}
def testSerialisingTuples(): values = (1, 2, 3, 4) assert '[1, 2, 3, 4]' == toJson(values)
def testUnserialisableThingsFail(): class Foo(object): pass with pytest.raises(TypeError): toJson(Foo())
def testSerialisingSetInListWithFloat(): inputValues = ['a', 'b', set('c'), 4, 5.6] assert u'["a", "b", ["c"], 4, 5.6]' == toJson(inputValues)
def testSerialisingListInListWithFloat(): inputValues = ['a', 'b', 'c', [4, 5.6, ['f']]] assert u'["a", "b", "c", [4, 5.6, ["f"]]]' == toJson(inputValues)
def testSerialisingListWithFLoat(): inputValues = ['a', 'b', 'c', 4, 5.6] output = toJson(inputValues) assert inputValues == fromJson(output) assert u'["a", "b", "c", 4, 5.6]' == output
def testSerialisingSet(): inputSet = set([u'opsi-client-agent', u'mshotfix', u'firefox']) output = toJson(inputSet) assert set(fromJson(output)) == inputSet
def _generateResponse(self, result): logger.info(u"Creating interface page") javascript = [ u"var currentParams = new Array();", u"var currentMethod = null;" ] currentMethod = u'' if self._rpcs: currentMethod = self._rpcs[0].getMethodName() javascript.append(u"currentMethod = '%s';" % currentMethod) for (index, param) in enumerate(self._rpcs[0].params): javascript.append(u"currentParams[%d] = '%s';" % (index, toJson(param))) selectMethod = [] for method in self._callInterface: methodName = method['name'] javascript.append(u"parameters['%s'] = new Array();" % methodName) for (index, param) in enumerate(method['params']): javascript.append(u"parameters['%s'][%s]='%s';" % (methodName, index, param)) selected = u'' if method['name'] == currentMethod: selected = u' selected="selected"' selectMethod.append(u'<option%s>%s</option>' % (selected, method['name'])) def wrapInDiv(obj): return u'<div class="json">{0}</div>'.format(obj) results = [u'<div id="result">'] if isinstance(result, failure.Failure): error = u'Unknown error' try: result.raiseException() except Exception as err: error = { 'class': err.__class__.__name__, 'message': unicode(err) } error = toJson({"id": None, "result": None, "error": error}) results.append(wrapInDiv(objectToHtml(error))) else: for rpc in self._rpcs: results.append( wrapInDiv(objectToHtml(serialize(rpc.getResponse())))) results.append(u'</div>') html = interfacePage % { 'path': self.path, 'title': u'opsi interface page', 'javascript': u'\n'.join(javascript), 'select_path': u'<option selected="selected">%s</option>' % self.path, 'select_method': u''.join(selectMethod), 'result': u''.join(results), } if not isinstance(result, http.Response): result = http.Response() result.code = responsecode.OK result.stream = stream.IByteStream(html.encode('utf-8').strip()) return result
def _generateResponse(self, result): invalidMime = False # For handling the invalid MIME type "gzip-application/json-rpc" encoding = None try: if 'gzip' in self.request.headers.getHeader('Accept-Encoding'): encoding = 'gzip' elif 'deflate' in self.request.headers.getHeader( 'Accept-Encoding'): encoding = 'deflate' except Exception as error: logger.debug2( "Failed to get Accept-Encoding from request header: {0}". format(error)) try: if self.request.headers.getHeader('Accept'): for accept in self.request.headers.getHeader('Accept').keys(): if accept.mediaType.startswith('gzip'): invalidMime = True encoding = 'gzip' break except Exception as error: logger.error(u"Failed to get accepted mime types from header: {0}", error) response = [serialize(rpc.getResponse()) for rpc in self._rpcs] if len(response) == 1: response = response[0] if not response: response = None if not isinstance(result, http.Response): result = http.Response() result.code = responsecode.OK result.headers.setHeader( 'content-type', http_headers.MimeType("application", "json", {"charset": "utf-8"})) if invalidMime: # The invalid requests expect the encoding set to # gzip but the content is deflated. result.headers.setHeader('content-encoding', ["gzip"]) result.headers.setHeader( 'content-type', http_headers.MimeType("gzip-application", "json", {"charset": "utf-8"})) logger.debug( u"Sending deflated data (backwards compatible - with content-encoding 'gzip')" ) result.stream = stream.IByteStream( deflateEncode(toJson(response).encode('utf-8'))) elif encoding == "deflate": logger.debug(u"Sending deflated data") result.headers.setHeader('content-encoding', [encoding]) result.stream = stream.IByteStream( deflateEncode(toJson(response).encode('utf-8'))) elif encoding == "gzip": logger.debug(u"Sending gzip compressed data") result.headers.setHeader('content-encoding', [encoding]) result.stream = stream.IByteStream( gzipEncode(toJson(response).encode('utf-8'))) else: logger.debug(u"Sending plain data") result.stream = stream.IByteStream( toJson(response).encode('utf-8')) return result