Aymon Fournier Aymon Fournier - 6 months ago 82
Android Question

HttpClient redirecting to URL with spaces throwing exception

I am accessing a URL that's redirecting me to a URL with spaces in it. (Using HttpClient 4.x) How do I prevent this from throwing an error (replacing the spaces with %20 not +)

08-06 02:45:56.486: WARN/System.err(655): org.apache.http.client.ClientProtocolException
08-06 02:45:56.493: WARN/System.err(655): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:557)
08-06 02:45:56.534: WARN/System.err(655): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
08-06 02:45:56.603: WARN/System.err(655): at com.romcessed.romsearch.searchproviders.DopeRomsConnector$DownloadROMTask.doInBackground(DopeRomsConnector.java:636)
08-06 02:45:56.623: WARN/System.err(655): at com.romcessed.romsearch.searchproviders.DopeRomsConnector$DownloadROMTask.doInBackground(DopeRomsConnector.java:1)
08-06 02:45:56.643: WARN/System.err(655): at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-06 02:45:56.663: WARN/System.err(655): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-06 02:45:56.683: WARN/System.err(655): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-06 02:45:56.693: WARN/System.err(655): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-06 02:45:56.713: WARN/System.err(655): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-06 02:45:56.713: WARN/System.err(655): at java.lang.Thread.run(Thread.java:1096)
08-06 02:45:56.743: WARN/System.err(655): Caused by: org.apache.http.ProtocolException: Invalid redirect URI: http://somewebsite.com/some file with spaces.zip
08-06 02:45:56.787: WARN/System.err(655): at org.apache.http.impl.client.DefaultRedirectHandler.getLocationURI(DefaultRedirectHandler.java:116)
08-06 02:45:56.803: WARN/System.err(655): at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:892)
08-06 02:45:56.813: WARN/System.err(655): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:457)
08-06 02:45:56.843: WARN/System.err(655): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-06 02:45:56.843: WARN/System.err(655): ... 9 more
08-06 02:45:56.873: WARN/System.err(655): Caused by: java.net.URISyntaxException: Illegal character in path at index #: http://somewebsite.com/some file with spaces.zip
08-06 02:45:56.913: WARN/System.err(655): at java.net.URI$Helper.validatePath(URI.java:448)
08-06 02:45:56.923: WARN/System.err(655): at java.net.URI$Helper.parseURI(URI.java:398)
08-06 02:45:56.953: WARN/System.err(655): at java.net.URI$Helper.access$100(URI.java:302)
08-06 02:45:56.963: WARN/System.err(655): at java.net.URI.<init>(URI.java:87)
08-06 02:45:56.993: WARN/System.err(655): at org.apache.http.impl.client.DefaultRedirectHandler.getLocationURI(DefaultRedirectHandler.java:114)
08-06 02:45:57.013: WARN/System.err(655): ... 12 more

Answer

The Apache HTTP library allows you to register a RedirectHandler object that will get invoked whenever a redirect occurs. You can use this to intercept the redirect and fix it.

(That being said, the site that's sending you this redirect is broken. You should contact them and let them know.)

class CustomRedirectHandler extends DefaultRedirectHandler {
    public URI getLocationURI(HttpResponse response, HttpContext context) {
        // Extract the Location: header and manually convert spaces to %20's
        // Return the corrected URI
    }
}

DefaultHttpClient httpClient = new DefaultHttpClient();
RedirectHandler customRedirectHandler = new CustomRedirectHandler();
//...
httpClient.setRedirectHandler(customRedirectHandler);