Coverage Report - org.mule.transport.http.HttpServerConnection
 
Classes in this File Line Coverage Branch Coverage Complexity
HttpServerConnection
56%
61/109
43%
23/54
3.4
 
 1  
 /*
 2  
  * $Id: HttpServerConnection.java 12117 2008-06-20 09:40:51Z 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.transport.http;
 12  
 
 13  
 import org.mule.RequestContext;
 14  
 import org.mule.api.transformer.TransformerException;
 15  
 import org.mule.api.transport.Connector;
 16  
 import org.mule.api.transport.OutputHandler;
 17  
 
 18  
 import java.io.DataOutputStream;
 19  
 import java.io.IOException;
 20  
 import java.io.InputStream;
 21  
 import java.io.OutputStream;
 22  
 import java.io.UnsupportedEncodingException;
 23  
 import java.net.Socket;
 24  
 import java.net.SocketException;
 25  
 import java.util.Iterator;
 26  
 
 27  
 import org.apache.commons.httpclient.ChunkedOutputStream;
 28  
 import org.apache.commons.httpclient.Header;
 29  
 import org.apache.commons.httpclient.HttpParser;
 30  
 import org.apache.commons.httpclient.StatusLine;
 31  
 import org.apache.commons.io.IOUtils;
 32  
 import org.apache.commons.logging.Log;
 33  
 import org.apache.commons.logging.LogFactory;
 34  
 
 35  
 /** A connection to the SimpleHttpServer. */
 36  
 public class HttpServerConnection
 37  
 {
 38  2
     private static final Log logger = LogFactory.getLog(HttpServerConnection.class);
 39  
 
 40  
     private Socket socket;
 41  
     private final InputStream in;
 42  
     private final OutputStream out;
 43  152
     private boolean keepAlive = false;
 44  
     private final String encoding;
 45  
 
 46  
     public HttpServerConnection(final Socket socket, String encoding, HttpConnector connector) throws IOException
 47  
     {
 48  152
         super();
 49  
 
 50  152
         if (socket == null)
 51  
         {
 52  0
             throw new IllegalArgumentException("Socket may not be null");
 53  
         }
 54  
 
 55  152
         this.socket = socket;
 56  152
         this.socket.setTcpNoDelay(true);
 57  
         
 58  152
         if (connector.getReceiveBufferSize() != Connector.INT_VALUE_NOT_SET
 59  
             && socket.getReceiveBufferSize() != connector.getReceiveBufferSize())
 60  
         {
 61  0
             socket.setReceiveBufferSize(connector.getReceiveBufferSize());            
 62  
         }
 63  152
         if (connector.getServerSoTimeout() != Connector.INT_VALUE_NOT_SET
 64  
             && socket.getSoTimeout() != connector.getServerSoTimeout())
 65  
         {
 66  0
             socket.setSoTimeout(connector.getServerSoTimeout());
 67  
         }
 68  
         
 69  152
         this.in = socket.getInputStream();
 70  152
         this.out = new DataOutputStream(socket.getOutputStream());
 71  152
         this.encoding = encoding;
 72  152
     }
 73  
 
 74  
     public synchronized void close()
 75  
     {
 76  
         try
 77  
         {
 78  152
             if (socket != null)
 79  
             {
 80  152
                 if (logger.isDebugEnabled())
 81  
                 {
 82  0
                     logger.debug("Closing: " + socket);
 83  
                 }
 84  
 
 85  
                 try
 86  
                 {
 87  152
                     socket.shutdownOutput();
 88  
                 }
 89  0
                 catch (UnsupportedOperationException e)
 90  
                 {
 91  
                     //Can't shutdown in/output on SSL sockets
 92  152
                 }
 93  
                 
 94  152
                 if (in != null)
 95  
                 {
 96  152
                     in.close();
 97  
                 }
 98  152
                 if (out != null)
 99  
                 {
 100  152
                     out.close();
 101  
                 }
 102  152
                 socket.close();
 103  
             }
 104  
         }
 105  0
         catch (IOException e)
 106  
         {
 107  0
             if (logger.isDebugEnabled())
 108  
             {
 109  0
                 logger.debug("(Ignored) Error closing the socket: " + e.getMessage());
 110  
             }
 111  
         }
 112  
         finally
 113  
         {
 114  152
             socket = null;
 115  152
         }
 116  152
     }
 117  
 
 118  
     public synchronized boolean isOpen()
 119  
     {
 120  152
         return this.socket != null;
 121  
     }
 122  
 
 123  
     public void setKeepAlive(boolean b)
 124  
     {
 125  315
         this.keepAlive = b;
 126  315
     }
 127  
 
 128  
     public boolean isKeepAlive()
 129  
     {
 130  152
         return this.keepAlive;
 131  
     }
 132  
 
 133  
     public InputStream getInputStream()
 134  
     {
 135  0
         return this.in;
 136  
     }
 137  
 
 138  
     public OutputStream getOutputStream()
 139  
     {
 140  0
         return this.out;
 141  
     }
 142  
 
 143  
     /**
 144  
      * Returns the ResponseWriter used to write the output to the socket.
 145  
      *
 146  
      * @return This connection's ResponseWriter
 147  
      */
 148  
     public ResponseWriter getWriter() throws UnsupportedEncodingException
 149  
     {
 150  0
         return new ResponseWriter(out);
 151  
     }
 152  
 
 153  
     public HttpRequest readRequest() throws IOException
 154  
     {
 155  
         try
 156  
         {
 157  158
             String line = readLine();
 158  157
             if (line == null)
 159  
             {
 160  3
                 return null;
 161  
             }
 162  154
             return new HttpRequest(RequestLine.parseLine(line), HttpParser.parseHeaders(this.in, encoding), this.in);
 163  
         }
 164  3
         catch (IOException e)
 165  
         {
 166  3
             close();
 167  3
             throw e;
 168  
         }
 169  
     }
 170  
 
 171  
     public HttpResponse readResponse() throws IOException
 172  
     {
 173  
         try
 174  
         {
 175  0
             String line = readLine();
 176  0
             return new HttpResponse(new StatusLine(line), HttpParser.parseHeaders(this.in, encoding), this.in);
 177  
         }
 178  0
         catch (IOException e)
 179  
         {
 180  0
             close();
 181  0
             throw e;
 182  
         }
 183  
     }
 184  
 
 185  
     private String readLine() throws IOException
 186  
     {
 187  
         String line;
 188  
 
 189  
         do
 190  
         {
 191  158
             line = HttpParser.readLine(in, encoding);
 192  
         }
 193  157
         while (line != null && line.length() == 0);
 194  
 
 195  157
         if (line == null)
 196  
         {
 197  3
             setKeepAlive(false);
 198  3
             return null;
 199  
         }
 200  
 
 201  154
         return line;
 202  
     }
 203  
 
 204  
     public void writeRequest(final HttpRequest request) throws IOException
 205  
     {
 206  0
         if (request == null)
 207  
         {
 208  0
             return;
 209  
         }
 210  0
         ResponseWriter writer = new ResponseWriter(this.out, encoding);
 211  0
         writer.println(request.getRequestLine().toString());
 212  0
         Iterator item = request.getHeaderIterator();
 213  0
         while (item.hasNext())
 214  
         {
 215  0
             Header header = (Header) item.next();
 216  0
             writer.print(header.toExternalForm());
 217  0
         }
 218  0
         writer.println();
 219  0
         writer.flush();
 220  
 
 221  0
         OutputStream outstream = this.out;
 222  0
         InputStream content = request.getBody();
 223  0
         if (content != null)
 224  
         {
 225  0
             Header transferenc = request.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
 226  0
             if (transferenc != null)
 227  
             {
 228  0
                 request.removeHeaders(HttpConstants.HEADER_CONTENT_LENGTH);
 229  0
                 if (transferenc.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
 230  
                 {
 231  0
                     outstream = new ChunkedOutputStream(outstream);
 232  
                 }
 233  
             }
 234  
 
 235  0
             IOUtils.copy(content, outstream);
 236  
 
 237  0
             if (outstream instanceof ChunkedOutputStream)
 238  
             {
 239  0
                 ((ChunkedOutputStream) outstream).finish();
 240  
             }
 241  
         }
 242  
 
 243  0
         outstream.flush();
 244  0
     }
 245  
 
 246  
     public void writeResponse(final HttpResponse response) throws IOException, TransformerException
 247  
     {
 248  154
         if (response == null)
 249  
         {
 250  0
             return;
 251  
         }
 252  
 
 253  154
         setKeepAlive(response.isKeepAlive());
 254  154
         ResponseWriter writer = new ResponseWriter(this.out, encoding);
 255  154
         OutputStream outstream = this.out;
 256  
 
 257  154
         writer.println(response.getStatusLine());
 258  154
         Iterator item = response.getHeaderIterator();
 259  944
         while (item.hasNext())
 260  
         {
 261  790
             Header header = (Header) item.next();
 262  790
             writer.print(header.toExternalForm());
 263  790
         }
 264  
 
 265  154
         writer.println();
 266  154
         writer.flush();
 267  
 
 268  154
         OutputHandler content = response.getBody();
 269  154
         if (content != null)
 270  
         {
 271  140
             Header transferenc = response.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
 272  140
             if (transferenc != null)
 273  
             {
 274  0
                 response.removeHeaders(HttpConstants.HEADER_CONTENT_LENGTH);
 275  0
                 if (transferenc.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
 276  
                 {
 277  0
                     outstream = new ChunkedOutputStream(outstream);
 278  
                 }
 279  
             }
 280  
 
 281  140
             content.write(RequestContext.getEvent(), outstream);
 282  
 
 283  140
             if (outstream instanceof ChunkedOutputStream)
 284  
             {
 285  0
                 ((ChunkedOutputStream) outstream).finish();
 286  
             }
 287  
         }
 288  
 
 289  154
         outstream.flush();
 290  154
     }
 291  
 
 292  
     public int getSocketTimeout() throws SocketException
 293  
     {
 294  0
         return this.socket.getSoTimeout();
 295  
     }
 296  
 
 297  
     public void setSocketTimeout(int timeout) throws SocketException
 298  
     {
 299  0
         this.socket.setSoTimeout(timeout);
 300  0
     }
 301  
 }