[Bug 387928] retire jetty-ajp

This commit is contained in:
Jesse McConnell 2012-08-23 14:09:29 -05:00
parent a77093dd94
commit 6dadf2a8a4
15 changed files with 0 additions and 3614 deletions

View File

@ -1,82 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-ajp</artifactId>
<name>Jetty :: AJP</name>
<properties>
<bundle-symbolic-name>${project.groupId}.ajp</bundle-symbolic-name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="2.6.0",*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<!--
Required for OSGI
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.eclipse.jetty.ajp.*</onlyAnalyze>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Add a AJP listener on port 8009 -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.ajp.Ajp13SocketConnector">
<Set name="port">8009</Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -1,250 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.BlockingHttpConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* Connection implementation of the Ajp13 protocol. <p/> XXX Refactor to remove
* duplication of HttpConnection
*
*/
public class Ajp13Connection extends BlockingHttpConnection
{
private static final Logger LOG = Log.getLogger(Ajp13Connection.class);
public Ajp13Connection(Connector connector, EndPoint endPoint, Server server)
{
super(connector, endPoint, server,
new Ajp13Parser(connector.getRequestBuffers(), endPoint),
new Ajp13Generator(connector.getResponseBuffers(), endPoint),
new Ajp13Request()
);
((Ajp13Parser)_parser).setEventHandler(new RequestHandler());
((Ajp13Parser)_parser).setGenerator((Ajp13Generator)_generator);
((Ajp13Request)_request).setConnection(this);
}
@Override
public boolean isConfidential(Request request)
{
return ((Ajp13Request) request).isSslSecure();
}
@Override
public boolean isIntegral(Request request)
{
return ((Ajp13Request) request).isSslSecure();
}
@Override
public ServletInputStream getInputStream()
{
if (_in == null)
_in = new Ajp13Parser.Input((Ajp13Parser) _parser, _connector.getMaxIdleTime());
return _in;
}
private class RequestHandler implements Ajp13Parser.EventHandler
{
public void startForwardRequest() throws IOException
{
_uri.clear();
((Ajp13Request) _request).setSslSecure(false);
_request.setTimeStamp(System.currentTimeMillis());
_request.setUri(_uri);
}
public void parsedAuthorizationType(Buffer authType) throws IOException
{
//TODO JASPI this doesn't appear to make sense yet... how does ajp auth fit into jetty auth?
// _request.setAuthType(authType.toString());
}
public void parsedRemoteUser(Buffer remoteUser) throws IOException
{
((Ajp13Request)_request).setRemoteUser(remoteUser.toString());
}
public void parsedServletPath(Buffer servletPath) throws IOException
{
_request.setServletPath(servletPath.toString());
}
public void parsedContextPath(Buffer context) throws IOException
{
_request.setContextPath(context.toString());
}
public void parsedSslCert(Buffer sslCert) throws IOException
{
try
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bis = new ByteArrayInputStream(sslCert.toString().getBytes());
Collection<? extends java.security.cert.Certificate> certCollection = cf.generateCertificates(bis);
X509Certificate[] certificates = new X509Certificate[certCollection.size()];
int i=0;
for (Object aCertCollection : certCollection)
{
certificates[i++] = (X509Certificate) aCertCollection;
}
_request.setAttribute("javax.servlet.request.X509Certificate", certificates);
}
catch (Exception e)
{
LOG.warn(e.toString());
LOG.ignore(e);
if (sslCert!=null)
_request.setAttribute("javax.servlet.request.X509Certificate", sslCert.toString());
}
}
public void parsedSslCipher(Buffer sslCipher) throws IOException
{
_request.setAttribute("javax.servlet.request.cipher_suite", sslCipher.toString());
}
public void parsedSslSession(Buffer sslSession) throws IOException
{
_request.setAttribute("javax.servlet.request.ssl_session", sslSession.toString());
}
public void parsedSslKeySize(int keySize) throws IOException
{
_request.setAttribute("javax.servlet.request.key_size", new Integer(keySize));
}
public void parsedMethod(Buffer method) throws IOException
{
if (method == null)
throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);
_request.setMethod(method.toString());
}
public void parsedUri(Buffer uri) throws IOException
{
_uri.parse(uri.toString());
}
public void parsedProtocol(Buffer protocol) throws IOException
{
if (protocol != null && protocol.length()>0)
{
_request.setProtocol(protocol.toString());
}
}
public void parsedRemoteAddr(Buffer addr) throws IOException
{
if (addr != null && addr.length()>0)
{
_request.setRemoteAddr(addr.toString());
}
}
public void parsedRemoteHost(Buffer name) throws IOException
{
if (name != null && name.length()>0)
{
_request.setRemoteHost(name.toString());
}
}
public void parsedServerName(Buffer name) throws IOException
{
if (name != null && name.length()>0)
{
_request.setServerName(name.toString());
}
}
public void parsedServerPort(int port) throws IOException
{
_request.setServerPort(port);
}
public void parsedSslSecure(boolean secure) throws IOException
{
((Ajp13Request) _request).setSslSecure(secure);
}
public void parsedQueryString(Buffer value) throws IOException
{
String u = _uri + "?" + value;
_uri.parse(u);
}
public void parsedHeader(Buffer name, Buffer value) throws IOException
{
_requestFields.add(name, value);
}
public void parsedRequestAttribute(String key, Buffer value) throws IOException
{
if (value==null)
_request.removeAttribute(key);
else
_request.setAttribute(key,value.toString());
}
public void parsedRequestAttribute(String key, int value) throws IOException
{
_request.setAttribute(key, Integer.toString(value));
}
public void headerComplete() throws IOException
{
handleRequest();
}
public void messageComplete(long contextLength) throws IOException
{
}
public void content(Buffer ref) throws IOException
{
}
}
}

View File

@ -1,831 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import org.eclipse.jetty.http.AbstractGenerator;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpTokens;
import org.eclipse.jetty.http.HttpVersions;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
*
*
*/
public class Ajp13Generator extends AbstractGenerator
{
private static final Logger LOG = Log.getLogger(Ajp13Generator.class);
private static HashMap __headerHash = new HashMap();
static
{
byte[] xA001 =
{ (byte)0xA0, (byte)0x01 };
byte[] xA002 =
{ (byte)0xA0, (byte)0x02 };
byte[] xA003 =
{ (byte)0xA0, (byte)0x03 };
byte[] xA004 =
{ (byte)0xA0, (byte)0x04 };
byte[] xA005 =
{ (byte)0xA0, (byte)0x05 };
byte[] xA006 =
{ (byte)0xA0, (byte)0x06 };
byte[] xA007 =
{ (byte)0xA0, (byte)0x07 };
byte[] xA008 =
{ (byte)0xA0, (byte)0x08 };
byte[] xA009 =
{ (byte)0xA0, (byte)0x09 };
byte[] xA00A =
{ (byte)0xA0, (byte)0x0A };
byte[] xA00B =
{ (byte)0xA0, (byte)0x0B };
__headerHash.put("Content-Type",xA001);
__headerHash.put("Content-Language",xA002);
__headerHash.put("Content-Length",xA003);
__headerHash.put("Date",xA004);
__headerHash.put("Last-Modified",xA005);
__headerHash.put("Location",xA006);
__headerHash.put("Set-Cookie",xA007);
__headerHash.put("Set-Cookie2",xA008);
__headerHash.put("Servlet-Engine",xA009);
__headerHash.put("Status",xA00A);
__headerHash.put("WWW-Authenticate",xA00B);
}
// A, B ajp response header
// 0, 1 ajp int 1 packet length
// 9 CPONG response Code
private static final byte[] AJP13_CPONG_RESPONSE =
{ 'A', 'B', 0, 1, 9 };
private static final byte[] AJP13_END_RESPONSE =
{ 'A', 'B', 0, 2, 5, 1 };
// AB ajp respose
// 0, 3 int = 3 packets in length
// 6, send signal to get more data
// 31, -7 byte values for int 8185 = (8 * 1024) - 7 MAX_DATA
private static final byte[] AJP13_MORE_CONTENT =
{ 'A', 'B', 0, 3, 6, 31, -7 };
private static String SERVER = "Server: Jetty(7.x.x)";
public static void setServerVersion(String version)
{
SERVER = "Jetty(" + version + ")";
}
/* ------------------------------------------------------------ */
private boolean _expectMore = false;
private boolean _needMore = false;
private boolean _needEOC = false;
private boolean _bufferPrepared = false;
/* ------------------------------------------------------------ */
public Ajp13Generator(Buffers buffers, EndPoint io)
{
super(buffers,io);
}
/* ------------------------------------------------------------ */
@Override
public boolean isRequest()
{
return false;
}
/* ------------------------------------------------------------ */
@Override
public boolean isResponse()
{
return true;
}
/* ------------------------------------------------------------ */
@Override
public void reset()
{
super.reset();
_needEOC = false;
_needMore = false;
_expectMore = false;
_bufferPrepared = false;
_last = false;
_state = STATE_HEADER;
_status = 0;
_version = HttpVersions.HTTP_1_1_ORDINAL;
_reason = null;
_method = null;
_uri = null;
_contentWritten = 0;
_contentLength = HttpTokens.UNKNOWN_CONTENT;
_last = false;
_head = false;
_noContent = false;
_persistent = true;
_header = null; // Buffer for HTTP header (and maybe small _content)
_buffer = null; // Buffer for copy of passed _content
_content = null; // Buffer passed to addContent
}
/* ------------------------------------------------------------ */
@Override
public int getContentBufferSize()
{
try
{
initContent();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
return super.getContentBufferSize() - 7;
}
/* ------------------------------------------------------------ */
@Override
public void increaseContentBufferSize(int contentBufferSize)
{
// Not supported with AJP
}
/* ------------------------------------------------------------ */
/**
* Add content.
*
* @param content
* @param last
* @throws IllegalArgumentException
* if <code>content</code> is {@link Buffer#isImmutable immutable}.
* @throws IllegalStateException
* If the request is not expecting any more content, or if the buffers are full and cannot be flushed.
* @throws IOException
* if there is a problem flushing the buffers.
*/
public void addContent(Buffer content, boolean last) throws IOException
{
if (_noContent)
{
content.clear();
return;
}
if (content.isImmutable())
throw new IllegalArgumentException("immutable");
if (_last || _state == STATE_END)
{
LOG.debug("Ignoring extra content {}",content);
content.clear();
return;
}
_last = last;
if (!_endp.isOpen())
{
_state = STATE_END;
return;
}
// Handle any unfinished business?
if (_content != null && _content.length() > 0)
{
flushBuffer();
if (_content != null && _content.length() > 0)
throw new IllegalStateException("FULL");
}
_content = content;
_contentWritten += content.length();
// Handle the _content
if (_head)
{
content.clear();
_content = null;
}
else
{
// Yes - so we better check we have a buffer
initContent();
// Copy _content to buffer;
int len = 0;
len = _buffer.put(_content);
// make sure there is space for a trailing null
if (len > 0 && _buffer.space() == 0)
{
len--;
_buffer.setPutIndex(_buffer.putIndex() - 1);
}
_content.skip(len);
if (_content.length() == 0)
_content = null;
}
}
/* ------------------------------------------------------------ */
/**
* Add content.
*
* @param b
* byte
* @return true if the buffers are full
* @throws IOException
*/
public boolean addContent(byte b) throws IOException
{
if (_noContent)
return false;
if (_last || _state == STATE_END)
throw new IllegalStateException("Closed");
if (!_endp.isOpen())
{
_state = STATE_END;
return false;
}
// Handle any unfinished business?
if (_content != null && _content.length() > 0)
{
flushBuffer();
if (_content != null && _content.length() > 0)
throw new IllegalStateException("FULL");
}
_contentWritten++;
// Handle the _content
if (_head)
return false;
// we better check we have a buffer
initContent();
// Copy _content to buffer;
_buffer.put(b);
return _buffer.space() <= 1;
}
/* ------------------------------------------------------------ */
/**
* Prepare buffer for unchecked writes. Prepare the generator buffer to receive unchecked writes
*
* @return the available space in the buffer.
* @throws IOException
*/
@Override
public int prepareUncheckedAddContent() throws IOException
{
if (_noContent)
return -1;
if (_last || _state == STATE_END)
throw new IllegalStateException("Closed");
if (!_endp.isOpen())
{
_state = STATE_END;
return -1;
}
// Handle any unfinished business?
Buffer content = _content;
if (content != null && content.length() > 0)
{
flushBuffer();
if (content != null && content.length() > 0)
throw new IllegalStateException("FULL");
}
// we better check we have a buffer
initContent();
_contentWritten -= _buffer.length();
// Handle the _content
if (_head)
return Integer.MAX_VALUE;
return _buffer.space() - 1;
}
/* ------------------------------------------------------------ */
@Override
public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
{
if (_state != STATE_HEADER)
return;
if (_last && !allContentAdded)
throw new IllegalStateException("last?");
_last = _last | allContentAdded;
boolean has_server = false;
if (_persistent == null)
_persistent = (_version > HttpVersions.HTTP_1_0_ORDINAL);
// get a header buffer
if (_header == null)
_header = _buffers.getHeader();
Buffer tmpbuf = _buffer;
_buffer = _header;
try
{
// start the header
_buffer.put((byte)'A');
_buffer.put((byte)'B');
addInt(0);
_buffer.put((byte)0x4);
addInt(_status);
if (_reason == null)
_reason = HttpGenerator.getReasonBuffer(_status);
if (_reason == null)
_reason = new ByteArrayBuffer(Integer.toString(_status));
addBuffer(_reason);
if (_status == 100 || _status == 204 || _status == 304)
{
_noContent = true;
_content = null;
}
// allocate 2 bytes for number of headers
int field_index = _buffer.putIndex();
addInt(0);
int num_fields = 0;
if (fields != null)
{
// Add headers
int s = fields.size();
for (int f = 0; f < s; f++)
{
HttpFields.Field field = fields.getField(f);
if (field == null)
continue;
num_fields++;
byte[] codes = (byte[])__headerHash.get(field.getName());
if (codes != null)
{
_buffer.put(codes);
}
else
{
addString(field.getName());
}
addString(field.getValue());
}
}
if (!has_server && _status > 100 && getSendServerVersion())
{
num_fields++;
addString("Server");
addString(SERVER);
}
// TODO Add content length if last content known.
// insert the number of headers
int tmp = _buffer.putIndex();
_buffer.setPutIndex(field_index);
addInt(num_fields);
_buffer.setPutIndex(tmp);
// get the payload size ( - 4 bytes for the ajp header)
// excluding the
// ajp header
int payloadSize = _buffer.length() - 4;
// insert the total packet size on 2nd and 3rd byte that
// was previously
// allocated
addInt(2,payloadSize);
}
finally
{
_buffer = tmpbuf;
}
_state = STATE_CONTENT;
}
/* ------------------------------------------------------------ */
/**
* Complete the message.
*
* @throws IOException
*/
@Override
public void complete() throws IOException
{
if (_state == STATE_END)
return;
super.complete();
if (_state < STATE_FLUSHING)
{
_state = STATE_FLUSHING;
_needEOC = true;
}
flushBuffer();
}
/* ------------------------------------------------------------ */
@Override
public int flushBuffer() throws IOException
{
try
{
if (_state == STATE_HEADER && !_expectMore)
throw new IllegalStateException("State==HEADER");
prepareBuffers();
if (_endp == null)
{
// TODO - probably still needed!
// if (_rneedMore && _buffe != null)
// {
// if(!_hasSentEOC)
// _buffer.put(AJP13_MORE_CONTENT);
// }
if (!_expectMore && _needEOC && _buffer != null)
{
_buffer.put(AJP13_END_RESPONSE);
}
_needEOC = false;
return 0;
}
// Keep flushing while there is something to flush
// (except break below)
int total = 0;
long last_len = -1;
Flushing: while (true)
{
int len = -1;
int to_flush = ((_header != null && _header.length() > 0)?4:0) | ((_buffer != null && _buffer.length() > 0)?2:0);
switch (to_flush)
{
case 7:
throw new IllegalStateException(); // should
// never
// happen!
case 6:
len = _endp.flush(_header,_buffer,null);
break;
case 5:
throw new IllegalStateException(); // should
// never
// happen!
case 4:
len = _endp.flush(_header);
break;
case 3:
throw new IllegalStateException(); // should
// never
// happen!
case 2:
len = _endp.flush(_buffer);
break;
case 1:
throw new IllegalStateException(); // should
// never
// happen!
case 0:
{
// Nothing more we can write now.
if (_header != null)
_header.clear();
_bufferPrepared = false;
if (_buffer != null)
{
_buffer.clear();
// reserve some space for the
// header
_buffer.setPutIndex(7);
_buffer.setGetIndex(7);
// Special case handling for
// small left over buffer from
// an addContent that caused a
// buffer flush.
if (_content != null && _content.length() < _buffer.space() && _state != STATE_FLUSHING)
{
_buffer.put(_content);
_content.clear();
_content = null;
break Flushing;
}
}
// Are we completely finished for now?
if (!_expectMore && !_needEOC && (_content == null || _content.length() == 0))
{
if (_state == STATE_FLUSHING)
_state = STATE_END;
// if (_state == STATE_END)
// {
// _endp.close();
// }
//
break Flushing;
}
// Try to prepare more to write.
prepareBuffers();
}
}
// If we failed to flush anything twice in a row
// break
if (len <= 0)
{
if (last_len <= 0)
break Flushing;
break;
}
last_len = len;
total += len;
}
return total;
}
catch (IOException e)
{
LOG.ignore(e);
throw (e instanceof EofException)?e:new EofException(e);
}
}
/* ------------------------------------------------------------ */
private void prepareBuffers()
{
if (!_bufferPrepared)
{
// Refill buffer if possible
if (_content != null && _content.length() > 0 && _buffer != null && _buffer.space() > 0)
{
int len = _buffer.put(_content);
// Make sure there is space for a trailing null
if (len > 0 && _buffer.space() == 0)
{
len--;
_buffer.setPutIndex(_buffer.putIndex() - 1);
}
_content.skip(len);
if (_content.length() == 0)
_content = null;
if (_buffer.length() == 0)
{
_content = null;
}
}
// add header if needed
if (_buffer != null)
{
int payloadSize = _buffer.length();
// 4 bytes for the ajp header
// 1 byte for response type
// 2 bytes for the response size
// 1 byte because we count from zero??
if (payloadSize > 0)
{
_bufferPrepared = true;
_buffer.put((byte)0);
int put = _buffer.putIndex();
_buffer.setGetIndex(0);
_buffer.setPutIndex(0);
_buffer.put((byte)'A');
_buffer.put((byte)'B');
addInt(payloadSize + 4);
_buffer.put((byte)3);
addInt(payloadSize);
_buffer.setPutIndex(put);
}
}
if (_needMore)
{
if (_header == null)
{
_header = _buffers.getHeader();
}
if (_buffer == null && _header != null && _header.space() >= AJP13_MORE_CONTENT.length)
{
_header.put(AJP13_MORE_CONTENT);
_needMore = false;
}
else if (_buffer != null && _buffer.space() >= AJP13_MORE_CONTENT.length)
{
// send closing packet if all contents
// are added
_buffer.put(AJP13_MORE_CONTENT);
_needMore = false;
_bufferPrepared = true;
}
}
if (!_expectMore && _needEOC)
{
if (_buffer == null && _header.space() >= AJP13_END_RESPONSE.length)
{
_header.put(AJP13_END_RESPONSE);
_needEOC = false;
}
else if (_buffer != null && _buffer.space() >= AJP13_END_RESPONSE.length)
{
// send closing packet if all contents
// are added
_buffer.put(AJP13_END_RESPONSE);
_needEOC = false;
_bufferPrepared = true;
}
}
}
}
/* ------------------------------------------------------------ */
@Override
public boolean isComplete()
{
return !_expectMore && _state == STATE_END;
}
/* ------------------------------------------------------------ */
private void initContent() throws IOException
{
if (_buffer == null)
{
_buffer = _buffers.getBuffer();
_buffer.setPutIndex(7);
_buffer.setGetIndex(7);
}
}
/* ------------------------------------------------------------ */
private void addInt(int i)
{
_buffer.put((byte)((i >> 8) & 0xFF));
_buffer.put((byte)(i & 0xFF));
}
/* ------------------------------------------------------------ */
private void addInt(int startIndex, int i)
{
_buffer.poke(startIndex,(byte)((i >> 8) & 0xFF));
_buffer.poke((startIndex + 1),(byte)(i & 0xFF));
}
/* ------------------------------------------------------------ */
private void addString(String str) throws UnsupportedEncodingException
{
if (str == null)
{
addInt(0xFFFF);
return;
}
// TODO - need to use a writer to convert, to avoid this hacky
// conversion and temp buffer
byte[] b = str.getBytes(StringUtil.__ISO_8859_1);
addInt(b.length);
_buffer.put(b);
_buffer.put((byte)0);
}
/* ------------------------------------------------------------ */
private void addBuffer(Buffer b)
{
if (b == null)
{
addInt(0xFFFF);
return;
}
addInt(b.length());
_buffer.put(b);
_buffer.put((byte)0);
}
/* ------------------------------------------------------------ */
public void getBodyChunk() throws IOException
{
ByteArrayBuffer bf = new ByteArrayBuffer(AJP13_MORE_CONTENT);
_endp.flush(bf);
}
/* ------------------------------------------------------------ */
public void gotBody()
{
_needMore = false;
_expectMore = false;
}
/* ------------------------------------------------------------ */
public void sendCPong() throws IOException
{
Buffer buff = _buffers.getBuffer();
buff.put(AJP13_CPONG_RESPONSE);
// flushing cpong response
do
{
_endp.flush(buff);
}
while (buff.length() > 0);
_buffers.returnBuffer(buff);
reset();
}
}

View File

@ -1,68 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.io.BufferCache;
/**
*
*/
public class Ajp13Packet
{
public final static int MAX_PACKET_SIZE=(8*1024);
public final static int HDR_SIZE=4;
// Used in writing response...
public final static int DATA_HDR_SIZE=7;
public final static int MAX_DATA_SIZE=MAX_PACKET_SIZE-DATA_HDR_SIZE;
public final static String
// Server -> Container
FORWARD_REQUEST="FORWARD REQUEST",
SHUTDOWN="SHUTDOWN",
PING_REQUEST="PING REQUEST", // Obsolete
CPING_REQUEST="CPING REQUEST",
// Server <- Container
SEND_BODY_CHUNK="SEND BODY CHUNK", SEND_HEADERS="SEND HEADERS", END_RESPONSE="END RESPONSE",
GET_BODY_CHUNK="GET BODY CHUNK",
CPONG_REPLY="CPONG REPLY";
public final static int FORWARD_REQUEST_ORDINAL=2, SHUTDOWN_ORDINAL=7,
PING_REQUEST_ORDINAL=8, // Obsolete
CPING_REQUEST_ORDINAL=10, SEND_BODY_CHUNK_ORDINAL=3, SEND_HEADERS_ORDINAL=4, END_RESPONSE_ORDINAL=5, GET_BODY_CHUNK_ORDINAL=6,
CPONG_REPLY_ORDINAL=9;
public final static BufferCache CACHE=new BufferCache();
static
{
CACHE.add(FORWARD_REQUEST,FORWARD_REQUEST_ORDINAL);
CACHE.add(SHUTDOWN,SHUTDOWN_ORDINAL);
CACHE.add(PING_REQUEST,PING_REQUEST_ORDINAL); // Obsolete
CACHE.add(CPING_REQUEST,CPING_REQUEST_ORDINAL);
CACHE.add(SEND_BODY_CHUNK,SEND_BODY_CHUNK_ORDINAL);
CACHE.add(SEND_HEADERS,SEND_HEADERS_ORDINAL);
CACHE.add(END_RESPONSE,END_RESPONSE_ORDINAL);
CACHE.add(GET_BODY_CHUNK,GET_BODY_CHUNK_ORDINAL);
CACHE.add(CPONG_REPLY,CPONG_REPLY_ORDINAL);
}
}

View File

@ -1,74 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
/**
*
*/
public class Ajp13PacketMethods
{
// TODO - this can probably be replaced by HttpMethods or at least an
// extension of it.
// It is probably most efficient if "GET" ends up as the same instance
public final static String OPTIONS="OPTIONS", GET="GET", HEAD="HEAD", POST="POST", PUT="PUT", DELETE="DELETE", TRACE="TRACE", PROPFIND="PROPFIND",
PROPPATCH="PROPPATCH", MKCOL="MKCOL", COPY="COPY", MOVE="MOVE", LOCK="LOCK", UNLOCK="UNLOCK", ACL="ACL", REPORT="REPORT",
VERSION_CONTROL="VERSION-CONTROL", CHECKIN="CHECKIN", CHECKOUT="CHECKOUT", UNCHCKOUT="UNCHECKOUT", SEARCH="SEARCH", MKWORKSPACE="MKWORKSPACE",
UPDATE="UPDATE", LABEL="LABEL", MERGE="MERGE", BASELINE_CONTROL="BASELINE-CONTROL", MKACTIVITY="MKACTIVITY";
public final static int OPTIONS_ORDINAL=1, GET_ORDINAL=2, HEAD_ORDINAL=3, POST__ORDINAL=4, PUT_ORDINAL=5, DELETE_ORDINAL=6, TRACE_ORDINAL=7,
PROPFIND_ORDINAL=8, PROPPATCH_ORDINAL=9, MKCOL_ORDINAL=10, COPY_ORDINAL=11, MOVE_ORDINAL=12, LOCK_ORDINAL=13, UNLOCK_ORDINAL=14, ACL_ORDINAL=15,
REPORT_ORDINAL=16, VERSION_CONTROL_ORDINAL=17, CHECKIN_ORDINAL=18, CHECKOUT_ORDINAL=19, UNCHCKOUT_ORDINAL=20, SEARCH_ORDINAL=21,
MKWORKSPACE_ORDINAL=22, UPDATE_ORDINAL=23, LABEL_ORDINAL=24, MERGE_ORDINAL=25, BASELINE_CONTROL_ORDINAL=26, MKACTIVITY_ORDINAL=27;
public final static BufferCache CACHE=new BufferCache();
public final static Buffer
OPTIONS_BUFFER=CACHE.add(OPTIONS,OPTIONS_ORDINAL),
GET_BUFFER=CACHE.add(GET,GET_ORDINAL),
HEAD_BUFFER=CACHE.add(HEAD, HEAD_ORDINAL),
POST__BUFFER=CACHE.add(POST,POST__ORDINAL),
PUT_BUFFER=CACHE.add(PUT,PUT_ORDINAL),
DELETE_BUFFER=CACHE.add(DELETE,DELETE_ORDINAL),
TRACE_BUFFER=CACHE.add(TRACE,TRACE_ORDINAL),
PROPFIND_BUFFER=CACHE.add(PROPFIND,PROPFIND_ORDINAL),
PROPPATCH_BUFFER=CACHE.add(PROPPATCH, PROPPATCH_ORDINAL),
MKCOL_BUFFER=CACHE.add(MKCOL,MKCOL_ORDINAL),
COPY_BUFFER=CACHE.add(COPY,COPY_ORDINAL),
MOVE_BUFFER=CACHE.add(MOVE,MOVE_ORDINAL),
LOCK_BUFFER=CACHE.add(LOCK,LOCK_ORDINAL),
UNLOCK_BUFFER=CACHE.add(UNLOCK,UNLOCK_ORDINAL),
ACL_BUFFER=CACHE.add(ACL,ACL_ORDINAL),
REPORT_BUFFER=CACHE.add(REPORT,REPORT_ORDINAL),
VERSION_CONTROL_BUFFER=CACHE.add(VERSION_CONTROL,VERSION_CONTROL_ORDINAL),
CHECKIN_BUFFER=CACHE.add(CHECKIN,CHECKIN_ORDINAL),
CHECKOUT_BUFFER=CACHE.add(CHECKOUT,CHECKOUT_ORDINAL),
UNCHCKOUT_BUFFER=CACHE.add(UNCHCKOUT,UNCHCKOUT_ORDINAL),
SEARCH_BUFFER=CACHE.add(SEARCH,SEARCH_ORDINAL),
MKWORKSPACE_BUFFER=CACHE.add(MKWORKSPACE,MKWORKSPACE_ORDINAL),
UPDATE_BUFFER=CACHE.add(UPDATE,UPDATE_ORDINAL),
LABEL_BUFFER=CACHE.add(LABEL,LABEL_ORDINAL),
MERGE_BUFFER=CACHE.add(MERGE,MERGE_ORDINAL),
BASELINE_CONTROL_BUFFER=CACHE.add(BASELINE_CONTROL,BASELINE_CONTROL_ORDINAL),
MKACTIVITY_BUFFER=CACHE.add(MKACTIVITY,MKACTIVITY_ORDINAL);
}

View File

@ -1,890 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import java.io.IOException;
import java.io.InterruptedIOException;
import javax.servlet.ServletInputStream;
import org.eclipse.jetty.http.HttpTokens;
import org.eclipse.jetty.http.Parser;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferUtil;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
*
*/
public class Ajp13Parser implements Parser
{
private static final Logger LOG = Log.getLogger(Ajp13Parser.class);
private final static int STATE_START = -1;
private final static int STATE_END = 0;
private final static int STATE_AJP13CHUNK_START = 1;
private final static int STATE_AJP13CHUNK = 2;
private int _state = STATE_START;
private long _contentLength;
private long _contentPosition;
private int _chunkLength;
private int _chunkPosition;
private int _headers;
private Buffers _buffers;
private EndPoint _endp;
private Buffer _buffer;
private Buffer _header; // Buffer for header data (and small _content)
private Buffer _body; // Buffer for large content
private View _contentView = new View();
private EventHandler _handler;
private Ajp13Generator _generator;
private View _tok0; // Saved token: header name, request method or response version
private View _tok1; // Saved token: header value, request URI orresponse code
protected int _length;
protected int _packetLength;
/* ------------------------------------------------------------------------------- */
public Ajp13Parser(Buffers buffers, EndPoint endPoint)
{
_buffers = buffers;
_endp = endPoint;
}
/* ------------------------------------------------------------------------------- */
public void setEventHandler(EventHandler handler)
{
_handler=handler;
}
/* ------------------------------------------------------------------------------- */
public void setGenerator(Ajp13Generator generator)
{
_generator=generator;
}
/* ------------------------------------------------------------------------------- */
public long getContentLength()
{
return _contentLength;
}
/* ------------------------------------------------------------------------------- */
public int getState()
{
return _state;
}
/* ------------------------------------------------------------------------------- */
public boolean inContentState()
{
return _state > 0;
}
/* ------------------------------------------------------------------------------- */
public boolean inHeaderState()
{
return _state < 0;
}
/* ------------------------------------------------------------------------------- */
public boolean isIdle()
{
return _state == STATE_START;
}
/* ------------------------------------------------------------------------------- */
public boolean isComplete()
{
return _state == STATE_END;
}
/* ------------------------------------------------------------------------------- */
public boolean isMoreInBuffer()
{
if (_header != null && _header.hasContent() || _body != null && _body.hasContent())
return true;
return false;
}
/* ------------------------------------------------------------------------------- */
public boolean isState(int state)
{
return _state == state;
}
/* ------------------------------------------------------------------------------- */
public void parse() throws IOException
{
if (_state == STATE_END)
reset();
if (_state != STATE_START)
throw new IllegalStateException("!START");
// continue parsing
while (!isComplete())
{
parseNext();
}
}
/* ------------------------------------------------------------------------------- */
public boolean parseAvailable() throws IOException
{
boolean progress=parseNext()>0;
// continue parsing
while (!isComplete() && _buffer!=null && _buffer.length()>0)
{
progress |= parseNext()>0;
}
return progress;
}
/* ------------------------------------------------------------------------------- */
private int fill() throws IOException
{
int filled = -1;
if (_body != null && _buffer != _body)
{
// mod_jk implementations may have some partial data from header
// check if there are partial contents in the header
// copy it to the body if there are any
if(_header.length() > 0)
{
// copy the patial data from the header to the body
_body.put(_header);
}
_buffer = _body;
if (_buffer.length()>0)
{
filled = _buffer.length();
return filled;
}
}
if (_buffer.markIndex() == 0 && _buffer.putIndex() == _buffer.capacity())
throw new IOException("FULL");
if (_endp != null && filled <= 0)
{
// Compress buffer if handling _content buffer
// TODO check this is not moving data too much
if (_buffer == _body)
_buffer.compact();
if (_buffer.space() == 0)
throw new IOException("FULL");
try
{
filled = _endp.fill(_buffer);
}
catch (IOException e)
{
// This is normal in AJP since the socket closes on timeout only
LOG.debug(e);
reset();
throw (e instanceof EofException) ? e : new EofException(e);
}
}
if (filled < 0)
{
if (_state > STATE_END)
{
_state = STATE_END;
_handler.messageComplete(_contentPosition);
return filled;
}
reset();
throw new EofException();
}
return filled;
}
volatile int _seq=0;
/* ------------------------------------------------------------------------------- */
public int parseNext() throws IOException
{
int total_filled = 0;
if (_buffer == null)
{
if (_header == null)
_header = _buffers.getHeader();
_buffer = _header;
_tok0 = new View(_header);
_tok1 = new View(_header);
_tok0.setPutIndex(_tok0.getIndex());
_tok1.setPutIndex(_tok1.getIndex());
}
if (_state == STATE_END)
throw new IllegalStateException("STATE_END");
if (_state > STATE_END && _contentPosition == _contentLength)
{
_state = STATE_END;
_handler.messageComplete(_contentPosition);
return 1;
}
if (_state < 0)
{
// have we seen a packet?
if (_packetLength<=0)
{
if (_buffer.length()<4)
{
if (total_filled<0)
total_filled=0;
total_filled+=fill();
if (_buffer.length()<4)
return total_filled;
}
_contentLength = HttpTokens.UNKNOWN_CONTENT;
int _magic = Ajp13RequestPacket.getInt(_buffer);
if (_magic != Ajp13RequestHeaders.MAGIC)
throw new IOException("Bad AJP13 rcv packet: " + "0x" + Integer.toHexString(_magic) + " expected " + "0x" + Integer.toHexString(Ajp13RequestHeaders.MAGIC) + " " + this);
_packetLength = Ajp13RequestPacket.getInt(_buffer);
if (_packetLength > Ajp13Packet.MAX_PACKET_SIZE)
throw new IOException("AJP13 packet (" + _packetLength + "bytes) too large for buffer");
}
if (_buffer.length() < _packetLength)
{
if (total_filled<0)
total_filled=0;
total_filled+=fill();
if (_buffer.length() < _packetLength)
return total_filled;
}
// Parse Header
Buffer bufHeaderName = null;
Buffer bufHeaderValue = null;
int attr_type = 0;
byte packetType = Ajp13RequestPacket.getByte(_buffer);
switch (packetType)
{
case Ajp13Packet.FORWARD_REQUEST_ORDINAL:
_handler.startForwardRequest();
break;
case Ajp13Packet.CPING_REQUEST_ORDINAL:
(_generator).sendCPong();
if(_header != null)
{
_buffers.returnBuffer(_header);
_header = null;
}
if(_body != null)
{
_buffers.returnBuffer(_body);
_body = null;
}
_buffer= null;
reset();
return -1;
case Ajp13Packet.SHUTDOWN_ORDINAL:
shutdownRequest();
return -1;
default:
// XXX Throw an Exception here?? Close
// connection!
LOG.warn("AJP13 message type ({PING}: "+packetType+" ) not supported/recognized as an AJP request");
throw new IllegalStateException("PING is not implemented");
}
_handler.parsedMethod(Ajp13RequestPacket.getMethod(_buffer));
_handler.parsedProtocol(Ajp13RequestPacket.getString(_buffer, _tok0));
_handler.parsedUri(Ajp13RequestPacket.getString(_buffer, _tok1));
_handler.parsedRemoteAddr(Ajp13RequestPacket.getString(_buffer, _tok1));
_handler.parsedRemoteHost(Ajp13RequestPacket.getString(_buffer, _tok1));
_handler.parsedServerName(Ajp13RequestPacket.getString(_buffer, _tok1));
_handler.parsedServerPort(Ajp13RequestPacket.getInt(_buffer));
_handler.parsedSslSecure(Ajp13RequestPacket.getBool(_buffer));
_headers = Ajp13RequestPacket.getInt(_buffer);
for (int h=0;h<_headers;h++)
{
bufHeaderName = Ajp13RequestPacket.getHeaderName(_buffer, _tok0);
bufHeaderValue = Ajp13RequestPacket.getString(_buffer, _tok1);
if (bufHeaderName != null && bufHeaderName.toString().equals(Ajp13RequestHeaders.CONTENT_LENGTH))
{
_contentLength = BufferUtil.toLong(bufHeaderValue);
if (_contentLength == 0)
_contentLength = HttpTokens.NO_CONTENT;
}
_handler.parsedHeader(bufHeaderName, bufHeaderValue);
}
attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
while (attr_type != 0xFF)
{
switch (attr_type)
{
// XXX How does this plug into the web
// containers
// authentication?
case Ajp13RequestHeaders.REMOTE_USER_ATTR:
_handler.parsedRemoteUser(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.AUTH_TYPE_ATTR:
//XXX JASPI how does this make sense?
_handler.parsedAuthorizationType(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.QUERY_STRING_ATTR:
_handler.parsedQueryString(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.JVM_ROUTE_ATTR:
// moved to Eclipse naming usage
// used in org.eclipse.jetty.servlet.HashSessionIdManager
_handler.parsedRequestAttribute("org.eclipse.jetty.ajp.JVMRoute", Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.SSL_CERT_ATTR:
_handler.parsedSslCert(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.SSL_CIPHER_ATTR:
_handler.parsedSslCipher(Ajp13RequestPacket.getString(_buffer, _tok1));
// SslSocketConnector.customize()
break;
case Ajp13RequestHeaders.SSL_SESSION_ATTR:
_handler.parsedSslSession(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.REQUEST_ATTR:
_handler.parsedRequestAttribute(Ajp13RequestPacket.getString(_buffer, _tok0).toString(), Ajp13RequestPacket.getString(_buffer, _tok1));
break;
// New Jk API?
// Check if experimental or can they
// assumed to be
// supported
case Ajp13RequestHeaders.SSL_KEYSIZE_ATTR:
// This has been implemented in AJP13 as either a string or a integer.
// Servlet specs say javax.servlet.request.key_size must be an Integer
// Does it look like a string containing digits?
int length = Ajp13RequestPacket.getInt(_buffer);
if (length>0 && length<16)
{
// this must be a string length rather than a key length
_buffer.skip(-2);
_handler.parsedSslKeySize(Integer.parseInt(Ajp13RequestPacket.getString(_buffer, _tok1).toString()));
}
else
_handler.parsedSslKeySize(length);
break;
// Used to lock down jk requests with a
// secreate
// key.
case Ajp13RequestHeaders.SECRET_ATTR:
// XXX Investigate safest way to
// deal with
// this...
// should this tie into shutdown
// packet?
break;
case Ajp13RequestHeaders.STORED_METHOD_ATTR:
// XXX Confirm this should
// really overide
// previously parsed method?
// _handler.parsedMethod(Ajp13PacketMethods.CACHE.get(Ajp13RequestPacket.getString()));
break;
case Ajp13RequestHeaders.CONTEXT_ATTR:
_handler.parsedContextPath(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
case Ajp13RequestHeaders.SERVLET_PATH_ATTR:
_handler.parsedServletPath(Ajp13RequestPacket.getString(_buffer, _tok1));
break;
default:
LOG.warn("Unsupported Ajp13 Request Attribute {}", new Integer(attr_type));
break;
}
attr_type = Ajp13RequestPacket.getByte(_buffer) & 0xff;
}
_contentPosition = 0;
switch ((int) _contentLength)
{
case HttpTokens.NO_CONTENT:
_state = STATE_END;
_handler.headerComplete();
_handler.messageComplete(_contentPosition);
break;
case HttpTokens.UNKNOWN_CONTENT:
_generator.getBodyChunk();
if (_buffers != null && _body == null && _buffer == _header && _header.length() <= 0)
{
_body = _buffers.getBuffer();
_body.clear();
}
_state = STATE_AJP13CHUNK_START;
_handler.headerComplete(); // May recurse here!
return total_filled;
default:
if (_buffers != null && _body == null && _buffer == _header && _contentLength > (_header.capacity() - _header.getIndex()))
{
_body = _buffers.getBuffer();
_body.clear();
}
_state = STATE_AJP13CHUNK_START;
_handler.headerComplete(); // May recurse here!
return total_filled;
}
}
Buffer chunk;
while (_state>STATE_END)
{
switch (_state)
{
case STATE_AJP13CHUNK_START:
if (_buffer.length()<6)
{
if (total_filled<0)
total_filled=0;
total_filled+=fill();
if (_buffer.length()<6)
return total_filled;
}
int _magic=Ajp13RequestPacket.getInt(_buffer);
if (_magic!=Ajp13RequestHeaders.MAGIC)
{
throw new IOException("Bad AJP13 rcv packet: "+"0x"+Integer.toHexString(_magic)+" expected "+"0x"
+Integer.toHexString(Ajp13RequestHeaders.MAGIC)+" "+this);
}
_chunkPosition=0;
_chunkLength=Ajp13RequestPacket.getInt(_buffer)-2;
Ajp13RequestPacket.getInt(_buffer);
if (_chunkLength==0)
{
_state=STATE_END;
_generator.gotBody();
_handler.messageComplete(_contentPosition);
return total_filled;
}
_state=STATE_AJP13CHUNK;
break;
case STATE_AJP13CHUNK:
if (_buffer.length()<_chunkLength)
{
if (total_filled<0)
total_filled=0;
total_filled+=fill();
if (_buffer.length()<_chunkLength)
return total_filled;
}
int remaining=_chunkLength-_chunkPosition;
if (remaining==0)
{
_state=STATE_AJP13CHUNK_START;
if (_contentPosition<_contentLength)
{
_generator.getBodyChunk();
}
else
{
_generator.gotBody();
}
return total_filled;
}
if (_buffer.length()<remaining)
{
remaining=_buffer.length();
}
chunk=Ajp13RequestPacket.get(_buffer,remaining);
_contentPosition+=chunk.length();
_chunkPosition+=chunk.length();
_contentView.update(chunk);
remaining=_chunkLength-_chunkPosition;
if (remaining==0)
{
_state=STATE_AJP13CHUNK_START;
if (_contentPosition<_contentLength || _contentLength == HttpTokens.UNKNOWN_CONTENT)
{
_generator.getBodyChunk();
}
else
{
_generator.gotBody();
}
}
_handler.content(chunk);
return total_filled;
default:
throw new IllegalStateException("Invalid Content State");
}
}
return total_filled;
}
/* ------------------------------------------------------------------------------- */
public void reset()
{
_state = STATE_START;
_contentLength = HttpTokens.UNKNOWN_CONTENT;
_contentPosition = 0;
_length = 0;
_packetLength = 0;
if (_body!=null && _body.hasContent())
{
// There is content in the body after the end of the request.
// This is probably a pipelined header of the next request, so we need to
// copy it to the header buffer.
if (_header==null)
{
_header=_buffers.getHeader();
_tok0.update(_header);
_tok0.update(0,0);
_tok1.update(_header);
_tok1.update(0,0);
}
else
{
_header.setMarkIndex(-1);
_header.compact();
}
int take=_header.space();
if (take>_body.length())
take=_body.length();
_body.peek(_body.getIndex(),take);
_body.skip(_header.put(_body.peek(_body.getIndex(),take)));
}
if (_header!=null)
_header.setMarkIndex(-1);
if (_body!=null)
_body.setMarkIndex(-1);
_buffer=_header;
}
/* ------------------------------------------------------------------------------- */
public void returnBuffers()
{
if (_body!=null && !_body.hasContent() && _body.markIndex()==-1)
{
if (_buffer==_body)
_buffer=_header;
if (_buffers!=null)
_buffers.returnBuffer(_body);
_body=null;
}
if (_header!=null && !_header.hasContent() && _header.markIndex()==-1)
{
if (_buffer==_header)
_buffer=null;
_buffers.returnBuffer(_header);
_header=null;
}
}
/* ------------------------------------------------------------------------------- */
Buffer getHeaderBuffer()
{
return _buffer;
}
private void shutdownRequest()
{
_state = STATE_END;
if(!Ajp13SocketConnector.__allowShutdown)
{
LOG.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
return;
}
if(Ajp13SocketConnector.__secretWord != null)
{
LOG.warn("AJP13: Validating Secret Word");
try
{
String secretWord = Ajp13RequestPacket.getString(_buffer, _tok1).toString();
if(!Ajp13SocketConnector.__secretWord.equals(secretWord))
{
LOG.warn("AJP13: Shutdown Request Denied, Invalid Sercret word!!!");
throw new IllegalStateException("AJP13: Secret Word is Invalid: Peer has requested shutdown but, Secret Word did not match");
}
}
catch (Exception e)
{
LOG.warn("AJP13: Secret Word is Required!!!");
LOG.debug(e);
throw new IllegalStateException("AJP13: Secret Word is Required: Peer has requested shutdown but, has not provided a Secret Word");
}
LOG.warn("AJP13: Shutdown Request is Denied, allowShutdown is set to false!!!");
return;
}
LOG.warn("AJP13: Peer Has Requested for Shutdown!!!");
LOG.warn("AJP13: Jetty 6 is shutting down !!!");
System.exit(0);
}
/* ------------------------------------------------------------------------------- */
public interface EventHandler
{
// public void shutdownRequest() throws IOException;
// public void cpingRequest() throws IOException;
public void content(Buffer ref) throws IOException;
public void headerComplete() throws IOException;
public void messageComplete(long contextLength) throws IOException;
public void parsedHeader(Buffer name, Buffer value) throws IOException;
public void parsedMethod(Buffer method) throws IOException;
public void parsedProtocol(Buffer protocol) throws IOException;
public void parsedQueryString(Buffer value) throws IOException;
public void parsedRemoteAddr(Buffer addr) throws IOException;
public void parsedRemoteHost(Buffer host) throws IOException;
public void parsedRequestAttribute(String key, Buffer value) throws IOException;
public void parsedRequestAttribute(String key, int value) throws IOException;
public void parsedServerName(Buffer name) throws IOException;
public void parsedServerPort(int port) throws IOException;
public void parsedSslSecure(boolean secure) throws IOException;
public void parsedUri(Buffer uri) throws IOException;
public void startForwardRequest() throws IOException;
public void parsedAuthorizationType(Buffer authType) throws IOException;
public void parsedRemoteUser(Buffer remoteUser) throws IOException;
public void parsedServletPath(Buffer servletPath) throws IOException;
public void parsedContextPath(Buffer context) throws IOException;
public void parsedSslCert(Buffer sslCert) throws IOException;
public void parsedSslCipher(Buffer sslCipher) throws IOException;
public void parsedSslSession(Buffer sslSession) throws IOException;
public void parsedSslKeySize(int keySize) throws IOException;
}
/* ------------------------------------------------------------ */
/**
* TODO Make this common with HttpParser
*
*/
public static class Input extends ServletInputStream
{
private Ajp13Parser _parser;
private EndPoint _endp;
private long _maxIdleTime;
private View _content;
/* ------------------------------------------------------------ */
public Input(Ajp13Parser parser, long maxIdleTime)
{
_parser = parser;
_endp = parser._endp;
_maxIdleTime = maxIdleTime;
_content = _parser._contentView;
}
/* ------------------------------------------------------------ */
@Override
public int read() throws IOException
{
int c = -1;
if (blockForContent())
c = 0xff & _content.get();
return c;
}
/* ------------------------------------------------------------ */
/*
* @see java.io.InputStream#read(byte[], int, int)
*/
@Override
public int read(byte[] b, int off, int len) throws IOException
{
int l = -1;
if (blockForContent())
l = _content.get(b, off, len);
return l;
}
/* ------------------------------------------------------------ */
private boolean blockForContent() throws IOException
{
if (_content.length() > 0)
return true;
if (_parser.isState(Ajp13Parser.STATE_END) || _parser.isState(Ajp13Parser.STATE_START))
return false;
// Handle simple end points.
if (_endp == null)
_parser.parseNext();
// Handle blocking end points
else if (_endp.isBlocking())
{
_parser.parseNext();
// parse until some progress is made (or IOException thrown for timeout)
while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
{
// Try to get more _parser._content
_parser.parseNext();
}
}
else // Handle non-blocking end point
{
long filled = _parser.parseNext();
boolean blocked = false;
// parse until some progress is made (or
// IOException thrown for timeout)
while (_content.length() == 0 && !_parser.isState(Ajp13Parser.STATE_END))
{
// if fill called, but no bytes read,
// then block
if (filled > 0)
blocked = false;
else if (filled == 0)
{
if (blocked)
throw new InterruptedIOException("timeout");
blocked = true;
_endp.blockReadable(_maxIdleTime);
}
// Try to get more _parser._content
filled = _parser.parseNext();
}
}
return _content.length() > 0;
}
}
public boolean isPersistent()
{
return true;
}
public void setPersistent(boolean persistent)
{
LOG.warn("AJP13.setPersistent is not IMPLEMENTED!");
}
}

View File

@ -1,124 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
public class Ajp13Request extends Request
{
protected String _remoteAddr;
protected String _remoteHost;
protected String _remoteUser;
protected boolean _sslSecure;
/* ------------------------------------------------------------ */
public Ajp13Request(AbstractHttpConnection connection)
{
super(connection);
}
/* ------------------------------------------------------------ */
public Ajp13Request()
{
}
/* ------------------------------------------------------------ */
void setConnection(Ajp13Connection connection)
{
super.setConnection(connection);
}
/* ------------------------------------------------------------ */
public void setRemoteUser(String remoteUser)
{
_remoteUser = remoteUser;
}
/* ------------------------------------------------------------ */
@Override
public String getRemoteUser()
{
if(_remoteUser != null)
return _remoteUser;
return super.getRemoteUser();
}
/* ------------------------------------------------------------ */
@Override
public String getRemoteAddr()
{
if (_remoteAddr != null)
return _remoteAddr;
if (_remoteHost != null)
return _remoteHost;
return super.getRemoteAddr();
}
/* ------------------------------------------------------------ */
@Override
public void setRemoteAddr(String remoteAddr)
{
_remoteAddr = remoteAddr;
}
/* ------------------------------------------------------------ */
@Override
public String getRemoteHost()
{
if (_remoteHost != null)
return _remoteHost;
if (_remoteAddr != null)
return _remoteAddr;
return super.getRemoteHost();
}
/* ------------------------------------------------------------ */
@Override
public void setRemoteHost(String remoteHost)
{
_remoteHost = remoteHost;
}
/* ------------------------------------------------------------ */
public boolean isSslSecure()
{
return _sslSecure;
}
/* ------------------------------------------------------------ */
public void setSslSecure(boolean sslSecure)
{
_sslSecure = sslSecure;
}
/* ------------------------------------------------------------ */
@Override
protected void recycle()
{
super.recycle();
_remoteAddr = null;
_remoteHost = null;
_remoteUser = null;
_sslSecure = false;
}
}

View File

@ -1,67 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
/**
* XXX Should this implement the Buffer interface?
*
*
*/
public class Ajp13RequestHeaders extends BufferCache
{
public final static int MAGIC=0x1234;
public final static String ACCEPT="accept", ACCEPT_CHARSET="accept-charset", ACCEPT_ENCODING="accept-encoding", ACCEPT_LANGUAGE="accept-language",
AUTHORIZATION="authorization", CONNECTION="connection", CONTENT_TYPE="content-type", CONTENT_LENGTH="content-length", COOKIE="cookie",
COOKIE2="cookie2", HOST="host", PRAGMA="pragma", REFERER="referer", USER_AGENT="user-agent";
public final static int ACCEPT_ORDINAL=1, ACCEPT_CHARSET_ORDINAL=2, ACCEPT_ENCODING_ORDINAL=3, ACCEPT_LANGUAGE_ORDINAL=4, AUTHORIZATION_ORDINAL=5,
CONNECTION_ORDINAL=6, CONTENT_TYPE_ORDINAL=7, CONTENT_LENGTH_ORDINAL=8, COOKIE_ORDINAL=9, COOKIE2_ORDINAL=10, HOST_ORDINAL=11, PRAGMA_ORDINAL=12,
REFERER_ORDINAL=13, USER_AGENT_ORDINAL=14;
public final static BufferCache CACHE=new BufferCache();
public final static Buffer ACCEPT_BUFFER=CACHE.add(ACCEPT,ACCEPT_ORDINAL), ACCEPT_CHARSET_BUFFER=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL),
ACCEPT_ENCODING_BUFFER=CACHE.add(ACCEPT_ENCODING,ACCEPT_ENCODING_ORDINAL), ACCEPT_LANGUAGE_BUFFER=CACHE
.add(ACCEPT_LANGUAGE,ACCEPT_LANGUAGE_ORDINAL), AUTHORIZATION_BUFFER=CACHE.add(AUTHORIZATION,AUTHORIZATION_ORDINAL), CONNECTION_BUFFER=CACHE
.add(CONNECTION,CONNECTION_ORDINAL), CONTENT_TYPE_BUFFER=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL), CONTENT_LENGTH_BUFFER=CACHE.add(
CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL), COOKIE_BUFFER=CACHE.add(COOKIE,COOKIE_ORDINAL), COOKIE2_BUFFER=CACHE.add(COOKIE2,COOKIE2_ORDINAL),
HOST_BUFFER=CACHE.add(HOST,HOST_ORDINAL), PRAGMA_BUFFER=CACHE.add(PRAGMA,PRAGMA_ORDINAL), REFERER_BUFFER=CACHE.add(REFERER,REFERER_ORDINAL),
USER_AGENT_BUFFER=CACHE.add(USER_AGENT,USER_AGENT_ORDINAL);
public final static byte
CONTEXT_ATTR=1, // Legacy
SERVLET_PATH_ATTR=2, // Legacy
REMOTE_USER_ATTR=3,
AUTH_TYPE_ATTR=4,
QUERY_STRING_ATTR=5,
JVM_ROUTE_ATTR=6,
SSL_CERT_ATTR=7,
SSL_CIPHER_ATTR=8,
SSL_SESSION_ATTR=9,
REQUEST_ATTR=10,
SSL_KEYSIZE_ATTR=11,
SECRET_ATTR=12,
STORED_METHOD_ATTR=13;
}

View File

@ -1,90 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.View;
/**
*
*
*
*/
public class Ajp13RequestPacket
{
public static boolean isEmpty(Buffer _buffer)
{
return _buffer.length()==0;
}
public static int getInt(Buffer _buffer)
{
return ((_buffer.get()&0xFF)<<8)|(_buffer.get()&0xFF);
}
public static Buffer getString(Buffer _buffer, View tok)
{
int len=((_buffer.peek()&0xFF)<<8)|(_buffer.peek(_buffer.getIndex()+1)&0xFF);
if (len==0xffff)
{
_buffer.skip(2);
return null;
}
int start=_buffer.getIndex();
tok.update(start+2,start+len+2);
_buffer.skip(len+3);
return tok;
}
public static byte getByte(Buffer _buffer)
{
return _buffer.get();
}
public static boolean getBool(Buffer _buffer)
{
return _buffer.get()>0;
}
public static Buffer getMethod(Buffer _buffer)
{
return Ajp13PacketMethods.CACHE.get(_buffer.get());
}
public static Buffer getHeaderName(Buffer _buffer, View tok)
{
int len=((_buffer.peek()&0xFF)<<8)|(_buffer.peek(_buffer.getIndex()+1)&0xFF);
if ((0xFF00&len)==0xA000)
{
_buffer.skip(1);
return Ajp13RequestHeaders.CACHE.get(_buffer.get());
}
int start=_buffer.getIndex();
tok.update(start+2,start+len+2);
_buffer.skip(len+3);
return tok;
}
public static Buffer get(Buffer buffer, int length)
{
return buffer.get(length);
}
}

View File

@ -1,48 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.BufferCache;
/**
*
*/
public class Ajp13ResponseHeaders extends BufferCache
{
public final static int MAGIC=0xab00;
public final static String CONTENT_TYPE="Content-Type", CONTENT_LANGUAGE="Content-Language", CONTENT_LENGTH="Content-Length", DATE="Date",
LAST_MODIFIED="Last-Modified", LOCATION="Location", SET_COOKIE="Set-Cookie", SET_COOKIE2="Set-Cookie2", SERVLET_ENGINE="Servlet-Engine",
STATUS="Status", WWW_AUTHENTICATE="WWW-Authenticate";
public final static int CONTENT_TYPE_ORDINAL=1, CONTENT_LANGUAGE_ORDINAL=2, CONTENT_LENGTH_ORDINAL=3, DATE_ORDINAL=4, LAST_MODIFIED_ORDINAL=5,
LOCATION_ORDINAL=6, SET_COOKIE_ORDINAL=7, SET_COOKIE2_ORDINAL=8, SERVLET_ENGINE_ORDINAL=9, STATUS_ORDINAL=10, WWW_AUTHENTICATE_ORDINAL=11;
public final static BufferCache CACHE=new BufferCache();
public final static Buffer CONTENT_TYPE_BUFFER=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL), CONTENT_LANGUAGE_BUFFER=CACHE.add(CONTENT_LANGUAGE,
CONTENT_LANGUAGE_ORDINAL), CONTENT_LENGTH_BUFFER=CACHE.add(CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL), DATE_BUFFER=CACHE.add(DATE,DATE_ORDINAL),
LAST_MODIFIED_BUFFER=CACHE.add(LAST_MODIFIED,LAST_MODIFIED_ORDINAL), LOCATION_BUFFER=CACHE.add(LOCATION,LOCATION_ORDINAL), SET_COOKIE_BUFFER=CACHE
.add(SET_COOKIE,SET_COOKIE_ORDINAL), SET_COOKIE2_BUFFER=CACHE.add(SET_COOKIE2,SET_COOKIE2_ORDINAL), SERVLET_ENGINE_BUFFER=CACHE.add(
SERVLET_ENGINE,SERVLET_ENGINE_ORDINAL), STATUS_BUFFER=CACHE.add(STATUS,STATUS_ORDINAL), WWW_AUTHENTICATE_BUFFER=CACHE.add(WWW_AUTHENTICATE,
WWW_AUTHENTICATE_ORDINAL);
}

View File

@ -1,132 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import java.io.IOException;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
*
*
*
*/
public class Ajp13SocketConnector extends SocketConnector
{
private static final Logger LOG = Log.getLogger(Ajp13SocketConnector.class);
static String __secretWord = null;
static boolean __allowShutdown = false;
public Ajp13SocketConnector()
{
super.setRequestHeaderSize(Ajp13Packet.MAX_PACKET_SIZE);
super.setResponseHeaderSize(Ajp13Packet.MAX_PACKET_SIZE);
super.setRequestBufferSize(Ajp13Packet.MAX_PACKET_SIZE);
super.setResponseBufferSize(Ajp13Packet.MAX_PACKET_SIZE);
// IN AJP protocol the socket stay open, so
// by default the time out is set to 0 seconds
super.setMaxIdleTime(0);
}
@Override
protected void doStart() throws Exception
{
super.doStart();
LOG.info("AJP13 is not a secure protocol. Please protect port {}",Integer.toString(getLocalPort()));
}
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see org.eclipse.jetty.server.bio.SocketConnector#customize(org.eclipse.io.EndPoint, org.eclipse.jetty.server.Request)
*/
@Override
public void customize(EndPoint endpoint, Request request) throws IOException
{
super.customize(endpoint,request);
if (request.isSecure())
request.setScheme(HttpSchemes.HTTPS);
}
/* ------------------------------------------------------------ */
@Override
protected Connection newConnection(EndPoint endpoint)
{
return new Ajp13Connection(this,endpoint,getServer());
}
/* ------------------------------------------------------------ */
// Secured on a packet by packet bases not by connection
@Override
public boolean isConfidential(Request request)
{
return ((Ajp13Request) request).isSslSecure();
}
/* ------------------------------------------------------------ */
// Secured on a packet by packet bases not by connection
@Override
public boolean isIntegral(Request request)
{
return ((Ajp13Request) request).isSslSecure();
}
/* ------------------------------------------------------------ */
@Deprecated
public void setHeaderBufferSize(int headerBufferSize)
{
LOG.debug(Log.IGNORED);
}
/* ------------------------------------------------------------ */
@Override
public void setRequestBufferSize(int requestBufferSize)
{
LOG.debug(Log.IGNORED);
}
/* ------------------------------------------------------------ */
@Override
public void setResponseBufferSize(int responseBufferSize)
{
LOG.debug(Log.IGNORED);
}
/* ------------------------------------------------------------ */
public void setAllowShutdown(boolean allowShutdown)
{
LOG.warn("AJP13: Shutdown Request is: " + allowShutdown);
__allowShutdown = allowShutdown;
}
/* ------------------------------------------------------------ */
public void setSecretWord(String secretWord)
{
LOG.warn("AJP13: Shutdown Request secret word is : " + secretWord);
__secretWord = secretWord;
}
}

View File

@ -1,331 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class Ajp13ConnectionTest
{
private static final Logger LOG = Log.getLogger(Ajp13ConnectionTest.class);
private static Server _server;
private static Ajp13SocketConnector _connector;
private Socket _client;
@BeforeClass
public static void startServer() throws Exception
{
_server=new Server();
_connector=new Ajp13SocketConnector();
_connector.setPort(0);
_server.setConnectors(new Connector[] { _connector });
_server.setHandler(new Handler());
_server.start();
}
@AfterClass
public static void stopServer() throws Exception
{
_connector.close();
_server.stop();
}
@Before
public void openSocket() throws Exception
{
_client=new Socket("localhost",_connector.getLocalPort());
_client.setSoTimeout(500);
}
@After
public void closeSocket() throws Exception
{
_client.close();
}
@Test
public void testPacket1() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="123401070202000f77696474683d20485454502f312e300000122f636f6e74726f6c2f70726f647563742f2200000e3230382e32372e3230332e31323800ffff000c7777772e756c74612e636f6d000050000005a006000a6b6565702d616c69766500a00b000c7777772e756c74612e636f6d00a00e002b4d6f7a696c6c612f342e302028636f6d70617469626c653b20426f726465724d616e6167657220332e302900a0010043696d6167652f6769662c20696d6167652f782d786269746d61702c20696d6167652f6a7065672c20696d6167652f706a7065672c20696d6167652f706d672c202a2f2a00a008000130000600067570726f64310008000a4145533235362d53484100ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
readResponse(_client);
assertTrue(true);
}
@Test
public void testPacket2() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="1234020102020008485454502f312e3100000f2f6363632d7777777777772f61616100000c38382e3838382e38382e383830ffff00116363632e6363636363636363632e636f6d0001bb010009a00b00116363632e6363636363636363632e636f6d00a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004039324643303544413043444141443232303137413743443141453939353132413330443938363838423843433041454643364231363035323543433232353341000b0100ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
readResponse(_client);
assertTrue(true);
}
@Test
public void testPacket3() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="1234028f02020008485454502f312e3100000d2f666f726d746573742e6a737000000d3139322e3136382e342e31383000ffff00107777772e777265636b6167652e6f726700005000000aa0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a00200075554462d382c2a00a003000c677a69702c6465666c61746500a004000e656e2d67622c656e3b713d302e3500a006000a6b6565702d616c69766500a00900f95048505345535349443d37626361383232616638333466316465373663633630336366636435313938633b20667041757468436f6f6b69653d433035383430394537393344364245434633324230353234344242303039343230383344443645443533304230454637464137414544413745453231313538333745363033454435364332364446353531383635333335423433374531423637414641343533364345304546323342333642323133374243423932333943363631433131443330393842333938414546334546334146454344423746353842443b204a53455353494f4e49443d7365366331623864663432762e6a657474793300a00b00107777772e777265636b6167652e6f726700000a6b6565702d616c69766500000333303000a00e00654d6f7a696c6c612f352e3020285831313b20553b204c696e7578207838365f36343b20656e2d55533b2072763a312e382e302e3929204765636b6f2f3230303631323035202844656269616e2d312e382e302e392d3129204570697068616e792f322e313400a008000130000600066a657474793300ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
readResponse(_client);
assertTrue(true);
}
@Test
public void testSSLPacketWithIntegerKeySize() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b0100ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
readResponse(_client);
assertTrue(true);
}
@Test
public void testSSLPacketWithStringKeySize() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b000332353600ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
readResponse(_client);
assertTrue(true);
}
@Test
public void testPacketWithBody() throws Exception
{
OutputStream os=_client.getOutputStream();
os.write(TypeUtil.fromHexString(getTestHeader()));
os.write(TypeUtil.fromHexString(getTestShortBody()));
os.write(TypeUtil.fromHexString(getTestTinyBody()));
readResponse(_client);
assertTrue(true);
}
@Test
public void testPacketWithChunkedBody() throws Exception
{
OutputStream os=_client.getOutputStream();
String packet="123400ff02040008485454502f312e3100000f2f746573742f64756d702f696e666f0000093132372e302e302e3100ffff00096c6f63616c686f7374000050000007a00e000d4a6176612f312e352e305f313100a00b00096c6f63616c686f737400a0010034746578742f68746d6c2c20696d6167652f6769662c20696d6167652f6a7065672c202a3b20713d2e322c202a2f2a3b20713d2e3200a006000a6b6565702d616c69766500a00700216170706c69636174696f6e2f782d7777772d666f726d2d75726c656e636f6465640000115472616e736665722d456e636f64696e670000076368756e6b656400000c4d61782d466f727761726473000002313000ff";
os.write(TypeUtil.fromHexString(packet));
os.flush();
os.write(TypeUtil.fromHexString("1234007e007c7468656e616d653d746865253230717569636b25323062726f776e253230666f782532306a756d70732532306f766572253230746f2532307468652532306c617a79253230646f67253230544845253230515549434b25323042524f574e253230464f582532304a554d50532532304f564552253230544f25323054"));
os.flush();
os.write(TypeUtil.fromHexString("12340042004048452532304c415a59253230444f472532302676616c75656f66323d6162636465666768696a6b6c6d6e6f707172737475767778797a31323334353637383930"));
os.flush();
os.write(TypeUtil.fromHexString("123400020000"));
os.flush();
readResponse(_client);
assertTrue(true);
}
private String getTestHeader()
{
StringBuffer header=new StringBuffer("");
header.append("1234026902040008485454502f31");
header.append("2e310000162f61646d696e2f496d6167");
header.append("6555706c6f61642e68746d00000a3130");
header.append("2e34382e31302e3100ffff000a31302e");
header.append("34382e31302e3200005000000da00b00");
header.append("0a31302e34382e31302e3200a00e005a");
header.append("4d6f7a696c6c612f352e30202857696e");
header.append("646f77733b20553b2057696e646f7773");
header.append("204e5420352e313b20656e2d55533b20");
header.append("72763a312e382e312e3129204765636b");
header.append("6f2f3230303631323034204669726566");
header.append("6f782f322e302e302e3100a001006374");
header.append("6578742f786d6c2c6170706c69636174");
header.append("696f6e2f786d6c2c6170706c69636174");
header.append("696f6e2f7868746d6c2b786d6c2c7465");
header.append("78742f68746d6c3b713d302e392c7465");
header.append("78742f706c61696e3b713d302e382c69");
header.append("6d6167652f706e672c2a2f2a3b713d30");
header.append("2e3500a004000e656e2d75732c656e3b");
header.append("713d302e3500a003000c677a69702c64");
header.append("65666c61746500a002001e49534f2d38");
header.append("3835392d312c7574662d383b713d302e");
header.append("372c2a3b713d302e3700000a4b656570");
header.append("2d416c69766500000333303000a00600");
header.append("0a6b6565702d616c69766500a00d003f");
header.append("687474703a2f2f31302e34382e31302e");
header.append("322f61646d696e2f496d61676555706c");
header.append("6f61642e68746d3f6964303d4974656d");
header.append("266964313d32266964323d696d673200");
header.append("a00900174a53455353494f4e49443d75");
header.append("383977733070696168746d00a0070046");
header.append("6d756c7469706172742f666f726d2d64");
header.append("6174613b20626f756e646172793d2d2d");
header.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
header.append("2d2d2d2d2d2d2d2d2d39343338333235");
header.append("34323630383700a00800033735390000");
header.append("0c4d61782d466f727761726473000002");
header.append("3130000500176964303d4974656d2669");
header.append("64313d32266964323d696d673200ff");
return header.toString();
}
private String getTestShortBody()
{
StringBuffer body=new StringBuffer("");
body.append("123402f702f52d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d3934333833323534323630");
body.append("38370d0a436f6e74656e742d44697370");
body.append("6f736974696f6e3a20666f726d2d6461");
body.append("74613b206e616d653d227265636f7264");
body.append("4964220d0a0d0a320d0a2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d393433383332353432");
body.append("363038370d0a436f6e74656e742d4469");
body.append("73706f736974696f6e3a20666f726d2d");
body.append("646174613b206e616d653d226e616d65");
body.append("220d0a0d0a4974656d0d0a2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d3934333833323534");
body.append("32363038370d0a436f6e74656e742d44");
body.append("6973706f736974696f6e3a20666f726d");
body.append("2d646174613b206e616d653d22746e49");
body.append("6d674964220d0a0d0a696d67320d0a2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d39343338");
body.append("3332353432363038370d0a436f6e7465");
body.append("6e742d446973706f736974696f6e3a20");
body.append("666f726d2d646174613b206e616d653d");
body.append("227468756d624e61696c496d61676546");
body.append("696c65223b2066696c656e616d653d22");
body.append("6161612e747874220d0a436f6e74656e");
body.append("742d547970653a20746578742f706c61");
body.append("696e0d0a0d0a61616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("0d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d39");
body.append("3433383332353432363038370d0a436f");
body.append("6e74656e742d446973706f736974696f");
body.append("6e3a20666f726d2d646174613b206e61");
body.append("6d653d226c61726765496d6167654669");
body.append("6c65223b2066696c656e616d653d2261");
body.append("61612e747874220d0a436f6e74656e74");
body.append("2d547970653a20746578742f706c6169");
body.append("6e0d0a0d0a6161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("6161616161616161616161616161610d");
body.append("0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d3934");
body.append("33383332353432363038372d2d");
return body.toString();
}
private String getTestTinyBody()
{
StringBuffer body = new StringBuffer("");
body.append("123400042d2d0d0a");
return body.toString();
}
// TODO: char array instead of string?
private String readResponse(Socket _client) throws IOException
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
{
IO.copy(_client.getInputStream(),bout);
}
catch(SocketTimeoutException e)
{
LOG.ignore(e);
}
return bout.toString("utf-8");
}
public static class Handler extends AbstractHandler
{
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("text/plain");
response.getWriter().println("success");
}
}
}

View File

@ -1,608 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ajp;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.SimpleBuffers;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Test;
public class TestAjpParser
{
@Test
public void testPacket1() throws Exception
{
String packet = "123401070202000f77696474683d20485454502f312e300000122f636f6e74726f6c2f70726f647563742f2200000e3230382e32372e3230332e31323800ffff000c7777772e756c74612e636f6d000050000005a006000a6b6565702d616c69766500a00b000c7777772e756c74612e636f6d00a00e002b4d6f7a696c6c612f342e302028636f6d70617469626c653b20426f726465724d616e6167657220332e302900a0010043696d6167652f6769662c20696d6167652f782d786269746d61702c20696d6167652f6a7065672c20696d6167652f706a7065672c20696d6167652f706d672c202a2f2a00a008000130000600067570726f64310008000a4145533235362d53484100ff";
byte[] src = TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseAvailable();
assertTrue(true);
}
@Test
public void testPacket2() throws Exception
{
String packet="1234020102020008485454502f312e3100000f2f6363632d7777777777772f61616100000c38382e3838382e38382e383830ffff00116363632e6363636363636363632e636f6d0001bb010009a00b00116363632e6363636363636363632e636f6d00a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004039324643303544413043444141443232303137413743443141453939353132413330443938363838423843433041454643364231363035323543433232353341000b0100ff";
byte[] src=TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer=new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
EndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parse();
assertTrue(true);
}
@Test
public void testPacket3() throws Exception
{
String packet="1234028f02020008485454502f312e3100000d2f666f726d746573742e6a737000000d3139322e3136382e342e31383000ffff00107777772e777265636b6167652e6f726700005000000aa0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a00200075554462d382c2a00a003000c677a69702c6465666c61746500a004000e656e2d67622c656e3b713d302e3500a006000a6b6565702d616c69766500a00900f95048505345535349443d37626361383232616638333466316465373663633630336366636435313938633b20667041757468436f6f6b69653d433035383430394537393344364245434633324230353234344242303039343230383344443645443533304230454637464137414544413745453231313538333745363033454435364332364446353531383635333335423433374531423637414641343533364345304546323342333642323133374243423932333943363631433131443330393842333938414546334546334146454344423746353842443b204a53455353494f4e49443d7365366331623864663432762e6a657474793300a00b00107777772e777265636b6167652e6f726700000a6b6565702d616c69766500000333303000a00e00654d6f7a696c6c612f352e3020285831313b20553b204c696e7578207838365f36343b20656e2d55533b2072763a312e382e302e3929204765636b6f2f3230303631323035202844656269616e2d312e382e302e392d3129204570697068616e792f322e313400a008000130000600066a657474793300ff";
byte[] src=TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer=new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
EndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parse();
assertTrue(true);
}
@Test
public void testSSLPacketWithIntegerKeySize() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b0100ff";
byte[] src = TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseAvailable();
assertTrue(true);
}
@Test
public void testSSLPacketWithStringKeySize() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b000332353600ff";
byte[] src = TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
EndPoint endp = new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseAvailable();
assertTrue(true);
}
@Test
public void testSSLPacketFragment() throws Exception
{
String packet = "1234025002020008485454502f312e3100000f2f746573742f64756d702f696e666f00000e3139322e3136382e3130302e343000ffff000c776562746964652d746573740001bb01000ca00b000c776562746964652d7465737400a00e005a4d6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420352e313b20656e2d55533b2072763a312e382e312e3129204765636b6f2f32303036313230342046697265666f782f322e302e302e3100a0010063746578742f786d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d302e382c696d6167652f706e672c2a2f2a3b713d302e3500a004000e656e2d75732c656e3b713d302e3500a003000c677a69702c6465666c61746500a002001e49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e3700000a4b6565702d416c69766500000333303000a006000a6b6565702d616c69766500a00d001a68747470733a2f2f776562746964652d746573742f746573742f00a00900174a53455353494f4e49443d69326c6e307539773573387300000d43616368652d436f6e74726f6c0000096d61782d6167653d3000000c4d61782d466f7277617264730000023130000800124448452d5253412d4145533235362d5348410009004032413037364245323330433238393130383941414132303631344139384441443131314230323132343030374130363642454531363742303941464337383942000b0100ff";
byte[] src = TypeUtil.fromHexString(packet);
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
assertTrue(true);
}
@Test
public void testPacketWithBody() throws Exception
{
String packet=getTestHeader();
byte[] src=TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer=new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
final int count[]={0};
Ajp13Generator gen = new Ajp13Generator(buffers,endp)
{
public void getBodyChunk() throws IOException
{
count[0]++;
super.getBodyChunk();
}
};
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(gen);
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(0,count[0]);
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString(getTestShortBody())));
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(1,count[0]);
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString(getTestTinyBody())));
parser.parseNext();
parser.parseNext();
assertEquals(0,parser.getState());
assertEquals(1,count[0]);
assertTrue(true);
}
@Test
public void testPacketWithChunkedBody() throws Exception
{
String packet="123400ff02040008485454502f312e3100000f2f746573742f64756d702f696e666f0000093132372e302e302e3100ffff00096c6f63616c686f7374000050000007a00e000d4a6176612f312e352e305f313100a00b00096c6f63616c686f737400a0010034746578742f68746d6c2c20696d6167652f6769662c20696d6167652f6a7065672c202a3b20713d2e322c202a2f2a3b20713d2e3200a006000a6b6565702d616c69766500a00700216170706c69636174696f6e2f782d7777772d666f726d2d75726c656e636f6465640000115472616e736665722d456e636f64696e670000076368756e6b656400000c4d61782d466f727761726473000002313000ff";
byte[] src=TypeUtil.fromHexString(packet);
ByteArrayBuffer buffer=new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp=new ByteArrayEndPoint(src,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
final int count[]={0};
Ajp13Generator gen = new Ajp13Generator(buffers,endp)
{
public void getBodyChunk() throws IOException
{
count[0]++;
super.getBodyChunk();
}
};
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(gen);
parser.parseNext();
assertEquals(1,parser.getState());
assertEquals(1,count[0]);
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("1234007e007c7468656e616d653d746865253230717569636b25323062726f776e253230666f782532306a756d70732532306f766572253230746f2532307468652532306c617a79253230646f67253230544845253230515549434b25323042524f574e253230464f582532304a554d50532532304f564552253230544f25323054")));
while (parser.parseNext()>0);
assertEquals(1,parser.getState());
assertEquals(2,count[0]);
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("12340042004048452532304c415a59253230444f472532302676616c75656f66323d6162636465666768696a6b6c6d6e6f707172737475767778797a31323334353637383930")));
while (parser.parseNext()>0);
assertEquals(1,parser.getState());
assertEquals(3,count[0]);
endp.setIn(new ByteArrayBuffer(TypeUtil.fromHexString("123400020000")));
while (parser.getState()!=0 && parser.parseNext()>0);
assertEquals(0,parser.getState());
assertEquals(3,count[0]);
assertTrue(true);
}
@Test
public void testPacketFragment() throws Exception
{
String packet = "123401070202000f77696474683d20485454502f312e300000122f636f6e74726f6c2f70726f647563742f2200000e3230382e32372e3230332e31323800ffff000c7777772e756c74612e636f6d000050000005a006000a6b6565702d616c69766500a00b000c7777772e756c74612e636f6d00a00e002b4d6f7a696c6c612f342e302028636f6d70617469626c653b20426f726465724d616e6167657220332e302900a0010043696d6167652f6769662c20696d6167652f782d786269746d61702c20696d6167652f6a7065672c20696d6167652f706a7065672c20696d6167652f706d672c202a2f2a00a008000130000600067570726f64310008000a4145533235362d53484100ff";
byte[] src = TypeUtil.fromHexString(packet);
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
assertTrue(true);
}
@Test
public void testPacketFragmentWithBody() throws Exception
{
String packet = getTestHeader()+getTestBody();
byte[] src = TypeUtil.fromHexString(packet);
for (int f=1;f<src.length;f++)
{
byte[] frag0=new byte[src.length-f];
byte[] frag1=new byte[f];
System.arraycopy(src,0,frag0,0,src.length-f);
System.arraycopy(src,src.length-f,frag1,0,f);
ByteArrayBuffer buffer= new ByteArrayBuffer(Ajp13Packet.MAX_PACKET_SIZE);
SimpleBuffers buffers=new SimpleBuffers(buffer,null);
ByteArrayEndPoint endp = new ByteArrayEndPoint(frag0,Ajp13Packet.MAX_PACKET_SIZE);
endp.setNonBlocking(true);
Ajp13Parser parser = new Ajp13Parser(buffers,endp);
parser.setEventHandler(new EH());
parser.setGenerator(new Ajp13Generator(buffers,endp));
parser.parseNext();
endp.setIn(new ByteArrayBuffer(frag1));
parser.parseAvailable();
}
assertTrue(true);
}
private String getTestHeader()
{
StringBuffer header = new StringBuffer("");
header.append("1234026902040008485454502f31");
header.append("2e310000162f61646d696e2f496d6167");
header.append("6555706c6f61642e68746d00000a3130");
header.append("2e34382e31302e3100ffff000a31302e");
header.append("34382e31302e3200005000000da00b00");
header.append("0a31302e34382e31302e3200a00e005a");
header.append("4d6f7a696c6c612f352e30202857696e");
header.append("646f77733b20553b2057696e646f7773");
header.append("204e5420352e313b20656e2d55533b20");
header.append("72763a312e382e312e3129204765636b");
header.append("6f2f3230303631323034204669726566");
header.append("6f782f322e302e302e3100a001006374");
header.append("6578742f786d6c2c6170706c69636174");
header.append("696f6e2f786d6c2c6170706c69636174");
header.append("696f6e2f7868746d6c2b786d6c2c7465");
header.append("78742f68746d6c3b713d302e392c7465");
header.append("78742f706c61696e3b713d302e382c69");
header.append("6d6167652f706e672c2a2f2a3b713d30");
header.append("2e3500a004000e656e2d75732c656e3b");
header.append("713d302e3500a003000c677a69702c64");
header.append("65666c61746500a002001e49534f2d38");
header.append("3835392d312c7574662d383b713d302e");
header.append("372c2a3b713d302e3700000a4b656570");
header.append("2d416c69766500000333303000a00600");
header.append("0a6b6565702d616c69766500a00d003f");
header.append("687474703a2f2f31302e34382e31302e");
header.append("322f61646d696e2f496d61676555706c");
header.append("6f61642e68746d3f6964303d4974656d");
header.append("266964313d32266964323d696d673200");
header.append("a00900174a53455353494f4e49443d75");
header.append("383977733070696168746d00a0070046");
header.append("6d756c7469706172742f666f726d2d64");
header.append("6174613b20626f756e646172793d2d2d");
header.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
header.append("2d2d2d2d2d2d2d2d2d39343338333235");
header.append("34323630383700a00800033735390000");
header.append("0c4d61782d466f727761726473000002");
header.append("3130000500176964303d4974656d2669");
header.append("64313d32266964323d696d673200ff");
return header.toString();
}
private String getTestBody()
{
StringBuffer body = new StringBuffer("");
body.append("123402f902f72d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d3934333833323534323630");
body.append("38370d0a436f6e74656e742d44697370");
body.append("6f736974696f6e3a20666f726d2d6461");
body.append("74613b206e616d653d227265636f7264");
body.append("4964220d0a0d0a320d0a2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d393433383332353432");
body.append("363038370d0a436f6e74656e742d4469");
body.append("73706f736974696f6e3a20666f726d2d");
body.append("646174613b206e616d653d226e616d65");
body.append("220d0a0d0a4974656d0d0a2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d3934333833323534");
body.append("32363038370d0a436f6e74656e742d44");
body.append("6973706f736974696f6e3a20666f726d");
body.append("2d646174613b206e616d653d22746e49");
body.append("6d674964220d0a0d0a696d67320d0a2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d39343338");
body.append("3332353432363038370d0a436f6e7465");
body.append("6e742d446973706f736974696f6e3a20");
body.append("666f726d2d646174613b206e616d653d");
body.append("227468756d624e61696c496d61676546");
body.append("696c65223b2066696c656e616d653d22");
body.append("6161612e747874220d0a436f6e74656e");
body.append("742d547970653a20746578742f706c61");
body.append("696e0d0a0d0a61616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("0d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d39");
body.append("3433383332353432363038370d0a436f");
body.append("6e74656e742d446973706f736974696f");
body.append("6e3a20666f726d2d646174613b206e61");
body.append("6d653d226c61726765496d6167654669");
body.append("6c65223b2066696c656e616d653d2261");
body.append("61612e747874220d0a436f6e74656e74");
body.append("2d547970653a20746578742f706c6169");
body.append("6e0d0a0d0a6161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("6161616161616161616161616161610d");
body.append("0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d3934");
body.append("33383332353432363038372d2d0d0a");
return body.toString();
}
private String getTestShortBody()
{
StringBuffer body = new StringBuffer("");
body.append("123402f702f52d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d3934333833323534323630");
body.append("38370d0a436f6e74656e742d44697370");
body.append("6f736974696f6e3a20666f726d2d6461");
body.append("74613b206e616d653d227265636f7264");
body.append("4964220d0a0d0a320d0a2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d393433383332353432");
body.append("363038370d0a436f6e74656e742d4469");
body.append("73706f736974696f6e3a20666f726d2d");
body.append("646174613b206e616d653d226e616d65");
body.append("220d0a0d0a4974656d0d0a2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d3934333833323534");
body.append("32363038370d0a436f6e74656e742d44");
body.append("6973706f736974696f6e3a20666f726d");
body.append("2d646174613b206e616d653d22746e49");
body.append("6d674964220d0a0d0a696d67320d0a2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d39343338");
body.append("3332353432363038370d0a436f6e7465");
body.append("6e742d446973706f736974696f6e3a20");
body.append("666f726d2d646174613b206e616d653d");
body.append("227468756d624e61696c496d61676546");
body.append("696c65223b2066696c656e616d653d22");
body.append("6161612e747874220d0a436f6e74656e");
body.append("742d547970653a20746578742f706c61");
body.append("696e0d0a0d0a61616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("0d0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d39");
body.append("3433383332353432363038370d0a436f");
body.append("6e74656e742d446973706f736974696f");
body.append("6e3a20666f726d2d646174613b206e61");
body.append("6d653d226c61726765496d6167654669");
body.append("6c65223b2066696c656e616d653d2261");
body.append("61612e747874220d0a436f6e74656e74");
body.append("2d547970653a20746578742f706c6169");
body.append("6e0d0a0d0a6161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("61616161616161616161616161616161");
body.append("6161616161616161616161616161610d");
body.append("0a2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d");
body.append("2d2d2d2d2d2d2d2d2d2d2d2d2d2d3934");
body.append("33383332353432363038372d2d");
return body.toString();
}
private String getTestTinyBody()
{
StringBuffer body = new StringBuffer("");
body.append("123400042d2d0d0a");
return body.toString();
}
private static class EH implements Ajp13Parser.EventHandler
{
final boolean debug=false;
public void content(Buffer ref) throws IOException
{
if (debug) System.err.println(ref);
}
public void headerComplete() throws IOException
{
if (debug) System.err.println("--");
}
public void messageComplete(long contextLength) throws IOException
{
if (debug) System.err.println("==");
}
public void parsedHeader(Buffer name, Buffer value) throws IOException
{
if (debug) System.err.println(name+": "+value);
}
public void parsedMethod(Buffer method) throws IOException
{
if (debug) System.err.println(method);
}
public void parsedProtocol(Buffer protocol) throws IOException
{
if (debug) System.err.println(protocol);
}
public void parsedQueryString(Buffer value) throws IOException
{
if (debug) System.err.println("?"+value);
}
public void parsedRemoteAddr(Buffer addr) throws IOException
{
if (debug) System.err.println("addr="+addr);
}
public void parsedRemoteHost(Buffer host) throws IOException
{
if (debug) System.err.println("host="+host);
}
public void parsedRequestAttribute(String key, Buffer value) throws IOException
{
if (debug) System.err.println(key+":: "+value);
}
public void parsedServerName(Buffer name) throws IOException
{
if (debug) System.err.println("Server:: "+name);
}
public void parsedServerPort(int port) throws IOException
{
if (debug) System.err.println("Port:: "+port);
}
public void parsedSslSecure(boolean secure) throws IOException
{
if (debug) System.err.println("Secure:: "+secure);
}
public void parsedUri(Buffer uri) throws IOException
{
if (debug) System.err.println("URI:: "+uri);
}
public void startForwardRequest() throws IOException
{
if (debug) System.err.println("..");
}
public void parsedAuthorizationType(Buffer authType) throws IOException
{
if (debug) System.err.println("auth:: "+authType);
}
public void parsedRemoteUser(Buffer remoteUser) throws IOException
{
if (debug) System.err.println("user:: "+remoteUser);
}
public void parsedServletPath(Buffer servletPath) throws IOException
{
if (debug) System.err.println("servletPath:: "+servletPath);
}
public void parsedContextPath(Buffer context) throws IOException
{
if (debug) System.err.println("Context:: "+context);
}
public void parsedSslCert(Buffer sslCert) throws IOException
{
if (debug) System.err.println("sslCert:: "+sslCert);
}
public void parsedSslCipher(Buffer sslCipher) throws IOException
{
if (debug) System.err.println("sslCipher:: "+sslCipher);
}
public void parsedSslSession(Buffer sslSession) throws IOException
{
if (debug) System.err.println("sslSession:: "+sslSession);
}
public void parsedSslKeySize(int keySize) throws IOException
{
if (debug) System.err.println("sslkeysize:: "+keySize);
}
public void parsedRequestAttribute(String key, int value) throws IOException
{
if (debug) System.err.println(key+":: "+value);
}
}
}

View File

@ -386,7 +386,6 @@
<module>jetty-jndi</module>
<!--
<module>jetty-jaspi</module>
<module>jetty-ajp</module>