/* * This file is part of the OWASP Proxy, a free intercepting proxy library. * Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to: * The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.owasp.proxy.model; import java.net.URISyntaxException; public class URI { private String input = null, scheme = null, host = null, path = null, query = null, fragment = null; private int port = -1; public URI(String url) throws URISyntaxException { input = url; parseHierarchical(); } private void parseHierarchical() throws URISyntaxException { int length = input.length(); int start = 0, end; end = scan(start, ":"); if (end == length) throw new URISyntaxException(input, "No ':' found extracting the scheme"); scheme = input.substring(start, end); if (end > length - 3 || !"://".equals(input.substring(end, end + 3))) throw new URISyntaxException(input, "Expected '://'", end); end = end + 3; start = end; end = scan(start, ":/"); if (end == length) throw new URISyntaxException(input, "Unexpected end of URI looking for port or path"); host = input.substring(start, end); if (input.charAt(end) == ':') { // get the port start = end; end = scan(start, "/"); if (end == length) throw new URISyntaxException(input, "Unexpected end of URI looking for path"); try { port = Integer.parseInt(input.substring(start + 1, end)); if (port < 1 || port > 65535) throw new URISyntaxException(input, "port out of range", start); } catch (NumberFormatException nfe) { URISyntaxException use = new URISyntaxException(input, "Illegal port specification!", start); use.initCause(nfe); throw use; } } start = end; end = scan(start, "?#"); path = input.substring(start, end); if (end == length) return; if (input.charAt(end) == '?') { // get the query start = end; end = scan(start, "#"); query = input.substring(start, end); } if (end == length) return; if (input.charAt(end) == '#') { // get the fragment start = end; fragment = input.substring(start); } } // Scan forward from the given start position. Stop at the first char // in the stop string (in which case the index of the preceding char is // returned), or the end of the input string (in which case the length // of the input string is returned). private int scan(int start, String stop) { int p = start; int end = input.length(); while (p < end) { char c = input.charAt(p); if (stop.indexOf(c) >= 0) break; p++; } return p; } public String getScheme() { return scheme; } public String getHost() { return host; } public int getPort() { return port; } public String getPath() { return path; } public String getQuery() { return query; } public String getFragment() { return fragment; } public String getResource() { StringBuilder buff = new StringBuilder(path); if (query != null) buff.append(query); if (fragment != null) buff.append(fragment); return buff.toString(); } public String toString() { StringBuilder buff = new StringBuilder(); buff.append(scheme).append("://"); buff.append(host); if (port > -1) buff.append(":").append(port); buff.append(path); if (query != null) buff.append(query); if (fragment != null) buff.append(fragment); return buff.toString(); } }