All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sunlabs.brazil.util.http.HttpUtil Maven / Gradle / Ivy

The newest version!
/*
 * HttpUtil.java
 *
 * Brazil project web application toolkit,
 * export version: 2.3 
 * Copyright (c) 1999-2004 Sun Microsystems, Inc.
 *
 * Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License Version 
 * 1.0 (the "License"). You may not use this file except in compliance with 
 * the License. A copy of the License is included as the file "license.terms",
 * and also available at http://www.sun.com/
 * 
 * The Original Code is from:
 *    Brazil project web application toolkit release 2.3.
 * The Initial Developer of the Original Code is: cstevens.
 * Portions created by cstevens are Copyright (C) Sun Microsystems, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s): cstevens, guym, suhler.
 *
 * Version:  2.3
 * Created by cstevens on 99/09/15
 * Last modified by suhler on 04/11/30 15:19:46
 *
 * Version Histories:
 *
 * 2.3 04/11/30-15:19:46 (suhler)
 *   fixed sccs version string
 *
 * 2.2 03/08/01-16:17:39 (suhler)
 *   fixes for javadoc
 *
 * 2.1 02/10/01-16:37:05 (suhler)
 *   version change
 *
 * 1.14 02/07/29-14:57:34 (suhler)
 *   added convenience routines to extract parts of url's
 *
 * 1.13 01/06/11-17:13:22 (guym)
 *   Fixed a mapping problem with '\n' in HTMLmap.
 *
 * 1.12 01/04/06-09:35:45 (suhler)
 *   Generate entity references for <>&" instead of #xxx;
 *
 * 1.11 00/11/20-13:22:31 (suhler)
 *   doc fixes
 *
 * 1.10 00/11/19-10:33:29 (suhler)
 *   added "parseTime" method to convet mime dates into time stamps
 *
 * 1.9 00/04/12-16:05:55 (cstevens)
 *   imports
 *
 * 1.8 00/03/29-16:47:35 (cstevens)
 *
 * 1.7 99/11/16-14:49:08 (cstevens)
 *   null
 *
 * 1.6 99/11/09-20:24:49 (cstevens)
 *   bugs revealed by writing tests.
 *
 * 1.5 99/10/14-13:02:28 (cstevens)
 *   Documentation
 *   HttpUtil.urlEncode was wrong.
 *
 * 1.4 99/09/30-14:13:06 (cstevens)
 *   better error message
 *
 * 1.3 99/09/15-15:57:27 (cstevens)
 *
 * 1.2 99/09/15-14:52:16 (cstevens)
 *   import *;
 *
 * 1.2 99/09/15-14:39:37 (Codemgr)
 *   SunPro Code Manager data about conflicts, renames, etc...
 *   Name history : 1 0 util/http/HttpUtil.java
 *
 * 1.1 99/09/15-14:39:36 (cstevens)
 *   date and time created 99/09/15 14:39:36 by cstevens
 *
 */

package sunlabs.brazil.util.http;

import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Dictionary;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.StringTokenizer;
import sunlabs.brazil.util.regexp.Regexp;

/**
 * The HttpUtil class contains methods for performing simple
 * HTTP operations.
 *
 * @author      Colin Stevens ([email protected])
 * @version		2.3
 */
public class HttpUtil
{
    private HttpUtil() {}

    /**
     * Which ascii characters may be sent in HTML without escaping
     */
    private static String[] htmlMap = new String[256];

    /**
     * Initialize htmlMap array
     * @see #htmlMap
     */
    static {
	for (int i = 0; i < 256; i++) {
	    if (i >= 32 && i < 126) {
		htmlMap[i]=null;
	    } else {
		htmlMap[i] = "#" + i;
	    }
	}
	htmlMap['"'] = "quot";
	htmlMap['&'] = "amp";
	htmlMap['<'] = "lt";
	htmlMap['>'] = "gt";
	htmlMap['\n'] = null;
	htmlMap['\r'] = null;
	htmlMap['\t'] = null;
    }

    /**
     * Converts a string into a valid HTML fragment.  Escapes the characters
     * ", &, <, >, and all
     * non-printables into the form &#xx; (their "decimal
     * reference" form).
     *
     * @param	src
     *		The string to convert.
     *
     * @return	The string with all the special characters converted to
     *		decimal reference form.
     */
    public static String
    htmlEncode(String src)
    {
	StringBuffer result = new StringBuffer();

	int length = (src == null) ? 0 : src.length();
	for (int i = 0; i < length; i++) {
	    int ch = src.charAt(i) & 0xff;
	    if (htmlMap[ch]==null) {
		result.append((char) ch);
	    } else {
		result.append("&" + htmlMap[ch] + ";");
	    }
	}
	return result.toString();
    }

    private static final boolean[] safeUrl = new boolean[256];
    static {
	for (int i = 'a'; i <= 'z'; i++) {
	    safeUrl[i] = true;
	}
	for (int i = 'A'; i <= 'Z'; i++) {
	    safeUrl[i] = true;
	}
	for (int i = '0'; i <= '9'; i++) {
	    safeUrl[i] = true;
	}
	safeUrl['_'] = true;
	safeUrl[':'] = true;
	safeUrl['/'] = true;
	safeUrl['.'] = true;
	safeUrl['~'] = true;
    }

    /**
     * Maps a string to be used in a query or post into a form that is
     * acceptable in an URL.  Typically used when the caller wants to
     * safely generate an HREF containing an arbitrary string that may
     * have special characters.
     * 

* URL strings may not contain non-alphanumeric characters. All * non-alphanumeric characters are converted to the escape sequence * "%XX", where XX is the hexadecimal value of that character's code. *

* Note that the space character " " is NOT converted to "+". That is * a common misconception. "+" represents a space only in query strings, * not in the URL. "%20" is how an actual space character must be * passed in an URL, and is also an acceptable way of passing a space in * a query string. * * @param string * The string to convert. * * @return The URL-encoded version of the given string. */ public static String urlEncode(String src) { StringBuffer result = new StringBuffer(); int length = (src == null) ? 0 : src.length(); for (int i = 0; i < length; i++) { int ch = src.charAt(i) & 0xff; if (safeUrl[ch]) { result.append((char) ch); } else { result.append('%'); result.append(Character.forDigit((ch >> 4) & 0x0f, 16)); result.append(Character.forDigit(ch & 0x0f, 16)); } } return result.toString(); } /** * Decodes a URL-encoded string by replacing all the "%XX" escape * sequences in the string with the corresponding character. *

* Malformed "%XX" sequences are silently ignored. * * @param string * The URL-encoded string. * * @return The decoded version of the given string. */ public static String urlDecode(String src) { if (src == null) { return ""; } int i = src.indexOf('%'); if (i < 0) { return src; } StringBuffer result = new StringBuffer(src.substring(0, i)); int length = src.length(); for ( ; i < length; i++) { char ch = src.charAt(i); if (ch == '%') { try { ch = (char) Integer.parseInt(src.substring(i + 1, i + 3), 16); i += 2; } catch (Exception e) { // Ignore malformed % sequences, just insert the '%'. } } result.append(ch); } return result.toString(); } /** * The format describing an http date. */ private static SimpleDateFormat dateFormat; static { dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); dateFormat.setTimeZone(new SimpleTimeZone(0, "GMT")); dateFormat.setLenient(true); } /** * Returns a string containing the current time as an HTTP-formatted * date. * * @return HTTP date string representing the current time. */ public static String formatTime() { return formatTime(System.currentTimeMillis()); } /** * Returns a string containing an HTTP-formatted date. * * @param time * The date to format (current time in msec). * * @return HTTP date string representing the given time. */ public static String formatTime(long time) { return dateFormat.format(new Date(time)).substring(0, 29); } /** * Convert a last-modified date in "standard" format * into a time stamp. This "inverses" formatTime. * * @param time * A correctly formatted HTTP date string. * @return milliseconds since the epoch, or 0 if the conversion * failed. */ public static long parseTime(String time) { try { return dateFormat.parse(time.trim(),new ParsePosition(0)).getTime(); } catch (Exception e) { return 0; } } /** * Turns x-www-form-urlencoded form data into a dictionary. * * @param query * The x-www-form-urlencoded string. May be null * * @param table * The dictionary to insert the form data into. */ public static void extractQuery(String query, Dictionary table) { if (query == null) { return; } query = query.replace('+', ' '); StringTokenizer st = new StringTokenizer(query, "&"); while (st.hasMoreTokens()) { String field = st.nextToken(); int index = field.indexOf('='); if (index < 0) { table.put(urlDecode(field), ""); } else { table.put(urlDecode(field.substring(0, index)), urlDecode(field.substring(index + 1))); } } } /* * Extract parts of a URL. * part: 1=protocol, 2=host, 3=port, 4=path */ static Regexp urlRe = new Regexp("([^:]*)://([^:/]*)(:[0-9]+)?(.*)"); static String parseUrl(String url, int part) { String matches[] = new String[5]; return (urlRe.match(url, matches) ? matches[part] : null); } /** * Get the protocol portion of a Url String. * @return null if the string is an invalid URL. */ public static String extractUrlProtocol(String url) { return parseUrl(url, 1); } /** * Get the host portion of a Url String. * @return null if the string is an invalid URL. */ public static String extractUrlHost(String url) { return parseUrl(url, 2); } /** * Get the port portion of a Url String as a string. * @return null if the string is an invalid URL, the empy string * if no port was specified. */ public static String extractUrlPort(String url) { String port = parseUrl(url, 3); return (port == null ? null : port.substring(1)); } /** * Get the path portion of a Url String. * @return null if the string is an invalid URL. */ public static String extractUrlPath(String url) { String s = parseUrl(url, 4); if (s != null && s.equals("")) { return "/"; } else { return s; } } /** * Returns the HTTP error string associated with the integer error code. * This error string can be used in HTTP responses. Unknown codes * return the string "Error" * * @param code * The code to look up. * * @return The associated error string. */ public static String getStatusPhrase(int code) { switch (code) { case 100: return "Continue"; case 101: return "Switching Protocols"; case 200: return "OK"; case 201: return "Created"; case 202: return "Accepted"; case 203: return "Non-Authoritative Information"; case 204: return "No Content"; case 205: return "Reset Content"; case 206: return "Partial Content"; case 300: return "Multiple Choices"; case 301: return "Moved Permanently"; case 302: return "Moved Temporarily"; case 303: return "See Other"; case 304: return "Not Modified"; case 305: return "Use Proxy"; case 400: return "Bad Request"; case 401: return "Unauthorized"; case 402: return "Payment Required"; case 403: return "Forbidden"; case 404: return "Not Found"; case 405: return "Method Not Allowed"; case 406: return "Not Acceptable"; case 407: return "Proxy Authentication Required"; case 408: return "Request Time-out"; case 409: return "Conflict"; case 410: return "Gone"; case 411: return "Length Required"; case 412: return "Precondition Failed"; case 413: return "Request Entity Too Large"; case 414: return "Request-URI Too Large"; case 415: return "Unsupported Media Type"; case 500: return "Server Error"; case 501: return "Not Implemented"; case 502: return "Bad Gateway"; case 503: return "Service Unavailable"; case 504: return "Gateway Time-out"; case 505: return "HTTP Version not supported"; default: return "Error"; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy