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 17package android.net; 18 19import java.util.regex.Matcher; 20import java.util.regex.Pattern; 21 22/** 23 * {@hide} 24 * 25 * Web Address Parser 26 * 27 * This is called WebAddress, rather than URL or URI, because it 28 * attempts to parse the stuff that a user will actually type into a 29 * browser address widget. 30 * 31 * Unlike java.net.uri, this parser will not choke on URIs missing 32 * schemes. It will only throw a ParseException if the input is 33 * really hosed. 34 * 35 * If given an https scheme but no port, fills in port 36 * 37 */ 38public class WebAddress { 39 40 private final static String LOGTAG = "http"; 41 42 public String mScheme; 43 public String mHost; 44 public int mPort; 45 public String mPath; 46 public 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|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" + 56 /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" + 57 /* host */ "([-A-Za-z0-9%_]+(?:\\.[-A-Za-z0-9%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" + 58 /* port */ "(?:\\:([0-9]+))?" + 59 /* path */ "(\\/?.*)?"); 60 61 /** parses given uriString. */ 62 public WebAddress(String address) throws ParseException { 63 if (address == null) { 64 throw new NullPointerException(); 65 } 66 67 // android.util.Log.d(LOGTAG, "WebAddress: " + address); 68 69 mScheme = ""; 70 mHost = ""; 71 mPort = -1; 72 mPath = "/"; 73 mAuthInfo = ""; 74 75 Matcher m = sAddressPattern.matcher(address); 76 String t; 77 if (m.matches()) { 78 t = m.group(MATCH_GROUP_SCHEME); 79 if (t != null) mScheme = t; 80 t = m.group(MATCH_GROUP_AUTHORITY); 81 if (t != null) mAuthInfo = t; 82 t = m.group(MATCH_GROUP_HOST); 83 if (t != null) mHost = t; 84 t = m.group(MATCH_GROUP_PORT); 85 if (t != null) { 86 try { 87 mPort = Integer.parseInt(t); 88 } catch (NumberFormatException ex) { 89 throw new ParseException("Bad port"); 90 } 91 } 92 t = m.group(MATCH_GROUP_PATH); 93 if (t != null && t.length() > 0) { 94 /* handle busted myspace frontpage redirect with 95 missing initial "/" */ 96 if (t.charAt(0) == '/') { 97 mPath = t; 98 } else { 99 mPath = "/" + t; 100 } 101 } 102 103 } else { 104 // nothing found... outa here 105 throw new ParseException("Bad address"); 106 } 107 108 /* Get port from scheme or scheme from port, if necessary and 109 possible */ 110 if (mPort == 443 && mScheme.equals("")) { 111 mScheme = "https"; 112 } else if (mPort == -1) { 113 if (mScheme.equals("https")) 114 mPort = 443; 115 else 116 mPort = 80; // default 117 } 118 if (mScheme.equals("")) mScheme = "http"; 119 } 120 121 public String toString() { 122 String port = ""; 123 if ((mPort != 443 && mScheme.equals("https")) || 124 (mPort != 80 && mScheme.equals("http"))) { 125 port = ":" + Integer.toString(mPort); 126 } 127 String authInfo = ""; 128 if (mAuthInfo.length() > 0) { 129 authInfo = mAuthInfo + "@"; 130 } 131 132 return mScheme + "://" + authInfo + mHost + port + mPath; 133 } 134} 135