View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.server;
20  
21  import java.io.IOException;
22  import java.util.concurrent.BlockingQueue;
23  import java.util.concurrent.CountDownLatch;
24  import java.util.concurrent.LinkedBlockingQueue;
25  import java.util.concurrent.TimeUnit;
26  
27  import org.eclipse.jetty.io.ByteArrayBuffer;
28  import org.eclipse.jetty.io.ByteArrayEndPoint;
29  import org.eclipse.jetty.io.Connection;
30  import org.eclipse.jetty.util.StringUtil;
31  import org.eclipse.jetty.util.log.Log;
32  import org.eclipse.jetty.util.log.Logger;
33  
34  public class LocalConnector extends AbstractConnector
35  {
36      private static final Logger LOG = Log.getLogger(LocalConnector.class);
37      private final BlockingQueue<Request> _requests = new LinkedBlockingQueue<Request>();
38      
39      public LocalConnector()
40      {
41          setMaxIdleTime(30000);
42      }
43  
44      public Object getConnection()
45      {
46          return this;
47      }
48  
49      public String getResponses(String requests) throws Exception
50      {
51          return getResponses(requests, false);
52      }
53  
54      public String getResponses(String requests, boolean keepOpen) throws Exception
55      {
56          ByteArrayBuffer result = getResponses(new ByteArrayBuffer(requests, StringUtil.__ISO_8859_1), keepOpen);
57          return result==null?null:result.toString(StringUtil.__ISO_8859_1);
58      }
59  
60      public ByteArrayBuffer getResponses(ByteArrayBuffer requestsBuffer, boolean keepOpen) throws Exception
61      {
62          CountDownLatch latch = new CountDownLatch(1);
63          Request request = new Request(requestsBuffer, keepOpen, latch);
64          _requests.add(request);
65          latch.await(getMaxIdleTime(),TimeUnit.MILLISECONDS);
66          return request.getResponsesBuffer();
67      }
68  
69      @Override
70      protected void accept(int acceptorID) throws IOException, InterruptedException
71      {
72          Request request = _requests.take();
73          getThreadPool().dispatch(request);
74      }
75  
76      public void open() throws IOException
77      {
78      }
79  
80      public void close() throws IOException
81      {
82      }
83  
84      public int getLocalPort()
85      {
86          return -1;
87      }
88  
89      public void executeRequest(String rawRequest) throws IOException
90      {
91          Request request = new Request(new ByteArrayBuffer(rawRequest, "UTF-8"), true, null);
92          _requests.add(request);
93      }
94  
95      private class Request implements Runnable
96      {
97          private final ByteArrayBuffer _requestsBuffer;
98          private final boolean _keepOpen;
99          private final CountDownLatch _latch;
100         private volatile ByteArrayBuffer _responsesBuffer;
101 
102         private Request(ByteArrayBuffer requestsBuffer, boolean keepOpen, CountDownLatch latch)
103         {
104             _requestsBuffer = requestsBuffer;
105             _keepOpen = keepOpen;
106             _latch = latch;
107         }
108 
109         public void run()
110         {
111             try
112             {
113                 ByteArrayEndPoint endPoint = new ByteArrayEndPoint(_requestsBuffer.asArray(), 1024)
114                 {
115                     @Override
116                     public void setConnection(Connection connection)
117                     {
118                         if (getConnection()!=null && connection!=getConnection())
119                             connectionUpgraded(getConnection(),connection);
120                         super.setConnection(connection);
121                     }
122                 };
123 
124                 endPoint.setGrowOutput(true);
125                 AbstractHttpConnection connection = new BlockingHttpConnection(LocalConnector.this, endPoint, getServer());
126                 endPoint.setConnection(connection);
127                 connectionOpened(connection);
128 
129                 boolean leaveOpen = _keepOpen;
130                 try
131                 {
132                     while (endPoint.getIn().length() > 0 && endPoint.isOpen())
133                     {
134                         while (true)
135                         {
136                             final Connection con = endPoint.getConnection();
137                             final Connection next = con.handle();
138                             if (next!=con)
139                             {  
140                                 endPoint.setConnection(next);
141                                 continue;
142                             }
143                             break;
144                         }
145                     }
146                 }
147                 catch (IOException x)
148                 {
149                     LOG.debug(x);
150                     leaveOpen = false;
151                 }
152                 catch (Exception x)
153                 {
154                     LOG.warn(x);
155                     leaveOpen = false;
156                 }
157                 finally
158                 {
159                     if (!leaveOpen)
160                         connectionClosed(connection);
161                     _responsesBuffer = endPoint.getOut();
162                 }
163             }
164             finally
165             {
166                 if (_latch != null)
167                     _latch.countDown();
168             }
169         }
170 
171         public ByteArrayBuffer getResponsesBuffer()
172         {
173             return _responsesBuffer;
174         }
175     }
176 }