Beispiel #1
0
        /**
         * Parses the clear text URL in {@code str} into a URL object. URL strings
         * generally have the following format:
         * <p/>
         * http://www.company.com/java/file1.java#reference
         * <p/>
         * The string is parsed in HTTP format. If the protocol has a different URL
         * format this method must be overridden.
         *
         * @param u
         *            the URL to fill in the parsed clear text URL parts.
         * @param str
         *            the URL string that is to be parsed.
         * @param start
         *            the string position from where to begin parsing.
         * @param end
         *            the string position to stop parsing.
         * @see #toExternalForm
         * @see URL
         */
        protected internal void parseURL(URL u, String str, int start, int end)
        {
            if (end < start || end < 0)
            {
                // Checks to ensure string index exception ahead of
                // security exception for compatibility.
                if (end <= java.lang.Integer.MIN_VALUE + 1 && (start >= str.length() || start < 0) ||
                    str.startsWith("//", start) && str.indexOf('/', start + 2) == -1)      //$NON-NLS-1$
                {
                    throw new java.lang.StringIndexOutOfBoundsException(end);
                }
                if (this != u.strmHandler)
                {
                    throw new java.lang.SecurityException();
                }
                return;
            }
            String parseString = str.substring(start, end);

            end -= start;
            int fileIdx = 0;

            // Default is to use info from context
            String host      = u.getHost();
            int    port      = u.getPort();
            String refJ      = u.getRef();
            String file      = u.getPath();
            String query     = u.getQuery();
            String authority = u.getAuthority();
            String userInfo  = u.getUserInfo();

            int refIdx = parseString.indexOf('#', 0);

            if (parseString.startsWith("//") && !parseString.startsWith("////")) //$NON-NLS-1$
            {
                int hostIdx = 2, portIdx = -1;
                port    = -1;
                fileIdx = parseString.indexOf('/', hostIdx);
                int questionMarkIndex = parseString.indexOf('?', hostIdx);
                if ((questionMarkIndex != -1) &&
                    ((fileIdx == -1) || (fileIdx > questionMarkIndex)))
                {
                    fileIdx = questionMarkIndex;
                }
                if (fileIdx == -1)
                {
                    fileIdx = end;
                    // Use default
                    file = ""; //$NON-NLS-1$
                }
                int hostEnd = fileIdx;
                if (refIdx != -1 && refIdx < fileIdx)
                {
                    hostEnd = refIdx;
                }
                int userIdx = parseString.lastIndexOf('@', hostEnd);
                authority = parseString.substring(hostIdx, hostEnd);
                if (userIdx > -1)
                {
                    userInfo = parseString.substring(hostIdx, userIdx);
                    hostIdx  = userIdx + 1;
                }

                portIdx = parseString.indexOf(':', userIdx == -1 ? hostIdx
                    : userIdx);
                int endOfIPv6Addr = parseString.indexOf(']');
                // if there are square braces, ie. IPv6 address, use last ':'
                if (endOfIPv6Addr != -1)
                {
                    try {
                        if (parseString.length() > endOfIPv6Addr + 1)
                        {
                            char c = parseString.charAt(endOfIPv6Addr + 1);
                            if (c == ':')
                            {
                                portIdx = endOfIPv6Addr + 1;
                            }
                            else
                            {
                                portIdx = -1;
                            }
                        }
                        else
                        {
                            portIdx = -1;
                        }
                    } catch (Exception) {
                        // Ignored
                    }
                }

                if (portIdx == -1 || portIdx > fileIdx)
                {
                    host = parseString.substring(hostIdx, hostEnd);
                }
                else
                {
                    host = parseString.substring(hostIdx, portIdx);
                    String portString = parseString.substring(portIdx + 1, hostEnd);
                    if (portString.length() == 0)
                    {
                        port = -1;
                    }
                    else
                    {
                        port = java.lang.Integer.parseInt(portString);
                    }
                }
            }

            if (refIdx > -1)
            {
                refJ = parseString.substring(refIdx + 1, end);
            }
            int fileEnd = (refIdx == -1 ? end : refIdx);

            int  queryIdx     = parseString.lastIndexOf('?', fileEnd);
            bool canonicalize = false;

            if (queryIdx > -1)
            {
                query = parseString.substring(queryIdx + 1, fileEnd);
                if (queryIdx == 0 && file != null)
                {
                    if (file.equals(""))           //$NON-NLS-1$
                    {
                        file = "/";                //$NON-NLS-1$
                    }
                    else if (file.startsWith("/")) //$NON-NLS-1$
                    {
                        canonicalize = true;
                    }
                    int last = file.lastIndexOf('/') + 1;
                    file = file.substring(0, last);
                }
                fileEnd = queryIdx;
            }
            else
            // Don't inherit query unless only the ref is changed
            if (refIdx != 0)
            {
                query = null;
            }

            if (fileIdx > -1)
            {
                if (fileIdx < end && parseString.charAt(fileIdx) == '/')
                {
                    file = parseString.substring(fileIdx, fileEnd);
                }
                else if (fileEnd > fileIdx)
                {
                    if (file == null)
                    {
                        file = "";                 //$NON-NLS-1$
                    }
                    else if (file.equals(""))      //$NON-NLS-1$
                    {
                        file = "/";                //$NON-NLS-1$
                    }
                    else if (file.startsWith("/")) //$NON-NLS-1$
                    {
                        canonicalize = true;
                    }
                    int last = file.lastIndexOf('/') + 1;
                    if (last == 0)
                    {
                        file = parseString.substring(fileIdx, fileEnd);
                    }
                    else
                    {
                        file = file.substring(0, last)
                               + parseString.substring(fileIdx, fileEnd);
                    }
                }
            }
            if (file == null)
            {
                file = ""; //$NON-NLS-1$
            }

            if (host == null)
            {
                host = ""; //$NON-NLS-1$
            }

            if (canonicalize)
            {
                // modify file if there's any relative referencing
                file = URLUtil.canonicalizePath(file);
            }

            setURL(u, u.getProtocol(), host, port, authority, userInfo, file,
                   query, refJ);
        }