def api_get_request(self): logger.debug("\n------------------ Sending request ------------------") # creating credentials header logger.debug("Creating credentials header") crd_header_value = QByteArray() crd_header_value.append(self.token) crd_header_name = QByteArray() crd_header_name.append("Authorization") # creating request rqst = QNetworkRequest(QUrl(self.request_url)) logger.debug("Creating request : {}".format(rqst.url())) # setting credentials header rqst.setRawHeader(crd_header_name, crd_header_value) logger.debug("Setting credentials header : {}".format( rqst.rawHeader(crd_header_name))) # sending request rqst_reply = self.naMngr.get(rqst) logger.debug("Sending request") rqst_reply.finished.connect( partial(self.api_handle_request, reply=rqst_reply))
def _get_decoded_credentials(self, username, password): """Extracts and decode credentials from request Authorization header""" ac = self.setUpAuth(username, password) req = QNetworkRequest(QUrl('http://none')) self.authm.updateNetworkRequest(req, ac.id()) auth = bytes(req.rawHeader(b'Authorization'))[6:] # Note that RFC7617 states clearly: User-ids containing colons cannot be encoded in user-pass strings u, p = base64.b64decode(auth).split(b':') return u.decode('utf8'), p.decode('utf8')
def api_authentification(self): logger.debug("\n------------------ Authentication ------------------") # creating credentials header logger.debug("Creating credentials header") crd_header_value = QByteArray() crd_header_value.append("Basic ") crd_header_value.append( base64.b64encode("{}:{}".format(self.app_id, self.app_secrets).encode())) crd_header_name = QByteArray() crd_header_name.append("Authorization") # creating Content-Type header logger.debug("Creating 'Content-Type' header") ct_header_value = QByteArray() ct_header_value.append("application/json") # creating request token_rqst = QNetworkRequest(QUrl(self.token_url)) logger.debug("Creating token request : {}".format(token_rqst.url())) # setting headers token_rqst.setRawHeader(crd_header_name, crd_header_value) logger.debug("Setting credentials header : {}".format( token_rqst.rawHeader(crd_header_name))) token_rqst.setHeader(token_rqst.ContentTypeHeader, ct_header_value) logger.debug("Setting 'Content-Type' header : {}".format( token_rqst.header(token_rqst.ContentTypeHeader))) # creating data data = QByteArray() data.append(urlencode({"grant_type": "client_credentials"})) logger.debug("Creating data : {}".format(data)) # requesting and handle reply logger.debug("Asking for token") token_reply = self.naMngr.post(token_rqst, data) token_reply.finished.connect( partial(self.api_handle_token, reply=token_reply))
def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None, blocking=True): """ Make a network request by calling QgsNetworkAccessManager. redirections argument is ignored and is here only for httplib2 compatibility. """ self.msg_log(u'http_call request: {0}'.format(url)) self.blocking_mode = blocking req = QNetworkRequest() # Avoid double quoting form QUrl url = urllib.parse.unquote(url) req.setUrl(QUrl(url)) if headers is not None: # This fixes a wierd error with compressed content not being correctly # inflated. # If you set the header on the QNetworkRequest you are basically telling # QNetworkAccessManager "I know what I'm doing, please don't do any content # encoding processing". # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1 try: del headers['Accept-Encoding'] except KeyError: pass for k, v in list(headers.items()): self.msg_log("Setting header %s to %s" % (k, v)) if k and v: req.setRawHeader(k.encode(), v.encode()) if self.authid: self.msg_log("Update request w/ authid: {0}".format(self.authid)) self.auth_manager().updateNetworkRequest(req, self.authid) if self.reply is not None and self.reply.isRunning(): self.reply.close() if method.lower() == 'delete': func = getattr(QgsNetworkAccessManager.instance(), 'deleteResource') else: func = getattr(QgsNetworkAccessManager.instance(), method.lower()) # Calling the server ... # Let's log the whole call for debugging purposes: self.msg_log("Sending %s request to %s" % (method.upper(), req.url().toString())) self.on_abort = False headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()} for k, v in list(headers.items()): self.msg_log("%s: %s" % (k, v)) if method.lower() in ['post', 'put']: if isinstance(body, io.IOBase): body = body.read() if isinstance(body, str): body = body.encode() if isinstance(body, dict): body = str(json.dumps(body)).encode(encoding='utf-8') self.reply = func(req, body) else: self.reply = func(req) if self.authid: self.msg_log("Update reply w/ authid: {0}".format(self.authid)) self.auth_manager().updateNetworkReply(self.reply, self.authid) QgsNetworkAccessManager.instance().setTimeout(int(self.timeout) * 1000) # necessary to trap local timeout manage by QgsNetworkAccessManager # calling QgsNetworkAccessManager::abortRequest QgsNetworkAccessManager.instance().requestTimedOut.connect( self.requestTimedOut) self.reply.sslErrors.connect(self.sslErrors) self.reply.finished.connect(self.replyFinished) self.reply.downloadProgress.connect(self.downloadProgress) # block if blocking mode otherwise return immediatly # it's up to the caller to manage listeners in case of no blocking mode if not self.blocking_mode: return (None, None) # Call and block self.el = QEventLoop() self.reply.finished.connect(self.el.quit) # Catch all exceptions (and clean up requests) try: self.el.exec_(QEventLoop.ExcludeUserInputEvents) except Exception as e: raise e if self.reply: self.reply.finished.disconnect(self.el.quit) # emit exception in case of error if not self.http_call_result.ok: if self.http_call_result.exception and not self.exception_class: raise self.http_call_result.exception else: raise self.exception_class(self.http_call_result.reason) return (self.http_call_result, self.http_call_result.content)
def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None): """ Make a network request by calling QgsNetworkAccessManager. redirections argument is ignored and is here only for httplib2 compatibility. """ self.msg_log(u'http_call request: {0}'.format(url)) self.http_call_result = Response({ 'status': 0, 'status_code': 0, 'status_message': '', 'text': '', 'ok': False, 'headers': {}, 'reason': '', 'exception': None, }) req = QNetworkRequest() # Avoid double quoting form QUrl if PYTHON_VERSION >= 3: url = urllib.parse.unquote(url) else: url = urllib2.unquote(url) req.setUrl(QUrl(url)) if self.cookie is not None: if headers is not None: headers['Cookie'] = self.cookie else: headers = {'Cookie': self.cookie} if self.basicauth is not None: if headers is not None: headers['Authorization'] = self.basicauth else: headers = {'Authorization': self.basicauth} if headers is not None: # This fixes a wierd error with compressed content not being correctly # inflated. # If you set the header on the QNetworkRequest you are basically telling # QNetworkAccessManager "I know what I'm doing, please don't do any content # encoding processing". # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1 try: del headers['Accept-Encoding'] except KeyError: pass for k, v in headers.items(): if PYTHON_VERSION >= 3: if isinstance(k, str): k = k.encode('utf-8') if isinstance(v, str): v = v.encode('utf-8') req.setRawHeader(k, v) if self.authid: self.msg_log("Update request w/ authid: {0}".format(self.authid)) QgsAuthManager.instance().updateNetworkRequest(req, self.authid) if self.reply is not None and self.reply.isRunning(): self.reply.close() if method.lower() == 'delete': func = getattr(QgsNetworkAccessManager.instance(), 'deleteResource') else: func = getattr(QgsNetworkAccessManager.instance(), method.lower()) # Calling the server ... # Let's log the whole call for debugging purposes: self.msg_log("Sending %s request to %s" % (method.upper(), req.url().toString())) headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()} for k, v in headers.items(): self.msg_log("%s: %s" % (k, v)) if method.lower() in ['post', 'put']: if PYTHON_VERSION >= 3: if isinstance(body, str): body = body.encode('utf-8') self.reply = func(req, body) else: self.reply = func(req) if self.authid: self.msg_log("Update reply w/ authid: {0}".format(self.authid)) QgsAuthManager.instance().updateNetworkReply( self.reply, self.authid) self.reply.sslErrors.connect(self.sslErrors) self.reply.finished.connect(self.replyFinished) # Call and block self.el = QEventLoop() self.reply.finished.connect(self.el.quit) self.reply.downloadProgress.connect(self.downloadProgress) # Catch all exceptions (and clean up requests) try: self.el.exec_() # Let's log the whole response for debugging purposes: self.msg_log("Got response %s %s from %s" % \ (self.http_call_result.status_code, self.http_call_result.status_message, self.reply.url().toString())) headers = { str(h): str(self.reply.rawHeader(h)) for h in self.reply.rawHeaderList() } for k, v in headers.items(): self.msg_log("%s: %s" % (k, v)) if len(self.http_call_result.text) < 1024: self.msg_log("Payload :\n%s" % self.http_call_result.text) else: self.msg_log("Payload is > 1 KB ...") except Exception as e: raise e finally: if self.reply is not None: if self.reply.isRunning(): self.reply.close() self.msg_log("Deleting reply ...") self.reply.deleteLater() self.reply = None else: self.msg_log("Reply was already deleted ...") if not self.http_call_result.ok: if self.http_call_result.exception and not self.exception_class: raise self.http_call_result.exception else: raise self.exception_class(self.http_call_result.reason) return (self.http_call_result, self.http_call_result.text)
def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None, blocking=True): """ Make a network request by calling QgsNetworkAccessManager. redirections argument is ignored and is here only for httplib2 compatibility. """ self.msg_log(u'http_call request: {0}'.format(url)) self.blocking_mode = blocking req = QNetworkRequest() # Avoid double quoting form QUrl url = urllib.parse.unquote(url) req.setUrl(QUrl(url)) if headers is not None: # This fixes a wierd error with compressed content not being correctly # inflated. # If you set the header on the QNetworkRequest you are basically telling # QNetworkAccessManager "I know what I'm doing, please don't do any content # encoding processing". # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1 try: del headers['Accept-Encoding'] except KeyError: pass for k, v in list(headers.items()): self.msg_log("Setting header %s to %s" % (k, v)) req.setRawHeader(k, v) if self.authid: self.msg_log("Update request w/ authid: {0}".format(self.authid)) QgsAuthManager.instance().updateNetworkRequest(req, self.authid) if self.reply is not None and self.reply.isRunning(): self.reply.close() if method.lower() == 'delete': func = getattr(QgsNetworkAccessManager.instance(), 'deleteResource') else: func = getattr(QgsNetworkAccessManager.instance(), method.lower()) # Calling the server ... # Let's log the whole call for debugging purposes: self.msg_log("Sending %s request to %s" % (method.upper(), req.url().toString())) self.on_abort = False headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()} for k, v in list(headers.items()): self.msg_log("%s: %s" % (k, v)) if method.lower() in ['post', 'put']: if isinstance(body, file): body = body.read() self.reply = func(req, body) else: self.reply = func(req) if self.authid: self.msg_log("Update reply w/ authid: {0}".format(self.authid)) QgsAuthManager.instance().updateNetworkReply(self.reply, self.authid) # necessary to trap local timout manage by QgsNetworkAccessManager # calling QgsNetworkAccessManager::abortRequest QgsNetworkAccessManager.instance().requestTimedOut.connect(self.requestTimedOut) self.reply.sslErrors.connect(self.sslErrors) self.reply.finished.connect(self.replyFinished) self.reply.downloadProgress.connect(self.downloadProgress) # block if blocking mode otherwise return immediatly # it's up to the caller to manage listeners in case of no blocking mode if not self.blocking_mode: return (None, None) # Call and block self.el = QEventLoop() self.reply.finished.connect(self.el.quit) # Catch all exceptions (and clean up requests) try: self.el.exec_(QEventLoop.ExcludeUserInputEvents) except Exception as e: raise e if self.reply: self.reply.finished.disconnect(self.el.quit) # emit exception in case of error if not self.http_call_result.ok: if self.http_call_result.exception and not self.exception_class: raise self.http_call_result.exception else: raise self.exception_class(self.http_call_result.reason) return (self.http_call_result, self.http_call_result.content)