View Javadoc

1   /*
2    * $Id: HttpResponse.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.http;
12  
13  import java.io.ByteArrayInputStream;
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.io.UnsupportedEncodingException;
17  import java.util.Iterator;
18  
19  import org.apache.commons.httpclient.ChunkedInputStream;
20  import org.apache.commons.httpclient.ContentLengthInputStream;
21  import org.apache.commons.httpclient.Header;
22  import org.apache.commons.httpclient.HeaderElement;
23  import org.apache.commons.httpclient.HeaderGroup;
24  import org.apache.commons.httpclient.HttpStatus;
25  import org.apache.commons.httpclient.HttpVersion;
26  import org.apache.commons.httpclient.NameValuePair;
27  import org.apache.commons.httpclient.StatusLine;
28  import org.apache.commons.io.IOUtils;
29  import org.apache.commons.io.output.ByteArrayOutputStream;
30  
31  /**
32   * A generic HTTP response wrapper.
33   */
34  public class HttpResponse
35  {
36  
37      public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";
38      private static final int DEFAULT_BUFFER_SIZE = 8192;
39  
40      private HttpVersion ver = HttpVersion.HTTP_1_1;
41      private int statusCode = HttpStatus.SC_OK;
42      private String phrase = HttpStatus.getStatusText(HttpStatus.SC_OK);
43      private HeaderGroup headers = new HeaderGroup();
44      private InputStream entity = null;
45      private boolean keepAlive = false;
46      private boolean disableKeepAlive = false;
47      private String fallbackCharset = DEFAULT_CONTENT_CHARSET;
48  
49      public HttpResponse()
50      {
51          super();
52      }
53  
54      public HttpResponse(final StatusLine statusline, final Header[] headers, final InputStream content)
55          throws IOException
56      {
57          super();
58          if (statusline == null)
59          {
60              throw new IllegalArgumentException("Status line may not be null");
61          }
62          setStatusLine(HttpVersion.parse(statusline.getHttpVersion()), statusline.getStatusCode(),
63              statusline.getReasonPhrase());
64          setHeaders(headers);
65          if (content != null)
66          {
67              InputStream in = content;
68              Header contentLength = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_LENGTH);
69              Header transferEncoding = this.headers.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
70  
71              if (transferEncoding != null)
72              {
73                  if (transferEncoding.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
74                  {
75                      in = new ChunkedInputStream(in);
76                  }
77              }
78              else if (contentLength != null)
79              {
80                  long len = getContentLength();
81                  if (len >= 0)
82                  {
83                      in = new ContentLengthInputStream(in, len);
84                  }
85              }
86              this.entity = in;
87          }
88      }
89  
90      public void setStatusLine(final HttpVersion ver, int statuscode, final String phrase)
91      {
92          if (ver == null)
93          {
94              throw new IllegalArgumentException("HTTP version may not be null");
95          }
96          if (statuscode <= 0)
97          {
98              throw new IllegalArgumentException("Status code may not be negative or zero");
99          }
100         this.ver = ver;
101         this.statusCode = statuscode;
102         if (phrase != null)
103         {
104             this.phrase = phrase;
105         }
106         else
107         {
108             this.phrase = HttpStatus.getStatusText(statuscode);
109         }
110     }
111 
112     public void setStatusLine(final HttpVersion ver, int statuscode)
113     {
114         setStatusLine(ver, statuscode, null);
115     }
116 
117     public String getPhrase()
118     {
119         return this.phrase;
120     }
121 
122     /**
123      * @deprecated use {@link #getStatusCode()} instead
124      * @return HTTP status code
125      */
126     public int getStatuscode()
127     {
128         return this.getStatusCode();
129     }
130 
131     public int getStatusCode()
132     {
133         return this.statusCode;
134     }
135 
136     public HttpVersion getHttpVersion()
137     {
138         return this.ver;
139     }
140 
141     public String getStatusLine()
142     {
143         StringBuffer buffer = new StringBuffer(64);
144         buffer.append(this.ver);
145         buffer.append(' ');
146         buffer.append(this.statusCode);
147         if (this.phrase != null)
148         {
149             buffer.append(' ');
150             buffer.append(this.phrase);
151         }
152         return buffer.toString();
153     }
154 
155     public boolean containsHeader(final String name)
156     {
157         return this.headers.containsHeader(name);
158     }
159 
160     public Header[] getHeaders()
161     {
162         return this.headers.getAllHeaders();
163     }
164 
165     public Header getFirstHeader(final String name)
166     {
167         return this.headers.getFirstHeader(name);
168     }
169 
170     public void removeHeaders(final String s)
171     {
172         if (s == null)
173         {
174             return;
175         }
176         Header[] headers = this.headers.getHeaders(s);
177         for (int i = 0; i < headers.length; i++)
178         {
179             this.headers.removeHeader(headers[i]);
180         }
181     }
182 
183     public void addHeader(final Header header)
184     {
185         if (header == null)
186         {
187             return;
188         }
189         this.headers.addHeader(header);
190     }
191 
192     public void setHeader(final Header header)
193     {
194         if (header == null)
195         {
196             return;
197         }
198         removeHeaders(header.getName());
199         addHeader(header);
200     }
201 
202     public void setHeaders(final Header[] headers)
203     {
204         if (headers == null)
205         {
206             return;
207         }
208         this.headers.setHeaders(headers);
209     }
210 
211     public Iterator getHeaderIterator()
212     {
213         return this.headers.getIterator();
214     }
215 
216     public String getCharset()
217     {
218         String charset = getFallbackCharset();
219         Header contenttype = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_TYPE);
220         if (contenttype != null)
221         {
222             HeaderElement values[] = contenttype.getElements();
223             if (values.length == 1)
224             {
225                 NameValuePair param = values[0].getParameterByName("charset");
226                 if (param != null)
227                 {
228                     charset = param.getValue();
229                 }
230             }
231         }
232         return charset;
233     }
234 
235     public long getContentLength()
236     {
237         Header contentLength = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_LENGTH);
238         if (contentLength != null)
239         {
240             try
241             {
242                 return Long.parseLong(contentLength.getValue());
243             }
244             catch (NumberFormatException e)
245             {
246                 return -1;
247             }
248         }
249         else
250         {
251             return -1;
252         }
253     }
254 
255     public void setBodyString(final String string)
256     {
257         if (string != null)
258         {
259             byte[] raw;
260             try
261             {
262                 raw = string.getBytes(getCharset());
263             }
264             catch (UnsupportedEncodingException e)
265             {
266                 raw = string.getBytes();
267             }
268             this.entity = new ByteArrayInputStream(raw);
269             if (!containsHeader(HttpConstants.HEADER_CONTENT_TYPE))
270             {
271                 setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, HttpConstants.DEFAULT_CONTENT_TYPE));
272             }
273             setHeader(new Header(HttpConstants.HEADER_CONTENT_LENGTH, Long.toString(raw.length)));
274         }
275         else
276         {
277             this.entity = null;
278         }
279     }
280 
281     public void setBody(final InputStream instream)
282     {
283         this.entity = instream;
284     }
285 
286     public InputStream getBody()
287     {
288         return this.entity;
289     }
290 
291     public byte[] getBodyBytes() throws IOException
292     {
293         InputStream in = getBody();
294         if (in != null)
295         {
296             ByteArrayOutputStream buffer = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
297             IOUtils.copy(in, buffer);
298             return buffer.toByteArray();
299         }
300         else
301         {
302             return null;
303         }
304     }
305 
306     public String getBodyString() throws IOException
307     {
308         byte[] raw = getBodyBytes();
309         if (raw != null)
310         {
311             return new String(raw, getCharset());
312         }
313         else
314         {
315             return null;
316         }
317     }
318 
319     public boolean isKeepAlive()
320     {
321         return !disableKeepAlive && keepAlive;
322     }
323 
324     public void setKeepAlive(boolean keepAlive)
325     {
326         this.keepAlive = keepAlive;
327     }
328 
329     public void disableKeepAlive(boolean keepalive)
330     {
331         disableKeepAlive = keepalive;
332     }
333 
334     public String getFallbackCharset()
335     {
336         return fallbackCharset;
337     }
338 
339     public void setFallbackCharset(String overrideCharset)
340     {
341         this.fallbackCharset = overrideCharset;
342     }
343 
344 }