blob: eb459514bb7cf51836992a5af6092aaa80ab3e88 [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.catalina.connector.warp;
import java.io.IOException;
import java.io.InputStream;
import org.apache.catalina.Host;
import org.apache.catalina.connector.HttpRequestBase;
public class WarpRequest extends HttpRequestBase {
/** The local stream */
private Stream localstream;
/** The connection to which we are associated */
private WarpConnection connection;
private Host host=null;
public WarpRequest() {
super();
this.localstream=new Stream(this);
this.setStream(this.localstream);
}
/** Process the SSL attributes */
public Object getAttribute(String name) {
/* Use cached values */
Object object = super.getAttribute(name);
if (object != null)
return object;
/* Fill the cache and return value if possible */
if (!localstream.request.isSecure()) return null;
/* Client Certificate */
if (name.equals("javax.servlet.request.X509Certificate")) {
WarpCertificates cert = null;
try {
cert = new WarpCertificates(localstream.getX509Certificates());
} catch (IOException e) {
return null;
}
super.setAttribute("javax.servlet.request.X509Certificate",
cert.getCertificates());
}
/* other ssl parameters */
if (name.equals("javax.servlet.request.cipher_suite") ||
name.equals("javax.servlet.request.key_size") ||
name.equals("javax.servlet.request.ssl_session")) {
WarpSSLData ssldata = null;
try {
ssldata = localstream.getSSL();
} catch (IOException e) {
return null;
}
if (ssldata == null) return null;
super.setAttribute("javax.servlet.request.cipher_suite",
ssldata.ciph);
if (ssldata.size!=0)
super.setAttribute("javax.servlet.request.key_size",
new Integer (ssldata.size));
super.setAttribute("javax.servlet.request.ssl_session",
ssldata.sess);
}
return(super.getAttribute(name));
}
public void setHost(Host host) {
this.host=host;
}
public Host getHost() {
return(this.host);
}
/**
* Recycle this <code>WarpResponse</code> instance.
*/
public void recycle() {
// Recycle our parent
super.recycle();
// Recycle the stream
this.localstream.recycle();
// Tell the parent that a stream is already in use.
this.setStream(localstream);
}
/**
* Associate this <code>WarpResponse</code> instance with a specific
* <code>WarpConnection</code> instance.
*/
public void setConnection(WarpConnection connection) {
this.connection=connection;
}
/**
* Return the <code>WarpConnection</code> associated this instance of
* <code>WarpResponse</code>.
*/
public WarpConnection getConnection() {
return(this.connection);
}
protected class Stream extends InputStream {
/** The response associated with this stream instance. */
private WarpRequest request=null;
/** The packet used by this stream instance. */
private WarpPacket packet=null;
/** Wether <code>close()</code> was called or not. */
private boolean closed=false;
protected Stream(WarpRequest request) {
super();
this.request=request;
this.packet=new WarpPacket();
this.packet.setType(Constants.TYPE_CBK_DATA);
}
public int read()
throws IOException {
if (closed) throw new IOException("Stream closed");
if (this.packet.pointer<this.packet.size)
return(((int)this.packet.buffer[this.packet.pointer++])&0x0ff);
this.packet.reset();
this.packet.setType(Constants.TYPE_CBK_READ);
this.packet.writeUnsignedShort(65535);
this.request.getConnection().send(packet);
packet.reset();
this.request.getConnection().recv(packet);
if (packet.getType()==Constants.TYPE_CBK_DONE) return(-1);
if (packet.getType()!=Constants.TYPE_CBK_DATA)
throw new IOException("Invalid WARP packet type for body");
return(this.read());
}
public String getX509Certificates()
throws IOException {
if (closed) throw new IOException("Stream closed");
this.packet.reset();
this.packet.setType(Constants.TYPE_ASK_SSL_CLIENT);
this.request.getConnection().send(packet);
packet.reset();
this.request.getConnection().recv(packet);
if (closed) throw new IOException("Stream closed");
if (packet.getType()==Constants.TYPE_REP_SSL_NO) return(null);
if (packet.getType()!=Constants.TYPE_REP_SSL_CERT)
throw new IOException("Invalid WARP packet type for CC");
return(this.packet.readString());
}
/** Read the data from the SSL environment. */
public WarpSSLData getSSL()
throws IOException {
if (closed) throw new IOException("Stream closed");
this.packet.reset();
this.packet.setType(Constants.TYPE_ASK_SSL);
this.request.getConnection().send(packet);
packet.reset();
this.request.getConnection().recv(packet);
if (closed) throw new IOException("Stream closed");
if (packet.getType()==Constants.TYPE_REP_SSL_NO) return(null);
if (packet.getType()!=Constants.TYPE_REP_SSL)
throw new IOException("Invalid WARP packet type for SSL data");
WarpSSLData ssldata = new WarpSSLData();
ssldata.ciph = this.packet.readString();
ssldata.sess = this.packet.readString();
ssldata.size = this.packet.readInteger();
return(ssldata);
}
public void close()
throws IOException {
if (closed) throw new IOException("Stream closed");
this.packet.reset();
this.packet.setType(Constants.TYPE_CBK_DONE);
this.closed=true;
}
public void recycle() {
this.packet.reset();
this.packet.setType(Constants.TYPE_CBK_DATA);
this.closed=false;
}
}
}