0

The following piece of code should print out the new location of a website that uses the Location header to redirect to a new page/file (http://somepagethatredirects.me/after.txt):

URL website = new URL("http://somepagethatredirects.me/before.txt");
URLConnection urlConnection = website.openConnection();
System.out.println(urlConnection.getURL());

Even though we expect the location to be http://somepagethatredirects.me/after.txt, we get the URL parameter specified.

Adding a (seemingly unconnected) method like urlConnection.getHeaderField("Location"), urlConnection.getHeaderFields() or even urlConnection.getExpiration() will (strangely) give us the expected result:

URL website = new URL("http://somepagethatredirects.me/before.txt");
URLConnection urlConnection = website.openConnection();
urlConnection.getHeaderFields();
System.out.println(urlConnection.getURL());

Is this intended behaviour? It seems like a bug to me.


Edit 1: As Jeffrey Bosbom pointed out, calling urlConnection.openConnection() doesn't actually establish a connection to the server, urlConnection.connect() does (or other methods that imply an active connection). This doesn't change the program's output however:

URL website = new URL("http://somepagethatredirects.me/before.txt");
URLConnection urlConnection = website.openConnection();
urlConnection.connect();
System.out.println(urlConnection.getURL());
linkD
  • 121
  • 13
  • @JeffreyBosboom good idea, but `urlConnection.connect()` doesn't "update" the URL either, I just checked it. I'll add it to the methods in the question and write another piece of example code. – linkD Jan 01 '17 at 23:57
  • [URLConnection.getURL()](https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getURL()) returns the the original url which you connect to, not the `Location` header, you can't read anything from the url which you are connecting to until you have established a connection by calling `connect` – Trash Can Jan 02 '17 at 00:28
  • @Dummy I don't get why `urlConnection.getURL()` returns the new URL I've been redirected to after calling `urlConnection.getHeaderFields()` or `urlConnection.getExpiration()` then, though. – linkD Jan 02 '17 at 00:37
  • That is strange because the behaviour is not consistent with the API docs, you might wanna peek into the source for those methods to see what's really going on. But `getURL()` should never return anything other than the original url you connected to as per the docs .e.g. it returns the protected field url passed to `URLConnection` class constructor – Trash Can Jan 02 '17 at 00:44
  • @Dummy as you can read in the original question, I was wondering the same; I didn't expect to see those results. You can try and execute it on your own PC with some page that does a `Location` redirect. For some odd reason, `urlConnection.getHeaderFields()` or any methods I listed seem to modify the URL field. – linkD Jan 02 '17 at 00:52
  • I would like to test this out if Im not on my tablet. But could you insert a call to `connect()` after `urlConnection.getHeaderFields()` to see if you get any error? – Trash Can Jan 02 '17 at 00:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132043/discussion-between-linkd-and-dummy). – linkD Jan 02 '17 at 01:03

1 Answers1

0

Nothing happens in terms of HTTP transactions until you either:

  • get the response code
  • open the input stream
  • open the error stream.

I'm not sure that even after that you have any basis for expecting getURL() to deliver the final target URL.

user207421
  • 305,947
  • 44
  • 307
  • 483