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

Quick Search    Search Deep

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


1   // ========================================================================
2   // Copyright (c) 2002-2003 Mort Bay Consulting (Australia) Pty. Ltd.
3   // $Id: AJP13Connection.java,v 1.27 2003/10/05 23:46:23 gregwilkins Exp $
4   // ========================================================================
5   
6   package org.mortbay.http.ajp;
7   
8   
9   import java.io.ByteArrayInputStream;
10  import java.io.IOException;
11  import java.io.InputStream;
12  import java.io.OutputStream;
13  import java.net.InetAddress;
14  import java.net.Socket;
15  import java.net.SocketException;
16  import java.security.cert.CertificateFactory;
17  import java.security.cert.X509Certificate;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.mortbay.http.HttpConnection;
22  import org.mortbay.http.HttpContext;
23  import org.mortbay.http.HttpFields;
24  import org.mortbay.http.HttpMessage;
25  import org.mortbay.http.HttpRequest;
26  import org.mortbay.http.HttpResponse;
27  import org.mortbay.http.Version;
28  import org.mortbay.util.LineInput;
29  import org.mortbay.util.LogSupport;
30  
31  /* ------------------------------------------------------------ */
32  /** 
33   * @version $Id: AJP13Connection.java,v 1.27 2003/10/05 23:46:23 gregwilkins Exp $
34   * @author Greg Wilkins (gregw)
35   */
36  public class AJP13Connection extends HttpConnection
37  {
38      private static Log log = LogFactory.getLog(AJP13Connection.class);
39  
40      private AJP13Listener _listener;
41      private AJP13InputStream _ajpIn;
42      private AJP13OutputStream _ajpOut;
43      private String _remoteHost;
44      private String _remoteAddr;
45      private String _serverName;
46      private int _serverPort;
47      private boolean _isSSL;
48      
49      /* ------------------------------------------------------------ */
50      public AJP13Connection(AJP13Listener listener,
51                             InputStream in,
52                             OutputStream out,
53                             Socket socket,
54                             int bufferSize)
55          throws IOException
56      {
57          super(listener,
58                null,
59                new AJP13InputStream(in,out,bufferSize),
60                out,
61                socket);
62  
63          LineInput lin = (LineInput)getInputStream().getInputStream();
64          _ajpIn=(AJP13InputStream)lin.getInputStream();
65          _ajpOut=new AJP13OutputStream(getOutputStream().getFilterStream(),
66                                        bufferSize);
67          _ajpOut.setCommitObserver(this);
68          getOutputStream().setBufferedOutputStream(_ajpOut,true);
69          _listener=listener;
70      }
71  
72      /* ------------------------------------------------------------ */
73      /** Get the Remote address.
74       * @return the remote address
75       */
76      public InetAddress getRemoteInetAddress()
77      {
78          return null;
79      }
80  
81      /* ------------------------------------------------------------ */
82      public void destroy()
83      {
84          if (_ajpIn!=null)_ajpIn.destroy();
85          _ajpIn=null;
86          if (_ajpOut!=null)_ajpOut.destroy();
87          _ajpOut=null;
88          _remoteHost=null;
89          _remoteAddr=null;
90          _serverName=null;
91      }
92      
93      /* ------------------------------------------------------------ */
94      /** Get the Remote address.
95       * @return the remote host name
96       */
97      public String getRemoteAddr()
98      {
99          return _remoteAddr;
100     }
101     
102     /* ------------------------------------------------------------ */
103     /** Get the Remote address.
104      * @return the remote host name
105      */
106     public String getRemoteHost()
107     {
108         return _remoteHost;
109     }
110     
111     /* ------------------------------------------------------------ */
112     /** Get the listeners HttpServer .
113      * Conveniance method equivalent to getListener().getHost().
114      * @return HttpServer.
115      */
116     public String getServerName()
117     {
118         return _serverName;
119     }
120     
121     /* ------------------------------------------------------------ */
122     /** Get the listeners Port .
123      * Conveniance method equivalent to getListener().getPort().
124      * @return HttpServer.
125      */
126     public int getServerPort()
127     {
128         return _serverPort;
129     }
130 
131     /* ------------------------------------------------------------ */
132     /** Get the listeners Default scheme. 
133      * Conveniance method equivalent to getListener().getDefaultProtocol().
134      * @return HttpServer.
135      */
136     public String getDefaultScheme()
137     {
138         return _isSSL?HttpMessage.__SSL_SCHEME:super.getDefaultScheme();
139     }
140     
141     /* ------------------------------------------------------------ */
142     public boolean isSSL()
143     {
144         return _isSSL;
145     }
146     
147     /* ------------------------------------------------------------ */
148     public boolean handleNext()
149     {
150         AJP13RequestPacket packet=null;
151         HttpRequest request = getRequest();
152         HttpResponse response = getResponse();
153         HttpContext context = null;
154         boolean gotRequest=false;
155         _persistent=true;
156         _keepAlive=true;
157         
158         try
159         {
160             try
161             {
162                 packet = null;
163                 packet = _ajpIn.nextPacket();
164                 if (packet==null)
165                     return false;
166                 if (packet.getDataSize()==0)
167                     return true;
168             }
169             catch (IOException e)
170             {
171                 LogSupport.ignore(log,e);
172                 return false;
173             }
174             
175             int type=packet.getByte();
176             if(log.isDebugEnabled())log.debug("AJP13 type="+type+" size="+packet.unconsumedData());
177             
178             switch (type)
179             {
180               case AJP13Packet.__FORWARD_REQUEST:
181                   request.setTimeStamp(System.currentTimeMillis());
182                   
183                   request.setState(HttpMessage.__MSG_EDITABLE);
184                   request.setMethod(packet.getMethod());
185                   request.setVersion(packet.getString());
186                   request.setPath(packet.getString());
187                   _remoteAddr=packet.getString();
188                   _remoteHost=packet.getString();
189                   _serverName=packet.getString();
190                   _serverPort=packet.getInt();
191                   _isSSL=packet.getBoolean();
192 
193                   // Check keep alive
194                   _keepAlive=request.getDotVersion()>=1;
195                   
196                   // Headers
197                   int h=packet.getInt();
198                   for (int i=0;i<h;i++)
199                   {
200                       String hdr=packet.getHeader();
201                       String val=packet.getString();
202                       request.setField(hdr,val);
203                       if (!_keepAlive && hdr.equalsIgnoreCase(HttpFields.__Connection) &&
204                           val.equalsIgnoreCase(HttpFields.__KeepAlive))
205                           _keepAlive=true;
206                   }
207                   
208                   
209                   // Handler other attributes
210                   byte attr=packet.getByte();
211                   while ((0xFF&attr)!=0xFF)
212                   {
213                       String value=packet.getString();
214                       switch (attr)
215                       {
216                         case 10: // request attribute
217                             request.setAttribute(value,packet.getString());
218                             break;
219                         case 9: // SSL session
220                             //log.warn("not implemented: sslsession="+value);
221                             break;
222                         case 8: // SSL cipher
223                             request.setAttribute("javax.servlet.request.cipher_suite",value);
224                             break;
225                         case 7: // SSL cert
226                             //request.setAttribute("javax.servlet.request.X509Certificate",value);
227                             CertificateFactory cf =
228                                 CertificateFactory.getInstance("X.509");
229                             InputStream certstream =
230                                 new ByteArrayInputStream(value.getBytes());
231                             X509Certificate cert = (X509Certificate)
232                                 cf.generateCertificate(certstream);
233                             X509Certificate certs[] = {cert};
234                             request.setAttribute("javax.servlet.request.X509Certificate",certs);
235                             break;
236                         case 6: // JVM Route
237                             request.setAttribute("org.mortbay.http.ajp.JVMRoute",value);
238                             break;
239                         case 5: // Query String
240                             request.setQuery(value);
241                             break;
242                         case 4: // AuthType
243                             request.setAuthType(value);
244                             break;
245                         case 3: // Remote User
246                             request.setAuthUser(value);
247                             break;
248                             
249                         case 2:  // servlet path not implemented
250                         case 1:  // context not implemented
251                         default:
252                             log.warn("Unknown attr: "+attr+"="+value);  
253                       }
254                       
255                       attr=packet.getByte();
256                   }
257         
258                   _listener.customizeRequest(this,request);
259                   
260                   gotRequest=true;
261                   statsRequestStart();
262                   request.setState(HttpMessage.__MSG_RECEIVED);
263                   
264                   // Complete response
265                   if (request.getContentLength()==0 &&
266                       request.getField(HttpFields.__TransferEncoding)==null)
267                       _ajpIn.close();
268                   
269                   // Prepare response
270                   response.setState(HttpMessage.__MSG_EDITABLE);
271                   response.setVersion(HttpMessage.__HTTP_1_1);
272                   response.setDateField(HttpFields.__Date,_request.getTimeStamp());
273                   response.setField(HttpFields.__Server,Version.__VersionDetail);
274                   
275                   // Service request
276                   if(log.isDebugEnabled())log.debug("REQUEST:\n"+request);
277                   context=service(request,response);
278                   if(log.isDebugEnabled())log.debug("RESPONSE:\n"+response);
279 
280                   break;
281                   
282               default:
283                   if(log.isDebugEnabled())log.debug("Ignored: "+packet);
284                   _persistent=false;
285             }
286   
287         }
288         catch (SocketException e)
289         {
290             LogSupport.ignore(log,e);
291             _persistent=false; 
292         }
293         catch (Exception e)
294         {
295             log.warn(LogSupport.EXCEPTION,e);
296             _persistent=false; 
297             try{
298                 if (gotRequest)
299                     _ajpOut.close();
300             }
301             catch (IOException e2){LogSupport.ignore(log,e2);}
302         }
303         finally
304         {
305             // abort if nothing received.
306             if (packet==null || !gotRequest)
307                 return false;
308             
309             // flush and end the output
310             try{
311                 //Consume unread input.
312                 // while(_ajpIn.skip(4096)>0 || _ajpIn.read()>=0);
313 
314                 // end response
315                 getOutputStream().close();
316                 if (!_persistent)
317                     _ajpOut.end();
318 
319                 // Close the outout
320                 _ajpOut.close();
321 
322                 // reset streams
323                 getOutputStream().resetStream();
324                 getOutputStream().addObserver(this);
325                 getInputStream().resetStream();
326                 _ajpIn.resetStream();
327                 _ajpOut.resetStream();
328             }
329             catch (Exception e)
330             {
331                 log.debug(LogSupport.EXCEPTION,e);
332                 _persistent=false;
333             }
334             finally
335             {
336                 statsRequestEnd();
337                 if (context!=null)
338                     context.log(request,response,-1);
339             }
340         }
341         return _persistent;
342     }
343 
344 
345     /* ------------------------------------------------------------ */
346     protected void firstWrite()
347         throws IOException
348     {
349         log.debug("ajp13 firstWrite()");
350     }
351     
352     /* ------------------------------------------------------------ */
353     protected void commit()
354         throws IOException
355     {
356         log.debug("ajp13 commit()");
357         if (_response.isCommitted())
358             return;
359         _request.setHandled(true);
360         getOutputStream().writeHeader(_response);
361     }
362     
363 
364     /* ------------------------------------------------------------ */
365     protected void setupOutputStream()
366         throws IOException
367     {
368         // Nobble the OutputStream for HEAD requests
369         if (HttpRequest.__HEAD.equals(getRequest().getMethod()))
370             getOutputStream().nullOutput();
371     }
372 }