Manual redirect handling for QNetworkReply
-
I'm using QNetworkAccessManager to download some data: that data requires two redirects from the original url, one of which is to a different subdomain, so I have to use the UserVerifiedRedirectPolicy, since SameOriginRedirectPolicy won't follow that redirect. I am doing something horribly wrong, though, because I seem to be somehow doubling up on my network request and getting the data twice (at least, I think that's what's happening).
I don't quite know what questions I need to ask to figure out where things are going wrong, but my first question is: the documentation states: "Client decides whether to follow each redirect by handling the redirected() signal, emitting redirectAllowed() on the QNetworkReply object to allow the redirect or aborting/finishing it to reject the redirect. "
So I have a QNetworkReply, it's emitting the redirected() signal. When the reply gets created, I connect that signal to a function that accepts the redirect URL. In that function, what is the expected way for me to get access to the QNetworkReply object that I am supposed to be emitting the redirectAllowed() signal on?
Here's the code as it stands now, using a pretty sketchy lambda to attach a reference to the reply to the signal handler:
reply = self.QNAM.get(item.request) self.replies[item.index] = reply reply.redirected.connect(lambda url, r=reply: self.__on_redirect(r, url))And my handler:
def __on_redirect(self, reply, url): # For now just blindly follow all redirects reply.redirectAllowed.emit() print(f"Redirected from {reply.url()} to {url}\n")I get the expected printouts, following the redirect. But the function that gets called when data is available to be read is getting way too much data, and while the file starts out fine, midway through it starts to be corrupted, I believe by a second copy of itself. If I manually eliminate the redirects it all works perfectly.
-
Hi,
Can you provide the full code with handling of the downloaded data ?
-
The whole class is here: https://github.com/FreeCAD/FreeCAD/blob/0ead5a793b03be17bebd603c6c19a905bc636796/src/Mod/AddonManager/NetworkManager.py
I can't tell if the problem is really in my handling of the threading, or if I'm using the redirectAllowed signal incorrectly (or both!). If I print out the thread handle in the function attached to readyRead, the version using the signal shows me two different threads trying to read the data (obviously not good!). If instead of emitting that signal, I tell that reply to abort and replace it with a new one, that works fine. So I've got a workaround now, but I'd love to see how someone else implements this type of redirect handling, because this seems very clunky to me.