View Javadoc

1   /**********************************************************************
2    * HttpRequest.java
3    * created on 04.03.2005 by netseeker
4    * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/http/HttpRequest.java,v $
5    * $Date: 2007/11/17 10:57:02 $
6    * $Revision: 1.3 $
7    *
8    * ====================================================================
9    *
10   *  Copyright 2005-2006 netseeker aka Michael Manske
11   *
12   *  Licensed under the Apache License, Version 2.0 (the "License");
13   *  you may not use this file except in compliance with the License.
14   *  You may obtain a copy of the License at
15   *
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the License for the specific language governing permissions and
22   *  limitations under the License.
23   * ====================================================================
24   *
25   * This file is part of the ejoe framework.
26   * For more information on the author, please see
27   * <http://www.manskes.de/>.
28   *
29   *********************************************************************/
30  package de.netseeker.ejoe.http;
31  
32  import java.io.IOException;
33  import java.nio.ByteBuffer;
34  
35  import de.netseeker.ejoe.ConnectionHeader;
36  import de.netseeker.ejoe.EJConstants;
37  import de.netseeker.ejoe.adapter.AdapterFactory;
38  import de.netseeker.ejoe.io.ByteBufferOutputStream;
39  import de.netseeker.ejoe.io.IOUtil;
40  
41  /***
42   * A simple container encapsulating a HTTP header. Additional methods are provided to convert such a header into
43   * ByteBuffer and/or String representations
44   * 
45   * @author netseeker
46   * @since 0.3.9.1
47   */
48  public class HttpRequest
49  {
50      public static final String       HTTP_GET   = "GET";
51  
52      public static final String       HTTP_POST  = "POST";
53  
54      public static final String       HTTP_HEAD  = "HEAD";
55  
56      protected static final String    CHARSET    = "ISO-8859-1";
57  
58      protected static final String    LINE_SEP   = "\r\n";
59  
60      private static final String      HDR_CHUNK1 = " HTTP/1.0" + LINE_SEP + "Host: ";
61  
62      private static final String      HDR_CHUNK2 = LINE_SEP + "User-Agent: EJClient/" + EJConstants.EJOE_VERSION
63                                                          + LINE_SEP + "Content-Type: ";
64  
65      private static final String      HDR_CHUNK3 = LINE_SEP + "Connection: ";
66  
67      private static final String      HDR_CHUNK4 = LINE_SEP + "Accept-Encoding: x-gzip";
68  
69      private static final String      HDR_CHUNK5 = LINE_SEP + "Content-Length: ";
70  
71      private static final String      HDR_CHUNK6 = LINE_SEP + LINE_SEP;
72  
73      protected ByteBufferOutputStream _out       = new ByteBufferOutputStream();
74  
75      protected ConnectionHeader       _header;
76  
77      private String                   _method;
78  
79      private String                   _host;
80  
81      private String                   _contentType;
82  
83      /***
84       * Creates a new HTTP request using the given connection header and the given HTTP method (HEAD, POST). The host
85       * name will be taken from the given connection header. The content (mime) type will be determined from the
86       * SerializeAdapter as declared in the connection header. If the connection header does not declare a
87       * SerializeAdapter the default content type will be used.
88       * 
89       * @param header a valid connection header
90       * @param method a valid HTTP method string
91       */
92      public HttpRequest(ConnectionHeader header, String method)
93      {
94          this( header, header.hasAdapter() ? AdapterFactory.getSupportedContentType( header.getAdapterName() )
95                  : EJConstants.HTTP_DEFAULT_CONTENTTYPE, method );
96      }
97  
98      /***
99       * Creates a new HTTP request using the given connection header, the given HTTP method (HEAD, POST) and the given
100      * content (mime) type. The host name will be taken from the given connection header.
101      * 
102      * @param header a valid connection header
103      * @param contentType a valid mime type string
104      * @param method a valid HTTP method string
105      */
106     public HttpRequest(ConnectionHeader header, String contentType, String method)
107     {
108         this( header, header.getHost(), contentType, method );
109     }
110 
111     /***
112      * Creates a new HTTP request using the given connection header, the given host name, the given content (mime) type
113      * and the given HTTP method (HEAD, POST).
114      * 
115      * @param header a valid connection header
116      * @param host name of the target HOST
117      * @param contentType a valid mime type string
118      * @param method a valid HTTP method string
119      */
120     public HttpRequest(ConnectionHeader header, String host, String contentType, String method)
121     {
122         this._header = header;
123         this._host = host;
124         this._contentType = contentType;
125         this._method = method;
126     }
127 
128     /***
129      * @return the content type
130      */
131     public String getContentType()
132     {
133         return _contentType;
134     }
135 
136     /***
137      * @return the host
138      */
139     public String getHost()
140     {
141         return _host;
142     }
143 
144     /***
145      * @return the HTTP method
146      */
147     public String getMethod()
148     {
149         return _method;
150     }
151 
152     /***
153      * @param data
154      */
155     public void addData( byte data )
156     {
157         try
158         {
159             _out.write( data );
160         }
161         catch ( IOException e )
162         {
163             //
164         }
165     }
166 
167     /***
168      * @param data
169      */
170     public void addData( int data )
171     {
172         try
173         {
174             _out.write( data );
175         }
176         catch ( IOException e )
177         {
178             //
179         }
180     }
181 
182     /***
183      * @param data
184      */
185     public void addData( byte[] data )
186     {
187         try
188         {
189             _out.write( data );
190         }
191         catch ( IOException e )
192         {
193             //
194         }
195     }
196 
197     /***
198      * @param data
199      */
200     public void addData( String data )
201     {
202         try
203         {
204             _out.write( IOUtil.encodeToBytes( data, "UTF-8" ) );
205         }
206         catch ( IOException e )
207         {
208         }
209     }
210 
211     /***
212      * @param data
213      */
214     public void addData( ByteBuffer data )
215     {
216         _out.write( data );
217     }
218 
219     /***
220      * Transforms this HTTP request into a ByteBuffer
221      * 
222      * @return a ByteBuffer containing the encoded HTTP request data
223      */
224     public ByteBuffer toByteBuffer()
225     {
226         ByteBuffer result = null;
227         ByteBufferOutputStream lOut = null;
228 
229         try
230         {
231             lOut = new ByteBufferOutputStream();
232             lOut.write( IOUtil.encodeToBytes( toHeaderString(), CHARSET ) );
233             ByteBuffer buffer = this._out.getBackingBuffer();
234             int pos = buffer.position();
235             int limit = buffer.limit();
236             buffer.flip();
237             lOut.write( buffer );
238             result = lOut.getBackingBuffer();
239             result.flip();
240             buffer.limit( limit );
241             buffer.position( pos );
242         }
243         catch ( IOException e )
244         {
245             //
246         }
247         finally
248         {
249             IOUtil.closeQuiet( lOut );
250         }
251 
252         return result;
253     }
254 
255     /***
256      * Transforms only the contained HTTP header into a string representation
257      * 
258      * @return a string representation of this HTTP header
259      */
260     protected String toHeaderString()
261     {
262         StringBuffer sb = new StringBuffer( this._method );
263         sb.append( " " );
264         sb.append( this._header.toString() );
265         sb.append( HDR_CHUNK1 );
266         sb.append( this._host );
267         sb.append( HDR_CHUNK2 );
268         sb.append( this._contentType );
269         sb.append( HDR_CHUNK3 );
270         sb.append( this._header.isPersistent() ? "keep-alive" : "close" );
271         if ( this._header.hasCompression() )
272         {
273             sb.append( HDR_CHUNK4 );
274         }
275         sb.append( HDR_CHUNK5 );
276         sb.append( this._out.getBackingBuffer().position() );
277         sb.append( HDR_CHUNK6 );
278 
279         return sb.toString();
280     }
281 
282     /*
283      * (non-Javadoc)
284      * 
285      * @see java.lang.Object#toString()
286      */
287     public String toString()
288     {
289         String str = toHeaderString();
290         str += IOUtil.decodeToString( this._out.getBackingBuffer(), "UTF-8" );
291         return str;
292     }
293 
294     /***
295      * Resets all data appended to this request
296      */
297     public void reset()
298     {
299         this._out.reset();
300     }
301 
302     /***
303      * @return the underlying OutputStream used to append request data
304      */
305     public final ByteBufferOutputStream getOutputStream()
306     {
307         return this._out;
308     }
309 }