1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.bio;
15
16 import java.io.IOException;
17 import java.net.InetAddress;
18 import java.net.ServerSocket;
19 import java.net.Socket;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.Set;
23
24 import org.eclipse.jetty.http.HttpException;
25 import org.eclipse.jetty.io.Buffer;
26 import org.eclipse.jetty.io.ByteArrayBuffer;
27 import org.eclipse.jetty.io.EndPoint;
28 import org.eclipse.jetty.io.EofException;
29 import org.eclipse.jetty.io.bio.SocketEndPoint;
30 import org.eclipse.jetty.server.AbstractConnector;
31 import org.eclipse.jetty.server.HttpConnection;
32 import org.eclipse.jetty.server.Request;
33 import org.eclipse.jetty.util.log.Log;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class SocketConnector extends AbstractConnector
49 {
50 protected ServerSocket _serverSocket;
51 protected final Set _connections;
52
53
54
55
56
57 public SocketConnector()
58 {
59 _connections=new HashSet();
60 }
61
62
63 public Object getConnection()
64 {
65 return _serverSocket;
66 }
67
68
69 public void open() throws IOException
70 {
71
72 if (_serverSocket==null || _serverSocket.isClosed())
73 _serverSocket= newServerSocket(getHost(),getPort(),getAcceptQueueSize());
74 _serverSocket.setReuseAddress(getReuseAddress());
75 }
76
77
78 protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
79 {
80 ServerSocket ss= host==null?
81 new ServerSocket(port,backlog):
82 new ServerSocket(port,backlog,InetAddress.getByName(host));
83
84 return ss;
85 }
86
87
88 public void close() throws IOException
89 {
90 if (_serverSocket!=null)
91 _serverSocket.close();
92 _serverSocket=null;
93 }
94
95
96 public void accept(int acceptorID)
97 throws IOException, InterruptedException
98 {
99 Socket socket = _serverSocket.accept();
100 configure(socket);
101
102 Connection connection=new Connection(socket);
103 connection.dispatch();
104 }
105
106
107
108
109
110 protected HttpConnection newHttpConnection(EndPoint endpoint)
111 {
112 return new HttpConnection(this, endpoint, getServer());
113 }
114
115
116 public void customize(EndPoint endpoint, Request request)
117 throws IOException
118 {
119 Connection connection = (Connection)endpoint;
120 int lrmit = isLowResources()?_lowResourceMaxIdleTime:_maxIdleTime;
121 if (connection._sotimeout!=lrmit)
122 {
123 connection._sotimeout=lrmit;
124 ((Socket)endpoint.getTransport()).setSoTimeout(lrmit);
125 }
126
127 super.customize(endpoint, request);
128 }
129
130
131 public int getLocalPort()
132 {
133 if (_serverSocket==null || _serverSocket.isClosed())
134 return -1;
135 return _serverSocket.getLocalPort();
136 }
137
138
139 protected void doStart() throws Exception
140 {
141 _connections.clear();
142 super.doStart();
143 }
144
145
146 protected void doStop() throws Exception
147 {
148 super.doStop();
149 Set set=null;
150
151 synchronized(_connections)
152 {
153 set= new HashSet(_connections);
154 }
155
156 Iterator iter=set.iterator();
157 while(iter.hasNext())
158 {
159 Connection connection = (Connection)iter.next();
160 connection.close();
161 }
162 }
163
164
165
166
167 protected class Connection extends SocketEndPoint implements Runnable
168 {
169 boolean _dispatched=false;
170 HttpConnection _connection;
171 int _sotimeout;
172 protected Socket _socket;
173
174 public Connection(Socket socket) throws IOException
175 {
176 super(socket);
177 _connection = newHttpConnection(this);
178 _sotimeout=socket.getSoTimeout();
179 _socket=socket;
180 }
181
182 public void dispatch() throws IOException
183 {
184 if (getThreadPool()==null || !getThreadPool().dispatch(this))
185 {
186 Log.warn("dispatch failed for {}",_connection);
187 close();
188 }
189 }
190
191 public int fill(Buffer buffer) throws IOException
192 {
193 int l = super.fill(buffer);
194 if (l<0)
195 close();
196 return l;
197 }
198
199 public void close() throws IOException
200 {
201 _connection.getRequest().getAsyncContinuation().cancel();
202 super.close();
203 }
204
205 public void run()
206 {
207 try
208 {
209 connectionOpened(_connection);
210 synchronized(_connections)
211 {
212 _connections.add(this);
213 }
214
215 while (isStarted() && !isClosed())
216 {
217 if (_connection.isIdle())
218 {
219 if (isLowResources())
220 {
221 int lrmit = getLowResourceMaxIdleTime();
222 if (lrmit>=0 && _sotimeout!= lrmit)
223 {
224 _sotimeout=lrmit;
225 _socket.setSoTimeout(_sotimeout);
226 }
227 }
228 }
229 _connection.handle();
230 }
231 }
232 catch (EofException e)
233 {
234 Log.debug("EOF", e);
235 try{close();}
236 catch(IOException e2){Log.ignore(e2);}
237 }
238 catch (HttpException e)
239 {
240 Log.debug("BAD", e);
241 try{close();}
242 catch(IOException e2){Log.ignore(e2);}
243 }
244 catch(Exception e)
245 {
246 Log.warn("handle failed?",e);
247 try{close();}
248 catch(IOException e2){Log.ignore(e2);}
249 }
250 finally
251 {
252 connectionClosed(_connection);
253 synchronized(_connections)
254 {
255 _connections.remove(this);
256 }
257 }
258 }
259 }
260 }