Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mortbay/http/ajp/AJP13Listener.java


1   // ========================================================================
2   // Copyright (c) 2002 Mort Bay Consulting (Australia) Pty. Ltd.
3   // $Id: AJP13Listener.java,v 1.17 2003/11/22 16:06:02 gregwilkins Exp $
4   // ========================================================================
5   
6   package org.mortbay.http.ajp;
7   
8   
9   import java.io.IOException;
10  import java.net.InetAddress;
11  import java.net.Socket;
12  
13  import org.apache.commons.logging.Log;
14  import org.apache.commons.logging.LogFactory;
15  import org.mortbay.http.HttpConnection;
16  import org.mortbay.http.HttpHandler;
17  import org.mortbay.http.HttpListener;
18  import org.mortbay.http.HttpMessage;
19  import org.mortbay.http.HttpRequest;
20  import org.mortbay.http.HttpServer;
21  import org.mortbay.util.InetAddrPort;
22  import org.mortbay.util.ThreadedServer;
23  
24  
25  /* ------------------------------------------------------------ */
26  /** AJP 1.3 Protocol Listener.
27   * This listener takes requests from the mod_jk or mod_jk2 modules
28   * used by web servers such as apache and IIS to forward requests to a
29   * servlet container.
30   * <p>
31   * This code uses the AJP13 code from tomcat3.3 as the protocol
32   * specification, but is new  implementation.
33   *
34   * @version $Id: AJP13Listener.java,v 1.17 2003/11/22 16:06:02 gregwilkins Exp $
35   * @author Greg Wilkins (gregw)
36   */
37  public class AJP13Listener
38      extends ThreadedServer
39      implements HttpListener
40  {
41      private static Log log = LogFactory.getLog(AJP13Listener.class);
42  
43      /* ------------------------------------------------------------------- */
44      private HttpServer _server;
45      private boolean _lastOut=false;
46      private boolean _lastLow=false;
47      private String _integralScheme=HttpMessage.__SSL_SCHEME;
48      private String _confidentialScheme=HttpMessage.__SSL_SCHEME;
49      private int _integralPort=0;
50      private int _confidentialPort=0;
51      private boolean _identifyListener=false;
52      private int _bufferSize=8192; 
53      private int _bufferReserve=512;
54      private String[] _remoteServers;
55      private HttpHandler _handler;
56      
57      /* ------------------------------------------------------------------- */
58      public AJP13Listener()
59      {}
60  
61      /* ------------------------------------------------------------------- */
62      public AJP13Listener(InetAddrPort address)
63      {
64          super(address);
65      }
66      
67      /* ------------------------------------------------------------ */
68      public void setHttpServer(HttpServer server)
69      {
70          _server=server;
71      }
72  
73      /* ------------------------------------------------------------ */
74      public HttpServer getHttpServer()
75      {
76          return _server;
77      }
78  
79      /* ------------------------------------------------------------ */
80      public int getBufferSize()
81      {
82          return _bufferSize;
83      }
84      
85      /* ------------------------------------------------------------ */
86      public void setBufferSize(int size)
87      {
88          _bufferSize=size;
89          if (_bufferSize>8192)
90              log.warn("AJP Data buffer > 8192: "+size);
91      }
92          
93      /* ------------------------------------------------------------ */
94      public int getBufferReserve()
95      {
96          return _bufferReserve;
97      }
98      
99      /* ------------------------------------------------------------ */
100     public void setBufferReserve(int size)
101     {
102         _bufferReserve=size;
103     }
104         
105     /* ------------------------------------------------------------ */
106     public boolean getIdentifyListener()
107     {
108         return _identifyListener;
109     }
110     
111     /* ------------------------------------------------------------ */
112     /** 
113      * @param identifyListener If true, the listener name is added to all
114      * requests as the org.mortbay.http.HttListener attribute
115      */
116     public void setIdentifyListener(boolean identifyListener)
117     {
118         _identifyListener = identifyListener;
119     }
120     
121     /* --------------------------------------------------------------- */
122     public String getDefaultScheme()
123     {
124         return HttpMessage.__SCHEME;
125     }    
126     
127     /* --------------------------------------------------------------- */
128     public void start()
129         throws Exception
130     {
131         super.start();
132         log.info("Started AJP13Listener on "+getInetAddrPort());
133         log.info("NOTICE: AJP13 is not a secure protocol. Please protect the port "+
134                   getInetAddrPort());
135     }
136 
137     /* --------------------------------------------------------------- */
138     public void stop()
139         throws InterruptedException
140     {
141         super.stop();
142         log.info("Stopped AJP13Listener on "+getInetAddrPort());
143     }
144 
145     /* ------------------------------------------------------------ */
146     /** 
147      * @return Array of accepted remote server hostnames or IPs.
148      */
149     public String[] getRemoteServers()
150     {
151         return _remoteServers;
152     }
153     
154     /* ------------------------------------------------------------ */
155     /** Set accepted remote servers.
156      * The AJP13 protocol is not secure and contains no authentication. If
157      * remote servers are set, then this listener will only accept
158      * connections from hosts with matching addresses or hostnames.
159      * @param servers Array of accepted remote server hostnames or IPs
160      */
161     public void setRemoteServers(String[] servers)
162     {
163         _remoteServers=servers;
164     }
165     
166     
167     /* ------------------------------------------------------------ */
168     /** Handle Job.
169      * Implementation of ThreadPool.handle(), calls handleConnection.
170      * @param socket A Connection.
171      */
172     public void handleConnection(Socket socket)
173         throws IOException
174     {
175         // Check acceptable remote servers
176         if (_remoteServers!=null && _remoteServers.length>0)
177         {
178             boolean match=false;
179             InetAddress inetAddress=socket.getInetAddress();
180             String hostAddr=inetAddress.getHostAddress();
181             String hostName=inetAddress.getHostName();
182             for (int i=0;i<_remoteServers.length;i++)
183             {
184                 if (hostName.equals(_remoteServers[i]) ||
185                     hostAddr.equals(_remoteServers[i]))
186                 {
187                     match=true;
188                     break;
189                 }                    
190             }
191             if (!match)
192             {
193                 log.warn("AJP13 Connection from un-approved host: "+inetAddress);
194                 return;
195             }
196         }
197 
198         // Handle the connection
199         socket.setTcpNoDelay(true);
200         socket.setSoTimeout(getMaxIdleTimeMs());
201         AJP13Connection connection= createConnection(socket);
202         try{connection.handle();}
203         finally{connection.destroy();}
204     }
205 
206     /* ------------------------------------------------------------ */
207     /** Create an AJP13Connection instance. This method can be used to
208      * override the connection instance.
209      * @param socket The underlying socket.
210      */
211     protected AJP13Connection createConnection(Socket socket)
212         throws IOException
213     {
214         return new AJP13Connection(this,
215                                    socket.getInputStream(),
216                                    socket.getOutputStream(),
217                                    socket,
218                                    getBufferSize());
219     }
220 
221     /* ------------------------------------------------------------ */
222     /** Customize the request from connection.
223      * This method extracts the socket from the connection and calls
224      * the customizeRequest(Socket,HttpRequest) method.
225      * @param request
226      */
227     public void customizeRequest(HttpConnection connection,
228                                  HttpRequest request)
229     {
230         if (_identifyListener)
231             request.setAttribute(HttpListener.ATTRIBUTE,getName());
232         
233         Socket socket=(Socket)(connection.getConnection());
234         customizeRequest(socket,request);
235     }
236 
237     /* ------------------------------------------------------------ */
238     /** Customize request from socket.
239      * Derived versions of SocketListener may specialize this method
240      * to customize the request with attributes of the socket used (eg
241      * SSL session ids).
242      * @param request
243      */
244     protected void customizeRequest(Socket socket,
245                                     HttpRequest request)
246     {
247     }
248 
249     /* ------------------------------------------------------------ */
250     /** Persist the connection.
251      * @param connection
252      */
253     public void persistConnection(HttpConnection connection)
254     {
255     }
256 
257     /* ------------------------------------------------------------ */
258     /** 
259      * @return True if low on idle threads. 
260      */
261     public boolean isLowOnResources()
262     {
263         boolean low =
264             getThreads()==getMaxThreads() &&
265             getIdleThreads()<getMinThreads();
266         if (low && !_lastLow)
267             log.info("LOW ON THREADS: "+this);
268         else if (!low && _lastLow)
269         {
270             log.info("OK on threads: "+this);
271             _lastOut=false;
272         }
273         _lastLow=low;
274         return low;
275     }
276 
277     /* ------------------------------------------------------------ */
278     /** 
279      * @return True if out of resources. 
280      */
281     public boolean isOutOfResources()
282     {
283         boolean out =
284             getThreads()==getMaxThreads() &&
285             getIdleThreads()==0;
286         if (out && !_lastOut)
287             log.warn("OUT OF THREADS: "+this);
288             
289         _lastOut=out;
290         return out;
291     }
292     
293     /* ------------------------------------------------------------ */
294     public boolean isIntegral(HttpConnection connection)
295     {
296         return ((AJP13Connection)connection).isSSL();
297     }
298     
299     /* ------------------------------------------------------------ */
300     public boolean isConfidential(HttpConnection connection)
301     {
302         return ((AJP13Connection)connection).isSSL();
303     }
304 
305     /* ------------------------------------------------------------ */
306     public String getIntegralScheme()
307     {
308         return _integralScheme;
309     }
310     
311     /* ------------------------------------------------------------ */
312     public void setIntegralScheme(String integralScheme)
313     {
314         _integralScheme = integralScheme;
315     }
316     
317     /* ------------------------------------------------------------ */
318     public int getIntegralPort()
319     {
320         return _integralPort;
321     }
322 
323     /* ------------------------------------------------------------ */
324     public void setIntegralPort(int integralPort)
325     {
326         _integralPort = integralPort;
327     }
328     
329     /* ------------------------------------------------------------ */
330     public String getConfidentialScheme()
331     {
332         return _confidentialScheme;
333     }
334 
335     /* ------------------------------------------------------------ */
336     public void setConfidentialScheme(String confidentialScheme)
337     {
338         _confidentialScheme = confidentialScheme;
339     }
340 
341     /* ------------------------------------------------------------ */
342     public int getConfidentialPort()
343     {
344         return _confidentialPort;
345     }
346 
347     /* ------------------------------------------------------------ */
348     public void setConfidentialPort(int confidentialPort)
349     {
350         _confidentialPort = confidentialPort;
351     }    
352 
353     /* ------------------------------------------------------------ */
354     public HttpHandler getHttpHandler()
355     {
356         return _handler;
357     }
358     
359     /* ------------------------------------------------------------ */
360     public void setHttpHandler(HttpHandler handler)
361     {
362         _handler=handler;
363     }
364 }