General purpose request parsing and encoding utility methods.
| Method from org.apache.catalina.util.RequestUtil Detail: |
public static String URLDecode(String str) {
return URLDecode(str, null);
}
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. It is assumed the string is not a query string. |
public static String URLDecode(byte[] bytes) {
return URLDecode(bytes, null);
}
Decode and return the specified URL-encoded byte array. It is assumed
the string is not a query string. |
public static String URLDecode(String str,
String enc) {
return URLDecode(str, enc, false);
}
Decode and return the specified URL-encoded String. It is assumed the
string is not a query string. |
public static String URLDecode(byte[] bytes,
String enc) {
return URLDecode(bytes, null, false);
}
Decode and return the specified URL-encoded byte array. It is assumed
the string is not a query string. |
public static String URLDecode(String str,
String enc,
boolean isQuery) {
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(bytes, enc, isQuery);
}
Decode and return the specified URL-encoded String. |
public static String URLDecode(byte[] bytes,
String enc,
boolean isQuery) {
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 == '+" && isQuery) {
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, ox, enc);
} catch (Exception e) {
e.printStackTrace();
}
}
return new String(bytes, 0, ox);
}
Decode and return the specified URL-encoded byte array. |
public static String filter(String message) {
format.setTimeZone(TimeZone.getTimeZone("GMT"));
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.length; i++) {
switch (content[i]) {
case '< ":
result.append("<");
break;
case ' >":
result.append(">");
break;
case '&":
result.append("&");
break;
case '"":
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.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. |
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);
}
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. |
public static void parseParameters(Map map,
String data,
String encoding) throws UnsupportedEncodingException {
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(map, bytes, encoding);
}
}
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. |
public static void parseParameters(Map map,
byte[] data,
String encoding) throws UnsupportedEncodingException {
if (data != null && data.length > 0) {
int ix = 0;
int ox = 0;
String key = null;
String value = null;
while (ix < data.length) {
byte c = data[ix++];
switch ((char) c) {
case '&":
value = new String(data, 0, ox, encoding);
if (key != null) {
putMapEntry(map, key, value);
key = null;
}
ox = 0;
break;
case '=":
if (key == null) {
key = new String(data, 0, ox, encoding);
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, ox, encoding);
putMapEntry(map, key, value);
}
}
}
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. |