blob: aa3777d5534258614df818bfe5e32ed7396ae83b [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
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -070021import android.annotation.NonNull;
Ignacio Solla451e3382014-11-10 10:35:54 +000022import android.annotation.SystemApi;
Artur Satayev26958002019-12-10 17:47:52 +000023import android.compat.annotation.UnsupportedAppUsage;
Mathew Inwood31755f92018-12-20 13:53:36 +000024import android.os.Build;
Ignacio Solla451e3382014-11-10 10:35:54 +000025
Elliott Hughescb64d432013-08-02 10:00:44 -070026import java.util.Locale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import java.util.regex.Matcher;
28import java.util.regex.Pattern;
29
30/**
31 * {@hide}
32 *
33 * Web Address Parser
34 *
35 * This is called WebAddress, rather than URL or URI, because it
36 * attempts to parse the stuff that a user will actually type into a
37 * browser address widget.
38 *
39 * Unlike java.net.uri, this parser will not choke on URIs missing
40 * schemes. It will only throw a ParseException if the input is
41 * really hosed.
42 *
43 * If given an https scheme but no port, fills in port
44 *
45 */
Ignacio Solla451e3382014-11-10 10:35:54 +000046// TODO(igsolla): remove WebAddress from the system SDK once the WebView apk does not
47// longer need to be binary compatible with the API 21 version of the framework.
48@SystemApi
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049public class WebAddress {
50
Mathew Inwood53f089f2018-08-08 14:44:44 +010051 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010052 private String mScheme;
Mathew Inwood53f089f2018-08-08 14:44:44 +010053 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010054 private String mHost;
Mathew Inwood31755f92018-12-20 13:53:36 +000055 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Bjorn Bringerteb8be972010-10-12 16:24:55 +010056 private int mPort;
Mathew Inwood53f089f2018-08-08 14:44:44 +010057 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +010058 private String mPath;
59 private String mAuthInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
61 static final int MATCH_GROUP_SCHEME = 1;
62 static final int MATCH_GROUP_AUTHORITY = 2;
63 static final int MATCH_GROUP_HOST = 3;
64 static final int MATCH_GROUP_PORT = 4;
65 static final int MATCH_GROUP_PATH = 5;
66
67 static Pattern sAddressPattern = Pattern.compile(
Patrick Scott92534462010-03-31 13:35:24 -040068 /* scheme */ "(?:(http|https|file)\\:\\/\\/)?" +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
Steve Block582deec2010-09-06 16:16:39 +010070 /* host */ "([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" +
Steve Block22574402010-03-08 17:52:02 +000071 /* port */ "(?:\\:([0-9]*))?" +
Patrick Scottfa4039e42010-02-16 16:15:55 -050072 /* path */ "(\\/?[^#]*)?" +
Patrick Scott92534462010-03-31 13:35:24 -040073 /* anchor */ ".*", Pattern.CASE_INSENSITIVE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75 /** parses given uriString. */
76 public WebAddress(String address) throws ParseException {
77 if (address == null) {
78 throw new NullPointerException();
79 }
80
81 // android.util.Log.d(LOGTAG, "WebAddress: " + address);
82
83 mScheme = "";
84 mHost = "";
85 mPort = -1;
86 mPath = "/";
87 mAuthInfo = "";
88
89 Matcher m = sAddressPattern.matcher(address);
90 String t;
91 if (m.matches()) {
92 t = m.group(MATCH_GROUP_SCHEME);
Elliott Hughescb64d432013-08-02 10:00:44 -070093 if (t != null) mScheme = t.toLowerCase(Locale.ROOT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 t = m.group(MATCH_GROUP_AUTHORITY);
95 if (t != null) mAuthInfo = t;
96 t = m.group(MATCH_GROUP_HOST);
97 if (t != null) mHost = t;
98 t = m.group(MATCH_GROUP_PORT);
Steve Block22574402010-03-08 17:52:02 +000099 if (t != null && t.length() > 0) {
100 // The ':' character is not returned by the regex.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 try {
102 mPort = Integer.parseInt(t);
103 } catch (NumberFormatException ex) {
104 throw new ParseException("Bad port");
105 }
106 }
107 t = m.group(MATCH_GROUP_PATH);
108 if (t != null && t.length() > 0) {
109 /* handle busted myspace frontpage redirect with
110 missing initial "/" */
111 if (t.charAt(0) == '/') {
112 mPath = t;
113 } else {
114 mPath = "/" + t;
115 }
116 }
117
118 } else {
119 // nothing found... outa here
120 throw new ParseException("Bad address");
121 }
122
123 /* Get port from scheme or scheme from port, if necessary and
124 possible */
125 if (mPort == 443 && mScheme.equals("")) {
126 mScheme = "https";
127 } else if (mPort == -1) {
128 if (mScheme.equals("https"))
129 mPort = 443;
130 else
131 mPort = 80; // default
132 }
133 if (mScheme.equals("")) mScheme = "http";
134 }
135
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -0700136 @NonNull
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100137 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 public String toString() {
139 String port = "";
140 if ((mPort != 443 && mScheme.equals("https")) ||
141 (mPort != 80 && mScheme.equals("http"))) {
142 port = ":" + Integer.toString(mPort);
143 }
144 String authInfo = "";
145 if (mAuthInfo.length() > 0) {
146 authInfo = mAuthInfo + "@";
147 }
148
149 return mScheme + "://" + authInfo + mHost + port + mPath;
150 }
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100151
Ignacio Solla451e3382014-11-10 10:35:54 +0000152 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100153 public void setScheme(String scheme) {
154 mScheme = scheme;
155 }
156
Ignacio Solla451e3382014-11-10 10:35:54 +0000157 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100158 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100159 public String getScheme() {
160 return mScheme;
161 }
162
Ignacio Solla451e3382014-11-10 10:35:54 +0000163 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100164 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100165 public void setHost(String host) {
166 mHost = host;
167 }
168
Ignacio Solla451e3382014-11-10 10:35:54 +0000169 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100170 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100171 public String getHost() {
172 return mHost;
173 }
174
Ignacio Solla451e3382014-11-10 10:35:54 +0000175 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100176 public void setPort(int port) {
177 mPort = port;
178 }
179
Ignacio Solla451e3382014-11-10 10:35:54 +0000180 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100181 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100182 public int getPort() {
183 return mPort;
184 }
185
Ignacio Solla451e3382014-11-10 10:35:54 +0000186 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100187 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100188 public void setPath(String path) {
189 mPath = path;
190 }
191
Ignacio Solla451e3382014-11-10 10:35:54 +0000192 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100193 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100194 public String getPath() {
195 return mPath;
196 }
197
Ignacio Solla451e3382014-11-10 10:35:54 +0000198 /** {@hide} */
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100199 public void setAuthInfo(String authInfo) {
200 mAuthInfo = authInfo;
201 }
202
Ignacio Solla451e3382014-11-10 10:35:54 +0000203 /** {@hide} */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100204 @UnsupportedAppUsage
Bjorn Bringerteb8be972010-10-12 16:24:55 +0100205 public String getAuthInfo() {
206 return mAuthInfo;
207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208}