This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,279 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import java.net.InetAddress;
import java.util.regex.Pattern;
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.Processor;
import org.apache.coyote.UpgradeProtocol;
import org.apache.coyote.UpgradeToken;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.apache.tomcat.util.res.StringManager;
/**
* The is the base implementation for the AJP protocol handlers. Implementations
* typically extend this base class rather than implement {@link
* org.apache.coyote.ProtocolHandler}. All of the implementations that ship with
* Tomcat are implemented this way.
*
* @param <S> The type of socket used by the implementation
*/
public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> {
/**
* The string manager for this package.
*/
protected static final StringManager sm = StringManager.getManager(AbstractAjpProtocol.class);
public AbstractAjpProtocol(AbstractEndpoint<S> endpoint) {
super(endpoint);
setConnectionTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
// AJP does not use Send File
getEndpoint().setUseSendfile(false);
// AJP listens on loopback by default
getEndpoint().setAddress(InetAddress.getLoopbackAddress());
ConnectionHandler<S> cHandler = new ConnectionHandler<>(this);
setHandler(cHandler);
getEndpoint().setHandler(cHandler);
}
@Override
protected String getProtocolName() {
return "Ajp";
}
/**
* {@inheritDoc}
*
* Overridden to make getter accessible to other classes in this package.
*/
@Override
protected AbstractEndpoint<S> getEndpoint() {
return super.getEndpoint();
}
/**
* {@inheritDoc}
*
* AJP does not support protocol negotiation so this always returns null.
*/
@Override
protected UpgradeProtocol getNegotiatedProtocol(String name) {
return null;
}
/**
* {@inheritDoc}
*
* AJP does not support protocol upgrade so this always returns null.
*/
@Override
protected UpgradeProtocol getUpgradeProtocol(String name) {
return null;
}
// ------------------------------------------------- AJP specific properties
// ------------------------------------------ managed in the ProtocolHandler
protected boolean ajpFlush = true;
public boolean getAjpFlush() { return ajpFlush; }
/**
* Configure whether to aend an AJP flush packet when flushing. A flush
* packet is a zero byte AJP13 SEND_BODY_CHUNK packet. mod_jk and
* mod_proxy_ajp interpret this as a request to flush data to the client.
* AJP always does flush at the and of the response, so if it is not
* important, that the packets get streamed up to the client, do not use
* extra flush packets. For compatibility and to stay on the safe side,
* flush packets are enabled by default.
*
* @param ajpFlush The new flush setting
*/
public void setAjpFlush(boolean ajpFlush) {
this.ajpFlush = ajpFlush;
}
private boolean tomcatAuthentication = true;
/**
* Should authentication be done in the native web server layer,
* or in the Servlet container ?
*
* @return {@code true} if authentication should be performed by Tomcat,
* otherwise {@code false}
*/
public boolean getTomcatAuthentication() { return tomcatAuthentication; }
public void setTomcatAuthentication(boolean tomcatAuthentication) {
this.tomcatAuthentication = tomcatAuthentication;
}
private boolean tomcatAuthorization = false;
/**
* Should authentication be done in the native web server layer and
* authorization in the Servlet container?
*
* @return {@code true} if authorization should be performed by Tomcat,
* otherwise {@code false}
*/
public boolean getTomcatAuthorization() { return tomcatAuthorization; }
public void setTomcatAuthorization(boolean tomcatAuthorization) {
this.tomcatAuthorization = tomcatAuthorization;
}
private String secret = null;
/**
* Set the secret that must be included with every request.
*
* @param secret The required secret
*/
public void setSecret(String secret) {
this.secret = secret;
}
protected String getSecret() {
return secret;
}
/**
* Set the required secret that must be included with every request.
*
* @param requiredSecret The required secret
*
* @deprecated Replaced by {@link #setSecret(String)}.
* Will be removed in Tomcat 11 onwards
*/
@Deprecated
public void setRequiredSecret(String requiredSecret) {
setSecret(requiredSecret);
}
/**
* @return The current secret
*
* @deprecated Replaced by {@link #getSecret()}.
* Will be removed in Tomcat 11 onwards
*/
@Deprecated
protected String getRequiredSecret() {
return getSecret();
}
private boolean secretRequired = true;
public void setSecretRequired(boolean secretRequired) {
this.secretRequired = secretRequired;
}
public boolean getSecretRequired() {
return secretRequired;
}
private Pattern allowedRequestAttributesPattern;
public void setAllowedRequestAttributesPattern(String allowedRequestAttributesPattern) {
this.allowedRequestAttributesPattern = Pattern.compile(allowedRequestAttributesPattern);
}
public String getAllowedRequestAttributesPattern() {
return allowedRequestAttributesPattern.pattern();
}
protected Pattern getAllowedRequestAttributesPatternInternal() {
return allowedRequestAttributesPattern;
}
/**
* AJP packet size.
*/
private int packetSize = Constants.MAX_PACKET_SIZE;
public int getPacketSize() { return packetSize; }
public void setPacketSize(int packetSize) {
if(packetSize < Constants.MAX_PACKET_SIZE) {
this.packetSize = Constants.MAX_PACKET_SIZE;
} else {
this.packetSize = packetSize;
}
}
// --------------------------------------------- SSL is not supported in AJP
@Override
public void addSslHostConfig(SSLHostConfig sslHostConfig) {
getLog().warn(sm.getString("ajpprotocol.noSSL", sslHostConfig.getHostName()));
}
@Override
public SSLHostConfig[] findSslHostConfigs() {
return new SSLHostConfig[0];
}
@Override
public void addUpgradeProtocol(UpgradeProtocol upgradeProtocol) {
getLog().warn(sm.getString("ajpprotocol.noUpgrade", upgradeProtocol.getClass().getName()));
}
@Override
public UpgradeProtocol[] findUpgradeProtocols() {
return new UpgradeProtocol[0];
}
@SuppressWarnings("deprecation")
@Override
protected Processor createProcessor() {
AjpProcessor processor = new AjpProcessor(getPacketSize(), getEndpoint());
processor.setAdapter(getAdapter());
processor.setAjpFlush(getAjpFlush());
processor.setTomcatAuthentication(getTomcatAuthentication());
processor.setTomcatAuthorization(getTomcatAuthorization());
processor.setSecret(secret);
processor.setKeepAliveTimeout(getKeepAliveTimeout());
processor.setClientCertProvider(getClientCertProvider());
processor.setSendReasonPhrase(getSendReasonPhrase());
processor.setAllowedRequestAttributesPattern(getAllowedRequestAttributesPatternInternal());
return processor;
}
@Override
protected Processor createUpgradeProcessor(SocketWrapperBase<?> socket,
UpgradeToken upgradeToken) {
throw new IllegalStateException(sm.getString("ajpprotocol.noUpgradeHandler",
upgradeToken.getHttpUpgradeHandler().getClass().getName()));
}
@Override
public void start() throws Exception {
if (getSecretRequired()) {
String secret = getSecret();
if (secret == null || secret.length() == 0) {
throw new IllegalArgumentException(sm.getString("ajpprotocol.nosecret"));
}
}
super.start();
}
}

View File

@@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.AprEndpoint;
/**
* This the APR/native based protocol handler implementation for AJP.
*/
public class AjpAprProtocol extends AbstractAjpProtocol<Long> {
private static final Log log = LogFactory.getLog(AjpAprProtocol.class);
@Override
protected Log getLog() { return log; }
@Override
public boolean isAprRequired() {
// Override since this protocol implementation requires the APR/native
// library
return true;
}
// ------------------------------------------------------------ Constructor
public AjpAprProtocol() {
super(new AprEndpoint());
}
// --------------------------------------------------------- Public Methods
public int getPollTime() { return ((AprEndpoint)getEndpoint()).getPollTime(); }
public void setPollTime(int pollTime) { ((AprEndpoint)getEndpoint()).setPollTime(pollTime); }
// ----------------------------------------------------- JMX related methods
@Override
protected String getNamePrefix() {
return "ajp-apr";
}
}

View File

@@ -0,0 +1,426 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import java.nio.ByteBuffer;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.res.StringManager;
/**
* A single packet for communication between the web server and the
* container. Designed to be reused many times with no creation of
* garbage. Understands the format of data types for these packets.
* Can be used (somewhat confusingly) for both incoming and outgoing
* packets.
*
* @author Henri Gomez
* @author Dan Milstein
* @author Keith Wannamaker
* @author Kevin Seguin
* @author Costin Manolache
*/
public class AjpMessage {
private static final Log log = LogFactory.getLog(AjpMessage.class);
/**
* The string manager for this package.
*/
protected static final StringManager sm = StringManager.getManager(AjpMessage.class);
// ------------------------------------------------------------ Constructor
public AjpMessage(int packetSize) {
buf = new byte[packetSize];
}
// ----------------------------------------------------- Instance Variables
/**
* Fixed size buffer.
*/
protected final byte buf[];
/**
* The current read or write position in the buffer.
*/
protected int pos;
/**
* This actually means different things depending on whether the
* packet is read or write. For read, it's the length of the
* payload (excluding the header). For write, it's the length of
* the packet as a whole (counting the header). Oh, well.
*/
protected int len;
// --------------------------------------------------------- Public Methods
/**
* Prepare this packet for accumulating a message from the container to
* the web server. Set the write position to just after the header
* (but leave the length unwritten, because it is as yet unknown).
*/
public void reset() {
len = 4;
pos = 4;
}
/**
* For a packet to be sent to the web server, finish the process of
* accumulating data and write the length of the data payload into
* the header.
*/
public void end() {
len = pos;
int dLen = len - 4;
buf[0] = (byte) 0x41;
buf[1] = (byte) 0x42;
buf[2] = (byte) ((dLen>>>8) & 0xFF);
buf[3] = (byte) (dLen & 0xFF);
}
/**
* Return the underlying byte buffer.
*
* @return The buffer
*/
public byte[] getBuffer() {
return buf;
}
/**
* Return the current message length.
*
* @return For read, it's the length of the payload (excluding the header).
* For write, it's the length of the packet as a whole (counting the
* header).
*/
public int getLen() {
return len;
}
/**
* Add a short integer (2 bytes) to the message.
*
* @param val The integer to append
*/
public void appendInt(int val) {
buf[pos++] = (byte) ((val >>> 8) & 0xFF);
buf[pos++] = (byte) (val & 0xFF);
}
/**
* Append a byte (1 byte) to the message.
*
* @param val The byte value to append
*/
public void appendByte(int val) {
buf[pos++] = (byte) val;
}
/**
* Write a MessageBytes out at the current write position. A null
* MessageBytes is encoded as a string with length 0.
*
* @param mb The data to write
*/
public void appendBytes(MessageBytes mb) {
if (mb == null) {
log.error(sm.getString("ajpmessage.null"),
new NullPointerException());
appendInt(0);
appendByte(0);
return;
}
if (mb.getType() != MessageBytes.T_BYTES) {
mb.toBytes();
ByteChunk bc = mb.getByteChunk();
// Need to filter out CTLs excluding TAB. ISO-8859-1 and UTF-8
// values will be OK. Strings using other encodings may be
// corrupted.
byte[] buffer = bc.getBuffer();
for (int i = bc.getOffset(); i < bc.getLength(); i++) {
// byte values are signed i.e. -128 to 127
// The values are used unsigned. 0 to 31 are CTLs so they are
// filtered (apart from TAB which is 9). 127 is a control (DEL).
// The values 128 to 255 are all OK. Converting those to signed
// gives -128 to -1.
if ((buffer[i] > -1 && buffer[i] <= 31 && buffer[i] != 9) ||
buffer[i] == 127) {
buffer[i] = ' ';
}
}
}
appendByteChunk(mb.getByteChunk());
}
/**
* Write a ByteChunk out at the current write position. A null ByteChunk is
* encoded as a string with length 0.
*
* @param bc The data to write
*/
public void appendByteChunk(ByteChunk bc) {
if (bc == null) {
log.error(sm.getString("ajpmessage.null"),
new NullPointerException());
appendInt(0);
appendByte(0);
return;
}
appendBytes(bc.getBytes(), bc.getStart(), bc.getLength());
}
/**
* Copy a chunk of bytes into the packet, starting at the current
* write position. The chunk of bytes is encoded with the length
* in two bytes first, then the data itself, and finally a
* terminating \0 (which is <B>not</B> included in the encoded
* length).
*
* @param b The array from which to copy bytes.
* @param off The offset into the array at which to start copying
* @param numBytes The number of bytes to copy.
*/
public void appendBytes(byte[] b, int off, int numBytes) {
if (checkOverflow(numBytes)) {
return;
}
appendInt(numBytes);
System.arraycopy(b, off, buf, pos, numBytes);
pos += numBytes;
appendByte(0);
}
/**
* Copy a chunk of bytes into the packet, starting at the current
* write position. The chunk of bytes is encoded with the length
* in two bytes first, then the data itself, and finally a
* terminating \0 (which is <B>not</B> included in the encoded
* length).
*
* @param b The ByteBuffer from which to copy bytes.
*/
public void appendBytes(ByteBuffer b) {
int numBytes = b.remaining();
if (checkOverflow(numBytes)) {
return;
}
appendInt(numBytes);
b.get(buf, pos, numBytes);
pos += numBytes;
appendByte(0);
}
private boolean checkOverflow(int numBytes) {
if (pos + numBytes + 3 > buf.length) {
log.error(sm.getString("ajpmessage.overflow", "" + numBytes, "" + pos),
new ArrayIndexOutOfBoundsException());
if (log.isDebugEnabled()) {
dump("Overflow/coBytes");
}
return true;
}
return false;
}
/**
* Read an integer from packet, and advance the read position past
* it. Integers are encoded as two unsigned bytes with the
* high-order byte first, and, as far as I can tell, in
* little-endian order within each byte.
*
* @return The integer value read from the message
*/
public int getInt() {
int b1 = buf[pos++] & 0xFF;
int b2 = buf[pos++] & 0xFF;
validatePos(pos);
return (b1<<8) + b2;
}
public int peekInt() {
validatePos(pos + 2);
int b1 = buf[pos] & 0xFF;
int b2 = buf[pos+1] & 0xFF;
return (b1<<8) + b2;
}
public byte getByte() {
byte res = buf[pos++];
validatePos(pos);
return res;
}
public void getBytes(MessageBytes mb) {
doGetBytes(mb, true);
}
public void getBodyBytes(MessageBytes mb) {
doGetBytes(mb, false);
}
private void doGetBytes(MessageBytes mb, boolean terminated) {
int length = getInt();
if ((length == 0xFFFF) || (length == -1)) {
mb.recycle();
return;
}
if (terminated) {
validatePos(pos + length + 1);
} else {
validatePos(pos + length);
}
mb.setBytes(buf, pos, length);
mb.getCharChunk().recycle(); // not valid anymore
pos += length;
if (terminated) {
pos++; // Skip the terminating \0
}
}
/**
* Read a 32 bits integer from packet, and advance the read position past
* it. Integers are encoded as four unsigned bytes with the
* high-order byte first, and, as far as I can tell, in
* little-endian order within each byte.
*
* @return The long value read from the message
*/
public int getLongInt() {
int b1 = buf[pos++] & 0xFF; // No swap, Java order
b1 <<= 8;
b1 |= (buf[pos++] & 0xFF);
b1 <<= 8;
b1 |= (buf[pos++] & 0xFF);
b1 <<=8;
b1 |= (buf[pos++] & 0xFF);
validatePos(pos);
return b1;
}
public int processHeader(boolean toContainer) {
pos = 0;
int mark = getInt();
len = getInt();
// Verify message signature
if ((toContainer && mark != 0x1234) ||
(!toContainer && mark != 0x4142)) {
log.error(sm.getString("ajpmessage.invalid", "" + mark));
if (log.isDebugEnabled()) {
dump("In");
}
return -1;
}
if (log.isDebugEnabled()) {
log.debug("Received " + len + " " + buf[0]);
}
return len;
}
private void dump(String prefix) {
if (log.isDebugEnabled()) {
log.debug(prefix + ": " + HexUtils.toHexString(buf) + " " + pos +"/" + (len + 4));
}
int max = pos;
if (len + 4 > pos)
max = len+4;
if (max > 1000)
max = 1000;
if (log.isDebugEnabled()) {
for (int j = 0; j < max; j += 16) {
log.debug(hexLine(buf, j, len));
}
}
}
private void validatePos(int posToTest) {
if (posToTest > len + 4) {
// Trying to read data beyond the end of the AJP message
throw new ArrayIndexOutOfBoundsException(sm.getString(
"ajpMessage.invalidPos", Integer.valueOf(posToTest)));
}
}
// ------------------------------------------------------ Protected Methods
protected static String hexLine(byte buf[], int start, int len) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < start + 16 ; i++) {
if (i < len + 4) {
sb.append(hex(buf[i]) + " ");
} else {
sb.append(" ");
}
}
sb.append(" | ");
for (int i = start; i < start + 16 && i < len + 4; i++) {
if (!Character.isISOControl((char) buf[i])) {
sb.append(Character.valueOf((char) buf[i]));
} else {
sb.append(".");
}
}
return sb.toString();
}
protected static String hex(int x) {
String h = Integer.toHexString(x);
if (h.length() == 1) {
h = "0" + h;
}
return h.substring(h.length() - 2);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.Nio2Channel;
import org.apache.tomcat.util.net.Nio2Endpoint;
/**
* This the NIO2 based protocol handler implementation for AJP.
*/
public class AjpNio2Protocol extends AbstractAjpProtocol<Nio2Channel> {
private static final Log log = LogFactory.getLog(AjpNio2Protocol.class);
@Override
protected Log getLog() { return log; }
// ------------------------------------------------------------ Constructor
public AjpNio2Protocol() {
super(new Nio2Endpoint());
}
// ----------------------------------------------------- JMX related methods
@Override
protected String getNamePrefix() {
return "ajp-nio2";
}
}

View File

@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
/**
* This the NIO based protocol handler implementation for AJP.
*/
public class AjpNioProtocol extends AbstractAjpProtocol<NioChannel> {
private static final Log log = LogFactory.getLog(AjpNioProtocol.class);
@Override
protected Log getLog() { return log; }
// ------------------------------------------------------------ Constructor
public AjpNioProtocol() {
super(new NioEndpoint());
}
// ----------------------------------------------------- JMX related methods
@Override
protected String getNamePrefix() {
return "ajp-nio";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
/**
* @deprecated This class will be removed in Tomcat 9.
*/
@Deprecated
public class AjpProtocol extends AjpNioProtocol {
private static final Log log = LogFactory.getLog(AjpProtocol.class);
private static final StringManager sm = StringManager.getManager(AjpProtocol.class);
public AjpProtocol() {
super();
log.warn(sm.getString("ajpprotocol.noBio"));
}
}

View File

@@ -0,0 +1,240 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.coyote.ajp;
import java.util.Hashtable;
/**
* Constants.
*
* @author Remy Maucherat
*/
public final class Constants {
public static final int DEFAULT_CONNECTION_TIMEOUT = -1;
// Prefix codes for message types from server to container
public static final byte JK_AJP13_FORWARD_REQUEST = 2;
public static final byte JK_AJP13_SHUTDOWN = 7; // XXX Unused
public static final byte JK_AJP13_PING_REQUEST = 8; // XXX Unused
public static final byte JK_AJP13_CPING_REQUEST = 10;
// Prefix codes for message types from container to server
public static final byte JK_AJP13_SEND_BODY_CHUNK = 3;
public static final byte JK_AJP13_SEND_HEADERS = 4;
public static final byte JK_AJP13_END_RESPONSE = 5;
public static final byte JK_AJP13_GET_BODY_CHUNK = 6;
public static final byte JK_AJP13_CPONG_REPLY = 9;
// Integer codes for common response header strings
public static final int SC_RESP_CONTENT_TYPE = 0xA001;
public static final int SC_RESP_CONTENT_LANGUAGE = 0xA002;
public static final int SC_RESP_CONTENT_LENGTH = 0xA003;
public static final int SC_RESP_DATE = 0xA004;
public static final int SC_RESP_LAST_MODIFIED = 0xA005;
public static final int SC_RESP_LOCATION = 0xA006;
public static final int SC_RESP_SET_COOKIE = 0xA007;
public static final int SC_RESP_SET_COOKIE2 = 0xA008;
public static final int SC_RESP_SERVLET_ENGINE = 0xA009;
public static final int SC_RESP_STATUS = 0xA00A;
public static final int SC_RESP_WWW_AUTHENTICATE = 0xA00B;
public static final int SC_RESP_AJP13_MAX = 11;
// Integer codes for common (optional) request attribute names
public static final byte SC_A_CONTEXT = 1; // XXX Unused
public static final byte SC_A_SERVLET_PATH = 2; // XXX Unused
public static final byte SC_A_REMOTE_USER = 3;
public static final byte SC_A_AUTH_TYPE = 4;
public static final byte SC_A_QUERY_STRING = 5;
public static final byte SC_A_JVM_ROUTE = 6;
public static final byte SC_A_SSL_CERT = 7;
public static final byte SC_A_SSL_CIPHER = 8;
public static final byte SC_A_SSL_SESSION = 9;
public static final byte SC_A_SSL_KEY_SIZE = 11;
public static final byte SC_A_SECRET = 12;
public static final byte SC_A_STORED_METHOD = 13;
// Used for attributes which are not in the list above
public static final byte SC_A_REQ_ATTRIBUTE = 10;
/**
* AJP private request attributes
*/
public static final String SC_A_REQ_LOCAL_ADDR = "AJP_LOCAL_ADDR";
public static final String SC_A_REQ_REMOTE_PORT = "AJP_REMOTE_PORT";
public static final String SC_A_SSL_PROTOCOL = "AJP_SSL_PROTOCOL";
// Terminates list of attributes
public static final byte SC_A_ARE_DONE = (byte)0xFF;
// Ajp13 specific - needs refactoring for the new model
/**
* Default maximum total byte size for an AJP packet
*/
public static final int MAX_PACKET_SIZE = 8192;
/**
* Size of basic packet header
*/
public static final int H_SIZE = 4;
/**
* Size of the header metadata
*/
public static final int READ_HEAD_LEN = 6;
public static final int SEND_HEAD_LEN = 8;
/**
* Default maximum size of data that can be sent in one packet
*/
public static final int MAX_READ_SIZE = MAX_PACKET_SIZE - READ_HEAD_LEN;
public static final int MAX_SEND_SIZE = MAX_PACKET_SIZE - SEND_HEAD_LEN;
// Translates integer codes to names of HTTP methods
private static final String [] methodTransArray = {
"OPTIONS",
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"PROPFIND",
"PROPPATCH",
"MKCOL",
"COPY",
"MOVE",
"LOCK",
"UNLOCK",
"ACL",
"REPORT",
"VERSION-CONTROL",
"CHECKIN",
"CHECKOUT",
"UNCHECKOUT",
"SEARCH",
"MKWORKSPACE",
"UPDATE",
"LABEL",
"MERGE",
"BASELINE-CONTROL",
"MKACTIVITY"
};
/**
* Converts an AJP coded HTTP method to the method name.
* @param code the coded value
* @return the string value of the method
*/
public static final String getMethodForCode(final int code) {
return methodTransArray[code];
}
public static final int SC_M_JK_STORED = (byte) 0xFF;
// id's for common request headers
public static final int SC_REQ_ACCEPT = 1;
public static final int SC_REQ_ACCEPT_CHARSET = 2;
public static final int SC_REQ_ACCEPT_ENCODING = 3;
public static final int SC_REQ_ACCEPT_LANGUAGE = 4;
public static final int SC_REQ_AUTHORIZATION = 5;
public static final int SC_REQ_CONNECTION = 6;
public static final int SC_REQ_CONTENT_TYPE = 7;
public static final int SC_REQ_CONTENT_LENGTH = 8;
public static final int SC_REQ_COOKIE = 9;
public static final int SC_REQ_COOKIE2 = 10;
public static final int SC_REQ_HOST = 11;
public static final int SC_REQ_PRAGMA = 12;
public static final int SC_REQ_REFERER = 13;
public static final int SC_REQ_USER_AGENT = 14;
// Translates integer codes to request header names
private static final String [] headerTransArray = {
"accept",
"accept-charset",
"accept-encoding",
"accept-language",
"authorization",
"connection",
"content-type",
"content-length",
"cookie",
"cookie2",
"host",
"pragma",
"referer",
"user-agent"
};
/**
* Converts an AJP coded HTTP request header to the header name.
* @param code the coded value
* @return the string value of the header name
*/
public static final String getHeaderForCode(final int code) {
return headerTransArray[code];
}
// Translates integer codes to response header names
private static final String [] responseTransArray = {
"Content-Type",
"Content-Language",
"Content-Length",
"Date",
"Last-Modified",
"Location",
"Set-Cookie",
"Set-Cookie2",
"Servlet-Engine",
"Status",
"WWW-Authenticate"
};
/**
* Converts an AJP coded response header name to the HTTP response header name.
* @param code the coded value
* @return the string value of the header
*/
public static final String getResponseHeaderForCode(final int code) {
return responseTransArray[code];
}
private static final Hashtable<String,Integer> responseTransHash =
new Hashtable<>(20);
static {
try {
int i;
for (i = 0; i < SC_RESP_AJP13_MAX; i++) {
responseTransHash.put(getResponseHeaderForCode(i),
Integer.valueOf(0xA001 + i));
}
}
catch (Exception e) {
// Do nothing
}
}
public static final int getResponseAjpIndex(String header)
{
Integer i = responseTransHash.get(header);
if (i == null)
return 0;
else
return i.intValue();
}
}

View File

@@ -0,0 +1,37 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpMessage.invalidPos=Requested read of bytes at position [{0}] which is beyond the end of the AJP message
ajpmessage.invalid=Invalid message received with signature [{0}]
ajpmessage.invalidLength=Invalid message received with length [{0}]
ajpmessage.null=Cannot append null value
ajpmessage.overflow=Overflow error for buffer adding [{0}] bytes at position [{1}]
ajpnioprotocol.releaseEnd=Done iterating through our connections to release a socket channel [{0}] released [{1}]
ajpnioprotocol.releaseStart=Iterating through our connections to release a socket channel [{0}]
ajpprocessor.certs.fail=Certificate conversion failed
ajpprocessor.header.error=Header message parsing failed
ajpprocessor.header.tooLong=Header message of length [{0}] received but the packetSize is only [{1}]
ajpprocessor.readtimeout=Timeout attempting to read data from the socket
ajpprocessor.request.prepare=Error preparing request
ajpprocessor.request.process=Error processing request
ajpprotocol.noBio=The AJP BIO connector has been removed in Tomcat 8.5.x onwards. The AJP BIO connector configuration has been automatically switched to use the AJP NIO connector instead.
ajpprotocol.noSSL=SSL is not supported with AJP. The SSL host configuration for [{0}] was ignored
ajpprotocol.nosecret=The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
ajpprotocol.noUpgrade=Upgrade is not supported with AJP. The UpgradeProtocol configuration for [{0}] was ignored
ajpprotocol.noUpgradeHandler=Upgrade is not supported with AJP. The HttpUpgradeHandler [{0}] can not be processed

View File

@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpmessage.overflow=Überlauffehler im Puffer beim Hinzufügen von [{0}] Bytes an Position [{1}]
ajpprotocol.noUpgrade=Upgrade wird von AJP nicht unterstützt. Die Konfiguration UpgradeProtocol für [{0}] wurde ignoriert

View File

@@ -0,0 +1,25 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpmessage.invalid=Mensaje inválido recibido con firma [{0}]
ajpmessage.null=No puedo añadir valor nulo
ajpmessage.overflow=Error de desbordamiento en búfer al añadir [{0}] bytes en posición [{1}]
ajpprocessor.certs.fail=Fallo en conversión de Certificado
ajpprocessor.header.error=Fallo en análisis de mensaje de cabecera
ajpprocessor.request.prepare=Error preparando requerimiento
ajpprocessor.request.process=Error procesando requerimiento
ajpprotocol.noUpgrade=Actualización (upgrade) no esta soportada para AJP. Se ha ignorado la configuración UpgradeProtocol para [{0}]

View File

@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpMessage.invalidPos=Une lecture d''octets à la position [{0}] a été demandée ce qui est au-delà de la fin du message AJP
ajpmessage.invalid=Message invalide reçu avec la signature [{0}]
ajpmessage.invalidLength=Message invalide reçu avec une longueur [{0}]
ajpmessage.null=Impossible d'ajouter une valeur nulle.
ajpmessage.overflow=Débordement du tampon en ajoutant [{0}] octets à la position [{1}]
ajpprocessor.certs.fail=La conversion du certificat a échouée
ajpprocessor.header.error=Erreur de traitement du message d'en-tête
ajpprocessor.header.tooLong=Un en-tête de message de taille [{0}] a été reçu mais la packtSize est de seulement [{1}]
ajpprocessor.readtimeout=Timeout lors de la lecture de données sur le socket
ajpprocessor.request.prepare=Erreur lors de la préparation de la requête
ajpprocessor.request.process=Erreur de traitement de la requête
ajpprotocol.noSSL=SSL n''est pas supporté par AJP, la configuration de l''hôte SSL pour [{0}] a été ignorée
ajpprotocol.noUpgrade=L''upgrade n''est pas supporté par AJP. La configuration UpgradeProtocol pour [{0}] a été ignorée
ajpprotocol.noUpgradeHandler=AJP ne supporte pas la mise à niveau (upgrade) de HTTP/1.1, le HttpUpgradeHandler [{0}] ne peut pas être utilisé

View File

@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpMessage.invalidPos=AJP メッセージの終端より先の位置 [{0}] のバイト読み取りを要求されました。
ajpmessage.invalid=署名[{0}]で無効なメッセージが受信されました。
ajpmessage.invalidLength=長さ[{0}]の無効なメッセージが受信されました
ajpmessage.null=null 値は追加できません。
ajpmessage.overflow=バッファーの位置 [{1}] へ [{0}] バイトのデータを追加しようとして、オーバーフローエラーが発生しました。
ajpprocessor.certs.fail=証明書変換に失敗しました。
ajpprocessor.header.error=ヘッダーメッセージの解析に失敗しました
ajpprocessor.header.tooLong=受信したヘッダーに指定されたメッセージ長は [{0}] ですがpacketSize は [{1}] しかありません。
ajpprocessor.readtimeout=ソケットからのデータの読み取りをタイムアウトにします。
ajpprocessor.request.prepare=リクエスト準備中エラー
ajpprocessor.request.process=リクエスト処理エラー
ajpprotocol.noSSL=AJP は SSL に対応していません。SSL ホスト構成 [{0}] を無視します。
ajpprotocol.noUpgrade=AJP はプロトコルアップグレードに対応していないため、[{0}] の設定を無視しました。
ajpprotocol.noUpgradeHandler=アップグレードはAJPではサポートされていません。 HttpUpgradeHandler [{0}]を処理できません。

View File

@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpMessage.invalidPos=위치 [{0}](으)로부터 바이트들을 읽기를 요청 받았는데, 이는 해당 AJP 메시지의 끝 위치를 넘어섰습니다.
ajpmessage.invalid=서명 [{0}]와(과) 함께, 유효하지 않은 메시지를 받았습니다.
ajpmessage.invalidLength=길이가 [{0}]인 유효하지 않은 메시지를 받았습니다.
ajpmessage.null=널 값을 추가할 수 없습니다.
ajpmessage.overflow=버퍼에 [{0}] 바이트들을 위치 [{1}]에 추가하는 동안 오버플로우 오류 발생
ajpprocessor.certs.fail=인증서를 변환시키지 못했습니다.
ajpprocessor.header.error=헤더 메시지를 파싱하지 못했습니다.
ajpprocessor.header.tooLong=길이가 [{0}]인 헤더 메시지를 받았지만, 패킷 크기는 단지 [{1}]입니다.
ajpprocessor.readtimeout=소켓으로부터 데이터를 읽으려는 시도가 제한 시간 초과되었습니다.
ajpprocessor.request.prepare=요청을 준비하는 중 오류 발생
ajpprocessor.request.process=요청 처리 중 오류 발생
ajpprotocol.noSSL=AJP와 함께 SSL은 지원되지 않습니다. [{0}]을(를) 위한 SSL 호스트 설정은 무시되었습니다.
ajpprotocol.noUpgrade=AJP에서 프로토콜 업그레이드는 지원되지 않습니다. [{0}]을(를) 위한 UpgradeProtocol 설정은 무시됩니다.
ajpprotocol.noUpgradeHandler=AJP를 사용할 때, 업그레이드는 지원되지 않습니다. HttpUpgradeHandler [{0}]은(는) 처리될 수 없습니다.

View File

@@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
ajpmessage.null=不能赋空值
ajpmessage.overflow=在缓冲区[{1}]位置添加[{0}]字节时发生溢出错误
ajpprocessor.certs.fail=):证书转换失败
ajpprocessor.header.error=头部信息解析失败
ajpprocessor.readtimeout=从Socket读取数据超时
ajpprotocol.noUpgrade=AJP 不支持升级。[{0}] 的升级协议配置被忽略。