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