1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.bio;
16
17 import java.io.IOException;
18 import java.net.InetAddress;
19 import java.net.ServerSocket;
20 import java.net.Socket;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Set;
24
25 import org.mortbay.io.Buffer;
26 import org.mortbay.io.ByteArrayBuffer;
27 import org.mortbay.io.EndPoint;
28 import org.mortbay.io.bio.SocketEndPoint;
29 import org.mortbay.jetty.AbstractConnector;
30 import org.mortbay.jetty.EofException;
31 import org.mortbay.jetty.HttpConnection;
32 import org.mortbay.jetty.HttpException;
33 import org.mortbay.jetty.Request;
34 import org.mortbay.log.Log;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class SocketConnector extends AbstractConnector
50 {
51 protected ServerSocket _serverSocket;
52 protected Set _connections;
53
54
55
56
57
58 public SocketConnector()
59 {
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 protected Buffer newBuffer(int size)
117 {
118 return new ByteArrayBuffer(size);
119 }
120
121
122 public void customize(EndPoint endpoint, Request request)
123 throws IOException
124 {
125 Connection connection = (Connection)endpoint;
126 if (connection._sotimeout!=_maxIdleTime)
127 {
128 connection._sotimeout=_maxIdleTime;
129 ((Socket)endpoint.getTransport()).setSoTimeout(_maxIdleTime);
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().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
205 public void close() throws IOException
206 {
207 _connection.getRequest().reset();
208 super.close();
209 }
210
211 public void run()
212 {
213 try
214 {
215 connectionOpened(_connection);
216 synchronized(_connections)
217 {
218 _connections.add(this);
219 }
220
221 while (isStarted() && !isClosed())
222 {
223 if (_connection.isIdle())
224 {
225 if (getServer().getThreadPool().isLowOnThreads())
226 {
227 int lrmit = getLowResourceMaxIdleTime();
228 if (lrmit>=0 && _sotimeout!= lrmit)
229 {
230 _sotimeout=lrmit;
231 _socket.setSoTimeout(_sotimeout);
232 }
233 }
234 }
235 _connection.handle();
236 }
237 }
238 catch (EofException e)
239 {
240 Log.debug("EOF", e);
241 try{close();}
242 catch(IOException e2){Log.ignore(e2);}
243 }
244 catch (HttpException e)
245 {
246 Log.debug("BAD", e);
247 try{close();}
248 catch(IOException e2){Log.ignore(e2);}
249 }
250 catch(Exception e)
251 {
252 Log.warn("handle failed?",e);
253 try{close();}
254 catch(IOException e2){Log.ignore(e2);}
255 }
256 finally
257 {
258 connectionClosed(_connection);
259 synchronized(_connections)
260 {
261 _connections.remove(this);
262 }
263 }
264 }
265 }
266 }