com.noelios.restlet.http.HttpUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.restlet
Show all versions of org.apache.servicemix.bundles.restlet
This OSGi bundle wraps org.restlet, and com.noelios.restlet ${pkgVersion} jar files.
The newest version!
/**
* Copyright 2005-2008 Noelios Technologies.
*
* The contents of this file are subject to the terms of the following open
* source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.gnu.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.sun.com/cddl/cddl.html
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royaltee free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/
package com.noelios.restlet.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import org.restlet.data.CharacterSet;
import org.restlet.data.Dimension;
import org.restlet.data.Parameter;
import org.restlet.data.Reference;
/**
* Various HTTP utilities.
*
* @author Jerome Louvel
*/
public class HttpUtils {
/**
* Appends a source string as an HTTP comment.
*
* @param source
* The source string to format.
* @param destination
* The appendable destination.
* @throws IOException
*/
public static Appendable appendComment(CharSequence source,
Appendable destination) throws IOException {
destination.append('(');
char c;
for (int i = 0; i < source.length(); i++) {
c = source.charAt(i);
if (c == '(') {
destination.append("\\(");
} else if (c == ')') {
destination.append("\\)");
} else if (c == '\\') {
destination.append("\\\\");
} else {
destination.append(c);
}
}
destination.append(')');
return destination;
}
/**
* Appends a source string as an HTTP quoted string.
*
* @param source
* The unquoted source string.
* @param destination
* The destination to append to.
* @throws IOException
*/
public static Appendable appendQuote(CharSequence source,
Appendable destination) throws IOException {
destination.append('"');
char c;
for (int i = 0; i < source.length(); i++) {
c = source.charAt(i);
if (c == '"') {
destination.append("\\\"");
} else if (c == '\\') {
destination.append("\\\\");
} else {
destination.append(c);
}
}
destination.append('"');
return destination;
}
/**
* Appends a source string as an URI encoded string.
*
* @param source
* The source string to format.
* @param destination
* The appendable destination.
* @param characterSet
* The supported character encoding.
* @throws IOException
*/
public static Appendable appendUriEncoded(CharSequence source,
Appendable destination, CharacterSet characterSet)
throws IOException {
destination.append(Reference.encode(source.toString(), characterSet));
return destination;
}
/**
* Creates a parameter.
*
* @param name
* The parameter name buffer.
* @param value
* The parameter value buffer (can be null).
* @return The created parameter.
* @throws IOException
*/
public static Parameter createParameter(CharSequence name,
CharSequence value) {
if (value != null) {
return new Parameter(name.toString(), value.toString());
} else {
return new Parameter(name.toString(), null);
}
}
/**
* Creates a vary header from the given dimensions.
*
* @param dimensions
* The dimensions to copy to the response.
* @return Returns the Vary header or null, if dimensions is null or empty.
*/
public static String createVaryHeader(Collection dimensions) {
String vary = null;
if ((dimensions != null) && !dimensions.isEmpty()) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
if (dimensions.contains(Dimension.CLIENT_ADDRESS)
|| dimensions.contains(Dimension.TIME)
|| dimensions.contains(Dimension.UNSPECIFIED)) {
// From an HTTP point of view the representations can
// vary in unspecified ways
vary = "*";
} else {
for (final Dimension dim : dimensions) {
if (first) {
first = false;
} else {
sb.append(", ");
}
if (dim == Dimension.CHARACTER_SET) {
sb.append(HttpConstants.HEADER_ACCEPT_CHARSET);
} else if (dim == Dimension.CLIENT_AGENT) {
sb.append(HttpConstants.HEADER_USER_AGENT);
} else if (dim == Dimension.ENCODING) {
sb.append(HttpConstants.HEADER_ACCEPT_ENCODING);
} else if (dim == Dimension.LANGUAGE) {
sb.append(HttpConstants.HEADER_ACCEPT_LANGUAGE);
} else if (dim == Dimension.MEDIA_TYPE) {
sb.append(HttpConstants.HEADER_ACCEPT);
} else if (dim == Dimension.AUTHORIZATION) {
sb.append(HttpConstants.HEADER_AUTHORIZATION);
}
}
vary = sb.toString();
}
}
return vary;
}
/**
* Formats a product description.
*
* @param nameToken
* The product name token.
* @param versionToken
* The product version token.
* @param destination
* The appendable destination;
* @throws IOException
*/
public static void formatProduct(CharSequence nameToken,
CharSequence versionToken, Appendable destination)
throws IOException {
if (!isToken(nameToken)) {
throw new IllegalArgumentException(
"Invalid product name detected. Only token characters are allowed.");
} else {
destination.append(nameToken);
if (versionToken != null) {
if (!isToken(versionToken)) {
throw new IllegalArgumentException(
"Invalid product version detected. Only token characters are allowed.");
} else {
destination.append('/').append(versionToken);
}
}
}
}
/**
* Indicates if the given character is alphabetical (a-z or A-Z).
*
* @param character
* The character to test.
* @return True if the given character is alphabetical (a-z or A-Z).
*/
public static boolean isAlpha(int character) {
return isUpperCase(character) || isLowerCase(character);
}
/**
* Indicates if the given character is in ASCII range.
*
* @param character
* The character to test.
* @return True if the given character is in ASCII range.
*/
public static boolean isAsciiChar(int character) {
return (character >= 0) && (character <= 127);
}
/**
* Indicates if the given character is a carriage return.
*
* @param character
* The character to test.
* @return True if the given character is a carriage return.
*/
public static boolean isCarriageReturn(int character) {
return (character == 13);
}
/**
* Indicates if the given character is a control character.
*
* @param character
* The character to test.
* @return True if the given character is a control character.
*/
public static boolean isControlChar(int character) {
return ((character >= 0) && (character <= 31)) || (character == 127);
}
/**
* Indicates if the given character is a digit (0-9).
*
* @param character
* The character to test.
* @return True if the given character is a digit (0-9).
*/
public static boolean isDigit(int character) {
return (character >= '0') && (character <= '9');
}
/**
* Indicates if the given character is a double quote.
*
* @param character
* The character to test.
* @return True if the given character is a double quote.
*/
public static boolean isDoubleQuote(int character) {
return (character == 34);
}
/**
* Indicates if the given character is an horizontal tab.
*
* @param character
* The character to test.
* @return True if the given character is an horizontal tab.
*/
public static boolean isHorizontalTab(int character) {
return (character == 9);
}
/**
* Indicates if the given character is a line feed.
*
* @param character
* The character to test.
* @return True if the given character is a line feed.
*/
public static boolean isLineFeed(int character) {
return (character == 10);
}
/**
* Indicates if the given character is lower case (a-z).
*
* @param character
* The character to test.
* @return True if the given character is lower case (a-z).
*/
public static boolean isLowerCase(int character) {
return (character >= 'a') && (character <= 'z');
}
/**
* Indicates if the given character is a separator.
*
* @param character
* The character to test.
* @return True if the given character is a separator.
*/
public static boolean isSeparator(int character) {
switch (character) {
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case ':':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
case ' ':
case '\t':
return true;
default:
return false;
}
}
/**
* Indicates if the given character is a space.
*
* @param character
* The character to test.
* @return True if the given character is a space.
*/
public static boolean isSpace(int character) {
return (character == 32);
}
/**
* Indicates if the given character is textual (ASCII and not a control
* character).
*
* @param character
* The character to test.
* @return True if the given character is textual (ASCII and not a control
* character).
*/
public static boolean isText(int character) {
return isAsciiChar(character) && !isControlChar(character);
}
/**
* Indicates if the token is valid.
* Only contains valid token characters.
*
* @param token
* The token to check
* @return True if the token is valid.
*/
public static boolean isToken(CharSequence token) {
for (int i = 0; i < token.length(); i++) {
if (!isTokenChar(token.charAt(i))) {
return false;
}
}
return true;
}
/**
* Indicates if the given character is a token character (text and not a
* separator).
*
* @param character
* The character to test.
* @return True if the given character is a token character (text and not a
* separator).
*/
public static boolean isTokenChar(int character) {
return isText(character) && !isSeparator(character);
}
/**
* Indicates if the given character is upper case (A-Z).
*
* @param character
* The character to test.
* @return True if the given character is upper case (A-Z).
*/
public static boolean isUpperCase(int character) {
return (character >= 'A') && (character <= 'Z');
}
/**
* Read a header. Return null if the last header was already read.
*
* @param is
* The message input stream.
* @param sb
* The string builder to reuse.
* @return The header read or null.
* @throws IOException
*/
public static Parameter readHeader(InputStream is, StringBuilder sb)
throws IOException {
Parameter result = null;
// Detect the end of headers
int next = is.read();
if (HttpUtils.isCarriageReturn(next)) {
next = is.read();
if (!HttpUtils.isLineFeed(next)) {
throw new IOException(
"Invalid end of headers. Line feed missing after the carriage return.");
}
} else {
result = new Parameter();
// Parse the header name
while ((next != -1) && (next != ':')) {
sb.append((char) next);
next = is.read();
}
if (next == -1) {
throw new IOException(
"Unable to parse the header name. End of stream reached too early.");
} else {
result.setName(sb.toString());
sb.delete(0, sb.length());
next = is.read();
while (HttpUtils.isSpace(next)) {
// Skip any separator space between colon and header value
next = is.read();
}
// Parse the header value
while ((next != -1) && (!HttpUtils.isCarriageReturn(next))) {
sb.append((char) next);
next = is.read();
}
if (next == -1) {
throw new IOException(
"Unable to parse the header value. End of stream reached too early.");
} else {
next = is.read();
if (HttpUtils.isLineFeed(next)) {
result.setValue(sb.toString());
sb.delete(0, sb.length());
} else {
throw new IOException(
"Unable to parse the HTTP header value. The carriage return must be followed by a line feed.");
}
}
}
}
return result;
}
/**
* Writes a new line.
*
* @param os
* The output stream.
* @throws IOException
*/
public static void writeCRLF(OutputStream os) throws IOException {
os.write(13); // CR
os.write(10); // LF
}
/**
* Writes a header line.
*
* @param header
* The header to write.
* @param os
* The output stream.
* @throws IOException
*/
public static void writeHeader(Parameter header, OutputStream os)
throws IOException {
os.write(header.getName().getBytes());
os.write(':');
os.write(' ');
os.write(header.getValue().getBytes());
os.write(13); // CR
os.write(10); // LF
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy