Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package net.sf.webdav.fromcatalina;
 
 import java.util.Map;
 
General purpose request parsing and encoding utility methods.

Author(s):
Craig R. McClanahan
Tim Tye
Version:
$Revision: 1.1 $ $Date: 2007-01-05 03:23:22 $
 
 
 public final class RequestUtil {

    
The DateFormat to use for generating readable dates in cookies.
 
     private static SimpleDateFormat format = new SimpleDateFormat(
 	    " EEEE, dd-MMM-yy kk:mm:ss zz");
 
     static {
 	.setTimeZone(TimeZone.getTimeZone("GMT"));
     }

    
Encode a cookie as per RFC 2109. The resulting string can be used as the value for a Set-Cookie header.

Parameters:
cookie The cookie to encode.
Returns:
A string following RFC 2109.
 
     public static String encodeCookie(Cookie cookie) {
 
 	StringBuffer buf = new StringBuffer(cookie.getName());
 	buf.append("=");
 	buf.append(cookie.getValue());
 
 	if (cookie.getComment() != null) {
 	    buf.append("; Comment=\"");
 	    buf.append(cookie.getComment());
 	    buf.append("\"");
 	}
 
 	if (cookie.getDomain() != null) {
 	    buf.append("; Domain=\"");
 	    buf.append(cookie.getDomain());
 	    buf.append("\"");
 	}
 
 	long age = cookie.getMaxAge();
 	if (cookie.getMaxAge() >= 0) {
 	    buf.append("; Max-Age=\"");
 	    buf.append(cookie.getMaxAge());
 	    buf.append("\"");
 	}
 
 	if (cookie.getPath() != null) {
 	    buf.append("; Path=\"");
 	    buf.append(cookie.getPath());
 	    buf.append("\"");
 	}
 
 	if (cookie.getSecure()) {
 	    buf.append("; Secure");
 	}
 
 	if (cookie.getVersion() > 0) {
 	    buf.append("; Version=\"");
 	    buf.append(cookie.getVersion());
 	    buf.append("\"");
 	}
 
 	return (buf.toString());
     }

    
Filter the specified message string for characters that are sensitive in HTML. This avoids potential attacks caused by including JavaScript codes in the request URL that is often reported in error messages.

Parameters:
message The message string to be filtered
    public static String filter(String message) {
	if (message == null)
	    return (null);
	char content[] = new char[message.length()];
	message.getChars(0, message.length(), content, 0);
	StringBuffer result = new StringBuffer(content.length + 50);
	for (int i = 0; i < content.lengthi++) {
	    switch (content[i]) {
	    case '<':
		result.append("&lt;");
		break;
	    case '>':
		result.append("&gt;");
		break;
	    case '&':
		result.append("&amp;");
		break;
	    case '"':
		result.append("&quot;");
		break;
	    default:
		result.append(content[i]);
	    }
	}
	return (result.toString());
    }

    
Normalize a relative URI path that may have relative values ("/./", "/../", and so on ) it it. WARNING - This method is useful only for normalizing application-generated paths. It does not try to perform security checks for malicious input.

Parameters:
path Relative path to be normalized
    public static String normalize(String path) {
	if (path == null)
	    return null;
	// Create a place for the normalized path
	String normalized = path;
	if (normalized.equals("/."))
	    return "/";
	// Add a leading "/" if necessary
	if (!normalized.startsWith("/"))
	    normalized = "/" + normalized;
	// Resolve occurrences of "//" in the normalized path
	while (true) {
	    int index = normalized.indexOf("//");
	    if (index < 0)
		break;
	    normalized = normalized.substring(0, index)
		    + normalized.substring(index + 1);
	}
	// Resolve occurrences of "/./" in the normalized path
	while (true) {
	    int index = normalized.indexOf("/./");
	    if (index < 0)
		break;
	    normalized = normalized.substring(0, index)
		    + normalized.substring(index + 2);
	}
	// Resolve occurrences of "/../" in the normalized path
	while (true) {
	    int index = normalized.indexOf("/../");
	    if (index < 0)
		break;
	    if (index == 0)
		return (null); // Trying to go outside our context
	    int index2 = normalized.lastIndexOf('/'index - 1);
	    normalized = normalized.substring(0, index2)
		    + normalized.substring(index + 3);
	}
	// Return the normalized path that we have completed
	return (normalized);
    }

    
Parse the character encoding from the specified content type header. If the content type is null, or there is no explicit character encoding, null is returned.

Parameters:
contentType a content type header
    public static String parseCharacterEncoding(String contentType) {
	if (contentType == null)
	    return (null);
	int start = contentType.indexOf("charset=");
	if (start < 0)
	    return (null);
	String encoding = contentType.substring(start + 8);
	int end = encoding.indexOf(';');
	if (end >= 0)
	    encoding = encoding.substring(0, end);
	encoding = encoding.trim();
	if ((encoding.length() > 2) && (encoding.startsWith("\""))
		&& (encoding.endsWith("\"")))
	    encoding = encoding.substring(1, encoding.length() - 1);
	return (encoding.trim());
    }

    
Parse a cookie header into an array of cookies according to RFC 2109.

Parameters:
header Value of an HTTP "Cookie" header
    public static Cookie[] parseCookieHeader(String header) {
	if ((header == null) || (header.length() < 1))
	    return (new Cookie[0]);
	ArrayList cookies = new ArrayList();
	while (header.length() > 0) {
	    int semicolon = header.indexOf(';');
	    if (semicolon < 0)
		semicolon = header.length();
	    if (semicolon == 0)
		break;
	    String token = header.substring(0, semicolon);
	    if (semicolon < header.length())
		header = header.substring(semicolon + 1);
	    else
		header = "";
	    try {
		int equals = token.indexOf('=');
		if (equals > 0) {
		    String name = token.substring(0, equals).trim();
		    String value = token.substring(equals + 1).trim();
		    cookies.add(new Cookie(namevalue));
		}
	    } catch (Throwable e) {
		;
	    }
	}
	return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()]));
    }

    
Append request parameters from the specified String to the specified Map. It is presumed that the specified Map is not accessed from any other thread, so no synchronization is performed.

IMPLEMENTATION NOTE: URL decoding is performed individually on the parsed name and value elements, rather than on the entire query string ahead of time, to properly deal with the case where the name or value includes an encoded "=" or "&" character that would otherwise be interpreted as a delimiter.

Parameters:
map Map that accumulates the resulting parameters
data Input string containing request parameters
Throws:
java.lang.IllegalArgumentException if the data is malformed
    public static void parseParameters(Map mapString dataString encoding)
	if ((data != null) && (data.length() > 0)) {
	    // use the specified encoding to extract bytes out of the
	    // given string so that the encoding is not lost. If an
	    // encoding is not specified, let it use platform default
	    byte[] bytes = null;
	    try {
		if (encoding == null) {
		    bytes = data.getBytes();
else {
		    bytes = data.getBytes(encoding);
		}
	    } catch (UnsupportedEncodingException uee) {
	    }
	    parseParameters(mapbytesencoding);
	}
    }

    
Decode and return the specified URL-encoded String. When the byte array is converted to a string, the system default character encoding is used... This may be different than some other servers.

Parameters:
str The url-encoded string
Throws:
java.lang.IllegalArgumentException if a '%' character is not followed by a valid 2-digit hexadecimal number
    public static String URLDecode(String str) {
	return URLDecode(strnull);
    }

    
Decode and return the specified URL-encoded String.

Parameters:
str The url-encoded string
enc The encoding to use; if null, the default encoding is used
Throws:
java.lang.IllegalArgumentException if a '%' character is not followed by a valid 2-digit hexadecimal number
    public static String URLDecode(String strString enc) {
	if (str == null)
	    return (null);
	// use the specified encoding to extract bytes out of the
	// given string so that the encoding is not lost. If an
	// encoding is not specified, let it use platform default
	byte[] bytes = null;
	try {
	    if (enc == null) {
		bytes = str.getBytes();
	    } else {
		bytes = str.getBytes(enc);
	    }
catch (UnsupportedEncodingException uee) {
	}
	return URLDecode(bytesenc);
    }

    
Decode and return the specified URL-encoded byte array.

Parameters:
bytes The url-encoded byte array
Throws:
java.lang.IllegalArgumentException if a '%' character is not followed by a valid 2-digit hexadecimal number
    public static String URLDecode(byte[] bytes) {
	return URLDecode(bytesnull);
    }

    
Decode and return the specified URL-encoded byte array.

Parameters:
bytes The url-encoded byte array
enc The encoding to use; if null, the default encoding is used
Throws:
java.lang.IllegalArgumentException if a '%' character is not followed by a valid 2-digit hexadecimal number
    public static String URLDecode(byte[] bytesString enc) {
	if (bytes == null)
	    return (null);
	int len = bytes.length;
	int ix = 0;
	int ox = 0;
	while (ix < len) {
	    byte b = bytes[ix++]; // Get byte to test
	    if (b == '+') {
		b = (byte' ';
	    } else if (b == '%') {
		b = (byte) ((convertHexDigit(bytes[ix++]) << 4) + convertHexDigit(bytes[ix++]));
	    }
	    bytes[ox++] = b;
	}
	if (enc != null) {
	    try {
		return new String(bytes, 0, oxenc);
	    } catch (Exception e) {
	    }
	}
	return new String(bytes, 0, ox);
    }

    
Convert a byte character value to hexidecimal digit value.

Parameters:
b the character value byte
    private static byte convertHexDigit(byte b) {
	if ((b >= '0') && (b <= '9'))
	    return (byte) (b - '0');
	if ((b >= 'a') && (b <= 'f'))
	    return (byte) (b - 'a' + 10);
	if ((b >= 'A') && (b <= 'F'))
	    return (byte) (b - 'A' + 10);
	return 0;
    }

    
Put name and value pair in map. When name already exist, add value to array of values.

Parameters:
map The map to populate
name The parameter name
value The parameter value
    private static void putMapEntry(Map mapString nameString value) {
	String[] newValues = null;
	String[] oldValues = (String[]) map.get(name);
	if (oldValues == null) {
	    newValues = new String[1];
	    newValues[0] = value;
else {
	    newValues = new String[oldValues.length + 1];
	    System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
	    newValues[oldValues.length] = value;
	}
	map.put(namenewValues);
    }

    
Append request parameters from the specified String to the specified Map. It is presumed that the specified Map is not accessed from any other thread, so no synchronization is performed.

IMPLEMENTATION NOTE: URL decoding is performed individually on the parsed name and value elements, rather than on the entire query string ahead of time, to properly deal with the case where the name or value includes an encoded "=" or "&" character that would otherwise be interpreted as a delimiter. NOTE: byte array data is modified by this method. Caller beware.

Parameters:
map Map that accumulates the resulting parameters
data Input string containing request parameters
encoding Encoding to use for converting hex
Throws:
java.io.UnsupportedEncodingException if the data is malformed
    public static void parseParameters(Map mapbyte[] dataString encoding)
	if (data != null && data.length > 0) {
	    int pos = 0;
	    int ix = 0;
	    int ox = 0;
	    String key = null;
	    String value = null;
	    while (ix < data.length) {
		byte c = data[ix++];
		switch ((charc) {
		case '&':
		    value = new String(data, 0, oxencoding);
		    if (key != null) {
			putMapEntry(mapkeyvalue);
			key = null;
		    }
		    ox = 0;
		    break;
		case '=':
		    if (key == null) {
			key = new String(data, 0, oxencoding);
			ox = 0;
		    } else {
			data[ox++] = c;
		    }
		    break;
		case '+':
		    data[ox++] = (byte' ';
		    break;
		case '%':
		    data[ox++] = (byte) ((convertHexDigit(data[ix++]) << 4) + convertHexDigit(data[ix++]));
		    break;
		default:
		    data[ox++] = c;
		}
	    }
	    // The last value does not end in '&'. So save it now.
	    if (key != null) {
		value = new String(data, 0, oxencoding);
		putMapEntry(mapkeyvalue);
	    }
	}
    }
New to GrepCode? Check out our FAQ X