blob: d9b4af5e6d3bc9b7c2a49bc680845ecc38c21d44 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ajp.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.ajp.Ajp13;
import org.apache.ajp.Ajp13Packet;
import org.apache.ajp.RequestHandler;
import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.MimeHeaders;
public class TestAjp13 extends TestCase {
Ajp13Server server = null;
public TestAjp13(String name) {
super(name);
}
public static Test suite() {
return new TestSuite(TestAjp13.class);
}
protected void setUp() {
println("setup...");
server = new Ajp13Server();
server.start();
}
protected void tearDown() {
println("tear down...");
server.shutdown();
}
public void test1() throws Exception {
println("running test1");
Socket s = new Socket("localhost", 8009);
Ajp13Packet p = new Ajp13Packet(Ajp13.MAX_PACKET_SIZE);
p.appendInt(0x1234);
p.appendInt(0);
p.setByteOff(4);
p.appendByte(RequestHandler.JK_AJP13_FORWARD_REQUEST);
p.appendByte((byte)2);
p.appendString("http");
p.appendString("/test_uri");
p.appendString("remote_addr");
p.appendString("remote_host");
p.appendString("server_name");
p.appendInt(80);
p.appendBool(false);
p.appendInt(3);
p.appendString("my header");
p.appendString("my header value");
p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_AUTHORIZATION);
p.appendString("some auth string");
p.appendInt((0xA0 << 8) + RequestHandler.SC_REQ_USER_AGENT);
p.appendString("TestAjp13 User Agent");
p.appendByte(RequestHandler.SC_A_ARE_DONE);
int len = p.getByteOff() - 4;
p.setByteOff(2);
p.appendInt(len);
OutputStream os = s.getOutputStream();
os.write(p.getBuff(), 0, len + 4);
InputStream is = s.getInputStream();
println("decoding response...");
boolean done = false;
while (!done) {
int b1, b2;
// read a packet
// first 2 bytes should be AB
b1 = is.read();
assertTrue("byte 1 was " + (char)b1, b1 == (int)'A');
b2 = is.read();
assertTrue("byte 2 was " + (char)b2, b2 == (int)'B');
println("b1 = " + (char)b1 + "; b2 = " + (char)b2);
// next is length
b1 = is.read();
b1 &= 0xFF;
b2 = is.read();
b2 &= 0xFF;
int l = (b1 << 8) + b2;
println("length = " + l);
// now get data
byte[] buf = new byte[l];
int n = 0;
int off = 0;
int total = 0;
while ((n = is.read(buf, off, l - off)) != -1 && (l - off != 0)) {
total += n;
off += n;
}
println("read " + total);
assertTrue("total read was " + total +
", should have been " + l,
total == l);
int code = (int)buf[0];
switch (code) {
case 3:
println("AJP13_SEND_BODY_CHUNK ");
break;
case 4:
println("AJP13_SEND_HEADERS ");
break;
case 5:
println("AJP13_END_RESPONSE ");
done = true;
break;
case 6:
println("AJP13_GET_BODY_CHUNK ");
break;
default:
assertTrue("invalid prefix code: " + code, false);
break;
}
}
println("shutting down socket...");
s.shutdownOutput();
s.shutdownInput();
s.close();
println("done test1...");
}
protected static void println(String msg) {
System.out.println("[TestAjp13] " + msg);
}
public static void main(String[] args) throws Exception {
}
}
class Ajp13Server extends Thread {
boolean shutdown = false;
void shutdown() {
this.shutdown = true;
this.interrupt();
}
public void run() {
try {
ServerSocket server = new ServerSocket(8009);
TestAjp13.println("Ajp13Server running...");
Socket socket = server.accept();
Ajp13 ajp13 = new Ajp13();
MimeHeaders headers = new MimeHeaders();
BaseRequest request = new BaseRequest();
ajp13.setSocket(socket);
boolean moreRequests = true;
while (moreRequests && !shutdown) {
int status = 0;
try {
status = ajp13.receiveNextRequest(request);
} catch (IOException e) {
if (shutdown) {
TestAjp13.println("Ajp13Server told to shutdown");
break;
}
TestAjp13.println("process: ajp13.receiveNextRequest -> " + e);
}
if( status==-2) {
// special case - shutdown
// XXX need better communication, refactor it
// if( !doShutdown(socket.getLocalAddress(),
// socket.getInetAddress())) {
// moreRequests = false;
// continue;
// }
break;
}
// Special low level request allready handled (ie: PING/PONG)
if( status == 999 )
{
request.recycle();
continue;
}
if( status != 200 )
break;
TestAjp13.println(request.toString());
String message =
"<html><body><pre>" +
"hello from ajp13: " +
System.getProperty("line.separator") +
request.toString() +
"</pre></body></html>";
headers.addValue("content-type").setString( "text/html");
headers.addValue("content-length").setInt(message.length());
headers.addValue("my-header").setString( "my value");
ajp13.sendHeaders(200, headers);
byte[] b = message.getBytes();
ajp13.doWrite(b, 0, b.length);
ajp13.finish();
request.recycle();
headers.recycle();
}
try {
ajp13.close();
} catch (IOException e) {
TestAjp13.println("process: ajp13.close ->" + e);
}
try {
socket.close();
} catch (IOException e) {
TestAjp13.println("process: socket.close ->" + e);
}
socket = null;
TestAjp13.println("process: done");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.toString());
}
}
}