/*********************************************************************
* HttpRequest.java
* created on 04.03.2005 by netseeker
* $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/http/HttpRequest.java,v $
* $Date: 2007/11/17 10:57:02 $
* $Revision: 1.3 $
*
* ====================================================================
*
* Copyright 2005-2006 netseeker aka Michael Manske
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This file is part of the ejoe framework.
* For more information on the author, please see
* <http://www.manskes.de/>.
*
*********************************************************************/
package de.netseeker.ejoe.http;
import java.io.IOException;
import java.nio.ByteBuffer;
import de.netseeker.ejoe.ConnectionHeader;
import de.netseeker.ejoe.EJConstants;
import de.netseeker.ejoe.adapter.AdapterFactory;
import de.netseeker.ejoe.io.ByteBufferOutputStream;
import de.netseeker.ejoe.io.IOUtil;
/**
* A simple container encapsulating a HTTP header. Additional methods are provided to convert such a header into
* ByteBuffer and/or String representations
*
* @author netseeker
* @since 0.3.9.1
*/
public class HttpRequest
{
public static final String HTTP_GET = "GET";
public static final String HTTP_POST = "POST";
public static final String HTTP_HEAD = "HEAD";
protected static final String CHARSET = "ISO-8859-1";
protected static final String LINE_SEP = "\r\n";
private static final String HDR_CHUNK1 = " HTTP/1.0" + LINE_SEP + "Host: ";
private static final String HDR_CHUNK2 = LINE_SEP + "User-Agent: EJClient/" + EJConstants.EJOE_VERSION
+ LINE_SEP + "Content-Type: ";
private static final String HDR_CHUNK3 = LINE_SEP + "Connection: ";
private static final String HDR_CHUNK4 = LINE_SEP + "Accept-Encoding: x-gzip";
private static final String HDR_CHUNK5 = LINE_SEP + "Content-Length: ";
private static final String HDR_CHUNK6 = LINE_SEP + LINE_SEP;
protected ByteBufferOutputStream _out = new ByteBufferOutputStream();
protected ConnectionHeader _header;
private String _method;
private String _host;
private String _contentType;
/**
* Creates a new HTTP request using the given connection header and the given HTTP method (HEAD, POST). The host
* name will be taken from the given connection header. The content (mime) type will be determined from the
* SerializeAdapter as declared in the connection header. If the connection header does not declare a
* SerializeAdapter the default content type will be used.
*
* @param header a valid connection header
* @param method a valid HTTP method string
*/
public HttpRequest(ConnectionHeader header, String method)
{
this( header, header.hasAdapter() ? AdapterFactory.getSupportedContentType( header.getAdapterName() )
: EJConstants.HTTP_DEFAULT_CONTENTTYPE, method );
}
/**
* Creates a new HTTP request using the given connection header, the given HTTP method (HEAD, POST) and the given
* content (mime) type. The host name will be taken from the given connection header.
*
* @param header a valid connection header
* @param contentType a valid mime type string
* @param method a valid HTTP method string
*/
public HttpRequest(ConnectionHeader header, String contentType, String method)
{
this( header, header.getHost(), contentType, method );
}
/**
* Creates a new HTTP request using the given connection header, the given host name, the given content (mime) type
* and the given HTTP method (HEAD, POST).
*
* @param header a valid connection header
* @param host name of the target HOST
* @param contentType a valid mime type string
* @param method a valid HTTP method string
*/
public HttpRequest(ConnectionHeader header, String host, String contentType, String method)
{
this._header = header;
this._host = host;
this._contentType = contentType;
this._method = method;
}
/**
* @return the content type
*/
public String getContentType()
{
return _contentType;
}
/**
* @return the host
*/
public String getHost()
{
return _host;
}
/**
* @return the HTTP method
*/
public String getMethod()
{
return _method;
}
/**
* @param data
*/
public void addData( byte data )
{
try
{
_out.write( data );
}
catch ( IOException e )
{
//
}
}
/**
* @param data
*/
public void addData( int data )
{
try
{
_out.write( data );
}
catch ( IOException e )
{
//
}
}
/**
* @param data
*/
public void addData( byte[] data )
{
try
{
_out.write( data );
}
catch ( IOException e )
{
//
}
}
/**
* @param data
*/
public void addData( String data )
{
try
{
_out.write( IOUtil.encodeToBytes( data, "UTF-8" ) );
}
catch ( IOException e )
{
}
}
/**
* @param data
*/
public void addData( ByteBuffer data )
{
_out.write( data );
}
/**
* Transforms this HTTP request into a ByteBuffer
*
* @return a ByteBuffer containing the encoded HTTP request data
*/
public ByteBuffer toByteBuffer()
{
ByteBuffer result = null;
ByteBufferOutputStream lOut = null;
try
{
lOut = new ByteBufferOutputStream();
lOut.write( IOUtil.encodeToBytes( toHeaderString(), CHARSET ) );
ByteBuffer buffer = this._out.getBackingBuffer();
int pos = buffer.position();
int limit = buffer.limit();
buffer.flip();
lOut.write( buffer );
result = lOut.getBackingBuffer();
result.flip();
buffer.limit( limit );
buffer.position( pos );
}
catch ( IOException e )
{
//
}
finally
{
IOUtil.closeQuiet( lOut );
}
return result;
}
/**
* Transforms only the contained HTTP header into a string representation
*
* @return a string representation of this HTTP header
*/
protected String toHeaderString()
{
StringBuffer sb = new StringBuffer( this._method );
sb.append( " " );
sb.append( this._header.toString() );
sb.append( HDR_CHUNK1 );
sb.append( this._host );
sb.append( HDR_CHUNK2 );
sb.append( this._contentType );
sb.append( HDR_CHUNK3 );
sb.append( this._header.isPersistent() ? "keep-alive" : "close" );
if ( this._header.hasCompression() )
{
sb.append( HDR_CHUNK4 );
}
sb.append( HDR_CHUNK5 );
sb.append( this._out.getBackingBuffer().position() );
sb.append( HDR_CHUNK6 );
return sb.toString();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString()
{
String str = toHeaderString();
str += IOUtil.decodeToString( this._out.getBackingBuffer(), "UTF-8" );
return str;
}
/**
* Resets all data appended to this request
*/
public void reset()
{
this._out.reset();
}
/**
* @return the underlying OutputStream used to append request data
*/
public final ByteBufferOutputStream getOutputStream()
{
return this._out;
}
}