1 16 17 package org.apache.ajp.tomcat4; 18 19 20 import java.io.IOException ; 21 import java.net.Socket ; 22 23 import javax.servlet.ServletException ; 24 import javax.servlet.http.HttpServletResponse ; 25 26 import org.apache.ajp.Ajp13; 27 import org.apache.catalina.Lifecycle; 28 import org.apache.catalina.LifecycleException; 29 import org.apache.catalina.LifecycleListener; 30 import org.apache.catalina.util.LifecycleSupport; 31 import org.apache.catalina.util.StringManager; 32 import org.apache.tomcat.util.http.BaseRequest; 33 34 38 39 final class Ajp13Processor 40 implements Lifecycle, Runnable { 41 42 46 private class Bool { 47 48 private boolean b = false; 49 50 Bool() { 51 } 52 53 Bool(boolean b) { 54 this.b = b; 55 } 56 57 synchronized boolean value() { 58 return b; 59 } 60 61 synchronized void set(boolean b) { 62 this.b = b; 63 } 64 } 65 66 68 69 77 public Ajp13Processor(Ajp13Connector connector, 78 int id, 79 ThreadGroup threadGroup) { 80 81 super(); 82 this.connector = connector; 83 this.debug = connector.getDebug(); 84 this.id = id; 85 this.request = (Ajp13Request) connector.createRequest(); 86 this.request.setConnector(connector); 87 this.request.setConnector(connector); 88 this.response = (Ajp13Response) connector.createResponse(); 89 this.response.setConnector(connector); 90 this.threadName = 91 "Ajp13Processor[" + connector.getPort() + "][" + id + "]"; 92 this.threadGroup = threadGroup; 93 94 this.logger.setConnector(connector); 95 this.logger.setName(this.threadName); 96 } 97 98 99 101 private Ajp13Logger logger = new Ajp13Logger(); 102 private BaseRequest ajpRequest = new BaseRequest(); 103 104 107 private boolean available = false; 108 109 110 113 private Ajp13Connector connector = null; 114 115 116 119 private int debug = 0; 120 121 122 125 private int id = 0; 126 127 128 131 private LifecycleSupport lifecycle = new LifecycleSupport(this); 132 133 134 137 private Ajp13Request request = null; 138 139 140 143 private Ajp13Response response = null; 144 145 146 149 protected StringManager sm = 150 StringManager.getManager(Constants.PACKAGE); 151 152 153 157 private Socket socket = null; 158 159 160 163 private boolean started = false; 164 165 166 169 private Bool stopped = new Bool(true); 170 171 174 private Bool handlingRequest = new Bool(false); 175 176 177 180 private Thread thread = null; 181 182 183 186 private String threadName = null; 187 188 189 192 private ThreadGroup threadGroup = null; 193 194 195 198 private Object threadSync = new Object (); 199 200 201 202 204 205 214 synchronized void assign(Socket socket) { 215 216 while (available) { 218 try { 219 wait(); 220 } catch (InterruptedException e) { 221 } 222 } 223 224 this.socket = socket; 226 available = true; 227 notifyAll(); 228 229 if ((debug > 0) && (socket != null)) 230 logger.log(" An incoming request is being assigned"); 231 232 } 233 234 235 237 238 242 private synchronized Socket await() { 243 244 while (!available) { 246 try { 247 wait(); 248 } catch (InterruptedException e) { 249 } 250 } 251 252 Socket socket = this.socket; 254 available = false; 255 notifyAll(); 256 257 if ((debug > 0) && (socket != null)) 258 logger.log(" The incoming request has been awaited"); 259 260 return (socket); 261 262 } 263 264 272 private void parseConnection(Socket socket) 273 throws IOException , ServletException { 274 275 if (debug > 1) 276 logger.log(" parseConnection: address=" + socket.getInetAddress() + 277 ", port=" + connector.getPort()); 278 request.setServerPort(connector.getPort()); 279 request.setSocket(socket); 280 281 } 282 283 290 private void process(Socket socket) { 291 292 Ajp13 ajp13 = new Ajp13(); 293 ajp13.setDebug(debug); 294 ajp13.setLogger(new org.apache.ajp.Logger() { 295 public void log(String msg) { 296 logger.log("[Ajp13] " + msg); 297 } 298 299 public void log(String msg, Throwable t) { 300 logger.log("[Ajp13] " + msg, t); 301 } 302 }); 303 304 Ajp13InputStream input = new Ajp13InputStream(ajp13); 305 Ajp13OutputStream output = new Ajp13OutputStream(ajp13); 306 response.setAjp13(ajp13); 307 308 try { 309 ajp13.setSocket(socket); 310 } catch (IOException e) { 311 logger.log("process: ajp13.setSocket", e); 312 } 313 314 boolean moreRequests = true; 315 String expectedSecret=connector.getSecret(); 316 317 boolean needAuth= ( expectedSecret != null ); 318 319 while (moreRequests && !stopped.value()) { 320 321 int status = 0; 322 try { 323 if (debug > 0) { 324 logger.log("waiting on next request..."); 325 } 326 327 status = ajp13.receiveNextRequest(ajpRequest); 328 329 if (debug > 0) { 330 logger.log("received next request, status=" + status); 331 } 332 } catch (IOException e) { 333 logger.log("process: ajp13.receiveNextRequest", e); 334 } 335 336 if( needAuth ) { 337 String connSecret=ajp13.getSecret(); 338 if( connSecret == null ) { 339 logger.log( "Connection without password, " + 340 "tomcat is configured to require one" ); 341 break; 342 } 343 if( ! connSecret.equals(expectedSecret) ) { 344 logger.log( "Connection with wrong password" ); 345 break; 346 } 347 348 needAuth=false; 349 } 350 351 if (stopped.value()) { 352 if (debug > 0) { 353 logger.log("process: received request, but we're stopped"); 354 } 355 break; 356 } 357 358 if( status==-2) { 359 break; 367 } 368 369 if( status == 999 ) 371 { 372 ajpRequest.recycle(); 373 request.recycle(); 374 375 ajp13.recycle(); 377 378 continue; 379 } 380 381 if( status != 200 ) 382 break; 383 384 try { 385 handlingRequest.set(true); 387 388 boolean bad_request = false; 389 390 try { 392 request.setAjpRequest(ajpRequest); 393 } catch (IllegalArgumentException e) { 394 bad_request = true; 395 } 396 request.setResponse(response); 397 request.setStream(input); 398 399 response.setRequest(request); 401 response.setStream(output); 402 403 if (debug > 0) { 404 logger.log("invoking..."); 405 } 406 407 if (!bad_request) { 408 try { 409 connector.getContainer().invoke(request, response); 410 } catch (IOException ioe) { 411 throw ioe; 413 } catch (Throwable e) { 414 logger.log("process: invoke", e); 419 response.sendError 420 (HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 421 } 422 } else { 423 response.sendError 424 (HttpServletResponse.SC_BAD_REQUEST); 425 } 426 427 if (debug > 0) { 428 logger.log("done invoking, finishing request/response...."); 429 } 430 431 response.finishResponse(); 432 request.finishRequest(); 433 434 if (debug > 0) { 435 logger.log("finished handling request."); 436 } 437 438 } catch (IOException ioe) { 439 logger.log("process: IOException " + ioe.getMessage()); 443 moreRequests = false; 444 } catch (Throwable e) { 445 logger.log("process: finish", e); 449 moreRequests = false; 450 } 451 452 if (debug > 0) { 454 logger.log("recyling objects ..."); 455 } 456 457 ajpRequest.recycle(); 458 request.recycle(); 459 response.recycle(); 460 461 ajp13.recycle(); 463 464 handlingRequest.set(false); 466 } 467 468 try { 469 if (debug > 0) { 470 logger.log("closing ajp13 object..."); 471 } 472 473 ajp13.close(); 474 475 if (debug > 0) { 476 logger.log("ajp13 object closed."); 477 } 478 } catch (IOException e) { 479 logger.log("process: ajp13.close", e); 480 } 481 482 try { 483 if (debug > 0) { 484 logger.log("closing socket..."); 485 } 486 487 socket.close(); 488 489 if (debug > 0) { 490 logger.log("socket closed."); 491 } 492 } catch (IOException e) { 493 logger.log("process: socket.close", e); 494 } 495 socket = null; 496 497 if (debug > 0) { 498 logger.log("process: done"); 499 } 500 } 501 502 503 505 506 510 public void run() { 511 512 while (!stopped.value()) { 514 515 if (debug > 0) { 517 logger.log("waiting for next socket to be assigned..."); 518 } 519 Socket socket = await(); 520 if (socket == null) 521 continue; 522 523 if (debug > 0) { 524 logger.log("socket assigned."); 525 } 526 527 process(socket); 529 530 if (debug > 0) { 532 logger.log("recycling myself ..."); 533 } 534 connector.recycle(this); 535 } 536 537 synchronized (threadSync) { 539 threadSync.notifyAll(); 540 } 541 542 } 543 544 545 548 private void threadStart() { 549 550 logger.log(sm.getString("ajp13Processor.starting")); 551 552 stopped.set(false); 553 thread = new Thread (threadGroup, this, threadName); 554 thread.setDaemon(true); 555 thread.start(); 556 557 if (debug > 0) 558 logger.log(" Background thread has been started"); 559 560 } 561 562 563 566 private void threadStop() { 567 568 logger.log(sm.getString("ajp13Processor.stopping")); 569 570 stopped.set(true); 571 assign(null); 572 synchronized (threadSync) { 573 try { 574 if (handlingRequest.value()) { 575 if (debug > 0) { 576 logger.log 577 ("currentling handling a request, so waiting...."); 578 } 579 threadSync.wait(5000); 580 } else { 581 if (debug > 0) { 582 logger.log 583 ("not currently handling a request, not waiting."); 584 } 585 } 586 } catch (InterruptedException e) { 587 ; 588 } 589 } 590 thread = null; 591 592 } 593 594 595 597 598 603 public void addLifecycleListener(LifecycleListener listener) { 604 605 lifecycle.addLifecycleListener(listener); 606 607 } 608 609 613 public LifecycleListener[] findLifecycleListeners() { 614 return null; } 616 617 618 623 public void removeLifecycleListener(LifecycleListener listener) { 624 625 lifecycle.removeLifecycleListener(listener); 626 627 } 628 629 630 635 public void start() throws LifecycleException { 636 637 if (started) 638 throw new LifecycleException 639 (sm.getString("ajp13Processor.alreadyStarted")); 640 lifecycle.fireLifecycleEvent(START_EVENT, null); 641 started = true; 642 643 threadStart(); 644 645 } 646 647 648 653 public void stop() throws LifecycleException { 654 655 if (!started) 656 throw new LifecycleException 657 (sm.getString("ajp13Processor.notStarted")); 658 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 659 started = false; 660 661 threadStop(); 662 663 } 664 665 666 } 667 | Popular Tags |