Coverage Report - org.mule.transport.http.HttpResponse
 
Classes in this File Line Coverage Branch Coverage Complexity
HttpResponse
0%
0/130
0%
0/58
2.273
HttpResponse$1
0%
0/3
N/A
2.273
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport.http;
 8  
 
 9  
 import org.mule.RequestContext;
 10  
 import org.mule.api.MuleEvent;
 11  
 import org.mule.api.MuleMessage;
 12  
 import org.mule.api.transport.OutputHandler;
 13  
 import org.mule.transformer.types.DataTypeFactory;
 14  
 import org.mule.transport.NullPayload;
 15  
 
 16  
 import java.io.ByteArrayOutputStream;
 17  
 import java.io.IOException;
 18  
 import java.io.InputStream;
 19  
 import java.io.OutputStream;
 20  
 import java.io.UnsupportedEncodingException;
 21  
 import java.util.Iterator;
 22  
 
 23  
 import org.apache.commons.httpclient.ChunkedInputStream;
 24  
 import org.apache.commons.httpclient.ContentLengthInputStream;
 25  
 import org.apache.commons.httpclient.Header;
 26  
 import org.apache.commons.httpclient.HeaderElement;
 27  
 import org.apache.commons.httpclient.HeaderGroup;
 28  
 import org.apache.commons.httpclient.HttpStatus;
 29  
 import org.apache.commons.httpclient.HttpVersion;
 30  
 import org.apache.commons.httpclient.NameValuePair;
 31  
 import org.apache.commons.httpclient.StatusLine;
 32  
 
 33  
 /**
 34  
  * A generic HTTP response wrapper.
 35  
  */
 36  
 public class HttpResponse
 37  
 {
 38  
 
 39  
     public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";
 40  
 
 41  0
     private HttpVersion ver = HttpVersion.HTTP_1_1;
 42  0
     private int statusCode = HttpStatus.SC_OK;
 43  0
     private String phrase = HttpStatus.getStatusText(HttpStatus.SC_OK);
 44  0
     private HeaderGroup headers = new HeaderGroup();
 45  0
     private boolean keepAlive = false;
 46  0
     private boolean disableKeepAlive = false;
 47  0
     private String fallbackCharset = DEFAULT_CONTENT_CHARSET;
 48  
     private OutputHandler outputHandler;
 49  
 
 50  
     public HttpResponse()
 51  
     {
 52  0
         super();
 53  0
     }
 54  
 
 55  
     public HttpResponse(final StatusLine statusline, final Header[] headers, final InputStream content)
 56  
         throws IOException
 57  
     {
 58  0
         super();
 59  0
         if (statusline == null)
 60  
         {
 61  0
             throw new IllegalArgumentException("Status line may not be null");
 62  
         }
 63  0
         setStatusLine(HttpVersion.parse(statusline.getHttpVersion()), statusline.getStatusCode(),
 64  
             statusline.getReasonPhrase());
 65  0
         setHeaders(headers);
 66  0
         if (content != null)
 67  
         {
 68  0
             InputStream in = content;
 69  0
             Header contentLength = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_LENGTH);
 70  0
             Header transferEncoding = this.headers.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
 71  
 
 72  0
             if (transferEncoding != null)
 73  
             {
 74  0
                 if (transferEncoding.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
 75  
                 {
 76  0
                     in = new ChunkedInputStream(in);
 77  
                 }
 78  
             }
 79  0
             else if (contentLength != null)
 80  
             {
 81  0
                 long len = getContentLength();
 82  0
                 if (len >= 0)
 83  
                 {
 84  0
                     in = new ContentLengthInputStream(in, len);
 85  
                 }
 86  
             }
 87  
         }
 88  0
     }
 89  
 
 90  
     public void setStatusLine(final HttpVersion ver, int statuscode, final String phrase)
 91  
     {
 92  0
         if (ver == null)
 93  
         {
 94  0
             throw new IllegalArgumentException("HTTP version may not be null");
 95  
         }
 96  0
         if (statuscode <= 0)
 97  
         {
 98  0
             throw new IllegalArgumentException("Status code may not be negative or zero");
 99  
         }
 100  0
         this.ver = ver;
 101  0
         this.statusCode = statuscode;
 102  0
         if (phrase != null)
 103  
         {
 104  0
             this.phrase = phrase;
 105  
         }
 106  
         else
 107  
         {
 108  0
             this.phrase = HttpStatus.getStatusText(statuscode);
 109  
         }
 110  0
     }
 111  
 
 112  
     public void setStatusLine(final HttpVersion ver, int statuscode)
 113  
     {
 114  0
         setStatusLine(ver, statuscode, null);
 115  0
     }
 116  
 
 117  
     public String getPhrase()
 118  
     {
 119  0
         return this.phrase;
 120  
     }
 121  
 
 122  
     /**
 123  
      * @deprecated use {@link #getStatusCode()} instead
 124  
      * @return HTTP status code
 125  
      */
 126  
     public int getStatuscode()
 127  
     {
 128  0
         return this.getStatusCode();
 129  
     }
 130  
 
 131  
     public int getStatusCode()
 132  
     {
 133  0
         return this.statusCode;
 134  
     }
 135  
 
 136  
     public HttpVersion getHttpVersion()
 137  
     {
 138  0
         return this.ver;
 139  
     }
 140  
 
 141  
     public String getStatusLine()
 142  
     {
 143  0
         StringBuffer buffer = new StringBuffer(64);
 144  0
         buffer.append(this.ver);
 145  0
         buffer.append(' ');
 146  0
         buffer.append(this.statusCode);
 147  0
         if (this.phrase != null)
 148  
         {
 149  0
             buffer.append(' ');
 150  0
             buffer.append(this.phrase);
 151  
         }
 152  0
         return buffer.toString();
 153  
     }
 154  
 
 155  
     public boolean containsHeader(final String name)
 156  
     {
 157  0
         return this.headers.containsHeader(name);
 158  
     }
 159  
 
 160  
     public Header[] getHeaders()
 161  
     {
 162  0
         return this.headers.getAllHeaders();
 163  
     }
 164  
 
 165  
     public Header getFirstHeader(final String name)
 166  
     {
 167  0
         return this.headers.getFirstHeader(name);
 168  
     }
 169  
 
 170  
     public void removeHeaders(final String s)
 171  
     {
 172  0
         if (s == null)
 173  
         {
 174  0
             return;
 175  
         }
 176  0
         Header[] headers = this.headers.getHeaders(s);
 177  0
         for (int i = 0; i < headers.length; i++)
 178  
         {
 179  0
             this.headers.removeHeader(headers[i]);
 180  
         }
 181  0
     }
 182  
 
 183  
     public void addHeader(final Header header)
 184  
     {
 185  0
         if (header == null)
 186  
         {
 187  0
             return;
 188  
         }
 189  0
         this.headers.addHeader(header);
 190  0
     }
 191  
 
 192  
     public void setHeader(final Header header)
 193  
     {
 194  0
         if (header == null)
 195  
         {
 196  0
             return;
 197  
         }
 198  0
         removeHeaders(header.getName());
 199  0
         addHeader(header);
 200  0
     }
 201  
 
 202  
     public void setHeaders(final Header[] headers)
 203  
     {
 204  0
         if (headers == null)
 205  
         {
 206  0
             return;
 207  
         }
 208  0
         this.headers.setHeaders(headers);
 209  0
     }
 210  
 
 211  
     public Iterator getHeaderIterator()
 212  
     {
 213  0
         return this.headers.getIterator();
 214  
     }
 215  
 
 216  
     public String getCharset()
 217  
     {
 218  0
         String charset = getFallbackCharset();
 219  0
         Header contenttype = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_TYPE);
 220  0
         if (contenttype != null)
 221  
         {
 222  0
             HeaderElement values[] = contenttype.getElements();
 223  0
             if (values.length == 1)
 224  
             {
 225  0
                 NameValuePair param = values[0].getParameterByName("charset");
 226  0
                 if (param != null)
 227  
                 {
 228  0
                     charset = param.getValue();
 229  
                 }
 230  
             }
 231  
         }
 232  0
         return charset;
 233  
     }
 234  
 
 235  
     public long getContentLength()
 236  
     {
 237  0
         Header contentLength = this.headers.getFirstHeader(HttpConstants.HEADER_CONTENT_LENGTH);
 238  0
         if (contentLength != null)
 239  
         {
 240  
             try
 241  
             {
 242  0
                 return Long.parseLong(contentLength.getValue());
 243  
             }
 244  0
             catch (NumberFormatException e)
 245  
             {
 246  0
                 return -1;
 247  
             }
 248  
         }
 249  
         else
 250  
         {
 251  0
             return -1;
 252  
         }
 253  
     }
 254  
 
 255  
     public boolean hasBody()
 256  
     {
 257  0
         return outputHandler != null;
 258  
     }
 259  
 
 260  
     public OutputHandler getBody() throws IOException
 261  
     {
 262  0
         return outputHandler; 
 263  
     }
 264  
     
 265  
     public void setBody(MuleMessage msg) throws Exception
 266  
     {
 267  0
         if (msg == null) return;
 268  
 
 269  
         //TODO MULE-5005 response attachments
 270  
 //        if(msg.getOutboundAttachmentNames().size() > 0)
 271  
 //        {
 272  
 //            setBody(createMultipart());
 273  
 //            setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, MimeTypes.MULTIPART_MIXED));
 274  
 //            return;
 275  
 //        }
 276  
         
 277  0
         Object payload = msg.getPayload();
 278  0
         if (payload instanceof String)
 279  
         {
 280  0
             setBody(payload.toString());
 281  
         }
 282  0
         else if (payload instanceof NullPayload) 
 283  
         {
 284  0
             return;
 285  
         }
 286  0
         else if (payload instanceof byte[]) 
 287  
         {
 288  0
             setBody((byte[]) payload);
 289  
         }
 290  
         else 
 291  
         {
 292  0
             setBody(msg.getPayload(DataTypeFactory.create(OutputHandler.class)));
 293  
         }
 294  0
     }
 295  
     
 296  
     public void setBody(OutputHandler outputHandler) 
 297  
     {
 298  0
         this.outputHandler = outputHandler;
 299  0
     }
 300  
     
 301  
     public void setBody(final String string)
 302  
     {
 303  
         byte[] raw;
 304  
         try
 305  
         {
 306  0
             raw = string.getBytes(getCharset());
 307  
         }
 308  0
         catch (UnsupportedEncodingException e)
 309  
         {
 310  0
             raw = string.getBytes();
 311  0
         }
 312  0
         setBody(raw);
 313  0
     }
 314  
 
 315  
     private void setBody(final byte[] raw)
 316  
     {
 317  0
         if (!containsHeader(HttpConstants.HEADER_CONTENT_TYPE))
 318  
         {
 319  0
             setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, HttpConstants.DEFAULT_CONTENT_TYPE));
 320  
         }
 321  0
         if (!containsHeader(HttpConstants.HEADER_TRANSFER_ENCODING))
 322  
         {
 323  0
             setHeader(new Header(HttpConstants.HEADER_CONTENT_LENGTH, Long.toString(raw.length)));
 324  
         }        
 325  
         
 326  0
         this.outputHandler = new OutputHandler() {
 327  
 
 328  
             public void write(MuleEvent event, OutputStream out) throws IOException
 329  
             {
 330  0
                 out.write(raw);
 331  0
             }
 332  
             
 333  
         };
 334  0
     }
 335  
     
 336  
     public String getBodyAsString() throws IOException 
 337  
     {
 338  0
         if (!hasBody()) return "";
 339  
         
 340  0
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 341  
         
 342  0
         outputHandler.write(RequestContext.getEvent(), out);
 343  
         
 344  
         try
 345  
         {
 346  0
             return new String(out.toByteArray(), getCharset());
 347  
         }
 348  0
         catch (UnsupportedEncodingException e)
 349  
         {
 350  0
             return new String(out.toByteArray());
 351  
         }
 352  
     }
 353  
     
 354  
     public boolean isKeepAlive()
 355  
     {
 356  0
         return !disableKeepAlive && keepAlive;
 357  
     }
 358  
 
 359  
     public void setKeepAlive(boolean keepAlive)
 360  
     {
 361  0
         this.keepAlive = keepAlive;
 362  0
     }
 363  
     
 364  
     /**
 365  
      * The HTTTP spec suggests that for HTTP 1.1 persistent connections should be used, 
 366  
      * for HTTP 1.0 the connection should not be kept alive. This method sets up the keepAlive flag
 367  
      * according to the <code>version</code> that was passed in.
 368  
      */
 369  
     protected void setupKeepAliveFromRequestVersion(HttpVersion version)
 370  
     {
 371  0
         setKeepAlive(version.equals(HttpVersion.HTTP_1_1));
 372  0
     }
 373  
 
 374  
     public void disableKeepAlive(boolean keepalive)
 375  
     {
 376  0
         disableKeepAlive = keepalive;
 377  0
     }
 378  
 
 379  
     public String getFallbackCharset()
 380  
     {
 381  0
         return fallbackCharset;
 382  
     }
 383  
 
 384  
     public void setFallbackCharset(String overrideCharset)
 385  
     {
 386  0
         this.fallbackCharset = overrideCharset;
 387  0
     }
 388  
 
 389  
       //TODO MULE-5005 response attachments
 390  
 //    protected OutputHandler createMultipart() throws Exception
 391  
 //    {
 392  
 //
 393  
 //        return new OutputHandler() {
 394  
 //            public void write(MuleEvent event, OutputStream out) throws IOException
 395  
 //            {
 396  
 //                MultiPartOutputStream partStream = new MultiPartOutputStream(out, event.getEncoding());
 397  
 //                try
 398  
 //                {
 399  
 //                    MuleMessage msg = event.getMessage();
 400  
 //                    if (!(msg.getPayload() instanceof NullPayload))
 401  
 //                    {
 402  
 //                        String contentType = msg.getOutboundProperty(HttpConstants.HEADER_CONTENT_TYPE, MimeTypes.BINARY);
 403  
 //                        partStream.startPart(contentType);
 404  
 //                        try
 405  
 //                        {
 406  
 //                            partStream.getOut().write(msg.getPayloadAsBytes());
 407  
 //                        }
 408  
 //                        catch (Exception e)
 409  
 //                        {
 410  
 //                            throw new IOException(e);
 411  
 //                        }
 412  
 //                    }
 413  
 //                    //Write attachments
 414  
 //                    for (String name : event.getMessage().getOutboundAttachmentNames())
 415  
 //                    {
 416  
 //                        DataHandler dh = event.getMessage().getOutboundAttachment(name);
 417  
 //                        partStream.startPart(dh.getContentType());
 418  
 //                        partStream.getOut().write(IOUtils.toByteArray(dh.getInputStream()));
 419  
 //                    }
 420  
 //                }
 421  
 //                finally
 422  
 //                {
 423  
 //                    partStream.close();
 424  
 //                }
 425  
 //            }
 426  
 //        };
 427  
 //
 428  
 //    }
 429  
 
 430  
 }