def process_get_call(self,
                         url,
                         url_query_items,
                         timeout=None,
                         report_url=True):
        """
        Run a GET request and return reply data
        :param url: url for request
        :param url_query_items:
        :param timeout: in ms
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        url_query = QUrl(url)
        if report_url:
            self.report_info('GET ' + url_query.toString())

        if url_query_items:
            url_query.setQuery(url_query_items)

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        if timeout is not None and "setTransferTimeout" in dir(request):
            request.setTransferTimeout(timeout)

        reply = self.network_access_manager.blockingGet(
            request, self.connection.auth_cfg, True, self.feedback)
        return self.process_qgs_reply(reply)
Beispiel #2
0
    def executeHTTPQuery(self, method, path, callback, body, context={}, downloadProgressCallback=None, showProgress=True, ignoreErrors=False, progressText=None, timeout=5):
        """
        Call the remote server

        :param method: HTTP method
        :param path: Remote path
        :param body: params to send (dictionary)
        :param callback: callback method to call when the server replies
        :param context: Pass a context to the response callback
        :param downloadProgressCallback: Callback called when received something, it can be an incomplete response
        :param showProgress: Display progress to the user
        :param progressText: Text display to user in progress dialog. None for auto generated
        :param ignoreErrors: Ignore connection error (usefull to not closing a connection when notification feed is broken)
        :param timeout: Delay in seconds before raising a timeout
        :returns: QNetworkReply
        """

        try:
            ip = self._http_host.rsplit('%', 1)[0]
            ipaddress.IPv6Address(ip)  # remove any scope ID
            # this is an IPv6 address, we must surround it with brackets to be used with QUrl.
            host = "[{}]".format(ip)
        except ipaddress.AddressValueError:
            host = self._http_host

        log.debug("{method} {protocol}://{host}:{port}/v1{path} {body}".format(method=method, protocol=self._scheme, host=host, port=self._http_port, path=path, body=body))
        if self._user:
            url = QtCore.QUrl("{protocol}://{user}@{host}:{port}/v1{path}".format(protocol=self._scheme, user=self._user, host=host, port=self._http_port, path=path))
        else:
            url = QtCore.QUrl("{protocol}://{host}:{port}/v1{path}".format(protocol=self._scheme, host=host, port=self._http_port, path=path))
        request = self._request(url)

        request = self.addAuth(request)

        request.setRawHeader(b"User-Agent", "GNS3 QT Client v{version}".format(version=__version__).encode())

        # By default QT doesn't support GET with body even if it's in the RFC that's why we need to use sendCustomRequest
        body = self._addBodyToRequest(body, request)

        response = self._network_manager.sendCustomRequest(request, method.encode(), body)

        context = copy.copy(context)
        context["query_id"] = str(uuid.uuid4())

        response.finished.connect(qpartial(self._processResponse, response, callback, context, body, ignoreErrors))

        if downloadProgressCallback is not None:
            response.downloadProgress.connect(qpartial(self._processDownloadProgress, response, downloadProgressCallback, context))

        if showProgress:
            response.uploadProgress.connect(qpartial(self.notify_progress_upload, context["query_id"]))
            response.downloadProgress.connect(qpartial(self.notify_progress_download, context["query_id"]))
            # Should be the last operation otherwise we have race condition in Qt
            # where query start before finishing connect to everything
            self.notify_progress_start_query(context["query_id"], progressText, response)

        if timeout is not None:
            QtCore.QTimer.singleShot(timeout * 1000, qpartial(self._timeoutSlot, response))

        return response
Beispiel #3
0
 def addAuth(self, request):
     """
     If require add basic auth header
     """
     if self._user:
         auth_string = "{}:{}".format(self._user, self._password)
         auth_string = base64.b64encode(auth_string.encode("utf-8"))
         auth_string = "Basic {}".format(auth_string.decode())
         request.setRawHeader("Authorization", auth_string)
     return request
Beispiel #4
0
 def _addAuth(self, request):
     """
     If require add basic auth header
     """
     if self._user:
         auth_string = "{}:{}".format(self._user, self._password)
         auth_string = base64.b64encode(auth_string.encode("utf-8"))
         auth_string = "Basic {}".format(auth_string.decode())
         request.setRawHeader(b"Authorization", auth_string.encode())
     return request
 def createRequest(self, operation, request, data):
     al1 = QtCore.QByteArray()
     al1.append("Accept-Language")
     al2 = QtCore.QByteArray()
     al2.append("en-US,en;q=0.5")
     request.setRawHeader(al1, al2)
     dnt1 = QtCore.QByteArray()
     dnt1.append("DNT")
     dnt2 = QtCore.QByteArray()
     dnt2.append("1")
     request.setRawHeader(dnt1, dnt2)
     return QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data)
    def process_post_call(self,
                          url,
                          url_query_items,
                          data,
                          is_read_only=True,
                          report_url=True):
        """
        Run a POST request and return reply data
        :param url: url for request
        :param url_query_items:
        :param data:
        :param is_read_only: True if the request does not update data
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        if self.connection.read_only and not is_read_only:
            return {
                "error": {
                    "msg": "Graphium connection is set to read-only!"
                }
            }

        url_query = QUrl(url)
        if report_url:
            self.report_info('POST ' + url_query.toString())

        if url_query_items:
            url_query.setQuery(url_query_items)

        # data_byte_array = json.dumps(data).encode('utf8')
        # data = QtCore.QByteArray( json.dumps( json_request ) )
        data_byte_array = QJsonDocument.fromVariant(data)

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        request.setHeader(QNetworkRequest.ContentTypeHeader,
                          "application/json")
        reply = self.network_access_manager.blockingPost(
            request, data_byte_array.toJson(), self.connection.auth_cfg, True,
            self.feedback)
        return self.process_qgs_reply(reply)
    def process_put_call(self, url, data=None, report_url=True):
        """
        Run a PUT request and return reply data
        :param url: url for request
        :param data:
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        if self.connection.read_only:
            return {
                "error": {
                    "msg": "Graphium connection is set to read-only!"
                }
            }

        url_query = QUrl(url)
        if report_url:
            self.report_info('PUT ' + url_query.toString())

        data_byte_array = QJsonDocument.fromVariant(data)

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            self.auth = 0
            config = QgsAuthMethodConfig()
            QgsApplication.authManager().loadAuthenticationConfig(
                self.connection.auth_cfg, config, True)
            concatenated = config.configMap(
            )['username'] + ":" + config.configMap()['password']

            data = base64.encodebytes(concatenated.encode("utf-8")).replace(
                '\n'.encode("utf-8"), ''.encode("utf-8"))
            request.setRawHeader("Authorization".encode("utf-8"),
                                 ("Basic %s" % data).encode("utf-8"))
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        loop = QEventLoop()  # https://stackoverflow.com/a/46514984
        reply = self.network_access_manager.put(request,
                                                data_byte_array.toJson())
        reply.finished.connect(loop.quit)
        loop.exec_()

        return self.process_q_reply(reply)
    def process_delete_call(self, url, report_url=True):
        """
        Run a DELETE request and return reply data
        :param url: url for request
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        if self.connection.read_only:
            return {
                "error": {
                    "msg": "Graphium connection is set to read-only!"
                }
            }

        url_query = QUrl(url)
        if report_url:
            self.report_info('DELETE ' + url_query.toString())

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            self.auth = 0
            config = QgsAuthMethodConfig()
            QgsApplication.authManager().loadAuthenticationConfig(
                self.connection.auth_cfg, config, True)
            concatenated = config.configMap(
            )['username'] + ":" + config.configMap()['password']

            data = base64.encodebytes(concatenated.encode("utf-8")).replace(
                '\n'.encode("utf-8"), ''.encode("utf-8"))
            request.setRawHeader("Authorization".encode("utf-8"),
                                 ("Basic %s" % data).encode("utf-8"))
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        loop = QEventLoop()
        reply = self.network_access_manager.deleteResource(request)
        reply.finished.connect(loop.quit)
        loop.exec_()

        return self.process_q_reply(reply)
Beispiel #9
0
    def _addBodyToRequest(self, body, request):
        """
        Add the require headers for sending the body.
        It detect the type of body for sending the corresponding headers
        and methods.

        :param body: The body
        :returns: The body compatible with Qt
        """

        if body is None:
            return None

        if isinstance(body, dict):
            body = json.dumps(body)
            request.setRawHeader(b"Content-Type", b"application/json")
            request.setRawHeader(b"Content-Length", str(len(body)).encode())
            data = QtCore.QByteArray(body.encode())
            body = QtCore.QBuffer(self)
            body.setData(data)
            body.open(QtCore.QIODevice.ReadOnly)
            return body
        elif isinstance(body, pathlib.Path):
            body = QtCore.QFile(str(body), self)
            body.open(QtCore.QFile.ReadOnly)
            request.setRawHeader(b"Content-Type", b"application/octet-stream")
            # QT is smart and will compute the Content-Lenght for us
            return body
        else:
            return None
Beispiel #10
0
    def _sendRequest(self, url, params, headers={}):
        if self.asynchonous:

            if self.reply is not None:
                self.reply.finished.disconnect(self.reply_finished)
                self.reply.abort()
                self.reply = None

            url = QUrl(url)
            urlQuery = QUrlQuery(url)
            for key, value in params.items():
                urlQuery.addQueryItem(key, value)
            QgsLogger.debug('Request: {}'.format(url.toEncoded()))
            url.setQuery(urlQuery)
            request = QNetworkRequest(url)
            for key, value in headers.items():
                request.setRawHeader(key, value)
            self.reply = QgsNetworkAccessManager.instance().get(request)

        else:
            url = url + '?' + urllib.parse.urlencode(params)
            response = urllib.request.urlopen(url)
            data = json.load(response)
            self.load_data(data)
Beispiel #11
0
    def executeHTTPQuery(self, method, path, callback, body, context={}):
        """
        Call the remote server

        :param method: HTTP method
        :param path: Remote path
        :param body: params to send (dictionary)
        :param callback: callback method to call when the server replies
        :param context: Pass a context to the response callback
        """

        import copy
        context = copy.copy(context)
        context["query_id"] = str(uuid.uuid4())
        self.notify_progress_start_query(context["query_id"])
        log.debug("{method} {scheme}://{host}:{port}/v1{path} {body}".format(method=method, scheme=self.scheme, host=self.host, port=self.port, path=path, body=body))
        url = QtCore.QUrl("{scheme}://{host}:{port}/v1{path}".format(scheme=self.scheme, host=self.host, port=self.port, path=path))
        request = self._request(url)
        request = self.addAuth(request)

        request.setRawHeader("Content-Type", "application/json")
        request.setRawHeader("Content-Length", str(len(body)))
        request.setRawHeader("User-Agent", "GNS3 QT Client v{version}".format(version=__version__))

        if method == "GET":
            response = self._network_manager.get(request)

        if method == "PUT":
            body = json.dumps(body)
            request.setRawHeader("Content-Type", "application/json")
            request.setRawHeader("Content-Length", str(len(body)))
            response = self._network_manager.put(request, body)

        if method == "POST":
            body = json.dumps(body)
            request.setRawHeader("Content-Type", "application/json")
            request.setRawHeader("Content-Length", str(len(body)))
            response = self._network_manager.post(request, body)

        if method == "DELETE":
            response = self._network_manager.deleteResource(request)

        if HTTPClient._progress_callback and HTTPClient._progress_callback.progress_dialog():
            request_canceled = partial(self._requestCanceled, response, context)
            HTTPClient._progress_callback.progress_dialog().canceled.connect(request_canceled)
        response.finished.connect(partial(self._processResponse, response, callback, context))
Beispiel #12
0
    def getSynchronous(self, method, endpoint, prefix="/v2", timeout=5):
        """
        Synchronous check if a server is running

        :returns: Tuple (Status code, json of answer). Status 0 is a non HTTP error
        """

        host = self._getHostForQuery()

        log.debug(
            "{method} {protocol}://{host}:{port}{prefix}{endpoint}".format(
                method=method,
                protocol=self._protocol,
                host=host,
                port=self._port,
                prefix=prefix,
                endpoint=endpoint))
        if self._user:
            url = QtCore.QUrl(
                "{protocol}://{user}@{host}:{port}{prefix}{endpoint}".format(
                    protocol=self._protocol,
                    user=self._user,
                    host=host,
                    port=self._port,
                    prefix=prefix,
                    endpoint=endpoint))
        else:
            url = QtCore.QUrl(
                "{protocol}://{host}:{port}{prefix}{endpoint}".format(
                    protocol=self._protocol,
                    host=host,
                    port=self._port,
                    prefix=prefix,
                    endpoint=endpoint))

        request = self._request(url)
        request = self._addAuth(request)
        request.setRawHeader(
            b"User-Agent",
            "GNS3 QT Client v{version}".format(version=__version__).encode())

        try:
            response = self._network_manager.sendCustomRequest(
                request, method.encode())
        except SystemError as e:
            log.error("Can't send query: {}".format(str(e)))
            return

        loop = QtCore.QEventLoop()
        response.finished.connect(loop.quit)

        if timeout is not None:
            QtCore.QTimer.singleShot(
                timeout * 1000, qpartial(self._timeoutSlot, response, timeout))

        if not loop.isRunning():
            loop.exec_()

        status = response.attribute(
            QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)
        if response.error() != QtNetwork.QNetworkReply.NoError:
            log.debug("Error while connecting to local server {}".format(
                response.errorString()))
            return status, None
        else:
            content_type = response.header(
                QtNetwork.QNetworkRequest.ContentTypeHeader)
            if status == 200:
                if content_type == "application/json":
                    content = bytes(response.readAll())
                    json_data = json.loads(content.decode("utf-8"))
                    return status, json_data
            else:
                return status, None

        return 0, None
Beispiel #13
0
    def _executeHTTPQuery(self,
                          method,
                          path,
                          callback,
                          body,
                          context={},
                          downloadProgressCallback=None,
                          showProgress=True,
                          ignoreErrors=False,
                          progressText=None,
                          server=None,
                          timeout=120,
                          prefix="/v2",
                          params={},
                          networkManager=None,
                          eventsHandler=None,
                          **kwargs):
        """
        Call the remote server

        :param method: HTTP method
        :param path: Remote path
        :param body: params to send (dictionary)
        :param callback: callback method to call when the server replies
        :param context: Pass a context to the response callback
        :param downloadProgressCallback: Callback called when received something, it can be an incomplete response
        :param showProgress: Display progress to the user
        :param networkManager: The network manager to use. If None use default
        :param progressText: Text display to user in progress dialog. None for auto generated
        :param ignoreErrors: Ignore connection error (usefull to not closing a connection when notification feed is broken)
        :param server: The server where the query is executed
        :param timeout: Delay in seconds before raising a timeout
        :param eventsHandler: Handler receiving and triggering events like `updated`, `cancelled`.
                      If not specified and showProgress is `True` then `ProgressDialog` receives them.
        :param params: Query arguments parameters
        :returns: QNetworkReply
        """

        host = self._getHostForQuery()
        query_string = self._paramsToQueryString(params)

        log.debug(
            "{method} {protocol}://{host}:{port}{prefix}{path} {body}{query_string}"
            .format(method=method,
                    protocol=self._protocol,
                    host=host,
                    port=self._port,
                    path=path,
                    body=body,
                    prefix=prefix,
                    query_string=query_string))
        if self._user:
            url = QtCore.QUrl(
                "{protocol}://{user}@{host}:{port}{prefix}{path}{query_string}"
                .format(protocol=self._protocol,
                        user=self._user,
                        host=host,
                        port=self._port,
                        path=path,
                        prefix=prefix,
                        query_string=query_string))
        else:
            url = QtCore.QUrl(
                "{protocol}://{host}:{port}{prefix}{path}{query_string}".
                format(protocol=self._protocol,
                       host=host,
                       port=self._port,
                       path=path,
                       prefix=prefix,
                       query_string=query_string))
        request = self._request(url)

        request = self._addAuth(request)

        request.setRawHeader(
            b"User-Agent",
            "GNS3 QT Client v{version}".format(version=__version__).encode())

        # By default QT doesn't support GET with body even if it's in the RFC that's why we need to use sendCustomRequest
        body = self._addBodyToRequest(body, request)

        if not networkManager:
            networkManager = self._network_manager

        try:
            response = networkManager.sendCustomRequest(
                request, method.encode(), body)
        except SystemError as e:
            log.error("Can't send query: {}".format(str(e)))
            return

        context = copy.copy(context)
        context["query_id"] = str(uuid.uuid4())

        response.finished.connect(
            qpartial(self._processResponse, response, server, callback,
                     context, body, ignoreErrors))
        response.error.connect(
            qpartial(self._processError, response, server, callback, context,
                     body, ignoreErrors))

        if downloadProgressCallback is not None:
            response.readyRead.connect(
                qpartial(self._readyReadySlot, response,
                         downloadProgressCallback, context, server))

        request_canceled = qpartial(self._requestCanceled, response, context)

        if eventsHandler is not None:
            eventsHandler.canceled.connect(request_canceled)
        elif not sip_is_deleted(
                HTTPClient._progress_callback
        ) and HTTPClient._progress_callback.progress_dialog():
            HTTPClient._progress_callback.progress_dialog().canceled.connect(
                request_canceled)

        if showProgress:
            response.uploadProgress.connect(
                qpartial(self._notify_progress_upload, context["query_id"]))
            response.downloadProgress.connect(
                qpartial(self._notify_progress_download, context["query_id"]))
            # Should be the last operation otherwise we have race condition in Qt
            # where query start before finishing connect to everything
            self._notify_progress_start_query(context["query_id"],
                                              progressText, response)

        if timeout is not None:
            QtCore.QTimer.singleShot(
                timeout * 1000, qpartial(self._timeoutSlot, response, timeout))

        return response
Beispiel #14
0
    def _executeHTTPQuery(self, method, path, callback, body, context={}, downloadProgressCallback=None, showProgress=True, ignoreErrors=False, progressText=None, server=None, timeout=120, prefix="/v2", params={}, networkManager=None, eventsHandler=None, **kwargs):
        """
        Call the remote server

        :param method: HTTP method
        :param path: Remote path
        :param body: params to send (dictionary)
        :param callback: callback method to call when the server replies
        :param context: Pass a context to the response callback
        :param downloadProgressCallback: Callback called when received something, it can be an incomplete response
        :param showProgress: Display progress to the user
        :param networkManager: The network manager to use. If None use default
        :param progressText: Text display to user in progress dialog. None for auto generated
        :param ignoreErrors: Ignore connection error (usefull to not closing a connection when notification feed is broken)
        :param server: The server where the query is executed
        :param timeout: Delay in seconds before raising a timeout
        :param eventsHandler: Handler receiving and triggering events like `updated`, `cancelled`.
                      If not specified and showProgress is `True` then `ProgressDialog` receives them.
        :param params: Query arguments parameters
        :returns: QNetworkReply
        """

        host = self._getHostForQuery()
        query_string = self._paramsToQueryString(params)

        log.debug("{method} {protocol}://{host}:{port}{prefix}{path} {body}{query_string}".format(method=method, protocol=self._protocol, host=host, port=self._port, path=path, body=body, prefix=prefix, query_string=query_string))
        if self._user:
            url = QtCore.QUrl("{protocol}://{user}@{host}:{port}{prefix}{path}{query_string}".format(protocol=self._protocol, user=self._user, host=host, port=self._port, path=path, prefix=prefix, query_string=query_string))
        else:
            url = QtCore.QUrl("{protocol}://{host}:{port}{prefix}{path}{query_string}".format(protocol=self._protocol, host=host, port=self._port, path=path, prefix=prefix, query_string=query_string))
        request = self._request(url)

        request = self._addAuth(request)

        request.setRawHeader(b"User-Agent", "GNS3 QT Client v{version}".format(version=__version__).encode())

        # By default QT doesn't support GET with body even if it's in the RFC that's why we need to use sendCustomRequest
        body = self._addBodyToRequest(body, request)

        if not networkManager:
            networkManager = self._network_manager

        try:
            response = networkManager.sendCustomRequest(request, method.encode(), body)
        except SystemError as e:
            log.error("Can't send query: {}".format(str(e)))
            return

        context = copy.copy(context)
        context["query_id"] = str(uuid.uuid4())

        response.finished.connect(qpartial(self._processResponse, response, server, callback, context, body, ignoreErrors))
        response.error.connect(qpartial(self._processError, response, server, callback, context, body, ignoreErrors))

        if downloadProgressCallback is not None:
            response.readyRead.connect(qpartial(self._readyReadySlot, response, downloadProgressCallback, context, server))

        request_canceled = qpartial(self._requestCanceled, response, context)

        if eventsHandler is not None:
            eventsHandler.canceled.connect(request_canceled)
        elif not sip_is_deleted(HTTPClient._progress_callback) and HTTPClient._progress_callback.progress_dialog():
            HTTPClient._progress_callback.progress_dialog().canceled.connect(request_canceled)

        if showProgress:
            response.uploadProgress.connect(qpartial(self._notify_progress_upload, context["query_id"]))
            response.downloadProgress.connect(qpartial(self._notify_progress_download, context["query_id"]))
            # Should be the last operation otherwise we have race condition in Qt
            # where query start before finishing connect to everything
            self._notify_progress_start_query(context["query_id"], progressText, response)

        if timeout is not None:
            QtCore.QTimer.singleShot(timeout * 1000, qpartial(self._timeoutSlot, response, timeout))

        return response
Beispiel #15
0
    def executeHTTPQuery(self, method, path, callback, body, context={}):
        """
        Call the remote server

        :param method: HTTP method
        :param path: Remote path
        :param body: params to send (dictionary)
        :param callback: callback method to call when the server replies
        :param context: Pass a context to the response callback
        """

        import copy
        context = copy.copy(context)
        context["query_id"] = str(uuid.uuid4())
        self.notify_progress_start_query(context["query_id"])
        log.debug("{method} {scheme}://{host}:{port}/v1{path} {body}".format(method=method, scheme=self.scheme, host=self.host, port=self.port, path=path, body=body))
        url = QtCore.QUrl("{scheme}://{host}:{port}/v1{path}".format(scheme=self.scheme, host=self.host, port=self.port, path=path))
        request = self._request(url)
        request.setRawHeader("Content-Type", "application/json")
        request.setRawHeader("Content-Length", str(len(body)))
        request.setRawHeader("User-Agent", "GNS3 QT Client v{version}".format(version=__version__))

        if method == "GET":
            response = self._network_manager.get(request)

        if method == "PUT":
            body = json.dumps(body)
            request.setRawHeader("Content-Type", "application/json")
            request.setRawHeader("Content-Length", str(len(body)))
            response = self._network_manager.put(request, body)

        if method == "POST":
            body = json.dumps(body)
            request.setRawHeader("Content-Type", "application/json")
            request.setRawHeader("Content-Length", str(len(body)))
            response = self._network_manager.post(request, body)

        if method == "DELETE":
            response = self._network_manager.deleteResource(request)

        response.finished.connect(partial(self._processResponse, response, callback, context))

        if HTTPClient._progress_callback and HTTPClient._progress_callback.progress_dialog():
            request_canceled = partial(self._requestCanceled, response, context)
            HTTPClient._progress_callback.progress_dialog().canceled.connect(request_canceled)