169 lines
3.7 KiB
Java
169 lines
3.7 KiB
Java
/*
|
|
* Copyright 2014 A.C.R. Development
|
|
*/
|
|
package acr.browser.lightning;
|
|
|
|
import java.util.Locale;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import static android.util.Patterns.GOOD_IRI_CHAR;
|
|
|
|
/**
|
|
* Web Address Parser
|
|
*
|
|
* This is called WebAddress, rather than URL or URI, because it attempts to
|
|
* parse the stuff that a user will actually type into a browser address widget.
|
|
*
|
|
* Unlike java.net.uri, this parser will not choke on URIs missing schemes. It
|
|
* will only throw a ParseException if the input is really hosed.
|
|
*
|
|
* If given an https scheme but no port, fills in port
|
|
*/
|
|
public class WebAddress {
|
|
|
|
private String mScheme;
|
|
private String mHost;
|
|
private int mPort;
|
|
private String mPath;
|
|
private String mAuthInfo;
|
|
static final int MATCH_GROUP_SCHEME = 1;
|
|
static final int MATCH_GROUP_AUTHORITY = 2;
|
|
static final int MATCH_GROUP_HOST = 3;
|
|
static final int MATCH_GROUP_PORT = 4;
|
|
static final int MATCH_GROUP_PATH = 5;
|
|
static Pattern sAddressPattern = Pattern.compile(
|
|
/* scheme */"(?:(http|https|file)\\:\\/\\/)?" +
|
|
/* authority */"(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
|
|
/* host */"([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" +
|
|
/* port */"(?:\\:([0-9]*))?" +
|
|
/* path */"(\\/?[^#]*)?" +
|
|
/* anchor */".*", Pattern.CASE_INSENSITIVE);
|
|
|
|
/**
|
|
* Parses given URI-like string.
|
|
*/
|
|
public WebAddress(String address) {
|
|
|
|
if (address == null) {
|
|
throw new IllegalArgumentException("address can't be null");
|
|
}
|
|
|
|
mScheme = "";
|
|
mHost = "";
|
|
mPort = -1;
|
|
mPath = "/";
|
|
mAuthInfo = "";
|
|
|
|
Matcher m = sAddressPattern.matcher(address);
|
|
String t;
|
|
if (!m.matches()) {
|
|
throw new IllegalArgumentException("Parsing of address '" + address + "' failed");
|
|
}
|
|
|
|
t = m.group(MATCH_GROUP_SCHEME);
|
|
if (t != null) {
|
|
mScheme = t.toLowerCase(Locale.ROOT);
|
|
}
|
|
t = m.group(MATCH_GROUP_AUTHORITY);
|
|
if (t != null) {
|
|
mAuthInfo = t;
|
|
}
|
|
t = m.group(MATCH_GROUP_HOST);
|
|
if (t != null) {
|
|
mHost = t;
|
|
}
|
|
t = m.group(MATCH_GROUP_PORT);
|
|
if (t != null && !t.isEmpty()) {
|
|
// The ':' character is not returned by the regex.
|
|
try {
|
|
mPort = Integer.parseInt(t);
|
|
} catch (NumberFormatException ex) {
|
|
throw new RuntimeException("Parsing of port number failed", ex);
|
|
}
|
|
}
|
|
t = m.group(MATCH_GROUP_PATH);
|
|
if (t != null && !t.isEmpty()) {
|
|
/*
|
|
* handle busted myspace frontpage redirect with missing initial "/"
|
|
*/
|
|
if (t.charAt(0) == '/') {
|
|
mPath = t;
|
|
} else {
|
|
mPath = '/' + t;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Get port from scheme or scheme from port, if necessary and possible
|
|
*/
|
|
if (mPort == 443 && "".equals(mScheme)) {
|
|
mScheme = "https";
|
|
} else if (mPort == -1) {
|
|
if ("https".equals(mScheme)) {
|
|
mPort = 443;
|
|
} else {
|
|
mPort = 80; // default
|
|
}
|
|
}
|
|
if ("".equals(mScheme)) {
|
|
mScheme = "http";
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
|
|
String port = "";
|
|
if ((mPort != 443 && "https".equals(mScheme)) || (mPort != 80 && "http".equals(mScheme))) {
|
|
port = ':' + Integer.toString(mPort);
|
|
}
|
|
String authInfo = "";
|
|
if (!mAuthInfo.isEmpty()) {
|
|
authInfo = mAuthInfo + '@';
|
|
}
|
|
|
|
return mScheme + "://" + authInfo + mHost + port + mPath;
|
|
}
|
|
|
|
public void setScheme(String scheme) {
|
|
mScheme = scheme;
|
|
}
|
|
|
|
public String getScheme() {
|
|
return mScheme;
|
|
}
|
|
|
|
public void setHost(String host) {
|
|
mHost = host;
|
|
}
|
|
|
|
public String getHost() {
|
|
return mHost;
|
|
}
|
|
|
|
public void setPort(int port) {
|
|
mPort = port;
|
|
}
|
|
|
|
public int getPort() {
|
|
return mPort;
|
|
}
|
|
|
|
public void setPath(String path) {
|
|
mPath = path;
|
|
}
|
|
|
|
public String getPath() {
|
|
return mPath;
|
|
}
|
|
|
|
public void setAuthInfo(String authInfo) {
|
|
mAuthInfo = authInfo;
|
|
}
|
|
|
|
public String getAuthInfo() {
|
|
return mAuthInfo;
|
|
}
|
|
}
|