WebBrowserComponent::pageAboutToLoad and HTTP 302 Redirects


#1

Hi,

when the WebBrowserComponent hits a URL (say http://localhost/redirect) that returns a 302 redirect
to another URL (http://localhost/test) the pageAboutToLoad gets called with the original URL (http://localhost/redirect) instead of the URL that gets loaded (http://localhost/test).

I’m testing this with juce 1.54.27 on OS X 10.6.8.

Let me know if you need more specific infos.

Thanks!
Johannes


#2

Not sure what you want me to do about that - the callback will just contain whatever URL the browser decides to supply, it’s not the kind of thing where I can flip a switch and change its behaviour…


#3

Sorry, I’m not familiar with the internals of juce or the webbrowsercomponent.
So you agree that the behavior is wrong but there is not much to do about it on the juce side?

If that’s the case do you have a suggestion for a workaround to access the actual URL that’s about to be loaded?
(I’ve tried with lastHeaders which should contain the Location header of the 302. But it seems to be empty)

Thanks
Johannes


#4

I don’t really know - it’s not an issue I’ve ever considered, and don’t really have an opinion on whether it’s “right” or “wrong”. Best thing might be to step through the code and watch what the browser object is doing, you might be able to spot something you could try.


#5

Aha:

juce_mac_WebBrowserComponent.mm:70:
NSURL* url = [actionInformation valueForKey: nsStringLiteral (“WebActionOriginalURLKey”)];
if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))…

That will set the URL to the original URL not the URL that is about to be loaded (which can be accessed through [request URL]).
From the naming ( pageAboutToLoad(const String& newURL) ) I would expect that newURL is set to the new URL that is about to be loaded.

Do you agree that this is a bug?

I tried to figure out in which way the win32 implementation behaves but wasn’t able to :frowning: (Sorry I’m not a C/C++ guy)

Cheers
Johannes


#6

…well, not really. I can’t really see anything wrong with getting the original URL. Changing the behaviour risks breaking other people’s code, so you’d need to give me a seriously good argument as to why I’d want to do so.


#7

Well isn’t the naming of pageAboutToLoad(const String& newURL) a good enough argument.
It clearly says that it’s passing the new URL and not the one that is triggering the loading (either by user action or an automatic redirect).

Just to explain my usecase:
I want to implement an OAuth client and have to catch a redirect to a specific URI protocol before that gets handled by the browser.
pageAboutToLoad is the perfect fit for that if it would behave like I would expect it.

Johannes


#8

Hmm. Not convinced. The callback is designed to give the option of cancelling the navigation before it happens, by returning ‘false’. To know that there’s a redirect involved, the page would already have to have been loaded before the callback happens, so how could it be cancelled? I guess you could argue that the callback should happen twice, but it’s really not the way the method was intended to be used…


#9

But the callback is already now called twice (since a redirect is another navigation). But the second call will still pass the first URL.
Here is the current behavior:

browser->goToURL(“http://abc.com/123”);
// will trigger pageAboutToLoad(“http://abc.com/123”). cool.
// browser navigates to “http://abc.com/123
// “http://abc.com/123” returns a 302 Location: “http://abc.com/somewhere-else
// will trigger pageAboutToLoad(“http://abc.com/123”). not cool. I already know where I am. What I want to know is the newURL that get’s loaded.

Correct behavior would be:

browser->goToURL(“http://abc.com/123”);
// will trigger pageAboutToLoad(“http://abc.com/123”)
// browser navigates to “http://abc.com/123
// “http://abc.com/123” returns a 302 Location: “http://abc.com/somewhere-else
// will trigger pageAboutToLoad(“http://abc.com/somewhere-else”). cool!

I think the current documentation and naming is quite clearly describing this
"This callback is called when the browser is about to navigate to a new location."
And a Redirect is nothing else than telling the browser to navigate to a new/different location.

And to be honest I don’t see any practical use of a pageAboutToLoad callback that passes the original URL.


#10

Ok, well if the current behaviour is to call it with the same thing twice, that’s a different matter! I haven’t time to test and fix this myself at the moment, but nag me about it if I don’t look at it soon-ish.

I did a project some time ago where it used specially-named URLs that made the app trigger special tasks when someone clicked on certain links. The app looked at the URL, checked it for its special embedded tags, and then followed it. Those links might have been redirects (I can’t remember), but it was the original URL that the app needed to see, not the destination.

Anyway, it doesn’t matter whether you can think of a use for something. If changing a long-established behaviour could break people’s code, then it’s not an option when you’re writing a library.


#11

If that’s your site that you’re accessing, you can make it work by changing the redirection to ifram or image source.
Then you will get the right URL at pageAboutToLoad().

If I remember correctly the reason that you don’t get the right URL while doing a regular redirection is because
you need to set a special redirection value in the underlining web components (IWebBrowser2, …) that its default value is false.