FileDocCategorySizeDatePackage
URLUtil.javaAPI DocAndroid 5.1 API14046Thu Mar 12 22:22:10 GMT 2015android.webkit

URLUtil

public final class URLUtil extends Object

Fields Summary
private static final String
LOGTAG
private static final boolean
TRACE
static final String
ASSET_BASE
static final String
RESOURCE_BASE
static final String
FILE_BASE
static final String
PROXY_BASE
static final String
CONTENT_BASE
private static final Pattern
CONTENT_DISPOSITION_PATTERN
Regex used to parse content-disposition headers
Constructors Summary
Methods Summary
public static java.lang.StringcomposeSearchUrl(java.lang.String inQuery, java.lang.String template, java.lang.String queryPlaceHolder)

        int placeHolderIndex = template.indexOf(queryPlaceHolder);
        if (placeHolderIndex < 0) {
            return null;
        }

        String query;
        StringBuilder buffer = new StringBuilder();
        buffer.append(template.substring(0, placeHolderIndex));

        try {
            query = java.net.URLEncoder.encode(inQuery, "utf-8");
            buffer.append(query);
        } catch (UnsupportedEncodingException ex) {
            return null;
        }

        buffer.append(template.substring(
                placeHolderIndex + queryPlaceHolder.length()));

        return buffer.toString();
    
public static byte[]decode(byte[] url)

        if (url.length == 0) {
            return new byte[0];
        }

        // Create a new byte array with the same length to ensure capacity
        byte[] tempData = new byte[url.length];

        int tempCount = 0;
        for (int i = 0; i < url.length; i++) {
            byte b = url[i];
            if (b == '%") {
                if (url.length - i > 2) {
                    b = (byte) (parseHex(url[i + 1]) * 16
                            + parseHex(url[i + 2]));
                    i += 2;
                } else {
                    throw new IllegalArgumentException("Invalid format");
                }
            }
            tempData[tempCount++] = b;
        }
        byte[] retData = new byte[tempCount];
        System.arraycopy(tempData, 0, retData, 0, tempCount);
        return retData;
    
public static final java.lang.StringguessFileName(java.lang.String url, java.lang.String contentDisposition, java.lang.String mimeType)
Guesses canonical filename that a download would have, using the URL and contentDisposition. File extension, if not defined, is added based on the mimetype

param
url Url to the content
param
contentDisposition Content-Disposition HTTP header or null
param
mimeType Mime-type of the content or null
return
suggested filename

        String filename = null;
        String extension = null;

        // If we couldn't do anything with the hint, move toward the content disposition
        if (filename == null && contentDisposition != null) {
            filename = parseContentDisposition(contentDisposition);
            if (filename != null) {
                int index = filename.lastIndexOf('/") + 1;
                if (index > 0) {
                    filename = filename.substring(index);
                }
            }
        }

        // If all the other http-related approaches failed, use the plain uri
        if (filename == null) {
            String decodedUrl = Uri.decode(url);
            if (decodedUrl != null) {
                int queryIndex = decodedUrl.indexOf('?");
                // If there is a query string strip it, same as desktop browsers
                if (queryIndex > 0) {
                    decodedUrl = decodedUrl.substring(0, queryIndex);
                }
                if (!decodedUrl.endsWith("/")) {
                    int index = decodedUrl.lastIndexOf('/") + 1;
                    if (index > 0) {
                        filename = decodedUrl.substring(index);
                    }
                }
            }
        }

        // Finally, if couldn't get filename from URI, get a generic filename
        if (filename == null) {
            filename = "downloadfile";
        }

        // Split filename between base and extension
        // Add an extension if filename does not have one
        int dotIndex = filename.indexOf('.");
        if (dotIndex < 0) {
            if (mimeType != null) {
                extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
                if (extension != null) {
                    extension = "." + extension;
                }
            }
            if (extension == null) {
                if (mimeType != null && mimeType.toLowerCase(Locale.ROOT).startsWith("text/")) {
                    if (mimeType.equalsIgnoreCase("text/html")) {
                        extension = ".html";
                    } else {
                        extension = ".txt";
                    }
                } else {
                    extension = ".bin";
                }
            }
        } else {
            if (mimeType != null) {
                // Compare the last segment of the extension against the mime type.
                // If there's a mismatch, discard the entire extension.
                int lastDotIndex = filename.lastIndexOf('.");
                String typeFromExt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                        filename.substring(lastDotIndex + 1));
                if (typeFromExt != null && !typeFromExt.equalsIgnoreCase(mimeType)) {
                    extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
                    if (extension != null) {
                        extension = "." + extension;
                    }
                }
            }
            if (extension == null) {
                extension = filename.substring(dotIndex);
            }
            filename = filename.substring(0, dotIndex);
        }

        return filename + extension;
    
public static java.lang.StringguessUrl(java.lang.String inUrl)
Cleans up (if possible) user-entered web addresses


                
         

        String retVal = inUrl;
        WebAddress webAddress;

        if (TRACE) Log.v(LOGTAG, "guessURL before queueRequest: " + inUrl);

        if (inUrl.length() == 0) return inUrl;
        if (inUrl.startsWith("about:")) return inUrl;
        // Do not try to interpret data scheme URLs
        if (inUrl.startsWith("data:")) return inUrl;
        // Do not try to interpret file scheme URLs
        if (inUrl.startsWith("file:")) return inUrl;
        // Do not try to interpret javascript scheme URLs
        if (inUrl.startsWith("javascript:")) return inUrl;

        // bug 762454: strip period off end of url
        if (inUrl.endsWith(".") == true) {
            inUrl = inUrl.substring(0, inUrl.length() - 1);
        }

        try {
            webAddress = new WebAddress(inUrl);
        } catch (ParseException ex) {

            if (TRACE) {
                Log.v(LOGTAG, "smartUrlFilter: failed to parse url = " + inUrl);
            }
            return retVal;
        }

        // Check host
        if (webAddress.getHost().indexOf('.") == -1) {
            // no dot: user probably entered a bare domain.  try .com
            webAddress.setHost("www." + webAddress.getHost() + ".com");
        }
        return webAddress.toString();
    
public static booleanisAboutUrl(java.lang.String url)

return
True iff the url is an about: url.

        return (null != url) && url.startsWith("about:");
    
public static booleanisAssetUrl(java.lang.String url)

return
True iff the url is an asset file.

        return (null != url) && url.startsWith(ASSET_BASE);
    
public static booleanisContentUrl(java.lang.String url)

return
True iff the url is a content: url.

        return (null != url) && url.startsWith(CONTENT_BASE);
    
public static booleanisCookielessProxyUrl(java.lang.String url)

return
True iff the url is a proxy url to allow cookieless network requests from a file url.
deprecated
Cookieless proxy is no longer supported.

        return (null != url) && url.startsWith(PROXY_BASE);
    
public static booleanisDataUrl(java.lang.String url)

return
True iff the url is a data: url.

        return (null != url) && url.startsWith("data:");
    
public static booleanisFileUrl(java.lang.String url)

return
True iff the url is a local file.

        return (null != url) && (url.startsWith(FILE_BASE) &&
                                 !url.startsWith(ASSET_BASE) &&
                                 !url.startsWith(PROXY_BASE));
    
public static booleanisHttpUrl(java.lang.String url)

return
True iff the url is an http: url.

        return (null != url) &&
               (url.length() > 6) &&
               url.substring(0, 7).equalsIgnoreCase("http://");
    
public static booleanisHttpsUrl(java.lang.String url)

return
True iff the url is an https: url.

        return (null != url) &&
               (url.length() > 7) &&
               url.substring(0, 8).equalsIgnoreCase("https://");
    
public static booleanisJavaScriptUrl(java.lang.String url)

return
True iff the url is a javascript: url.

        return (null != url) && url.startsWith("javascript:");
    
public static booleanisNetworkUrl(java.lang.String url)

return
True iff the url is a network url.

        if (url == null || url.length() == 0) {
            return false;
        }
        return isHttpUrl(url) || isHttpsUrl(url);
    
public static booleanisResourceUrl(java.lang.String url)

return
True iff the url is a resource file.
hide

        return (null != url) && url.startsWith(RESOURCE_BASE);
    
public static booleanisValidUrl(java.lang.String url)

return
True iff the url is valid.

        if (url == null || url.length() == 0) {
            return false;
        }

        return (isAssetUrl(url) ||
                isResourceUrl(url) ||
                isFileUrl(url) ||
                isAboutUrl(url) ||
                isHttpUrl(url) ||
                isHttpsUrl(url) ||
                isJavaScriptUrl(url) ||
                isContentUrl(url));
    
static java.lang.StringparseContentDisposition(java.lang.String contentDisposition)


    /*
     * Parse the Content-Disposition HTTP Header. The format of the header
     * is defined here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html
     * This header provides a filename for content that is going to be
     * downloaded to the file system. We only support the attachment type.
     * Note that RFC 2616 specifies the filename value must be double-quoted.
     * Unfortunately some servers do not quote the value so to maintain
     * consistent behaviour with other browsers, we allow unquoted values too.
     */
        
        try {
            Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);
            if (m.find()) {
                return m.group(2);
            }
        } catch (IllegalStateException ex) {
             // This function is defined as returning null when it can't parse the header
        }
        return null;
    
private static intparseHex(byte b)

        if (b >= '0" && b <= '9") return (b - '0");
        if (b >= 'A" && b <= 'F") return (b - 'A" + 10);
        if (b >= 'a" && b <= 'f") return (b - 'a" + 10);

        throw new IllegalArgumentException("Invalid hex char '" + b + "'");
    
public static java.lang.StringstripAnchor(java.lang.String url)
Strips the url of the anchor.

        int anchorIndex = url.indexOf('#");
        if (anchorIndex != -1) {
            return url.substring(0, anchorIndex);
        }
        return url;
    
static booleanverifyURLEncoding(java.lang.String url)

return
True iff the url is correctly URL encoded

        int count = url.length();
        if (count == 0) {
            return false;
        }

        int index = url.indexOf('%");
        while (index >= 0 && index < count) {
            if (index < count - 2) {
                try {
                    parseHex((byte) url.charAt(++index));
                    parseHex((byte) url.charAt(++index));
                } catch (IllegalArgumentException e) {
                    return false;
                }
            } else {
                return false;
            }
            index = url.indexOf('%", index + 1);
        }
        return true;