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
284
285
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 }