📄 ajp13processor.java
字号:
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ajp.tomcat4;
import java.io.IOException;
import java.net.Socket;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.ajp.Ajp13;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.tomcat.util.http.BaseRequest;
/**
* @author Kevin Seguin
* @version $Revision: 299218 $ $Date: 2004-02-24 03:48:44 -0500 (Tue, 24 Feb 2004) $
*/
final class Ajp13Processor
implements Lifecycle, Runnable {
/**
* A simple class to provide synchronized access
* to a boolean.
*/
private class Bool {
private boolean b = false;
Bool() {
}
Bool(boolean b) {
this.b = b;
}
synchronized boolean value() {
return b;
}
synchronized void set(boolean b) {
this.b = b;
}
}
// ----------------------------------------------------------- Constructors
/**
* Construct a new Ajp13Processor associated with the specified connector.
*
* @param connector Ajp13Connector that owns this processor
* @param id Identifier of this Ajp13Processor (unique per connector)
* @param threadGroup The thread group any threads created by the processor
* should be in.
*/
public Ajp13Processor(Ajp13Connector connector,
int id,
ThreadGroup threadGroup) {
super();
this.connector = connector;
this.debug = connector.getDebug();
this.id = id;
this.request = (Ajp13Request) connector.createRequest();
this.request.setConnector(connector);
this.request.setConnector(connector);
this.response = (Ajp13Response) connector.createResponse();
this.response.setConnector(connector);
this.threadName =
"Ajp13Processor[" + connector.getPort() + "][" + id + "]";
this.threadGroup = threadGroup;
this.logger.setConnector(connector);
this.logger.setName(this.threadName);
}
// ----------------------------------------------------- Instance Variables
private Ajp13Logger logger = new Ajp13Logger();
private BaseRequest ajpRequest = new BaseRequest();
/**
* Is there a new socket available?
*/
private boolean available = false;
/**
* The Ajp13Connector with which this processor is associated.
*/
private Ajp13Connector connector = null;
/**
* The debugging detail level for this component.
*/
private int debug = 0;
/**
* The identifier of this processor, unique per connector.
*/
private int id = 0;
/**
* The lifecycle event support for this component.
*/
private LifecycleSupport lifecycle = new LifecycleSupport(this);
/**
* The AJP13 request object we will pass to our associated container.
*/
private Ajp13Request request = null;
/**
* The AJP13 response object we will pass to our associated container.
*/
private Ajp13Response response = null;
/**
* The string manager for this package.
*/
protected StringManager sm =
StringManager.getManager(Constants.PACKAGE);
/**
* The socket we are currently processing a request for. This object
* is used for inter-thread communication only.
*/
private Socket socket = null;
/**
* Has this component been started yet?
*/
private boolean started = false;
/**
* The shutdown signal to our background thread
*/
private Bool stopped = new Bool(true);
/**
* Are we currently handling a request?
*/
private Bool handlingRequest = new Bool(false);
/**
* The background thread.
*/
private Thread thread = null;
/**
* The name to register for the background thread.
*/
private String threadName = null;
/**
* This processor's thread group.
*/
private ThreadGroup threadGroup = null;
/**
* The thread synchronization object.
*/
private Object threadSync = new Object();
// -------------------------------------------------------- Package Methods
/**
* Process an incoming TCP/IP connection on the specified socket. Any
* exception that occurs during processing must be logged and swallowed.
* <b>NOTE</b>: This method is called from our Connector's thread. We
* must assign it to our own thread so that multiple simultaneous
* requests can be handled.
*
* @param socket TCP socket to process
*/
synchronized void assign(Socket socket) {
// Wait for the Processor to get the previous Socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Store the newly available Socket and notify our thread
this.socket = socket;
available = true;
notifyAll();
if ((debug > 0) && (socket != null))
logger.log(" An incoming request is being assigned");
}
// -------------------------------------------------------- Private Methods
/**
* Await a newly assigned Socket from our Connector, or <code>null</code>
* if we are supposed to shut down.
*/
private synchronized Socket await() {
// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Notify the Connector that we have received this Socket
Socket socket = this.socket;
available = false;
notifyAll();
if ((debug > 0) && (socket != null))
logger.log(" The incoming request has been awaited");
return (socket);
}
/**
* Parse and record the connection parameters related to this request.
*
* @param socket The socket on which we are connected
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a parsing error occurs
*/
private void parseConnection(Socket socket)
throws IOException, ServletException {
if (debug > 1)
logger.log(" parseConnection: address=" + socket.getInetAddress() +
", port=" + connector.getPort());
request.setServerPort(connector.getPort());
request.setSocket(socket);
}
/**
* Process an incoming AJP13 request on the Socket that has been assigned
* to this Processor. Any exceptions that occur during processing must be
* swallowed and dealt with.
*
* @param socket The socket on which we are connected to the client
*/
private void process(Socket socket) {
Ajp13 ajp13 = new Ajp13();
ajp13.setDebug(debug);
ajp13.setLogger(new org.apache.ajp.Logger() {
public void log(String msg) {
logger.log("[Ajp13] " + msg);
}
public void log(String msg, Throwable t) {
logger.log("[Ajp13] " + msg, t);
}
});
Ajp13InputStream input = new Ajp13InputStream(ajp13);
Ajp13OutputStream output = new Ajp13OutputStream(ajp13);
response.setAjp13(ajp13);
try {
ajp13.setSocket(socket);
} catch (IOException e) {
logger.log("process: ajp13.setSocket", e);
}
boolean moreRequests = true;
String expectedSecret=connector.getSecret();
boolean needAuth= ( expectedSecret != null );
while (moreRequests && !stopped.value()) {
int status = 0;
try {
if (debug > 0) {
logger.log("waiting on next request...");
}
status = ajp13.receiveNextRequest(ajpRequest);
if (debug > 0) {
logger.log("received next request, status=" + status);
}
} catch (IOException e) {
logger.log("process: ajp13.receiveNextRequest", e);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -