PageRenderTime 25ms CodeModel.GetById 19ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/test/src/solidstack/httpserver/HttpHeaderTokenizer.java

http://solidstack.googlecode.com/
Java | 158 lines | 102 code | 20 blank | 36 comment | 30 complexity | b99a57e2b57aa8411c65a58511f67299 MD5 | raw file
Possible License(s): Apache-2.0
  1/*--
  2 * Copyright 2010 René M. de Bloois
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *     http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 * See the License for the specific language governing permissions and
 14 * limitations under the License.
 15 */
 16
 17package solidstack.httpserver;
 18
 19import java.io.IOException;
 20import java.io.InputStream;
 21
 22import solidstack.io.FatalIOException;
 23
 24
 25public class HttpHeaderTokenizer
 26{
 27	/**
 28	 * The reader used to read from and push back characters.
 29	 */
 30	protected InputStream in;
 31
 32
 33	/**
 34	 * Constructs a new instance of the HttpHeaderTokenizer.
 35	 *
 36	 * @param in The input.
 37	 */
 38	public HttpHeaderTokenizer( InputStream in )
 39	{
 40		this.in = in;
 41	}
 42
 43	/**
 44	 * Is the given character a whitespace?
 45	 *
 46	 * @param ch The character to check.
 47	 * @return True if the characters is whitespace, false otherwise.
 48	 */
 49	protected boolean isWhitespace( int ch )
 50	{
 51		switch( ch )
 52		{
 53			case ' ':
 54			case '\t':
 55				return true;
 56		}
 57		return false;
 58	}
 59
 60	public String getLine()
 61	{
 62		try
 63		{
 64			StringBuilder result = new StringBuilder();
 65			while( true )
 66			{
 67				int ch = this.in.read();
 68				if( ch == -1 )
 69					throw new HttpException( "Unexpected end of line" );
 70				if( ch == '\r' )
 71					continue;
 72				if( ch == '\n' )
 73					return result.toString();
 74				result.append( (char)ch );
 75			}
 76		}
 77		catch( IOException e )
 78		{
 79			throw new FatalIOException( e );
 80		}
 81	}
 82
 83	public Token getField()
 84	{
 85		try
 86		{
 87			int ch = this.in.read();
 88
 89			// Ignore whitespace
 90			while( isWhitespace( ch ) && ch != -1 )
 91				ch = this.in.read();
 92
 93			// Ignore carriage return
 94			if( ch == '\r' )
 95				ch = this.in.read();
 96
 97			// Empty line means end of input for the header
 98			if( ch == '\n' )
 99				return new Token( null );
100
101			StringBuilder result = new StringBuilder();
102			while( ch != ':' && !isWhitespace( ch ) )
103			{
104				if( ch == -1 )
105					throw new HttpException( "Unexpected end of statement" );
106				if( ch == '\n' )
107					throw new HttpException( "Unexpected end of line" );
108				result.append( (char)ch );
109				ch = this.in.read();
110			}
111
112			// Ignore whitespace
113			while( isWhitespace( ch ) && ch != -1 )
114				ch = this.in.read();
115
116			if( ch != ':' )
117				throw new HttpException( "Expecting a :" );
118
119			// Return the result
120			if( result.length() == 0 )
121				throw new HttpException( "Empty header field" );
122
123			return new Token( result.toString() );
124		}
125		catch( IOException e )
126		{
127			throw new FatalIOException( e );
128		}
129	}
130
131	public Token getValue()
132	{
133		try
134		{
135			// Read whitespace
136			int ch = this.in.read();
137			while( isWhitespace( ch ) )
138				ch = this.in.read();
139
140			// Read everything until end-of-line
141			StringBuilder result = new StringBuilder();
142			while( true )
143			{
144				if( ch == -1 )
145					throw new HttpException( "Unexpected end-of-input" );
146				if( ch == '\n' ) // TODO Multiline header field values (space or tab)
147					return new Token( result.toString() );
148				if( ch != '\r' ) // ignore carriage return
149					result.append( (char)ch );
150				ch = this.in.read();
151			}
152		}
153		catch( IOException e )
154		{
155			throw new FatalIOException( e );
156		}
157	}
158}