2 // ========================================================================
3 // Copyright (c) 1995-2014 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.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.server;
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.nio.charset.StandardCharsets;
24 import java.util.concurrent.BlockingQueue;
25 import java.util.concurrent.CountDownLatch;
26 import java.util.concurrent.Executor;
27 import java.util.concurrent.LinkedBlockingQueue;
28 import java.util.concurrent.TimeUnit;
30 import org.eclipse.jetty.io.ByteArrayEndPoint;
31 import org.eclipse.jetty.io.ByteBufferPool;
32 import org.eclipse.jetty.io.Connection;
33 import org.eclipse.jetty.util.BufferUtil;
34 import org.eclipse.jetty.util.ssl.SslContextFactory;
35 import org.eclipse.jetty.util.thread.Scheduler;
37 public class LocalConnector extends AbstractConnector
39 private final BlockingQueue<LocalEndPoint> _connects = new LinkedBlockingQueue<>();
42 public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, int acceptors, ConnectionFactory... factories)
44 super(server,executor,scheduler,pool,acceptors,factories);
45 setIdleTimeout(30000);
48 public LocalConnector(Server server)
50 this(server, null, null, null, -1, new HttpConnectionFactory());
53 public LocalConnector(Server server, SslContextFactory sslContextFactory)
55 this(server, null, null, null, -1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
58 public LocalConnector(Server server, ConnectionFactory connectionFactory)
60 this(server, null, null, null, -1, connectionFactory);
63 public LocalConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory sslContextFactory)
65 this(server, null, null, null, -1, AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory));
69 public Object getTransport()
74 /** Sends requests and get responses based on thread activity.
75 * Returns all the responses received once the thread activity has
76 * returned to the level it was before the requests.
78 * This methods waits until the connection is closed or
79 * is idle for 1s before returning the responses.
80 * @param requests the requests
81 * @return the responses
82 * @throws Exception if the requests fail
84 public String getResponses(String requests) throws Exception
86 return getResponses(requests, 5, TimeUnit.SECONDS);
89 /** Sends requests and get responses based on thread activity.
90 * Returns all the responses received once the thread activity has
91 * returned to the level it was before the requests.
93 * This methods waits until the connection is closed or
94 * an idle period before returning the responses.
95 * @param requests the requests
96 * @param idleFor The time the response stream must be idle for before returning
97 * @param units The units of idleFor
98 * @return the responses
99 * @throws Exception if the requests fail
101 public String getResponses(String requests,long idleFor,TimeUnit units) throws Exception
103 ByteBuffer result = getResponses(BufferUtil.toBuffer(requests,StandardCharsets.UTF_8),idleFor,units);
104 return result==null?null:BufferUtil.toString(result,StandardCharsets.UTF_8);
107 /** Sends requests and get's responses based on thread activity.
108 * Returns all the responses received once the thread activity has
109 * returned to the level it was before the requests.
111 * This methods waits until the connection is closed or
112 * is idle for 1s before returning the responses.
113 * @param requestsBuffer the requests
114 * @return the responses
115 * @throws Exception if the requests fail
117 public ByteBuffer getResponses(ByteBuffer requestsBuffer) throws Exception
119 return getResponses(requestsBuffer, 5, TimeUnit.SECONDS);
122 /** Sends requests and get's responses based on thread activity.
123 * Returns all the responses received once the thread activity has
124 * returned to the level it was before the requests.
126 * This methods waits until the connection is closed or
127 * an idle period before returning the responses.
128 * @param requestsBuffer the requests
129 * @param idleFor The time the response stream must be idle for before returning
130 * @param units The units of idleFor
131 * @return the responses
132 * @throws Exception if the requests fail
134 public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
136 LOG.debug("requests {}", BufferUtil.toUTF8String(requestsBuffer));
137 LocalEndPoint endp = executeRequest(requestsBuffer);
138 endp.waitUntilClosedOrIdleFor(idleFor,units);
139 ByteBuffer responses = endp.takeOutput();
140 endp.getConnection().close();
141 LOG.debug("responses {}", BufferUtil.toUTF8String(responses));
146 * Execute a request and return the EndPoint through which
147 * responses can be received.
148 * @param rawRequest the request
149 * @return the local endpoint
151 public LocalEndPoint executeRequest(String rawRequest)
153 return executeRequest(BufferUtil.toBuffer(rawRequest, StandardCharsets.UTF_8));
156 private LocalEndPoint executeRequest(ByteBuffer rawRequest)
158 LocalEndPoint endp = new LocalEndPoint();
159 endp.setInput(rawRequest);
165 protected void accept(int acceptorID) throws IOException, InterruptedException
167 LOG.debug("accepting {}", acceptorID);
168 LocalEndPoint endPoint = _connects.take();
170 onEndPointOpened(endPoint);
172 Connection connection = getDefaultConnectionFactory().newConnection(this, endPoint);
173 endPoint.setConnection(connection);
178 public class LocalEndPoint extends ByteArrayEndPoint
180 private final CountDownLatch _closed = new CountDownLatch(1);
182 public LocalEndPoint()
184 super(getScheduler(), LocalConnector.this.getIdleTimeout());
188 public void addInput(String s)
190 // TODO this is a busy wait
191 while(getIn()==null || BufferUtil.hasContent(getIn()))
193 setInput(BufferUtil.toBuffer(s, StandardCharsets.UTF_8));
199 boolean wasOpen=isOpen();
203 // connectionClosed(getConnection());
204 getConnection().onClose();
210 public void onClose()
212 LocalConnector.this.onEndPointClosed(this);
218 public void shutdownOutput()
220 super.shutdownOutput();
224 public void waitUntilClosed()
230 if (!_closed.await(10,TimeUnit.SECONDS))
240 public void waitUntilClosedOrIdleFor(long idleFor,TimeUnit units)
243 int size=getOutput().remaining();
248 if (!_closed.await(idleFor,units))
250 if (size==getOutput().remaining())
252 LOG.debug("idle for {} {}",idleFor,units);
255 size=getOutput().remaining();