1 16 package org.mortbay.http.ajp; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.net.InetAddress ; 23 import java.net.Socket ; 24 import java.net.SocketException ; 25 import java.security.cert.CertificateFactory ; 26 import java.security.cert.X509Certificate ; 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 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 _remoteHost; 54 private String _remoteAddr; 55 private String _serverName; 56 private int _serverPort; 57 private boolean _isSSL; 58 59 60 public AJP13Connection(AJP13Listener listener, InputStream in, OutputStream out, Socket socket, int bufferSize) throws IOException 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 78 public InetAddress 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 103 public String getRemoteAddr() 104 { 105 return _remoteAddr; 106 } 107 108 109 114 public String getRemoteHost() 115 { 116 return _remoteHost; 117 } 118 119 120 126 public String getServerName() 127 { 128 return _serverName; 129 } 130 131 132 138 public int getServerPort() 139 { 140 return _serverPort; 141 } 142 143 144 150 public String 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 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 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 _keepAlive=request.getDotVersion()>=1; 217 218 int h=packet.getInt(); 220 for (int i=0; i<h; i++) 221 { 222 String hdr=packet.getHeader(); 223 String 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 byte attr=packet.getByte(); 231 while ((0xFF&attr)!=0xFF) 232 { 233 String value=(attr==11)?null:packet.getString(); 234 switch (attr) 235 { 236 case 11: request.setAttribute("javax.servlet.request.key_size",new Integer (packet.getInt())); 238 break; 239 case 10: request.setAttribute(value,packet.getString()); 241 break; 242 case 9: request.setAttribute("javax.servlet.request.ssl_session",value); 244 break; 245 case 8: request.setAttribute("javax.servlet.request.cipher_suite",value); 247 break; 248 case 7: CertificateFactory cf=CertificateFactory.getInstance("X.509"); 251 InputStream certstream=new ByteArrayInputStream (value.getBytes()); 252 X509Certificate cert=(X509Certificate )cf.generateCertificate(certstream); 253 X509Certificate certs[]= 254 { cert }; 255 request.setAttribute("javax.servlet.request.X509Certificate",certs); 256 break; 257 case 6: request.setAttribute("org.mortbay.http.ajp.JVMRoute",value); 259 break; 260 case 5: request.setQuery(value); 262 break; 263 case 4: request.setAuthType(value); 265 break; 266 case 3: request.setAuthUser(value); 268 break; 269 270 case 2: case 1: 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 if (request.getContentLength()==0&&request.getField(HttpFields.__TransferEncoding)==null) 287 _ajpIn.close(); 288 289 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 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 e) 313 { 314 LogSupport.ignore(log,e); 315 _persistent=false; 316 } 317 catch (Exception e) 318 { 319 log.warn(LogSupport.EXCEPTION,e); 320 _persistent=false; 321 try 322 { 323 if (gotRequest) 324 _ajpOut.close(); 325 } 326 catch (IOException e2) 327 { 328 LogSupport.ignore(log,e2); 329 } 330 } 331 finally 332 { 333 if (packet==null||!gotRequest) 335 return false; 336 337 try 339 { 340 343 getOutputStream().close(); 345 if (!_persistent) 346 _ajpOut.end(); 347 348 _ajpOut.close(); 350 351 getOutputStream().resetStream(); 353 getOutputStream().addObserver(this); 354 getInputStream().resetStream(); 355 _ajpIn.resetStream(); 356 _ajpOut.resetStream(); 357 } 358 catch (Exception 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 375 { 376 log.debug("ajp13 firstWrite()"); 377 } 378 379 380 protected void commit() throws IOException 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 391 { 392 if (HttpRequest.__HEAD.equals(getRequest().getMethod())) 394 getOutputStream().nullOutput(); 395 } 396 } 397 | Popular Tags |