⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uri.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 * conditions are met:
 *  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the distribution.
 *  3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This
 * product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this
 * acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear.
 *  4. The names "Xalan" and "Apache Software Foundation" must not be used to endorse or promote products derived from this
 * software without prior written permission. For written permission, please contact apache@apache.org.
 *  5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written
 * permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE
 * FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus Development Corporation., http://www.lotus.com. For more information on
 * the Apache Software Foundation, please see <http://www.apache.org/> .
 *
 *
 *
 * Adapted for use as a standalone class in Maverick by removing references to XSLMessages and XSLErrorResources.
 */
package com.sslexplorer.vpn.util;

import java.io.IOException;
import java.io.Serializable;

/**
 * A class to represent a Uniform Resource Identifier (URI). This class is designed to handle the parsing of URIs and provide
 * access to the various components (scheme, host, port, userinfo, path, query string and fragment) that may constitute a URI.
 * <p>
 * Parsing of a URI specification is done according to the URI syntax described in RFC 2396
 * <http://www.ietf.org/rfc/rfc2396.txt?number=2396>. Every URI consists of a scheme, followed by a colon (':'), followed by a
 * scheme-specific part. For URIs that follow the "generic URI" syntax, the scheme- specific part begins with two slashes ("//")
 * and may be followed by an authority segment (comprised of user information, host, and port), path segment, query segment and
 * fragment. Note that RFC 2396 no longer specifies the use of the parameters segment and excludes the "user:password" syntax as
 * part of the authority segment. If "user:password" appears in a URI, the entire user/password string is stored as userinfo.
 * <p>
 * For URIs that do not follow the "generic URI" syntax (e.g. mailto), the entire scheme-specific part is treated as the "path"
 * portion of the URI.
 * <p>
 * Note that, unlike the java.net.URL class, this class does not provide any built-in network access functionality nor does it
 * provide any scheme-specific functionality (for example, it does not know a default port for a specific scheme). Rather, it only
 * knows the grammar and basic set of operations that can be applied to a URI.
 *
 *
 */
public class URI
    implements Serializable {

  /**
   * MalformedURIExceptions are thrown in the process of building a URI or setting fields on a URI when an operation would result
   * in an invalid URI specification.
   *
   */
  public static class MalformedURIException
      extends IOException {

    /**
     * Constructs a <code>MalformedURIException</code> with no specified detail message.
     */
    public MalformedURIException() {
      super();
    }

    /**
     * Constructs a <code>MalformedURIException</code> with the specified detail message.
     *
     * @param p_msg the detail message.
     */
    public MalformedURIException(String p_msg) {
      super(p_msg);
    }
  }

  /** reserved characters */
  private static final String RESERVED_CHARACTERS = ";/?:@&=+$,";

  /**
   * URI punctuation mark characters - these, combined with alphanumerics, constitute the "unreserved" characters
   */
  private static final String MARK_CHARACTERS = "-_.!~*'() ";

  /** scheme can be composed of alphanumerics and these characters */
  private static final String SCHEME_CHARACTERS = "+-.";

  /**
   * userinfo can be composed of unreserved, escaped and these characters
   */
  private static final String USERINFO_CHARACTERS = ";:&=+$,";

  /**
   * Stores the scheme (usually the protocol) for this URI.
   *
   * @serial
   */
  private String m_scheme = null;

  /**
   * If specified, stores the userinfo for this URI; otherwise null.
   *
   * @serial
   */
  private String m_userinfo = null;

  /**
   * If specified, stores the host for this URI; otherwise null.
   *
   * @serial
   */
  private String m_host = null;

  /**
   * If specified, stores the port for this URI; otherwise -1.
   *
   * @serial
   */
  private int m_port = -1;

  /**
   * If specified, stores the path for this URI; otherwise null.
   *
   * @serial
   */
  private String m_path = null;

  /**
   * If specified, stores the query string for this URI; otherwise null.
   *
   * @serial
   */
  private String m_queryString = null;

  /**
   * If specified, stores the fragment for this URI; otherwise null.
   *
   * @serial
   */
  private String m_fragment = null;

  /** Indicate whether in DEBUG mode */
  private static boolean DEBUG = false;

  /**
   * Construct a new and uninitialized URI.
   */
  public URI() {
  }

  /**
   * Construct a new URI from another URI. All fields for this URI are set equal to the fields of the URI passed in.
   *
   * @param p_other the URI to copy (cannot be null)
   */
  public URI(URI p_other) {
    initialize(p_other);
  }

  /**
   * Construct a new URI from a URI specification string. If the specification follows the "generic URI" syntax, (two slashes
   * following the first colon), the specification will be parsed accordingly - setting the scheme, userinfo, host,port, path,
   * query string and fragment fields as necessary. If the specification does not follow the "generic URI" syntax, the
   * specification is parsed into a scheme and scheme-specific part (stored as the path) only.
   *
   * @param p_uriSpec the URI specification string (cannot be null or empty)
   *
   * @throws MalformedURIException if p_uriSpec violates any syntax rules
   */
  public URI(String p_uriSpec) throws MalformedURIException {
    this( (URI)null, p_uriSpec);
  }

  /**
   * Construct a new URI from a base URI and a URI specification string. The URI specification string may be a relative URI.
   *
   * @param p_base the base URI (cannot be null if p_uriSpec is null or empty)
   * @param p_uriSpec the URI specification string (cannot be null or empty if p_base is null)
   *
   * @throws MalformedURIException if p_uriSpec violates any syntax rules
   */
  public URI(URI p_base, String p_uriSpec) throws MalformedURIException {
    initialize(p_base, p_uriSpec);
  }

  /**
   * Construct a new URI that does not follow the generic URI syntax. Only the scheme and scheme-specific part (stored as the
   * path) are initialized.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
       * @param p_schemeSpecificPart the scheme-specific part (cannot be null or empty)
   *
   * @throws MalformedURIException if p_scheme violates any syntax rules
   */
  public URI(String p_scheme, String p_schemeSpecificPart) throws
      MalformedURIException {

    if (p_scheme == null || p_scheme.trim().length() == 0) {
      throw new MalformedURIException(
          "Cannot construct URI with null/empty scheme!");
    }

    if (p_schemeSpecificPart == null ||
        p_schemeSpecificPart.trim().length() == 0) {
      throw new MalformedURIException(
          "Cannot construct URI with null/empty scheme-specific part!");
    }

    setScheme(p_scheme);
    setPath(p_schemeSpecificPart);
  }

  /**
   * Construct a new URI that follows the generic URI syntax from its component parts. Each component is validated for syntax and
   * some basic semantic checks are performed as well. See the individual setter methods for specifics.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
   * @param p_host the hostname or IPv4 address for the URI
   * @param p_path the URI path - if the path contains '?' or '#', then the query string and/or fragment will be set from the
   *            path; however, if the query and fragment are specified both in the path and as separate parameters, an exception
   *            is thrown
   * @param p_queryString the URI query string (cannot be specified if path is null)
   * @param p_fragment the URI fragment (cannot be specified if path is null)
   *
   * @throws MalformedURIException if any of the parameters violates syntax rules or semantic rules
   */
  public URI(String p_scheme, String p_host, String p_path,
             String p_queryString, String p_fragment) throws
      MalformedURIException {
    this(p_scheme, null, p_host, -1, p_path, p_queryString, p_fragment);
  }

  /**
   * Construct a new URI that follows the generic URI syntax from its component parts. Each component is validated for syntax and
   * some basic semantic checks are performed as well. See the individual setter methods for specifics.
   *
   * @param p_scheme the URI scheme (cannot be null or empty)
   * @param p_userinfo the URI userinfo (cannot be specified if host is null)
   * @param p_host the hostname or IPv4 address for the URI
   * @param p_port the URI port (may be -1 for "unspecified"; cannot be specified if host is null)
   * @param p_path the URI path - if the path contains '?' or '#', then the query string and/or fragment will be set from the
   *            path; however, if the query and fragment are specified both in the path and as separate parameters, an exception
   *            is thrown
   * @param p_queryString the URI query string (cannot be specified if path is null)
   * @param p_fragment the URI fragment (cannot be specified if path is null)
   *
   * @throws MalformedURIException if any of the parameters violates syntax rules or semantic rules
   */
  public URI(
      String p_scheme,
      String p_userinfo,
      String p_host,
      int p_port,
      String p_path,
      String p_queryString,
      String p_fragment) throws MalformedURIException {

    if (p_scheme == null || p_scheme.trim().length() == 0) {
      throw new MalformedURIException("Scheme is required!");
    }

    if (p_host == null) {
      if (p_userinfo != null) {
        throw new MalformedURIException(
            "Userinfo may not be specified if host is not specified!");
      }

      if (p_port != -1) {
        throw new MalformedURIException(
            "Port may not be specified if host is not specified!");
      }
    }

    if (p_path != null) {
      if (p_path.indexOf('?') != -1 && p_queryString != null) {
        throw new MalformedURIException(
            "Query string cannot be specified in path and query string!");
      }

      if (p_path.indexOf('#') != -1 && p_fragment != null) {
        throw new MalformedURIException(
            "Fragment cannot be specified in both the path and fragment!");
      }
    }

    setScheme(p_scheme);
    setHost(p_host);
    setPort(p_port);
    setUserinfo(p_userinfo);
    setPath(p_path);
    setQueryString(p_queryString);
    setFragment(p_fragment);
  }

  /**
   * Initialize all fields of this URI from another URI.
   *
   * @param p_other the URI to copy (cannot be null)
   */
  private void initialize(URI p_other) {

    m_scheme = p_other.getScheme();
    m_userinfo = p_other.getUserinfo();
    m_host = p_other.getHost();
    m_port = p_other.getPort();
    m_path = p_other.getPath();
    m_queryString = p_other.getQueryString();
    m_fragment = p_other.getFragment();
  }

  /**
   * Initializes this URI from a base URI and a URI specification string. See RFC 2396 Section 4 and Appendix B for
   * specifications on parsing the URI and Section 5 for specifications on resolving relative URIs and relative paths.
   *
   * @param p_base the base URI (may be null if p_uriSpec is an absolute URI)
   * @param p_uriSpec the URI spec string which may be an absolute or relative URI (can only be null/empty if p_base is not null)
   *
   * @throws MalformedURIException if p_base is null and p_uriSpec is not an absolute URI or if p_uriSpec violates syntax rules
   */
  private void initialize(URI p_base, String p_uriSpec) throws
      MalformedURIException {

    if (p_base == null && (p_uriSpec == null || p_uriSpec.trim().length() == 0)) {
      throw new MalformedURIException(
          "Cannot initialize URI with empty parameters.");
    }

    // just make a copy of the base if spec is empty
    if (p_uriSpec == null || p_uriSpec.trim().length() == 0) {
      initialize(p_base);

      return;
    }

    String uriSpec = p_uriSpec.trim();
    int uriSpecLen = uriSpec.length();
    int index = 0;

    // check for scheme
    if (uriSpec.indexOf(':') == -1) {
      if (p_base == null) {
        throw new MalformedURIException("No scheme found in URI: " + uriSpec);
      }
    }
    else {
      initializeScheme(uriSpec);

      index = m_scheme.length() + 1;
    }

    // two slashes means generic URI syntax, so we get the authority
    if ( ( (index + 1) < uriSpecLen) &&
        (uriSpec.substring(index).startsWith("//"))) {
      index += 2;

      int startPos = index;

      // get authority - everything up to path, query or fragment
      char testChar = '\0';

      while (index < uriSpecLen) {
        testChar = uriSpec.charAt(index);

        if (testChar == '/' || testChar == '?' || testChar == '#') {
          break;
        }

        index++;
      }

      // if we found authority, parse it out, otherwise we set the
      // host to empty string
      if (index > startPos) {
        initializeAuthority(uriSpec.substring(startPos, index));
      }
      else {
        m_host = "";
      }
    }

    initializePath(uriSpec.substring(index));

    // Resolve relative URI to base URI - see RFC 2396 Section 5.2
    // In some cases, it might make more sense to throw an exception
    // (when scheme is specified is the string spec and the base URI
    // is also specified, for example), but we're just following the
    // RFC specifications
    if (p_base != null) {

      // check to see if this is the current doc - RFC 2396 5.2 #2
      // note that this is slightly different from the RFC spec in that
      // we don't include the check for query string being null
      // - this handles cases where the urispec is just a query
      // string or a fragment (e.g. "?y" or "#s") -
      // see <http://www.ics.uci.edu/~fielding/url/test1.html> which
      // identified this as a bug in the RFC
      if (m_path.length() == 0 && m_scheme == null && m_host == null) {
        m_scheme = p_base.getScheme();
        m_userinfo = p_base.getUserinfo();
        m_host = p_base.getHost();
        m_port = p_base.getPort();
        m_path = p_base.getPath();

        if (m_queryString == null) {
          m_queryString = p_base.getQueryString();
        }

        return;
      }

      // check for scheme - RFC 2396 5.2 #3
      // if we found a scheme, it means absolute URI, so we're done
      if (m_scheme == null) {
        m_scheme = p_base.getScheme();
      }
      else {
        return;
      }

      // check for authority - RFC 2396 5.2 #4
      // if we found a host, then we've got a network path, so we're done
      if (m_host == null) {
        m_userinfo = p_base.getUserinfo();
        m_host = p_base.getHost();
        m_port = p_base.getPort();
      }
      else {
        return;
      }

      // check for absolute path - RFC 2396 5.2 #5
      if (m_path.length() > 0 && m_path.startsWith("/")) {
        return;
      }

      // if we get to this point, we need to resolve relative path
      // RFC 2396 5.2 #6
      String path = new String();
      String basePath = p_base.getPath();

      // 6a - get all but the last segment of the base URI path
      if (basePath != null) {
        int lastSlash = basePath.lastIndexOf('/');

        if (lastSlash != -1) {
          path = basePath.substring(0, lastSlash + 1);
        }
      }

      // 6b - append the relative URI path
      path = path.concat(m_path);

      // 6c - remove all "./" where "." is a complete path segment
      index = -1;

      while ( (index = path.indexOf("/./")) != -1) {
        path = path.substring(0, index + 1).concat(path.substring(index + 3));
      }

      // 6d - remove "." if path ends with "." as a complete path segment
      if (path.endsWith("/.")) {
        path = path.substring(0, path.length() - 1);
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -