com.bigdata.util.httpd.HTTPHeaderUtility Maven / Gradle / Ivy
/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 [email protected] This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Mar 9, 2011 */ package com.bigdata.util.httpd; import java.util.Enumeration; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.log4j.Logger; /** * This class provides set of utilities for encoding and decoding HTTP * headers and doubles as the base class for all classes that * implement support for a specific HTTP header, such as {@link * LinkHeader}, {@link AcceptHeader}, etc. */ public class HTTPHeaderUtility { /** * The {@link Logger} for HTTP header operations, including * parsing and serialization. The {@link Logger} is named for * this class. It should be used by all derived classes. */ protected static final Logger log = Logger.getLogger ( HTTPHeaderUtility.class ); // quoted-string // := // // token := One of more of any CHAR except CTLs or separators. // // CTL :=
.// // separators := "(" | ")" | "<" | ">" | "@" // | "," | ";" | ":" | "\" | <"> // | "/" | "[" | "]" | "?" | "=" // | "{" | "}" | SP | HT // token := One of more of any CHAR except CTLs or separators. // // CTL := // // separators := "(" | ")" | "<" | ">" | "@" // | "," | ";" | ":" | "\" | <"> // | "/" | "[" | "]" | "?" | "=" // | "{" | "}" | SP | HT /** * Matches an HTTP token
, which consists of one or * more of any CHAR exceptCTL
or *separator
. */ final protected static String httpTokenPattern = "[^\\p{Cntrl}\\(\\)<>@,;:\\\\\\\"/\\[\\]\\?=\\{\\}\\s\\x09]+" ; /** * The text for a {@link Pattern} matching an HTTP *quoted-string
.* * From HTTP/1.1:
* * A string of text is parsed as a single word if it is quoted * using double-quote marks.
* * The backslash character '\' MAY be used as a single-character * quoting mechanism only within quoted-string and comment * constructs.
*
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) qdtext =* Note: This pattern text uses a non-capturing group to * encapsulate the choice between a legal character (TEXT) and an * escaped character (quoted-pair) within the context of the * quoted-string. Any quoted-pair sequences must be reversed by * the consumer of the matched group.> quoted-pair = "\" CHAR TEXT = */ final protected static String httpQuotedStringPattern = "\\\"(?:\\\\\"|[^\\p{Cntrl}\\\"])*\\\"" ; /** * Returns true iff the character is an HTTP
CTL
* character. */ static public boolean isHttpCtlChar( char ch ) { int c = (int)ch; if( c >= 0 && c <= 31 ) return true; if( c == 127 ) return true; return false; } /** * Returns true iff the character is an HTTP *separator
character. */ static public boolean isHttpSeparatorChar( char ch ) { switch( ch ) { case '(': case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '"': case '/': case '[': case ']': case '?': case '=': case '{': case '}': case ' ': // ASCII space (32). case (char)0x09: // Horizontal tab (9). return true; } return false; } /** * Matches an HTTPtoken
, which consists of one or * more of any CHAR exceptCTL
or *separator
. */ final protected static String tok = "[^\\p{Cntrl}\\(\\)<>@,;:\\\\\\\"/\\[\\]\\?=\\{\\}\\s\\x09]+" ; /** * Returns true iff the {@link String} obeys the syntax rules * for an HTTPtoken
. */ static public boolean isHttpToken( String token ) { int len = token.length(); for( int i=0; iquoted-string * * From HTTP/1.1:
* * A string of text is parsed as a single word if it is quoted * using double-quote marks.
* * The backslash character '\' MAY be used as a single-character * quoting mechanism only within quoted-string and comment * constructs.
*
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) qdtext =* Note: This pattern text uses a non-capturing group to * encapsulate the choice between a legal character (TEXT) and an * escaped character (quoted-pair) within the context of the * quoted-string. Any quoted-pair sequences must be reversed by * the consumer of the matched group.> quoted-pair = "\" CHAR TEXT = */ final protected static String qs = "\\\"(?:\\\\\"|[^\\p{Cntrl}\\\"])*\\\"" ; /** * Pattern used to match the type/subtype of a MIME expression. * The matched groups are numbered by the opening parentheses in * the pattern. The different matching groups are:
-
*
*
- group(0) : the matched input. * *
- group(1) : type * *
- group(2) : subtype * *
- group(3) : the rest of the input, to which you then apply * {@link #m_p2}. * *
-
*
*
- group( 0 ) : parameter ( attribute=value ). * *
- group( 1 ) : attribute (parameter name). * *
- group( 2 ) : value for that parameter. * *
*/
static protected Pattern m_p2 = null;
/**
* Initialization for shared {@link Pattern} object that matches
* valid MIME type expressions.
*/
static protected void init()
{
try {
if( m_p1 != null && m_p2 != null ) return;
m_p1 = Pattern.compile
( "^("+tok+")/("+tok+")(.*)$"
);
m_p2 = Pattern.compile
( "\\s*;\\s*("+tok+")=("+tok+"|"+qs+")\\s*"
);
}
catch( PatternSyntaxException ex ) {
/* Masquerade this exception so that it does not show up
* on method signatures throughout this and other
* packages. The decision to use java.util.regex here is
* an implementation decision and its exception signatures
* should not be propagated.
*/
AssertionError err = new AssertionError
( "Could not compile regex patterns."
);
err.initCause( ex );
throw err;
}
}
/**
* Returns the MIME type parameter value as either an HTTP
* token
or HTTP quoted-string
depending
* on whether or not it contains any characters that need to be
* escaped.
*
* @param force When true the returned value is always a
* quoted-string
.
*/
static public String quoteString
( String value,
boolean force
)
{
StringBuffer sb = new StringBuffer();
int len = value.length();
boolean didEscape = false;
for( int i=0; i