blob: fbc281f26ce869e99244d3e7ac4d669e366545c2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Dianne Hackborn2269d1572010-02-24 19:54:22 -080019import static android.util.Patterns.GOOD_IRI_CHAR;
Shimeng (Simon) Wang51c02db2010-02-11 14:07:44 -080020
Ignacio Solla451e3382014-11-10 10:35:54 +000021import android.annotation.SystemApi;
Mathew Inwood53f089f2018-08-08 14:44:44 +010022import android.annotation.UnsupportedAppUsage;
Mathew Inwood31755f92018-12-20 13:53:36 +000023import android.os.Build;
Ignacio Solla451e3382014-11-10 10:35:54 +000024
Elliott Hughescb64d432013-08-02 10:00:44 -070025import java.util.Locale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import java.util.regex.Matcher;
27import java.util.regex.Pattern;
28
29/**
30 * {@hide}
31 *
32 * Web Address Parser
33 *
34 * This is called WebAddress, rather than URL or URI, because it
35 * attempts to parse the stuff that a user will actually type into a
36 * browser address widget.
37 *
38 * Unlike java.net.uri, this parser will not choke on URIs missing
39 * schemes. It will only throw a ParseException if the input is
40 * really hosed.
41 *
42 * If given an https scheme but no port, fills in port
43 *
44 */
Ignacio Solla451e3382014-11-10 10:35:54 +000045// TODO(igsolla): remove WebAddress from the system SDK once the WebView apk does not
46// longer need to be binary compatible with the API 21 version of the framework.
47@SystemApi
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048public class WebAddress {
49
Mathew Inwood53f089f2018-08-08 14:44:44 +010050 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010051 private String mScheme;
Mathew Inwood53f089f2018-08-08 14:44:44 +010052 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010053 private String mHost;
Mathew Inwood31755f92018-12-20 13:53:36 +000054 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Bjorn Bringerteb8be972010-10-12 16:24:55 +010055 private int mPort;
Mathew Inwood53f089f2018-08-08 14:44:44 +010056 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010057 private String mPath;
58 private String mAuthInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60 static final int MATCH_GROUP_SCHEME = 1;
61 static final int MATCH_GROUP_AUTHORITY = 2;
62 static final int MATCH_GROUP_HOST = 3;
63 static final int MATCH_GROUP_PORT = 4;
64 static final int MATCH_GROUP_PATH = 5;
65
66 static Pattern sAddressPattern = Pattern.compile(
Patrick Scott92534462010-03-31 13:35:24 -040067 /* scheme */ "(?:(http|https|file)\\:\\/\\/)?" +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
Steve Block582deec2010-09-06 16:16:39 +010069 /* host */ "([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" +
Steve Block22574402010-03-08 17:52:02 +000070 /* port */ "(?:\\:([0-9]*))?" +
Patrick Scottfa4039e42010-02-16 16:15:55 -050071 /* path */ "(\\/?[^#]*)?" +
Patrick Scott92534462010-03-31 13:35:24 -040072 /* anchor */ ".*", Pattern.CASE_INSENSITIVE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74 /** parses given uriString. */
75 public WebAddress(String address) throws ParseException {
76 if (address == null) {
77 throw new NullPointerException();
78 }
79
80 // android.util.Log.d(LOGTAG, "WebAddress: " + address);
81
82 mScheme = "";
83 mHost = "";
84 mPort = -1;
85 mPath = "/";
86 mAuthInfo = "";
87
88 Matcher m = sAddressPattern.matcher(address);
89 String t;
90 if (m.matches()) {
91 t = m.group(MATCH_GROUP_SCHEME);
Elliott Hughescb64d432013-08-02 10:00:44 -070092 if (t != null) mScheme = t.toLowerCase(Locale.ROOT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 t = m.group(MATCH_GROUP_AUTHORITY);
94 if (t != null) mAuthInfo = t;
95 t = m.group(MATCH_GROUP_HOST);
96 if (t != null) mHost = t;
97 t = m.group(MATCH_GROUP_PORT);
Steve Block22574402010-03-08 17:52:02 +000098 if (t != null && t.length() > 0) {
99 // The ':' character is not returned by the regex.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 try {
101 mPort = Integer.parseInt(t);
102 } catch (NumberFormatException ex) {
103 throw new ParseException("Bad port");
104 }
105 }
106 t = m.group(MATCH_GROUP_PATH);
107 if (t != null && t.length() > 0) {
108 /* handle busted myspace frontpage redirect with
109 missing initial "/" */
110 if (t.charAt(0) == '/') {
111 mPath = t;
112 } else {
113 mPath = "/" + t;
114 }
115 }
116
117 } else {
118 // nothing found... outa here
119 throw new ParseException("Bad address");
120 }
121
122 /* Get port from scheme or scheme from port, if necessary and
123 possible */
124 if (mPort == 443 && mScheme.equals("")) {
125 mScheme = "https";
126 } else if (mPort == -1) {
127 if (mScheme.equals("https"))
128 mPort = 443;
129 else
130 mPort = 80; // default
131 }
132 if (mScheme.equals("")) mScheme = "http";
133 }
134
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100135 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 public String toString() {
137 String port = "";
138 if ((mPort != 443 && mScheme.equals("https")) ||
139 (mPort != 80 && mScheme.equals("http"))) {
140 port = ":" + Integer.toString(mPort);
141 }
142 String authInfo = "";
143 if (mAuthInfo.length() > 0) {
144 authInfo = mAuthInfo + "@";
145 }
146
147 return mScheme + "://" + authInfo + mHost + port + mPath;
148 }
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100149
Ignacio Solla451e3382014-11-10 10:35:54 +0000150 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100151 public void setScheme(String scheme) {
152 mScheme = scheme;
153 }
154
Ignacio Solla451e3382014-11-10 10:35:54 +0000155 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100156 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100157 public String getScheme() {
158 return mScheme;
159 }
160
Ignacio Solla451e3382014-11-10 10:35:54 +0000161 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100162 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100163 public void setHost(String host) {
164 mHost = host;
165 }
166
Ignacio Solla451e3382014-11-10 10:35:54 +0000167 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100168 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100169 public String getHost() {
170 return mHost;
171 }
172
Ignacio Solla451e3382014-11-10 10:35:54 +0000173 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100174 public void setPort(int port) {
175 mPort = port;
176 }
177
Ignacio Solla451e3382014-11-10 10:35:54 +0000178 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100179 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100180 public int getPort() {
181 return mPort;
182 }
183
Ignacio Solla451e3382014-11-10 10:35:54 +0000184 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100185 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100186 public void setPath(String path) {
187 mPath = path;
188 }
189
Ignacio Solla451e3382014-11-10 10:35:54 +0000190 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100191 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100192 public String getPath() {
193 return mPath;
194 }
195
Ignacio Solla451e3382014-11-10 10:35:54 +0000196 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100197 public void setAuthInfo(String authInfo) {
198 mAuthInfo = authInfo;
199 }
200
Ignacio Solla451e3382014-11-10 10:35:54 +0000201 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100202 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100203 public String getAuthInfo() {
204 return mAuthInfo;
205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206}