Skip to content

Commit

Permalink
Implemented a workaround for Issue #74 where URI.getHost() returns nu…
Browse files Browse the repository at this point in the history
…ll on some Samsung devices.
  • Loading branch information
TakahikoKawasaki committed Aug 19, 2016
1 parent c212dc7 commit 47498fe
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 1 deletion.
82 changes: 82 additions & 0 deletions src/main/java/com/neovisionaries/ws/client/Misc.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


class Misc
Expand Down Expand Up @@ -305,4 +308,83 @@ private static void join(StringBuilder builder, Collection<?> values, String del
builder.append(value.toString());
}
}


public static String extractHost(URI uri)
{
// Extract the host part from the URI.
String host = uri.getHost();

if (host != null)
{
return host;
}

// According to Issue#74, URI.getHost() method returns null in
// the following environment when the host part of the URI is
// a host name.
//
// - Samsung Galaxy S3 + Android API 18
// - Samsung Galaxy S4 + Android API 21
//
// The following is a workaround for the issue.

// Extract the host part from the authority part of the URI.
host = extractHostFromAuthorityPart(uri.getRawAuthority());

if (host != null)
{
return host;
}

// Extract the host part from the entire URI.
return extractHostFromEntireUri(uri.toString());
}


static String extractHostFromAuthorityPart(String authority)
{
// If the authority part is not available.
if (authority == null)
{
// Hmm... This should not happen.
return null;
}

// Parse the authority part. The expected format is "[id:password@]host[:port]".
Matcher matcher = Pattern.compile("^(.*@)?([^:]+)(:\\d+)?$").matcher(authority);

// If the authority part does not match the expected format.
if (matcher == null || matcher.matches() == false)
{
// Hmm... This should not happen.
return null;
}

// Return the host part.
return matcher.group(2);
}


static String extractHostFromEntireUri(String uri)
{
if (uri == null)
{
// Hmm... This should not happen.
return null;
}

// Parse the URI. The expected format is "scheme://[id:password@]host[:port][...]".
Matcher matcher = Pattern.compile("^\\w+://([^@/]*@)?([^:/]+)(:\\d+)?(/.*)?$").matcher(uri);

// If the URI does not match the expected format.
if (matcher == null || matcher.matches() == false)
{
// Hmm... This should not happen.
return null;
}

// Return the host part.
return matcher.group(2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ public WebSocket createSocket(URI uri, int timeout) throws IOException
// Split the URI.
String scheme = uri.getScheme();
String userInfo = uri.getUserInfo();
String host = uri.getHost();
String host = Misc.extractHost(uri);
int port = uri.getPort();
String path = uri.getRawPath();
String query = uri.getRawQuery();
Expand Down
232 changes: 232 additions & 0 deletions src/test/java/com/neovisionaries/ws/client/MiscTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/*
* Copyright (C) 2016 Neo Visionaries Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.neovisionaries.ws.client;


import static org.junit.Assert.assertEquals;
import java.net.URI;
import org.junit.Test;


public class MiscTest
{
private static void extractHostTest(String expected, String input)
{
URI uri = URI.create(input);

String result = Misc.extractHost(uri);

assertEquals(expected, result);
}


private static void extractHostFromAuthorityPartTest(String expected, String input)
{
String result = Misc.extractHostFromAuthorityPart(input);

assertEquals(expected, result);
}


private static void extractHostFromEntireUriTest(String expected, String input)
{
String result = Misc.extractHostFromEntireUri(input);

assertEquals(expected, result);
}


@Test
public void test01()
{
extractHostFromAuthorityPartTest("example.com", "example.com");
}


@Test
public void test02()
{
extractHostFromAuthorityPartTest("example.com", "example.com:8080");
}


@Test
public void test03()
{
extractHostFromAuthorityPartTest("example.com", "id:password@example.com");
}


@Test
public void test04()
{
extractHostFromAuthorityPartTest("example.com", "id:password@example.com:8080");
}


@Test
public void test05()
{
extractHostFromAuthorityPartTest("example.com", "id@example.com");
}


@Test
public void test06()
{
extractHostFromAuthorityPartTest("example.com", "id:@example.com");
}


@Test
public void test07()
{
extractHostFromAuthorityPartTest("example.com", ":@example.com");
}


@Test
public void test08()
{
extractHostFromAuthorityPartTest("example.com", ":password@example.com");
}


@Test
public void test09()
{
extractHostFromAuthorityPartTest("example.com", "@example.com");
}


@Test
public void test10()
{
extractHostFromEntireUriTest("example.com", "ws://example.com");
}


@Test
public void test11()
{
extractHostFromEntireUriTest("example.com", "ws://example.com:8080");
}


@Test
public void test12()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com");
}


@Test
public void test13()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com:8080");
}


@Test
public void test14()
{
extractHostFromEntireUriTest("example.com", "ws://example.com/");
}


@Test
public void test15()
{
extractHostFromEntireUriTest("example.com", "ws://example.com:8080/");
}


@Test
public void test16()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com/");
}


@Test
public void test17()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com:8080/");
}


@Test
public void test18()
{
extractHostFromEntireUriTest("example.com", "ws://example.com/path?key=@value");
}


@Test
public void test19()
{
extractHostFromEntireUriTest("example.com", "ws://example.com:8080/path?key=@value");
}


@Test
public void test20()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com/path?key=@value");
}


@Test
public void test21()
{
extractHostFromEntireUriTest("example.com", "ws://id:password@example.com:8080/path?key=@value");
}


@Test
public void test22()
{
extractHostTest("example.com", "ws://example.com");
}


@Test
public void test23()
{
extractHostTest("example.com", "ws://example.com:8080");
}


@Test
public void test24()
{
extractHostTest("example.com", "ws://id:password@example.com");
}


@Test
public void test25()
{
extractHostTest("example.com", "ws://id:password@example.com:8080");
}


@Test
public void test26()
{
extractHostTest("example.com", "ws://id:password@example.com:8080/path?key=@value");
}
}

0 comments on commit 47498fe

Please sign in to comment.