smanikandan14 / ThinDownloadManager

To download files and to avoid using DOWNLOAD_WITHOUT_NOTIFICATION permission if you are using Android's DownloadManager in your apps.
Apache License 2.0
783 stars 186 forks source link

Error:MalformedURLException: URI passed is malformed. #65

Open yuvalken opened 8 years ago

yuvalken commented 8 years ago

I get a onFail callback when trying to download from link. I've checked this link with:

try {
                url = new URL(downloadLink);
            } catch (MalformedURLException e) {
                System.out.println("The URL is not valid.");
                System.out.println(e.getMessage());
            }

and the link isn't malformed at all, it's just already encoded. If the library is doing extra encoding that might cause the problem but I haven't seen where it's done. here's an example link: http://www.youtubeinmp3.com/download/get/?i=FmmPZJEYZxOxfh1gkEGv24eLM3Cy%2FXCXSjRXI0FzkCkOBkefF1DV78B8cMWtpsaujT8ul9AZ1FFltO1uj436rQ%3D%3D

yuvalken commented 8 years ago

Ok, I finally got it... For some reason I get response code "HTTP_TEMP_REDIRECT" for the first time I try to download. I receive a new URL for that specific download, which parsed from connection headers: String location = conn.getHeaderField("Location");

Than the library calls executeDownload(location);

There's no check upon this new link - no encoding and it misses a protocol ("http:"). So I added this checks after getting the location header:

if (!location.startsWith("http")){
                            location = "http:" + location;
                        }

                        try {
                            location = URLDecoder.decode(location, "UTF-8");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }

                        executeDownload(location);

and also at the executeDownload function:

URL url;
        try {
            url = new URL(downloadUrl);
            URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
            url = uri.toURL();
            Log.d("DownloadDispatcher","Final url: " + url.toString());
        } catch (MalformedURLException e) {
            updateDownloadFailed(DownloadManager.ERROR_MALFORMED_URI,"MalformedURLException: URI passed is malformed.");
            return;
        } catch (URISyntaxException e) {
            e.printStackTrace();
            updateDownloadFailed(DownloadManager.ERROR_MALFORMED_URI, "MalformedURLException: URI passed is malformed.");
            return;
        }

You should add this to, this broke my app for more than 2 weeks and only when I dive in to the library I saw that I get a new link instead of the link I;m sending and thats cause the issues.

smanikandan14 commented 8 years ago

@yuvalken After browsing little more about http status codes 301/307 the response header "Location:" should always be a absolute URL, that is a fully qualified URL with scheme (http|https), server name (domain|subdomain), and path (directory/file name) plus the optional query string (”?” followed by variable/value pairs like ?id=1&page=2...). In your case, i think it is a relative URL. Thats why "http/https" scheme is missing.

You should fix this on server side. Let me know what you think about this.

kndl22 commented 8 years ago

I get your point... It's probably a unique case with the api I'm using and there isn't a generic solution. You can mention in the project comments that if someone else face this - they should be aware of this redirect and "location" property

smanikandan14 commented 8 years ago

sure. will do.

mrStudent123 commented 7 years ago

The RFC norm specifies that also relative links in the location header are allowed at certain status codes. This definitely is an issue with this library that is hard to detect. If you can please have a detailed look at the specification for the 3xx statuscodes.