def request_obj(self, url, headers=None, body=None): """ Return a QNetworkRequest object """ request = QNetworkRequest() request.setUrl(to_qurl(url)) request.setOriginatingObject(self.web_page.mainFrame()) if headers is not None: self.web_page.skip_custom_headers = True self._set_request_headers(request, headers) if body and not request.hasRawHeader(b"content-type"): # there is POST body but no content-type # QT will set this header, but it will complain so better to do this here request.setRawHeader(b"content-type", b"application/x-www-form-urlencoded") return request
def GM_xmlhttpRequest(self, details): # we could actually mock a XMLHttpRequest to support progress # signals but who really uses them? # https://wiki.greasespot.net/GM_xmlhttpRequest # qtwebchannel.js calls JSON.stringify in QWebChannel.send() so any # method attributes of arguments (eg {'onload':function(...){...;}) are # stripped. # * handle method, url, headers, data # * figure out what headers we need to automatically set (referer, ...) # * can we use some qt thing (page.get()?) to do ^ # * should probably check how cookies are handled # chrome/tampermonkey sends cookies (for the requested domain, # duh) with GM_xhr requests # https://openuserjs.org/ # https://greasyfork.org/en/scripts # tampermoney on chrome prompts when a script tries to do a # cross-origin request. print("==============================================") print("GM_xmlhttpRequest") print(details) if not 'url' in details: return request_index = details['_qute_gm_request_index'] if not request_index: log.greasemonkey.error(("GM_xmlhttpRequest received request " "without nonce, skipping.")) return if objreg.get('host-blocker').is_blocked(QUrl(details['url'])): return # TODO: url might be relative, need to fix on the JS side. request = QNetworkRequest(QUrl(details['url'])) request.setOriginatingObject(self) # The C++ docs say the default is to not follow any redirects. request.setAttribute(QNetworkRequest.RedirectionTargetAttribute, QNetworkRequest.NoLessSafeRedirectPolicy) # TODO: Ensure these headers are encoded to spec if containing eg # unicodes if 'headers' in details: for k, v in details['headers'].items(): # With this script: https://raw.githubusercontent.com/evazion/translate-pixiv-tags/master/translate-pixiv-tags.user.js # One of the headers it 'X-Twitter-Polling': True, which was # causing the below to error out because v is a bool. Not sure # where that is coming from or what value twitter expects. # That script is patching jquery so try with unpatched jquery # and see what it does. request.setRawHeader(k.encode('ascii'), str(v).encode('ascii')) # TODO: Should we allow xhr to set user-agent? if not request.header(QNetworkRequest.UserAgentHeader): request.setHeader(QNetworkRequest.UserAgentHeader, self.profile.httpUserAgent()) payload = details.get('data', None) if payload: # Should check encoding from content-type header? payload = payload.encode('utf-8') reply = self.nam.sendCustomRequest( request, details.get('method', 'GET').encode('ascii'), payload) if reply.isFinished(): self.handle_xhr_reply(reply, request_index) else: reply.finished.connect( functools.partial(self.handle_xhr_reply, reply, request_index))