1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.transport.impl.jetty;
17
18 import org.eclipse.jetty.server.AbstractHttpConnection;
19 import org.eclipse.jetty.server.Connector;
20 import org.eclipse.jetty.server.Request;
21 import org.eclipse.jetty.server.Server;
22 import org.eclipse.jetty.server.bio.SocketConnector;
23 import org.eclipse.jetty.servlet.ServletContextHandler;
24 import org.eclipse.jetty.servlet.ServletHolder;
25 import org.eclipse.jetty.util.thread.ExecutorThreadPool;
26 import org.fourthline.cling.transport.spi.ServletContainerAdapter;
27
28 import javax.servlet.Servlet;
29 import javax.servlet.http.HttpServletRequest;
30 import java.io.IOException;
31 import java.net.Socket;
32 import java.util.concurrent.ExecutorService;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class JettyServletContainer implements ServletContainerAdapter {
51
52 final private static Logger log = Logger.getLogger(JettyServletContainer.class.getName());
53
54
55 public static final JettyServletContainer INSTANCE = new JettyServletContainer();
56 private JettyServletContainer() {
57 resetServer();
58 }
59
60 protected Server server;
61
62 @Override
63 synchronized public void setExecutorService(ExecutorService executorService) {
64 if (INSTANCE.server.getThreadPool() == null) {
65 INSTANCE.server.setThreadPool(new ExecutorThreadPool(executorService) {
66 @Override
67 protected void doStop() throws Exception {
68
69 }
70 });
71 }
72 }
73
74 @Override
75 synchronized public int addConnector(String host, int port) throws IOException {
76 SocketConnector connector = new SocketConnector();
77 connector.setHost(host);
78 connector.setPort(port);
79
80
81 connector.open();
82
83
84 server.addConnector(connector);
85
86
87 if (server.isStarted()) {
88 try {
89 connector.start();
90 } catch (Exception ex) {
91 log.severe("Couldn't start connector: " + connector + " " + ex);
92 throw new RuntimeException(ex);
93 }
94 }
95 return connector.getLocalPort();
96 }
97
98 @Override
99 synchronized public void removeConnector(String host, int port) {
100 Connector[] connectors = server.getConnectors();
101 for (Connector connector : connectors) {
102 if (connector.getHost().equals(host) && connector.getLocalPort() == port) {
103 if (connector.isStarted() || connector.isStarting()) {
104 try {
105 connector.stop();
106 } catch (Exception ex) {
107 log.severe("Couldn't stop connector: " + connector + " " + ex);
108 throw new RuntimeException(ex);
109 }
110 }
111 server.removeConnector(connector);
112 if (connectors.length == 1) {
113 log.info("No more connectors, stopping Jetty server");
114 stopIfRunning();
115 }
116 break;
117 }
118 }
119 }
120
121 @Override
122 synchronized public void registerServlet(String contextPath, Servlet servlet) {
123 if (server.getHandler() != null) {
124 return;
125 }
126 log.info("Registering UPnP servlet under context path: " + contextPath);
127 ServletContextHandler servletHandler =
128 new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
129 if (contextPath != null && contextPath.length() > 0)
130 servletHandler.setContextPath(contextPath);
131 ServletHolder s = new ServletHolder(servlet);
132 servletHandler.addServlet(s, "/*");
133 server.setHandler(servletHandler);
134 }
135
136 @Override
137 synchronized public void startIfNotRunning() {
138 if (!server.isStarted() && !server.isStarting()) {
139 log.info("Starting Jetty server... ");
140 try {
141 server.start();
142 } catch (Exception ex) {
143 log.severe("Couldn't start Jetty server: " + ex);
144 throw new RuntimeException(ex);
145 }
146 }
147 }
148
149 @Override
150 synchronized public void stopIfRunning() {
151 if (!server.isStopped() && !server.isStopping()) {
152 log.info("Stopping Jetty server...");
153 try {
154 server.stop();
155 } catch (Exception ex) {
156 log.severe("Couldn't stop Jetty server: " + ex);
157 throw new RuntimeException(ex);
158 } finally {
159 resetServer();
160 }
161 }
162 }
163
164 protected void resetServer() {
165 server = new Server();
166 server.setGracefulShutdown(1000);
167 }
168
169
170
171
172
173
174
175
176
177 public static boolean isConnectionOpen(HttpServletRequest request) {
178 return isConnectionOpen(request, " ".getBytes());
179 }
180
181 public static boolean isConnectionOpen(HttpServletRequest request, byte[] heartbeat) {
182 Request jettyRequest = (Request)request;
183 AbstractHttpConnection connection = jettyRequest.getConnection();
184 Socket socket = (Socket)connection.getEndPoint().getTransport();
185 if (log.isLoggable(Level.FINE))
186 log.fine("Checking if client connection is still open: " + socket.getRemoteSocketAddress());
187 try {
188 socket.getOutputStream().write(heartbeat);
189 socket.getOutputStream().flush();
190 return true;
191 } catch (IOException ex) {
192 if (log.isLoggable(Level.FINE))
193 log.fine("Client connection has been closed: " + socket.getRemoteSocketAddress());
194 return false;
195 }
196 }
197
198 }