ComputerWhiz
ComputerWhiz

Reputation: 193

How to get Android HttpURLConnection to handle a redirect

I'm making an app that basically downloads an image from the URL that I define and save it to the user's device. I'm doing this with:

 URL url = new URL("http://speedtest.clotheslinedigital.com");
 HttpURLConnection c = (HttpURLConnection) url.openConnection();
 c.setRequestMethod("GET");
 c.connect();

And then after checking that the storage is working properly and creating a blank file to save onto the device, I use a file output stream and an input stream to download the file to the device.

For testing purposes, I've just been using a Dropbox download link to an image and it's been working perfectly. However, in production, I want to use a DNS subdomain redirect to link to the file, instead of a hardcoded link in my app so that I don't have to update the app if I change the path to the file that the app needs to download.

For testing, I set a 301 redirect through my Godaddy DNS that redirects to the Dropbox link that I was using hardcoded for testing. The subdomain works perfectly when I enter the subdomain on my browser, but when I hardcore the subdomain URL into my app, nothing is downloaded and it just leaves behind a blank file (the one that was made after the request to be used to store the downloaded file).

I've tried using setFollowRedirects() and setting it to true, which I believe is the default but I tried anyway, and it still fails.

I thought maybe the issue was that the HttpURLConnection could not handle 301 response codes from the server, but I looked at the header of the Dropbox link and it 301 redirects the app a couple of times before downloading the file without issues.

Any ideas on how to fix this?

Upvotes: 0

Views: 1161

Answers (1)

ComputerWhiz
ComputerWhiz

Reputation: 193

After some more research, it seems that I have to manually handle the redirect in my code. I basically did this by listening to the connection request's response code. If it's a 301 or 302 for a redirect, I have to grab the Location field from the header and feed that through the connection instead.

This is my code to do that:

boolean isRedirect;
do {
    if (c.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || c.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP) {
        isRedirect = true;
        String newURL = c.getHeaderField("Location");
        c = (HttpURLConnection) new URL(newURL).openConnection();
    } else {
        isRedirect = false;
    }
} while (isRedirect);

It's not necessary to encase the whole thing in an kind of loop, but doing so will allow the code to work properly, even if you have multiple redirects that need to be handled.

Upvotes: 3

Related Questions