--- /dev/null
+/*
+ */
+package org.apache.tomcat.addons;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Abstract the filesystem - lighter than the JNDI used in catalina.
+ *
+ * This can be used to port the File/Dav servlets to environments that
+ * don't have a file system access, or in servlet engines with class-based
+ * sandboxing.
+ */
+public class Filesystem {
+
+ public OutputStream getOutputStream(String name) throws IOException {
+ return null;
+ }
+
+ public InputStream getInputStream(String name) throws IOException {
+ return new FileInputStream(name);
+ }
+}
* The framework may inject properties - if it supports that.
*/
public void bind(String name, Object o) {
- for (ObjectManagerSpi p : providers) {
+ for (ObjectManager p : children) {
p.bind(name, o);
}
}
* When an object is no longer in use.
*/
public void unbind(String name) {
- for (ObjectManagerSpi p : providers) {
+ for (ObjectManager p : children) {
p.unbind(name);
}
}
* Create or get a new object with the given name.
*/
public Object get(String key) {
- for (ObjectManagerSpi p : providers) {
+ for (ObjectManager p : children) {
Object o = p.get(key);
if (o != null) {
return o;
* ObjectManager delegates to providers. You can have multiple
* providers - for example JMX, DI and OSGI at the same time.
*/
- protected List<ObjectManagerSpi> providers =
- new ArrayList<ObjectManagerSpi>();
+ protected List<ObjectManager> children =
+ new ArrayList<ObjectManager>();
+
+ public void register(ObjectManager om) {
+ om.children.add(this);
+ }
}
+++ /dev/null
-/*
- */
-package org.apache.tomcat.integration;
-
-/**
- * Base class for framework-integration plugins.
- */
-public abstract class ObjectManagerSpi {
- public abstract void bind(String name, Object o);
-
- public abstract void unbind(String name);
-
- public abstract Object get(String key);
-
- public void register(ObjectManager om) {
- om.providers.add(this);
- }
-}
\ No newline at end of file
import java.util.logging.Logger;
-import org.apache.tomcat.integration.ObjectManagerSpi;
+import org.apache.tomcat.integration.ObjectManager;
import org.apache.tomcat.util.modeler.Registry;
/**
*
* All objects of interest are registered automatically.
*/
-public class JmxObjectManagerSpi extends ObjectManagerSpi {
+public class JmxObjectManagerSpi extends ObjectManager {
Registry registry;
Logger log = Logger.getLogger("JmxObjectManager");
--- /dev/null
+/*
+ */
+package org.apache.tomcat.integration.simple;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.tomcat.addons.Filesystem;
+
+public class LocalFilesystem extends Filesystem {
+
+ public OutputStream getOutputStream(String name) throws IOException {
+ return new FileOutputStream(name);
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.integration.simple;
+
+import org.apache.tomcat.integration.ObjectManager;
+
+/**
+ * Replacement for tomcat-lite specific Main, using the simple
+ * injection. SimpleObjectManager also has support for simple
+ * command line processing - CLI is treated the same with
+ * properties from the config file.
+ *
+ * @author Costin Manolache
+ */
+public class Main {
+
+ public static void main(String args[])
+ throws Exception {
+ SimpleObjectManager om = new SimpleObjectManager();
+
+ // Will process CLI.
+ // 'config' will load a config file.
+ om.bind("Main.args", args);
+
+ Runnable main = (Runnable) om.get("Main");
+ if (main == null) {
+ // TODO: look for a pre-defined name in local dir, resource,
+ // manifest
+ System.err.println("Using default tomcat-lite configuration");
+
+ if (args.length == 0) {
+ System.err.println("Example command line:");
+ System.err.println("-context /:webapps/ROOT -Connector.port 9999");
+ }
+
+ String cfgFile = "org/apache/tomcat/lite/config.properties";
+ om.loadResource(cfgFile);
+ main = (Runnable) om.get("Main");
+ }
+
+ // add JMX support
+ ObjectManager jmx = (ObjectManager) om.get("JMX");
+ if (jmx != null) {
+ jmx.register(om);
+ }
+
+ main.run();
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.integration.simple;
+
+import java.util.Enumeration;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.tomcat.integration.ObjectManager;
+
+public class ServletHelper {
+
+ public static ObjectManager getObjectManager(ServletContext ctx) {
+ // May be provided by container or a listener
+ ObjectManager om = (ObjectManager) ctx.getAttribute(ObjectManager.ATTRIBUTE);
+ if (om == null) {
+ // Default
+ SimpleObjectManager som = new SimpleObjectManager();
+ om = som;
+
+ // All context init params are set
+ Enumeration namesE = ctx.getInitParameterNames();
+ while (namesE.hasMoreElements()) {
+ String n = (String) namesE.nextElement();
+ String v = ctx.getInitParameter(n);
+ som.getProperties().put(n, v);
+ }
+
+ ctx.setAttribute(ObjectManager.ATTRIBUTE, om);
+ // load context settings
+ }
+ return om;
+ }
+
+ public static void initServlet(Servlet s) {
+ ServletConfig sc = s.getServletConfig();
+ String name = sc.getServletName();
+ String ctx = sc.getServletContext().getContextPath();
+
+ // Servlets are named:...
+
+ ObjectManager om = getObjectManager(sc.getServletContext());
+
+ String dn = ctx + ":" + name;
+
+ // If SimpleObjectManager ( or maybe other supporting dynamic config ):
+ if (om instanceof SimpleObjectManager) {
+ SimpleObjectManager som = (SimpleObjectManager) om;
+
+
+ }
+
+
+ om.bind(dn, s);
+
+ }
+
+}
*/
package org.apache.tomcat.integration.simple;
+import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;
import org.apache.tomcat.integration.ObjectManager;
-import org.apache.tomcat.integration.ObjectManagerSpi;
import org.apache.tomcat.util.IntrospectionUtils;
+import org.apache.tools.ant.taskdefs.LoadResource;
/**
* This is a very small 'dependency injection'/registry poor-man substitute,
*
* @author Costin Manolache
*/
-public class SimpleObjectManager extends ObjectManagerSpi {
-
+public class SimpleObjectManager extends ObjectManager {
static Logger log = Logger.getLogger(SimpleObjectManager.class.getName());
- /**
- * Saved CLI arguments. Will be added to the properties.
- */
- public static String[] args;
-
protected Properties props = new Properties();
protected Map<String, Object> objects = new HashMap();
ObjectManager om;
public SimpleObjectManager() {
+ // Register PropertiesSpi
}
- public SimpleObjectManager(ObjectManager om) {
- register(om);
+ public SimpleObjectManager(String[] args) {
+ this();
+ bind("Main.args", args);
}
-
+
+ public void loadResource(String res) {
+ InputStream in = this.getClass().getClassLoader()
+ .getResourceAsStream(res);
+ load(in);
+ }
+
public void register(ObjectManager om) {
this.om = om;
- if (args != null) {
- try {
- processArgs(args, props);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
super.register(om);
}
}
}
- public void loadResource(String res) {
- InputStream in = this.getClass().getClassLoader()
- .getResourceAsStream(res);
- load(in);
- }
-
public Properties getProperties() {
return props;
}
@Override
public void bind(String name, Object o) {
- log.info("Bound: " + name + " " + o);
+ //log.info("Bound: " + name + " " + o);
+ if ("Main.args".equals(name)) {
+ try {
+ processArgs((String[]) o, props);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
// TODO: can I make 'inject' public - Guice seems to
// support this.
inject(name, o);
* @return everything after the first non arg not starting with '-'
* @throws IOException
*/
- public static String[] processArgs(String[] args, Properties props)
+ public String[] processArgs(String[] args, Properties props)
throws IOException {
for (int i = 0; i < args.length; i++) {
}
if ("config".equals(arg)) {
- props.load(new FileInputStream(value));
+ if (new File(value).exists()) {
+ load(new FileInputStream(value));
+ } else {
+ loadResource(value);
+ }
} else {
props.put(name, value);
}
}
return new String[] {};
- }
-
- public static void setArgs(String[] argv) {
- SimpleObjectManager.args = argv;
- }
+ }
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.HashMap;
+
+import org.apache.tomcat.util.buf.B2CConverter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.CharChunk;
+
+/**
+ * Refactored from catalina.connector.InputBuffer. Renamed to avoid conflict
+ * with coyote class.
+ *
+ */
+
+/**
+ * The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3
+ * OutputBuffer, adapted to handle input instead of output. This allows
+ * complete recycling of the facade objects (the ServletInputStream and the
+ * BufferedReader).
+ *
+ * @author Remy Maucherat
+ */
+public class BodyReader extends Reader
+ implements ByteChunk.ByteInputChannel, CharChunk.CharInputChannel,
+ CharChunk.CharOutputChannel {
+
+
+ // -------------------------------------------------------------- Constants
+
+
+ public static final String DEFAULT_ENCODING =
+ org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+
+ // The buffer can be used for byte[] and char[] reading
+ // ( this is needed to support ServletInputStream and BufferedReader )
+ public final int INITIAL_STATE = 0;
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The byte buffer. More data may be added to it while reading.
+ */
+ private ByteChunk bb;
+
+
+ /**
+ * The chunk buffer, will be filled in from the bb.
+ */
+ private CharChunk cb;
+
+
+ /**
+ * State of the output buffer.
+ */
+ private int state = 0;
+
+
+ /**
+ * Number of bytes read.
+ */
+ private int bytesRead = 0;
+
+
+ /**
+ * Number of chars read.
+ */
+ private int charsRead = 0;
+
+
+ /**
+ * Flag which indicates if the input buffer is closed.
+ */
+ private boolean closed = false;
+
+ /**
+ * Encoding to use.
+ */
+ private String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ private boolean gotEnc = false;
+
+
+ /**
+ * Cached encoders.
+ */
+ protected HashMap<String, B2CConverter> encoders =
+ new HashMap<String, B2CConverter>();
+
+
+ /**
+ * Current byte to char converter.
+ */
+ protected B2CConverter conv;
+
+
+ /**
+ * Associated Coyote request.
+ */
+ private ServletRequestImpl coyoteRequest;
+ Connector connector;
+
+ /**
+ * Buffer position.
+ */
+ private int markPos = -1;
+
+
+ /**
+ * Buffer size.
+ */
+ private int size = -1;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer size.
+ */
+ public BodyReader() {
+ this(DEFAULT_BUFFER_SIZE);
+ }
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer size.
+ *
+ * @param size Buffer size to use
+ */
+ public BodyReader(int size) {
+ this.size = size;
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteInputChannel(this);
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setOptimizedWrite(false);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+ }
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Associated Coyote request.
+ *
+ * @param coyoteRequest Associated Coyote request
+ */
+ public void setConnector(Connector c, ServletRequestImpl coyoteRequest) {
+ this.connector = c;
+ this.coyoteRequest = coyoteRequest;
+ }
+
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+
+ state = INITIAL_STATE;
+ bytesRead = 0;
+ charsRead = 0;
+
+ // If usage of mark made the buffer too big, reallocate it
+ if (cb.getChars().length > size) {
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+ } else {
+ cb.recycle();
+ }
+ markPos = -1;
+ bb.recycle();
+ closed = false;
+
+ if (conv != null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ }
+
+
+ /**
+ * Close the input buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+ closed = true;
+ }
+
+
+ public int available()
+ throws IOException {
+ if (state == BYTE_STATE) {
+ return bb.getLength();
+ } else if (state == CHAR_STATE) {
+ return cb.getLength();
+ } else {
+ return 0;
+ }
+ }
+
+
+ // ------------------------------------------------- Bytes Handling Methods
+
+
+ /**
+ * Reads new bytes in the byte chunk.
+ *
+ * @param cbuf Byte buffer to be written to the response
+ * @param off Offset
+ * @param len Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public int realReadBytes(byte cbuf[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return -1;
+ if (coyoteRequest == null)
+ return -1;
+
+ state = BYTE_STATE;
+
+ int result = connector.doRead(coyoteRequest, bb);
+
+ return result;
+
+ }
+
+
+ public int readByte()
+ throws IOException {
+ return bb.substract();
+ }
+
+
+ public int read(byte[] b, int off, int len)
+ throws IOException {
+ return bb.substract(b, off, len);
+ }
+
+
+ // ------------------------------------------------- Chars Handling Methods
+
+
+ /**
+ * Since the converter will use append, it is possible to get chars to
+ * be removed from the buffer for "writing". Since the chars have already
+ * been read before, they are ignored. If a mark was set, then the
+ * mark is lost.
+ */
+ public void realWriteChars(char c[], int off, int len)
+ throws IOException {
+ markPos = -1;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+ /**
+ * Called when a read(char[]) operation is lacking data. It will read
+ * bytes.
+ */
+ public int realReadChars(char cbuf[], int off, int len)
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ if (bb.getLength() <= 0) {
+ int nRead = realReadBytes(bb.getBytes(), 0, bb.getBytes().length);
+ if (nRead < 0) {
+ return -1;
+ }
+ }
+
+ if (markPos == -1) {
+ cb.setOffset(0);
+ cb.setEnd(0);
+ }
+
+ conv.convert(bb, cb, -1);
+ bb.setOffset(bb.getEnd());
+ state = CHAR_STATE;
+
+ return cb.getLength();
+
+ }
+
+
+ public int read()
+ throws IOException {
+ return cb.substract();
+ }
+
+
+ public int read(char[] cbuf)
+ throws IOException {
+ return read(cbuf, 0, cbuf.length);
+ }
+
+
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+ return cb.substract(cbuf, off, len);
+ }
+
+
+ public long skip(long n)
+ throws IOException {
+
+ if (n < 0) {
+ throw new IllegalArgumentException();
+ }
+
+ long nRead = 0;
+ while (nRead < n) {
+ if (cb.getLength() >= n) {
+ cb.setOffset(cb.getStart() + (int) n);
+ nRead = n;
+ } else {
+ nRead += cb.getLength();
+ cb.setOffset(cb.getEnd());
+ int toRead = 0;
+ if (cb.getChars().length < (n - nRead)) {
+ toRead = cb.getChars().length;
+ } else {
+ toRead = (int) (n - nRead);
+ }
+ int nb = realReadChars(cb.getChars(), 0, toRead);
+ if (nb < 0)
+ break;
+ }
+ }
+
+ return nRead;
+
+ }
+
+
+ public boolean ready()
+ throws IOException {
+ return (cb.getLength() > 0);
+ }
+
+
+ public boolean markSupported() {
+ return true;
+ }
+
+
+ public void mark(int readAheadLimit)
+ throws IOException {
+ if (cb.getLength() <= 0) {
+ cb.setOffset(0);
+ cb.setEnd(0);
+ } else {
+ if ((cb.getBuffer().length > (2 * size))
+ && (cb.getLength()) < (cb.getStart())) {
+ System.arraycopy(cb.getBuffer(), cb.getStart(),
+ cb.getBuffer(), 0, cb.getLength());
+ cb.setEnd(cb.getLength());
+ cb.setOffset(0);
+ }
+ }
+ int offset = readAheadLimit;
+ if (offset < size) {
+ offset = size;
+ }
+ cb.setLimit(cb.getStart() + offset);
+ markPos = cb.getStart();
+ }
+
+
+ public void reset()
+ throws IOException {
+ if (state == CHAR_STATE) {
+ if (markPos < 0) {
+ cb.recycle();
+ markPos = -1;
+ throw new IOException();
+ } else {
+ cb.setOffset(markPos);
+ }
+ } else {
+ bb.recycle();
+ }
+ }
+
+
+ protected void setConverter()
+ throws IOException {
+ if (coyoteRequest != null)
+ enc = coyoteRequest.getCharacterEncoding();
+
+ gotEnc = true;
+ if (enc == null)
+ enc = DEFAULT_ENCODING;
+ conv = (B2CConverter) encoders.get(enc);
+ if (conv == null) {
+ conv = new B2CConverter(enc);
+ encoders.put(enc, conv);
+ }
+ }
+
+ public class MRInputStream extends InputStream {
+ public long skip(long n)
+ throws IOException {
+ return BodyReader.this.skip(n);
+ }
+
+ public void mark(int readAheadLimit)
+ {
+ try {
+ BodyReader.this.mark(readAheadLimit);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public void reset()
+ throws IOException {
+ BodyReader.this.reset();
+ }
+
+
+
+ public int read()
+ throws IOException {
+ return BodyReader.this.readByte();
+ }
+
+ public int available() throws IOException {
+ return BodyReader.this.available();
+ }
+
+ public int read(final byte[] b) throws IOException {
+ return BodyReader.this.read(b, 0, b.length);
+ }
+
+
+ public int read(final byte[] b, final int off, final int len)
+ throws IOException {
+
+ return BodyReader.this.read(b, off, len);
+ }
+
+
+ /**
+ * Close the stream
+ * Since we re-cycle, we can't allow the call to super.close()
+ * which would permantely disable us.
+ */
+ public void close() throws IOException {
+ BodyReader.this.close();
+ }
+ }
+
+ MRInputStream is = new MRInputStream();
+
+ public InputStream asInputStream() {
+ return is;
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.C2BConverter;
+import org.apache.tomcat.util.buf.CharChunk;
+
+/**
+ * Implement buffering and character translation acording to the
+ * servlet spec.
+ *
+ * This class handles both chars and bytes.
+ *
+ * It is tightly integrated with servlet response, sending headers
+ * and updating the commit state.
+ *
+ * TODO: add 'extension' interface that allows direct access to
+ * the async connector non-copy non-blocking queue. Same for the
+ * OutputStream. Maybe switch the buffer to the brigade.
+ *
+ * @author Costin Manolache
+ */
+public class BodyWriter extends Writer {
+
+ // used in getWriter, until a method is added to res.
+ protected static final int WRITER_NOTE = 3;
+
+
+ private ByteChunk.ByteOutputChannel byteFlusher =
+ new ByteChunk.ByteOutputChannel() {
+
+ @Override
+ public void realWriteBytes(byte[] cbuf, int off, int len)
+ throws IOException {
+ BodyWriter.this.realWriteBytes(cbuf, off, len);
+ }
+ };
+
+ private CharChunk.CharOutputChannel charFlusher =
+ new CharChunk.CharOutputChannel() {
+ @Override
+ public void realWriteChars(char[] cbuf, int off, int len)
+ throws IOException {
+ BodyWriter.this.realWriteChars(cbuf, off, len);
+ }
+ };
+
+
+ public static final String DEFAULT_ENCODING =
+ org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+
+
+ // The buffer can be used for byte[] and char[] writing
+ // ( this is needed to support ServletOutputStream and for
+ // efficient implementations of templating systems )
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+ boolean headersSent = false;
+ // ----------------------------------------------------- Instance Variables
+ ServletResponseImpl res;
+
+ /**
+ * The byte buffer.
+ */
+ protected ByteChunk bb;
+
+
+ /**
+ * The chunk buffer.
+ */
+ protected CharChunk cb;
+
+
+ /**
+ * State of the output buffer.
+ */
+ protected int state = 0;
+
+
+ /**
+ * Number of bytes written.
+ */
+ protected int bytesWritten = 0;
+
+
+ /**
+ * Number of chars written.
+ */
+ protected int charsWritten = 0;
+
+
+ /**
+ * Flag which indicates if the output buffer is closed.
+ */
+ protected boolean closed = false;
+
+
+ /**
+ * Do a flush on the next operation.
+ */
+ protected boolean doFlush = false;
+
+
+ /**
+ * Byte chunk used to output bytes. This is just used to wrap the byte[]
+ * to match the coyote OutputBuffer interface
+ */
+ protected ByteChunk outputChunk = new ByteChunk();
+
+
+ /**
+ * Encoding to use.
+ * TODO: isn't it redundant ? enc, gotEnc, conv plus the enc in the bb
+ */
+ protected String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ protected boolean gotEnc = false;
+
+
+ /**
+ * List of encoders. The writer is reused - the encoder mapping
+ * avoids creating expensive objects. In future it'll contain nio.Charsets
+ */
+ protected HashMap encoders = new HashMap();
+
+
+ /**
+ * Current char to byte converter. TODO: replace with Charset
+ */
+ protected C2BConverter conv;
+
+ /**
+ * Suspended flag. All output bytes will be swallowed if this is true.
+ */
+ protected boolean suspended = false;
+
+ private Connector connector;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer size.
+ */
+ public BodyWriter() {
+
+ this(DEFAULT_BUFFER_SIZE);
+
+ }
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer size.
+ *
+ * @param size Buffer size to use
+ */
+ public BodyWriter(int size) {
+
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteOutputChannel(byteFlusher);
+ cb = new CharChunk(size);
+ cb.setCharOutputChannel(charFlusher);
+ cb.setLimit(size);
+
+ }
+
+ public void setConnector(Connector c, ServletResponseImpl res) {
+ this.res = res;
+ this.connector = c;
+ }
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Is the response output suspended ?
+ *
+ * @return suspended flag value
+ */
+ public boolean isSuspended() {
+ return this.suspended;
+ }
+
+
+ /**
+ * Set the suspended flag.
+ *
+ * @param suspended New suspended flag value
+ */
+ public void setSuspended(boolean suspended) {
+ this.suspended = suspended;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+
+ state = BYTE_STATE;
+ headersSent = false;
+ bytesWritten = 0;
+ charsWritten = 0;
+
+ cb.recycle();
+ bb.recycle();
+ closed = false;
+ suspended = false;
+
+ if (conv!= null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ }
+
+
+ /**
+ * Close the output buffer. This tries to calculate the response size if
+ * the response has not been committed yet.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+
+ if (closed)
+ return;
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ }
+ connector.beforeClose(res, bb.getLength());
+
+ doFlush(false);
+ closed = true;
+
+ connector.finishResponse(res);
+ }
+
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void flush()
+ throws IOException {
+ doFlush(true);
+ }
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ protected void doFlush(boolean realFlush)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ doFlush = true;
+ if (!headersSent) {
+ // If the buffers are empty, commit the response header
+ connector.sendHeaders(res);
+ headersSent = true;
+ }
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ }
+ if (state == BYTE_STATE) {
+ bb.flushBuffer();
+ }
+ doFlush = false;
+
+ if (realFlush) {
+ connector.realFlush(res);
+ }
+
+ }
+
+
+ // ------------------------------------------------- Bytes Handling Methods
+
+
+ /**
+ * Sends the buffer data to the client output, checking the
+ * state of Response and calling the right interceptors.
+ *
+ * @param buf Byte buffer to be written to the response
+ * @param off Offset
+ * @param cnt Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ private void realWriteBytes(byte buf[], int off, int cnt)
+ throws IOException {
+
+ if (closed)
+ return;
+
+ // If we really have something to write
+ if (cnt > 0) {
+ // real write to the adapter
+ outputChunk.setBytes(buf, off, cnt);
+ try {
+ connector.doWrite(res, outputChunk);
+ } catch (IOException e) {
+ // An IOException on a write is almost always due to
+ // the remote client aborting the request. Wrap this
+ // so that it can be handled better by the error dispatcher.
+ throw new ClientAbortException(e);
+ }
+ }
+
+ }
+
+
+ public void write(byte b[], int off, int len) throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ writeBytes(b, off, len);
+
+ }
+
+
+ private void writeBytes(byte b[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return;
+
+ bb.append(b, off, len);
+ bytesWritten += len;
+
+ // if called from within flush(), then immediately flush
+ // remaining bytes
+ if (doFlush) {
+ bb.flushBuffer();
+ }
+
+ }
+
+
+ public void writeByte(int b)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ bb.append( (byte)b );
+ bytesWritten++;
+
+ }
+
+
+ // ------------------------------------------------- Chars Handling Methods
+
+
+ public void write(int c)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ cb.append((char) c);
+ charsWritten++;
+
+ }
+
+
+ public void write(char c[])
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ write(c, 0, c.length);
+
+ }
+
+
+ public void write(char c[], int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ cb.append(c, off, len);
+ charsWritten += len;
+
+ }
+
+
+ public void write(StringBuffer sb)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ int len = sb.length();
+ charsWritten += len;
+ cb.append(sb);
+
+ }
+
+
+ /**
+ * Append a string to the buffer
+ */
+ public void write(String s, int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state=CHAR_STATE;
+
+ charsWritten += len;
+ if (s==null)
+ s="null";
+ cb.append( s, off, len );
+
+ }
+
+
+ public void write(String s)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+ if (s==null)
+ s="null";
+ write(s, 0, s.length());
+
+ }
+
+ public void println() throws IOException {
+ write("\n");
+ }
+
+ public void println(String s) throws IOException {
+ write(s);
+ write("\n");
+ }
+
+ public void print(String s) throws IOException {
+ write(s);
+ }
+
+ public void flushChars()
+ throws IOException {
+
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ }
+
+
+ public boolean flushCharsNeeded() {
+ return state == CHAR_STATE;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+
+ private void realWriteChars(char c[], int off, int len)
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ conv.convert(c, off, len);
+ conv.flushBuffer(); // ???
+
+ }
+
+
+ public void checkConverter()
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ }
+
+
+ protected void setConverter()
+ throws IOException {
+
+ enc = res.getCharacterEncoding();
+
+ gotEnc = true;
+ if (enc == null)
+ enc = DEFAULT_ENCODING;
+ conv = (C2BConverter) encoders.get(enc);
+ if (conv == null) {
+
+ if (System.getSecurityManager() != null){
+ try{
+ conv = (C2BConverter)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ return new C2BConverter(bb, enc);
+ }
+
+ }
+ );
+ }catch(PrivilegedActionException ex){
+ Exception e = ex.getException();
+ if (e instanceof IOException)
+ throw (IOException)e;
+ }
+ } else {
+ conv = new C2BConverter(bb, enc);
+ }
+
+ encoders.put(enc, conv);
+
+ }
+ }
+
+
+ // -------------------- BufferedOutputStream compatibility
+
+
+ /**
+ * Real write - this buffer will be sent to the client
+ */
+ public void flushBytes()
+ throws IOException {
+
+ bb.flushBuffer();
+
+ }
+
+
+ public int getBytesWritten() {
+ return bytesWritten;
+ }
+
+
+ public int getCharsWritten() {
+ return charsWritten;
+ }
+
+
+ public int getContentWritten() {
+ return bytesWritten + charsWritten;
+ }
+
+
+ /**
+ * True if this buffer hasn't been used ( since recycle() ) -
+ * i.e. no chars or bytes have been added to the buffer.
+ */
+ public boolean isNew() {
+ return (bytesWritten == 0) && (charsWritten == 0);
+ }
+
+
+ public void setBufferSize(int size) {
+ if (size > bb.getLimit()) {// ??????
+ bb.setLimit(size);
+ }
+ }
+
+
+ public void reset() {
+
+ //count=0;
+ bb.recycle();
+ bytesWritten = 0;
+ cb.recycle();
+ charsWritten = 0;
+ gotEnc = false;
+ enc = null;
+ state = BYTE_STATE;
+ }
+
+
+ public int getBufferSize() {
+ return bb.getLimit();
+ }
+
+ public ByteChunk getByteBuffer() {
+ return outputChunk;
+ }
+
+}
+//{
+// public abstract int getBytesWritten();
+// public abstract int getCharsWritten();
+// public abstract void recycle();
+// public abstract void setSuspended(boolean suspended);
+// public abstract boolean isSuspended();
+//
+// public abstract void reset();
+// public abstract int getBufferSize();
+// public abstract void setBufferSize(int n);
+// public abstract void checkConverter() throws IOException;
+// public boolean isNew() {
+// return getBytesWritten() == 0 && getCharsWritten() == 0;
+// }
+// public abstract void write(byte[] b, int off, int len) throws IOException;
+// public abstract void writeByte(int b) throws IOException;
+//
+//}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite;
+
+import java.io.IOException;
+
+/**
+ * Wrap an IOException identifying it as being caused by an abort
+ * of a request by a remote client.
+ *
+ * @author Glenn L. Nielsen
+ * @version $Revision: 304063 $ $Date: 2005-08-18 06:25:18 -0700 (Thu, 18 Aug 2005) $
+ */
+
+public final class ClientAbortException extends IOException {
+
+
+ //------------------------------------------------------------ Constructors
+
+
+ /**
+ * Construct a new ClientAbortException with no other information.
+ */
+ public ClientAbortException() {
+
+ this(null, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message.
+ *
+ * @param message Message describing this exception
+ */
+ public ClientAbortException(String message) {
+
+ this(message, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified throwable.
+ *
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(Throwable throwable) {
+
+ this(null, throwable);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message
+ * and throwable.
+ *
+ * @param message Message describing this exception
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(String message, Throwable throwable) {
+
+ super();
+ this.message = message;
+ this.throwable = throwable;
+
+ }
+
+
+ //------------------------------------------------------ Instance Variables
+
+
+ /**
+ * The error message passed to our constructor (if any)
+ */
+ protected String message = null;
+
+
+ /**
+ * The underlying exception or error passed to our constructor (if any)
+ */
+ protected Throwable throwable = null;
+
+
+ //---------------------------------------------------------- Public Methods
+
+
+ /**
+ * Returns the message associated with this exception, if any.
+ */
+ public String getMessage() {
+
+ return (message);
+
+ }
+
+
+ /**
+ * Returns the cause that caused this exception, if any.
+ */
+ public Throwable getCause() {
+
+ return (throwable);
+
+ }
+
+
+ /**
+ * Return a formatted string that describes this exception.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("ClientAbortException: ");
+ if (message != null) {
+ sb.append(message);
+ if (throwable != null) {
+ sb.append(": ");
+ }
+ }
+ if (throwable != null) {
+ sb.append(throwable.toString());
+ }
+ return (sb.toString());
+
+ }
+
+
+}
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.integration.ObjectManager;
+import org.apache.tomcat.util.buf.ByteChunk;
/**
* What we need to plugin a connector.
public void setDaemon(boolean b);
- public void start();
+ public void start() throws IOException;
- public void stop();
+ public void stop() throws Exception;
- public void finishResponse(HttpServletResponse res) throws IOException;
+ /**
+ * Called during close() - either on explicit output close, or
+ * after the request is completed.
+ *
+ * @throws IOException
+ */
+ public abstract void finishResponse(HttpServletResponse res) throws IOException;
+
+ /**
+ * Called before flushing the output during close.
+ * Content-Length may be updated.
+ * @param len
+ *
+ * @throws IOException
+ */
+ public abstract void beforeClose(HttpServletResponse res, int len) throws IOException;
+
+ /**
+ * Called when the first flush() is called.
+ * @throws IOException
+ */
+ public abstract void sendHeaders(HttpServletResponse res) throws IOException;
+
+ /**
+ * Send data to the client.
+ * @throws IOException
+ */
+ public abstract void realFlush(HttpServletResponse res) throws IOException;
+
+ /**
+ * Write to the connector underlying buffer.
+ * The chunk will be reused (currently).
+ */
+ public abstract void doWrite(HttpServletResponse res, ByteChunk outputChunk2) throws IOException;
+
+
+ //public void finishResponse(HttpServletResponse res) throws IOException;
+
+ public void acknowledge(HttpServletResponse res) throws IOException;
+
+ public void reset(HttpServletResponse res);
public void recycle(HttpServletRequest req, HttpServletResponse res);
public void setTomcatLite(TomcatLite tomcatLite);
public void setObjectManager(ObjectManager objectManager);
+
+ public String getRemoteHost(HttpServletRequest req);
+
+ public String getRemoteAddr(HttpServletRequest req);
+
+ public int doRead(ServletRequestImpl coyoteRequest, ByteChunk bb) throws IOException;
}
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
+import javax.servlet.FilterRegistration.Dynamic;
import org.apache.tomcat.addons.UserSessionManager;
import org.apache.tomcat.integration.ObjectManager;
public void processWebAppData(ServletContextConfig d) throws ServletException {
this.contextConfig = d;
- Iterator i1 = d.mimeMapping.entrySet().iterator();
- while (i1.hasNext()) {
- Entry k = (Entry)i1.next();
- addMimeType((String)k.getKey(), (String)k.getValue());
+ for (String k: d.mimeMapping.keySet()) {
+ addMimeType(k, d.mimeMapping.get(k));
}
String[] wFiles = (String[])d.welcomeFileList.toArray(new String[0]);
addServletConfig(sw);
}
- Iterator i4 = d.servletMapping.entrySet().iterator();
- while (i4.hasNext()) {
- Entry/*<String, String>*/ k = (Entry) i4.next();
- addMapping((String) k.getKey(), (String) k.getValue());
+ for (String k: d.servletMapping.keySet()) {
+ addMapping(k, d.servletMapping.get(k));
}
Iterator i5 = d.filterMappings.iterator();
addServletConfig(sc);
}
- public void addServlet(String servletName, Servlet servlet) {
+ public javax.servlet.Registration.Dynamic addServlet(String servletName, Servlet servlet) {
ServletConfigImpl sc = new ServletConfigImpl(this, servletName, null);
sc.setServlet(servlet);
addServletConfig(sc);
+ return null;
}
public void addServletSec(String serlvetName, String runAs, Map roles) {
}
@Override
- public void addFilter(String filterName, String description, String className,
- Map<String, String> initParameters,
- boolean isAsyncSupported) {
+ public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ return null;
}
@Override
- public void addFilterMappingForServletNames(
- String filterName,
- EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... servletNames) {
+ public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ return null;
}
@Override
- public void addFilterMappingForUrlPatterns(
- String filterName,
- EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... urlPatterns) {
+ public SessionCookieConfig getSessionCookieConfig() {
+ return null;
}
@Override
- public void addServletMapping(String servletName, String[] urlPatterns) {
+ public void setSessionTrackingModes(EnumSet<SessionTrackingMode> sessionTrackingModes) {
}
@Override
- public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ public Dynamic addFilter(String filterName, String className) {
return null;
}
@Override
- public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ public Dynamic addFilter(String filterName, Filter filter) {
return null;
}
@Override
- public SessionCookieConfig getSessionCookieConfig() {
+ public Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
return null;
}
@Override
- public void setSessionCookieConfig(SessionCookieConfig sessionCookieConfig) {
+ public javax.servlet.Registration.Dynamic addServlet(String servletName,
+ String className) {
+ return null;
}
@Override
- public void setSessionTrackingModes(
- EnumSet<SessionTrackingMode> sessionTrackingModes) {
+ public javax.servlet.Registration.Dynamic addServlet(
+ String servletName,
+ Class<? extends Servlet> servletClass) {
+ return null;
+ }
+
+ @Override
+ public <T extends Filter> T createFilter(Class<T> c) throws ServletException {
+ return null;
}
+ @Override
+ public <T extends Servlet> T createServlet(Class<T> c) throws ServletException {
+ return null;
+ }
+
+ @Override
+ public FilterRegistration findFilterRegistration(String filterName) {
+ return null;
+ }
+
+ @Override
+ public ServletRegistration findServletRegistration(String servletName) {
+ return null;
+ }
+
+ @Override
+ public boolean setInitParameter(String name, String value) {
+ return false;
+ }
}
import javax.servlet.ServletOutputStream;
-import org.apache.tomcat.lite.coyote.MessageWriter;
/**
* Coyote implementation of the servlet output stream.
// ----------------------------------------------------- Instance Variables
- protected MessageWriter ob;
+ protected BodyWriter ob;
// ----------------------------------------------------------- Constructors
- public ServletOutputStreamImpl(MessageWriter ob) {
+ public ServletOutputStreamImpl(BodyWriter ob) {
this.ob = ob;
}
import javax.security.auth.Subject;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncListener;
+import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.Request;
import org.apache.tomcat.addons.UserSessionManager;
-import org.apache.tomcat.lite.coyote.MessageReader;
import org.apache.tomcat.servlets.util.Enumerator;
import org.apache.tomcat.servlets.util.LocaleParser;
import org.apache.tomcat.servlets.util.RequestUtil;
import org.apache.tomcat.util.buf.UriNormalizer;
import org.apache.tomcat.util.http.Cookies;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.HttpRequest;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.mapper.MappingData;
/**
+ *
* Wrapper object for the Coyote request.
*
* @author Remy Maucherat
* @author Craig R. McClanahan
- * @version $Revision$ $Date$
*/
-
public class ServletRequestImpl implements HttpServletRequest {
/**
/**
* The associated input buffer.
*/
- protected MessageReader inputBuffer = new MessageReader();
+ protected BodyReader inputBuffer;
+ Connector connector;
/**
* ServletInputStream.
*/
- protected ServletInputStreamImpl inputStream =
- new ServletInputStreamImpl(inputBuffer.asInputStream());
+ protected ServletInputStreamImpl inputStream;
/**
* Reader.
*/
- protected BufferedReader reader = new ServletReaderImpl(inputBuffer);
-
+ protected BufferedReader reader;
+
/**
* Using stream flag.
public byte[] postData = null;
- private Request coyoteRequest;
+ private HttpRequest httpRequest;
/** New IO/buffer model
*/
// Not used
}
+ public void setConnector(Connector c) {
+ connector = c;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
/**
* Add a Locale to the set of preferred Locales for this Request. The
* @param values Corresponding values for this request parameter
*/
public void addParameter(String name, String values[]) {
- coyoteRequest.getParameters().addParameterValues(name, values);
+ httpRequest.getParameters().addParameterValues(name, values);
}
/**
* Return the character encoding for this Request.
*/
public String getCharacterEncoding() {
- return (coyoteRequest.getCharacterEncoding());
+ return (httpRequest.getCharacterEncoding());
}
* Return the content length for this Request.
*/
public int getContentLength() {
- return (coyoteRequest.getContentLength());
+ return (httpRequest.getContentLength());
}
* Return the content type for this Request.
*/
public String getContentType() {
- return (coyoteRequest.getContentType());
+ return (httpRequest.getContentType());
}
* @return the URL decoded request URI
*/
public String getDecodedRequestURI() {
- return (coyoteRequest.decodedURI().toString());
+ return (httpRequest.decodedURI().toString());
}
* @return the URL decoded request URI
*/
public MessageBytes getDecodedRequestURIMB() {
- return (coyoteRequest.decodedURI());
+ return (httpRequest.decodedURI());
}
* @param name Name of the requested header
*/
public String getHeader(String name) {
- return coyoteRequest.getHeader(name);
+ return httpRequest.getHeader(name);
}
/**
* Return the names of all headers received with this request.
*/
public Enumeration getHeaderNames() {
- return coyoteRequest.getMimeHeaders().names();
+ return httpRequest.getMimeHeaders().names();
}
* @param name Name of the requested header
*/
public Enumeration getHeaders(String name) {
- return coyoteRequest.getMimeHeaders().values(name);
+ return httpRequest.getMimeHeaders().values(name);
}
/**
* which the request was received.
*/
public String getLocalAddr(){
- return coyoteRequest.localAddr().toString();
+ return httpRequest.localAddr().toString();
}
* which the request was received.
*/
public String getLocalName(){
- return coyoteRequest.localName().toString();
+ return httpRequest.localName().toString();
}
* on which the request was received.
*/
public int getLocalPort(){
- return coyoteRequest.getLocalPort();
+ return httpRequest.getLocalPort();
}
* Return the HTTP request method used in this Request.
*/
public String getMethod() {
- return coyoteRequest.method().toString();
+ return httpRequest.method().toString();
}
if (!parametersParsed)
parseParameters();
- return coyoteRequest.getParameters().getParameter(name);
+ return httpRequest.getParameters().getParameter(name);
}
if (!parametersParsed)
parseParameters();
- return coyoteRequest.getParameters().getParameterNames();
+ return httpRequest.getParameters().getParameterNames();
}
if (!parametersParsed)
parseParameters();
- return coyoteRequest.getParameters().getParameterValues(name);
+ return httpRequest.getParameters().getParameterValues(name);
}
* Return the protocol and version used to make this Request.
*/
public String getProtocol() {
- return coyoteRequest.protocol().toString();
+ return httpRequest.protocol().toString();
}
/**
* Return the query string associated with this request.
*/
public String getQueryString() {
- String queryString = coyoteRequest.queryString().toString();
+ String queryString = httpRequest.queryString().toString();
if (queryString == null || queryString.equals("")) {
return (null);
} else {
* Return the remote IP address making this Request.
*/
public String getRemoteAddr() {
- if (coyoteRequest.remoteAddr().isNull()) {
- coyoteRequest.action(ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, coyoteRequest);
+ if (httpRequest.remoteAddr().isNull()) {
+ httpRequest.remoteAddr().setString(connector.getRemoteAddr(this));
}
- return coyoteRequest.remoteAddr().toString();
+ return httpRequest.remoteAddr().toString();
}
* Return the remote host name making this Request.
*/
public String getRemoteHost() {
- if (coyoteRequest.remoteHost().isNull()) {
- coyoteRequest.action(ActionCode.ACTION_REQ_HOST_ATTRIBUTE, coyoteRequest);
+ if (httpRequest.remoteHost().isNull()) {
+ httpRequest.remoteHost().setString(connector.getRemoteHost(this));
}
- return coyoteRequest.remoteHost().toString();
+ return httpRequest.remoteHost().toString();
}
* or last proxy that sent the request.
*/
public int getRemotePort(){
- return coyoteRequest.getRemotePort();
+ return httpRequest.getRemotePort();
}
return this;
}
- public Request getCoyoteRequest() {
- return coyoteRequest;
+ public HttpRequest getHttpRequest() {
+ return httpRequest;
}
- public void setCoyoteRequest(Request req) {
- this.coyoteRequest = req;
- inputBuffer.setRequest(req);
+ public void setHttpRequest(HttpRequest req, BodyReader in) {
+ this.httpRequest = req;
+ inputBuffer = in;
+ inputStream = new ServletInputStreamImpl(inputBuffer.asInputStream());
+ reader = new ServletReaderImpl(inputBuffer);
}
+ public BodyReader getBodyReader() {
+ return inputBuffer;
+ }
/**
* Return a RequestDispatcher that wraps the resource at the specified
* Return the request URI for this request.
*/
public String getRequestURI() {
- return coyoteRequest.requestURI().toString();
+ return httpRequest.requestURI().toString();
}
/**
*/
public void setRequestURI(String uri) {
- coyoteRequest.decodedURI().setString(uri);
+ httpRequest.decodedURI().setString(uri);
try {
- UriNormalizer.decodeRequest(coyoteRequest.decodedURI(),
- coyoteRequest.requestURI(), coyoteRequest.getURLDecoder());
+ UriNormalizer.decodeRequest(httpRequest.decodedURI(),
+ httpRequest.requestURI(), httpRequest.getURLDecoder());
} catch(IOException ioe) {
ioe.printStackTrace();
return;
* Return the scheme used to make this Request.
*/
public String getScheme() {
- String scheme = coyoteRequest.scheme().toString();
+ String scheme = httpRequest.scheme().toString();
if (scheme == null) {
scheme = (isSecure() ? "https" : "http");
}
* Return the server name responding to this Request.
*/
public String getServerName() {
- return (coyoteRequest.serverName().toString());
+ return (httpRequest.serverName().toString());
}
* Return the server port responding to this Request.
*/
public int getServerPort() {
- return (coyoteRequest.getServerPort());
+ return (httpRequest.getServerPort());
}
parameterMap.clear();
mappingData.recycle();
-
+ httpRequest.recycle();
}
String dummy = new String(buffer, enc);
// Save the validated encoding
- coyoteRequest.setCharacterEncoding(enc);
+ httpRequest.setCharacterEncoding(enc);
}
* @param method The request method
*/
public void setMethod(String method) {
- coyoteRequest.method().setString(method);
+ httpRequest.method().setString(method);
}
* @param name The server name
*/
public void setServerName(String name) {
- coyoteRequest.serverName().setString(name);
+ httpRequest.serverName().setString(name);
}
* @param port The server port
*/
public void setServerPort(int port) {
- coyoteRequest.setServerPort(port);
+ httpRequest.setServerPort(port);
}
public String toString() {
- return coyoteRequest.requestURI().toString();
+ return httpRequest.requestURI().toString();
}
cookiesParsed = true;
- Cookies serverCookies = coyoteRequest.getCookies();
+ Cookies serverCookies = httpRequest.getCookies();
int count = serverCookies.getCookieCount();
if (count <= 0)
return;
parametersParsed = true;
- Parameters parameters = coyoteRequest.getParameters();
+ Parameters parameters = httpRequest.getParameters();
// getCharacterEncoding() may have been overridden to search for
// hidden form field containing request encoding
String sessionCookieName = context.getSessionCookieName();
// Parse session id from cookies
- Cookies serverCookies = coyoteRequest.getCookies();
+ Cookies serverCookies = httpRequest.getCookies();
int count = serverCookies.getCookieCount();
if (count <= 0)
return;
* Parse session id in URL.
*/
protected void parseSessionId() {
- Request req = coyoteRequest;
ServletRequestImpl request = this;
- ByteChunk uriBC = req.requestURI().getByteChunk();
+ ByteChunk uriBC = httpRequest.requestURI().getByteChunk();
int semicolon = uriBC.indexOf(match, 0, match.length(), 0);
if (semicolon > 0) {
}
+ @Override
+ public boolean authenticate(HttpServletResponse response)
+ throws IOException, ServletException {
+ return false;
+ }
+
+
+ @Override
+ public Part getPart(String name) {
+ return null;
+ }
+
+
+ @Override
+ public Iterable<Part> getParts() {
+ return null;
+ }
+
+
+ @Override
+ public void login(String username, String password) throws ServletException {
+ }
+
+
+ @Override
+ public void logout() throws ServletException {
+ }
+
+
+ @Override
+ public long getAsyncTimeout() {
+ return 0;
+ }
+
+
+ @Override
+ public DispatcherType getDispatcherType() {
+ return null;
+ }
+
+
}
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
+ * ontentLicensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.apache.coyote.Response;
-import org.apache.tomcat.lite.coyote.MessageWriter;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UEncoder;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.HttpResponse;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.ServerCookie;
"EEE, dd MMM yyyy HH:mm:ss zzz";
// ----------------------------------------------------------- Constructors
-
- private Response resB;
+
ServletResponseImpl() {
urlEncoder.addSafeCharacter('/');
}
- // ----------------------------------------------------- Class Variables
-
-
- /**
- * Descriptive information about this Response implementation.
- */
- protected static final String info =
- "org.apache.tomcat.lite/1.0";
-
-
- // ----------------------------------------------------- Instance Variables
-
/**
* The date format we will use for creating date headers.
*/
protected SimpleDateFormat format = null;
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Set the Connector through which this Request was received.
- *
- * @param connector The new connector
- */
- public void setConnector() {
- // default size to size of one ajp-packet
- outputBuffer = MessageWriter.getWriter(req.getCoyoteRequest(), getCoyoteResponse(), 4096);
- outputStream = new ServletOutputStreamImpl(outputBuffer);
- }
-
- /**
- * Coyote response.
- */
- //protected org.apache.coyote.Response coyoteResponse;
-
-
/**
* The associated output buffer.
*/
- protected MessageWriter outputBuffer;
+ protected BodyWriter outputBuffer;
/**
/**
+ * The request with which this response is associated.
+ */
+ protected ServletRequestImpl req = null;
+
+ /**
* URL encoder.
*/
protected UEncoder urlEncoder = new UEncoder();
protected CharChunk redirectURLCC = new CharChunk(1024);
+ private HttpResponse resB;
+
+
+ // Cached/derived information - reflected in headers
+ protected static Locale DEFAULT_LOCALE = Locale.getDefault();
+
+ public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";
+
+ protected Locale locale = DEFAULT_LOCALE;
+
+ // XXX
+ protected boolean commited = false;
+ protected String contentType = null;
+
+ /**
+ * Has the charset been explicitly set.
+ */
+ protected boolean charsetSet = false;
+ protected String characterEncoding = DEFAULT_CHARACTER_ENCODING;
+
+
// --------------------------------------------------------- Public Methods
*/
public void recycle() {
- outputBuffer.recycle();
usingOutputStream = false;
usingWriter = false;
appCommitted = false;
+ commited = false;
included = false;
error = false;
isCharacterEncodingSet = false;
cookies.clear();
outputBuffer.recycle();
-
+
+ resB.recycle();
}
* Return the number of bytes actually written to the output stream.
*/
public int getContentCount() {
- return outputBuffer.getContentWritten();
+ return outputBuffer.getBytesWritten() + outputBuffer.getCharsWritten();
}
*/
public boolean isAppCommitted() {
return (this.appCommitted || isCommitted() || isSuspended()
- || ((getContentLength() > 0)
- && (getContentCount() >= getContentLength())));
+ || ((getHttpResponse().getContentLength() > 0)
+ && (getContentCount() >= getHttpResponse().getContentLength())));
}
/**
- * Return descriptive information about this Response implementation and
- * the corresponding version number, in the format
- * <code><description>/<version></code>.
- */
- public String getInfo() {
- return (info);
- }
-
-
- /**
- * The request with which this response is associated.
- */
- protected ServletRequestImpl req = null;
-
- /**
* Return the Request with which this Response is associated.
*/
public ServletRequestImpl getRequest() {
* Return the output stream associated with this Response.
*/
public OutputStream getStream() {
- if (outputStream == null) {
- outputStream = new ServletOutputStreamImpl(outputBuffer);
- }
return outputStream;
}
public ServletOutputStream createOutputStream()
throws IOException {
// Probably useless
- if (outputStream == null) {
- outputStream = new ServletOutputStreamImpl(outputBuffer);
- }
return outputStream;
}
-
- /**
- * Return the content length that was set or calculated for this Response.
- */
- public int getContentLength() {
- return getCoyoteResponse().getContentLength();
- }
-
-
/**
* Return the content type that was set or calculated for this response,
* or <code>null</code> if no content type was set.
*/
public String getContentType() {
- return getCoyoteResponse().getContentType();
+ String ret = contentType;
+
+ if (ret != null
+ && characterEncoding != null
+ && charsetSet) {
+ ret = ret + ";charset=" + characterEncoding;
+ }
+
+ return ret;
}
* Return the character encoding used for this Response.
*/
public String getCharacterEncoding() {
- return (getCoyoteResponse().getCharacterEncoding());
+ return characterEncoding;
}
("usingWriter");
usingOutputStream = true;
- if (outputStream == null) {
- outputStream = new ServletOutputStreamImpl(outputBuffer);
- }
return outputStream;
}
+ public BodyWriter getBodyWriter() {
+ return outputBuffer;
+ }
/**
* Return the Locale assigned to this response.
*/
public Locale getLocale() {
- return (getCoyoteResponse().getLocale());
+ return locale;
}
* Has the output of this response already been committed?
*/
public boolean isCommitted() {
- return (getCoyoteResponse().isCommitted());
+ return getHttpResponse().isCommitted();
}
-
/**
* Clear any content written to the buffer.
*
if (included)
return; // Ignore any call from an included servlet
- getCoyoteResponse().reset();
- //req.con.reset();
+ if (isCommitted())
+ throw new IllegalStateException("isCommitted");
+
+ resB.recycle(); // reset headers, status code, message
+ req.getConnector().reset(this);
+ contentType = null;
+ locale = DEFAULT_LOCALE;
+ characterEncoding = DEFAULT_CHARACTER_ENCODING;
+ charsetSet = false;
+
outputBuffer.reset();
}
if (usingWriter && !"ISO-8859-1".equals(getCharacterEncoding())) {
return;
}
- getCoyoteResponse().setContentLength(length);
+ getHttpResponse().setContentLength(length);
}
}
}
- getCoyoteResponse().setContentType(type);
+ getHttpResponse().setContentType(type);
// Check to see if content type contains charset
if (type != null) {
if (usingWriter)
return;
- getCoyoteResponse().setCharacterEncoding(charset);
+ if (isCommitted())
+ return;
+ if (charset == null)
+ return;
+
+ characterEncoding = charset;
+ charsetSet=true;
isCharacterEncodingSet = true;
}
if (included)
return;
- getCoyoteResponse().setLocale(locale);
+ if (locale == null) {
+ return; // throw an exception?
+ }
+
+ // Save the locale for use by getLocale()
+ this.locale = locale;
+
+ // Set the contentLanguage for header output
+ String contentLanguage = locale.getLanguage();
+ if ((contentLanguage != null) && (contentLanguage.length() > 0)) {
+ String country = locale.getCountry();
+ StringBuffer value = new StringBuffer(contentLanguage);
+ if ((country != null) && (country.length() > 0)) {
+ value.append('-');
+ value.append(country);
+ }
+ contentLanguage = value.toString();
+ }
+ resB.setHeader("Content-Language", contentLanguage);
// Ignore any call made after the getWriter has been invoked.
// The default should be used
Locale2Charset cm = req.getContext().getCharsetMapper();
String charset = cm.getCharset( locale );
if ( charset != null ){
- getCoyoteResponse().setCharacterEncoding(charset);
+ setCharacterEncoding(charset);
}
}
* @param name Header name to look up
*/
public String getHeader(String name) {
- return getCoyoteResponse().getMimeHeaders().getHeader(name);
+ return getHttpResponse().getMimeHeaders().getHeader(name);
}
* Return an array of all the header names set for this response, or
* a zero-length array if no headers have been set.
*/
- public String[] getHeaderNames() {
+ public Iterable<String> getHeaderNames() {
- MimeHeaders headers = getCoyoteResponse().getMimeHeaders();
+ MimeHeaders headers = getHttpResponse().getMimeHeaders();
int n = headers.size();
- String[] result = new String[n];
+ ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i < n; i++) {
- result[i] = headers.getName(i).toString();
+ result.add(headers.getName(i).toString());
}
return result;
-
}
*/
public String[] getHeaderValues(String name) {
- Enumeration enumeration = getCoyoteResponse().getMimeHeaders().values(name);
+ Enumeration enumeration = getHttpResponse().getMimeHeaders().values(name);
Vector result = new Vector();
while (enumeration.hasMoreElements()) {
result.addElement(enumeration.nextElement());
* for this Response.
*/
public String getMessage() {
- return getCoyoteResponse().getMessage();
+ return getHttpResponse().getMessage();
}
* Return the HTTP status code associated with this Response.
*/
public int getStatus() {
- return getCoyoteResponse().getStatus();
+ return getHttpResponse().getStatus();
}
if (included)
return;
- getCoyoteResponse().addHeader(name, value);
+ getHttpResponse().addHeader(name, value);
}
if(cc=='C' || cc=='c') {
if(name.equalsIgnoreCase("Content-Type")) {
// Will return null if this has not been set
- return (getCoyoteResponse().getContentType() != null);
+ return getContentType() != null;
}
if(name.equalsIgnoreCase("Content-Length")) {
// -1 means not known and is not sent to client
- return (getCoyoteResponse().getContentLengthLong() != -1);
+ return (getHttpResponse().getContentLength() != -1);
}
}
- return getCoyoteResponse().containsHeader(name);
+ return getHttpResponse().containsHeader(name);
}
if (included)
return;
- getCoyoteResponse().acknowledge();
-
+ req.getConnector().acknowledge(this);
}
setError();
- getCoyoteResponse().setStatus(status);
- getCoyoteResponse().setMessage(message);
+ getHttpResponse().setStatus(status);
+ getHttpResponse().setMessage(message);
// Clear any data content that has been buffered
resetBuffer();
if (included)
return;
- getCoyoteResponse().setHeader(name, value);
+ getHttpResponse().setHeader(name, value);
}
if (included)
return;
- getCoyoteResponse().setStatus(status);
- getCoyoteResponse().setMessage(message);
+ getHttpResponse().setStatus(status);
+ getHttpResponse().setMessage(message);
}
return outputBuffer.getBytesWritten();
}
- public MessageWriter getOutputBuffer() {
+ public BodyWriter getOutputBuffer() {
return outputBuffer;
}
+
+ public void setWriter(BodyWriter ob) {
+ outputBuffer = ob;
+ outputStream = new ServletOutputStreamImpl(outputBuffer);
+ }
public CharSequence getResponseHeader(String name) {
- MessageBytes v = getCoyoteResponse().getMimeHeaders().getValue(name);
+ MessageBytes v = getHttpResponse().getMimeHeaders().getValue(name);
return (v == null) ? null : v.toString();
}
- public Response getCoyoteResponse() {
+ public HttpResponse getHttpResponse() {
return resB;
}
- public void setCoyoteResponse(Response resB) {
+ public void setHttpResponse(HttpResponse resB, BodyWriter ob) {
this.resB = resB;
+ setWriter(ob);
+ }
+
+
+ @Override
+ public Iterable<String> getHeaders(String name) {
+ return null;
}
Map<String,String> ctxDefaultInitParam = new HashMap();
- Connector coyoteAdapter;
+ Connector connector;
ObjectManager om;
}
// --------------- start/stop ---------------
-
+
+ public static ObjectManager defaultObjectManager() {
+ SimpleObjectManager cfg = new SimpleObjectManager();
+ cfg.loadResource("org/apache/tomcat/lite/config.properties");
+ return cfg;
+ }
/**
* Return the object manager associated with this tomcat.
* If none set, create a minimal one with the default
*/
public ObjectManager getObjectManager() {
if (om == null) {
- // Defaults.
- om = new ObjectManager();
- SimpleObjectManager props = new SimpleObjectManager(om);
- // Init defaults. If using a custom OM, you should register
- // at the default objects as well.
- props.loadResource("org/apache/tomcat/lite/config.properties");
+ om = defaultObjectManager();
}
return om;
}
e.printStackTrace();
}
}
- stopConnector();
+ try {
+ stopConnector();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
// -------------- Context add/remove --------------
req.parseSessionId();
try {
- UriNormalizer.decodeRequest(req.getCoyoteRequest().decodedURI(),
- req.getCoyoteRequest().requestURI(),
- req.getCoyoteRequest().getURLDecoder());
+ UriNormalizer.decodeRequest(req.getHttpRequest().decodedURI(),
+ req.getHttpRequest().requestURI(),
+ req.getHttpRequest().getURLDecoder());
} catch(IOException ioe) {
res.setStatus(400);
return;
Thread.currentThread().setContextClassLoader(ctx.getClassLoader());
WebappServletMapper mapper = ctx.getMapper();
- mapper.map(req.getCoyoteRequest().decodedURI(), mapRes);
+ mapper.map(req.getHttpRequest().decodedURI(), mapRes);
// Possible redirect
MessageBytes redirectPathMB = mapRes.redirectPath;
getConnector().initRequest(req, res);
- req.getCoyoteRequest().method().setString("GET");
- req.getCoyoteRequest().protocol().setString("HTTP/1.1");
+ req.getHttpRequest().method().setString("GET");
+ req.getHttpRequest().protocol().setString("HTTP/1.1");
return req;
}
public void endRequest(ServletRequestImpl req,
ServletResponseImpl res) throws IOException {
res.outputBuffer.flush();
- res.getCoyoteResponse().finish();
+ req.getConnector().finishResponse(res);
}
public Connector getConnector() {
- if (coyoteAdapter == null) {
- coyoteAdapter = (Connector) getObjectManager().get(Connector.class);
- setConnector(coyoteAdapter);
+ if (connector == null) {
+ connector = (Connector) getObjectManager().get(Connector.class);
+ setConnector(connector);
}
- return coyoteAdapter;
+ return connector;
}
public void setConnector(Connector c) {
- coyoteAdapter = c;
- coyoteAdapter.setTomcatLite(this);
- getObjectManager().bind("Connector", coyoteAdapter);
+ connector = c;
+ connector.setTomcatLite(this);
+ getObjectManager().bind("Connector", connector);
}
public void setDaemon(boolean d) {
getConnector();
- if (coyoteAdapter != null) {
- coyoteAdapter.setDaemon(d);
+ if (connector != null) {
+ connector.setDaemon(d);
}
}
- public void startConnector() {
+ public void startConnector() throws IOException {
getConnector();
- if (coyoteAdapter != null) {
- coyoteAdapter.start();
+ if (connector != null) {
+ connector.start();
}
}
- public void stopConnector() {
- getConnector();
- if (coyoteAdapter != null) {
- coyoteAdapter.stop();
+ public void stopConnector() throws Exception {
+ if (connector != null) {
+ connector.stop();
}
}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.cli;
-
-import org.apache.tomcat.integration.ObjectManager;
-import org.apache.tomcat.integration.jmx.JmxObjectManagerSpi;
-import org.apache.tomcat.integration.simple.SimpleObjectManager;
-import org.apache.tomcat.lite.TomcatLite;
-import org.apache.tomcat.lite.coyote.CoyoteHttp;
-
-/**
- * Run tomcat lite, mostly for demo. In normal use you would
- * embed it in an app, or use a small customized launcher.
- *
- * With no arguments, it'll load only the root context / from
- * ./webapps/ROOT
- *
- * Most configuration can be done using web.xml files, few settings
- * can be set by flags.
- *
- * @author Costin Manolache
- */
-public class Main {
-
- public static void main(String args[])
- throws Exception {
-
- if (args.length == 0) {
- System.err.println("Please specify at least one webapp.");
- System.err.println("Example:");
- System.err.println("-context /:webapps/ROOT -port 9999");
- }
-
- // Enable CLI processing
- SimpleObjectManager.setArgs(args);
-
- TomcatLite lite = new TomcatLite();
- ObjectManager om = lite.getObjectManager();
-
- // add JMX support
- new JmxObjectManagerSpi().register(om);
-
- lite.run();
- }
-}
# If tomcat is used with a proper framework, you need to bind and configure
# those objects in the framework.
+Main.(class)=org.apache.tomcat.lite.TomcatLite
+
+Jmx.(class)=org.apache.tomcat.integration.jmx.JmxObjectManagerSpi
+
# --- Class names for required plugin interfaces ---
org.apache.tomcat.lite.WebappServletMapper.(class)=org.apache.tomcat.lite.WebappServletMapper
# *.jsp support
org.apache.tomcat.addons.UserTemplateClassMapper.(class)=org.apache.tomcat.servlets.jsp.JasperCompilerTemplateClassMapper
+org.apache.tomcat.addons.Filesystem.(class)=org.apache.tomcat.integration.simple.LocalFilesystem
+
# Loader for web.xml - you can have your own custom class using a more efficient
# or hardcoded.
org.apache.tomcat.lite.ContextPreinitListener.(class)=org.apache.tomcat.lite.webxml.TomcatLiteWebXmlConfig
# Connector class
-org.apache.tomcat.lite.Connector.(class)=org.apache.tomcat.lite.coyote.CoyoteHttp
+org.apache.tomcat.lite.Connector.(class)=org.apache.tomcat.lite.coyote.CoyoteConnector
+
+# JMX
+jmx-connector.(class)=org.apache.tomcat.integration.jmx.JmxObjectManagerSpi
# --- Other required settings ---
# Customize default and *.jsp mappings
default-servlet.(class)=org.apache.tomcat.servlets.file.WebdavServlet
jspwildcard-servlet.(class)=org.apache.tomcat.servlets.jsp.WildcardTemplateServlet
+filetemplate-servlet.(class)=org.apache.tomcat.servlets.jsp.JspFileTemplateServlet
+
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-
-/**
- * Wrap an IOException identifying it as being caused by an abort
- * of a request by a remote client.
- *
- * @author Glenn L. Nielsen
- * @version $Revision$ $Date$
- */
-
-public final class ClientAbortException extends IOException {
-
-
- //------------------------------------------------------------ Constructors
-
-
- /**
- * Construct a new ClientAbortException with no other information.
- */
- public ClientAbortException() {
-
- this(null, null);
-
- }
-
-
- /**
- * Construct a new ClientAbortException for the specified message.
- *
- * @param message Message describing this exception
- */
- public ClientAbortException(String message) {
-
- this(message, null);
-
- }
-
-
- /**
- * Construct a new ClientAbortException for the specified throwable.
- *
- * @param throwable Throwable that caused this exception
- */
- public ClientAbortException(Throwable throwable) {
-
- this(null, throwable);
-
- }
-
-
- /**
- * Construct a new ClientAbortException for the specified message
- * and throwable.
- *
- * @param message Message describing this exception
- * @param throwable Throwable that caused this exception
- */
- public ClientAbortException(String message, Throwable throwable) {
-
- super();
- this.message = message;
- this.throwable = throwable;
-
- }
-
-
- //------------------------------------------------------ Instance Variables
-
-
- /**
- * The error message passed to our constructor (if any)
- */
- protected String message = null;
-
-
- /**
- * The underlying exception or error passed to our constructor (if any)
- */
- protected Throwable throwable = null;
-
-
- //---------------------------------------------------------- Public Methods
-
-
- /**
- * Returns the message associated with this exception, if any.
- */
- public String getMessage() {
-
- return (message);
-
- }
-
-
- /**
- * Returns the cause that caused this exception, if any.
- */
- public Throwable getCause() {
-
- return (throwable);
-
- }
-
-
- /**
- * Return a formatted string that describes this exception.
- */
- public String toString() {
-
- StringBuffer sb = new StringBuffer("ClientAbortException: ");
- if (message != null) {
- sb.append(message);
- if (throwable != null) {
- sb.append(": ");
- }
- }
- if (throwable != null) {
- sb.append(throwable.toString());
- }
- return (sb.toString());
-
- }
-
-
-}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.coyote;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.coyote.ActionCode;
+import org.apache.coyote.ActionHook;
+import org.apache.coyote.Adapter;
+import org.apache.coyote.ProtocolHandler;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.coyote.http11.Http11NioProtocol;
+import org.apache.tomcat.integration.ObjectManager;
+import org.apache.tomcat.lite.BodyReader;
+import org.apache.tomcat.lite.BodyWriter;
+import org.apache.tomcat.lite.ClientAbortException;
+import org.apache.tomcat.lite.Connector;
+import org.apache.tomcat.lite.ServletRequestImpl;
+import org.apache.tomcat.lite.ServletResponseImpl;
+import org.apache.tomcat.lite.TomcatLite;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.UriNormalizer;
+import org.apache.tomcat.util.http.HttpRequest;
+import org.apache.tomcat.util.http.HttpResponse;
+import org.apache.tomcat.util.net.SocketStatus;
+
+public class CoyoteConnector implements Adapter, Connector {
+
+ private TomcatLite lite;
+
+ public CoyoteConnector() {
+ }
+
+
+
+ public void acknowledge(HttpServletResponse res) throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+ cres.acknowledge();
+ }
+
+ public void reset(HttpServletResponse res) {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+ cres.reset();
+ }
+
+ public void recycle(HttpServletRequest req, HttpServletResponse res) {
+
+ }
+
+ public static HttpResponse getResponse(final Response cres) {
+ HttpResponse hres = new HttpResponse() {
+ public int getStatus() {
+ return cres.getStatus();
+ }
+ public void setStatus(int i) {
+ super.setStatus(i);
+ cres.setStatus(i);
+ }
+ public void setMessage(String s) {
+ super.setMessage(s);
+ cres.setMessage(s);
+ }
+ public String getMessage() {
+ return cres.getMessage();
+ }
+ public boolean isCommitted() {
+ return cres.isCommitted();
+ }
+
+ public void setCommitted(boolean b) {
+ cres.setCommitted(b);
+ }
+ };
+
+ hres.setMimeHeaders(cres.getMimeHeaders());
+ hres.nativeResponse = cres;
+
+ return hres;
+ }
+
+ public static HttpRequest getRequest(Request req) {
+
+ HttpRequest httpReq = new HttpRequest(req.scheme(),
+ req.method(),
+ req.unparsedURI(),
+ req.protocol(),
+ req.getMimeHeaders(),
+ req.requestURI(),
+ req.decodedURI(),
+ req.query(), req.getParameters(),
+ req.serverName(),
+ req.getCookies()) {
+
+ };
+ httpReq.nativeRequest = req;
+
+ // TODO: anything else computed in coyote ?
+
+ return httpReq;
+ }
+
+ @Override
+ public void initRequest(HttpServletRequest hreq, HttpServletResponse hres) {
+ ServletRequestImpl req = (ServletRequestImpl) hreq;
+ ServletResponseImpl res = (ServletResponseImpl) hres;
+ req.setConnector(this);
+
+ Request creq = new Request();
+ Response cres = new Response();
+ HttpResponse nRes = getResponse(cres);
+
+ BodyWriter out = new BodyWriter(4096);
+ out.setConnector(this, res);
+
+ res.setHttpResponse(nRes, out);
+
+ cres.setRequest(creq);
+ cres.setHook(new ActionHook() {
+ public void action(ActionCode actionCode,
+ Object param) {
+ }
+ });
+
+ BodyReader in = new BodyReader();
+ in.setConnector(this, req);
+ HttpRequest nReq = getRequest(creq);
+ req.setHttpRequest(nReq, in);
+
+ }
+
+
+ // ---- Coyote Adapter interface ---
+
+ @Override
+ public void service(Request creq, Response cres) throws Exception {
+ long t0 = System.currentTimeMillis();
+
+ // compute decodedURI - not done by connector
+ UriNormalizer.decodeRequest(creq.decodedURI(), creq.requestURI(), creq.getURLDecoder());
+
+ // find the facades
+ ServletRequestImpl req = (ServletRequestImpl) creq.getNote(ADAPTER_REQ_NOTE);
+ ServletResponseImpl res = (ServletResponseImpl) cres.getNote(ADAPTER_RES_NOTE);
+
+
+ if (req == null) {
+ req = new ServletRequestImpl();
+ res = req.getResponse();
+
+ BodyReader in = new BodyReader();
+ in.setConnector(this, req);
+
+ HttpRequest nReq = getRequest(creq);
+ nReq.setServerPort(creq.getServerPort());
+ HttpResponse nRes = getResponse(cres);
+
+ req.setHttpRequest(nReq, in);
+ BodyWriter out = new BodyWriter(4096);
+ out.setConnector(this, res);
+
+ res.setHttpResponse(nRes, out);
+
+ creq.setNote(ADAPTER_REQ_NOTE, req);
+ cres.setNote(ADAPTER_RES_NOTE, res);
+
+ }
+ req.setConnector(this);
+
+ try {
+ lite.service(req, res);
+ } catch(IOException ex) {
+ throw ex;
+ } catch( Throwable t ) {
+ t.printStackTrace();
+ } finally {
+ long t1 = System.currentTimeMillis();
+
+// log.info("<<<<<<<< DONE: " + creq.method() + " " +
+// creq.decodedURI() + " " +
+// res.getStatus() + " " +
+// (t1 - t0));
+
+ // Final processing
+ // TODO: only if not commet, this doesn't work with the
+ // other connectors since we don't have the info
+ // TODO: add this note in the nio/apr connectors
+ // TODO: play nice with TomcatLite, other adapters that flush/close
+ if (cres.getNote(COMET_RES_NOTE) == null) {
+
+ if (!res.isCommitted()) {
+ cres.sendHeaders();
+ }
+ res.getOutputBuffer().flush();
+
+ BodyWriter mw = res.getBodyWriter();
+ //MessageWriter.getWriter(creq, cres, 0);
+ mw.flush();
+ mw.recycle();
+
+ BodyReader reader = req.getBodyReader();
+ //getReader(creq);
+ reader.recycle();
+
+ cres.finish();
+
+ creq.recycle();
+ cres.recycle();
+
+ req.recycle();
+ res.recycle();
+ }
+ }
+ }
+
+ @Override
+ public boolean event(Request req, Response res, SocketStatus status)
+ throws Exception {
+ return false;
+ }
+
+
+ public void setTomcatLite(TomcatLite lite) {
+ this.lite = lite;
+ }
+
+
+ public String getRemoteHost(HttpServletRequest hreq) {
+ ServletRequestImpl req = (ServletRequestImpl) hreq;
+
+ Request creq = (Request) req.getHttpRequest().nativeRequest;
+ creq.action(ActionCode.ACTION_REQ_HOST_ATTRIBUTE, creq);
+ return creq.remoteHost().toString();
+ }
+
+ public String getRemoteAddr(HttpServletRequest hreq) {
+ ServletRequestImpl req = (ServletRequestImpl) hreq;
+
+ Request creq = (Request) req.getHttpRequest().nativeRequest;
+ creq.action(ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, creq);
+ return creq.remoteAddr().toString();
+ }
+
+
+ @Override
+ public void beforeClose(HttpServletResponse res, int len) throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+
+ if ((!cres.isCommitted())
+ && (cres.getContentLengthLong() == -1)) {
+ // Flushing the char buffer
+ // If this didn't cause a commit of the response, the final content
+ // length can be calculated
+ if (!cres.isCommitted()) {
+ cres.setContentLength(len);
+ }
+ }
+ }
+
+ public int doRead(ServletRequestImpl hreq, ByteChunk bb) throws IOException {
+ ServletRequestImpl req = (ServletRequestImpl) hreq;
+
+ Request creq = (Request) req.getHttpRequest().nativeRequest;
+ return creq.doRead(bb);
+ }
+
+ @Override
+ public void doWrite(HttpServletResponse res, ByteChunk chunk)
+ throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+ cres.doWrite(chunk);
+
+ }
+
+
+ @Override
+ public void realFlush(HttpServletResponse res) throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+ cres.action(ActionCode.ACTION_CLIENT_FLUSH,
+ cres);
+ // If some exception occurred earlier, or if some IOE occurred
+ // here, notify the servlet with an IOE
+ if (cres.isExceptionPresent()) {
+ throw new ClientAbortException
+ (cres.getErrorException());
+ }
+
+ }
+
+
+ @Override
+ public void sendHeaders(HttpServletResponse res) throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+
+ // This should happen before 'prepareResponse' is called !!
+ // Now update coyote response based on response
+ // don't set charset/locale - they're computed in lite
+ cres.setContentType(res.getContentType());
+ cres.sendHeaders();
+ }
+
+ @Override
+ public void finishResponse(HttpServletResponse res) throws IOException {
+ Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
+ cres.finish();
+ }
+
+ protected int port = 8800;
+ protected boolean daemon = false;
+
+ /**
+ * Note indicating the response is COMET.
+ */
+ public static final int COMET_RES_NOTE = 2;
+ public static final int COMET_REQ_NOTE = 2;
+
+ public static final int ADAPTER_RES_NOTE = 1;
+ public static final int ADAPTER_REQ_NOTE = 1;
+
+ protected ProtocolHandler proto;
+
+ //protected Adapter adapter = new MapperAdapter();
+ protected int maxThreads = 20;
+ boolean started = false;
+ boolean async = false; // use old nio connector
+
+ protected ObjectManager om;
+
+
+ public void setObjectManager(ObjectManager om) {
+ this.om = om;
+ }
+
+ /**
+ * Add an adapter. If more than the 'default' adapter is
+ * added, a MapperAdapter will be inserted.
+ *
+ * @param path Use "/" for the default.
+ * @param adapter
+ */
+// public void addAdapter(String path, Adapter added) {
+// if ("/".equals(path)) {
+// ((MapperAdapter) adapter).setDefaultAdapter(added);
+// } else {
+// ((MapperAdapter) adapter).getMapper().addWrapper(path, added);
+// }
+// }
+
+ /**
+ */
+ public void run() {
+ try {
+ init();
+ start();
+ } catch(IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void setDaemon(boolean b) {
+ daemon = b;
+ }
+
+ protected void initAdapters() {
+ if (proto == null) {
+ addProtocolHandler(port, daemon);
+ }
+ // adapter = ...
+ // Adapter secondaryadapter = ...
+ //registry.registerComponent(secondaryadapter, ":name=adapter", null);
+ }
+
+ public void stop() throws Exception {
+ if (!started) {
+ return;
+ }
+ proto.destroy();
+ started = false;
+ }
+
+// /**
+// * Simple CLI support - arg is a path:className pair.
+// */
+// public void setAdapter(String arg) {
+// String[] pathClass = arg.split(":", 2);
+// try {
+// Class c = Class.forName(pathClass[1]);
+// Adapter a = (Adapter) c.newInstance();
+// addAdapter(pathClass[0],a);
+// } catch (Throwable e) {
+// e.printStackTrace();
+// }
+// }
+
+ public void setConnector(ProtocolHandler h) {
+ this.proto = h;
+ h.setAttribute("port", Integer.toString(port));
+
+ om.bind("ProtocolHandler:" + "ep-" + port, proto);
+ }
+
+ public void addProtocolHandler(int port, boolean daemon) {
+ Http11NioProtocol proto = new Http11NioProtocol();
+ proto.setCompression("on");
+ proto.setCompressionMinSize(32);
+ proto.setPort(port);
+ proto.getEndpoint().setDaemon(daemon);
+ setConnector(proto);
+ setPort(port);
+ setDaemon(daemon);
+ }
+
+ public void addProtocolHandler(ProtocolHandler proto,
+ int port, boolean daemon) {
+ setConnector(proto);
+ setPort(port);
+ setDaemon(daemon);
+ }
+
+ public void setPort(int port) {
+ if (proto != null) {
+ proto.setAttribute("port", Integer.toString(port));
+ }
+ this.port = port;
+ }
+
+
+ public void init() {
+ //JdkLoggerConfig.loadCustom();
+ om.bind("CoyoteConnector:" + "CoyoteConnector-" + port,
+ this);
+ }
+
+
+ public void start() throws IOException {
+ try {
+ if (started) {
+ return;
+ }
+ init();
+ initAdapters();
+
+ // not required - should run fine without a connector.
+ if (proto != null) {
+ proto.setAdapter(this);
+
+ proto.init();
+ proto.start();
+ }
+
+ started = true;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public boolean getStarted() {
+ return started;
+ }
+
+}
+++ /dev/null
-/*
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.ActionHook;
-import org.apache.coyote.Adapter;
-import org.apache.coyote.Request;
-import org.apache.coyote.Response;
-import org.apache.tomcat.integration.ObjectManager;
-import org.apache.tomcat.lite.Connector;
-import org.apache.tomcat.lite.ServletRequestImpl;
-import org.apache.tomcat.lite.ServletResponseImpl;
-import org.apache.tomcat.lite.TomcatLite;
-import org.apache.tomcat.util.net.SocketStatus;
-
-public class CoyoteHttp implements Adapter, Connector {
-
- //private TomcatLite lite;
- CoyoteServer coyote;
- private TomcatLite lite;
-
- public CoyoteHttp() {
- }
-
-
- @Override
- public void finishResponse(HttpServletResponse res) throws IOException {
- ((ServletResponseImpl) res).getCoyoteResponse().finish();
- }
-
-
- public void recycle(HttpServletRequest req, HttpServletResponse res) {
-
- }
-
- public void setPort(int port) {
- if (getConnectors() != null) {
- coyote.setPort(port);
- }
- }
-
- @Override
- public void setDaemon(boolean b) {
- if (getConnectors() != null) {
- coyote.setDaemon(b);
- }
- }
-
-
- @Override
- public void start() {
- if (getConnectors() != null) {
- try {
- coyote.init();
- coyote.start();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
-
-
- @Override
- public void stop() {
- if (coyote != null) {
- try {
- coyote.stop();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
- @Override
- public void initRequest(HttpServletRequest hreq, HttpServletResponse hres) {
- ServletRequestImpl req = (ServletRequestImpl) hreq;
- ServletResponseImpl res = (ServletResponseImpl) hres;
-
- Request creq = new Request();
- res.setCoyoteResponse(new Response());
- res.getCoyoteResponse().setRequest(creq);
- res.getCoyoteResponse().setHook(new ActionHook() {
- public void action(ActionCode actionCode,
- Object param) {
- }
- });
-
- req.setCoyoteRequest(creq);
-
- res.setConnector();
-
- }
-
- // Coyote-specific hooking.
- // This could be moved out to a separate class, TomcatLite can
- // work without it.
- public CoyoteServer getConnectors() {
- if (coyote == null) {
- coyote = new CoyoteServer();
- coyote.addAdapter("/", this);
- }
- return coyote;
- }
-
- public void setConnectors(CoyoteServer server) {
- this.coyote = server;
- coyote.addAdapter("/", this);
- }
-
- @Override
- public void service(Request req, Response res) throws Exception {
- // find the facades
- ServletRequestImpl sreq = (ServletRequestImpl) req.getNote(CoyoteServer.ADAPTER_REQ_NOTE);
- ServletResponseImpl sres = (ServletResponseImpl) res.getNote(CoyoteServer.ADAPTER_RES_NOTE);
- if (sreq == null) {
- sreq = new ServletRequestImpl();
- sres = sreq.getResponse();
-
- sreq.setCoyoteRequest(req);
- sres.setCoyoteResponse(res);
-
- req.setNote(CoyoteServer.ADAPTER_REQ_NOTE, sreq);
- res.setNote(CoyoteServer.ADAPTER_RES_NOTE, sres);
-
- sres.setConnector();
-
- }
-
- lite.service(sreq, sres);
-
- if (res.getNote(CoyoteServer.COMET_RES_NOTE) == null) {
- if (!sres.isCommitted()) {
- res.sendHeaders();
- }
- sres.getOutputBuffer().flush();
- res.finish();
-
- sreq.recycle();
- sres.recycle();
- }
- }
-
- // ---- Coyote ---
-
- @Override
- public boolean event(Request req, Response res, SocketStatus status)
- throws Exception {
- return false;
- }
-
-
- public void setTomcatLite(TomcatLite lite) {
- this.lite = lite;
- }
-
-
- @Override
- public void setObjectManager(ObjectManager objectManager) {
- getConnectors();
- coyote.setObjectManager(objectManager);
- }
-
-
-
-}
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-
-import org.apache.coyote.Adapter;
-import org.apache.coyote.ProtocolHandler;
-import org.apache.coyote.http11.Http11NioProtocol;
-import org.apache.tomcat.integration.ObjectManager;
-
-
-/**
- * Simple example of embeding coyote servlet.
- *
- */
-public class CoyoteServer {
- protected int port = 8800;
- protected boolean daemon = false;
-
- /**
- * Note indicating the response is COMET.
- */
- public static final int COMET_RES_NOTE = 2;
- public static final int COMET_REQ_NOTE = 2;
-
- public static final int ADAPTER_RES_NOTE = 1;
- public static final int ADAPTER_REQ_NOTE = 1;
-
- protected ProtocolHandler proto;
-
- protected Adapter adapter = new MapperAdapter();
- protected int maxThreads = 20;
- boolean started = false;
- boolean async = false; // use old nio connector
-
- protected ObjectManager om;
-
- public CoyoteServer() {
- }
-
- public void setObjectManager(ObjectManager om) {
- this.om = om;
- }
-
- /**
- * Add an adapter. If more than the 'default' adapter is
- * added, a MapperAdapter will be inserted.
- *
- * @param path Use "/" for the default.
- * @param adapter
- */
- public void addAdapter(String path, Adapter added) {
- if ("/".equals(path)) {
- ((MapperAdapter) adapter).setDefaultAdapter(added);
- } else {
- ((MapperAdapter) adapter).getMapper().addWrapper(path, added);
- }
- }
-
- /**
- */
- public void run() {
- try {
- init();
- start();
- } catch(IOException ex) {
- ex.printStackTrace();
- }
- }
-
- public void setDaemon(boolean b) {
- daemon = b;
- }
-
- public void init() {
- //JdkLoggerConfig.loadCustom();
- om.bind("CoyoteServer:" + "CoyoteServer-" + port,
- this);
- om.bind("CoyoteAdapter", adapter);
- }
-
- protected void initAdapters() {
- if (proto == null) {
- addProtocolHandler(port, daemon);
- }
- // adapter = ...
- // Adapter secondaryadapter = ...
- //registry.registerComponent(secondaryadapter, ":name=adapter", null);
- }
-
- public void stop() throws Exception {
- if (!started) {
- return;
- }
- proto.destroy();
- started = false;
- }
-
- /**
- * Simple CLI support - arg is a path:className pair.
- */
- public void setAdapter(String arg) {
- String[] pathClass = arg.split(":", 2);
- try {
- Class c = Class.forName(pathClass[1]);
- Adapter a = (Adapter) c.newInstance();
- addAdapter(pathClass[0],a);
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-
- public void setPort(int port) {
- if (proto != null) {
- proto.setAttribute("port", Integer.toString(port));
- }
- this.port = port;
- }
-
- public void setConnector(ProtocolHandler h) {
- this.proto = h;
- h.setAttribute("port", Integer.toString(port));
-
- om.bind("ProtocolHandler:" + "ep-" + port, proto);
- }
-
- public void addProtocolHandler(int port, boolean daemon) {
- Http11NioProtocol proto = new Http11NioProtocol();
- proto.setCompression("on");
- proto.setCompressionMinSize(32);
- proto.setPort(port);
- proto.getEndpoint().setDaemon(daemon);
- CoyoteServer server = this;
- server.setConnector(proto);
- server.setPort(port);
- server.setDaemon(daemon);
- }
-
- public void addProtocolHandler(ProtocolHandler proto,
- int port, boolean daemon) {
- CoyoteServer server = this;
- server.setConnector(proto);
- server.setPort(port);
- server.setDaemon(daemon);
- }
-
-
-
- public void start() throws IOException {
- try {
- if (started) {
- return;
- }
- initAdapters();
-
- // not required - should run fine without a connector.
- if (proto != null) {
- proto.setAdapter(adapter);
-
- proto.init();
- proto.start();
- }
-
- started = true;
- } catch (Throwable e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
-
- public boolean getStarted() {
- return started;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-
-import org.apache.coyote.Request;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.http.mapper.MappingData;
-
-public class CoyoteUtils {
- static ByteChunk space = new ByteChunk(1);
- static ByteChunk col = new ByteChunk(1);
- static ByteChunk crlf = new ByteChunk(2);
- static {
- try {
- space.append(' ');
- col.append(':');
- crlf.append('\r');
- crlf.append('\n');
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public static String getContextPath(Request request) {
- MappingData md = MapperAdapter.getMappingData(request);
- String ctxPath = (md.contextPath.isNull()) ? "/" :
- md.contextPath.toString();
- return ctxPath;
- }
-
- public static String getPathInfo(Request request) {
- MappingData md = MapperAdapter.getMappingData(request);
- String ctxPath = (md.pathInfo.isNull()) ? "/" :
- md.pathInfo.toString();
- return ctxPath;
- }
- public static String getServletPath(Request request) {
- MappingData md = MapperAdapter.getMappingData(request);
- String ctxPath = (md.wrapperPath.isNull()) ? "/" :
- md.wrapperPath.toString();
- return ctxPath;
- }
-
- // TODO: collate all notes in a signle file
- static int READER_NOTE = 5;
-
- public static MessageReader getReader(Request req) {
- MessageReader r = (MessageReader) req.getNote(READER_NOTE);
- if (r == null) {
- r = new MessageReader();
- r.setRequest(req);
- req.setNote(READER_NOTE, r);
- }
- return r;
- }
-
- /**
- * Convert the request to bytes, ready to send.
- */
- public static void serializeRequest(Request req,
- ByteChunk reqBuf) throws IOException {
- req.method().toBytes();
- if (!req.unparsedURI().isNull()) {
- req.unparsedURI().toBytes();
- }
- req.protocol().toBytes();
-
- reqBuf.append(req.method().getByteChunk());
- reqBuf.append(space);
- if (req.unparsedURI().isNull()) {
- req.requestURI().toBytes();
-
- reqBuf.append(req.requestURI().getByteChunk());
- } else {
- reqBuf.append(req.unparsedURI().getByteChunk());
- }
- reqBuf.append(space);
- reqBuf.append(req.protocol().getByteChunk());
- reqBuf.append(crlf);
- // Headers
- MimeHeaders mimeHeaders = req.getMimeHeaders();
- boolean hasHost = false;
- for (int i = 0; i < mimeHeaders.size(); i++) {
- MessageBytes name = mimeHeaders.getName(i);
- name.toBytes();
- reqBuf.append(name.getByteChunk());
- if (name.equalsIgnoreCase("host")) {
- hasHost = true;
- }
- reqBuf.append(col);
- mimeHeaders.getValue(i).toBytes();
- reqBuf.append(mimeHeaders.getValue(i).getByteChunk());
- reqBuf.append(crlf);
- }
- if (!hasHost) {
- reqBuf.append("Host: localhost\r\n".getBytes(), 0, 17);
- }
- reqBuf.append(crlf);
- }
-
-
-}
+++ /dev/null
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-import java.util.logging.Logger;
-
-import org.apache.coyote.Adapter;
-import org.apache.coyote.Request;
-import org.apache.coyote.Response;
-import org.apache.tomcat.util.buf.UriNormalizer;
-import org.apache.tomcat.util.http.mapper.BaseMapper;
-import org.apache.tomcat.util.http.mapper.MappingData;
-import org.apache.tomcat.util.net.SocketStatus;
-
-/**
- *
- */
-public class MapperAdapter implements Adapter {
-
- private BaseMapper mapper=new BaseMapper();
-
- static Logger log = Logger.getLogger("Mapper");
- static final int MAP_NOTE = 4;
-
- public MapperAdapter() {
- mapper.setDefaultHostName("localhost");
- mapper.setContext("", new String[] {"index.html"},
- null);
- }
-
- public MapperAdapter(BaseMapper mapper2) {
- mapper = mapper2;
- }
-
- public static MappingData getMappingData(Request req) {
- MappingData md = (MappingData) req.getNote(MAP_NOTE);
- if (md == null) {
- md = new MappingData();
- req.setNote(MAP_NOTE, md);
- }
- return md;
- }
-
- /**
- * Copy an array of bytes to a different position. Used during
- * normalization.
- */
- public static void copyBytes(byte[] b, int dest, int src, int len) {
- for (int pos = 0; pos < len; pos++) {
- b[pos + dest] = b[pos + src];
- }
- }
-
-
- public void service(Request req, final Response res)
- throws Exception {
- long t0 = System.currentTimeMillis();
- try {
- // compute decodedURI - not done by connector
- UriNormalizer.decodeRequest(req.decodedURI(), req.requestURI(), req.getURLDecoder());
- MappingData mapRes = getMappingData(req);
- mapRes.recycle();
-
- mapper.map(req.requestURI(), mapRes);
-
- Adapter h=(Adapter)mapRes.wrapper;
-
- if (h != null) {
- log.info(">>>>>>>> START: " + req.method() + " " +
- req.decodedURI() + " " +
- h.getClass().getSimpleName());
- h.service( req, res );
- } else {
- res.setStatus(404);
- }
- } catch(IOException ex) {
- throw ex;
- } catch( Throwable t ) {
- t.printStackTrace();
- } finally {
- long t1 = System.currentTimeMillis();
-
- log.info("<<<<<<<< DONE: " + req.method() + " " +
- req.decodedURI() + " " +
- res.getStatus() + " " +
- (t1 - t0));
-
- // Final processing
- // TODO: only if not commet, this doesn't work with the
- // other connectors since we don't have the info
- // TODO: add this note in the nio/apr connectors
- // TODO: play nice with TomcatLite, other adapters that flush/close
- if (res.getNote(CoyoteServer.COMET_RES_NOTE) == null) {
- MessageWriter mw = MessageWriter.getWriter(req, res, 0);
- mw.flush();
- mw.recycle();
- MessageReader reader = CoyoteUtils.getReader(req);
- reader.recycle();
- res.finish();
-
- req.recycle();
- res.recycle();
- }
- }
- }
-
- public BaseMapper getMapper() {
- return mapper;
- }
-
- public void setDefaultAdapter(Adapter adapter) {
- mapper.addWrapper("/", adapter);
- }
-
- public boolean event(Request req, Response res, boolean error) throws Exception {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean event(Request req, Response res, SocketStatus status)
- throws Exception {
- return false;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.coyote;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.HashMap;
-
-import org.apache.coyote.Request;
-import org.apache.tomcat.util.buf.B2CConverter;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.CharChunk;
-
-/**
- * Refactored from catalina.connector.InputBuffer. Renamed to avoid conflict
- * with coyote class.
- *
- * TODO: move to coyote package.
- */
-
-/**
- * The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3
- * OutputBuffer, adapted to handle input instead of output. This allows
- * complete recycling of the facade objects (the ServletInputStream and the
- * BufferedReader).
- *
- * @author Remy Maucherat
- */
-public class MessageReader extends Reader
- implements ByteChunk.ByteInputChannel, CharChunk.CharInputChannel,
- CharChunk.CharOutputChannel {
-
-
- // -------------------------------------------------------------- Constants
-
-
- public static final String DEFAULT_ENCODING =
- org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
- public static final int DEFAULT_BUFFER_SIZE = 8*1024;
-
- // The buffer can be used for byte[] and char[] reading
- // ( this is needed to support ServletInputStream and BufferedReader )
- public final int INITIAL_STATE = 0;
- public final int CHAR_STATE = 1;
- public final int BYTE_STATE = 2;
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The byte buffer. More data may be added to it while reading.
- */
- private ByteChunk bb;
-
-
- /**
- * The chunk buffer, will be filled in from the bb.
- */
- private CharChunk cb;
-
-
- /**
- * State of the output buffer.
- */
- private int state = 0;
-
-
- /**
- * Number of bytes read.
- */
- private int bytesRead = 0;
-
-
- /**
- * Number of chars read.
- */
- private int charsRead = 0;
-
-
- /**
- * Flag which indicates if the input buffer is closed.
- */
- private boolean closed = false;
-
- /**
- * Encoding to use.
- */
- private String enc;
-
-
- /**
- * Encoder is set.
- */
- private boolean gotEnc = false;
-
-
- /**
- * Cached encoders.
- */
- protected HashMap<String, B2CConverter> encoders =
- new HashMap<String, B2CConverter>();
-
-
- /**
- * Current byte to char converter.
- */
- protected B2CConverter conv;
-
-
- /**
- * Associated Coyote request.
- */
- private Request coyoteRequest;
-
-
- /**
- * Buffer position.
- */
- private int markPos = -1;
-
-
- /**
- * Buffer size.
- */
- private int size = -1;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Default constructor. Allocate the buffer with the default buffer size.
- */
- public MessageReader() {
- this(DEFAULT_BUFFER_SIZE);
- }
-
-
- /**
- * Alternate constructor which allows specifying the initial buffer size.
- *
- * @param size Buffer size to use
- */
- public MessageReader(int size) {
- this.size = size;
- bb = new ByteChunk(size);
- bb.setLimit(size);
- bb.setByteInputChannel(this);
- cb = new CharChunk(size);
- cb.setLimit(size);
- cb.setOptimizedWrite(false);
- cb.setCharInputChannel(this);
- cb.setCharOutputChannel(this);
- }
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Associated Coyote request.
- *
- * @param coyoteRequest Associated Coyote request
- */
- public void setRequest(Request coyoteRequest) {
- this.coyoteRequest = coyoteRequest;
- }
-
-
- /**
- * Get associated Coyote request.
- *
- * @return the associated Coyote request
- */
- public Request getRequest() {
- return this.coyoteRequest;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Recycle the output buffer.
- */
- public void recycle() {
-
- state = INITIAL_STATE;
- bytesRead = 0;
- charsRead = 0;
-
- // If usage of mark made the buffer too big, reallocate it
- if (cb.getChars().length > size) {
- cb = new CharChunk(size);
- cb.setLimit(size);
- cb.setCharInputChannel(this);
- cb.setCharOutputChannel(this);
- } else {
- cb.recycle();
- }
- markPos = -1;
- bb.recycle();
- closed = false;
-
- if (conv != null) {
- conv.recycle();
- }
-
- gotEnc = false;
- enc = null;
-
- }
-
-
- /**
- * Close the input buffer.
- *
- * @throws IOException An underlying IOException occurred
- */
- public void close()
- throws IOException {
- closed = true;
- }
-
-
- public int available()
- throws IOException {
- if (state == BYTE_STATE) {
- return bb.getLength();
- } else if (state == CHAR_STATE) {
- return cb.getLength();
- } else {
- return 0;
- }
- }
-
-
- // ------------------------------------------------- Bytes Handling Methods
-
-
- /**
- * Reads new bytes in the byte chunk.
- *
- * @param cbuf Byte buffer to be written to the response
- * @param off Offset
- * @param len Length
- *
- * @throws IOException An underlying IOException occurred
- */
- public int realReadBytes(byte cbuf[], int off, int len)
- throws IOException {
-
- if (closed)
- return -1;
- if (coyoteRequest == null)
- return -1;
-
- state = BYTE_STATE;
-
- int result = coyoteRequest.doRead(bb);
-
- return result;
-
- }
-
-
- public int readByte()
- throws IOException {
- return bb.substract();
- }
-
-
- public int read(byte[] b, int off, int len)
- throws IOException {
- return bb.substract(b, off, len);
- }
-
-
- // ------------------------------------------------- Chars Handling Methods
-
-
- /**
- * Since the converter will use append, it is possible to get chars to
- * be removed from the buffer for "writing". Since the chars have already
- * been read before, they are ignored. If a mark was set, then the
- * mark is lost.
- */
- public void realWriteChars(char c[], int off, int len)
- throws IOException {
- markPos = -1;
- }
-
-
- public void setEncoding(String s) {
- enc = s;
- }
-
- /**
- * Called when a read(char[]) operation is lacking data. It will read
- * bytes.
- */
- public int realReadChars(char cbuf[], int off, int len)
- throws IOException {
-
- if (!gotEnc)
- setConverter();
-
- if (bb.getLength() <= 0) {
- int nRead = realReadBytes(bb.getBytes(), 0, bb.getBytes().length);
- if (nRead < 0) {
- return -1;
- }
- }
-
- if (markPos == -1) {
- cb.setOffset(0);
- cb.setEnd(0);
- }
-
- conv.convert(bb, cb, -1);
- bb.setOffset(bb.getEnd());
- state = CHAR_STATE;
-
- return cb.getLength();
-
- }
-
-
- public int read()
- throws IOException {
- return cb.substract();
- }
-
-
- public int read(char[] cbuf)
- throws IOException {
- return read(cbuf, 0, cbuf.length);
- }
-
-
- public int read(char[] cbuf, int off, int len)
- throws IOException {
- return cb.substract(cbuf, off, len);
- }
-
-
- public long skip(long n)
- throws IOException {
-
- if (n < 0) {
- throw new IllegalArgumentException();
- }
-
- long nRead = 0;
- while (nRead < n) {
- if (cb.getLength() >= n) {
- cb.setOffset(cb.getStart() + (int) n);
- nRead = n;
- } else {
- nRead += cb.getLength();
- cb.setOffset(cb.getEnd());
- int toRead = 0;
- if (cb.getChars().length < (n - nRead)) {
- toRead = cb.getChars().length;
- } else {
- toRead = (int) (n - nRead);
- }
- int nb = realReadChars(cb.getChars(), 0, toRead);
- if (nb < 0)
- break;
- }
- }
-
- return nRead;
-
- }
-
-
- public boolean ready()
- throws IOException {
- return (cb.getLength() > 0);
- }
-
-
- public boolean markSupported() {
- return true;
- }
-
-
- public void mark(int readAheadLimit)
- throws IOException {
- if (cb.getLength() <= 0) {
- cb.setOffset(0);
- cb.setEnd(0);
- } else {
- if ((cb.getBuffer().length > (2 * size))
- && (cb.getLength()) < (cb.getStart())) {
- System.arraycopy(cb.getBuffer(), cb.getStart(),
- cb.getBuffer(), 0, cb.getLength());
- cb.setEnd(cb.getLength());
- cb.setOffset(0);
- }
- }
- int offset = readAheadLimit;
- if (offset < size) {
- offset = size;
- }
- cb.setLimit(cb.getStart() + offset);
- markPos = cb.getStart();
- }
-
-
- public void reset()
- throws IOException {
- if (state == CHAR_STATE) {
- if (markPos < 0) {
- cb.recycle();
- markPos = -1;
- throw new IOException();
- } else {
- cb.setOffset(markPos);
- }
- } else {
- bb.recycle();
- }
- }
-
-
- protected void setConverter()
- throws IOException {
- if (coyoteRequest != null)
- enc = coyoteRequest.getCharacterEncoding();
-
- gotEnc = true;
- if (enc == null)
- enc = DEFAULT_ENCODING;
- conv = (B2CConverter) encoders.get(enc);
- if (conv == null) {
- conv = new B2CConverter(enc);
- encoders.put(enc, conv);
- }
- }
-
- public class MRInputStream extends InputStream {
- public long skip(long n)
- throws IOException {
- return MessageReader.this.skip(n);
- }
-
- public void mark(int readAheadLimit)
- {
- try {
- MessageReader.this.mark(readAheadLimit);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
-
- public void reset()
- throws IOException {
- MessageReader.this.reset();
- }
-
-
-
- public int read()
- throws IOException {
- return MessageReader.this.readByte();
- }
-
- public int available() throws IOException {
- return MessageReader.this.available();
- }
-
- public int read(final byte[] b) throws IOException {
- return MessageReader.this.read(b, 0, b.length);
- }
-
-
- public int read(final byte[] b, final int off, final int len)
- throws IOException {
-
- return MessageReader.this.read(b, off, len);
- }
-
-
- /**
- * Close the stream
- * Since we re-cycle, we can't allow the call to super.close()
- * which would permantely disable us.
- */
- public void close() throws IOException {
- MessageReader.this.close();
- }
- }
-
- MRInputStream is = new MRInputStream();
-
- public InputStream asInputStream() {
- return is;
- }
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite.coyote;
-
-
-import java.io.IOException;
-import java.io.Writer;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.HashMap;
-
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.Request;
-import org.apache.coyote.Response;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.C2BConverter;
-import org.apache.tomcat.util.buf.CharChunk;
-
-/*
- * Refactoring: original code in catalina.connector.
- * - renamed to OutputWriter to avoid confusion with coyote OutputBuffer
- * -
- * TODO: move it to coyote, add Response.getWriter
- *
- */
-
-/**
- * The buffer used by Tomcat response. This is a derivative of the Tomcat 3.3
- * OutputBuffer, with the removal of some of the state handling (which in
- * Coyote is mostly the Processor's responsability).
- *
- * @author Costin Manolache
- * @author Remy Maucherat
- */
-public class MessageWriter extends Writer
- implements ByteChunk.ByteOutputChannel, CharChunk.CharOutputChannel {
-
- // used in getWriter, until a method is added to res.
- private static final int WRITER_NOTE = 3;
-
- // -------------------------------------------------------------- Constants
-
-
- public static final String DEFAULT_ENCODING =
- org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
- public static final int DEFAULT_BUFFER_SIZE = 8*1024;
-
-
- // The buffer can be used for byte[] and char[] writing
- // ( this is needed to support ServletOutputStream and for
- // efficient implementations of templating systems )
- public final int INITIAL_STATE = 0;
- public final int CHAR_STATE = 1;
- public final int BYTE_STATE = 2;
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The byte buffer.
- */
- private ByteChunk bb;
-
-
- /**
- * The chunk buffer.
- */
- private CharChunk cb;
-
-
- /**
- * State of the output buffer.
- */
- private int state = 0;
-
-
- /**
- * Number of bytes written.
- */
- private int bytesWritten = 0;
-
-
- /**
- * Number of chars written.
- */
- private int charsWritten = 0;
-
-
- /**
- * Flag which indicates if the output buffer is closed.
- */
- private boolean closed = false;
-
-
- /**
- * Do a flush on the next operation.
- */
- private boolean doFlush = false;
-
-
- /**
- * Byte chunk used to output bytes. This is just used to wrap the byte[]
- * to match the coyote OutputBuffer interface
- */
- private ByteChunk outputChunk = new ByteChunk();
-
-
- /**
- * Encoding to use.
- * TODO: isn't it redundant ? enc, gotEnc, conv plus the enc in the bb
- */
- private String enc;
-
-
- /**
- * Encoder is set.
- */
- private boolean gotEnc = false;
-
-
- /**
- * List of encoders. The writer is reused - the encoder mapping
- * avoids creating expensive objects. In future it'll contain nio.Charsets
- */
- protected HashMap encoders = new HashMap();
-
-
- /**
- * Current char to byte converter. TODO: replace with Charset
- */
- protected C2BConverter conv;
-
-
- /**
- * Associated Coyote response.
- */
- private Response coyoteResponse;
-
-
- /**
- * Suspended flag. All output bytes will be swallowed if this is true.
- */
- private boolean suspended = false;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Default constructor. Allocate the buffer with the default buffer size.
- */
- public MessageWriter() {
-
- this(DEFAULT_BUFFER_SIZE);
-
- }
-
-
- /**
- * Alternate constructor which allows specifying the initial buffer size.
- *
- * @param size Buffer size to use
- */
- public MessageWriter(int size) {
-
- bb = new ByteChunk(size);
- bb.setLimit(size);
- bb.setByteOutputChannel(this);
- cb = new CharChunk(size);
- cb.setCharOutputChannel(this);
- cb.setLimit(size);
-
- }
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Associated Coyote response.
- *
- * @param coyoteResponse Associated Coyote response
- */
- public void setResponse(Response coyoteResponse) {
- this.coyoteResponse = coyoteResponse;
- }
-
-
- /**
- * Get associated Coyote response.
- *
- * @return the associated Coyote response
- */
- public Response getResponse() {
- return this.coyoteResponse;
- }
-
-
- /**
- * Is the response output suspended ?
- *
- * @return suspended flag value
- */
- public boolean isSuspended() {
- return this.suspended;
- }
-
-
- /**
- * Set the suspended flag.
- *
- * @param suspended New suspended flag value
- */
- public void setSuspended(boolean suspended) {
- this.suspended = suspended;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Recycle the output buffer.
- */
- public void recycle() {
-
- state = INITIAL_STATE;
- bytesWritten = 0;
- charsWritten = 0;
-
- cb.recycle();
- bb.recycle();
- closed = false;
- suspended = false;
-
- if (conv!= null) {
- conv.recycle();
- }
-
- gotEnc = false;
- enc = null;
-
- }
-
-
- /**
- * Close the output buffer. This tries to calculate the response size if
- * the response has not been committed yet.
- *
- * @throws IOException An underlying IOException occurred
- */
- public void close()
- throws IOException {
-
- if (closed)
- return;
- if (suspended)
- return;
-
- if ((!coyoteResponse.isCommitted())
- && (coyoteResponse.getContentLengthLong() == -1)) {
- // Flushing the char buffer
- if (state == CHAR_STATE) {
- cb.flushBuffer();
- state = BYTE_STATE;
- }
- // If this didn't cause a commit of the response, the final content
- // length can be calculated
- if (!coyoteResponse.isCommitted()) {
- coyoteResponse.setContentLength(bb.getLength());
- }
- }
-
- doFlush(false);
- closed = true;
-
- coyoteResponse.finish();
-
- }
-
-
- /**
- * Flush bytes or chars contained in the buffer.
- *
- * @throws IOException An underlying IOException occurred
- */
- public void flush()
- throws IOException {
- doFlush(true);
- }
-
-
- /**
- * Flush bytes or chars contained in the buffer.
- *
- * @throws IOException An underlying IOException occurred
- */
- protected void doFlush(boolean realFlush)
- throws IOException {
-
- if (suspended)
- return;
-
- doFlush = true;
- if (state == CHAR_STATE) {
- cb.flushBuffer();
- bb.flushBuffer();
- state = BYTE_STATE;
- } else if (state == BYTE_STATE) {
- bb.flushBuffer();
- } else if (state == INITIAL_STATE) {
- // If the buffers are empty, commit the response header
- coyoteResponse.sendHeaders();
- }
- doFlush = false;
-
- if (realFlush) {
- coyoteResponse.action(ActionCode.ACTION_CLIENT_FLUSH,
- coyoteResponse);
- // If some exception occurred earlier, or if some IOE occurred
- // here, notify the servlet with an IOE
- if (coyoteResponse.isExceptionPresent()) {
- throw new ClientAbortException
- (coyoteResponse.getErrorException());
- }
- }
-
- }
-
-
- // ------------------------------------------------- Bytes Handling Methods
-
-
- /**
- * Sends the buffer data to the client output, checking the
- * state of Response and calling the right interceptors.
- *
- * @param buf Byte buffer to be written to the response
- * @param off Offset
- * @param cnt Length
- *
- * @throws IOException An underlying IOException occurred
- */
- public void realWriteBytes(byte buf[], int off, int cnt)
- throws IOException {
-
- if (closed)
- return;
- if (coyoteResponse == null)
- return;
-
- // If we really have something to write
- if (cnt > 0) {
- // real write to the adapter
- outputChunk.setBytes(buf, off, cnt);
- try {
- coyoteResponse.doWrite(outputChunk);
- } catch (IOException e) {
- // An IOException on a write is almost always due to
- // the remote client aborting the request. Wrap this
- // so that it can be handled better by the error dispatcher.
- throw new ClientAbortException(e);
- }
- }
-
- }
-
-
- public void write(byte b[], int off, int len) throws IOException {
-
- if (suspended)
- return;
-
- if (state == CHAR_STATE)
- cb.flushBuffer();
- state = BYTE_STATE;
- writeBytes(b, off, len);
-
- }
-
-
- private void writeBytes(byte b[], int off, int len)
- throws IOException {
-
- if (closed)
- return;
-
- bb.append(b, off, len);
- bytesWritten += len;
-
- // if called from within flush(), then immediately flush
- // remaining bytes
- if (doFlush) {
- bb.flushBuffer();
- }
-
- }
-
-
- public void writeByte(int b)
- throws IOException {
-
- if (suspended)
- return;
-
- if (state == CHAR_STATE)
- cb.flushBuffer();
- state = BYTE_STATE;
-
- bb.append( (byte)b );
- bytesWritten++;
-
- }
-
-
- // ------------------------------------------------- Chars Handling Methods
-
-
- public void write(int c)
- throws IOException {
-
- if (suspended)
- return;
-
- state = CHAR_STATE;
-
- cb.append((char) c);
- charsWritten++;
-
- }
-
-
- public void write(char c[])
- throws IOException {
-
- if (suspended)
- return;
-
- write(c, 0, c.length);
-
- }
-
-
- public void write(char c[], int off, int len)
- throws IOException {
-
- if (suspended)
- return;
-
- state = CHAR_STATE;
-
- cb.append(c, off, len);
- charsWritten += len;
-
- }
-
-
- public void write(StringBuffer sb)
- throws IOException {
-
- if (suspended)
- return;
-
- state = CHAR_STATE;
-
- int len = sb.length();
- charsWritten += len;
- cb.append(sb);
-
- }
-
-
- /**
- * Append a string to the buffer
- */
- public void write(String s, int off, int len)
- throws IOException {
-
- if (suspended)
- return;
-
- state=CHAR_STATE;
-
- charsWritten += len;
- if (s==null)
- s="null";
- cb.append( s, off, len );
-
- }
-
-
- public void write(String s)
- throws IOException {
-
- if (suspended)
- return;
-
- state = CHAR_STATE;
- if (s==null)
- s="null";
- write(s, 0, s.length());
-
- }
-
- public void println() throws IOException {
- write("\n");
- }
-
- public void println(String s) throws IOException {
- write(s);
- write("\n");
- }
-
- public void print(String s) throws IOException {
- write(s);
- }
-
- public void flushChars()
- throws IOException {
-
- cb.flushBuffer();
- state = BYTE_STATE;
-
- }
-
-
- public boolean flushCharsNeeded() {
- return state == CHAR_STATE;
- }
-
-
- public void setEncoding(String s) {
- enc = s;
- }
-
-
- public void realWriteChars(char c[], int off, int len)
- throws IOException {
-
- if (!gotEnc)
- setConverter();
-
- conv.convert(c, off, len);
- conv.flushBuffer(); // ???
-
- }
-
-
- public void checkConverter()
- throws IOException {
-
- if (!gotEnc)
- setConverter();
-
- }
-
-
- protected void setConverter()
- throws IOException {
-
- if (coyoteResponse != null)
- enc = coyoteResponse.getCharacterEncoding();
-
- gotEnc = true;
- if (enc == null)
- enc = DEFAULT_ENCODING;
- conv = (C2BConverter) encoders.get(enc);
- if (conv == null) {
-
- if (System.getSecurityManager() != null){
- try{
- conv = (C2BConverter)AccessController.doPrivileged(
- new PrivilegedExceptionAction(){
-
- public Object run() throws IOException{
- return new C2BConverter(bb, enc);
- }
-
- }
- );
- }catch(PrivilegedActionException ex){
- Exception e = ex.getException();
- if (e instanceof IOException)
- throw (IOException)e;
- }
- } else {
- conv = new C2BConverter(bb, enc);
- }
-
- encoders.put(enc, conv);
-
- }
- }
-
-
- // -------------------- BufferedOutputStream compatibility
-
-
- /**
- * Real write - this buffer will be sent to the client
- */
- public void flushBytes()
- throws IOException {
-
- bb.flushBuffer();
-
- }
-
-
- public int getBytesWritten() {
- return bytesWritten;
- }
-
-
- public int getCharsWritten() {
- return charsWritten;
- }
-
-
- public int getContentWritten() {
- return bytesWritten + charsWritten;
- }
-
-
- /**
- * True if this buffer hasn't been used ( since recycle() ) -
- * i.e. no chars or bytes have been added to the buffer.
- */
- public boolean isNew() {
- return (bytesWritten == 0) && (charsWritten == 0);
- }
-
-
- public void setBufferSize(int size) {
- if (size > bb.getLimit()) {// ??????
- bb.setLimit(size);
- }
- }
-
-
- public void reset() {
-
- //count=0;
- bb.recycle();
- bytesWritten = 0;
- cb.recycle();
- charsWritten = 0;
- gotEnc = false;
- enc = null;
- state = INITIAL_STATE;
- }
-
-
- public int getBufferSize() {
- return bb.getLimit();
- }
-
-
- public static MessageWriter getWriter(Request req, Response res, int size)
- {
- MessageWriter out=(MessageWriter)req.getNote(MessageWriter.WRITER_NOTE);
- if( out == null ) {
- if( size<=0 ) {
- out=new MessageWriter();
- } else {
- out=new MessageWriter(size);
- }
- out.setResponse(res);
- req.setNote(MessageWriter.WRITER_NOTE, out );
- }
- return out;
- }
-
- public ByteChunk getByteBuffer() {
- return outputChunk;
- }
-
-}
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import org.apache.tomcat.lite.ServletContextImpl;
import org.apache.tomcat.lite.ContextPreinitListener;
+import org.apache.tomcat.lite.ServletContextImpl;
/**
* Default configurator - parse web.xml, init the context.
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
d = cfg;
}
- /**
- * Serialize the data, for caching.
- */
- public void saveWebAppData(String fileName) throws IOException {
- ObjectOutputStream oos =
- new ObjectOutputStream(new FileOutputStream(fileName));
- oos.writeObject(d);
- oos.close();
- }
-
public ServletContextConfig getWebAppData() {
return d;
}
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
-import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.tomcat.addons.Filesystem;
+import org.apache.tomcat.integration.ObjectManager;
+import org.apache.tomcat.integration.simple.ServletHelper;
import org.apache.tomcat.servlets.util.Range;
/**
// ----------------------------------------------------- Instance Variables
-
/**
* Should we generate directory listings?
// --------------------------------------------------------- Public Methods
+ protected ObjectManager om;
+ protected Filesystem fs;
/**
* Finalize this servlet.
* Initialize this servlet.
*/
public void init() throws ServletException {
+ om = ServletHelper.getObjectManager(getServletContext());
+ fs = (Filesystem) om.get(Filesystem.class.getName());
+
String realPath = getServletContext().getRealPath("/");
basePath = new File(realPath);
try {
} catch (IOException e) {
basePathName = basePath.getAbsolutePath();
}
+ log("Init fs " + fs + " base: " + basePathName);
// Set our properties from the initialization parameters
String value = null;
input = 256;
if (output < 256)
output = 256;
+ }
+ public void setFilesystem(Filesystem fs) {
+ this.fs = fs;
+ }
+
+ public Filesystem getFilesystem() {
+ return fs;
+ }
+
+ public void setBasePath(String s) {
+ this.basePathName = s;
+ this.basePath = new File(s);
+ }
+
+ public String getBasePath() {
+ return basePathName;
+ }
+
+ public void setInput(int i) {
+ this.input = i;
+ }
+
+ public void setListings(boolean b) {
+ this.listings = b;
+ }
+
+ public void setReadme(String s) {
+ readmeFile = s;
}
+ public void setFileEncoding(String s) {
+ fileEncoding = s;
+ }
+
+
public void loadDefaultMime() throws IOException {
File mimeF = new File("/etc/mime.types");
boolean loaded =false;
int cacheSize;
public LRUFileCache() {
}
- protected boolean removeEldestEntity(Map.Entry eldest) {
- return size() > cacheSize;
- }
+// protected boolean removeEldestEntity(Map.Entry eldest) {
+// return size() > cacheSize;
+// }
}
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
}
// TODO: replace it with writeRole - who is enabled to write
- protected boolean readOnly = false;
+ protected boolean readOnly = true;
/**
* Repository of the lock-null resources.
} catch (Throwable t) {
;
}
+ log("Starting webdav");
}
-
+ public void setReadonly(boolean ro) {
+ readOnly = ro;
+ }
+
+ public boolean getReadonly() {
+ return readOnly;
+ }
// ------------------------------------------------------ Protected Methods
/**
try {
// will override
- FileOutputStream fos = new FileOutputStream(resFile);
+ OutputStream fos = getFilesystem().getOutputStream(resFile.getPath());
CopyUtils.copy(resourceInputStream, fos);
} catch(IOException e) {
result = false;
} else {
try {
- CopyUtils.copy( new FileInputStream(object),
- new FileOutputStream(dest));
+ CopyUtils.copy(getFilesystem().getInputStream(object.getPath()),
+ getFilesystem().getOutputStream(dest));
} catch(IOException ex ) {
errorList.put
(source,
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import org.apache.tomcat.InstanceManager;
import org.apache.jasper.EmbeddedServletOptions;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import org.apache.jasper.Options;
import org.apache.jasper.compiler.JspRuntimeContext;
import org.apache.jasper.servlet.JspServletWrapper;
+import org.apache.tomcat.InstanceManager;
/**
* The actual compiler. Maps and compile a jsp-file to a class.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.addons.UserAuthentication;
*/
public class BasicAuthentication implements UserAuthentication {
- private static Log log = LogFactory.getLog(BasicAuthentication.class);
String realm;
@Override
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.addons.UserAuthentication;
*/
public class FormAuthentication implements UserAuthentication {
- private static Log log = LogFactory.getLog(FormAuthentication.class);
String realm;
String url;
package org.apache.tomcat.servlets.sec;
-import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
/**
* Load user/passwords from a file.
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
try {
((HttpSessionBindingListener) value).valueBound(event);
} catch (Throwable t){
- manager.log.error("Listener valueBound() error", t);
+ manager.log.log(Level.SEVERE, "Listener valueBound() error", t);
}
}
}
((HttpSessionBindingListener) unbound).valueUnbound
(new HttpSessionBindingEvent(getSession(), name));
} catch (Throwable t) {
- manager.log.error("Listener valueUnbound()", t);
+ manager.log.log(Level.SEVERE, "Listener valueUnbound()", t);
}
}
listener.attributeAdded(event);
}
} catch (Throwable t) {
- manager.log.error("Listener attibuteAdded/Replaced()", t);
+ manager.log.log(Level.SEVERE, "Listener attibuteAdded/Replaced()", t);
}
}
try {
listener.sessionCreated(event);
} catch (Throwable t) {
- manager.log.error("listener.sessionCreated()", t);
+ manager.log.log(Level.SEVERE, "listener.sessionCreated()", t);
}
}
}
try {
listener.sessionDestroyed(event);
} catch (Throwable t) {
- manager.log.error("listener.sessionDestroyed", t);
+ manager.log.log(Level.SEVERE, "listener.sessionDestroyed", t);
}
}
}
}
listener.attributeRemoved(event);
} catch (Throwable t) {
- manager.log.error("listener.attributeRemoved", t);
+ manager.log.log(Level.SEVERE, "listener.attributeRemoved", t);
}
}
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
-
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* Generates random IDs, useable as cookies.
protected DataInputStream randomIS=null;
protected String devRandomSource="/dev/urandom";
- protected static Log log = LogFactory.getLog(RandomGenerator.class);
+ protected static Logger log = Logger.getLogger(RandomGenerator.class.getName());
/**
* The message digest algorithm to be used when generating session
try {
this.digest = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
- log.error("Algorithm not found", e);
+ log.log(Level.SEVERE, "Algorithm not found", e);
try {
this.digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException f) {
- log.error("No message digest available", f);
+ log.log(Level.SEVERE, "No message digest available", f);
this.digest = null;
}
}
long t2=System.currentTimeMillis();
- if( log.isDebugEnabled() )
- log.debug("getDigest() " + (t2-t1));
+ if( log.isLoggable(Level.FINEST) )
+ log.finest("getDigest() " + (t2-t1));
}
return (this.digest);
if (len == bytes.length) {
return;
}
- if(log.isDebugEnabled())
- log.debug("Got " + len + " " + bytes.length );
} catch (Exception ex) {
// Ignore
}
try {
randomIS.close();
} catch (Exception e) {
- log.warn("Failed to close randomIS.");
+ log.warning("Failed to close randomIS.");
}
randomIS = null;
this.random.setSeed(seed);
} catch (Exception e) {
// Fall back to the simple case
- log.error("Failed to create random " + randomClass, e);
+ log.log(Level.SEVERE, "Failed to create random " + randomClass, e);
this.random = new java.util.Random();
this.random.setSeed(seed);
}
- if(log.isDebugEnabled()) {
+ if(log.isLoggable(Level.FINEST)) {
long t2=System.currentTimeMillis();
if( (t2-t1) > 100 )
- log.debug("Init random: " + " " + (t2-t1));
+ log.finest("Init random: " + " " + (t2-t1));
}
}
if( ! f.exists() ) return;
randomIS= new DataInputStream( new FileInputStream(f));
randomIS.readLong();
- if( log.isDebugEnabled() )
- log.debug( "Opening " + devRandomSource );
+// if( log.isDebugEnabled() )
+// log.debug( "Opening " + devRandomSource );
} catch( IOException ex ) {
try {
randomIS.close();
} catch (Exception e) {
- log.warn("Failed to close randomIS.");
+ log.warning("Failed to close randomIS.");
}
randomIS=null;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.addons.UserSessionManager;
// TODO: move 'expiring objects' to a separate utility class
* @author Craig R. McClanahan
*/
public class SimpleSessionManager implements UserSessionManager {
- protected static Log log = LogFactory.getLog(SimpleSessionManager.class);
+ protected static Logger log = Logger.getLogger(SimpleSessionManager.class.getName());
protected RandomGenerator randomG = new RandomGenerator();
protected int expiredSessions = 0;
static class SessionLRU extends LinkedHashMap {
- protected boolean removeEldestEntry(Map.Entry eldest) {
- HttpSessionImpl s = (HttpSessionImpl)eldest.getValue();
- int size = this.size();
-
- // TODO: check if eldest is expired or if we're above the limit.
- // if eldest is expired, turn a flag to check for more.
-
- // Note: this doesn't work well for sessions that set shorter
- // expiry time, or longer expiry times.
- return false;
- }
+// protected boolean removeEldestEntry(Map.Entry eldest) {
+// HttpSessionImpl s = (HttpSessionImpl)eldest.getValue();
+// int size = this.size();
+//
+// // TODO: check if eldest is expired or if we're above the limit.
+// // if eldest is expired, turn a flag to check for more.
+//
+// // Note: this doesn't work well for sessions that set shorter
+// // expiry time, or longer expiry times.
+// return false;
+// }
}
HttpSessionImpl sessions[] = findSessions();
int expireHere = 0 ;
- if(log.isDebugEnabled())
- log.debug("Start expire sessions " + " at " + timeNow + " sessioncount " + sessions.length);
+ if(log.isLoggable(Level.FINE))
+ log.fine("Start expire sessions " + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
if (!sessions[i].isValid()) {
}
long timeEnd = System.currentTimeMillis();
- if(log.isDebugEnabled())
- log.debug("End expire sessions " + " processingTime " +
+ if(log.isLoggable(Level.FINE))
+ log.fine("End expire sessions " + " processingTime " +
(timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow );
--- /dev/null
+/*
+ */
+package org.apache.tomcat.util.http;
+
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.buf.UDecoder;
+
+/**
+ * Simple request representation, public fields - no I/O or actions,
+ * just a struct.
+ *
+ * Based on Coyote request.
+ *
+ * @author Costin Manolache
+ */
+public class HttpRequest {
+
+ // Same fields as in coyote - this is the primary info from request
+
+ protected MessageBytes schemeMB;
+
+ protected MessageBytes methodMB;
+ protected MessageBytes unparsedURIMB;
+ protected MessageBytes protoMB;
+ protected MimeHeaders headers;
+
+ // Reference to 'real' request object
+ public Object nativeRequest;
+ public Object wrapperRequest;
+
+ protected MessageBytes remoteAddrMB;
+ protected MessageBytes remoteHostMB;
+ protected int remotePort;
+
+ protected MessageBytes localNameMB;
+ protected MessageBytes localAddrMB;
+ protected int localPort;
+
+ protected MessageBytes serverNameMB;
+ protected int serverPort = -1;
+
+ public HttpRequest() {
+ schemeMB =
+ MessageBytes.newInstance();
+ methodMB = MessageBytes.newInstance();
+ unparsedURIMB = MessageBytes.newInstance();
+ decodedUriMB = MessageBytes.newInstance();
+ requestURI = MessageBytes.newInstance();
+ protoMB = MessageBytes.newInstance();
+ headers = new MimeHeaders();
+ queryMB = MessageBytes.newInstance();
+ serverNameMB = MessageBytes.newInstance();
+
+ parameters = new Parameters();
+ parameters.setQuery(queryMB);
+ parameters.setURLDecoder(urlDecoder);
+ //parameters.setHeaders(headers);
+ cookies = new Cookies(headers);
+
+ initRemote();
+ }
+
+ private void initRemote() {
+ remoteAddrMB = MessageBytes.newInstance();
+ localNameMB = MessageBytes.newInstance();
+ remoteHostMB = MessageBytes.newInstance();
+ localAddrMB = MessageBytes.newInstance();
+ }
+
+
+ public HttpRequest(MessageBytes scheme, MessageBytes method,
+ MessageBytes unparsedURI, MessageBytes protocol,
+ MimeHeaders mimeHeaders,
+ MessageBytes requestURI,
+ MessageBytes decodedURI,
+ MessageBytes query, Parameters params,
+ MessageBytes serverName,
+ Cookies cookies) {
+ this.schemeMB = scheme;
+ this.methodMB = method;
+ this.unparsedURIMB = unparsedURI;
+ this.protoMB = protocol;
+ this.headers = mimeHeaders;
+
+ this.requestURI = requestURI;
+ this.decodedUriMB = decodedURI;
+ this.queryMB = query;
+ this.parameters = params;
+ this.serverNameMB = serverName;
+ this.cookies = cookies;
+ initRemote();
+ }
+
+
+
+ // ==== Derived fields, computed after request is received ===
+
+ protected MessageBytes requestURI;
+ protected MessageBytes queryMB;
+ protected MessageBytes decodedUriMB;
+
+ // -----------------
+ protected Parameters parameters;
+
+ protected MessageBytes contentTypeMB;
+
+ protected String charEncoding;
+ protected long contentLength = -1;
+
+ protected Cookies cookies;
+
+ // Avoid object creation:
+ protected UDecoder urlDecoder = new UDecoder();
+
+
+ public void recycle() {
+ schemeMB.recycle();
+ methodMB.setString("GET");
+ unparsedURIMB.recycle();
+ protoMB.setString("HTTP/1.1");
+ headers.recycle();
+
+ requestURI.recycle();
+ queryMB.recycle();
+ decodedUriMB.recycle();
+
+ parameters.recycle();
+ contentTypeMB = null;
+ charEncoding = null;
+ contentLength = -1;
+ remoteAddrMB.recycle();
+ remoteHostMB.recycle();
+ cookies.recycle();
+ }
+
+ public Parameters getParameters() {
+ return parameters;
+ }
+
+ // For compatibility with coyote
+ public MessageBytes decodedURI() {
+ return decodedUriMB;
+ }
+
+ public MessageBytes requestURI() {
+ return requestURI;
+ }
+
+ public MessageBytes method() {
+ return methodMB;
+ }
+
+ public String getHeader(String name) {
+ return headers.getHeader(name);
+ }
+
+ public MimeHeaders getMimeHeaders() {
+ return headers;
+ }
+
+ /**
+ * Get the character encoding used for this request.
+ */
+ public String getCharacterEncoding() {
+
+ if (charEncoding != null)
+ return charEncoding;
+
+ charEncoding = ContentType.getCharsetFromContentType(getContentType());
+ return charEncoding;
+
+ }
+
+
+ public void setCharacterEncoding(String enc) {
+ this.charEncoding = enc;
+ }
+
+
+ public void setContentLength(int len) {
+ this.contentLength = len;
+ }
+
+
+ public int getContentLength() {
+ long length = getContentLengthLong();
+
+ if (length < Integer.MAX_VALUE) {
+ return (int) length;
+ }
+ return -1;
+ }
+
+ public long getContentLengthLong() {
+ if( contentLength > -1 ) return contentLength;
+
+ MessageBytes clB = headers.getUniqueValue("content-length");
+ contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong();
+
+ return contentLength;
+ }
+
+ public String getContentType() {
+ contentType();
+ if ((contentTypeMB == null) || contentTypeMB.isNull())
+ return null;
+ return contentTypeMB.toString();
+ }
+
+
+ public void setContentType(String type) {
+ contentTypeMB.setString(type);
+ }
+
+
+ public MessageBytes contentType() {
+ if (contentTypeMB == null || contentTypeMB.isNull())
+ contentTypeMB = headers.getValue("content-type");
+ return contentTypeMB;
+ }
+
+ public int getServerPort() {
+ return serverPort;
+ }
+
+ public void setServerPort(int serverPort ) {
+ this.serverPort=serverPort;
+ }
+
+ public MessageBytes remoteAddr() {
+ return remoteAddrMB;
+ }
+
+ public MessageBytes remoteHost() {
+ return remoteHostMB;
+ }
+
+ public MessageBytes localName() {
+ return localNameMB;
+ }
+
+ public MessageBytes localAddr() {
+ return localAddrMB;
+ }
+
+ public int getRemotePort(){
+ return remotePort;
+ }
+
+ public void setRemotePort(int port){
+ this.remotePort = port;
+ }
+
+ public int getLocalPort(){
+ return localPort;
+ }
+
+ public void setLocalPort(int port){
+ this.localPort = port;
+ }
+
+ public MessageBytes queryString() {
+ return queryMB;
+ }
+
+ public MessageBytes protocol() {
+ return protoMB;
+ }
+
+ public MessageBytes scheme() {
+ return schemeMB;
+ }
+
+ public MessageBytes serverName() {
+ return serverNameMB;
+ }
+
+ public MessageBytes unparsedURI() {
+ return unparsedURIMB;
+ }
+
+ public Cookies getCookies() {
+ return cookies;
+ }
+
+ public UDecoder getURLDecoder() {
+ return urlDecoder;
+ }
+
+}
+
--- /dev/null
+/*
+ */
+package org.apache.tomcat.util.http;
+
+import org.apache.tomcat.util.buf.MessageBytes;
+
+/**
+ * The data fields in a HTTP response and few helper and accessors.
+ * No actions - just a struct.
+ *
+ * Subset of coyte response.
+ *
+ * @author Costin Manolache
+ */
+public class HttpResponse {
+ // Primary fields
+ // in coyote message is String, status is int
+ protected MessageBytes message = MessageBytes.newInstance();
+ protected MessageBytes proto = MessageBytes.newInstance();
+ protected MessageBytes statusBuffer = MessageBytes.newInstance();
+ protected MimeHeaders headers = new MimeHeaders();
+ public Object nativeResponse;
+
+ boolean commited;
+
+ public void recycle() {
+ getMimeHeaders().recycle();
+ message.recycle();
+ statusBuffer.setInt(200);
+ commited = false;
+ }
+
+ public boolean isCommitted() {
+ return commited;
+ }
+
+ public void setCommitted(boolean b) {
+ commited = b;
+ }
+
+ // Methods named for compat with coyote
+
+ public void setStatus(int i) {
+ statusBuffer.setInt(i);
+ }
+
+ public void setMessage(String s) {
+ message.setString(s);
+ }
+
+ public String getMessage() {
+ return message.toString();
+ }
+
+ public MessageBytes getMessageBuffer() {
+ return message;
+ }
+
+ public MessageBytes protocol() {
+ return proto;
+ }
+
+ public int getStatus() {
+ return statusBuffer.getInt();
+ }
+
+ public MessageBytes getStatusBuffer() {
+ return statusBuffer;
+ }
+
+
+ public void addHeader(String name, String value) {
+ getMimeHeaders().addValue(name).setString(value);
+ }
+
+ public void setHeader(String name, String value) {
+ getMimeHeaders().setValue(name).setString(value);
+ }
+
+ public void setMimeHeaders(MimeHeaders resHeaders) {
+ this.headers = resHeaders;
+ }
+
+ public MimeHeaders getMimeHeaders() {
+ return headers;
+ }
+
+ /**
+ * Warning: This method always returns <code>false<code> for Content-Type
+ * and Content-Length.
+ */
+ public boolean containsHeader(String name) {
+ return headers.getHeader(name) != null;
+ }
+
+ public void setContentLength(long length) {
+ MessageBytes clB = getMimeHeaders().getUniqueValue("content-length");
+ if (clB == null) {
+ clB = getMimeHeaders().addValue("content-length");
+ }
+ clB.setLong(length);
+ }
+
+ public long getContentLength() {
+ MessageBytes clB = getMimeHeaders().getUniqueValue("content-length");
+ return (clB == null || clB.isNull()) ? -1 : clB.getLong();
+ }
+
+ public void setContentType(String contentType) {
+ MessageBytes clB = getMimeHeaders().getUniqueValue("content-type");
+ if (clB == null) {
+ setHeader("content-type", contentType);
+ } else {
+ clB.setString(contentType);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.util.http;
+
+import java.net.*;
+import java.util.*;
+
+
+/**
+ * A mime type map that implements the java.net.FileNameMap interface.
+ *
+ * @author James Duncan Davidson [duncan@eng.sun.com]
+ * @author Jason Hunter [jch@eng.sun.com]
+ */
+public class MimeMap implements FileNameMap {
+
+ // Defaults - all of them are "well-known" types,
+ // you can add using normal web.xml.
+
+ public static Hashtable<String,String> defaultMap =
+ new Hashtable<String,String>(101);
+ static {
+ defaultMap.put("txt", "text/plain");
+ defaultMap.put("css", "text/css");
+ defaultMap.put("html","text/html");
+ defaultMap.put("htm", "text/html");
+ defaultMap.put("gif", "image/gif");
+ defaultMap.put("jpg", "image/jpeg");
+ defaultMap.put("jpe", "image/jpeg");
+ defaultMap.put("jpeg", "image/jpeg");
+ defaultMap.put("png", "image/png");
+ defaultMap.put("java", "text/plain");
+ defaultMap.put("body", "text/html");
+ defaultMap.put("rtx", "text/richtext");
+ defaultMap.put("tsv", "text/tab-separated-values");
+ defaultMap.put("etx", "text/x-setext");
+ defaultMap.put("ps", "application/x-postscript");
+ defaultMap.put("class", "application/java");
+ defaultMap.put("csh", "application/x-csh");
+ defaultMap.put("sh", "application/x-sh");
+ defaultMap.put("tcl", "application/x-tcl");
+ defaultMap.put("tex", "application/x-tex");
+ defaultMap.put("texinfo", "application/x-texinfo");
+ defaultMap.put("texi", "application/x-texinfo");
+ defaultMap.put("t", "application/x-troff");
+ defaultMap.put("tr", "application/x-troff");
+ defaultMap.put("roff", "application/x-troff");
+ defaultMap.put("man", "application/x-troff-man");
+ defaultMap.put("me", "application/x-troff-me");
+ defaultMap.put("ms", "application/x-wais-source");
+ defaultMap.put("src", "application/x-wais-source");
+ defaultMap.put("zip", "application/zip");
+ defaultMap.put("bcpio", "application/x-bcpio");
+ defaultMap.put("cpio", "application/x-cpio");
+ defaultMap.put("gtar", "application/x-gtar");
+ defaultMap.put("shar", "application/x-shar");
+ defaultMap.put("sv4cpio", "application/x-sv4cpio");
+ defaultMap.put("sv4crc", "application/x-sv4crc");
+ defaultMap.put("tar", "application/x-tar");
+ defaultMap.put("ustar", "application/x-ustar");
+ defaultMap.put("dvi", "application/x-dvi");
+ defaultMap.put("hdf", "application/x-hdf");
+ defaultMap.put("latex", "application/x-latex");
+ defaultMap.put("bin", "application/octet-stream");
+ defaultMap.put("oda", "application/oda");
+ defaultMap.put("pdf", "application/pdf");
+ defaultMap.put("ps", "application/postscript");
+ defaultMap.put("eps", "application/postscript");
+ defaultMap.put("ai", "application/postscript");
+ defaultMap.put("rtf", "application/rtf");
+ defaultMap.put("nc", "application/x-netcdf");
+ defaultMap.put("cdf", "application/x-netcdf");
+ defaultMap.put("cer", "application/x-x509-ca-cert");
+ defaultMap.put("exe", "application/octet-stream");
+ defaultMap.put("gz", "application/x-gzip");
+ defaultMap.put("Z", "application/x-compress");
+ defaultMap.put("z", "application/x-compress");
+ defaultMap.put("hqx", "application/mac-binhex40");
+ defaultMap.put("mif", "application/x-mif");
+ defaultMap.put("ief", "image/ief");
+ defaultMap.put("tiff", "image/tiff");
+ defaultMap.put("tif", "image/tiff");
+ defaultMap.put("ras", "image/x-cmu-raster");
+ defaultMap.put("pnm", "image/x-portable-anymap");
+ defaultMap.put("pbm", "image/x-portable-bitmap");
+ defaultMap.put("pgm", "image/x-portable-graymap");
+ defaultMap.put("ppm", "image/x-portable-pixmap");
+ defaultMap.put("rgb", "image/x-rgb");
+ defaultMap.put("xbm", "image/x-xbitmap");
+ defaultMap.put("xpm", "image/x-xpixmap");
+ defaultMap.put("xwd", "image/x-xwindowdump");
+ defaultMap.put("au", "audio/basic");
+ defaultMap.put("snd", "audio/basic");
+ defaultMap.put("aif", "audio/x-aiff");
+ defaultMap.put("aiff", "audio/x-aiff");
+ defaultMap.put("aifc", "audio/x-aiff");
+ defaultMap.put("wav", "audio/x-wav");
+ defaultMap.put("mpeg", "video/mpeg");
+ defaultMap.put("mpg", "video/mpeg");
+ defaultMap.put("mpe", "video/mpeg");
+ defaultMap.put("qt", "video/quicktime");
+ defaultMap.put("mov", "video/quicktime");
+ defaultMap.put("avi", "video/x-msvideo");
+ defaultMap.put("movie", "video/x-sgi-movie");
+ defaultMap.put("avx", "video/x-rad-screenplay");
+ defaultMap.put("wrl", "x-world/x-vrml");
+ defaultMap.put("mpv2", "video/mpeg2");
+
+ /* Add XML related MIMEs */
+
+ defaultMap.put("xml", "text/xml");
+ defaultMap.put("xsl", "text/xml");
+ defaultMap.put("svg", "image/svg+xml");
+ defaultMap.put("svgz", "image/svg+xml");
+ defaultMap.put("wbmp", "image/vnd.wap.wbmp");
+ defaultMap.put("wml", "text/vnd.wap.wml");
+ defaultMap.put("wmlc", "application/vnd.wap.wmlc");
+ defaultMap.put("wmls", "text/vnd.wap.wmlscript");
+ defaultMap.put("wmlscriptc", "application/vnd.wap.wmlscriptc");
+ }
+
+
+ private Hashtable<String,String> map = new Hashtable<String,String>();
+
+ public void addContentType(String extn, String type) {
+ map.put(extn, type.toLowerCase());
+ }
+
+ public Enumeration getExtensions() {
+ return map.keys();
+ }
+
+ public String getMimeType(String ext) {
+ return getContentTypeFor(ext);
+ }
+
+ public String getContentType(String extn) {
+ String type = (String)map.get(extn.toLowerCase());
+ if( type == null ) type=(String)defaultMap.get( extn );
+ return type;
+ }
+
+ public void removeContentType(String extn) {
+ map.remove(extn.toLowerCase());
+ }
+
+ /** Get extension of file, without fragment id
+ */
+ public static String getExtension( String fileName ) {
+ // play it safe and get rid of any fragment id
+ // that might be there
+ int length=fileName.length();
+
+ int newEnd = fileName.lastIndexOf('#');
+ if( newEnd== -1 ) newEnd=length;
+ // Instead of creating a new string.
+ // if (i != -1) {
+ // fileName = fileName.substring(0, i);
+ // }
+ int i = fileName.lastIndexOf('.', newEnd );
+ if (i != -1) {
+ return fileName.substring(i + 1, newEnd );
+ } else {
+ // no extension, no content type
+ return null;
+ }
+ }
+
+ public String getContentTypeFor(String fileName) {
+ String extn=getExtension( fileName );
+ if (extn!=null) {
+ return getContentType(extn);
+ } else {
+ // no extension, no content type
+ return null;
+ }
+ }
+
+}
package org.apache.tomcat.util.http.mapper;
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.buf.Ascii;
-
import java.io.File;
import java.io.IOException;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tomcat.util.buf.Ascii;
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
/**
* Mapper, which implements the servlet API mapping rules (which are derived