com.meterware.pseudoserver.ReceivedHttpMessage Maven / Gradle / Ivy
The newest version!
package com.meterware.pseudoserver;
/********************************************************************************************************************
* $Id: ReceivedHttpMessage.java 915 2008-04-14 19:39:44Z russgold $
*
* Copyright (c) 2003-2004, Russell Gold
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*******************************************************************************************************************/
import java.util.Enumeration;
import java.util.Hashtable;
import java.io.*;
/**
*
* @author Russell Gold
**/
abstract class ReceivedHttpMessage {
private static final int CR = 13;
private static final int LF = 10;
private Reader _reader;
private Hashtable _headers = new Hashtable();
private byte[] _requestBody;
ReceivedHttpMessage( InputStream inputStream ) throws IOException {
interpretMessageHeader( readHeaderLine( inputStream ) );
readHeaders( inputStream );
readMessageBody( inputStream );
}
public String toString() {
StringBuffer sb = new StringBuffer( getClassName() ).append( "[ " );
appendMessageHeader( sb );
sb.append( "\n" );
for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
Object key = e.nextElement();
sb.append( " " ).append( key ).append( ": " ).append( _headers.get( key ) ).append( "\n" );
}
sb.append( " body contains " ).append( getBody().length ).append( " byte(s)]" );
return sb.toString();
}
private String readHeaderLine( InputStream inputStream ) throws IOException {
return new String( readDelimitedChunk( inputStream ) );
}
private byte[] readDelimitedChunk( InputStream inputStream ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = inputStream.read();
while (b != CR) {
baos.write( b );
b = inputStream.read();
}
b = inputStream.read();
if (b != LF) throw new IOException( "Bad header line termination: " + b );
return baos.toByteArray();
}
void appendContents( StringBuffer sb ) {
for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
Object key = e.nextElement();
sb.append( " " ).append( key ).append( ": " ).append( _headers.get( key ) ).append( "\n" );
}
sb.append( " body contains " ).append( getBody().length ).append( " byte(s)" );
}
Reader getReader() {
return _reader;
}
String getHeader( String name ) {
return (String) _headers.get( name.toUpperCase() );
}
byte[] getBody() {
return _requestBody;
}
private void readMessageBody( InputStream inputStream ) throws IOException {
if ("chunked".equalsIgnoreCase( getHeader( "Transfer-Encoding" ) )) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (getNextChunkLength( inputStream ) > 0) {
baos.write( readDelimitedChunk( inputStream ) );
}
flushChunkTrailer( inputStream );
_requestBody = baos.toByteArray();
} else {
int totalExpected = getContentLength();
ByteArrayOutputStream baos = new ByteArrayOutputStream( totalExpected );
byte[] buffer = new byte[1024];
int total = 0;
int count = -1;
while ((total < totalExpected) && ((count = inputStream.read( buffer )) != -1)) {
baos.write( buffer, 0, count );
total += count;
}
baos.flush();
_requestBody = baos.toByteArray();
}
_reader = new InputStreamReader( new ByteArrayInputStream( _requestBody ) );
}
private void flushChunkTrailer( InputStream inputStream ) throws IOException {
byte[] line;
do { line = readDelimitedChunk( inputStream ); } while (line.length > 0);
}
private int getNextChunkLength( InputStream inputStream ) throws IOException {
try {
return Integer.parseInt( readHeaderLine( inputStream ), 16 );
} catch (NumberFormatException e) {
throw new IOException( "Unabled to read chunk length: " + e );
}
}
private int getContentLength() {
try {
return Integer.parseInt( getHeader( "Content-Length" ) );
} catch (NumberFormatException e) {
return 0;
}
}
private void readHeaders( InputStream inputStream ) throws IOException {
String lastHeader = null;
String header = readHeaderLine( inputStream );
while (header.length() > 0) {
if (header.charAt(0) <= ' ') {
if (lastHeader == null) continue;
_headers.put( lastHeader, _headers.get( lastHeader ) + header.trim() );
} else {
lastHeader = header.substring( 0, header.indexOf(':') ).toUpperCase();
_headers.put( lastHeader, header.substring( header.indexOf(':')+1 ).trim() );
}
header = readHeaderLine( inputStream );
}
}
private String getClassName() {
return getClass().getName().substring( getClass().getName().lastIndexOf( '.' )+1 );
}
abstract void appendMessageHeader( StringBuffer sb );
abstract void interpretMessageHeader( String messageHeader );
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy