1 /* 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 17 package android.net; 18 19 import static android.util.Patterns.GOOD_IRI_CHAR; 20 21 import java.util.Locale; 22 import java.util.regex.Matcher; 23 import java.util.regex.Pattern; 24 25 /** 26 * {@hide} 27 * 28 * Web Address Parser 29 * 30 * This is called WebAddress, rather than URL or URI, because it 31 * attempts to parse the stuff that a user will actually type into a 32 * browser address widget. 33 * 34 * Unlike java.net.uri, this parser will not choke on URIs missing 35 * schemes. It will only throw a ParseException if the input is 36 * really hosed. 37 * 38 * If given an https scheme but no port, fills in port 39 * 40 */ 41 public class WebAddress { 42 43 private String mScheme; 44 private String mHost; 45 private int mPort; 46 private String mPath; 47 private String mAuthInfo; 48 49 static final int MATCH_GROUP_SCHEME = 1; 50 static final int MATCH_GROUP_AUTHORITY = 2; 51 static final int MATCH_GROUP_HOST = 3; 52 static final int MATCH_GROUP_PORT = 4; 53 static final int MATCH_GROUP_PATH = 5; 54 55 static Pattern sAddressPattern = Pattern.compile( 56 /* scheme */ "(?:(http|https|file)\\:\\/\\/)?" + 57 /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" + 58 /* host */ "([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" + 59 /* port */ "(?:\\:([0-9]*))?" + 60 /* path */ "(\\/?[^#]*)?" + 61 /* anchor */ ".*", Pattern.CASE_INSENSITIVE); 62 63 /** parses given uriString. */ 64 public WebAddress(String address) throws ParseException { 65 if (address == null) { 66 throw new NullPointerException(); 67 } 68 69 // android.util.Log.d(LOGTAG, "WebAddress: " + address); 70 71 mScheme = ""; 72 mHost = ""; 73 mPort = -1; 74 mPath = "/"; 75 mAuthInfo = ""; 76 77 Matcher m = sAddressPattern.matcher(address); 78 String t; 79 if (m.matches()) { 80 t = m.group(MATCH_GROUP_SCHEME); 81 if (t != null) mScheme = t.toLowerCase(Locale.ROOT); 82 t = m.group(MATCH_GROUP_AUTHORITY); 83 if (t != null) mAuthInfo = t; 84 t = m.group(MATCH_GROUP_HOST); 85 if (t != null) mHost = t; 86 t = m.group(MATCH_GROUP_PORT); 87 if (t != null && t.length() > 0) { 88 // The ':' character is not returned by the regex. 89 try { 90 mPort = Integer.parseInt(t); 91 } catch (NumberFormatException ex) { 92 throw new ParseException("Bad port"); 93 } 94 } 95 t = m.group(MATCH_GROUP_PATH); 96 if (t != null && t.length() > 0) { 97 /* handle busted myspace frontpage redirect with 98 missing initial "/" */ 99 if (t.charAt(0) == '/') { 100 mPath = t; 101 } else { 102 mPath = "/" + t; 103 } 104 } 105 106 } else { 107 // nothing found... outa here 108 throw new ParseException("Bad address"); 109 } 110 111 /* Get port from scheme or scheme from port, if necessary and 112 possible */ 113 if (mPort == 443 && mScheme.equals("")) { 114 mScheme = "https"; 115 } else if (mPort == -1) { 116 if (mScheme.equals("https")) 117 mPort = 443; 118 else 119 mPort = 80; // default 120 } 121 if (mScheme.equals("")) mScheme = "http"; 122 } 123 124 @Override 125 public String toString() { 126 String port = ""; 127 if ((mPort != 443 && mScheme.equals("https")) || 128 (mPort != 80 && mScheme.equals("http"))) { 129 port = ":" + Integer.toString(mPort); 130 } 131 String authInfo = ""; 132 if (mAuthInfo.length() > 0) { 133 authInfo = mAuthInfo + "@"; 134 } 135 136 return mScheme + "://" + authInfo + mHost + port + mPath; 137 } 138 139 public void setScheme(String scheme) { 140 mScheme = scheme; 141 } 142 143 public String getScheme() { 144 return mScheme; 145 } 146 147 public void setHost(String host) { 148 mHost = host; 149 } 150 151 public String getHost() { 152 return mHost; 153 } 154 155 public void setPort(int port) { 156 mPort = port; 157 } 158 159 public int getPort() { 160 return mPort; 161 } 162 163 public void setPath(String path) { 164 mPath = path; 165 } 166 167 public String getPath() { 168 return mPath; 169 } 170 171 public void setAuthInfo(String authInfo) { 172 mAuthInfo = authInfo; 173 } 174 175 public String getAuthInfo() { 176 return mAuthInfo; 177 } 178 } 179