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