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

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 except CTL 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 = >
quoted-pair = "\" CHAR
TEXT = 

* 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.

*/ 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 HTTP token, which consists of one or * more of any CHAR except CTL or * separator. */ final protected static String tok = "[^\\p{Cntrl}\\(\\)<>@,;:\\\\\\\"/\\[\\]\\?=\\{\\}\\s\\x09]+" ; /** * Returns true iff the {@link String} obeys the syntax rules * for an HTTP token. */ 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 = >
quoted-pair = "\" CHAR
TEXT = 

* 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.

*/ 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}. * *
*/ static protected Pattern m_p1 = null; /** * Pattern used to match the optional parameters of a MIME * expression. The matched groups are numbered by the opening * parentheses in the pattern. The source for the pattern is the * parameters as identified by {@link #m_p1}. The different * matching groups are:
    * *
  • group( 0 ) : parameter ( attribute=value ). * *
  • group( 1 ) : attribute (parameter name). * *
  • group( 2 ) : value for that parameter. * *
* * Note: You should match this pattern repeatedly until the input * is exhausted.

*/ 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; iquoted-string then we * strip of the quote characters now and translate any escaped * characters into themselves, e.g., '\"' => '"'. Otherwise * returns value. * * @param IllegalArgumentException If the value is a malformed * quoted string. For example, no closing quote character or no * character after an escape character. */ static public String unquoteString( String value ) throws IllegalArgumentException { String originalValue = value; // save. /* Do nothing unless a quoted-string. */ if( ! value.startsWith( "\"" ) ) { return value; } /* Drop off the quote characters. */ if( ! value.endsWith( "\"" ) ) { throw new IllegalArgumentException ( "Quoted string does not end with '\"'"+ " : "+originalValue ); } // Chop off the quote characters. value = value.substring ( 1, value.length() - 1 ); // Translate escaped characters. StringBuffer sb = new StringBuffer(); int len = value.length(); for( int i=0; ienum is an empty enumeration, * then this value is returned to the caller. */ public static String combineHeaders ( Enumeration values, String defaultValue ) { if( ! values.hasMoreElements() ) { return defaultValue; } StringBuffer sb = new StringBuffer(); boolean first = true; while( values.hasMoreElements() ) { String value = (String)values.nextElement(); if( ! first ) { sb.append( ", " ); } sb.append( value ); first = false; } return sb.toString(); } /** * Splits out the elements for an HTTP header value whose grammar * is a comma delimited list. */ public static String[] splitCommaList ( String value ) { log.debug ( "Header-Value: "+value ); String[] values = value.split ( "\\s*,\\s*" ); log.debug ( "Found "+values.length+" elements in list." ); return values; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy