KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > ajp > AJP13Connection


1 // ========================================================================
2
// $Id: AJP13Connection.java,v 1.37 2006/10/08 14:13:05 gregwilkins Exp $
3
// Copyright 200-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.http.ajp;
17
18 import java.io.ByteArrayInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.OutputStream JavaDoc;
22 import java.net.InetAddress JavaDoc;
23 import java.net.Socket JavaDoc;
24 import java.net.SocketException JavaDoc;
25 import java.security.cert.CertificateFactory JavaDoc;
26 import java.security.cert.X509Certificate JavaDoc;
27
28 import org.apache.commons.logging.Log;
29 import org.mortbay.log.LogFactory;
30 import org.mortbay.http.HttpConnection;
31 import org.mortbay.http.HttpContext;
32 import org.mortbay.http.HttpFields;
33 import org.mortbay.http.HttpMessage;
34 import org.mortbay.http.HttpRequest;
35 import org.mortbay.http.HttpResponse;
36 import org.mortbay.http.Version;
37 import org.mortbay.util.LineInput;
38 import org.mortbay.util.LogSupport;
39 import org.mortbay.util.URI;
40
41 /* ------------------------------------------------------------ */
42 /**
43  * @version $Id: AJP13Connection.java,v 1.37 2006/10/08 14:13:05 gregwilkins Exp $
44  * @author Greg Wilkins (gregw)
45  */

46 public class AJP13Connection extends HttpConnection
47 {
48     private static Log log=LogFactory.getLog(AJP13Connection.class);
49
50     private AJP13Listener _listener;
51     private AJP13InputStream _ajpIn;
52     private AJP13OutputStream _ajpOut;
53     private String JavaDoc _remoteHost;
54     private String JavaDoc _remoteAddr;
55     private String JavaDoc _serverName;
56     private int _serverPort;
57     private boolean _isSSL;
58
59     /* ------------------------------------------------------------ */
60     public AJP13Connection(AJP13Listener listener, InputStream JavaDoc in, OutputStream JavaDoc out, Socket JavaDoc socket, int bufferSize) throws IOException JavaDoc
61     {
62         super(listener,null,new AJP13InputStream(in,out,bufferSize),out,socket);
63
64         LineInput lin=(LineInput)getInputStream().getInputStream();
65         _ajpIn=(AJP13InputStream)lin.getInputStream();
66         _ajpOut=new AJP13OutputStream(getOutputStream().getOutputStream(),bufferSize);
67         _ajpOut.setCommitObserver(this);
68         getOutputStream().setBufferedOutputStream(_ajpOut);
69         _listener=listener;
70     }
71
72     /* ------------------------------------------------------------ */
73     /**
74      * Get the Remote address.
75      *
76      * @return the remote address
77      */

78     public InetAddress JavaDoc getRemoteInetAddress()
79     {
80         return null;
81     }
82
83     /* ------------------------------------------------------------ */
84     public void destroy()
85     {
86         if (_ajpIn!=null)
87             _ajpIn.destroy();
88         _ajpIn=null;
89         if (_ajpOut!=null)
90             _ajpOut.destroy();
91         _ajpOut=null;
92         _remoteHost=null;
93         _remoteAddr=null;
94         _serverName=null;
95     }
96
97     /* ------------------------------------------------------------ */
98     /**
99      * Get the Remote address.
100      *
101      * @return the remote host name
102      */

103     public String JavaDoc getRemoteAddr()
104     {
105         return _remoteAddr;
106     }
107
108     /* ------------------------------------------------------------ */
109     /**
110      * Get the Remote address.
111      *
112      * @return the remote host name
113      */

114     public String JavaDoc getRemoteHost()
115     {
116         return _remoteHost;
117     }
118
119     /* ------------------------------------------------------------ */
120     /**
121      * Get the listeners HttpServer . Conveniance method equivalent to
122      * getListener().getHost().
123      *
124      * @return HttpServer.
125      */

126     public String JavaDoc getServerName()
127     {
128         return _serverName;
129     }
130
131     /* ------------------------------------------------------------ */
132     /**
133      * Get the listeners Port . Conveniance method equivalent to
134      * getListener().getPort().
135      *
136      * @return HttpServer.
137      */

138     public int getServerPort()
139     {
140         return _serverPort;
141     }
142
143     /* ------------------------------------------------------------ */
144     /**
145      * Get the listeners Default scheme. Conveniance method equivalent to
146      * getListener().getDefaultProtocol().
147      *
148      * @return HttpServer.
149      */

150     public String JavaDoc getDefaultScheme()
151     {
152         return _isSSL?HttpMessage.__SSL_SCHEME:super.getDefaultScheme();
153     }
154
155     /* ------------------------------------------------------------ */
156     public boolean isSSL()
157     {
158         return _isSSL;
159     }
160
161     /* ------------------------------------------------------------ */
162     public boolean handleNext()
163     {
164         AJP13RequestPacket packet=null;
165         HttpRequest request=getRequest();
166         HttpResponse response=getResponse();
167         HttpContext context=null;
168         boolean gotRequest=false;
169         _persistent=true;
170         _keepAlive=true;
171
172         try
173         {
174             try
175             {
176                 packet=null;
177                 packet=_ajpIn.nextPacket();
178                 if (packet==null)
179                     return false;
180                 if (packet.getDataSize()==0)
181                     return true;
182             }
183             catch (IOException JavaDoc e)
184             {
185                 LogSupport.ignore(log,e);
186                 return false;
187             }
188
189             int type=packet.getByte();
190             if (log.isDebugEnabled())
191                 log.debug("AJP13 type="+type+" size="+packet.unconsumedData());
192
193             switch (type)
194             {
195                 case AJP13Packet.__FORWARD_REQUEST:
196                     request.setTimeStamp(System.currentTimeMillis());
197
198                     request.setState(HttpMessage.__MSG_EDITABLE);
199                     request.setMethod(packet.getMethod());
200                     request.setVersion(packet.getString());
201
202                     String JavaDoc path=packet.getString();
203                     int sc=path.lastIndexOf(";");
204                     if (sc<0)
205                         request.setPath(URI.encodePath(path));
206                     else
207                         request.setPath(URI.encodePath(path.substring(0,sc))+path.substring(sc));
208
209                     _remoteAddr=packet.getString();
210                     _remoteHost=packet.getString();
211                     _serverName=packet.getString();
212                     _serverPort=packet.getInt();
213                     _isSSL=packet.getBoolean();
214
215                     // Check keep alive
216
_keepAlive=request.getDotVersion()>=1;
217
218                     // Headers
219
int h=packet.getInt();
220                     for (int i=0; i<h; i++)
221                     {
222                         String JavaDoc hdr=packet.getHeader();
223                         String JavaDoc val=packet.getString();
224                         request.addField(hdr,val);
225                         if (!_keepAlive&&hdr.equalsIgnoreCase(HttpFields.__Connection)&&val.equalsIgnoreCase(HttpFields.__KeepAlive))
226                             _keepAlive=true;
227                     }
228
229                     // Handler other attributes
230
byte attr=packet.getByte();
231                     while ((0xFF&attr)!=0xFF)
232                     {
233                         String JavaDoc value=(attr==11)?null:packet.getString();
234                         switch (attr)
235                         {
236                             case 11: // key size
237
request.setAttribute("javax.servlet.request.key_size",new Integer JavaDoc(packet.getInt()));
238                                 break;
239                             case 10: // request attribute
240
request.setAttribute(value,packet.getString());
241                                 break;
242                             case 9: // SSL session
243
request.setAttribute("javax.servlet.request.ssl_session",value);
244                                 break;
245                             case 8: // SSL cipher
246
request.setAttribute("javax.servlet.request.cipher_suite",value);
247                                 break;
248                             case 7: // SSL cert
249
// request.setAttribute("javax.servlet.request.X509Certificate",value);
250
CertificateFactory JavaDoc cf=CertificateFactory.getInstance("X.509");
251                                 InputStream JavaDoc certstream=new ByteArrayInputStream JavaDoc(value.getBytes());
252                                 X509Certificate JavaDoc cert=(X509Certificate JavaDoc)cf.generateCertificate(certstream);
253                                 X509Certificate JavaDoc certs[]=
254                                 { cert };
255                                 request.setAttribute("javax.servlet.request.X509Certificate",certs);
256                                 break;
257                             case 6: // JVM Route
258
request.setAttribute("org.mortbay.http.ajp.JVMRoute",value);
259                                 break;
260                             case 5: // Query String
261
request.setQuery(value);
262                                 break;
263                             case 4: // AuthType
264
request.setAuthType(value);
265                                 break;
266                             case 3: // Remote User
267
request.setAuthUser(value);
268                                 break;
269
270                             case 2: // servlet path not implemented
271
case 1: // _context not implemented
272
default:
273                                 log.warn("Unknown attr: "+attr+"="+value);
274                         }
275
276                         attr=packet.getByte();
277                     }
278
279                     _listener.customizeRequest(this,request);
280
281                     gotRequest=true;
282                     statsRequestStart();
283                     request.setState(HttpMessage.__MSG_RECEIVED);
284
285                     // Complete response
286
if (request.getContentLength()==0&&request.getField(HttpFields.__TransferEncoding)==null)
287                         _ajpIn.close();
288
289                     // Prepare response
290
response.setState(HttpMessage.__MSG_EDITABLE);
291                     response.setVersion(HttpMessage.__HTTP_1_1);
292                     response.setDateField(HttpFields.__Date,_request.getTimeStamp());
293                     if (!Version.isParanoid())
294                         response.setField(HttpFields.__Server,Version.getDetail());
295
296                     // Service request
297
if (log.isDebugEnabled())
298                         log.debug("REQUEST:\n"+request);
299                     context=service(request,response);
300                     if (log.isDebugEnabled())
301                         log.debug("RESPONSE:\n"+response);
302
303                     break;
304
305                 default:
306                     if (log.isDebugEnabled())
307                         log.debug("Ignored: "+packet);
308                     _persistent=false;
309             }
310
311         }
312         catch (SocketException JavaDoc e)
313         {
314             LogSupport.ignore(log,e);
315             _persistent=false;
316         }
317         catch (Exception JavaDoc e)
318         {
319             log.warn(LogSupport.EXCEPTION,e);
320             _persistent=false;
321             try
322             {
323                 if (gotRequest)
324                     _ajpOut.close();
325             }
326             catch (IOException JavaDoc e2)
327             {
328                 LogSupport.ignore(log,e2);
329             }
330         }
331         finally
332         {
333             // abort if nothing received.
334
if (packet==null||!gotRequest)
335                 return false;
336
337             // flush and end the output
338
try
339             {
340                 // Consume unread input.
341
// while(_ajpIn.skip(4096)>0 || _ajpIn.read()>=0);
342

343                 // end response
344
getOutputStream().close();
345                 if (!_persistent)
346                     _ajpOut.end();
347
348                 // Close the outout
349
_ajpOut.close();
350
351                 // reset streams
352
getOutputStream().resetStream();
353                 getOutputStream().addObserver(this);
354                 getInputStream().resetStream();
355                 _ajpIn.resetStream();
356                 _ajpOut.resetStream();
357             }
358             catch (Exception JavaDoc e)
359             {
360                 log.debug(LogSupport.EXCEPTION,e);
361                 _persistent=false;
362             }
363             finally
364             {
365                 statsRequestEnd();
366                 if (context!=null)
367                     context.log(request,response,-1);
368             }
369         }
370         return _persistent;
371     }
372
373     /* ------------------------------------------------------------ */
374     protected void firstWrite() throws IOException JavaDoc
375     {
376         log.debug("ajp13 firstWrite()");
377     }
378
379     /* ------------------------------------------------------------ */
380     protected void commit() throws IOException JavaDoc
381     {
382         log.debug("ajp13 commit()");
383         if (_response.isCommitted())
384             return;
385         _request.setHandled(true);
386         getOutputStream().writeHeader(_response);
387     }
388
389     /* ------------------------------------------------------------ */
390     protected void setupOutputStream() throws IOException JavaDoc
391     {
392         // Nobble the OutputStream for HEAD requests
393
if (HttpRequest.__HEAD.equals(getRequest().getMethod()))
394             getOutputStream().nullOutput();
395     }
396 }
397
Popular Tags