Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem extracting port number with URL.getPort() when URL contains "]"

Tags:

java

android

url

I'm using java.net.URL.getPort() to extract the port number from a URL. Most of the time this works great. However, when the URL contains a right bracket character "]" it fails:

new URL("http://abc.com:123/abc.mp3").getPort();
 returns: (int) 123

But if the URL contains "]" I get:

new URL("http://abc.com:123/abc].mp3").getPort();
 returns: (int) -1

What am I doing wrong?

EDIT #1: As a test, I pasted this same code into a non-Android Java app and the port number was correctly returned, so this appears to be an anomaly with the Android SDK.

like image 838
Mike Lowery Avatar asked Feb 26 '23 06:02

Mike Lowery


2 Answers

If your URL contains some symbols that are not valid in URLs, you have to use an URL-encoded String. They way to do it in Java seem to be by using URI.

new URI( "http", null, "abc.com", 123, "abc].mp3", null, null).toURL().getPort();

If you already has an URL string:

URL url = new URL("http://abc.com:123/abc].mp3");

Then this works for me:

new URI(
    url.getProtocol(),
    null,
    url.getHost(),
    url.getPort(),
    url.getPath(),
    null,
    null);

But then again I'm using url.getPort() that you said didn't work. But when I'm testing on Java 6 now. new URL("http://abc.com:123/abc].mp3").getPort(); actually works for me, maybe it's just on Android it doesn't work? In case it doesn't work I think it's best to use a third party library for this. Apache Http Client that is included in Android seem to have some extra functionality for URLs: see org.apache.http.client.utils

See also HTTP URL Address Encoding in Java

like image 108
Jonas Avatar answered Apr 27 '23 11:04

Jonas


"http://abc.com:123/abc].mp3"

] is not allowed in the path part of a URI, so this is not a URL. However, you can modify the regular expression in the spec to get this information:

    //TODO: import java.util.regex.*;
    String expr = "^(([^:/?#]+):)?(//([^:/?#]*):([\\d]*))?";
    Matcher matcher = Pattern.compile(expr)
                             .matcher("http://abc.com:123/abc].mp3");
    if (matcher.find()) {
      String port = matcher.group(5);
      System.out.println(port);
    }

Despite the name, URLEncoder doesn't encode URLs. It should only be used to encode parameters in the query part when the server is expecting application/x-www-form-urlencoded encoded data. The URI and URL classes behave as documented - they aren't going to help you here.

like image 37
McDowell Avatar answered Apr 27 '23 11:04

McDowell