+++ /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.coyote.servlet;
-
-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
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.coyote.servlet;
-
-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(StringBuilder sb)
- throws IOException {
-
- if (suspended)
- return;
-
- state = CHAR_STATE;
-
- int len = sb.length();
- charsWritten += len;
- cb.append(sb.toString());
-
- }
-
-
- /**
- * 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
-en=ISO-8859-1
-fr=ISO-8859-1
+++ /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.coyote.servlet;
-
-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() {
-
- StringBuilder sb = new StringBuilder("ClientAbortException: ");
- if (message != null) {
- sb.append(message);
- if (throwable != null) {
- sb.append(": ");
- }
- }
- if (throwable != null) {
- sb.append(throwable.toString());
- }
- return (sb.toString());
-
- }
-
-
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-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.
- *
- * Currently we have lots of deps on coyote Request, but I plan to
- * change this and allow other HTTP implementations - like MINA, the
- * experimental async connector, etc. Most important will be
- * different support for IO - i.e. a more non-blocking mode.
- * We'll probably keep MessageBytes as wrappers for request/res
- * properties.
- *
- * This interface has no dep on coyote.
- *
- */
-public interface Connector {
-
- public void setDaemon(boolean b);
-
- public void start() throws IOException;
-
- public void stop() throws Exception;
-
- /**
- * 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);
-
- void initRequest(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;
-}
+++ /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.coyote.servlet;
-
-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.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;
- }
-
- public boolean asyncDispatch(Request req,Response res, SocketStatus status) throws Exception {
- // implement me
- return false;
- }
-
-}
+++ /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.coyote.servlet;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-/**
- * Wraps the list of filters for the current request. One instance
- * associated with each RequestImpl, reused.
- *
- * Populated by the mapper ( WebappFilterMapper for example ), which
- * determines the filters for the current request.
- *
- * Not thread safe.
- */
-public final class FilterChainImpl implements FilterChain {
- private List<FilterConfigImpl> filters = new ArrayList<FilterConfigImpl>();
-
-
- /**
- * The int which is used to maintain the current position
- * in the filter chain.
- */
- private int pos = 0;
-
- /**
- * The servlet instance to be executed by this chain.
- */
- private Servlet servlet = null;
-
-
- private ServletConfigImpl wrapper;
-
-
- public FilterChainImpl() {
- super();
- }
-
-
- /**
- * Invoke the next filter in this chain, passing the specified request
- * and response. If there are no more filters in this chain, invoke
- * the <code>service()</code> method of the servlet itself.
- *
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet exception occurs
- */
- public void doFilter(ServletRequest request, ServletResponse response)
- throws IOException, ServletException {
-
-
- // Call the next filter if there is one
- if (pos < filters.size()) {
- FilterConfigImpl filterConfig = filters.get(pos++);
- Filter filter = null;
- try {
- filter = filterConfig.getFilter();
- filter.doFilter(request, response, this);
- } catch (IOException e) {
- throw e;
- } catch (ServletException e) {
- throw e;
- } catch (RuntimeException e) {
- throw e;
- } catch (Throwable e) {
- e.printStackTrace();
- throw new ServletException("Throwable", e);
- }
- return;
- }
-
- // We fell off the end of the chain -- call the servlet instance
- try {
- if (servlet != null)
- servlet.service(request, response);
- } catch (IOException e) {
- throw e;
- } catch (ServletException e) {
- throw e;
- } catch (RuntimeException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("Throwable", e);
- }
- }
-
-
- // -------------------------------------------------------- Package Methods
-
-
-
- /**
- * Add a filter to the set of filters that will be executed in this chain.
- *
- * @param filterConfig The FilterConfig for the servlet to be executed
- */
- public void addFilter(FilterConfigImpl filterConfig) {
- filters.add(filterConfig);
- }
-
-
- /**
- * Release references to the filters and wrapper executed by this chain.
- */
- public void release() {
- filters.clear();
- pos = 0;
- servlet = null;
- }
-
-
- /**
- * Set the servlet that will be executed at the end of this chain.
- * Set by the mapper filter
- */
- public void setServlet(ServletConfigImpl wrapper, Servlet servlet) {
- this.wrapper = wrapper;
- this.servlet = servlet;
- }
-
- // ------ Getters for information ------------
-
- public int getSize() {
- return filters.size();
- }
-
- public FilterConfigImpl getFilter(int i) {
- return filters.get(i);
- }
-
- public Servlet getServlet() {
- return servlet;
- }
-
- public ServletConfigImpl getServletConfig() {
- return wrapper;
- }
-
- public int getPos() {
- return pos;
- }
-}
+++ /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.coyote.servlet;
-
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.FilterConfig;
-import javax.servlet.FilterRegistration;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.FilterRegistration.Dynamic;
-
-import org.apache.tomcat.servlets.util.Enumerator;
-
-
-/**
- * A Filter is configured in web.xml by:
- * - name - used in mappings
- * - className - used to instantiate the filter
- * - init params
- * - other things not used in the servlet container ( icon, descr, etc )
- *
- * Alternatively, in API mode you can pass the actual filter.
- *
- * @see ServletConfigImpl
- */
-public final class FilterConfigImpl implements FilterConfig, FilterRegistration {
-
- DynamicFilterRegistration dynamic = new DynamicFilterRegistration();
-
- public FilterConfigImpl(ServletContextImpl context) {
- this.ctx = context;
- }
-
- boolean asyncSupported;
-
- private ServletContextImpl ctx = null;
-
- /**
- * The application Filter we are configured for.
- */
- private transient Filter filter = null;
-
- String descryption;
-
- private String filterName;
-
- private String filterClassName;
-
- Map<String, String> initParams;
-
- private Class<? extends Filter> filterClass;
-
- public void setData(String filterName, String filterClass,
- Map<String, String> params) {
- this.filterName = filterName;
- this.filterClassName = filterClass;
- this.initParams = params;
- }
-
- public void setFilter(Filter f) {
- filter = f;
- }
-
- public String getFilterName() {
- return filterName;
- }
-
- public void setFilterClass(Class<? extends Filter> filterClass2) {
- this.filterClass = filterClass2;
- }
-
-
- public String getInitParameter(String name) {
- if (initParams == null) return null;
- return initParams.get(name);
- }
-
- /**
- * Return an <code>Enumeration</code> of the names of the initialization
- * parameters for this Filter.
- */
- public Enumeration getInitParameterNames() {
- if (initParams == null)
- return (new Enumerator(new ArrayList()));
- else
- return (new Enumerator(initParams.keySet()));
- }
-
-
- /**
- * Return the ServletContext of our associated web application.
- */
- public ServletContext getServletContext() {
- return ctx;
- }
-
- /**
- * Return the application Filter we are configured for.
- */
- public Filter createFilter() throws ClassCastException, ClassNotFoundException,
- IllegalAccessException, InstantiationException, ServletException {
-
- // Return the existing filter instance, if any
- if (filter != null)
- return filter;
-
- ClassLoader classLoader = ctx.getClassLoader();
-
- ClassLoader oldCtxClassLoader =
- Thread.currentThread().getContextClassLoader();
- if (classLoader != oldCtxClassLoader) {
- Thread.currentThread().setContextClassLoader(classLoader);
- }
- try {
- if (filterClass == null) {
- filterClass = (Class<? extends Filter>) classLoader.loadClass(filterClassName);
- }
- this.filter = (Filter) filterClass.newInstance();
- } finally {
- if (classLoader != oldCtxClassLoader) {
- Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
- }
- }
-
- // TODO: resource injection
-
- return filter;
- }
-
- public Filter getFilter() throws ClassCastException, ClassNotFoundException, IllegalAccessException, InstantiationException, ServletException {
- Filter filter = createFilter();
- filter.init(this);
- return (this.filter);
- }
-
-
- /**
- * Release the Filter instance associated with this FilterConfig,
- * if there is one.
- */
- public void release() {
- if (this.filter != null){
- filter.destroy();
- }
- this.filter = null;
- }
-
-
- @Override
- public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... servletNames) {
- if (ctx.startDone) {
- // Use the context method instead of the servlet API to
- // add mappings after context init.
- throw new IllegalStateException();
- }
- ArrayList<String> dispatchers = new ArrayList<String>();
- for (DispatcherType dt: dispatcherTypes) {
- dispatchers.add(dt.name());
- }
- for (String servletName: servletNames) {
- ctx.getFilterMapper().addMapping(getFilterName(),
- null, servletName, (String[]) dispatchers.toArray(), isMatchAfter);
- }
- }
-
-
- @Override
- public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... urlPatterns) {
- if (ctx.startDone) {
- // Use the context method instead of the servlet API to
- // add mappings after context init.
- throw new IllegalStateException();
- }
- ArrayList<String> dispatchers = new ArrayList<String>();
- for (DispatcherType dt: dispatcherTypes) {
- dispatchers.add(dt.name());
- }
- for (String url: urlPatterns) {
- ctx.getFilterMapper().addMapping(getFilterName(),
- url, null, (String[]) dispatchers.toArray(), isMatchAfter);
- }
- }
-
-
- @Override
- public boolean setInitParameter(String name, String value)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
- name, value);
- }
-
-
- @Override
- public Set<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
- initParameters);
- }
-
- public Dynamic getDynamic() {
- return dynamic;
- }
-
- public class DynamicFilterRegistration implements Dynamic {
-
-
- @Override
- public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... servletNames) {
- FilterConfigImpl.this.addMappingForServletNames(dispatcherTypes, isMatchAfter, servletNames);
- }
-
-
- @Override
- public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes,
- boolean isMatchAfter,
- String... urlPatterns) {
- FilterConfigImpl.this.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns);
- }
-
-
- @Override
- public boolean setInitParameter(String name, String value)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
- name, value);
- }
-
-
- @Override
- public Set<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
- initParameters);
- }
-
-
- @Override
- public void setAsyncSupported(boolean isAsyncSupported)
- throws IllegalStateException {
- asyncSupported = isAsyncSupported;
- }
-
-
- public void setDescription(String description)
- throws IllegalStateException {
- FilterConfigImpl.this.descryption = description;
- }
-
- @Override
- public Collection<String> getUrlPatternMappings() {
- // implement me
- return null;
- }
-
- @Override
- public Collection<String> getServletNameMappings() {
- // implement me
- return null;
- }
-
- @Override
- public Map<String, String> getInitParameters() {
- // implement me
- return null;
- }
-
- @Override
- public String getInitParameter(String name) {
- if (initParams == null) return null;
- return initParams.get(name);
- }
-
- @Override
- public String getClassName() {
- // implement me
- return null;
- }
-
- @Override
- public String getName() {
- // implement me
- return null;
- }
- }
-
- @Override
- public Collection<String> getUrlPatternMappings() {
- // implement me
- return null;
- }
-
- @Override
- public Collection<String> getServletNameMappings() {
- // implement me
- return null;
- }
-
- @Override
- public Map<String, String> getInitParameters() {
- // implement me
- return null;
- }
-
- @Override
- public String getClassName() {
- // implement me
- return null;
- }
-
- @Override
- public String getName() {
- // implement me
- return null;
- }
-
-}
+++ /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.coyote.servlet;
-
-import javax.servlet.ServletContext;
-
-import org.apache.tomcat.servlets.jsp.BaseJspLoader;
-
-public class JspLoader extends BaseJspLoader {
-
- public ClassLoader getClassLoader(ServletContext ctx) {
- return ((ServletContextImpl) ctx).getClassLoader();
- }
-
- public String getClassPath(ServletContext ctx) {
- return ((ServletContextImpl) ctx).getClassPath();
- }
-}
+++ /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.coyote.servlet;
-
-
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.Properties;
-
-
-
-/**
- * One instance per Context. Holds the
- *
- * Utility class that attempts to map from a Locale to the corresponding
- * character set to be used for interpreting input text (or generating
- * output text) when the Content-Type header does not include one. You
- * can customize the behavior of this class by modifying the mapping data
- * it loads, or by subclassing it (to change the algorithm) and then using
- * your own version for a particular web application.
- *
- * @author Craig R. McClanahan
- */
-public class Locale2Charset {
-
-
- // ---------------------------------------------------- Manifest Constants
-
-
- /**
- * Default properties resource name.
- */
- public static final String DEFAULT_RESOURCE =
- "/org/apache/coyote/servlet/CharsetMapperDefault.properties";
-
-
-
- // ---------------------------------------------------------- Constructors
-
-
- /**
- * Construct a new CharsetMapper using the default properties resource.
- */
- public Locale2Charset() {
- String name = DEFAULT_RESOURCE;
- if (defaultMap == null) { // once !
- try {
- defaultMap = new Properties();
- InputStream stream =
- this.getClass().getResourceAsStream(name);
- defaultMap.load(stream);
- stream.close();
- } catch (Throwable t) {
- throw new IllegalArgumentException(t.toString());
- }
- }
- map = defaultMap;
- }
-
-
- // ---------------------------------------------------- Instance Variables
-
-
- private static Properties defaultMap; // shared for all apps
-
- /**
- * The mapping properties that have been initialized from the specified or
- * default properties resource.
- */
- private Properties map;
-
-
- // ------------------------------------------------------- Public Methods
-
-
- /**
- * Calculate the name of a character set to be assumed, given the specified
- * Locale and the absence of a character set specified as part of the
- * content type header.
- *
- * @param locale The locale for which to calculate a character set
- */
- public String getCharset(Locale locale) {
- // Match full language_country_variant first, then language_country,
- // then language only
- String charset = map.getProperty(locale.toString());
- if (charset == null) {
- charset = map.getProperty(locale.getLanguage() + "_"
- + locale.getCountry());
- if (charset == null) {
- charset = map.getProperty(locale.getLanguage());
- }
- }
- return (charset);
- }
-
-
- /**
- * The deployment descriptor can have a
- * locale-encoding-mapping-list element which describes the
- * webapp's desired mapping from locale to charset. This method
- * gets called when processing the web.xml file for a context
- *
- * @param locale The locale for a character set
- * @param charset The charset to be associated with the locale
- */
- public void addCharsetMapping(String locale, String charset) {
- if (map == defaultMap) {
- // new copy, don't modify original
- map = new Properties(defaultMap);
- }
- map.put(locale, charset);
- }
-}
+++ /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.coyote.servlet;
-
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-/**
- * Extended implementation of <strong>HashMap</strong> that includes a
- * <code>locked</code> property. This class can be used to safely expose
- * Catalina internal parameter map objects to user classes without having
- * to clone them in order to avoid modifications. When first created, a
- * <code>ParmaeterMap</code> instance is not locked.
- *
- * @author Craig R. McClanahan
- * @version $Revision$ $Date$
- */
-
-public final class ParameterMap extends HashMap {
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Construct a new, empty map with the default initial capacity and
- * load factor.
- */
- public ParameterMap() {
-
- super();
-
- }
-
-
- /**
- * Construct a new, empty map with the specified initial capacity and
- * default load factor.
- *
- * @param initialCapacity The initial capacity of this map
- */
- public ParameterMap(int initialCapacity) {
-
- super(initialCapacity);
-
- }
-
-
- /**
- * Construct a new, empty map with the specified initial capacity and
- * load factor.
- *
- * @param initialCapacity The initial capacity of this map
- * @param loadFactor The load factor of this map
- */
- public ParameterMap(int initialCapacity, float loadFactor) {
-
- super(initialCapacity, loadFactor);
-
- }
-
-
- /**
- * Construct a new map with the same mappings as the given map.
- *
- * @param map Map whose contents are dupliated in the new map
- */
- public ParameterMap(Map map) {
-
- super(map);
-
- }
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * The current lock state of this parameter map.
- */
- private boolean locked = false;
-
-
- /**
- * Return the locked state of this parameter map.
- */
- public boolean isLocked() {
-
- return (this.locked);
-
- }
-
-
- /**
- * Set the locked state of this parameter map.
- *
- * @param locked The new locked state
- */
- public void setLocked(boolean locked) {
-
- this.locked = locked;
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
-
- /**
- * Remove all mappings from this map.
- *
- * @exception IllegalStateException if this map is currently locked
- */
- public void clear() {
-
- if (locked)
- throw new IllegalStateException
- ("parameterMap.locked");
- super.clear();
-
- }
-
-
- /**
- * Associate the specified value with the specified key in this map. If
- * the map previously contained a mapping for this key, the old value is
- * replaced.
- *
- * @param key Key with which the specified value is to be associated
- * @param value Value to be associated with the specified key
- *
- * @return The previous value associated with the specified key, or
- * <code>null</code> if there was no mapping for key
- *
- * @exception IllegalStateException if this map is currently locked
- */
- public Object put(Object key, Object value) {
-
- if (locked)
- throw new IllegalStateException
- ("parameterMap.locked");
- return (super.put(key, value));
-
- }
-
-
- /**
- * Copy all of the mappings from the specified map to this one. These
- * mappings replace any mappings that this map had for any of the keys
- * currently in the specified Map.
- *
- * @param map Mappings to be stored into this map
- *
- * @exception IllegalStateException if this map is currently locked
- */
- public void putAll(Map map) {
-
- if (locked)
- throw new IllegalStateException
- ("parameterMap.locked");
- super.putAll(map);
-
- }
-
-
- /**
- * Remove the mapping for this key from the map if present.
- *
- * @param key Key whose mapping is to be removed from the map
- *
- * @return The previous value associated with the specified key, or
- * <code>null</code> if there was no mapping for that key
- *
- * @exception IllegalStateException if this map is currently locked
- */
- public Object remove(Object key) {
-
- if (locked)
- throw new IllegalStateException
- ("parameterMap.locked");
- return (super.remove(key));
-
- }
-
-
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.RequestDispatcher;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletRequestWrapper;
-import javax.servlet.ServletResponse;
-import javax.servlet.ServletResponseWrapper;
-import javax.servlet.UnavailableException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.mapper.MappingData;
-
-/**
- *
- */
-public final class RequestDispatcherImpl implements RequestDispatcher {
- /**
- * The request attribute under which the original servlet path is stored
- * on an forwarded dispatcher request.
- */
- public static final String FORWARD_SERVLET_PATH_ATTR =
- "javax.servlet.forward.servlet_path";
-
-
- /**
- * The request attribute under which the original query string is stored
- * on an forwarded dispatcher request.
- */
- public static final String FORWARD_QUERY_STRING_ATTR =
- "javax.servlet.forward.query_string";
-
- /**
- * The request attribute under which the original request URI is stored
- * on an forwarded dispatcher request.
- */
- public static final String FORWARD_REQUEST_URI_ATTR =
- "javax.servlet.forward.request_uri";
-
-
- /**
- * The request attribute under which the original context path is stored
- * on an forwarded dispatcher request.
- */
- public static final String FORWARD_CONTEXT_PATH_ATTR =
- "javax.servlet.forward.context_path";
-
-
- /**
- * The request attribute under which the original path info is stored
- * on an forwarded dispatcher request.
- */
- public static final String FORWARD_PATH_INFO_ATTR =
- "javax.servlet.forward.path_info";
-
- /**
- * The request attribute under which we store the servlet name on a
- * named dispatcher request.
- */
- public static final String NAMED_DISPATCHER_ATTR =
- "org.apache.catalina.NAMED";
-
- /**
- * The request attribute under which the request URI of the included
- * servlet is stored on an included dispatcher request.
- */
- public static final String INCLUDE_REQUEST_URI_ATTR =
- "javax.servlet.include.request_uri";
-
-
- /**
- * The request attribute under which the context path of the included
- * servlet is stored on an included dispatcher request.
- */
- public static final String INCLUDE_CONTEXT_PATH_ATTR =
- "javax.servlet.include.context_path";
-
-
- /**
- * The request attribute under which the path info of the included
- * servlet is stored on an included dispatcher request.
- */
- public static final String INCLUDE_PATH_INFO_ATTR =
- "javax.servlet.include.path_info";
-
-
- /**
- * The request attribute under which the servlet path of the included
- * servlet is stored on an included dispatcher request.
- */
- public static final String INCLUDE_SERVLET_PATH_ATTR =
- "javax.servlet.include.servlet_path";
-
-
- /**
- * The request attribute under which the query string of the included
- * servlet is stored on an included dispatcher request.
- */
- public static final String INCLUDE_QUERY_STRING_ATTR =
- "javax.servlet.include.query_string";
-
- /**
- * The request attribute under which we expose the value of the
- * <code><jsp-file></code> value associated with this servlet,
- * if any.
- */
- public static final String JSP_FILE_ATTR =
- "org.apache.catalina.jsp_file";
-
-
- // ----------------------------------------------------- Instance Variables
-
- private static Logger log = Logger.getLogger(RequestDispatcherImpl.class.getName());
-
- private ServletContextImpl ctx = null;
-
- /**
- * The servlet name for a named dispatcher.
- */
- private String name = null;
-
- // Path for a path dispatcher
- private String path;
-
- /**
- * MappingData object - per thread for buffering.
- */
- private transient ThreadLocal localMappingData = new ThreadLocal();
-
- /*
- OrigRequest(ServletRequestImpl) -> include/forward * -> this include
-
- On the path: user-defined RequestWrapper or our ServletRequestWrapper
-
- include() is called with a RequestWrapper(->...->origRequest) or origRequest
-
- Based on params, etc -> we wrap the req / response in ServletRequestWrapper,
- call filters+servlet. Inside, the req can be wrapped again in
- userReqWrapper, and other include called.
-
-
- */
-
- /**
- * The outermost request that will be passed on to the invoked servlet.
- */
- private ServletRequest outerRequest = null;
-
- /**
- * The outermost response that will be passed on to the invoked servlet.
- */
- private ServletResponse outerResponse = null;
-
- /**
- * The request wrapper we have created and installed (if any).
- */
- private ServletRequest wrapRequest = null;
-
- /**
- * The response wrapper we have created and installed (if any).
- */
- private ServletResponse wrapResponse = null;
-
- // Parameters used when constructing the dispatcvher
- /**
- * The extra path information for this RequestDispatcher.
- */
- private String pathInfo = null;
- /**
- * The query string parameters for this RequestDispatcher.
- */
- private String queryString = null;
- /**
- * The request URI for this RequestDispatcher.
- */
- private String requestURI = null;
- /**
- * The servlet path for this RequestDispatcher.
- */
- private String servletPath = null;
-
- //
- private String origServletPath = null;
-
- /**
- * The Wrapper associated with the resource that will be forwarded to
- * or included.
- */
- private ServletConfigImpl wrapper = null;
-
- private Servlet servlet;
-
- /** Named dispatcher
- */
- public RequestDispatcherImpl(ServletConfigImpl wrapper, String name) {
- this.wrapper = wrapper;
- this.name = name;
- this.ctx = (ServletContextImpl) wrapper.getServletContext();
-
- }
-
- public RequestDispatcherImpl(ServletContextImpl ctx, String path) {
- this.path = path;
- this.ctx = ctx;
- }
-
-
-
- /**
- * Forward this request and response to another resource for processing.
- * Any runtime exception, IOException, or ServletException thrown by the
- * called servlet will be propogated to the caller.
- *
- * @param request The servlet request to be forwarded
- * @param response The servlet response to be forwarded
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet exception occurs
- */
- public void forward(ServletRequest request, ServletResponse response)
- throws ServletException, IOException
- {
- // Reset any output that has been buffered, but keep headers/cookies
- if (response.isCommitted()) {
- throw new IllegalStateException("forward(): response.isComitted()");
- }
-
- try {
- response.resetBuffer();
- } catch (IllegalStateException e) {
- throw e;
- }
-
- // Set up to handle the specified request and response
- setup(request, response, false);
-
- // Identify the HTTP-specific request and response objects (if any)
- HttpServletRequest hrequest = (HttpServletRequest) request;
-
- ServletRequestWrapperImpl wrequest =
- (ServletRequestWrapperImpl) wrapRequest();
-
-
- if (name != null) {
- wrequest.setRequestURI(hrequest.getRequestURI());
- wrequest.setContextPath(hrequest.getContextPath());
- wrequest.setServletPath(hrequest.getServletPath());
- wrequest.setPathInfo(hrequest.getPathInfo());
- wrequest.setQueryString(hrequest.getQueryString());
-
-
- } else { // path based
- mapPath();
- if (wrapper == null) {
- throw new ServletException("Forward not found " +
- path);
- }
- String contextPath = ctx.getContextPath();
- if (hrequest.getAttribute(FORWARD_REQUEST_URI_ATTR) == null) {
- wrequest.setAttribute(FORWARD_REQUEST_URI_ATTR,
- hrequest.getRequestURI());
- wrequest.setAttribute(FORWARD_CONTEXT_PATH_ATTR,
- hrequest.getContextPath());
- wrequest.setAttribute(FORWARD_SERVLET_PATH_ATTR,
- hrequest.getServletPath());
- wrequest.setAttribute(FORWARD_PATH_INFO_ATTR,
- hrequest.getPathInfo());
- wrequest.setAttribute(FORWARD_QUERY_STRING_ATTR,
- hrequest.getQueryString());
- }
-
- wrequest.setContextPath(contextPath);
- wrequest.setRequestURI(requestURI);
- wrequest.setServletPath(servletPath);
- wrequest.setPathInfo(pathInfo);
- if (queryString != null) {
- wrequest.setQueryString(queryString);
- wrequest.setQueryParams(queryString);
- }
- }
- processRequest(outerRequest, outerResponse);
-
- wrequest.recycle();
- unwrapRequest();
-
- // This is not a real close in order to support error processing
-// if ( log.isDebugEnabled() )
-// log.debug(" Disabling the response for futher output");
-
- if (response instanceof ServletResponseImpl) {
- ((ServletResponseImpl) response).flushBuffer();
- ((ServletResponseImpl) response).setSuspended(true);
- } else {
- // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped
- // and may no longer be instance of RequestFacade
- if (log.isLoggable(Level.FINE)){
- log.fine( " The Response is vehiculed using a wrapper: "
- + response.getClass().getName() );
- }
-
- // Close anyway
- try {
- PrintWriter writer = response.getWriter();
- writer.close();
- } catch (IllegalStateException e) {
- try {
- ServletOutputStream stream = response.getOutputStream();
- stream.close();
- } catch (IllegalStateException f) {
- ;
- } catch (IOException f) {
- ;
- }
- } catch (IOException e) {
- ;
- }
- }
- }
-
-
-
- /**
- * Include the response from another resource in the current response.
- * Any runtime exception, IOException, or ServletException thrown by the
- * called servlet will be propogated to the caller.
- *
- * @param request The servlet request that is including this one
- * @param response The servlet response to be appended to
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet exception occurs
- */
- public void include(ServletRequest request, ServletResponse response)
- throws ServletException, IOException
- {
-
- // Set up to handle the specified request and response
- setup(request, response, true);
-
- // Create a wrapped response to use for this request
- // this actually gets inserted somewhere in the chain - it's not
- // the last one, but first non-user response
- wrapResponse();
- ServletRequestWrapperImpl wrequest =
- (ServletRequestWrapperImpl) wrapRequest();
-
-
- // Handle an HTTP named dispatcher include
- if (name != null) {
- wrequest.setAttribute(NAMED_DISPATCHER_ATTR, name);
- if (servletPath != null) wrequest.setServletPath(servletPath);
- wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
- new Integer(WebappFilterMapper.INCLUDE));
- wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR,
- origServletPath);
- } else {
- mapPath();
- String contextPath = ctx.getContextPath();
- if (requestURI != null)
- wrequest.setAttribute(INCLUDE_REQUEST_URI_ATTR,
- requestURI);
- if (contextPath != null)
- wrequest.setAttribute(INCLUDE_CONTEXT_PATH_ATTR,
- contextPath);
- if (servletPath != null)
- wrequest.setAttribute(INCLUDE_SERVLET_PATH_ATTR,
- servletPath);
- if (pathInfo != null)
- wrequest.setAttribute(INCLUDE_PATH_INFO_ATTR,
- pathInfo);
- if (queryString != null) {
- wrequest.setAttribute(INCLUDE_QUERY_STRING_ATTR,
- queryString);
- wrequest.setQueryParams(queryString);
- }
-
- wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
- new Integer(WebappFilterMapper.INCLUDE));
- wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR,
- origServletPath);
- }
-
- invoke(outerRequest, outerResponse);
-
- wrequest.recycle();
- unwrapRequest();
- unwrapResponse();
- }
-
-
- // -------------------------------------------------------- Private Methods
-
- public void mapPath() {
- if (path == null || servletPath != null) return;
-
- // Retrieve the thread local URI, used for mapping
- // TODO: recycle RequestDispatcher stack and associated objects
- // instead of this object
-
- // Retrieve the thread local mapping data
- MappingData mappingData = (MappingData) localMappingData.get();
- if (mappingData == null) {
- mappingData = new MappingData();
- localMappingData.set(mappingData);
- }
-
- // Get query string
- int pos = path.indexOf('?');
- if (pos >= 0) {
- queryString = path.substring(pos + 1);
- } else {
- pos = path.length();
- }
-
- // Map the URI
- MessageBytes uriMB = MessageBytes.newInstance();
- CharChunk charBuffer = new CharChunk();
- //mappingData.localURIBytes;
- uriMB.recycle();
- //CharChunk uriCC = uriMB.getCharChunk();
- try {
- /*
- * Ignore any trailing path params (separated by ';') for mapping
- * purposes.
- * This is sometimes broken - path params can be on any path
- * component, not just last.
- */
- int semicolon = path.indexOf(';');
- if (pos >= 0 && semicolon > pos) {
- semicolon = -1;
- }
- if (ctx.getContextPath().length() > 1 ) {
- charBuffer.append(ctx.getContextPath());
- }
- charBuffer.append(path, 0,
- semicolon > 0 ? semicolon : pos);
-
- // Wrap the buffer
- uriMB.setChars(charBuffer.getBuffer(),
- charBuffer.getOffset(),
- charBuffer.getLength());
-
- // TODO: make charBuffer part of request or something
- ctx.getMapper().map(uriMB, mappingData);
-
- // at least default wrapper must be returned
-
- /*
- * Append any trailing path params (separated by ';') that were
- * ignored for mapping purposes, so that they're reflected in the
- * RequestDispatcher's requestURI
- */
- if (semicolon > 0) {
- // I don't think this will be used in future
- charBuffer.append(path,
- semicolon, pos - semicolon);
- }
- } catch (Exception e) {
- log.log(Level.SEVERE, "getRequestDispatcher()", e);
- }
-
- wrapper = (ServletConfigImpl) mappingData.wrapper;
- servletPath = mappingData.wrapperPath.toString();
- pathInfo = mappingData.pathInfo.toString();
-
- mappingData.recycle();
-
- }
-
-
- /**
- * Prepare the request based on the filter configuration.
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet error occurs
- */
- private void processRequest(ServletRequest request,
- ServletResponse response)
- throws IOException, ServletException {
- Integer disInt =
- (Integer) request.getAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR);
- if (disInt != null) {
- if (disInt.intValue() != WebappFilterMapper.ERROR) {
- outerRequest.setAttribute
- (WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR,
- origServletPath);
- outerRequest.setAttribute
- (WebappFilterMapper.DISPATCHER_TYPE_ATTR,
- new Integer(WebappFilterMapper.FORWARD));
- }
- invoke(outerRequest, response);
- }
-
- }
-
-
-
-
- /**
- * Ask the resource represented by this RequestDispatcher to process
- * the associated request, and create (or append to) the associated
- * response.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong>: This implementation assumes
- * that no filters are applied to a forwarded or included resource,
- * because they were already done for the original request.
- *
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet error occurs
- */
- private void invoke(ServletRequest request, ServletResponse response)
- throws IOException, ServletException {
-
- // Checking to see if the context classloader is the current context
- // classloader. If it's not, we're saving it, and setting the context
- // classloader to the Context classloader
- ClassLoader oldCCL = Thread.currentThread().getContextClassLoader();
- ClassLoader contextClassLoader = ctx.getClassLoader();
-
- if (oldCCL != contextClassLoader) {
- Thread.currentThread().setContextClassLoader(contextClassLoader);
- } else {
- oldCCL = null;
- }
-
- // Initialize local variables we may need
- HttpServletResponse hresponse = (HttpServletResponse) response;
- IOException ioException = null;
- ServletException servletException = null;
- RuntimeException runtimeException = null;
-
- servletException = allocateServlet(hresponse, servletException);
-
- // Get the FilterChain Here
- WebappFilterMapper factory =
- ((ServletContextImpl)wrapper.getServletContext()).getFilterMapper();
-
- FilterChainImpl filterChain = factory.createFilterChain(request,
- wrapper,
- servlet);
-
- // Call the service() method for the allocated servlet instance
- try {
- String jspFile = wrapper.getJspFile();
- if (jspFile != null)
- request.setAttribute(JSP_FILE_ATTR, jspFile);
- else
- request.removeAttribute(JSP_FILE_ATTR);
- // for includes/forwards
- if ((servlet != null) && (filterChain != null)) {
- filterChain.doFilter(request, response);
- }
- } catch (IOException e) {
- ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " +
- wrapper.getServletName(), e);
- ioException = e;
- } catch (UnavailableException e) {
- ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " +
- wrapper.getServletName(), e);
- servletException = e;
- wrapper.unavailable(e);
- } catch (ServletException e) {
- servletException = e;
- } catch (RuntimeException e) {
- ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " +
- wrapper.getServletName(), e);
- runtimeException = e;
- }
- request.removeAttribute(JSP_FILE_ATTR);
-
- // Release the filter chain (if any) for this request
- if (filterChain != null)
- filterChain.release();
-
- servletException = servletDealocate(servletException);
-
- // Reset the old context class loader
- if (oldCCL != null)
- Thread.currentThread().setContextClassLoader(oldCCL);
-
- // Unwrap request/response if needed
- unwrapRequest();
- unwrapResponse();
-
- // Rethrow an exception if one was thrown by the invoked servlet
- if (ioException != null)
- throw ioException;
- if (servletException != null)
- throw servletException;
- if (runtimeException != null)
- throw runtimeException;
-
- }
-
- private ServletException servletDealocate(ServletException servletException)
- {
- if (servlet != null) {
- wrapper.deallocate(servlet);
- }
- return servletException;
- }
-
- private ServletException allocateServlet(HttpServletResponse hresponse,
- ServletException servletException)
- throws IOException
- {
- boolean unavailable = false;
-
- // Check for the servlet being marked unavailable
- if (wrapper.isUnavailable()) {
- ctx.getLogger().log(Level.WARNING, "isUnavailable() " + wrapper.getServletName());
- long available = wrapper.getAvailable();
- if ((available > 0L) && (available < Long.MAX_VALUE))
- hresponse.setDateHeader("Retry-After", available);
- hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
- "Unavailable"); // No need to include internal info: wrapper.getServletName();
- unavailable = true;
- }
-
- // Allocate a servlet instance to process this request
- try {
- if (!unavailable) {
- servlet = wrapper.allocate();
- }
- } catch (ServletException e) {
- ctx.getLogger().log(Level.WARNING, "RequestDispatcher: allocate " +
- wrapper.toString());
- servletException = e;
- servlet = null;
- } catch (Throwable e) {
- ctx.getLogger().log(Level.WARNING, "allocate() error " + wrapper.getServletName(), e);
- servletException = new ServletException
- ("Allocate error " + wrapper.getServletName(), e);
- servlet = null;
- }
- return servletException;
- }
-
-
- /**
- * Set up to handle the specified request and response
- *
- * @param request The servlet request specified by the caller
- * @param response The servlet response specified by the caller
- * @param including Are we performing an include() as opposed to
- * a forward()?
- */
- private void setup(ServletRequest request, ServletResponse response,
- boolean including) {
-
- this.outerRequest = request;
- this.outerResponse = response;
- }
-
-
- /**
- * Unwrap the request if we have wrapped it. Not sure how it could end
- * up in the middle.
- */
- private void unwrapRequest() {
- if (wrapRequest == null)
- return;
-
- ServletRequest previous = null;
- ServletRequest current = outerRequest;
- while (current != null) {
- // If we run into the container request we are done
- if (current instanceof ServletRequestImpl)
- break;
-
- // Remove the current request if it is our wrapper
- if (current == wrapRequest) {
- ServletRequest next =
- ((ServletRequestWrapper) current).getRequest();
- if (previous == null)
- outerRequest = next;
- else
- ((ServletRequestWrapper) previous).setRequest(next);
- break;
- }
-
- // Advance to the next request in the chain
- previous = current;
- current = ((ServletRequestWrapper) current).getRequest();
- }
- }
-
-
- /**
- * Unwrap the response if we have wrapped it.
- */
- private void unwrapResponse() {
- if (wrapResponse == null)
- return;
-
- ServletResponse previous = null;
- ServletResponse current = outerResponse;
- while (current != null) {
- // If we run into the container response we are done
- if (current instanceof ServletResponseImpl)
- break;
-
- // Remove the current response if it is our wrapper
- if (current == wrapResponse) {
- ServletResponse next =
- ((ServletResponseWrapper) current).getResponse();
- if (previous == null)
- outerResponse = next;
- else
- ((ServletResponseWrapper) previous).setResponse(next);
- break;
- }
- // Advance to the next response in the chain
- previous = current;
- current = ((ServletResponseWrapper) current).getResponse();
- }
- }
-
-
- /**
- * Create and return a request wrapper that has been inserted in the
- * appropriate spot in the request chain.
- */
- private ServletRequest wrapRequest() {
- // Locate the request we should insert in front of
- ServletRequest previous = null;
- ServletRequest current = outerRequest;
- while (current != null) {
- if (!(current instanceof ServletRequestWrapper))
- break;
- if (current instanceof ServletRequestWrapperImpl)
- break;
- if (current instanceof ServletRequestImpl)
- break;
- // user-specified
- previous = current;
- current = ((ServletRequestWrapper) current).getRequest();
- }
- // now previous will be a user-specified wrapper,
- // and current one of our own wrappers ( deeper in stack )
- // ... current USER_previous USER USER
- // previous is null if the top request is ours.
-
- // Instantiate a new wrapper at this point and insert it in the chain
- ServletRequest wrapper = null;
-
- // Compute a crossContext flag
- boolean crossContext = isCrossContext();
- wrapper =
- new ServletRequestWrapperImpl((HttpServletRequest) current,
- ctx, crossContext);
-
- if (previous == null) {
- // outer becomes the wrapper, includes orig wrapper inside
- outerRequest = wrapper;
- } else {
- // outer remains user-specified sersvlet, delegating to
- // our wrapper, which delegates to real request or our wrapper.
- ((ServletRequestWrapper) previous).setRequest(wrapper);
- }
- wrapRequest = wrapper;
- return (wrapper);
- }
-
- private boolean isCrossContext() {
- boolean crossContext = false;
- if ((outerRequest instanceof ServletRequestWrapperImpl) ||
- (outerRequest instanceof ServletRequestImpl) ||
- (outerRequest instanceof HttpServletRequest)) {
- HttpServletRequest houterRequest =
- (HttpServletRequest) outerRequest;
- Object contextPath =
- houterRequest.getAttribute(INCLUDE_CONTEXT_PATH_ATTR);
- if (contextPath == null) {
- // Forward
- contextPath = houterRequest.getContextPath();
- }
- crossContext = !(ctx.getContextPath().equals(contextPath));
- }
- return crossContext;
- }
-
-
- /**
- * Create and return a response wrapper that has been inserted in the
- * appropriate spot in the response chain.
- *
- * Side effect: updates outerResponse, wrapResponse.
- * The chain is updated with a wrapper below lowest user wrapper
- */
- private ServletResponse wrapResponse() {
- // Locate the response we should insert in front of
- ServletResponse previous = null;
- ServletResponse current = outerResponse;
- while (current != null) {
- if (!(current instanceof ServletResponseWrapper))
- break;
- if (current instanceof ServletResponseImpl)
- break;
- previous = current;
- current = ((ServletResponseWrapper) current).getResponse();
- }
-
- // Instantiate a new wrapper at this point and insert it in the chain
- ServletResponse wrapper =
- new ServletResponseIncludeWrapper(current);
-
- if (previous == null) {
- // outer is ours, we can wrap on top
- outerResponse = wrapper;
- } else {
- // outer is user-specified, leave it alone.
- // we insert ourself below the lowest user-specified response
- ((ServletResponseWrapper) previous).setResponse(wrapper);
- }
- wrapResponse = wrapper;
- return (wrapper);
-
- }
-
-
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.MultipartConfigElement;
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRegistration;
-import javax.servlet.ServletSecurityElement;
-import javax.servlet.SingleThreadModel;
-import javax.servlet.UnavailableException;
-
-import org.apache.tomcat.servlets.jsp.BaseJspLoader;
-import org.apache.tomcat.servlets.util.Enumerator;
-import org.apache.tomcat.util.IntrospectionUtils;
-
-/**
- * Based on Wrapper.
- *
- * Standard implementation of the <b>Wrapper</b> interface that represents
- * an individual servlet definition. No child Containers are allowed, and
- * the parent Container must be a Context.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
- */
-@SuppressWarnings("deprecation")
-public class ServletConfigImpl implements ServletConfig, ServletRegistration {
-
- ServletDynamicRegistration dynamic = new ServletDynamicRegistration();
-
- protected boolean asyncSupported;
-
- private static Logger log=
- Logger.getLogger(ServletConfigImpl.class.getName());
-
- private static final String[] DEFAULT_SERVLET_METHODS = new String[] {
- "GET", "HEAD", "POST" };
-
- // TODO: refactor all 'stm' to separate class (not implemented)
- // public static final String SINGLE_THREADED_PROXY =
- // "org.apache.tomcat.servlets.jsp.SingleThreadedProxyServlet";
-
- protected String description;
- protected Map<String, String> initParams = new HashMap<String, String>();
- protected String servletName;
- protected String servletClassName;
- protected String jspFile;
- protected int loadOnStartup = -1;
- protected String runAs;
- protected Map securityRoleRef = new HashMap(); // roleName -> [roleLink]
-
- /**
- * The date and time at which this servlet will become available (in
- * milliseconds since the epoch), or zero if the servlet is available.
- * If this value equals Long.MAX_VALUE, the unavailability of this
- * servlet is considered permanent.
- */
- private transient long available = 0L;
-
- private ServletContextImpl ctx;
-
- /**
- * The (single) initialized instance of this servlet.
- */
- private transient Servlet instance = null;
-
- /**
- * Are we unloading our servlet instance at the moment?
- */
- private transient boolean unloading = false;
-
- private Class servletClass = null;
-
- // Support for SingleThreaded
- /**
- * The count of allocations that are currently active (even if they
- * are for the same instance, as will be true on a non-STM servlet).
- */
- private transient int countAllocated = 0;
-
- private transient boolean singleThreadModel = false;
- /**
- * Stack containing the STM instances.
- */
- private transient Stack instancePool = null;
-
-
- // Statistics
- private transient long loadTime=0;
- private transient int classLoadTime=0;
-
- // ------------------------------------------------------------- Properties
- public ServletConfigImpl(ServletContextImpl ctx, String name,
- String classname) {
- this.servletName = name;
- this.servletClassName = classname;
- this.ctx = ctx;
- ctx.facade.notifyAdd(this);
- }
-
- /**
- * Return the available date/time for this servlet, in milliseconds since
- * the epoch. If this date/time is Long.MAX_VALUE, it is considered to mean
- * that unavailability is permanent and any request for this servlet will return
- * an SC_NOT_FOUND error. If this date/time is in the future, any request for
- * this servlet will return an SC_SERVICE_UNAVAILABLE error. If it is zero,
- * the servlet is currently available.
- */
- public long getAvailable() {
- return (this.available);
- }
-
-
- /**
- * Set the available date/time for this servlet, in milliseconds since the
- * epoch. If this date/time is Long.MAX_VALUE, it is considered to mean
- * that unavailability is permanent and any request for this servlet will return
- * an SC_NOT_FOUND error. If this date/time is in the future, any request for
- * this servlet will return an SC_SERVICE_UNAVAILABLE error.
- *
- * @param available The new available date/time
- */
- public void setAvailable(long available) {
-
- long oldAvailable = this.available;
- if (available > System.currentTimeMillis())
- this.available = available;
- else
- this.available = 0L;
-
- }
-
-
- /**
- * Return the number of active allocations of this servlet, even if they
- * are all for the same instance (as will be true for servlets that do
- * not implement <code>SingleThreadModel</code>.
- */
- public int getCountAllocated() {
- return (this.countAllocated);
- }
-
- /**
- * Return the jsp-file setting for this servlet.
- */
- public String getJspFile() {
- return jspFile;
- }
-
- public void setJspFile(String s) {
- this.jspFile = s;
- }
-
- /**
- * Return the load-on-startup order value (negative value means
- * load on first call).
- */
- public int getLoadOnStartup() {
- return loadOnStartup;
- }
-
- /**
- * Return the fully qualified servlet class name for this servlet.
- */
- public String getServletClass() {
- return servletClassName;
- }
-
- /**
- * Is this servlet currently unavailable?
- */
- public boolean isUnavailable() {
- if (available == 0L)
- return (false);
- else if (available <= System.currentTimeMillis()) {
- available = 0L;
- return (false);
- } else
- return (true);
-
- }
-
-
- /**
- * Gets the names of the methods supported by the underlying servlet.
- *
- * This is the same set of methods included in the Allow response header
- * in response to an OPTIONS request method processed by the underlying
- * servlet.
- *
- * @return Array of names of the methods supported by the underlying
- * servlet
- */
- public String[] getServletMethods() throws ServletException {
-
- Class servletClazz = loadServlet().getClass();
- if (!javax.servlet.http.HttpServlet.class.isAssignableFrom(
- servletClazz)) {
- return DEFAULT_SERVLET_METHODS;
- }
-
- HashSet allow = new HashSet();
- allow.add("TRACE");
- allow.add("OPTIONS");
-
- Method[] methods = getAllDeclaredMethods(servletClazz);
- for (int i=0; methods != null && i<methods.length; i++) {
- Method m = methods[i];
-
- if (m.getName().equals("doGet")) {
- allow.add("GET");
- allow.add("HEAD");
- } else if (m.getName().equals("doPost")) {
- allow.add("POST");
- } else if (m.getName().equals("doPut")) {
- allow.add("PUT");
- } else if (m.getName().equals("doDelete")) {
- allow.add("DELETE");
- }
- }
-
- String[] methodNames = new String[allow.size()];
- return (String[]) allow.toArray(methodNames);
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Extract the root cause from a servlet exception.
- *
- * @param e The servlet exception
- */
- public static Throwable getRootCause(ServletException e) {
- Throwable rootCause = e;
- Throwable rootCauseCheck = null;
- // Extra aggressive rootCause finding
- do {
- try {
- rootCauseCheck = (Throwable)IntrospectionUtils.getProperty
- (rootCause, "rootCause");
- if (rootCauseCheck!=null)
- rootCause = rootCauseCheck;
-
- } catch (ClassCastException ex) {
- rootCauseCheck = null;
- }
- } while (rootCauseCheck != null);
- return rootCause;
- }
-
- /**
- * MUST be called before service()
- * This method should be called to get the servlet. After
- * service(), dealocate should be called. This deals with STM and
- * update use counters.
- *
- * Normally called from RequestDispatcher and TomcatLite.
- */
- public Servlet allocate() throws ServletException {
- // If we are currently unloading this servlet, throw an exception
- if (unloading)
- throw new ServletException
- ("allocate() while unloading " + getServletName());
-
- Servlet servlet = null;
- if (instance == null && !singleThreadModel) {
- // never loaded.
- synchronized (this) {
- if (instance == null && !singleThreadModel) {
- try {
- servlet = loadServlet();
- } catch (ServletException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("loadServlet()", e);
- }
- if (servlet != null && !singleThreadModel) {
- setServlet(servlet);
- }
- }
- }
- }
-
- // If not SingleThreadedModel, return the same instance every time
- if (instance != null) {
- countAllocated++;
- return (instance);
- }
-
- // Simpler policy for ST: unbound number of servlets ( can grow to
- // one per thread )
-
- synchronized (instancePool) {
- if (instancePool.isEmpty()) {
- try {
- if (servlet != null) {
- // this is the first invocation
- countAllocated++;
- return servlet;
- }
- countAllocated++;
- Servlet newServlet = loadServlet();
- log.fine("New STM servet " + newServlet + " " +
- countAllocated);
- return newServlet;
- } catch (ServletException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("allocate " + getServletName(),
- e);
- }
- }
- log.fine("Get from pool " + instancePool.size() + " " +
- countAllocated);
- Servlet s = (Servlet) instancePool.pop();
- countAllocated++;
- log.fine("After get " + instancePool.size() + " " + s +
- " " + countAllocated);
- return s;
- }
- }
-
-
- /**
- * MUST be called after service().
- */
- public void deallocate(Servlet servlet) {
- // If not SingleThreadModel, no action is required
- if (!singleThreadModel) {
- countAllocated--;
- return;
- }
-
- // Unlock and free this instance
- synchronized (instancePool) {
- countAllocated--;
- if (instancePool.contains(servlet)) {
- System.err.println("Aleady in pool " + servlet + " "
- + instancePool.size()+ " " + countAllocated);
- return;
- }
- System.err.println("return pool " + servlet + " " +
- instancePool.size() + " " + countAllocated);
- instancePool.push(servlet);
- }
- }
-
- public Servlet newInstance() throws ServletException {
- String actualClass = servletClassName;
-
- if (instance != null) {
- return instance;
- }
- if (actualClass == null) {
- // No explicit name. Try to use the framework
- if (jspFile != null) {
-
- // Named JSPs can be handled by a servlet or by the mapper.
- BaseJspLoader mapper = new JspLoader();
- try {
- return mapper.loadProxy(jspFile, ctx, this);
- } catch (IOException e) {
- throw new ServletException(e);
- }
- }
- if (actualClass == null) {
- // Covers 'default-" and "jspwildcard-" servlets as well
- Servlet res = (Servlet) ctx.getObjectManager().get( servletName +
- "-servlet");
- if (res != null) {
- servletClass = res.getClass();
- actualClass = servletClass.getName();
- return res;
- }
- }
-
- //ctx.getObjectManager().getObject(c);
- //ctx.getObjectManager().getObject(servletName);
- }
-
-
- if (servletClass == null) {
- // set classClass
- loadClass(actualClass);
- }
-
-
- // jsp-file case. Load the JspProxyServlet instead, with the
- // right params. Note the JspProxyServlet is _not_ jasper,
- // nor 'jsp' servlet - it is just a proxy with no special
- // params. It calls the jsp servlet and jasper to generate the
- // real class.
-
- // this is quite different from catalina, where an ugly kludge was
- // used to use the same jsp servlet in 2 roles
-
- // the jsp proxy is replaced by the web.xml processor
-
- if (servletClass == null) {
- unavailable(null);
- throw new UnavailableException("ClassNotFound: " + actualClass);
- }
-
- // Instantiate and initialize an instance of the servlet class itself
- try {
- return (Servlet) servletClass.newInstance();
- } catch (ClassCastException e) {
- unavailable(null);
- throw new UnavailableException("ClassCast: (Servlet)" +
- actualClass);
- } catch (Throwable e) {
- unavailable(null);
-
- // Added extra log statement for Bugzilla 36630:
- // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
- if(log.isLoggable(Level.FINE)) {
- log.log(Level.FINE, "newInstance() error: servlet-name: " +
- getServletName() +
- " servlet-class: " + actualClass, e);
- }
-
- // Restore the context ClassLoader
- throw new ServletException("newInstance() error " + getServletName() +
- " " + actualClass, e);
- }
- }
-
- /**
- * Load and initialize an instance of this servlet, if there is not already
- * at least one initialized instance. This can be used, for example, to
- * load servlets that are marked in the deployment descriptor to be loaded
- * at server startup time.
- */
- public synchronized Servlet loadServlet() throws ServletException {
- // Nothing to do if we already have an instance or an instance pool
- if (!singleThreadModel && (instance != null))
- return instance;
-
- long t1=System.currentTimeMillis();
-
- Servlet servlet = newInstance();
-
- classLoadTime=(int) (System.currentTimeMillis() -t1);
-
- // Call the initialization method of this servlet
- try {
- servlet.init(this);
- } catch (UnavailableException f) {
- unavailable(f);
- throw f;
- } catch (ServletException f) {
- throw f;
- } catch (Throwable f) {
- getServletContext().log("StandardWrapper.Throwable", f );
- throw new ServletException("Servlet.init()", f);
- }
-
- // Register our newly initialized instance
- singleThreadModel = servlet instanceof SingleThreadModel;
- if (singleThreadModel) {
- if (instancePool == null)
- instancePool = new Stack();
- }
- loadTime=System.currentTimeMillis() -t1;
-
- return servlet;
- }
-
-
- private void loadClass(String actualClass) throws ServletException {
- // Complain if no servlet class has been specified
- if (actualClass == null) {
- unavailable(null);
- throw new ServletException("servlet-class missing " +
- getServletName());
- }
-
- ClassLoader classLoader = ctx.getClassLoader();
- if (classLoader == null )
- classLoader = this.getClass().getClassLoader();
-
- // Load the specified servlet class from the appropriate class loader
- try {
- servletClass = classLoader.loadClass(actualClass);
- } catch (ClassNotFoundException e) {
- servletClass = null;
- }
- }
-
- /**
- * Return a String representation of this component.
- */
- public String toString() {
- StringBuilder sb = new StringBuilder();
- if (ctx != null) {
- sb.append(ctx.toString());
- sb.append(".");
- }
- sb.append("Servlet[");
- sb.append(getServletName()).append(" ");
- sb.append(servletClassName);
- if (jspFile != null) {
- sb.append(" jsp=").append(jspFile);
- }
- sb.append("]");
- return (sb.toString());
- }
-
-
- /**
- * Process an UnavailableException, marking this servlet as unavailable
- * for the specified amount of time.
- *
- * @param unavailable The exception that occurred, or <code>null</code>
- * to mark this servlet as permanently unavailable
- */
- public void unavailable(UnavailableException unavailable) {
- getServletContext().log("UnavailableException:" + getServletName());
- if (unavailable == null)
- setAvailable(Long.MAX_VALUE);
- else if (unavailable.isPermanent())
- setAvailable(Long.MAX_VALUE);
- else {
- int unavailableSeconds = unavailable.getUnavailableSeconds();
- if (unavailableSeconds <= 0)
- unavailableSeconds = 60; // Arbitrary default
- setAvailable(System.currentTimeMillis() +
- (unavailableSeconds * 1000L));
- }
-
- }
-
-
- /**
- * Unload all initialized instances of this servlet, after calling the
- * <code>destroy()</code> method for each instance. This can be used,
- * for example, prior to shutting down the entire servlet engine, or
- * prior to reloading all of the classes from the Loader associated with
- * our Loader's repository.
- *
- * @exception ServletException if an exception is thrown by the
- * destroy() method
- */
- public synchronized void unload() throws ServletException {
- setAvailable(Long.MAX_VALUE);
-
- // Nothing to do if we have never loaded the instance
- if (!singleThreadModel && (instance == null))
- return;
- unloading = true;
-
- // Loaf a while if the current instance is allocated
- // (possibly more than once if non-STM)
- if (countAllocated > 0) {
- int nRetries = 0;
- long delay = ctx.getUnloadDelay() / 20;
- while ((nRetries < 21) && (countAllocated > 0)) {
- if ((nRetries % 10) == 0) {
- log.info("Servlet.unload() timeout " +
- countAllocated);
- }
- try {
- Thread.sleep(delay);
- } catch (InterruptedException e) {
- ;
- }
- nRetries++;
- }
- }
-
- ClassLoader oldCtxClassLoader =
- Thread.currentThread().getContextClassLoader();
- if (instance != null) {
- ClassLoader classLoader = instance.getClass().getClassLoader();
-
- PrintStream out = System.out;
- // Call the servlet destroy() method
- try {
- Thread.currentThread().setContextClassLoader(classLoader);
- instance.destroy();
- } catch (Throwable t) {
- instance = null;
- //instancePool = null;
- unloading = false;
- throw new ServletException("Servlet.destroy() " +
- getServletName(), t);
- } finally {
- // restore the context ClassLoader
- Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
- }
-
- // Deregister the destroyed instance
- instance = null;
- }
- if (singleThreadModel && (instancePool != null)) {
- try {
- ClassLoader classLoader = ctx.getClassLoader();
- Thread.currentThread().setContextClassLoader(classLoader);
- while (!instancePool.isEmpty()) {
- ((Servlet) instancePool.pop()).destroy();
- }
- } catch (Throwable t) {
- instancePool = null;
- unloading = false;
- throw new ServletException("Servlet.destroy() " + getServletName(), t);
- } finally {
- // restore the context ClassLoader
- Thread.currentThread().setContextClassLoader
- (oldCtxClassLoader);
- }
- instancePool = null;
- }
-
- singleThreadModel = false;
-
- unloading = false;
- }
-
-
- /**
- * Return the initialization parameter value for the specified name,
- * if any; otherwise return <code>null</code>.
- *
- * @param name Name of the initialization parameter to retrieve
- */
- public String getInitParameter(String name) {
- return initParams.get(name);
- }
-
-
- /**
- * Return the set of initialization parameter names defined for this
- * servlet. If none are defined, an empty Enumeration is returned.
- */
- public Enumeration getInitParameterNames() {
- synchronized (initParams) {
- return (new Enumerator(initParams.keySet()));
- }
- }
-
-
- /**
- * Return the servlet context with which this servlet is associated.
- */
- public ServletContext getServletContext() {
- return ctx;
- }
-
-
- /**
- * Return the name of this servlet.
- */
- public String getServletName() {
- return servletName;
- }
-
-// public long getProcessingTime() {
-// return swValve.getProcessingTime();
-// }
-//
-// public void setProcessingTime(long processingTime) {
-// swValve.setProcessingTime(processingTime);
-// }
-//
-// public long getMaxTime() {
-// return swValve.getMaxTime();
-// }
-//
-// public void setMaxTime(long maxTime) {
-// swValve.setMaxTime(maxTime);
-// }
-//
-// public long getMinTime() {
-// return swValve.getMinTime();
-// }
-//
-// public void setMinTime(long minTime) {
-// swValve.setMinTime(minTime);
-// }
-//
-// public int getRequestCount() {
-// return swValve.getRequestCount();
-// }
-//
-// public void setRequestCount(int requestCount) {
-// swValve.setRequestCount(requestCount);
-// }
-//
-// public int getErrorCount() {
-// return swValve.getErrorCount();
-// }
-//
-// public void setErrorCount(int errorCount) {
-// swValve.setErrorCount(errorCount);
-// }
-//
-// /**
-// * Increment the error count used for monitoring.
-// */
-// public void incrementErrorCount(){
-// swValve.setErrorCount(swValve.getErrorCount() + 1);
-// }
-//
-// public long getLoadTime() {
-// return loadTime;
-// }
-//
-// public void setLoadTime(long loadTime) {
-// this.loadTime = loadTime;
-// }
-//
-// public int getClassLoadTime() {
-// return classLoadTime;
-// }
-
- // -------------------------------------------------------- Package Methods
-
-
- // -------------------------------------------------------- Private Methods
-
- private Method[] getAllDeclaredMethods(Class c) {
-
- if (c.equals(javax.servlet.http.HttpServlet.class)) {
- return null;
- }
-
- Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
-
- Method[] thisMethods = c.getDeclaredMethods();
- if (thisMethods == null) {
- return parentMethods;
- }
-
- if ((parentMethods != null) && (parentMethods.length > 0)) {
- Method[] allMethods =
- new Method[parentMethods.length + thisMethods.length];
- System.arraycopy(parentMethods, 0, allMethods, 0,
- parentMethods.length);
- System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
- thisMethods.length);
-
- thisMethods = allMethods;
- }
-
- return thisMethods;
- }
-
- /** Specify the instance. Avoids the class lookup, disables unloading.
- * Use for embedded case, or to control the allocation.
- *
- * @param servlet
- */
- public void setServlet(Servlet servlet) {
- instance = servlet;
- ctx.getObjectManager().bind("Servlet:" +
- ctx.getContextPath() + ":" + getServletName(),
- this);
- }
-
- public String getSecurityRoleRef(String role) {
- return (String)securityRoleRef.get(role);
- }
-
- public void setSecurityRoleRef(Map securityRoles) {
- this.securityRoleRef = securityRoles;
- }
-
- public void setConfig(Map initParams) {
- this.initParams = initParams;
- }
-
- public void setLoadOnStartup(int loadOnStartup) {
- this.loadOnStartup = loadOnStartup;
- }
-
- @Override
- public Set<String> addMapping(String... urlPatterns) {
- if (ctx.startDone) {
- // Use the context method instead of the servlet API to
- // add mappings after context init.
- throw new IllegalStateException();
- }
- Set<String> failed = new HashSet<String>();
- for (String url: urlPatterns) {
- if (url == null) {
- throw new IllegalArgumentException();
- }
- if (ctx.contextConfig.servletMapping.get(url) != null) {
- failed.add(url);
- } else {
- ctx.contextConfig.servletMapping.put(url, getServletName());
- ctx.addMapping(url, this);
- }
- }
- return failed;
- }
-
-
- @Override
- public boolean setInitParameter(String name, String value)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
- name, value);
- }
-
-
- @Override
- public Set<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
- initParameters);
- }
-
- public Dynamic getDynamic() {
- return dynamic;
- }
-
- class ServletDynamicRegistration implements Dynamic {
-
-
- @Override
- public void setAsyncSupported(boolean isAsyncSupported)
- throws IllegalStateException {
- asyncSupported = isAsyncSupported;
- }
-
-
- public void setDescription(String description)
- throws IllegalStateException {
- ServletConfigImpl.this.description = description;
- }
-
- @Override
- public Set<String> setServletSecurity(ServletSecurityElement constraint) {
- //implement me
- return null;
- }
-
- @Override
- public void setLoadOnStartup(int loadOnStartup) {
- //implement me - here to compile
- }
-
- @Override
- public void setMultipartConfig(MultipartConfigElement multipartConfig) {
- //implement me - here to compile
- }
-
- @Override
- public void setRunAsRole(String roleName) {
- //implement me - here to compile
- }
-
- @Override
- public String getRunAsRole() {
- //implement me - here to compile
- return null;
- }
-
- @Override
- public Collection<String> getMappings() {
- //implement me
- return null;
- }
-
- @Override
- public Set<String> addMapping(String... urlPatterns) {
- //implement me
- return null;
- }
-
- @Override
- public Map<String, String> getInitParameters() {
- // implement me
- return null;
- }
-
- @Override
- public Set<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- // implement me
- return null;
- }
-
- @Override
- public String getClassName() {
- // implement me
- return null;
- }
-
- @Override
- public String getName() {
- // implement me
- return null;
- }
-
- @Override
- public String getInitParameter(String name) {
- // implement me
- return null;
- }
-
- @Override
- public boolean setInitParameter(String name, String value)
- throws IllegalArgumentException, IllegalStateException {
- // implement me
- return false;
- }
-
- }
-
- @Override
- public Collection<String> getMappings() {
- //implement me
- return null;
- }
-
- public void setServletClass(Class<? extends Servlet> servletClass2) {
- servletClass = servletClass2;
- }
-
-
- @Override
- public String getRunAsRole() {
- //implement me
- return null;
- }
-
-
- @Override
- public Map<String, String> getInitParameters() {
- // implement me
- return null;
- }
-
- @Override
- public String getClassName() {
- // implement me
- return null;
- }
-
- @Override
- public String getName() {
- // implement me
- return null;
- }
-
-}
+++ /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.coyote.servlet;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.naming.NamingException;
-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.ServletContext;
-import javax.servlet.ServletContextAttributeEvent;
-import javax.servlet.ServletContextAttributeListener;
-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 javax.servlet.descriptor.JspConfigDescriptor;
-
-import org.apache.tomcat.InstanceManager;
-import org.apache.tomcat.servlets.session.UserSessionManager;
-import org.apache.tomcat.integration.ObjectManager;
-import org.apache.tomcat.servlets.config.ConfigLoader;
-import org.apache.tomcat.servlets.config.ServletContextConfig;
-import org.apache.tomcat.servlets.config.ServletContextConfig.FilterData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.FilterMappingData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.ServletData;
-import org.apache.tomcat.servlets.config.deploy.WarDeploy;
-import org.apache.tomcat.servlets.util.Enumerator;
-import org.apache.tomcat.servlets.util.RequestUtil;
-import org.apache.tomcat.servlets.util.UrlUtils;
-import org.apache.tomcat.util.http.MimeMap;
-
-
-/**
- * Context - initialized from web.xml or using APIs.
- *
- * Initialization order:
- *
- * - add all listeners
- * - add all filters
- * - add all servlets
- *
- * - session parameters
- * -
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
- * @version $Revision$ $Date$
- */
-
-public class ServletContextImpl implements ServletContext {
-
- /**
- * Empty collection to serve as the basis for empty enumerations.
- */
- private transient static final ArrayList empty = new ArrayList();
-
- transient Logger log;
-
- /**
- * Base path - the directory root of the webapp
- */
- protected String basePath = null;
-
- protected String contextPath;
-
- // All config from web.xml
- protected ServletContextConfig contextConfig = new ServletContextConfig();
-
- MimeMap contentTypes = new MimeMap();
-
- /**
- * The context attributes for this context.
- */
- protected transient Map<String, Object> attributes = new HashMap<String, Object>();
-
- /**
- * List of read only attributes for this context.
- * In catalina - used to protect workdir att. We trust the app, so no need
- * for extra complexity.
- */
- //protected transient HashMap readOnlyAttributes = new HashMap();
-
- protected transient ArrayList<EventListener> lifecycleListeners = new ArrayList();
-
- protected UserSessionManager manager;
-
- HashMap<String, FilterConfigImpl> filters = new HashMap<String, FilterConfigImpl>();
-
- HashMap<String, ServletConfigImpl> servlets = new HashMap<String, ServletConfigImpl>();
-
- ArrayList<String> securityRoles = new ArrayList<String>();
-
- /** Mapper for filters.
- */
- protected WebappFilterMapper webappFilterMapper;
-
- /** Internal mapper for request dispatcher, must have all
- * context mappings.
- */
- protected WebappServletMapper mapper;
-
- transient Locale2Charset charsetMapper = new Locale2Charset();
-
- transient TomcatLite facade;
-
- ObjectManager om;
-
- private String hostname;
-
-
- boolean initDone = false;
-
- boolean startDone = false;
-
- String jspcServlet = "org.apache.tomcat.servlets.jspc.JspcServlet";
-
-
- // ------------------------------------------------- ServletContext Methods
- public ServletContextImpl() {
- }
-
- public void setTomcat(TomcatLite facade) {
- this.facade = facade;
- }
-
- /**
- * Registry/framework interface associated with the context.
- * Also available as a context attribute.
- * @return
- */
- public ObjectManager getObjectManager() {
- if (om == null) {
- om = facade.getObjectManager();
- }
- return om;
- }
-
- public void setObjectManager(ObjectManager om) {
- this.om = om;
- }
-
- public Locale2Charset getCharsetMapper() {
- return charsetMapper;
- }
-
- /**
- * Set the context path, starting with "/" - "/" for ROOT
- * @param path
- */
- public void setContextPath(String path) {
- this.contextPath = path;
- log = Logger.getLogger("webapp" + path.replace('/', '.'));
- }
-
- public void setHostname(String hostname) {
- this.hostname = hostname;
- }
-
- public String getHostname() {
- return hostname;
- }
-
- /** The directory where this app is based. May be null.
- *
- * @param basePath
- */
- public void setBasePath(String basePath) {
- this.basePath = basePath;
- }
-
- public ServletContextConfig getContextConfig() {
- return contextConfig;
- }
-
- /** The directory where this app is based.
- *
- * @param basePath
- */
- public String getBasePath() {
- return basePath;
- }
-
- public String getEncodedPath() {
- return null;
- }
-
-
- public boolean getCookies() {
- return false;
- }
-
-
- public ServletContext getServletContext() {
- return this;
- }
-
- public List<EventListener> getListeners() {
- return lifecycleListeners;
- }
-
- public void addListener(Class <? extends EventListener> listenerClass) {
- // implement me
- }
-
- public void addListener(String className) {
- // implement me
- }
-
- public <T extends EventListener> void addListener(T t) {
- lifecycleListeners.add(t);
- }
-
-
- public void removeListener(EventListener listener) {
- lifecycleListeners.remove(listener);
- }
-
-
-
- public Logger getLogger() {
- return log;
- }
-
- public long getUnloadDelay() {
- return 0;
- }
-
- public ServletConfigImpl getServletConfig(String jsp_servlet_name) {
- return (ServletConfigImpl)servlets.get(jsp_servlet_name);
- }
-
- public Map getServletConfigs() {
- return servlets;
- }
-
- /**
- * Add a servlet to the context.
- * Called from processWebAppData()
- *
- * @param servletConfig
- */
- public void addServletConfig(ServletConfigImpl servletConfig) {
- servlets.put(servletConfig.getServletName(), servletConfig);
- }
-
- public boolean getPrivileged() {
- return false;
- }
-
-
- public Map getFilters() {
- return filters;
- }
-
-
- protected boolean getCrossContext() {
- return true;
- }
-
- public void addMimeType(String ext, String type) {
- contentTypes.addContentType(ext, type);
- }
-
- public WebappServletMapper getMapper() {
- if (mapper == null) {
- Object customMapper = getObjectManager().get(WebappServletMapper.class);
- if (customMapper == null) {
- mapper = new WebappServletMapper();
- } else {
- mapper = (WebappServletMapper) customMapper;
- }
- mapper.setServletContext(this);
- }
-
- return mapper;
- }
-
- public WebappFilterMapper getFilterMapper() {
- if (webappFilterMapper == null) {
- Object customMapper = getObjectManager().get(WebappFilterMapper.class);
- if (customMapper == null) {
- webappFilterMapper = new WebappFilterMapper();
- } else {
- webappFilterMapper = (WebappFilterMapper) customMapper;
- }
- webappFilterMapper.setServletContext(this);
- }
-
- return webappFilterMapper ;
- }
-
- public FilterConfigImpl getFilter(String name) {
- return (FilterConfigImpl)filters.get(name);
- }
-
- /**
- * Return the value of the specified context attribute, if any;
- * otherwise return <code>null</code>.
- *
- * @param name Name of the context attribute to return
- */
- public Object getAttribute(String name) {
- if ("ObjectManager".equals(name)) {
- return om;
- }
- if ("context-listeners".equals(name)) {
- return lifecycleListeners;
- }
- return (attributes.get(name));
- }
-
- /**
- * Return an enumeration of the names of the context attributes
- * associated with this context.
- */
- public Enumeration getAttributeNames() {
- return new Enumerator(attributes.keySet(), true);
- }
-
-
- public void addSecurityRole(String role) {
- securityRoles.add(role);
- }
-
- public List getSecurityRoles() {
- return securityRoles;
- }
-
- /**
- * Return a <code>ServletContext</code> object that corresponds to a
- * specified URI on the server. This method allows servlets to gain
- * access to the context for various parts of the server, and as needed
- * obtain <code>RequestDispatcher</code> objects or resources from the
- * context. The given path must be absolute (beginning with a "/"),
- * and is interpreted based on our virtual host's document root.
- *
- * @param uri Absolute URI of a resource on the server
- */
- public ServletContext getContext(String uri) {
- // TODO: support real uri ( http://host/path )
- // Validate the format of the specified argument
- if ((uri == null) || (!uri.startsWith("/")))
- return (null);
-
- ServletContextImpl child = null;
- try {
- child = facade.getContext(this, uri);
- } catch (IOException e) {
- } catch (ServletException e) {
- }
-
- if (child == null)
- return (null);
-
- if (this.getCrossContext()) {
- // If crossContext is enabled, can always return the context
- return child.getServletContext();
- } else if (child == this) {
- // Can still return the current context
- return this.getServletContext();
- } else {
- // Nothing to return
- return (null);
- }
- }
-
-
- /**
- * Return the main path associated with this context.
- */
- public String getContextPath() {
- return contextPath;
- }
-
-
- /**
- * Return the value of the specified initialization parameter, or
- * <code>null</code> if this parameter does not exist.
- *
- * @param name Name of the initialization parameter to retrieve
- */
- public String getInitParameter(final String name) {
- return ((String) contextConfig.contextParam.get(name));
- }
-
-
- /**
- * Return the names of the context's initialization parameters, or an
- * empty enumeration if the context has no initialization parameters.
- */
- public Enumeration getInitParameterNames() {
- return (new Enumerator(contextConfig.contextParam.keySet()));
- }
-
- public void setContextParams(Map newParams) {
- contextConfig.contextParam = (HashMap) newParams;
- }
-
- /**
- * Return the major version of the Java Servlet API that we implement.
- */
- public int getMajorVersion() {
- return 3;
- }
-
-
- /**
- * Return the minor version of the Java Servlet API that we implement.
- */
- public int getMinorVersion() {
- return 0;
- }
-
-
- /**
- * Return the MIME type of the specified file, or <code>null</code> if
- * the MIME type cannot be determined.
- *
- * @param file Filename for which to identify a MIME type
- */
- public String getMimeType(String file) {
- return contentTypes.getMimeType(file);
- }
-
- /**
- * Return the real path for a given virtual path, if possible; otherwise
- * return <code>null</code>.
- *
- * @param path The path to the desired resource
- */
- public String getRealPath(String path) {
- if (path == null) {
- return null;
- }
-
- File file = new File(basePath, path);
- return (file.getAbsolutePath());
- }
-
- /**
- * Return a <code>RequestDispatcher</code> object that acts as a
- * wrapper for the named servlet.
- *
- * @param name Name of the servlet for which a dispatcher is requested
- */
- public RequestDispatcher getNamedDispatcher(String name) {
- if (name == null) return null;
- ServletConfigImpl wrapper =
- (ServletConfigImpl) this.getServletConfig(name);
- if (wrapper == null) return null;
-
- return new RequestDispatcherImpl(wrapper, name);
- }
-
-
- /**
- * Return a <code>RequestDispatcher</code> instance that acts as a
- * wrapper for the resource at the given path. The path must begin
- * with a "/" and is interpreted as relative to the current context root.
- *
- * @param path The path to the desired resource.
- */
- public RequestDispatcher getRequestDispatcher(String path) {
- if (path == null) return null;
-
- if (!path.startsWith("/"))
- throw new IllegalArgumentException(path);
-
- path = UrlUtils.normalize(path);
- if (path == null) return (null);
-
-
- return new RequestDispatcherImpl(this, path);
- }
-
- public RequestDispatcher getRequestDispatcher(String path,
- int type,
- String dispatcherPath) {
- RequestDispatcher dispatcher = getRequestDispatcher(path);
- //((RequestDispatcherImpl)dispatcher);
- return dispatcher;
- }
-
- ThreadLocal requestDispatcherStack = new ThreadLocal();
-
- private String classPath;
-
- protected ClassLoader classLoader;
-
-// protected RequestDispatcherImpl getRequestDispatcher() {
-// ArrayList/*<RequestDispatcherImpl>*/ list =
-// (ArrayList)requestDispatcherStack.get();
-// if (list == null) {
-// list = new ArrayList();
-// requestDispatcherStack.set(list);
-// }
-//
-//
-// return null;
-// }
-
- public void resetDispatcherStack() {
-
- }
-
- /**
- * Return the URL to the resource that is mapped to a specified path.
- * The path must begin with a "/" and is interpreted as relative to the
- * current context root.
- *
- * @param path The path to the desired resource
- *
- * @exception MalformedURLException if the path is not given
- * in the correct form
- */
- public URL getResource(String path)
- throws MalformedURLException {
-
- if (path == null || !path.startsWith("/")) {
- throw new MalformedURLException("getResource() " + path);
- }
-
- path = UrlUtils.normalize(path);
- if (path == null)
- return (null);
-
- String libPath = "/WEB-INF/lib/";
- if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) {
- File jarFile = null;
- jarFile = new File(basePath, path);
- if (jarFile.exists()) {
- return jarFile.toURL();
- } else {
- return null;
- }
- } else {
- File resFile = new File(basePath + path);
- if (resFile.exists()) {
- return resFile.toURL();
- }
- }
-
- return (null);
-
- }
-
- /**
- * Return the requested resource as an <code>InputStream</code>. The
- * path must be specified according to the rules described under
- * <code>getResource</code>. If no such resource can be identified,
- * return <code>null</code>.
- *
- * @param path The path to the desired resource.
- */
- public InputStream getResourceAsStream(String path) {
-
- path = UrlUtils.normalize(path);
- if (path == null)
- return (null);
-
- File resFile = new File(basePath + path);
- if (!resFile.exists())
- return null;
-
- try {
- return new FileInputStream(resFile);
- } catch (FileNotFoundException e) {
- return null;
- }
-
- }
-
-
- /**
- * Return a Set containing the resource paths of resources member of the
- * specified collection. Each path will be a String starting with
- * a "/" character. The returned set is immutable.
- *
- * @param path Collection path
- */
- public Set getResourcePaths(String path) {
-
- // Validate the path argument
- if (path == null) {
- return null;
- }
- if (!path.startsWith("/")) {
- throw new IllegalArgumentException("getResourcePaths() " + path);
- }
-
- path = UrlUtils.normalize(path);
- if (path == null)
- return (null);
-
- File f = new File(basePath + path);
- File[] files = f.listFiles();
- if (files == null) return null;
- if (!path.endsWith("/")) {
- path = path + "/";
- }
-
- HashSet result = new HashSet();
- for (int i=0; i < files.length; i++) {
- if (files[i].isDirectory() ) {
- result.add(path + files[i].getName() + "/");
- } else {
- result.add(path + files[i].getName());
- }
- }
- return result;
- }
-
-
-
- /**
- * Return the name and version of the servlet container.
- */
- public String getServerInfo() {
- return "Apache Tomcat Lite";
- }
-
- /**
- * @deprecated As of Java Servlet API 2.1, with no direct replacement.
- */
- public Servlet getServlet(String name) {
- return (null);
- }
-
-
- /**
- * Return the display name of this web application.
- */
- public String getServletContextName() {
- return contextConfig.displayName;
- }
-
-
- /**
- * @deprecated As of Java Servlet API 2.1, with no direct replacement.
- */
- public Enumeration getServletNames() {
- return (new Enumerator(empty));
- }
-
-
- /**
- * @deprecated As of Java Servlet API 2.1, with no direct replacement.
- */
- public Enumeration getServlets() {
- return (new Enumerator(empty));
- }
-
-
- /**
- * Writes the specified message to a servlet log file.
- *
- * @param message Message to be written
- */
- public void log(String message) {
- this.getLogger().info(message);
- }
-
-
- /**
- * Writes the specified exception and message to a servlet log file.
- *
- * @param exception Exception to be reported
- * @param message Message to be written
- *
- * @deprecated As of Java Servlet API 2.1, use
- * <code>log(String, Throwable)</code> instead
- */
- public void log(Exception exception, String message) {
- this.getLogger().log(Level.INFO, message, exception);
- }
-
-
- /**
- * Writes the specified message and exception to a servlet log file.
- *
- * @param message Message to be written
- * @param throwable Exception to be reported
- */
- public void log(String message, Throwable throwable) {
- this.getLogger().log(Level.INFO, message, throwable);
- }
-
- /**
- * Remove the context attribute with the specified name, if any.
- *
- * @param name Name of the context attribute to be removed
- */
- public void removeAttribute(String name) {
-
- Object value = null;
- boolean found = false;
-
- // Remove the specified attribute
- // Check for read only attribute
- found = attributes.containsKey(name);
- if (found) {
- value = attributes.get(name);
- attributes.remove(name);
- } else {
- return;
- }
-
- // Notify interested application event listeners
- List listeners = this.getListeners();
- if (listeners.size() == 0)
- return;
- ServletContextAttributeEvent event = null;
- for (int i = 0; i < listeners.size(); i++) {
- if (!(listeners.get(i) instanceof ServletContextAttributeListener))
- continue;
- ServletContextAttributeListener listener =
- (ServletContextAttributeListener) listeners.get(i);
- try {
- if (event == null) {
- event = new ServletContextAttributeEvent(this.getServletContext(),
- name, value);
-
- }
- listener.attributeRemoved(event);
- } catch (Throwable t) {
- // FIXME - should we do anything besides log these?
- log("ServletContextAttributeListener", t);
- }
- }
- }
-
-
- /**
- * Bind the specified value with the specified context attribute name,
- * replacing any existing value for that name.
- *
- * @param name Attribute name to be bound
- * @param value New attribute value to be bound
- */
- public void setAttribute(String name, Object value) {
- // Name cannot be null
- if (name == null)
- throw new IllegalArgumentException
- ("name == null");
-
- // Null value is the same as removeAttribute()
- if (value == null) {
- removeAttribute(name);
- return;
- }
-
- Object oldValue = null;
- boolean replaced = false;
-
- // Add or replace the specified attribute
- synchronized (attributes) {
- // Check for read only attribute
- oldValue = attributes.get(name);
- if (oldValue != null)
- replaced = true;
- attributes.put(name, value);
- }
-
- // Notify interested application event listeners
- List listeners = this.getListeners();
- if (listeners.size() == 0)
- return;
- ServletContextAttributeEvent event = null;
- for (int i = 0; i < listeners.size(); i++) {
- if (!(listeners.get(i) instanceof ServletContextAttributeListener))
- continue;
- ServletContextAttributeListener listener =
- (ServletContextAttributeListener) listeners.get(i);
- try {
- if (event == null) {
- if (replaced)
- event =
- new ServletContextAttributeEvent(this.getServletContext(),
- name, oldValue);
- else
- event =
- new ServletContextAttributeEvent(this.getServletContext(),
- name, value);
-
- }
- if (replaced) {
- listener.attributeReplaced(event);
- } else {
- listener.attributeAdded(event);
- }
- } catch (Throwable t) {
- // FIXME - should we do anything besides log these?
- log("ServletContextAttributeListener error", t);
- }
- }
-
- }
-
- /**
- * Clear all application-created attributes.
- */
- void clearAttributes() {
- // Create list of attributes to be removed
- ArrayList list = new ArrayList();
- synchronized (attributes) {
- Iterator iter = attributes.keySet().iterator();
- while (iter.hasNext()) {
- list.add(iter.next());
- }
- }
-
- // Remove application originated attributes
- // (read only attributes will be left in place)
- Iterator keys = list.iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- removeAttribute(key);
- }
- }
-
- public void initFilters() throws ServletException {
- Iterator fI = getFilters().values().iterator();
- while (fI.hasNext()) {
- FilterConfigImpl fc = (FilterConfigImpl)fI.next();
- try {
- fc.getFilter(); // will triger init()
- } catch (Throwable e) {
- log.log(Level.WARNING, getContextPath() + " Filter.init() " +
- fc.getFilterName(), e);
- }
-
- }
- }
-
- public void initServlets() throws ServletException {
- Iterator fI = getServletConfigs().values().iterator();
- Map/*<Integer, List<ServletConfigImpl>>*/ onStartup =
- new TreeMap/*<Integer, List<ServletConfigImpl>>*/();
- while (fI.hasNext()) {
- ServletConfigImpl fc = (ServletConfigImpl)fI.next();
- if (fc.getLoadOnStartup() > 0 ) {
- Integer i = new Integer(fc.getLoadOnStartup());
- List/*<ServletConfigImpl>*/ old = (List)onStartup.get(i);
- if (old == null) {
- old = new ArrayList/*<ServletConfigImpl>*/();
- onStartup.put(i, old);
- }
- old.add(fc);
- }
- }
- Iterator keys = onStartup.keySet().iterator();
- while (keys.hasNext()) {
- Integer key = (Integer)keys.next();
- List/*<ServletConfigImpl>*/ servlets = (List)onStartup.get(key);
- Iterator servletsI = servlets.iterator();
- while (servletsI.hasNext()) {
- ServletConfigImpl fc = (ServletConfigImpl) servletsI.next();
- try {
- fc.loadServlet();
- } catch (Throwable e) {
- log.log(Level.WARNING, "Error initializing " + fc.getServletName(), e);
- }
- }
- }
- }
-
- public void initListeners() throws ServletException {
- Iterator fI = contextConfig.listenerClass.iterator();
- while (fI.hasNext()) {
- String listenerClass = (String)fI.next();
- try {
- Object l =
- getClassLoader().loadClass(listenerClass).newInstance();
- lifecycleListeners.add((EventListener) l);
- } catch (Throwable e) {
- log.log(Level.WARNING, "Error initializing listener " + listenerClass, e);
- }
- }
- }
-
- public ClassLoader getClassLoader() {
- return classLoader;
- }
-
- public void addMapping(String path, String name) {
- ServletConfigImpl wrapper = getServletConfig(name);
- addMapping(path, wrapper);
- }
-
- public void addMapping(String path, ServletConfig wrapper) {
- getMapper().addWrapper(getMapper().contextMapElement, path, wrapper);
- }
-
-
-
- public void setWelcomeFiles(String[] name) {
- getMapper().contextMapElement.welcomeResources = name;
- }
-
- public String[] getWelcomeFiles() {
- return getMapper().contextMapElement.welcomeResources;
- }
-
- public void setSessionTimeout(int to) {
- getManager().setSessionTimeout(to);
- }
-
- /**
- * Initialize the context from the parsed config.
- *
- * Note that WebAppData is serializable.
- */
- public void processWebAppData(ServletContextConfig d) throws ServletException {
- this.contextConfig = d;
-
- for (String k: d.mimeMapping.keySet()) {
- addMimeType(k, d.mimeMapping.get(k));
- }
-
- String[] wFiles = (String[])d.welcomeFileList.toArray(new String[0]);
- if (wFiles.length == 0) {
- wFiles = new String[] {"index.html" };
- }
- if (basePath != null) {
- getMapper().contextMapElement.resources = new File(getBasePath());
- }
- setWelcomeFiles(wFiles);
-
- Iterator i2 = d.filters.values().iterator();
- while (i2.hasNext()) {
- FilterData fd = (FilterData)i2.next();
- addFilter(fd.name, fd.className, fd.initParams);
- }
-
- Iterator i3 = d.servlets.values().iterator();
- while (i3.hasNext()) {
- ServletData sd = (ServletData) i3.next();
- // jsp-file
- if (sd.className == null) {
- if (sd.jspFile == null) {
- log.log(Level.WARNING, "Missing servlet class for " + sd.name);
- continue;
- }
- }
-
- ServletConfigImpl sw =
- new ServletConfigImpl(this, sd.name, sd.className);
- sw.setConfig(sd.initParams);
- sw.setJspFile(sd.jspFile);
- sw.setLoadOnStartup(sd.loadOnStartup);
- //sw.setRunAs(sd.runAs);
- sw.setSecurityRoleRef(sd.securityRoleRef);
-
- addServletConfig(sw);
- }
-
- for (String k: d.servletMapping.keySet()) {
- addMapping(k, d.servletMapping.get(k));
- }
-
- Iterator i5 = d.filterMappings.iterator();
- while (i5.hasNext()) {
- FilterMappingData k = (FilterMappingData) i5.next();
- String[] disp = new String[k.dispatcher.size()];
- if (k.urlPattern != null) {
- addFilterMapping(k.urlPattern,
- k.filterName,
- (String[])k.dispatcher.toArray(disp));
- }
- if (k.servletName != null) {
- addFilterServletMapping(k.servletName,
- k.filterName,
- (String[])k.dispatcher.toArray(disp));
- }
- }
-
- for (String n: d.localeEncodingMapping.keySet()) {
- getCharsetMapper().addCharsetMapping(n,
- d.localeEncodingMapping.get(n));
- }
- }
-
- public void addServlet(String servletName, String servletClass,
- String jspFile, Map params) {
- ServletConfigImpl sc = new ServletConfigImpl(this, servletName,
- servletClass);
- sc.setJspFile(jspFile);
- sc.setConfig(params);
- addServletConfig(sc);
- }
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
- ServletConfigImpl sc = new ServletConfigImpl(this, servletName, null);
- sc.setServlet(servlet);
- addServletConfig(sc);
- return sc.getDynamic();
- }
-
- public void addServletSec(String serlvetName, String runAs, Map roles) {
- // TODO
- }
-
-
-
- public void addFilterMapping(String path, String filterName,
- String[] dispatcher) {
- getFilterMapper().addMapping(filterName,
- path, null, dispatcher, true);
-
- }
-
- public void addFilterServletMapping(String servlet,
- String filterName,
- String[] dispatcher) {
- getFilterMapper().addMapping(filterName,
- null, servlet,
- dispatcher, true);
- }
-
- /**
- * Called from TomcatLite.init(), required before start.
- *
- * Will initialize defaults and load web.xml unless webAppData is
- * already set and recent. No other processing is done except reading
- * the config - you can add or alter it before start() is called.
- *
- * @throws ServletException
- */
- public void init() throws ServletException {
- if (initDone) {
- return;
- }
- initDone = true;
- // Load global init params from the facade
- initEngineDefaults();
-
- initTempDir();
-
-
- // Merge in web.xml - or other config source ( programmatic, etc )
- ConfigLoader cfg = new WarDeploy();
- contextConfig = cfg.loadConfig(getBasePath());
-
- processWebAppData(contextConfig);
-
- // if not defined yet:
- addDefaultServlets();
- }
-
-
- protected void initTempDir() throws ServletException {
- // We need a base path - at least for temp files, req. by spec
- if (basePath == null) {
- basePath = ("/".equals(contextPath)) ?
- facade.getWork().getAbsolutePath() + "/ROOT" :
- facade.getWork().getAbsolutePath() + contextPath;
- }
-
- File f = new File(basePath + "/WEB-INF/tmp");
- f.mkdirs();
- setAttribute("javax.servlet.context.tempdir", f);
- }
-
- /**
- * Static file handler ( default )
- * *.jsp support
- *
- */
- protected void addDefaultServlets() throws ServletException {
- if (servlets.get("default") == null) {
- ServletConfigImpl fileS = new ServletConfigImpl(this,
- "default", null);
- addServletConfig(fileS);
- addMapping("/", fileS);
- }
-
- // *.jsp support
- if (servlets.get("jspwildcard") == null) {
- ServletConfigImpl fileS = new ServletConfigImpl(this,
- "jspwildcard", null);
- fileS.initParams.put("mapper", JspLoader.class.getName());
- addServletConfig(fileS);
- addMapping("*.jsp", fileS);
- }
-
- ServletConfigImpl jspcS = new ServletConfigImpl(this,
- "jspc", jspcServlet);
- addServletConfig(jspcS);
- }
-
- protected void initEngineDefaults() throws ServletException {
-
- // TODO: make this customizable, avoid loading it on startup
- // Set the class name as default in the addon support
- for (String sname: facade.ctxDefaultInitParam.keySet()) {
- String path = facade.ctxDefaultInitParam.get(sname);
- contextConfig.contextParam.put(sname, path);
- }
-
- for (String sname: facade.preloadServlets.keySet()) {
- String sclass = facade.preloadServlets.get(sname);
- ServletConfigImpl fileS = new ServletConfigImpl(this, sname, sclass);
- addServletConfig(fileS);
- }
-
- for (String sname: facade.preloadMappings.keySet()) {
- String path = facade.preloadMappings.get(sname);
- ServletConfigImpl servletConfig = getServletConfig(sname);
- addMapping(path, servletConfig);
- }
-
- // JSP support
- setAttribute(InstanceManager.class.getName(),
- new LiteInstanceManager(getObjectManager()));
-
- }
-
- private void addClasspathLib(ArrayList res, File directory) {
-
- if (!directory.isDirectory() || !directory.exists()
- || !directory.canRead()) {
- return;
- }
-
- File[] jars = directory.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".jar");
- }
- });
-
- for (int j = 0; j < jars.length; j++) {
- try {
- URL url = jars[j].toURL();
- res.add(url);
- } catch (MalformedURLException e) {
- }
- }
- }
-
- private void addClasspathDir(ArrayList res, File classesDir) {
-
- if (classesDir.isDirectory() && classesDir.exists() &&
- classesDir.canRead()) {
- try {
- URL url = classesDir.toURL();
- res.add(url);
- } catch (MalformedURLException e) {
- }
- }
- }
- public String getClassPath() {
- return classPath;
- }
-
- public void start() throws ServletException {
- if (startDone) {
- return;
- }
- String base = getBasePath();
-
- ArrayList urls = new ArrayList();
-
- addClasspathDir(urls, new File(base + "/WEB-INF/classes"));
- addClasspathDir(urls, new File(base + "/WEB-INF/tmp"));
- addClasspathLib(urls, new File(base + "/WEB-INF/lib"));
-
- URL[] urlsA = new URL[urls.size()];
- urls.toArray(urlsA);
-
- URLClassLoader parentLoader =
- getEngine().getContextParentLoader();
-
- // create a class loader.
- // TODO: reimplement special 'deploy' dirs
-
- /*
- Repository ctxRepo = new Repository();
- ctxRepo.setParentClassLoader(parentLoader);
- ctxRepo.addURL(urlsA);
- repository = ctxRepo;
- */
-
- StringBuilder cp = new StringBuilder();
-
- for (URL cpUrl : urlsA) {
- cp.append(":").append(cpUrl.getFile());
- }
- classPath = cp.toString();
-
- classLoader = new URLClassLoader(urlsA, parentLoader);
-
- // JMX should know about us ( TODO: is it too early ? )
- facade.notifyAdd(this);
-
- initListeners();
-
- List listeners = this.getListeners();
- ServletContextEvent event = null;
- for (int i = 0; i < listeners.size(); i++) {
- if (!(listeners.get(i) instanceof ServletContextListener))
- continue;
- ServletContextListener listener =
- (ServletContextListener) listeners.get(i);
- if (event == null) {
- event = new ServletContextEvent(this);
- }
- try {
- // May add servlets/filters
- listener.contextInitialized(event);
- } catch (Throwable t) {
- log.log(Level.WARNING, "Context.init() contextInitialized() error:", t);
- }
- }
-
-
- initFilters();
- initServlets();
-
- startDone = true;
- }
-
- public UserSessionManager getManager() {
- if (manager == null) {
- manager = (UserSessionManager) getObjectManager().get(
- UserSessionManager.class);
- manager.setContext(this);
- if (contextConfig.sessionTimeout > 0 ) {
- manager.setSessionTimeout(contextConfig.sessionTimeout);
- }
- }
- return manager;
- }
-
-
- // TODO: configurable ? init-params
- public String getSessionCookieName() {
- return "JSESSIONID";
- }
-
-
-
- public void destroy() throws ServletException {
- // destroy filters
- Iterator fI = filters.values().iterator();
- while(fI.hasNext()) {
- FilterConfigImpl fc = (FilterConfigImpl) fI.next();
- try {
- fc.getFilter().destroy();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- // destroy servlets
- fI = servlets.values().iterator();
- while(fI.hasNext()) {
- ServletConfigImpl fc = (ServletConfigImpl) fI.next();
- try {
- fc.unload();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- public TomcatLite getEngine() {
- return facade;
- }
-
- public String findStatusPage(int status) {
- if (contextConfig.errorPageCode.size() == 0) {
- return null;
- }
- if (status == 200) {
- return null;
- }
-
- return (String) contextConfig.errorPageCode.get(Integer.toString(status));
- }
-
- public void handleStatusPage(ServletRequestImpl req,
- ServletResponseImpl res,
- int status,
- String statusPage) {
- String message = RequestUtil.filter(res.getMessage());
- if (message == null)
- message = "";
- setErrorAttributes(req, status, message);
- dispatchError(req, res, statusPage);
- }
-
- protected void setErrorAttributes(ServletRequestImpl req,
- int status,
- String message) {
- req.setAttribute("javax.servlet.error.status_code",
- new Integer(status));
- if (req.getWrapper() != null) {
- req.setAttribute("javax.servlet.error.servlet_name",
- req.getWrapper().servletName);
- }
- req.setAttribute("javax.servlet.error.request_uri",
- req.getRequestURI());
- req.setAttribute("javax.servlet.error.message",
- message);
-
- }
-
- public void handleError(ServletRequestImpl req,
- ServletResponseImpl res,
- Throwable t) {
- Throwable realError = t;
- if (realError instanceof ServletException) {
- realError = ((ServletException) realError).getRootCause();
- if (realError == null) {
- realError = t;
- }
- }
- //if (realError instanceof ClientAbortException ) {
-
- String errorPage = findErrorPage(t);
- if ((errorPage == null) && (realError != t)) {
- errorPage = findErrorPage(realError);
- }
-
- if (errorPage != null) {
- setErrorAttributes(req, 500, t.getMessage());
- req.setAttribute("javax.servlet.error.exception", realError);
- req.setAttribute("javax.servlet.error.exception_type",
- realError.getClass());
- dispatchError(req, res, errorPage);
- } else {
- log("Unhandled error", t);
- if (t instanceof ServletException &&
- ((ServletException)t).getRootCause() != null) {
- log("RootCause:", ((ServletException)t).getRootCause());
- }
- if (res.getStatus() < 500) {
- res.setStatus(500);
- }
- }
- }
-
- protected void dispatchError(ServletRequestImpl req,
- ServletResponseImpl res,
- String errorPage) {
- RequestDispatcher rd =
- getRequestDispatcher(errorPage);
- try {
- // will clean up the buffer
- rd.forward(req, res);
- return; // handled
- } catch (ServletException e) {
- // TODO
- } catch (IOException e) {
- // TODO
- }
- }
-
- protected String findErrorPage(Throwable exception) {
- if (contextConfig.errorPageException.size() == 0) {
- return null;
- }
- if (exception == null)
- return (null);
- Class clazz = exception.getClass();
- String name = clazz.getName();
- while (!Object.class.equals(clazz)) {
- String page = (String)contextConfig.errorPageException.get(name);
- if (page != null)
- return (page);
- clazz = clazz.getSuperclass();
- if (clazz == null)
- break;
- name = clazz.getName();
- }
- return (null);
-
- }
-
-
- @Override
- public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
- return null;
- }
-
-
- @Override
- public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() {
- return null;
- }
-
-
- @Override
- public SessionCookieConfig getSessionCookieConfig() {
- return null;
- }
-
-
- @Override
- public void setSessionTrackingModes(EnumSet<SessionTrackingMode> sessionTrackingModes) {
- }
-
-
- public void addFilter(String filterName, String filterClass,
- Map params) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, filterClass, params);
- filters.put(filterName, fc);
- }
-
-
- @Override
- public Dynamic addFilter(String filterName, String className) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, className, new HashMap());
- filters.put(filterName, fc);
- return fc.getDynamic();
- }
-
-
- @Override
- public Dynamic addFilter(String filterName, Filter filter) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, null, new HashMap());
- fc.setFilter(filter);
- filters.put(filterName, fc);
- return fc.getDynamic();
- }
-
-
- @Override
- public Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, null, new HashMap());
- fc.setFilterClass(filterClass);
- filters.put(filterName, fc);
- return fc.getDynamic();
- }
-
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName,
- String className) {
- ServletConfigImpl sc = new ServletConfigImpl(this, servletName, className);
- addServletConfig(sc);
- return sc.getDynamic();
- }
-
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName,
- Class<? extends Servlet> servletClass) {
- ServletConfigImpl sc = new ServletConfigImpl(this, servletName, servletClass.getName());
- sc.setServletClass(servletClass);
- addServletConfig(sc);
- return sc.getDynamic();
- }
-
- // That's tricky - this filter will have no name. We need to generate one
- // because our code relies on names.
- AtomicInteger autoName = new AtomicInteger();
-
-
- @Override
- public <T extends Filter> T createFilter(Class<T> c) throws ServletException {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- String filterName = "_tomcat_auto_filter_" + autoName.incrementAndGet();
- fc.setData(filterName, null, new HashMap());
- fc.setFilterClass(c);
- filters.put(filterName, fc);
-
- try {
- return (T) fc.createFilter();
- } catch (ClassCastException e) {
- throw new ServletException(e);
- } catch (ClassNotFoundException e) {
- throw new ServletException(e);
- } catch (IllegalAccessException e) {
- throw new ServletException(e);
- } catch (InstantiationException e) {
- throw new ServletException(e);
- }
- }
-
-
- @Override
- public <T extends Servlet> T createServlet(Class<T> c) throws ServletException {
- String filterName = "_tomcat_auto_servlet_" + autoName.incrementAndGet();
- ServletConfigImpl fc = new ServletConfigImpl(this, filterName, null);
- fc.setServletClass(c);
- servlets.put(filterName, fc);
-
- try {
- return (T) fc.newInstance();
- } catch (ClassCastException e) {
- throw new ServletException(e);
- }
- }
-
-
- public FilterRegistration findFilterRegistration(String filterName) {
- return filters.get(filterName);
- }
-
-
- public ServletRegistration findServletRegistration(String servletName) {
- return servlets.get(servletName);
- }
-
-
- @Override
- public boolean setInitParameter(String name, String value) {
- HashMap<String, String> params = contextConfig.contextParam;
- return setInitParameter(this, params, name, value);
- }
-
-
- static Set<String> setInitParameters(ServletContextImpl ctx,
- Map<String, String> params,
- Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- if (ctx.startDone) {
- throw new IllegalStateException();
- }
- Set<String> result = new HashSet<String>();
- for (String name: initParameters.keySet()) {
- String value = initParameters.get(name);
- if (name == null || value == null) {
- throw new IllegalArgumentException();
- }
- if (!setInitParameter(ctx, params, name, value)) {
- result.add(name);
- }
- }
- return result;
- }
-
- /**
- * true if the context initialization parameter with the given name and value was set successfully on this ServletContext, and false if it was not set because this ServletContext already contains a context initialization parameter with a matching name
- * Throws:
- * java.lang.IllegalStateException - if this ServletContext has already been initialized
- */
- static boolean setInitParameter(ServletContextImpl ctx, Map<String, String> params,
- String name, String value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException();
- }
- if (ctx.startDone) {
- throw new IllegalStateException();
- }
- String oldValue = params.get(name);
- if (oldValue != null) {
- return false;
- } else {
- params.put(name, value);
- return true;
- }
- }
-
- public JspConfigDescriptor getJspConfigDescriptor() {
- // fix me - just here to compile
- return null;
- }
-
-
-
- public void declareRoles(String... roleNames) {
- // implement me
- }
-
- public <T extends EventListener> T createListener(Class<T> c) throws ServletException {
- // implement me
- return null;
- }
-
- public Collection<String> getMappings() {
- // implement me
- return null;
- }
-
- public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
- // implement me
- return null;
- }
-
- public FilterRegistration getFilterRegistration(String filterName) {
- // implement me
- return null;
- }
-
- public Map<String, ? extends ServletRegistration> getServletRegistrations() {
- // implement me
- return null;
- }
-
- public ServletRegistration getServletRegistration(String servletName) {
- // implement me
- return null;
- }
-
- public int getEffectiveMinorVersion() {
- // implement me
- return -1;
- }
-
- public int getEffectiveMajorVersion() {
- // implement me
- return -1;
- }
-
- private final class LiteInstanceManager implements InstanceManager {
- private ObjectManager om;
-
- public LiteInstanceManager(ObjectManager objectManager) {
- this.om = objectManager;
- }
-
- @Override
- public void destroyInstance(Object o)
- throws IllegalAccessException,
- InvocationTargetException {
- }
-
- @Override
- public Object newInstance(String className)
- throws IllegalAccessException,
- InvocationTargetException, NamingException,
- InstantiationException,
- ClassNotFoundException {
- return om.get(className);
- }
-
- @Override
- public Object newInstance(String fqcn,
- ClassLoader classLoader)
- throws IllegalAccessException,
- InvocationTargetException, NamingException,
- InstantiationException,
- ClassNotFoundException {
- return om.get(fqcn);
- }
-
- @Override
- public void newInstance(Object o)
- throws IllegalAccessException,
- InvocationTargetException, NamingException {
- om.bind(o.getClass().getName(), o);
- }
- }
-
-}
-
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.servlet.ServletInputStream;
-
-
-/**
- * Wrapper around MessageReader
- *
- * @author Remy Maucherat
- * @author Jean-Francois Arcand
- * @author Costin Manolache
- */
-public class ServletInputStreamImpl extends ServletInputStream {
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- protected InputStream ib;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- public ServletInputStreamImpl(InputStream ib) {
- this.ib = ib;
- }
-
- // --------------------------------------------- ServletInputStream Methods
-
- public long skip(long n)
- throws IOException {
- return ib.skip(n);
- }
-
- public void mark(int readAheadLimit)
- {
- //try {
- ib.mark(readAheadLimit);
-// } catch (IOException e) {
-// e.printStackTrace();
-// }
- }
-
-
- public void reset()
- throws IOException {
- ib.reset();
- }
-
-
-
- public int read()
- throws IOException {
- return ib.read();
- }
-
- public int available() throws IOException {
- return ib.available();
- }
-
- public int read(final byte[] b) throws IOException {
- return ib.read(b, 0, b.length);
- }
-
-
- public int read(final byte[] b, final int off, final int len)
- throws IOException {
-
- return ib.read(b, off, len);
- }
-
-
- public int readLine(byte[] b, int off, int len) throws IOException {
- return super.readLine(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 {
- ib.close();
- }
-
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-
-import javax.servlet.ServletOutputStream;
-
-
-/**
- * Coyote implementation of the servlet output stream.
- *
- * @author Costin Manolache
- * @author Remy Maucherat
- */
-public class ServletOutputStreamImpl
- extends ServletOutputStream {
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- protected BodyWriter ob;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- public ServletOutputStreamImpl(BodyWriter ob) {
- this.ob = ob;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Prevent cloning the facade.
- */
- protected Object clone()
- throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
-
- // -------------------------------------------------------- Package Methods
-
-
- /**
- * Clear facade.
- */
- void clear() {
- ob = null;
- }
-
-
- // --------------------------------------------------- OutputStream Methods
-
-
- public void write(int i)
- throws IOException {
- ob.writeByte(i);
- }
-
-
- public void write(byte[] b)
- throws IOException {
- write(b, 0, b.length);
- }
-
-
- public void write(byte[] b, int off, int len)
- throws IOException {
- ob.write(b, off, len);
- }
-
-
- /**
- * Will send the buffer to the client.
- */
- public void flush()
- throws IOException {
- ob.flush();
- }
-
-
- public void close()
- throws IOException {
- ob.close();
- }
-
-
- // -------------------------------------------- ServletOutputStream Methods
-
-
- public void print(String s)
- throws IOException {
- ob.write(s);
- }
-
-
-}
-
+++ /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.coyote.servlet;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-
-
-
-/**
- * Coyote implementation of the buffred reader.
- *
- * @author Remy Maucherat
- */
-public class ServletReaderImpl
- extends BufferedReader {
-
-
- // -------------------------------------------------------------- Constants
-
-
- private static final char[] LINE_SEP = { '\r', '\n' };
- private static final int MAX_LINE_LENGTH = 4096;
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- protected Reader ib;
-
-
- protected char[] lineBuffer = null;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- public ServletReaderImpl(Reader ib) {
- super(ib, 1);
- this.ib = ib;
- }
-
- public void close()
- throws IOException {
- ib.close();
- }
-
-
- public int read()
- throws IOException {
- return ib.read();
- }
-
-
- public int read(char[] cbuf)
- throws IOException {
- return ib.read(cbuf, 0, cbuf.length);
- }
-
-
- public int read(char[] cbuf, int off, int len)
- throws IOException {
- return ib.read(cbuf, off, len);
- }
-
-
- public long skip(long n)
- throws IOException {
- return ib.skip(n);
- }
-
-
- public boolean ready()
- throws IOException {
- return ib.ready();
- }
-
-
- public boolean markSupported() {
- return true;
- }
-
-
- public void mark(int readAheadLimit)
- throws IOException {
- ib.mark(readAheadLimit);
- }
-
-
- public void reset()
- throws IOException {
- ib.reset();
- }
-
-
- // TODO: move the readLine functionality to base coyote IO
- public String readLine()
- throws IOException {
-
- if (lineBuffer == null) {
- lineBuffer = new char[MAX_LINE_LENGTH];
- }
-
- String result = null;
-
- int pos = 0;
- int end = -1;
- int skip = -1;
- StringBuilder aggregator = null;
- while (end < 0) {
- mark(MAX_LINE_LENGTH);
- while ((pos < MAX_LINE_LENGTH) && (end < 0)) {
- int nRead = read(lineBuffer, pos, MAX_LINE_LENGTH - pos);
- if (nRead < 0) {
- if (pos == 0) {
- return null;
- }
- end = pos;
- skip = pos;
- }
- for (int i = pos; (i < (pos + nRead)) && (end < 0); i++) {
- if (lineBuffer[i] == LINE_SEP[0]) {
- end = i;
- skip = i + 1;
- char nextchar;
- if (i == (pos + nRead - 1)) {
- nextchar = (char) read();
- } else {
- nextchar = lineBuffer[i+1];
- }
- if (nextchar == LINE_SEP[1]) {
- skip++;
- }
- } else if (lineBuffer[i] == LINE_SEP[1]) {
- end = i;
- skip = i + 1;
- }
- }
- if (nRead > 0) {
- pos += nRead;
- }
- }
- if (end < 0) {
- if (aggregator == null) {
- aggregator = new StringBuilder();
- }
- aggregator.append(lineBuffer);
- pos = 0;
- } else {
- reset();
- skip(skip);
- }
- }
-
- if (aggregator == null) {
- result = new String(lineBuffer, 0, end);
- } else {
- aggregator.append(lineBuffer, 0, end);
- result = aggregator.toString();
- }
-
- return result;
-
- }
-}
+++ /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.coyote.servlet;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.Principal;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.TreeMap;
-import java.util.logging.Level;
-
-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.ServletRequestAttributeListener;
-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.tomcat.servlets.session.UserSessionManager;
-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.B2CConverter;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-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
- */
-public class ServletRequestImpl implements HttpServletRequest {
-
- /**
- * The request attribute under which we store the array of X509Certificate
- * objects representing the certificate chain presented by our client,
- * if any.
- */
- public static final String CERTIFICATES_ATTR =
- "javax.servlet.request.X509Certificate";
-
- /**
- * The request attribute under which we store the name of the cipher suite
- * being used on an SSL connection (as an object of type
- * java.lang.String).
- */
- public static final String CIPHER_SUITE_ATTR =
- "javax.servlet.request.cipher_suite";
-
- /**
- * Request dispatcher state.
- */
- public static final String DISPATCHER_TYPE_ATTR =
- "org.apache.catalina.core.DISPATCHER_TYPE";
-
- /**
- * Request dispatcher path.
- */
- public static final String DISPATCHER_REQUEST_PATH_ATTR =
- "org.apache.catalina.core.DISPATCHER_REQUEST_PATH";
-
- /**
- * The servlet context attribute under which we store the class path
- * for our application class loader (as an object of type String),
- * delimited with the appropriate path delimiter for this platform.
- */
- public static final String CLASS_PATH_ATTR =
- "org.apache.catalina.jsp_classpath";
-
-
- /**
- * The request attribute under which we forward a Java exception
- * (as an object of type Throwable) to an error page.
- */
- public static final String EXCEPTION_ATTR =
- "javax.servlet.error.exception";
-
-
- /**
- * The request attribute under which we forward the request URI
- * (as an object of type String) of the page on which an error occurred.
- */
- public static final String EXCEPTION_PAGE_ATTR =
- "javax.servlet.error.request_uri";
-
-
- /**
- * The request attribute under which we forward a Java exception type
- * (as an object of type Class) to an error page.
- */
- public static final String EXCEPTION_TYPE_ATTR =
- "javax.servlet.error.exception_type";
-
-
- /**
- * The request attribute under which we forward an HTTP status message
- * (as an object of type STring) to an error page.
- */
- public static final String ERROR_MESSAGE_ATTR =
- "javax.servlet.error.message";
-
-
- /**
- * The request attribute under which we expose the value of the
- * <code><jsp-file></code> value associated with this servlet,
- * if any.
- */
- public static final String JSP_FILE_ATTR =
- "org.apache.catalina.jsp_file";
-
-
- /**
- * The request attribute under which we store the key size being used for
- * this SSL connection (as an object of type java.lang.Integer).
- */
- public static final String KEY_SIZE_ATTR =
- "javax.servlet.request.key_size";
-
- /**
- * The request attribute under which we store the session id being used
- * for this SSL connection (as an object of type java.lang.String).
- */
- public static final String SSL_SESSION_ID_ATTR =
- "javax.servlet.request.ssl_session";
-
- /**
- * The request attribute under which we forward a servlet name to
- * an error page.
- */
- public static final String SERVLET_NAME_ATTR =
- "javax.servlet.error.servlet_name";
-
-
- /**
- * The name of the cookie used to pass the session identifier back
- * and forth with the client.
- */
- public static final String SESSION_COOKIE_NAME = "JSESSIONID";
-
-
- /**
- * The name of the path parameter used to pass the session identifier
- * back and forth with the client.
- */
- public static final String SESSION_PARAMETER_NAME = "jsessionid";
-
-
- /**
- * The request attribute under which we forward an HTTP status code
- * (as an object of type Integer) to an error page.
- */
- public static final String STATUS_CODE_ATTR =
- "javax.servlet.error.status_code";
-
-
- /**
- * The subject under which the AccessControlContext is running.
- */
- public static final String SUBJECT_ATTR =
- "javax.security.auth.subject";
-
-
- /**
- * The servlet context attribute under which we store a temporary
- * working directory (as an object of type File) for use by servlets
- * within this web application.
- */
- public static final String WORK_DIR_ATTR =
- "javax.servlet.context.tempdir";
-
- protected static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
-
-
- /**
- * The default Locale if none are specified.
- */
- protected static Locale defaultLocale = Locale.getDefault();
-
- // ApplicationFilterFactory. What's the use ???
- private static Integer REQUEST_INTEGER = new Integer(8);
-
- /**
- * The match string for identifying a session ID parameter.
- */
- private static final String match = ";" + SESSION_PARAMETER_NAME + "=";
-
- /**
- * The set of cookies associated with this Request.
- */
- protected Cookie[] cookies = null;
-
-
- /**
- * The set of SimpleDateFormat formats to use in getDateHeader().
- *
- * Notice that because SimpleDateFormat is not thread-safe, we can't
- * declare formats[] as a static variable.
- */
- protected SimpleDateFormat formats[] = null;
-
-
- /**
- * The attributes associated with this Request, keyed by attribute name.
- */
- protected HashMap attributes = new HashMap();
-
-
- /**
- * List of read only attributes for this Request.
- */
- //private HashMap readOnlyAttributes = new HashMap();
-
-
- /**
- * The preferred Locales assocaited with this Request.
- */
- protected ArrayList locales = new ArrayList();
-
-
- /**
- * Authentication type.
- */
- protected String authType = null;
-
- /**
- * User principal.
- */
- protected Principal userPrincipal = null;
-
-
- /**
- * The Subject associated with the current AccessControllerContext
- */
- protected transient Subject subject = null;
-
-
- /**
- * The current dispatcher type.
- */
- protected Object dispatcherType = null;
-
-
- /**
- * The associated input buffer.
- */
- protected BodyReader inputBuffer;
-
- Connector connector;
-
- /**
- * ServletInputStream.
- */
- protected ServletInputStreamImpl inputStream;
-
-
- /**
- * Reader.
- */
- protected BufferedReader reader;
-
-
- /**
- * Using stream flag.
- */
- protected boolean usingInputStream = false;
-
-
- /**
- * Using writer flag.
- */
- protected boolean usingReader = false;
-
-
- /**
- * Session parsed flag.
- */
- protected boolean sessionParsed = false;
-
-
- /**
- * Request parameters parsed flag.
- */
- protected boolean parametersParsed = false;
-
-
- /**
- * Cookies parsed flag.
- */
- protected boolean cookiesParsed = false;
-
-
- /**
- * Secure flag.
- */
- protected boolean secure = false;
-
-
- /**
- * Hash map used in the getParametersMap method.
- */
- protected ParameterMap parameterMap = new ParameterMap();
-
-
- /**
- * The currently active session for this request.
- */
- protected HttpSession session = null;
-
-
- /**
- * The current request dispatcher path.
- */
- protected Object requestDispatcherPath = null;
-
-
- /**
- * Was the requested session ID received in a cookie?
- */
- protected boolean requestedSessionCookie = false;
-
-
- /**
- * The requested session ID (if any) for this request.
- */
- protected String requestedSessionId = null;
-
-
- /**
- * Was the requested session ID received in a URL?
- */
- protected boolean requestedSessionURL = false;
-
-
- /**
- * Parse locales.
- */
- protected boolean localesParsed = false;
-
-
- /**
- * Associated context.
- */
- protected ServletContextImpl context = null;
-
-
-
- // --------------------------------------------------------- Public Methods
-
- /**
- * Filter chain associated with the request.
- */
- protected FilterChainImpl filterChain = new FilterChainImpl();
-
- /**
- * Mapping data.
- */
- protected MappingData mappingData = new MappingData();
-
-
- // -------------------------------------------------------- Request Methods
-
- /**
- * The response with which this request is associated.
- */
- protected ServletResponseImpl response = new ServletResponseImpl();
-
- /**
- * URI byte to char converter (not recycled).
- */
- // protected B2CConverter URIConverter = null;
-
- /**
- * Associated wrapper.
- */
- protected ServletConfigImpl wrapper = null;
-
- /**
- * Post data buffer.
- */
- public final static int CACHED_POST_LEN = 8192;
-
- public byte[] postData = null;
-
-
- private HttpRequest httpRequest;
-
- /** New IO/buffer model
- */
- //protected Http11Connection con;
-
-
- public ServletRequestImpl() {
- response.setRequest(this);
- }
-
-
-// /**
-// * Return the Host within which this Request is being processed.
-// */
-// public Host getHost() {
-// if (getContext() == null)
-// return null;
-// return (Host) getContext().getParent();
-// //return ((Host) mappingData.host);
-// }
-//
-//
-// /**
-// * Set the Host within which this Request is being processed. This
-// * must be called as soon as the appropriate Host is identified, and
-// * before the Request is passed to a context.
-// *
-// * @param host The newly associated Host
-// */
-// public void setHost(Host host) {
-// mappingData.host = host;
-// }
-
- /**
- * Add a Cookie to the set of Cookies associated with this Request.
- *
- * @param cookie The new cookie
- */
- public void addCookie(Cookie cookie) {
-
- if (!cookiesParsed)
- parseCookies();
-
- int size = 0;
- if (cookies != null) {
- size = cookies.length;
- }
-
- Cookie[] newCookies = new Cookie[size + 1];
- for (int i = 0; i < size; i++) {
- newCookies[i] = cookies[i];
- }
- newCookies[size] = cookie;
-
- cookies = newCookies;
-
- }
-
- /**
- * Add a Header to the set of Headers associated with this Request.
- *
- * @param name The new header name
- * @param value The new header value
- */
- public void addHeader(String name, String value) {
- // 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
- * first added Locale will be the first one returned by getLocales().
- *
- * @param locale The new preferred Locale
- */
- public void addLocale(Locale locale) {
- locales.add(locale);
- }
-
-
- /**
- * Add a parameter name and corresponding set of values to this Request.
- * (This is used when restoring the original request on a form based
- * login).
- *
- * @param name Name of this request parameter
- * @param values Corresponding values for this request parameter
- */
- public void addParameter(String name, String values[]) {
- httpRequest.getParameters().addParameterValues(name, values);
- }
-
- /**
- * Clear the collection of Cookies associated with this Request.
- */
- public void clearCookies() {
- cookiesParsed = true;
- cookies = null;
- }
-
- /**
- * Clear the collection of Headers associated with this Request.
- */
- public void clearHeaders() {
- // Not used
- }
-
- /**
- * Clear the collection of Locales associated with this Request.
- */
- public void clearLocales() {
- locales.clear();
- }
-
- /**
- * Clear the collection of parameters associated with this Request.
- */
- public void clearParameters() {
- // Not used
- }
-
-
- /**
- * Create and return a ServletInputStream to read the content
- * associated with this Request.
- *
- * @exception IOException if an input/output error occurs
- */
- public ServletInputStream createInputStream()
- throws IOException {
- return inputStream;
- }
-
- /**
- * Perform whatever actions are required to flush and close the input
- * stream or reader, in a single operation.
- *
- * @exception IOException if an input/output error occurs
- */
- public void finishRequest() throws IOException {
- // The reader and input stream don't need to be closed
- }
-
-
- /**
- * Return the specified request attribute if it exists; otherwise, return
- * <code>null</code>.
- *
- * @param name Name of the request attribute to return
- */
- public Object getAttribute(String name) {
-
- if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) {
- return (dispatcherType == null)
- ? REQUEST_INTEGER
- : dispatcherType;
- } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) {
- return (requestDispatcherPath == null)
- ? getRequestPathMB().toString()
- : requestDispatcherPath.toString();
- }
-
- Object attr=attributes.get(name);
-
- if(attr!=null)
- return(attr);
-
-// attr = reqB.getAttribute(name);
-// if(attr != null)
-// return attr;
-// if( isSSLAttribute(name) ) {
-// reqB.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
-// reqB);
-// attr = reqB.getAttribute(ServletRequestImpl.CERTIFICATES_ATTR);
-// if( attr != null) {
-// attributes.put(ServletRequestImpl.CERTIFICATES_ATTR, attr);
-// }
-// attr = reqB.getAttribute(ServletRequestImpl.CIPHER_SUITE_ATTR);
-// if(attr != null) {
-// attributes.put(ServletRequestImpl.CIPHER_SUITE_ATTR, attr);
-// }
-// attr = reqB.getAttribute(ServletRequestImpl.KEY_SIZE_ATTR);
-// if(attr != null) {
-// attributes.put(ServletRequestImpl.KEY_SIZE_ATTR, attr);
-// }
-// attr = reqB.getAttribute(ServletRequestImpl.SSL_SESSION_ID_ATTR);
-// if(attr != null) {
-// attributes.put(ServletRequestImpl.SSL_SESSION_ID_ATTR, attr);
-// }
-// attr = attributes.get(name);
-// }
- return attr;
- }
-
- /**
- * Return the names of all request attributes for this Request, or an
- * empty <code>Enumeration</code> if there are none.
- */
- public Enumeration getAttributeNames() {
- if (isSecure()) {
- getAttribute(ServletRequestImpl.CERTIFICATES_ATTR);
- }
- return new Enumerator(attributes.keySet(), true);
- }
-
-
- /**
- * Return the authentication type used for this Request.
- */
- public String getAuthType() {
- return (authType);
- }
-
-
- // ------------------------------------------------- Request Public Methods
-
-
- /**
- * Return the character encoding for this Request.
- */
- public String getCharacterEncoding() {
- return (httpRequest.getCharacterEncoding());
- }
-
-
- /**
- * Return the content length for this Request.
- */
- public int getContentLength() {
- return (httpRequest.getContentLength());
- }
-
-
-// /**
-// * Return the object bound with the specified name to the internal notes
-// * for this request, or <code>null</code> if no such binding exists.
-// *
-// * @param name Name of the note to be returned
-// */
-// public Object getNote(String name) {
-// return (notes.get(name));
-// }
-//
-//
-// /**
-// * Return an Iterator containing the String names of all notes bindings
-// * that exist for this request.
-// */
-// public Iterator getNoteNames() {
-// return (notes.keySet().iterator());
-// }
-//
-//
-// /**
-// * Remove any object bound to the specified name in the internal notes
-// * for this request.
-// *
-// * @param name Name of the note to be removed
-// */
-// public void removeNote(String name) {
-// notes.remove(name);
-// }
-//
-//
-// /**
-// * Bind an object to a specified name in the internal notes associated
-// * with this request, replacing any existing binding for this name.
-// *
-// * @param name Name to which the object should be bound
-// * @param value Object to be bound to the specified name
-// */
-// public void setNote(String name, Object value) {
-// notes.put(name, value);
-// }
-//
-
- /**
- * Return the content type for this Request.
- */
- public String getContentType() {
- return (httpRequest.getContentType());
- }
-
-
- /**
- * Return the Context within which this Request is being processed.
- */
- public ServletContextImpl getContext() {
- return (this.context);
- }
-
-
- /**
- * Return the portion of the request URI used to select the Context
- * of the Request.
- */
- public String getContextPath() {
- return (mappingData.contextPath.toString());
- }
-
-
- /**
- * Get the context path.
- *
- * @return the context path
- */
- public MessageBytes getContextPathMB() {
- return (mappingData.contextPath);
- }
-
-
- /**
- * Return the set of Cookies received with this Request.
- */
- public Cookie[] getCookies() {
-
- if (!cookiesParsed)
- parseCookies();
-
- return cookies;
-
- }
-
-
- /**
- * Return the value of the specified date header, if any; otherwise
- * return -1.
- *
- * @param name Name of the requested date header
- *
- * @exception IllegalArgumentException if the specified header value
- * cannot be converted to a date
- */
- public long getDateHeader(String name) {
-
- String value = getHeader(name);
- if (value == null)
- return (-1L);
- if (formats == null) {
- formats = new SimpleDateFormat[] {
- new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
- };
- formats[0].setTimeZone(GMT_ZONE);
- formats[1].setTimeZone(GMT_ZONE);
- formats[2].setTimeZone(GMT_ZONE);
- }
-
- // Attempt to convert the date header in a variety of formats
- long result = FastHttpDateFormat.parseDate(value, formats);
- if (result != (-1L)) {
- return result;
- }
- throw new IllegalArgumentException(value);
-
- }
-
-
- /**
- * Get the decoded request URI.
- *
- * @return the URL decoded request URI
- */
- public String getDecodedRequestURI() {
- return (httpRequest.decodedURI().toString());
- }
-
-
- /**
- * Get the decoded request URI.
- *
- * @return the URL decoded request URI
- */
- public MessageBytes getDecodedRequestURIMB() {
- return (httpRequest.decodedURI());
- }
-
-
- /**
- * Get filter chain associated with the request.
- */
- public FilterChainImpl getFilterChain() {
- return (this.filterChain);
- }
-
-
- // ------------------------------------------------- ServletRequest Methods
-
- /**
- * Return the first value of the specified header, if any; otherwise,
- * return <code>null</code>
- *
- * @param name Name of the requested header
- */
- public String getHeader(String name) {
- return httpRequest.getHeader(name);
- }
-
- /**
- * Return the names of all headers received with this request.
- */
- public Enumeration getHeaderNames() {
- return httpRequest.getMimeHeaders().names();
- }
-
-
- /**
- * Return all of the values of the specified header, if any; otherwise,
- * return an empty enumeration.
- *
- * @param name Name of the requested header
- */
- public Enumeration getHeaders(String name) {
- return httpRequest.getMimeHeaders().values(name);
- }
-
- /**
- * Return the servlet input stream for this Request. The default
- * implementation returns a servlet input stream created by
- * <code>createInputStream()</code>.
- *
- * @exception IllegalStateException if <code>getReader()</code> has
- * already been called for this request
- * @exception IOException if an input/output error occurs
- */
- public ServletInputStream getInputStream() throws IOException {
-
- if (usingReader)
- throw new IllegalStateException
- ("usingReader");
-
- usingInputStream = true;
- return inputStream;
-
- }
-
-
- /**
- * Return the value of the specified header as an integer, or -1 if there
- * is no such header for this request.
- *
- * @param name Name of the requested header
- *
- * @exception IllegalArgumentException if the specified header value
- * cannot be converted to an integer
- */
- public int getIntHeader(String name) {
-
- String value = getHeader(name);
- if (value == null) {
- return (-1);
- } else {
- return (Integer.parseInt(value));
- }
-
- }
-
-
- /**
- * Returns the Internet Protocol (IP) address of the interface on
- * which the request was received.
- */
- public String getLocalAddr(){
- return httpRequest.localAddr().toString();
- }
-
-
- /**
- * Return the preferred Locale that the client will accept content in,
- * based on the value for the first <code>Accept-Language</code> header
- * that was encountered. If the request did not specify a preferred
- * language, the server's default Locale is returned.
- */
- public Locale getLocale() {
-
- if (!localesParsed)
- parseLocales();
-
- if (locales.size() > 0) {
- return ((Locale) locales.get(0));
- } else {
- return (defaultLocale);
- }
-
- }
-
-
- /**
- * Return the set of preferred Locales that the client will accept
- * content in, based on the values for any <code>Accept-Language</code>
- * headers that were encountered. If the request did not specify a
- * preferred language, the server's default Locale is returned.
- */
- public Enumeration getLocales() {
-
- if (!localesParsed)
- parseLocales();
-
- if (locales.size() > 0)
- return (new Enumerator(locales));
- ArrayList results = new ArrayList();
- results.add(defaultLocale);
- return (new Enumerator(results));
-
- }
-
-
- /**
- * Returns the host name of the Internet Protocol (IP) interface on
- * which the request was received.
- */
- public String getLocalName(){
- return httpRequest.localName().toString();
- }
-
-
- /**
- * Returns the Internet Protocol (IP) port number of the interface
- * on which the request was received.
- */
- public int getLocalPort(){
- return httpRequest.getLocalPort();
- }
-
-
- /**
- * Return mapping data.
- */
- public MappingData getMappingData() {
- return (mappingData);
- }
-
-
-
- /**
- * Return the HTTP request method used in this Request.
- */
- public String getMethod() {
- return httpRequest.method().toString();
- }
-
-
- /**
- * Return the value of the specified request parameter, if any; otherwise,
- * return <code>null</code>. If there is more than one value defined,
- * return only the first one.
- *
- * @param name Name of the desired request parameter
- */
- public String getParameter(String name) {
-
- if (!parametersParsed)
- parseParameters();
-
- return httpRequest.getParameters().getParameter(name);
-
- }
-
-
- /**
- * Returns a <code>Map</code> of the parameters of this request.
- * Request parameters are extra information sent with the request.
- * For HTTP servlets, parameters are contained in the query string
- * or posted form data.
- *
- * @return A <code>Map</code> containing parameter names as keys
- * and parameter values as map values.
- */
- public Map getParameterMap() {
-
- if (parameterMap.isLocked())
- return parameterMap;
-
- Enumeration enumeration = getParameterNames();
- while (enumeration.hasMoreElements()) {
- String name = enumeration.nextElement().toString();
- String[] values = getParameterValues(name);
- parameterMap.put(name, values);
- }
-
- parameterMap.setLocked(true);
-
- return parameterMap;
-
- }
-
-
- /**
- * Return the names of all defined request parameters for this request.
- */
- public Enumeration getParameterNames() {
-
- if (!parametersParsed)
- parseParameters();
-
- return httpRequest.getParameters().getParameterNames();
-
- }
-
-
- /**
- * Return the defined values for the specified request parameter, if any;
- * otherwise, return <code>null</code>.
- *
- * @param name Name of the desired request parameter
- */
- public String[] getParameterValues(String name) {
-
- if (!parametersParsed)
- parseParameters();
-
- return httpRequest.getParameters().getParameterValues(name);
-
- }
-
-
- /**
- * Return the path information associated with this Request.
- */
- public String getPathInfo() {
- return (mappingData.pathInfo.toString());
- }
-
-
- /**
- * Get the path info.
- *
- * @return the path info
- */
- public MessageBytes getPathInfoMB() {
- return (mappingData.pathInfo);
- }
-
-
- /**
- * Return the extra path information for this request, translated
- * to a real path.
- */
- public String getPathTranslated() {
-
- if (context == null)
- return (null);
-
- if (getPathInfo() == null) {
- return (null);
- } else {
- return (context.getServletContext().getRealPath(getPathInfo()));
- }
-
- }
-
- /**
- * Return the principal that has been authenticated for this Request.
- */
- public Principal getPrincipal() {
- return (userPrincipal);
- }
-
- /**
- * Return the protocol and version used to make this Request.
- */
- public String getProtocol() {
- return httpRequest.protocol().toString();
- }
-
- /**
- * Return the query string associated with this request.
- */
- public String getQueryString() {
- String queryString = httpRequest.queryString().toString();
- if (queryString == null || queryString.equals("")) {
- return (null);
- } else {
- return queryString;
- }
- }
-
-
- /**
- * Read the Reader wrapping the input stream for this Request. The
- * default implementation wraps a <code>BufferedReader</code> around the
- * servlet input stream returned by <code>createInputStream()</code>.
- *
- * @exception IllegalStateException if <code>getInputStream()</code>
- * has already been called for this request
- * @exception IOException if an input/output error occurs
- */
- public BufferedReader getReader() throws IOException {
-
- if (usingInputStream)
- throw new IllegalStateException
- ("usingInputStream");
-
- usingReader = true;
- //inputBuffer.setConverter();// getB2C());
- return reader;
-
- }
-
- /**
- * Cached list of encoders.
- */
- protected HashMap encoders = new HashMap();
-
- public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";
-
- /**
- * Converter for the encoding associated with the request.
- * If encoding is changed - a different encoder will be returned.
- *
- * Encoders are cached ( per request ) - at least 8K per charset
- */
- public B2CConverter getB2C() throws IOException {
- String enc = getCharacterEncoding();
- if (enc == null) {
- enc = DEFAULT_CHARACTER_ENCODING;
- }
- B2CConverter conv =
- (B2CConverter) encoders.get(enc);
- if (conv == null) {
- conv = new B2CConverter(enc);
- encoders.put(enc, conv);
- }
- return conv;
- }
-
- /**
- * Return the real path of the specified virtual path.
- *
- * @param path Path to be translated
- *
- * @deprecated As of version 2.1 of the Java Servlet API, use
- * <code>ServletContext.getRealPath()</code>.
- */
- public String getRealPath(String path) {
-
- if (context == null)
- return (null);
- ServletContext servletContext = context; // .getServletContext();
- if (servletContext == null)
- return (null);
- else {
- try {
- return (servletContext.getRealPath(path));
- } catch (IllegalArgumentException e) {
- return (null);
- }
- }
-
- }
-
-
- /**
- * Return the remote IP address making this Request.
- */
- public String getRemoteAddr() {
- if (httpRequest.remoteAddr().isNull()) {
- httpRequest.remoteAddr().setString(connector.getRemoteAddr(this));
- }
- return httpRequest.remoteAddr().toString();
- }
-
-
- /**
- * Return the remote host name making this Request.
- */
- public String getRemoteHost() {
- if (httpRequest.remoteHost().isNull()) {
- httpRequest.remoteHost().setString(connector.getRemoteHost(this));
- }
- return httpRequest.remoteHost().toString();
- }
-
-
- /**
- * Returns the Internet Protocol (IP) source port of the client
- * or last proxy that sent the request.
- */
- public int getRemotePort(){
- return httpRequest.getRemotePort();
- }
-
-
- /**
- * Return the name of the remote user that has been authenticated
- * for this Request.
- */
- public String getRemoteUser() {
-
- if (userPrincipal != null) {
- return (userPrincipal.getName());
- } else {
- return (null);
- }
-
- }
-
-
- /**
- * Return the <code>ServletRequest</code> for which this object
- * is the facade. This method must be implemented by a subclass.
- */
- public HttpServletRequest getRequest() {
- return this;
- }
-
- public HttpRequest getHttpRequest() {
- return httpRequest;
- }
-
- 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
- * path, which may be interpreted as relative to the current request path.
- *
- * @param path Path of the resource to be wrapped
- */
- public RequestDispatcher getRequestDispatcher(String path) {
-
- if (context == null)
- return (null);
-
- // If the path is already context-relative, just pass it through
- if (path == null)
- return (null);
- else if (path.startsWith("/"))
- return (context.getRequestDispatcher(path));
-
- // Convert a request-relative path to a context-relative one
- String servletPath = (String) getAttribute(RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR);
- if (servletPath == null)
- servletPath = getServletPath();
-
- // Add the path info, if there is any
- String pathInfo = getPathInfo();
- String requestPath = null;
-
- if (pathInfo == null) {
- requestPath = servletPath;
- } else {
- requestPath = servletPath + pathInfo;
- }
-
- int pos = requestPath.lastIndexOf('/');
- String relative = null;
- if (pos >= 0) {
- relative = RequestUtil.normalize
- (requestPath.substring(0, pos + 1) + path);
- } else {
- relative = RequestUtil.normalize(requestPath + path);
- }
-
- return (context.getRequestDispatcher(relative));
-
- }
-
-
- /**
- * Return the session identifier included in this request, if any.
- */
- public String getRequestedSessionId() {
- return (requestedSessionId);
- }
-
-
- // ---------------------------------------------------- HttpRequest Methods
-
-
- /**
- * Get the request path.
- *
- * @return the request path
- */
- public MessageBytes getRequestPathMB() {
- return (mappingData.requestPath);
- }
-
-
- /**
- * Return the request URI for this request.
- */
- public String getRequestURI() {
- return httpRequest.requestURI().toString();
- }
-
- /**
- */
- public void setRequestURI(String uri) {
- httpRequest.decodedURI().setString(uri);
- try {
- UriNormalizer.decodeRequest(httpRequest.decodedURI(),
- httpRequest.requestURI(), httpRequest.getURLDecoder());
- } catch(IOException ioe) {
- ioe.printStackTrace();
- return;
- }
- }
-
-
-
- /**
- * Reconstructs the URL the client used to make the request.
- * The returned URL contains a protocol, server name, port
- * number, and server path, but it does not include query
- * string parameters.
- * <p>
- * Because this method returns a <code>StringBuffer</code>,
- * not a <code>String</code>, you can modify the URL easily,
- * for example, to append query parameters.
- * <p>
- * This method is useful for creating redirect messages and
- * for reporting errors.
- *
- * @return A <code>StringBuffer</code> object containing the
- * reconstructed URL
- */
- public StringBuffer getRequestURL() {
-
- StringBuffer url = new StringBuffer();
- String scheme = getScheme();
- int port = getServerPort();
- if (port < 0)
- port = 80; // Work around java.net.URL bug
-
- url.append(scheme);
- url.append("://");
- url.append(getServerName());
- if ((scheme.equals("http") && (port != 80))
- || (scheme.equals("https") && (port != 443))) {
- url.append(':');
- url.append(port);
- }
- url.append(getRequestURI());
-
- return (url);
-
- }
-
-
- /**
- * Return the Response with which this Request is associated.
- */
- public ServletResponseImpl getResponse() {
- return (this.response);
- }
-
-
- /**
- * Return the scheme used to make this Request.
- */
- public String getScheme() {
- String scheme = httpRequest.scheme().toString();
- if (scheme == null) {
- scheme = (isSecure() ? "https" : "http");
- }
- return scheme;
- }
-
-
- /**
- * Return the server name responding to this Request.
- */
- public String getServerName() {
- return (httpRequest.serverName().toString());
- }
-
-
- /**
- * Return the server port responding to this Request.
- */
- public int getServerPort() {
- return (httpRequest.getServerPort());
- }
-
-
- /**
- * Return the portion of the request URI used to select the servlet
- * that will process this request.
- */
- public String getServletPath() {
- return (mappingData.wrapperPath.toString());
- }
-
-
- /**
- * Get the servlet path.
- *
- * @return the servlet path
- */
- public MessageBytes getServletPathMB() {
- return (mappingData.wrapperPath);
- }
-
-
-
- /**
- * Return the input stream associated with this Request.
- */
- public InputStream getStream() {
- return inputStream;
- }
-
-
- /**
- * Return the principal that has been authenticated for this Request.
- */
- public Principal getUserPrincipal() {
- return userPrincipal;
- }
-
-
- /**
- * Return the Wrapper within which this Request is being processed.
- */
- public ServletConfigImpl getWrapper() {
- return (this.wrapper);
- }
-
-
- /**
- * Return <code>true</code> if the session identifier included in this
- * request came from a cookie.
- */
- public boolean isRequestedSessionIdFromCookie() {
-
- if (requestedSessionId != null)
- return (requestedSessionCookie);
- else
- return (false);
-
- }
-
-
- /**
- * Return <code>true</code> if the session identifier included in this
- * request came from the request URI.
- *
- * @deprecated As of Version 2.1 of the Java Servlet API, use
- * <code>isRequestedSessionIdFromURL()</code> instead.
- */
- public boolean isRequestedSessionIdFromUrl() {
- return (isRequestedSessionIdFromURL());
- }
-
-
- /**
- * Return <code>true</code> if the session identifier included in this
- * request came from the request URI.
- */
- public boolean isRequestedSessionIdFromURL() {
-
- if (requestedSessionId != null)
- return (requestedSessionURL);
- else
- return (false);
-
- }
-
-
- /**
- * Return <code>true</code> if the session identifier included in this
- * request identifies a valid session.
- */
- public boolean isRequestedSessionIdValid() {
-
- if (requestedSessionId == null)
- return (false);
- if (context == null)
- return (false);
- UserSessionManager manager = context.getManager();
- if (manager == null)
- return (false);
- HttpSession session = null;
- try {
- session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
- session = null;
- }
- if ((session != null) && manager.isValid(session))
- return (true);
- else
- return (false);
-
- }
-
- /**
- * Was this request received on a secure connection?
- */
- public boolean isSecure() {
- return (secure);
- }
-
-
- /**
- * Return <code>true</code> if the authenticated user principal
- * possesses the specified role name.
- *
- * @param role Role name to be validated
- */
- public boolean isUserInRole(String role) {
- // Have we got an authenticated principal at all?
- Principal userPrincipal = getPrincipal();
- if (userPrincipal == null)
- return (false);
-
- // Identify the Realm we will use for checking role assignmenets
- if (context == null)
- return (false);
-
- // Check for a role alias defined in a <security-role-ref> element
- if (wrapper != null) {
- String realRole = wrapper.getSecurityRoleRef(role);
- if (realRole != null) {
- role = realRole;
- }
- }
-
- if (role.equals(userPrincipal.getName())) {
- return true;
- }
-
- // TODO: check !!!!
- // Check for a role defined directly as a <security-role>
- return false;
- }
-
- /**
- * Release all object references, and initialize instance variables, in
- * preparation for reuse of this object.
- */
- public void recycle() {
-
- wrapper = null;
-
- dispatcherType = null;
- requestDispatcherPath = null;
-
- authType = null;
- inputBuffer.recycle();
- usingInputStream = false;
- usingReader = false;
- userPrincipal = null;
- subject = null;
- sessionParsed = false;
- parametersParsed = false;
- cookiesParsed = false;
- locales.clear();
- localesParsed = false;
- secure = false;
-
- attributes.clear();
- //notes.clear();
- cookies = null;
-
- if (session != null) {
- context.getManager().endAccess(session);
- }
- context = null;
- session = null;
- requestedSessionCookie = false;
- requestedSessionId = null;
- requestedSessionURL = false;
-
- parameterMap.setLocked(false);
- parameterMap.clear();
-
- mappingData.recycle();
- httpRequest.recycle();
- }
-
-
- /**
- * Remove the specified request attribute if it exists.
- *
- * @param name Name of the request attribute to remove
- */
- public void removeAttribute(String name) {
- Object value = null;
- boolean found = false;
-
- // Remove the specified attribute
- // Check for read only attribute
- // requests are per thread so synchronization unnecessary
-// if (readOnlyAttributes.containsKey(name)) {
-// return;
-// }
- found = attributes.containsKey(name);
- if (found) {
- value = attributes.get(name);
- attributes.remove(name);
- } else {
- return;
- }
-
- // Notify interested application event listeners
- List listeners = context.getListeners();
- if (listeners.size() == 0)
- return;
- ServletRequestAttributeEvent event = null;
- for (int i = 0; i < listeners.size(); i++) {
- if (!(listeners.get(i) instanceof ServletRequestAttributeListener))
- continue;
- ServletRequestAttributeListener listener =
- (ServletRequestAttributeListener) listeners.get(i);
- try {
- if (event == null) {
- event =
- new ServletRequestAttributeEvent(context.getServletContext(),
- getRequest(), name, value);
- }
- listener.attributeRemoved(event);
- } catch (Throwable t) {
- context.getLogger().log(Level.WARNING, "ServletRequestAttributeListner.attributeRemoved()", t);
- // Error valve will pick this execption up and display it to user
- attributes.put( ServletRequestImpl.EXCEPTION_ATTR, t );
- }
- }
- }
-
-
- /**
- * Set the specified request attribute to the specified value.
- *
- * @param name Name of the request attribute to set
- * @param value The associated value
- */
- public void setAttribute(String name, Object value) {
-
- // Name cannot be null
- if (name == null)
- throw new IllegalArgumentException
- ("setAttribute() name == null");
-
- // Null value is the same as removeAttribute()
- if (value == null) {
- removeAttribute(name);
- return;
- }
-
- if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) {
- dispatcherType = value;
- return;
- } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) {
- requestDispatcherPath = value;
- return;
- }
-
- Object oldValue = null;
- boolean replaced = false;
-
- // Add or replace the specified attribute
- // Check for read only attribute
- // requests are per thread so synchronization unnecessary
-// if (readOnlyAttributes.containsKey(name)) {
-// return;
-// }
-
- oldValue = attributes.put(name, value);
- if (oldValue != null) {
- replaced = true;
- }
-
- // Pass special attributes to the native layer
-// if (name.startsWith("org.apache.tomcat.")) {
-// reqB.setAttribute(name, value);
-// }
-//
- // Notify interested application event listeners
- List listeners = context.getListeners();
- if (listeners.size() == 0)
- return;
- ServletRequestAttributeEvent event = null;
-
- for (int i = 0; i < listeners.size(); i++) {
- if (!(listeners.get(i) instanceof ServletRequestAttributeListener))
- continue;
- ServletRequestAttributeListener listener =
- (ServletRequestAttributeListener) listeners.get(i);
- try {
- if (event == null) {
- if (replaced)
- event =
- new ServletRequestAttributeEvent(context.getServletContext(),
- getRequest(), name, oldValue);
- else
- event =
- new ServletRequestAttributeEvent(context.getServletContext(),
- getRequest(), name, value);
- }
- if (replaced) {
- listener.attributeReplaced(event);
- } else {
- listener.attributeAdded(event);
- }
- } catch (Throwable t) {
- context.getLogger().log(Level.WARNING, "ServletRequestAttributeListener error", t);
- // Error valve will pick this execption up and display it to user
- attributes.put( ServletRequestImpl.EXCEPTION_ATTR, t );
- }
- }
- }
-
-
- // --------------------------------------------- HttpServletRequest Methods
-
-
- /**
- * Set the authentication type used for this request, if any; otherwise
- * set the type to <code>null</code>. Typical values are "BASIC",
- * "DIGEST", or "SSL".
- *
- * @param type The authentication type used
- */
- public void setAuthType(String type) {
- this.authType = type;
- }
-
-
- /**
- * Overrides the name of the character encoding used in the body of
- * this request. This method must be called prior to reading request
- * parameters or reading input using <code>getReader()</code>.
- *
- * @param enc The character encoding to be used
- *
- * @exception UnsupportedEncodingException if the specified encoding
- * is not supported
- *
- * @since Servlet 2.3
- */
- public void setCharacterEncoding(String enc)
- throws UnsupportedEncodingException {
-
- // Ensure that the specified encoding is valid
- byte buffer[] = new byte[1];
- buffer[0] = (byte) 'a';
- String dummy = new String(buffer, enc);
-
- // Save the validated encoding
- httpRequest.setCharacterEncoding(enc);
-
- }
-
-
-// public void setConnection(Http11Connection con) {
-// this.con = con;
-// //reqB.messageWriter.setConnection(con);
-// //inputBuffer.setRequest(req);
-// }
-
-
- /**
- * Set the content length associated with this Request.
- *
- * @param length The new content length
- */
- public void setContentLength(int length) {
- // Not used
- }
-
-
- /**
- * Set the content type (and optionally the character encoding)
- * associated with this Request. For example,
- * <code>text/html; charset=ISO-8859-4</code>.
- *
- * @param type The new content type
- */
- public void setContentType(String type) {
- // Not used
- }
-
-
- /**
- * Set the Context within which this Request is being processed. This
- * must be called as soon as the appropriate Context is identified, because
- * it identifies the value to be returned by <code>getContextPath()</code>,
- * and thus enables parsing of the request URI.
- *
- * @param context The newly associated Context
- */
- public void setContext(ServletContextImpl context) {
- this.context = context;
- }
-
-
- /**
- * Set the context path for this Request. This will normally be called
- * when the associated Context is mapping the Request to a particular
- * Wrapper.
- *
- * @param path The context path
- */
- public void setContextPath(String path) {
-
- if (path == null) {
- mappingData.contextPath.setString("");
- } else {
- mappingData.contextPath.setString(path);
- }
-
- }
-
-
- /**
- * Set the set of cookies recieved with this Request.
- */
- public void setCookies(Cookie[] cookies) {
-
- this.cookies = cookies;
-
- }
-
-
- /**
- * Set the decoded request URI.
- *
- * @param uri The decoded request URI
- */
- public void setDecodedRequestURI(String uri) {
- // Not used
- }
-
-
- /**
- * Set the HTTP request method used for this Request.
- *
- * @param method The request method
- */
- public void setMethod(String method) {
- httpRequest.method().setString(method);
- }
-
-
- /**
- * Set the path information for this Request. This will normally be called
- * when the associated Context is mapping the Request to a particular
- * Wrapper.
- *
- * @param path The path information
- */
- public void setPathInfo(String path) {
- mappingData.pathInfo.setString(path);
- }
-
-
- /**
- * Set the protocol name and version associated with this Request.
- *
- * @param protocol Protocol name and version
- */
- public void setProtocol(String protocol) {
- // Not used
- }
-
-
- /**
- * Set the query string for this Request. This will normally be called
- * by the HTTP Connector, when it parses the request headers.
- *
- * @param query The query string
- */
- public void setQueryString(String query) {
- // Not used
- }
-
-
- /**
- * Set the IP address of the remote client associated with this Request.
- *
- * @param remoteAddr The remote IP address
- */
- public void setRemoteAddr(String remoteAddr) {
- // Not used
- }
-
-
- /**
- * Set the fully qualified name of the remote client associated with this
- * Request.
- *
- * @param remoteHost The remote host name
- */
- public void setRemoteHost(String remoteHost) {
- // Not used
- }
-
-
- /**
- * Set a flag indicating whether or not the requested session ID for this
- * request came in through a cookie. This is normally called by the
- * HTTP Connector, when it parses the request headers.
- *
- * @param flag The new flag
- */
- public void setRequestedSessionCookie(boolean flag) {
-
- this.requestedSessionCookie = flag;
-
- }
-
-
- /**
- * Set the requested session ID for this request. This is normally called
- * by the HTTP Connector, when it parses the request headers.
- *
- * @param id The new session id
- */
- public void setRequestedSessionId(String id) {
-
- this.requestedSessionId = id;
-
- }
-
-
- /**
- * Set a flag indicating whether or not the requested session ID for this
- * request came in through a URL. This is normally called by the
- * HTTP Connector, when it parses the request headers.
- *
- * @param flag The new flag
- */
- public void setRequestedSessionURL(boolean flag) {
-
- this.requestedSessionURL = flag;
-
- }
-
-
- /**
- * Set the name of the scheme associated with this request. Typical values
- * are <code>http</code>, <code>https</code>, and <code>ftp</code>.
- *
- * @param scheme The scheme
- */
- public void setScheme(String scheme) {
- // Not used
- }
-
-
- /**
- * Set the value to be returned by <code>isSecure()</code>
- * for this Request.
- *
- * @param secure The new isSecure value
- */
- public void setSecure(boolean secure) {
- this.secure = secure;
- }
-
-
- /**
- * Set the name of the server (virtual host) to process this request.
- *
- * @param name The server name
- */
- public void setServerName(String name) {
- httpRequest.serverName().setString(name);
- }
-
-
- /**
- * Set the port number of the server to process this request.
- *
- * @param port The server port
- */
- public void setServerPort(int port) {
- httpRequest.setServerPort(port);
- }
-
-
- /**
- * Set the servlet path for this Request. This will normally be called
- * when the associated Context is mapping the Request to a particular
- * Wrapper.
- *
- * @param path The servlet path
- */
- public void setServletPath(String path) {
- if (path != null)
- mappingData.wrapperPath.setString(path);
- }
-
-
- /**
- * Set the input stream associated with this Request.
- *
- * @param stream The new input stream
- */
- public void setStream(InputStream stream) {
- // Ignore
- }
-
-
- /**
- * Set the Principal who has been authenticated for this Request. This
- * value is also used to calculate the value to be returned by the
- * <code>getRemoteUser()</code> method.
- *
- * @param principal The user Principal
- */
- public void setUserPrincipal(Principal principal) {
-
- if (System.getSecurityManager() != null){
- HttpSession session = getSession(false);
- if ( (subject != null) &&
- (!subject.getPrincipals().contains(principal)) ){
- subject.getPrincipals().add(principal);
- } else if (session != null &&
- session.getAttribute(ServletRequestImpl.SUBJECT_ATTR) == null) {
- subject = new Subject();
- subject.getPrincipals().add(principal);
- }
- if (session != null){
- session.setAttribute(ServletRequestImpl.SUBJECT_ATTR, subject);
- }
- }
-
- this.userPrincipal = principal;
- }
-
-
- /**
- * Set the Wrapper within which this Request is being processed. This
- * must be called as soon as the appropriate Wrapper is identified, and
- * before the Request is ultimately passed to an application servlet.
- * @param wrapper The newly associated Wrapper
- */
- public void setWrapper(ServletConfigImpl wrapper) {
- this.wrapper = wrapper;
- }
-
-
- public String toString() {
- return httpRequest.requestURI().toString();
- }
-
-
- /**
- * Configures the given JSESSIONID cookie.
- *
- * @param cookie The JSESSIONID cookie to be configured
- */
- protected void configureSessionCookie(Cookie cookie) {
- cookie.setMaxAge(-1);
- String contextPath = null;
- if (//!connector.getEmptySessionPath() &&
- (getContext() != null)) {
- contextPath = getContext().getEncodedPath();
- }
- if ((contextPath != null) && (contextPath.length() > 0)) {
- cookie.setPath(contextPath);
- } else {
- cookie.setPath("/");
- }
- if (isSecure()) {
- cookie.setSecure(true);
- }
- }
-
-
- /**
- * Return the session associated with this Request, creating one
- * if necessary.
- */
- public HttpSession getSession() {
- return getSession(true);
- }
-
-
- public HttpSession getSession(boolean create) {
-
- // There cannot be a session if no context has been assigned yet
- if (context == null)
- return (null);
-
-
- // Return the requested session if it exists and is valid
- UserSessionManager manager = null;
- if (context != null)
- manager = context.getManager();
- if (manager == null)
- return (null); // Sessions are not supported
-
- // Return the current session if it exists and is valid
- if ((session != null) && !manager.isValid(session))
- session = null;
- if (session != null)
- return (session);
-
-
- if (requestedSessionId != null) {
- try {
- session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
- session = null;
- }
- if ((session != null) && !manager.isValid(session))
- session = null;
- if (session != null) {
- manager.access(session);
- return (session);
- }
- }
-
- // Create a new session if requested and the response is not committed
- if (!create)
- return (null);
- if ((context != null) && (response != null) &&
- context.getCookies() &&
- getResponse().isCommitted()) {
- throw new IllegalStateException
- ("isCommited()");
- }
-
- // Attempt to reuse session id if one was submitted in a cookie
- // Do not reuse the session id if it is from a URL, to prevent possible
- // phishing attacks
- if (// connector.getEmptySessionPath() &&
- isRequestedSessionIdFromCookie()) {
- session = manager.createSession(getRequestedSessionId());
- } else {
- session = manager.createSession(null);
- }
-
- // Creating a new session cookie based on that session
- if ((session != null) && (getContext() != null)
- && getContext().getCookies()) {
- Cookie cookie = new Cookie(ServletRequestImpl.SESSION_COOKIE_NAME,
- session.getId());
- configureSessionCookie(cookie);
- response.addCookie(cookie);
- }
-
- if (session != null) {
- manager.access(session);
- return (session);
- } else {
- return (null);
- }
-
- }
-
-
- /**
- * Return the URI converter.
- */
-// protected B2CConverter getURIConverter() {
-// return URIConverter;
-// }
-//
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Parse cookies.
- */
- protected void parseCookies() {
-
- cookiesParsed = true;
-
- Cookies serverCookies = httpRequest.getCookies();
- int count = serverCookies.getCookieCount();
- if (count <= 0)
- return;
-
- cookies = new Cookie[count];
-
- int idx=0;
- for (int i = 0; i < count; i++) {
- ServerCookie scookie = serverCookies.getCookie(i);
- try {
- Cookie cookie = new Cookie(scookie.getName().toString(),
- scookie.getValue().toString());
- cookie.setPath(scookie.getPath().toString());
- cookie.setVersion(scookie.getVersion());
- String domain = scookie.getDomain().toString();
- if (domain != null) {
- cookie.setDomain(scookie.getDomain().toString());
- }
- cookies[idx++] = cookie;
- } catch(IllegalArgumentException e) {
- // Ignore bad cookie
- }
- }
- if( idx < count ) {
- Cookie [] ncookies = new Cookie[idx];
- System.arraycopy(cookies, 0, ncookies, 0, idx);
- cookies = ncookies;
- }
-
- }
-
- /**
- * Parse request locales.
- */
- protected void parseLocales() {
-
- localesParsed = true;
-
- Enumeration values = getHeaders("accept-language");
-
- while (values.hasMoreElements()) {
- String value = values.nextElement().toString();
- parseLocalesHeader(value);
- }
-
- }
-
- /**
- * Parse accept-language header value.
- */
- protected void parseLocalesHeader(String value) {
-
- TreeMap locales = new LocaleParser().parseLocale(value);
- // Process the quality values in highest->lowest order (due to
- // negating the Double value when creating the key)
- Iterator keys = locales.keySet().iterator();
- while (keys.hasNext()) {
- Double key = (Double) keys.next();
- ArrayList list = (ArrayList) locales.get(key);
- Iterator values = list.iterator();
- while (values.hasNext()) {
- Locale locale = (Locale) values.next();
- addLocale(locale);
- }
- }
-
- }
-
- /**
- * Parse request parameters.
- */
- protected void parseParameters() {
-
- parametersParsed = true;
-
- Parameters parameters = httpRequest.getParameters();
-
- // getCharacterEncoding() may have been overridden to search for
- // hidden form field containing request encoding
- String enc = getCharacterEncoding();
-
-// boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
- if (enc != null) {
- parameters.setEncoding(enc);
-// if (useBodyEncodingForURI) {
-// parameters.setQueryStringEncoding(enc);
-// }
- } else {
- parameters.setEncoding(DEFAULT_CHARACTER_ENCODING);
-// if (useBodyEncodingForURI) {
-// parameters.setQueryStringEncoding
-// (DEFAULT_CHARACTER_ENCODING);
-// }
- }
-
- parameters.handleQueryParameters();
-
- if (usingInputStream || usingReader)
- return;
-
- if (!getMethod().equalsIgnoreCase("POST"))
- return;
-
- String contentType = getContentType();
- if (contentType == null)
- contentType = "";
- int semicolon = contentType.indexOf(';');
- if (semicolon >= 0) {
- contentType = contentType.substring(0, semicolon).trim();
- } else {
- contentType = contentType.trim();
- }
- if (!("application/x-www-form-urlencoded".equals(contentType)))
- return;
-
- int len = getContentLength();
-
- if (len > 0) {
-// int maxPostSize = connector.getMaxPostSize();
-// if ((maxPostSize > 0) && (len > maxPostSize)) {
-// context.getLogger().info
-// (sm.getString("reqB.postTooLarge"));
-// throw new IllegalStateException("Post too large");
-// }
- try {
- byte[] formData = null;
- if (len < CACHED_POST_LEN) {
- if (postData == null)
- postData = new byte[CACHED_POST_LEN];
- formData = postData;
- } else {
- formData = new byte[len];
- }
- int actualLen = readPostBody(formData, len);
- if (actualLen == len) {
- parameters.processParameters(formData, 0, len);
- }
- } catch (Throwable t) {
- ; // Ignore
- }
- }
-
- }
-
-
- /**
- * Parse session id in URL. Done in request for performance.
- * TODO: should be done in manager
- */
- protected void parseSessionCookiesId() {
- String sessionCookieName = context.getSessionCookieName();
-
- // Parse session id from cookies
- Cookies serverCookies = httpRequest.getCookies();
- int count = serverCookies.getCookieCount();
- if (count <= 0)
- return;
-
- for (int i = 0; i < count; i++) {
- ServerCookie scookie = serverCookies.getCookie(i);
- if (scookie.getName().equals(sessionCookieName)) {
- // Override anything requested in the URL
- if (!isRequestedSessionIdFromCookie()) {
- // Accept only the first session id cookie
- //scookie.getValue().convertToAscii();
-
- setRequestedSessionId
- (scookie.getValue().toString());
- setRequestedSessionCookie(true);
- setRequestedSessionURL(false);
- } else {
- if (!isRequestedSessionIdValid()) {
- // Replace the session id until one is valid
- //scookie.getValue().convertToAscii();
- setRequestedSessionId
- (scookie.getValue().toString());
- }
- }
- }
- }
- }
-
- /**
- * Parse session id in URL.
- */
- protected void parseSessionId() {
- ServletRequestImpl request = this;
- ByteChunk uriBC = httpRequest.requestURI().getByteChunk();
- int semicolon = uriBC.indexOf(match, 0, match.length(), 0);
-
- if (semicolon > 0) {
-
- // Parse session ID, and extract it from the decoded request URI
- int start = uriBC.getStart();
- int end = uriBC.getEnd();
-
- int sessionIdStart = semicolon + match.length();
- int semicolon2 = uriBC.indexOf(';', sessionIdStart);
- if (semicolon2 >= 0) {
- request.setRequestedSessionId
- (new String(uriBC.getBuffer(), start + sessionIdStart,
- semicolon2 - sessionIdStart));
- // Extract session ID from request URI
- byte[] buf = uriBC.getBuffer();
- for (int i = 0; i < end - start - semicolon2; i++) {
- buf[start + semicolon + i]
- = buf[start + i + semicolon2];
- }
- uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon);
- } else {
- request.setRequestedSessionId
- (new String(uriBC.getBuffer(), start + sessionIdStart,
- (end - start) - sessionIdStart));
- uriBC.setEnd(start + semicolon);
- }
- request.setRequestedSessionURL(true);
-
- } else {
- request.setRequestedSessionId(null);
- request.setRequestedSessionURL(false);
- }
-
- }
-
-
- /**
- * Read post body in an array.
- */
- protected int readPostBody(byte body[], int len)
- throws IOException {
-
- int offset = 0;
- do {
- int inputLen = getStream().read(body, offset, len - offset);
- if (inputLen <= 0) {
- return offset;
- }
- offset += inputLen;
- } while ((len - offset) > 0);
- return len;
-
- }
-
-
- /**
- * Test if a given name is one of the special Servlet-spec SSL attributes.
- */
- static boolean isSSLAttribute(String name) {
- return ServletRequestImpl.CERTIFICATES_ATTR.equals(name) ||
- ServletRequestImpl.CIPHER_SUITE_ATTR.equals(name) ||
- ServletRequestImpl.KEY_SIZE_ATTR.equals(name) ||
- ServletRequestImpl.SSL_SESSION_ID_ATTR.equals(name);
- }
-
-
- public void addAsyncListener(AsyncListener listener) {
- }
-
-
-
- public void addAsyncListener(AsyncListener listener,
- ServletRequest servletRequest,
- ServletResponse servletResponse) {
- }
-
-
-
- @Override
- public AsyncContext getAsyncContext() {
- return null;
- }
-
-
-
- @Override
- public ServletContext getServletContext() {
- return null;
- }
-
-
-
- @Override
- public boolean isAsyncStarted() {
- return false;
- }
-
-
-
- @Override
- public boolean isAsyncSupported() {
- return false;
- }
-
-
- public void setAsyncTimeout(long timeout) {
- }
-
-
-
- @Override
- public AsyncContext startAsync() throws IllegalStateException {
- return null;
- }
-
-
- @Override
- public AsyncContext startAsync(ServletRequest servletRequest,
- ServletResponse servletResponse)
- throws IllegalStateException {
- return null;
- }
-
-
-
- @Override
- public boolean authenticate(HttpServletResponse response)
- throws IOException, ServletException {
- return false;
- }
-
-
-
- @Override
- public Part getPart(String name) {
- return null;
- }
-
-
-
- @Override
- public void login(String username, String password) throws ServletException {
- }
-
-
-
- @Override
- public void logout() throws ServletException {
- }
-
-
-
- public long getAsyncTimeout() {
- return 0;
- }
-
-
-
- @Override
- public DispatcherType getDispatcherType() {
- return null;
- }
-
-
- @Override
- public Collection<Part> getParts() throws IOException, ServletException {
- return null;
- }
-
-
-}
+++ /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.coyote.servlet;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.servlet.RequestDispatcher;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpSession;
-
-import org.apache.tomcat.servlets.session.UserSessionManager;
-import org.apache.tomcat.servlets.util.Enumerator;
-import org.apache.tomcat.servlets.util.RequestUtil;
-
-
-/**
- * Wrapper around a <code>javax.servlet.http.HttpServletRequest</code>
- * that transforms an application request object (which might be the original
- * one passed to a servlet, or might be based on the 2.3
- * <code>javax.servlet.http.HttpServletRequestWrapper</code> class)
- * back into an internal <code>org.apache.catalina.HttpRequest</code>.
- * <p>
- * <strong>WARNING</strong>: Due to Java's lack of support for multiple
- * inheritance, all of the logic in <code>ApplicationRequest</code> is
- * duplicated in <code>ApplicationHttpRequest</code>. Make sure that you
- * keep these two classes in synchronization when making changes!
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
- */
-public class ServletRequestWrapperImpl extends HttpServletRequestWrapper {
-
-
- // ------------------------------------------------------- Static Variables
-
-
- /**
- * The set of attribute names that are special for request dispatchers.
- */
- protected static final String specials[] =
- { RequestDispatcherImpl.INCLUDE_REQUEST_URI_ATTR,
- RequestDispatcherImpl.INCLUDE_CONTEXT_PATH_ATTR,
- RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR,
- RequestDispatcherImpl.INCLUDE_PATH_INFO_ATTR,
- RequestDispatcherImpl.INCLUDE_QUERY_STRING_ATTR,
- RequestDispatcherImpl.FORWARD_REQUEST_URI_ATTR,
- RequestDispatcherImpl.FORWARD_CONTEXT_PATH_ATTR,
- RequestDispatcherImpl.FORWARD_SERVLET_PATH_ATTR,
- RequestDispatcherImpl.FORWARD_PATH_INFO_ATTR,
- RequestDispatcherImpl.FORWARD_QUERY_STRING_ATTR };
-
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Construct a new wrapped request around the specified servlet request.
- *
- * @param request The servlet request being wrapped
- */
- public ServletRequestWrapperImpl(HttpServletRequest request,
- ServletContextImpl context,
- boolean crossContext) {
-
- super(request);
- this.context = context;
- this.crossContext = crossContext;
- setRequest(request);
-
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The context for this request.
- */
- protected ServletContextImpl context = null;
-
-
- /**
- * The context path for this request.
- */
- protected String contextPath = null;
-
-
- /**
- * If this request is cross context, since this changes session accesss
- * behavior.
- */
- protected boolean crossContext = false;
-
-
- /**
- * The current dispatcher type.
- */
- protected Object dispatcherType = null;
-
-
- /**
- * Descriptive information about this implementation.
- */
- protected static final String info =
- "org.apache.catalina.core.ApplicationHttpRequest/1.0";
-
-
- /**
- * The request parameters for this request. This is initialized from the
- * wrapped request, but updates are allowed.
- */
- protected Map parameters = null;
-
-
- /**
- * Have the parameters for this request already been parsed?
- */
- private boolean parsedParams = false;
-
-
- /**
- * The path information for this request.
- */
- protected String pathInfo = null;
-
-
- /**
- * The query parameters for the current request.
- */
- private String queryParamString = null;
-
-
- /**
- * The query string for this request.
- */
- protected String queryString = null;
-
-
- /**
- * The current request dispatcher path.
- */
- protected Object requestDispatcherPath = null;
-
-
- /**
- * The request URI for this request.
- */
- protected String requestURI = null;
-
-
- /**
- * The servlet path for this request.
- */
- protected String servletPath = null;
-
-
- /**
- * The currently active session for this request.
- */
- protected HttpSession session = null;
-
-
- /**
- * Special attributes.
- */
- protected Object[] specialAttributes = new Object[specials.length];
-
-
- // ------------------------------------------------- ServletRequest Methods
-
-
- /**
- * Override the <code>getAttribute()</code> method of the wrapped request.
- *
- * @param name Name of the attribute to retrieve
- */
- public Object getAttribute(String name) {
-
- if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) {
- return dispatcherType;
- } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) {
- if ( requestDispatcherPath != null ){
- return requestDispatcherPath.toString();
- } else {
- return null;
- }
- }
-
- int pos = getSpecial(name);
- if (pos == -1) {
- return getRequest().getAttribute(name);
- } else {
- if ((specialAttributes[pos] == null)
- && (specialAttributes[5] == null) && (pos >= 5)) {
- // If it's a forward special attribute, and null, it means this
- // is an include, so we check the wrapped request since
- // the request could have been forwarded before the include
- return getRequest().getAttribute(name);
- } else {
- return specialAttributes[pos];
- }
- }
-
- }
-
-
- /**
- * Override the <code>getAttributeNames()</code> method of the wrapped
- * request.
- */
- public Enumeration getAttributeNames() {
- return (new AttributeNamesEnumerator());
- }
-
-
- /**
- * Override the <code>removeAttribute()</code> method of the
- * wrapped request.
- *
- * @param name Name of the attribute to remove
- */
- public void removeAttribute(String name) {
-
- if (!removeSpecial(name))
- getRequest().removeAttribute(name);
-
- }
-
-
- /**
- * Override the <code>setAttribute()</code> method of the
- * wrapped request.
- *
- * @param name Name of the attribute to set
- * @param value Value of the attribute to set
- */
- public void setAttribute(String name, Object value) {
-
- if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) {
- dispatcherType = value;
- return;
- } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) {
- requestDispatcherPath = value;
- return;
- }
-
- if (!setSpecial(name, value)) {
- getRequest().setAttribute(name, value);
- }
-
- }
-
-
- /**
- * Return a RequestDispatcher that wraps the resource at the specified
- * path, which may be interpreted as relative to the current request path.
- *
- * @param path Path of the resource to be wrapped
- */
- public RequestDispatcher getRequestDispatcher(String path) {
-
- if (context == null)
- return (null);
-
- // If the path is already context-relative, just pass it through
- if (path == null)
- return (null);
- else if (path.startsWith("/"))
- return (context.getServletContext().getRequestDispatcher(path));
-
- // Convert a request-relative path to a context-relative one
- String servletPath =
- (String) getAttribute(RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR);
- if (servletPath == null)
- servletPath = getServletPath();
-
- // Add the path info, if there is any
- String pathInfo = getPathInfo();
- String requestPath = null;
-
- if (pathInfo == null) {
- requestPath = servletPath;
- } else {
- requestPath = servletPath + pathInfo;
- }
-
- int pos = requestPath.lastIndexOf('/');
- String relative = null;
- if (pos >= 0) {
- relative = RequestUtil.normalize
- (requestPath.substring(0, pos + 1) + path);
- } else {
- relative = RequestUtil.normalize(requestPath + path);
- }
-
- return (context.getServletContext().getRequestDispatcher(relative));
-
- }
-
-
- // --------------------------------------------- HttpServletRequest Methods
-
-
- /**
- * Override the <code>getContextPath()</code> method of the wrapped
- * request.
- */
- public String getContextPath() {
-
- return (this.contextPath);
-
- }
-
-
- /**
- * Override the <code>getParameter()</code> method of the wrapped request.
- *
- * @param name Name of the requested parameter
- */
- public String getParameter(String name) {
-
- parseParameters();
-
- Object value = parameters.get(name);
- if (value == null)
- return (null);
- else if (value instanceof String[])
- return (((String[]) value)[0]);
- else if (value instanceof String)
- return ((String) value);
- else
- return (value.toString());
-
- }
-
-
- /**
- * Override the <code>getParameterMap()</code> method of the
- * wrapped request.
- */
- public Map getParameterMap() {
-
- parseParameters();
- return (parameters);
-
- }
-
-
- /**
- * Override the <code>getParameterNames()</code> method of the
- * wrapped request.
- */
- public Enumeration getParameterNames() {
-
- parseParameters();
- return (new Enumerator(parameters.keySet()));
-
- }
-
-
- /**
- * Override the <code>getParameterValues()</code> method of the
- * wrapped request.
- *
- * @param name Name of the requested parameter
- */
- public String[] getParameterValues(String name) {
-
- parseParameters();
- Object value = parameters.get(name);
- if (value == null)
- return ((String[]) null);
- else if (value instanceof String[])
- return ((String[]) value);
- else if (value instanceof String) {
- String values[] = new String[1];
- values[0] = (String) value;
- return (values);
- } else {
- String values[] = new String[1];
- values[0] = value.toString();
- return (values);
- }
-
- }
-
-
- /**
- * Override the <code>getPathInfo()</code> method of the wrapped request.
- */
- public String getPathInfo() {
-
- return (this.pathInfo);
-
- }
-
-
- /**
- * Override the <code>getQueryString()</code> method of the wrapped
- * request.
- */
- public String getQueryString() {
-
- return (this.queryString);
-
- }
-
-
- /**
- * Override the <code>getRequestURI()</code> method of the wrapped
- * request.
- */
- public String getRequestURI() {
-
- return (this.requestURI);
-
- }
-
-
- /**
- * Override the <code>getRequestURL()</code> method of the wrapped
- * request.
- */
- public StringBuffer getRequestURL() {
-
- StringBuffer url = new StringBuffer();
- String scheme = getScheme();
- int port = getServerPort();
- if (port < 0)
- port = 80; // Work around java.net.URL bug
-
- url.append(scheme);
- url.append("://");
- url.append(getServerName());
- if ((scheme.equals("http") && (port != 80))
- || (scheme.equals("https") && (port != 443))) {
- url.append(':');
- url.append(port);
- }
- url.append(getRequestURI());
-
- return (url);
-
- }
-
-
- /**
- * Override the <code>getServletPath()</code> method of the wrapped
- * request.
- */
- public String getServletPath() {
-
- return (this.servletPath);
-
- }
-
-
- /**
- * Return the session associated with this Request, creating one
- * if necessary.
- */
- public HttpSession getSession() {
- return (getSession(true));
- }
-
-
- /**
- * Return the session associated with this Request, creating one
- * if necessary and requested.
- *
- * @param create Create a new session if one does not exist
- */
- public HttpSession getSession(boolean create) {
-
- if (crossContext) {
-
- // There cannot be a session if no context has been assigned yet
- if (context == null)
- return (null);
- UserSessionManager manager = context.getManager();
- // Return the current session if it exists and is valid
- if (session != null && manager.isValid(session)) {
- return session;
- }
-
- HttpSession other = super.getSession(false);
- if (create && (other == null)) {
- // First create a session in the first context: the problem is
- // that the top level request is the only one which can
- // create the cookie safely
- other = super.getSession(true);
- }
- if (other != null) {
- HttpSession localSession = null;
- try {
- localSession =
- manager.findSession(other.getId());
- } catch (IOException e) {
- // Ignore
- }
- if (localSession == null && create) {
- localSession =
- context.getManager().createSession(other.getId());
- }
- if (localSession != null) {
- context.getManager().access(localSession);
- session = localSession;
- return session;
- }
- }
- return null;
-
- } else {
- return super.getSession(create);
- }
-
- }
-
-
- /**
- * Returns true if the request specifies a JSESSIONID that is valid within
- * the context of this ApplicationHttpRequest, false otherwise.
- *
- * @return true if the request specifies a JSESSIONID that is valid within
- * the context of this ApplicationHttpRequest, false otherwise.
- */
- public boolean isRequestedSessionIdValid() {
-
- if (crossContext) {
-
- String requestedSessionId = getRequestedSessionId();
- if (requestedSessionId == null)
- return (false);
- if (context == null)
- return (false);
- UserSessionManager manager = context.getManager();
- if (manager == null)
- return (false);
- HttpSession session = null;
- try {
- session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
- session = null;
- }
- if ((session != null) && manager.isValid(session)) {
- return (true);
- } else {
- return (false);
- }
-
- } else {
- return super.isRequestedSessionIdValid();
- }
- }
-
-
- // -------------------------------------------------------- Package Methods
-
-
- /**
- * Recycle this request
- */
- public void recycle() {
- if (session != null) {
- context.getManager().endAccess(session);
- }
- }
-
-
- /**
- * Return descriptive information about this implementation.
- */
- public String getInfo() {
-
- return (info);
-
- }
-
-
- /**
- * Perform a shallow copy of the specified Map, and return the result.
- *
- * @param orig Origin Map to be copied
- */
- Map copyMap(Map orig) {
-
- if (orig == null)
- return (new HashMap());
- HashMap dest = new HashMap();
- Iterator keys = orig.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- dest.put(key, orig.get(key));
- }
- return (dest);
-
- }
-
-
- /**
- * Set the context path for this request.
- *
- * @param contextPath The new context path
- */
- void setContextPath(String contextPath) {
-
- this.contextPath = contextPath;
-
- }
-
-
- /**
- * Set the path information for this request.
- *
- * @param pathInfo The new path info
- */
- void setPathInfo(String pathInfo) {
-
- this.pathInfo = pathInfo;
-
- }
-
-
- /**
- * Set the query string for this request.
- *
- * @param queryString The new query string
- */
- void setQueryString(String queryString) {
-
- this.queryString = queryString;
-
- }
-
-
- /**
- * Set the request that we are wrapping.
- *
- * @param request The new wrapped request
- */
- void setRequest(HttpServletRequest request) {
-
- super.setRequest(request);
-
- // Initialize the attributes for this request
- dispatcherType = request.getAttribute(ServletRequestImpl.DISPATCHER_TYPE_ATTR);
- requestDispatcherPath =
- request.getAttribute(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR);
-
- // Initialize the path elements for this request
- contextPath = request.getContextPath();
- pathInfo = request.getPathInfo();
- queryString = request.getQueryString();
- requestURI = request.getRequestURI();
- servletPath = request.getServletPath();
-
- }
-
-
- /**
- * Set the request URI for this request.
- *
- * @param requestURI The new request URI
- */
- void setRequestURI(String requestURI) {
-
- this.requestURI = requestURI;
-
- }
-
-
- /**
- * Set the servlet path for this request.
- *
- * @param servletPath The new servlet path
- */
- void setServletPath(String servletPath) {
-
- this.servletPath = servletPath;
-
- }
-
-
- /**
- * Parses the parameters of this request.
- *
- * If parameters are present in both the query string and the request
- * content, they are merged.
- */
- void parseParameters() {
-
- if (parsedParams) {
- return;
- }
-
- parameters = new HashMap();
- parameters = copyMap(getRequest().getParameterMap());
- mergeParameters();
- parsedParams = true;
- }
-
-
- /**
- * Save query parameters for this request.
- *
- * @param queryString The query string containing parameters for this
- * request
- */
- void setQueryParams(String queryString) {
- this.queryParamString = queryString;
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Is this attribute name one of the special ones that is added only for
- * included servlets?
- *
- * @param name Attribute name to be tested
- */
- protected boolean isSpecial(String name) {
-
- for (int i = 0; i < specials.length; i++) {
- if (specials[i].equals(name))
- return (true);
- }
- return (false);
-
- }
-
-
- /**
- * Get a special attribute.
- *
- * @return the special attribute pos, or -1 if it is not a special
- * attribute
- */
- protected int getSpecial(String name) {
- for (int i = 0; i < specials.length; i++) {
- if (specials[i].equals(name)) {
- return (i);
- }
- }
- return (-1);
- }
-
-
- /**
- * Set a special attribute.
- *
- * @return true if the attribute was a special attribute, false otherwise
- */
- protected boolean setSpecial(String name, Object value) {
- for (int i = 0; i < specials.length; i++) {
- if (specials[i].equals(name)) {
- specialAttributes[i] = value;
- return (true);
- }
- }
- return (false);
- }
-
-
- /**
- * Remove a special attribute.
- *
- * @return true if the attribute was a special attribute, false otherwise
- */
- protected boolean removeSpecial(String name) {
- for (int i = 0; i < specials.length; i++) {
- if (specials[i].equals(name)) {
- specialAttributes[i] = null;
- return (true);
- }
- }
- return (false);
- }
-
-
- /**
- * Merge the two sets of parameter values into a single String array.
- *
- * @param values1 First set of values
- * @param values2 Second set of values
- */
- protected String[] mergeValues(Object values1, Object values2) {
-
- ArrayList results = new ArrayList();
-
- if (values1 == null)
- ;
- else if (values1 instanceof String)
- results.add(values1);
- else if (values1 instanceof String[]) {
- String values[] = (String[]) values1;
- for (int i = 0; i < values.length; i++)
- results.add(values[i]);
- } else
- results.add(values1.toString());
-
- if (values2 == null)
- ;
- else if (values2 instanceof String)
- results.add(values2);
- else if (values2 instanceof String[]) {
- String values[] = (String[]) values2;
- for (int i = 0; i < values.length; i++)
- results.add(values[i]);
- } else
- results.add(values2.toString());
-
- String values[] = new String[results.size()];
- return ((String[]) results.toArray(values));
-
- }
-
-
- // ------------------------------------------------------ Private Methods
-
-
- /**
- * Merge the parameters from the saved query parameter string (if any), and
- * the parameters already present on this request (if any), such that the
- * parameter values from the query string show up first if there are
- * duplicate parameter names.
- */
- private void mergeParameters() {
-
- if ((queryParamString == null) || (queryParamString.length() < 1))
- return;
-
- HashMap queryParameters = new HashMap();
- String encoding = getCharacterEncoding();
- if (encoding == null)
- encoding = "ISO-8859-1";
- try {
- RequestUtil.parseParameters
- (queryParameters, queryParamString, encoding);
- } catch (Exception e) {
- ;
- }
- Iterator keys = parameters.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- Object value = queryParameters.get(key);
- if (value == null) {
- queryParameters.put(key, parameters.get(key));
- continue;
- }
- queryParameters.put
- (key, mergeValues(value, parameters.get(key)));
- }
- parameters = queryParameters;
-
- }
-
-
- // ----------------------------------- AttributeNamesEnumerator Inner Class
-
-
- /**
- * Utility class used to expose the special attributes as being available
- * as request attributes.
- */
- protected class AttributeNamesEnumerator implements Enumeration {
-
- protected int pos = -1;
- protected int last = -1;
- protected Enumeration parentEnumeration = null;
- protected String next = null;
-
- public AttributeNamesEnumerator() {
- parentEnumeration = getRequest().getAttributeNames();
- for (int i = 0; i < specialAttributes.length; i++) {
- if (getAttribute(specials[i]) != null) {
- last = i;
- }
- }
- }
-
- public boolean hasMoreElements() {
- return ((pos != last) || (next != null)
- || ((next = findNext()) != null));
- }
-
- public Object nextElement() {
- if (pos != last) {
- for (int i = pos + 1; i <= last; i++) {
- if (getAttribute(specials[i]) != null) {
- pos = i;
- return (specials[i]);
- }
- }
- }
- String result = next;
- if (next != null) {
- next = findNext();
- } else {
- throw new NoSuchElementException();
- }
- return result;
- }
-
- protected String findNext() {
- String result = null;
- while ((result == null) && (parentEnumeration.hasMoreElements())) {
- String current = (String) parentEnumeration.nextElement();
- if (!isSpecial(current)) {
- result = current;
- }
- }
- return result;
- }
-
- }
-
-
-}
+++ /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.coyote.servlet;
-
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.TimeZone;
-import java.util.Vector;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-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;
-
-/**
- * Wrapper object for the Coyote response.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
- * @version $Revision$ $Date$
- */
-
-public class ServletResponseImpl
- implements HttpServletResponse {
-
- /**
- * Format for http response header date field
- * From DateTool
- */
- public static final String HTTP_RESPONSE_DATE_HEADER =
- "EEE, dd MMM yyyy HH:mm:ss zzz";
-
- // ----------------------------------------------------------- Constructors
-
-
- ServletResponseImpl() {
- urlEncoder.addSafeCharacter('/');
- }
-
-
- /**
- * The date format we will use for creating date headers.
- */
- protected SimpleDateFormat format = null;
-
-
- /**
- * The associated output buffer.
- */
- protected BodyWriter outputBuffer;
-
-
- /**
- * The associated output stream.
- */
- protected ServletOutputStreamImpl outputStream;
-
-
- /**
- * The associated writer.
- */
- protected PrintWriter writer;
-
-
- /**
- * The application commit flag.
- */
- protected boolean appCommitted = false;
-
-
- /**
- * The included flag.
- */
- protected boolean included = false;
-
-
- /**
- * The characterEncoding flag
- */
- private boolean isCharacterEncodingSet = false;
-
- /**
- * The error flag.
- */
- protected boolean error = false;
-
-
- /**
- * The set of Cookies associated with this Response.
- */
- protected ArrayList cookies = new ArrayList();
-
-
- /**
- * Using output stream flag.
- */
- protected boolean usingOutputStream = false;
-
-
- /**
- * Using writer flag.
- */
- protected boolean usingWriter = false;
-
-
- /**
- * The request with which this response is associated.
- */
- protected ServletRequestImpl req = null;
-
- /**
- * URL encoder.
- */
- protected UEncoder urlEncoder = new UEncoder();
-
-
- /**
- * Recyclable buffer to hold the redirect URL.
- */
- 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
-
-
- /**
- * Release all object references, and initialize instance variables, in
- * preparation for reuse of this object.
- */
- public void recycle() {
-
- usingOutputStream = false;
- usingWriter = false;
- appCommitted = false;
- commited = false;
- included = false;
- error = false;
- isCharacterEncodingSet = false;
-
- cookies.clear();
-
- outputBuffer.recycle();
-
- resB.recycle();
- }
-
-
- // ------------------------------------------------------- Response Methods
-
-
- /**
- * Return the number of bytes actually written to the output stream.
- */
- public int getContentCount() {
- return outputBuffer.getBytesWritten() + outputBuffer.getCharsWritten();
- }
-
-
- /**
- * Set the application commit flag.
- *
- * @param appCommitted The new application committed flag value
- */
- public void setAppCommitted(boolean appCommitted) {
- this.appCommitted = appCommitted;
- }
-
-
- /**
- * Application commit flag accessor.
- */
- public boolean isAppCommitted() {
- return (this.appCommitted || isCommitted() || isSuspended()
- || ((getHttpResponse().getContentLength() > 0)
- && (getContentCount() >= getHttpResponse().getContentLength())));
- }
-
-
- /**
- * Return the "processing inside an include" flag.
- */
- public boolean getIncluded() {
- return included;
- }
-
-
- /**
- * Set the "processing inside an include" flag.
- *
- * @param included <code>true</code> if we are currently inside a
- * RequestDispatcher.include(), else <code>false</code>
- */
- public void setIncluded(boolean included) {
- this.included = included;
- }
-
-
- /**
- * Return the Request with which this Response is associated.
- */
- public ServletRequestImpl getRequest() {
- return (this.req);
- }
-
- /**
- * Set the Request with which this Response is associated.
- *
- * @param request The new associated request
- */
- public void setRequest(ServletRequestImpl request) {
- this.req = (ServletRequestImpl) request;
- }
-
-
- /**
- * Return the output stream associated with this Response.
- */
- public OutputStream getStream() {
- return outputStream;
- }
-
-
- /**
- * Set the output stream associated with this Response.
- *
- * @param stream The new output stream
- */
- public void setStream(OutputStream stream) {
- // This method is evil
- }
-
-
- /**
- * Set the suspended flag.
- *
- * @param suspended The new suspended flag value
- */
- public void setSuspended(boolean suspended) throws IOException {
- //coyoteResponse.setCommitted(true);
- flushBuffer();
- outputBuffer.setSuspended(suspended);
- }
-
-
- /**
- * Suspended flag accessor.
- */
- public boolean isSuspended() {
- return outputBuffer.isSuspended();
- }
-
-
- /**
- * Set the error flag.
- */
- public void setError() {
- error = true;
- }
-
-
- /**
- * Error flag accessor.
- */
- public boolean isError() {
- return error;
- }
-
-
- /**
- * Create and return a ServletOutputStream to write the content
- * associated with this Response.
- *
- * @exception IOException if an input/output error occurs
- */
- public ServletOutputStream createOutputStream()
- throws IOException {
- // Probably useless
- return outputStream;
- }
-
- /**
- * 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() {
- String ret = contentType;
-
- if (ret != null
- && characterEncoding != null
- && charsetSet) {
- ret = ret + ";charset=" + characterEncoding;
- }
-
- return ret;
- }
-
-
- /**
- * Return a PrintWriter that can be used to render error messages,
- * regardless of whether a stream or writer has already been acquired.
- *
- * @return Writer which can be used for error reports. If the response is
- * not an error report returned using sendError or triggered by an
- * unexpected exception thrown during the servlet processing
- * (and only in that case), null will be returned if the response stream
- * has already been used.
- *
- * @exception IOException if an input/output error occurs
- */
- public PrintWriter getReporter() throws IOException {
- if (outputBuffer.isNew()) {
- outputBuffer.checkConverter();
- if (writer == null) {
- writer = new ServletWriterImpl(outputBuffer);
- }
- return writer;
- } else {
- return null;
- }
- }
-
-
- // ------------------------------------------------ ServletResponse Methods
-
-
- /**
- * Flush the buffer and commit this response.
- *
- * @exception IOException if an input/output error occurs
- */
- public void flushBuffer()
- throws IOException {
- outputBuffer.flush();
- }
-
-
- /**
- * Return the actual buffer size used for this Response.
- */
- public int getBufferSize() {
- return outputBuffer.getBufferSize();
- }
-
-
- /**
- * Return the character encoding used for this Response.
- */
- public String getCharacterEncoding() {
- return characterEncoding;
- }
-
-
- /**
- * Return the servlet output stream associated with this Response.
- *
- * @exception IllegalStateException if <code>getWriter</code> has
- * already been called for this response
- * @exception IOException if an input/output error occurs
- */
- public ServletOutputStream getOutputStream()
- throws IOException {
-
- if (usingWriter)
- throw new IllegalStateException
- ("usingWriter");
-
- usingOutputStream = true;
- return outputStream;
-
- }
-
- public BodyWriter getBodyWriter() {
- return outputBuffer;
- }
-
- /**
- * Return the Locale assigned to this response.
- */
- public Locale getLocale() {
- return locale;
- }
-
-
- /**
- * Return the writer associated with this Response.
- *
- * @exception IllegalStateException if <code>getOutputStream</code> has
- * already been called for this response
- * @exception IOException if an input/output error occurs
- */
- public PrintWriter getWriter()
- throws IOException {
-
- if (usingOutputStream)
- throw new IllegalStateException
- ("usingOutputStream");
-
- /*
- * If the response's character encoding has not been specified as
- * described in <code>getCharacterEncoding</code> (i.e., the method
- * just returns the default value <code>ISO-8859-1</code>),
- * <code>getWriter</code> updates it to <code>ISO-8859-1</code>
- * (with the effect that a subsequent call to getContentType() will
- * include a charset=ISO-8859-1 component which will also be
- * reflected in the Content-Type response header, thereby satisfying
- * the Servlet spec requirement that containers must communicate the
- * character encoding used for the servlet response's writer to the
- * client).
- */
- setCharacterEncoding(getCharacterEncoding());
-
- usingWriter = true;
- outputBuffer.checkConverter();
- if (writer == null) {
- writer = new ServletWriterImpl(outputBuffer);
- }
- return writer;
-
- }
-
-
- /**
- * Has the output of this response already been committed?
- */
- public boolean isCommitted() {
- return getHttpResponse().isCommitted();
- }
-
- /**
- * Clear any content written to the buffer.
- *
- * @exception IllegalStateException if this response has already
- * been committed
- */
- public void reset() {
-
- if (included)
- return; // Ignore any call from an included servlet
-
- 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();
- }
-
-
- /**
- * Reset the data buffer but not any status or header information.
- *
- * @exception IllegalStateException if the response has already
- * been committed
- */
- public void resetBuffer() {
-
- if (isCommitted())
- throw new IllegalStateException("isCommitted");
-
- outputBuffer.reset();
-
- }
-
-
- /**
- * Set the buffer size to be used for this Response.
- *
- * @param size The new buffer size
- *
- * @exception IllegalStateException if this method is called after
- * output has been committed for this response
- */
- public void setBufferSize(int size) {
-
- if (isCommitted() || !outputBuffer.isNew())
- throw new IllegalStateException
- ("isCommitted || !isNew");
-
- outputBuffer.setBufferSize(size);
-
- }
-
-
- /**
- * Set the content length (in bytes) for this Response.
- * Ignored for writers if non-ISO-8859-1 encoding ( we could add more
- * encodings that are constant.
- */
- public void setContentLength(int length) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- // writers can use variable-length encoding.
- if (usingWriter && !"ISO-8859-1".equals(getCharacterEncoding())) {
- return;
- }
- getHttpResponse().setContentLength(length);
-
- }
-
-
- /**
- * Set the content type for this Response.
- *
- * @param type The new content type
- */
- public void setContentType(String type) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- // Ignore charset if getWriter() has already been called
- if (usingWriter) {
- if (type != null) {
- int index = type.indexOf(";");
- if (index != -1) {
- type = type.substring(0, index);
- }
- }
- }
-
- getHttpResponse().setContentType(type);
-
- // Check to see if content type contains charset
- if (type != null) {
- int index = type.indexOf(";");
- if (index != -1) {
- int len = type.length();
- index++;
- while (index < len && Character.isSpace(type.charAt(index))) {
- index++;
- }
- if (index+7 < len
- && type.charAt(index) == 'c'
- && type.charAt(index+1) == 'h'
- && type.charAt(index+2) == 'a'
- && type.charAt(index+3) == 'r'
- && type.charAt(index+4) == 's'
- && type.charAt(index+5) == 'e'
- && type.charAt(index+6) == 't'
- && type.charAt(index+7) == '=') {
- isCharacterEncodingSet = true;
- }
- }
- }
- }
-
-
- /*
- * Overrides the name of the character encoding used in the body
- * of the request. This method must be called prior to reading
- * request parameters or reading input using getReader().
- *
- * @param charset String containing the name of the chararacter encoding.
- */
- public void setCharacterEncoding(String charset) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- // Ignore any call made after the getWriter has been invoked
- // The default should be used
- if (usingWriter)
- return;
-
- if (isCommitted())
- return;
- if (charset == null)
- return;
-
- characterEncoding = charset;
- charsetSet=true;
- isCharacterEncodingSet = true;
- }
-
-
-
- /**
- * Set the Locale that is appropriate for this response, including
- * setting the appropriate character encoding.
- *
- * @param locale The new locale
- */
- public void setLocale(Locale locale) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- 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
- if (usingWriter)
- return;
-
- if (isCharacterEncodingSet) {
- return;
- }
-
- Locale2Charset cm = req.getContext().getCharsetMapper();
- String charset = cm.getCharset( locale );
- if ( charset != null ){
- setCharacterEncoding(charset);
- }
-
- }
-
-
- // --------------------------------------------------- HttpResponse Methods
-
-
- /**
- * Return an array of all cookies set for this response, or
- * a zero-length array if no cookies have been set.
- */
- public Cookie[] getCookies() {
- return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()]));
- }
-
-
- /**
- * Return the value for the specified header, or <code>null</code> if this
- * header has not been set. If more than one value was added for this
- * name, only the first is returned; use getHeaderValues() to retrieve all
- * of them.
- *
- * @param name Header name to look up
- */
- public String getHeader(String 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 Collection<String> getHeaderNames() {
-
- MimeHeaders headers = getHttpResponse().getMimeHeaders();
- int n = headers.size();
- ArrayList<String> result = new ArrayList<String>();
- for (int i = 0; i < n; i++) {
- result.add(headers.getName(i).toString());
- }
- return result;
- }
-
-
- /**
- * Return an array of all the header values associated with the
- * specified header name, or an zero-length array if there are no such
- * header values.
- *
- * @param name Header name to look up
- */
- public String[] getHeaderValues(String name) {
-
- Enumeration enumeration = getHttpResponse().getMimeHeaders().values(name);
- Vector result = new Vector();
- while (enumeration.hasMoreElements()) {
- result.addElement(enumeration.nextElement());
- }
- String[] resultArray = new String[result.size()];
- result.copyInto(resultArray);
- return resultArray;
-
- }
-
-
- /**
- * Return the error message that was set with <code>sendError()</code>
- * for this Response.
- */
- public String getMessage() {
- return getHttpResponse().getMessage();
- }
-
-
- /**
- * Return the HTTP status code associated with this Response.
- */
- public int getStatus() {
- return getHttpResponse().getStatus();
- }
-
-
- /**
- * Reset this response, and specify the values for the HTTP status code
- * and corresponding message.
- *
- * @exception IllegalStateException if this response has already been
- * committed
- */
- public void reset(int status, String message) {
- reset();
- setStatus(status, message);
- }
-
-
- // -------------------------------------------- HttpServletResponse Methods
-
-
- /**
- * Add the specified Cookie to those that will be included with
- * this Response.
- *
- * @param cookie Cookie to be added
- */
- public void addCookie(final Cookie cookie) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- cookies.add(cookie);
-
- final StringBuffer sb = new StringBuffer();
- ServerCookie.appendCookieValue
- (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(),
- cookie.getPath(), cookie.getDomain(), cookie.getComment(),
- cookie.getMaxAge(), cookie.getSecure(), false);
-
- // the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
- // RFC2965 is not supported by browsers and the Servlet spec
- // asks for 2109.
- addHeader("Set-Cookie", sb.toString());
-
- }
-
-
- /**
- * Add the specified date header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Date value to be set
- */
- public void addDateHeader(String name, long value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included) {
- return;
- }
-
- if (format == null) {
- format = new SimpleDateFormat(HTTP_RESPONSE_DATE_HEADER,
- Locale.US);
- format.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
-
- addHeader(name, FastHttpDateFormat.formatDate(value, format));
-
- }
-
-
- /**
- * Add the specified header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Value to be set
- */
- public void addHeader(String name, String value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- getHttpResponse().addHeader(name, value);
-
- }
-
-
- /**
- * Add the specified integer header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Integer value to be set
- */
- public void addIntHeader(String name, int value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- addHeader(name, "" + value);
-
- }
-
-
- /**
- * Has the specified header been set already in this response?
- *
- * @param name Name of the header to check
- */
- public boolean containsHeader(String name) {
- // Need special handling for Content-Type and Content-Length due to
- // special handling of these in coyoteResponse
- char cc=name.charAt(0);
- if(cc=='C' || cc=='c') {
- if(name.equalsIgnoreCase("Content-Type")) {
- // Will return null if this has not been set
- return getContentType() != null;
- }
- if(name.equalsIgnoreCase("Content-Length")) {
- // -1 means not known and is not sent to client
- return (getHttpResponse().getContentLength() != -1);
- }
- }
-
- return getHttpResponse().containsHeader(name);
- }
-
-
- /**
- * Encode the session identifier associated with this response
- * into the specified redirect URL, if necessary.
- *
- * @param url URL to be encoded
- */
- public String encodeRedirectURL(String url) {
-
- if (isEncodeable(toAbsolute(url))) {
- return (toEncoded(url, req.getSession().getId()));
- } else {
- return (url);
- }
-
- }
-
-
- /**
- * Encode the session identifier associated with this response
- * into the specified redirect URL, if necessary.
- *
- * @param url URL to be encoded
- *
- * @deprecated As of Version 2.1 of the Java Servlet API, use
- * <code>encodeRedirectURL()</code> instead.
- */
- public String encodeRedirectUrl(String url) {
- return (encodeRedirectURL(url));
- }
-
-
- /**
- * Encode the session identifier associated with this response
- * into the specified URL, if necessary.
- *
- * @param url URL to be encoded
- */
- public String encodeURL(String url) {
-
- String absolute = toAbsolute(url);
- if (isEncodeable(absolute)) {
- // W3c spec clearly said
- if (url.equalsIgnoreCase("")){
- url = absolute;
- }
- return (toEncoded(url, req.getSession().getId()));
- } else {
- return (url);
- }
-
- }
-
-
- /**
- * Encode the session identifier associated with this response
- * into the specified URL, if necessary.
- *
- * @param url URL to be encoded
- *
- * @deprecated As of Version 2.1 of the Java Servlet API, use
- * <code>encodeURL()</code> instead.
- */
- public String encodeUrl(String url) {
- return (encodeURL(url));
- }
-
-
- /**
- * Send an acknowledgment of a request.
- *
- * @exception IOException if an input/output error occurs
- */
- public void sendAcknowledgement()
- throws IOException {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- req.getConnector().acknowledge(this);
- }
-
-
- /**
- * Send an error response with the specified status and a
- * default message.
- *
- * @param status HTTP status code to send
- *
- * @exception IllegalStateException if this response has
- * already been committed
- * @exception IOException if an input/output error occurs
- */
- public void sendError(int status)
- throws IOException {
- sendError(status, null);
- }
-
-
- /**
- * Send an error response with the specified status and message.
- *
- * @param status HTTP status code to send
- * @param message Corresponding message to send
- *
- * @exception IllegalStateException if this response has
- * already been committed
- * @exception IOException if an input/output error occurs
- */
- public void sendError(int status, String message)
- throws IOException {
-
- if (isCommitted())
- throw new IllegalStateException
- ("isCommitted");
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- setError();
-
- getHttpResponse().setStatus(status);
- getHttpResponse().setMessage(message);
-
- // Clear any data content that has been buffered
- resetBuffer();
-
- // Cause the response to be finished (from the application perspective)
- String statusPage = req.getContext().findStatusPage(status);
-
- if (statusPage != null) {
- req.getContext().handleStatusPage(req, this, status, statusPage);
- } else {
- // Send a default message body.
- // TODO: maybe other mechanism to customize default.
- defaultStatusPage(status, message);
- }
- setSuspended(true);
- }
-
- /**
- * Default handler for status code != 200
- */
- void defaultStatusPage(int status, String message)
- throws IOException {
- setContentType("text/html");
- if (status > 400 && status < 600) {
- if (getOutputBuffer().getBytesWritten() == 0) {
- getOutputBuffer().write("<html><body><h1>Status: " +
- status + "</h1><h1>Message: " + message +
- "</h1></body></html>");
- getOutputBuffer().flush();
- }
- }
- }
-
-
-
- /**
- * Send a temporary redirect to the specified redirect location URL.
- *
- * @param location Location URL to redirect to
- *
- * @exception IllegalStateException if this response has
- * already been committed
- * @exception IOException if an input/output error occurs
- */
- public void sendRedirect(String location)
- throws IOException {
-
- if (isCommitted())
- throw new IllegalStateException
- ("isCommitted");
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- // Clear any data content that has been buffered
- resetBuffer();
-
- // Generate a temporary redirect to the specified location
- try {
- String absolute = toAbsolute(location);
- setStatus(SC_FOUND);
- setHeader("Location", absolute);
- } catch (IllegalArgumentException e) {
- setStatus(SC_NOT_FOUND);
- }
-
- // Cause the response to be finished (from the application perspective)
- setSuspended(true);
-
- }
-
-
- /**
- * Set the specified date header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Date value to be set
- */
- public void setDateHeader(String name, long value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included) {
- return;
- }
-
- if (format == null) {
- format = new SimpleDateFormat(HTTP_RESPONSE_DATE_HEADER,
- Locale.US);
- format.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
-
- setHeader(name, FastHttpDateFormat.formatDate(value, format));
-
- }
-
-
- /**
- * Set the specified header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Value to be set
- */
- public void setHeader(String name, String value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- getHttpResponse().setHeader(name, value);
-
- }
-
-
- /**
- * Set the specified integer header to the specified value.
- *
- * @param name Name of the header to set
- * @param value Integer value to be set
- */
- public void setIntHeader(String name, int value) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- setHeader(name, "" + value);
-
- }
-
-
- /**
- * Set the HTTP status to be returned with this response.
- *
- * @param status The new HTTP status
- */
- public void setStatus(int status) {
- setStatus(status, null);
- }
-
-
- /**
- * Set the HTTP status and message to be returned with this response.
- *
- * @param status The new HTTP status
- * @param message The associated text message
- *
- * @deprecated As of Version 2.1 of the Java Servlet API, this method
- * has been deprecated due to the ambiguous meaning of the message
- * parameter.
- */
- public void setStatus(int status, String message) {
-
- if (isCommitted())
- return;
-
- // Ignore any call from an included servlet
- if (included)
- return;
-
- getHttpResponse().setStatus(status);
- getHttpResponse().setMessage(message);
-
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Return <code>true</code> if the specified URL should be encoded with
- * a session identifier. This will be true if all of the following
- * conditions are met:
- * <ul>
- * <li>The request we are responding to asked for a valid session
- * <li>The requested session ID was not received via a cookie
- * <li>The specified URL points back to somewhere within the web
- * application that is responding to this request
- * </ul>
- *
- * @param location Absolute URL to be validated
- */
- protected boolean isEncodeable(final String location) {
-
- if (location == null)
- return (false);
-
- // Is this an intra-document reference?
- if (location.startsWith("#"))
- return (false);
-
- // Are we in a valid session that is not using cookies?
- final ServletRequestImpl hreq = req;
- final HttpSession session = hreq.getSession(false);
- if (session == null)
- return (false);
- if (hreq.isRequestedSessionIdFromCookie())
- return (false);
-
- // Is this a valid absolute URL?
- URL url = null;
- try {
- url = new URL(location);
- } catch (MalformedURLException e) {
- return (false);
- }
-
- // Does this URL match down to (and including) the context path?
- if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol()))
- return (false);
- if (!hreq.getServerName().equalsIgnoreCase(url.getHost()))
- return (false);
- int serverPort = hreq.getServerPort();
- if (serverPort == -1) {
- if ("https".equals(hreq.getScheme()))
- serverPort = 443;
- else
- serverPort = 80;
- }
- int urlPort = url.getPort();
- if (urlPort == -1) {
- if ("https".equals(url.getProtocol()))
- urlPort = 443;
- else
- urlPort = 80;
- }
- if (serverPort != urlPort)
- return (false);
-
- String contextPath = req.getContext().getContextPath();
- if (contextPath != null) {
- String file = url.getFile();
- if ((file == null) || !file.startsWith(contextPath))
- return (false);
- if( file.indexOf(";jsessionid=" + session.getId()) >= 0 )
- return (false);
- }
-
- // This URL belongs to our web application, so it is encodeable
- return (true);
-
- }
-
-
- /**
- * Convert (if necessary) and return the absolute URL that represents the
- * resource referenced by this possibly relative URL. If this URL is
- * already absolute, return it unchanged.
- *
- * @param location URL to be (possibly) converted and then returned
- *
- * @exception IllegalArgumentException if a MalformedURLException is
- * thrown when converting the relative URL to an absolute one
- */
- private String toAbsolute(String location) {
-
- if (location == null)
- return (location);
-
- boolean leadingSlash = location.startsWith("/");
-
- if (leadingSlash || !hasScheme(location)) {
-
- redirectURLCC.recycle();
-
- String scheme = req.getScheme();
- String name = req.getServerName();
- int port = req.getServerPort();
-
- try {
- redirectURLCC.append(scheme, 0, scheme.length());
- redirectURLCC.append("://", 0, 3);
- redirectURLCC.append(name, 0, name.length());
- if ((scheme.equals("http") && port != 80)
- || (scheme.equals("https") && port != 443)) {
- redirectURLCC.append(':');
- String portS = port + "";
- redirectURLCC.append(portS, 0, portS.length());
- }
- if (!leadingSlash) {
- String relativePath = req.getDecodedRequestURI();
- int pos = relativePath.lastIndexOf('/');
- relativePath = relativePath.substring(0, pos);
-
- String encodedURI = null;
- encodedURI = urlEncoder.encodeURL(relativePath);
- redirectURLCC.append(encodedURI, 0, encodedURI.length());
- redirectURLCC.append('/');
- }
- redirectURLCC.append(location, 0, location.length());
- } catch (IOException e) {
- IllegalArgumentException iae =
- new IllegalArgumentException(location);
- iae.initCause(e);
- throw iae;
- }
-
- return redirectURLCC.toString();
-
- } else {
-
- return (location);
-
- }
-
- }
-
-
- /**
- * Determine if a URI string has a <code>scheme</code> component.
- */
- private boolean hasScheme(String uri) {
- int len = uri.length();
- for(int i=0; i < len ; i++) {
- char c = uri.charAt(i);
- if(c == ':') {
- return i > 0;
- } else if(!isSchemeChar(c)) {
- return false;
- }
- }
- return false;
- }
-
- /**
- * Determine if the character is allowed in the scheme of a URI.
- * See RFC 2396, Section 3.1
- */
- private static boolean isSchemeChar(char c) {
- return Character.isLetterOrDigit(c) ||
- c == '+' || c == '-' || c == '.';
- }
-
-
- /**
- * Return the specified URL with the specified session identifier
- * suitably encoded.
- *
- * @param url URL to be encoded with the session id
- * @param sessionId Session id to be included in the encoded URL
- */
- protected String toEncoded(String url, String sessionId) {
-
- if ((url == null) || (sessionId == null))
- return (url);
-
- String path = url;
- String query = "";
- String anchor = "";
- int question = url.indexOf('?');
- if (question >= 0) {
- path = url.substring(0, question);
- query = url.substring(question);
- }
- int pound = path.indexOf('#');
- if (pound >= 0) {
- anchor = path.substring(pound);
- path = path.substring(0, pound);
- }
- StringBuffer sb = new StringBuffer(path);
- if( sb.length() > 0 ) { // jsessionid can't be first.
- sb.append(";jsessionid=");
- sb.append(sessionId);
- }
- sb.append(anchor);
- sb.append(query);
- return (sb.toString());
-
- }
-
-
- public int getBytesWritten() {
- return outputBuffer.getBytesWritten();
- }
-
- public BodyWriter getOutputBuffer() {
- return outputBuffer;
- }
-
- public void setWriter(BodyWriter ob) {
- outputBuffer = ob;
- outputStream = new ServletOutputStreamImpl(outputBuffer);
- }
-
- public CharSequence getResponseHeader(String name) {
- MessageBytes v = getHttpResponse().getMimeHeaders().getValue(name);
- return (v == null) ? null : v.toString();
- }
-
-
- public HttpResponse getHttpResponse() {
- return resB;
- }
-
-
- public void setHttpResponse(HttpResponse resB, BodyWriter ob) {
- this.resB = resB;
- setWriter(ob);
- }
-
-
-
- @Override
- public Collection<String> getHeaders(String name) {
- return null;
- }
-
-
-}
-
+++ /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.coyote.servlet;
-
-
-import java.io.IOException;
-import java.util.Locale;
-
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-
-/**
- * Wrapper around the response object received as parameter to
- * RequestDispatcher.include().
- *
- * @author Costin Manolache
- */
-public class ServletResponseIncludeWrapper extends HttpServletResponseWrapper {
- public ServletResponseIncludeWrapper(ServletResponse current) {
- super((HttpServletResponse) current);
- }
-
- // Not overriden:
- /*
- public boolean containsHeader(String name)
- public String encodeRedirectUrl(String url)
- public String encodeRedirectURL(String url)
- public String encodeUrl(String url)
- public String encodeURL(String url)
- public void flushBuffer() throws IOException
- public int getBufferSize()
- public String getCharacterEncoding()
- public String getContentType()
- public Locale getLocale()
- public ServletOutputStream getOutputStream() throws IOException
- public ServletResponse getResponse()
- public PrintWriter getWriter() throws IOException
- public boolean isCommitted()
- public void resetBuffer()
- public void setCharacterEncoding(String charset)
- public void setResponse(ServletResponse response)
- */
-
- public void reset() {
- if (getResponse().isCommitted())
- getResponse().reset();
- else
- throw new IllegalStateException();
- }
-
- public void setContentLength(int len) {
- }
-
- public void setContentType(String type) {
- }
-
- public void setLocale(Locale loc) {
- }
-
- public void setBufferSize(int size) {
- }
-
- public void addCookie(Cookie cookie) {
- }
-
- public void addDateHeader(String name, long value) {
- }
-
- public void addHeader(String name, String value) {
- }
-
- public void addIntHeader(String name, int value) {
- }
-
- public void sendError(int sc) throws IOException {
- }
-
- public void sendError(int sc, String msg) throws IOException {
- }
-
- public void sendRedirect(String location) throws IOException {
- }
-
- public void setDateHeader(String name, long value) {
- }
-
- public void setHeader(String name, String value) {
- }
-
- public void setIntHeader(String name, int value) {
- }
-
- public void setStatus(int sc) {
- }
-
- public void setStatus(int sc, String msg) {
- }
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
-
-/**
- * Coyote implementation of the servlet writer.
- *
- * @author Remy Maucherat
- */
-public class ServletWriterImpl
- extends PrintWriter {
-
-
- // -------------------------------------------------------------- Constants
-
-
- private static final char[] LINE_SEP = { '\r', '\n' };
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- protected Writer ob;
- protected boolean error = false;
-
-
- // ----------------------------------------------------------- Constructors
-
-
- public ServletWriterImpl(Writer ob) {
- super(ob);
- this.ob = ob;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Prevent cloning the facade.
- */
- protected Object clone()
- throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
-
-
- // -------------------------------------------------------- Package Methods
-
-
- /**
- * Clear facade.
- */
- void clear() {
- ob = null;
- }
-
-
- /**
- * Recycle.
- */
- void recycle() {
- error = false;
- }
-
-
- // --------------------------------------------------------- Writer Methods
-
-
- public void flush() {
-
- if (error)
- return;
-
- try {
- ob.flush();
- } catch (IOException e) {
- error = true;
- }
-
- }
-
-
- public void close() {
-
- // We don't close the PrintWriter - super() is not called,
- // so the stream can be reused. We close ob.
- try {
- ob.close();
- } catch (IOException ex ) {
- ;
- }
- error = false;
-
- }
-
-
- public boolean checkError() {
- flush();
- return error;
- }
-
-
- public void write(int c) {
-
- if (error)
- return;
-
- try {
- ob.write(c);
- } catch (IOException e) {
- error = true;
- }
-
- }
-
-
- public void write(char buf[], int off, int len) {
-
- if (error)
- return;
-
- try {
- ob.write(buf, off, len);
- } catch (IOException e) {
- error = true;
- }
-
- }
-
-
- public void write(char buf[]) {
- write(buf, 0, buf.length);
- }
-
-
- public void write(String s, int off, int len) {
-
- if (error)
- return;
-
- try {
- ob.write(s, off, len);
- } catch (IOException e) {
- error = true;
- }
-
- }
-
-
- public void write(String s) {
- write(s, 0, s.length());
- }
-
-
- // ---------------------------------------------------- PrintWriter Methods
-
-
- public void print(boolean b) {
- if (b) {
- write("true");
- } else {
- write("false");
- }
- }
-
-
- public void print(char c) {
- write(c);
- }
-
-
- public void print(int i) {
- write(String.valueOf(i));
- }
-
-
- public void print(long l) {
- write(String.valueOf(l));
- }
-
-
- public void print(float f) {
- write(String.valueOf(f));
- }
-
-
- public void print(double d) {
- write(String.valueOf(d));
- }
-
-
- public void print(char s[]) {
- write(s);
- }
-
-
- public void print(String s) {
- if (s == null) {
- s = "null";
- }
- write(s);
- }
-
-
- public void print(Object obj) {
- write(String.valueOf(obj));
- }
-
-
- public void println() {
- write(LINE_SEP);
- }
-
-
- public void println(boolean b) {
- print(b);
- println();
- }
-
-
- public void println(char c) {
- print(c);
- println();
- }
-
-
- public void println(int i) {
- print(i);
- println();
- }
-
-
- public void println(long l) {
- print(l);
- println();
- }
-
-
- public void println(float f) {
- print(f);
- println();
- }
-
-
- public void println(double d) {
- print(d);
- println();
- }
-
-
- public void println(char c[]) {
- print(c);
- println();
- }
-
-
- public void println(String s) {
- print(s);
- println();
- }
-
-
- public void println(Object o) {
- print(o);
- println();
- }
-
-
-}
+++ /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.coyote.servlet;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.Filter;
-import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.UnavailableException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.tomcat.integration.ObjectManager;
-import org.apache.tomcat.integration.simple.SimpleObjectManager;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.buf.UriNormalizer;
-import org.apache.tomcat.util.http.mapper.MappingData;
-
-/**
- * Simpler, lower footprint serlvet engine.
- *
- * Uses ObjectManager to integate with an embedding app
- * - the object names it uses:
- *
- * Internal objects created by Tomcat and registered for management
- * and injection:
- * - Servlet:CONTEXT_PATH:SERVLETNAME - a ServletWrapper
- * - ServletContext:CONTEXT_PATH
- * - ProtocolHandler:ep-PORT - coyote ProtocolHandler
- * - CoyoteServer:CoyoteServer-PORT
- * - CoyoteAdapter:PATH - for the coyote used Adapter
- * - TomcatLite - this object.
- * - Connector - the connector object
- *
- * Plugins to be constructed by framework ( defaults set in initDefaults ):
- * - UserSessionManager
- * - UserTemplateClassMapper
- * - ContextPreinitListener
- * - Connector
- * - WebappServletMapper
- * - WebappFilterMapper
- * - default-servlet
- * - jspwildcard-servlet
- * - Foo-servlet - servlet named Foo
- *
- *
- * @author Costin Manolache
- */
-public class TomcatLite implements Runnable {
-
- private String serverDirName;
- private File workDir;
-
- // all contexts - hostMapper knows about hostnames and how they are mapped.
- // this shouldn't be needed if we want to delegate ctx management
- private ArrayList<ServletContextImpl> contexts = new ArrayList();
-
- URLClassLoader contextParentLoader;
-
- // Discovered or default Host/Context mapper
- Filter hostMapper;
-
- // Servlets to preload in each context, configurable from CLI or API
- Map<String,String> preloadServlets = new HashMap();
- Map<String,String> preloadMappings = new HashMap();
-
- Map<String,String> ctxDefaultInitParam = new HashMap();
-
- Connector connector;
-
- ObjectManager om;
-
- static String SERVLETS_PACKAGE = "org.apache.tomcat.servlets";
-
-
- protected boolean daemon = false;
-
- public TomcatLite() {
- }
-
- public TomcatLite(ObjectManager om) {
- this.setObjectManager(om);
- }
-
- // --------------- start/stop ---------------
-
- public static ObjectManager defaultObjectManager() {
- SimpleObjectManager cfg = new SimpleObjectManager();
- cfg.loadResource("org/apache/coyote/servlet/config.properties");
- return cfg;
- }
- /**
- * Return the object manager associated with this tomcat.
- * If none set, create a minimal one with the default
- * values.
- */
- public ObjectManager getObjectManager() {
- if (om == null) {
- om = defaultObjectManager();
- }
- return om;
- }
-
- public void setObjectManager(ObjectManager om) {
- this.om = om;
- }
-
- public List/*<ServletContextImpl>*/ getWebapps() {
- return contexts;
- }
-
- public URLClassLoader getContextParentLoader() {
- if (contextParentLoader == null) {
-
- ClassLoader parent = this.getClass().getClassLoader();
- contextParentLoader = new URLClassLoader(new URL[] {},
- parent);
-
- /*if (engineRepo == null) {
- engineRepo = new Repository();
- engineRepo.setParentClassLoader(parent);
- }
-
- contextParentLoader =
- engineRepo.getClassLoader();
- */
- }
- return contextParentLoader;
- }
-
- public void start() throws IOException {
- long t0 = System.currentTimeMillis();
-
- // start all contexts
- // init all contexts
- Iterator i1 = contexts.iterator();
- while (i1.hasNext()) {
- ServletContextImpl ctx = (ServletContextImpl) i1.next();
- try {
- ctx.start();
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- long t1 = System.currentTimeMillis();
- System.err.println("Engine.start() " + (t1-t0));
- }
-
-
- /**
- * Add a context - used for IntrospectionUtils.
- *
- * ContextPath:ContextBaseDir
- */
- public void setContext(String c) throws ServletException {
- String[] pathDir = c.split(":", 2);
- addServletContext("", pathDir[1], pathDir[0]);
- }
-
- public void setServletContexts(List<ServletContext> c) throws ServletException {
- for (ServletContext ctx: c) {
- addServletContext((ServletContextImpl) ctx);
- }
- }
-
- public void setPreload(String servletNameClass) {
- String[] nv = servletNameClass.split(":");
- preloadServlets.put(nv[0], nv[1]);
- }
-
- public void addPreload(String servletName, String servletClassName) {
- preloadServlets.put(servletName, servletClassName);
- }
-
- public void setDefaultInitParam(String nameValue) {
- String[] nv = nameValue.split(":");
- ctxDefaultInitParam.put(nv[0], nv[1]);
- }
-
- public void addDefaultInitParam(String name, String value) {
- ctxDefaultInitParam.put(name, value);
- }
-
- public void setPreloadMappings(String servletPath) {
- String[] nv = servletPath.split(":");
- preloadMappings.put(nv[0], nv[1]);
- }
-
- public void addPreloadMapping(String servletName, String path) {
- preloadMappings.put(servletName, path);
- }
-
- public void stop() {
- Iterator i1 = contexts.iterator();
- while (i1.hasNext()) {
- ServletContextImpl ctx = (ServletContextImpl) i1.next();
- try {
- ctx.destroy();
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- try {
- stopConnector();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- // -------------- Context add/remove --------------
-
- public static String[] DEFAULT_WELCOME = { "index.html" };
-
- public void addServletContext(ServletContextImpl ctx) throws ServletException {
- ctx.setTomcat(this);
- if (hostMapper == null) {
- hostMapper = new WebappContextMapper();
- }
-
- ((WebappContextMapper) hostMapper).addHost(ctx.getHostname(), null);
- ((WebappContextMapper) hostMapper).addContext(ctx.getHostname(),
- ctx);
-
- contexts.add(ctx);
-
- getObjectManager().bind("ServletContext:" + ctx.getContextPath(),
- ctx);
-
- }
-
- /**
- * Add a context.
- *
- * web.xml will be read as part of init, and the initialization will be
- * part of start or lazy.
- *
- * @param hostname - ""
- * if default host, or string to be matched with Host header
- * @param basePath = directory where the webapp is installed
- * @param path -
- * context path, "/" for root, "/examples", etc
- * @return a servlet context
- * @throws ServletException
- */
- public ServletContext addServletContext(String hostname,
- String basePath,
- String path)
- throws ServletException
- {
- ServletContextImpl ctx = new ServletContextImpl();
- ctx.setContextPath(path);
- ctx.setBasePath(basePath);
- addServletContext(ctx);
- return ctx;
- }
-
- public void removeServletContext(ServletContext sctx)
- throws ServletException
- {
- ServletContextImpl ctx = (ServletContextImpl) sctx;
- // TODO: destroy all servlets and filters
- // TODO: clean up any other reference to the context or its loader
- notifyRemove(ctx);
- }
-
-
- /**
- * Required for ServletContext.getContext(uri);
- * @throws ServletException
- * @throws IOException
- */
- public ServletContextImpl getContext(ServletContextImpl impl, String uri)
- throws IOException, ServletException {
- // Create a request - needs to be simplified
- ServletRequestImpl req = createMessage(impl, impl.contextPath, uri);
- hostMapper.doFilter(req, null, null);
- return req.getContext();
- }
-
- public ServletResponseImpl service(ServletRequestImpl req) throws IOException, Exception {
- ServletResponseImpl res = req.getResponse();
- service(req, res);
- endRequest(req, res);
- return res;
- }
-
- public void service(ServletRequestImpl req, ServletResponseImpl res)
- throws Exception, IOException {
- // parse the session id from URI
- req.parseSessionId();
-
- try {
- UriNormalizer.decodeRequest(req.getHttpRequest().decodedURI(),
- req.getHttpRequest().requestURI(),
- req.getHttpRequest().getURLDecoder());
- } catch(IOException ioe) {
- res.setStatus(400);
- return;
- }
-
- MappingData mapRes = req.getMappingData();
- try {
- // TODO: make hostMapper configurable, implement interface,
- // simple to set on ROOT context
- hostMapper.doFilter(req, null, null);
-
-
- ServletContextImpl ctx = (ServletContextImpl)mapRes.context;
- if( ctx == null ) {
- // TODO: 404
- res.setStatus(404);
- return;
- }
- req.setContext(ctx);
-
- // bind class loader
- Thread.currentThread().setContextClassLoader(ctx.getClassLoader());
-
- WebappServletMapper mapper = ctx.getMapper();
- mapper.map(req.getHttpRequest().decodedURI(), mapRes);
-
- // Possible redirect
- MessageBytes redirectPathMB = mapRes.redirectPath;
- if (!redirectPathMB.isNull()) {
- String redirectPath = res.urlEncoder.encodeURL(redirectPathMB.toString());
- String query = req.getQueryString();
- if (req.isRequestedSessionIdFromURL()) {
- // This is not optimal, but as this is not very common, it
- // shouldn't matter
- redirectPath = redirectPath + ";" + ServletRequestImpl.SESSION_PARAMETER_NAME + "="
- + req.getRequestedSessionId();
- }
- if (query != null) {
- // This is not optimal, but as this is not very common, it
- // shouldn't matter
- redirectPath = redirectPath + "?" + query;
- }
- res.sendRedirect(redirectPath);
- return;
- }
-
- req.parseSessionCookiesId();
-
- ServletConfigImpl h=(ServletConfigImpl)mapRes.wrapper;
- if (h != null) {
- req.setWrapper((ServletConfigImpl)mapRes.wrapper);
- serviceServlet(ctx, req, res, h, mapRes );
- // send the response...
-
- //res.flushBuffer();
-
- // Recycle the wrapper request and response
- //req.recycle();
- //res.recycle();
- }
- } finally {
- if(mapRes != null )
- mapRes.recycle();
- }
- }
-
- /** Coyote / mapper adapter. Result of the mapper.
- *
- * This replaces the valve chain, the path is:
- * 1. coyote calls mapper -> result Adapter
- * 2. service is called. Additional filters are set on the wrapper.
- * @param mapRes
- */
- private void serviceServlet(ServletContextImpl ctx,
- ServletRequestImpl req,
- ServletResponseImpl res,
- ServletConfigImpl servletConfig,
- MappingData mapRes)
- throws IOException {
- Servlet servlet = null;
- try {
- if (servletConfig.isUnavailable()) {
- handleUnavailable(res, servletConfig);
- return;
- }
- try {
- servlet = servletConfig.allocate();
- } catch(ServletException ex) {
- handleUnavailable(res, servletConfig);
- }
- WebappFilterMapper filterMap = ctx.getFilterMapper();
- FilterChainImpl chain =
- filterMap.createFilterChain(req, servletConfig, servlet);
-
- try {
- if (chain == null) {
- if (servlet != null) {
- servlet.service(req, res);
- } else {
- System.err.println("No servlet " + req.getRequestURI());
- res.sendError(404);
- }
- } else {
- chain.doFilter(req, res);
- }
- } catch(UnavailableException ex) {
- servletConfig.unavailable(ex);
- handleUnavailable(res, servletConfig);
- return;
- }
-
- // servlet completed without exception. Check status
- int status = res.getStatus();
- if (status != 200 && !res.isCommitted()) {
- String statusPage = ctx.findStatusPage(status);
-
- if (statusPage != null) {
- ctx.handleStatusPage(req, res, status, statusPage);
- } else {
- // Send a default message body.
- // TODO: maybe other mechanism to customize default.
- res.defaultStatusPage(status, res.getMessage());
- }
- }
- } catch (Throwable t) {
- ctx.handleError(req, res, t);
- } finally {
- if (servlet != null) {
- servletConfig.deallocate(servlet);
- }
- }
- }
-
- private void handleUnavailable(ServletResponseImpl response,
- ServletConfigImpl servletConfig)
- throws IOException {
- long available = servletConfig.getAvailable();
- if ((available > 0L) && (available < Long.MAX_VALUE))
- response.setDateHeader("Retry-After", available);
- // TODO: handle via error pages !
- response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
- "Service unavailable");
- }
-
-
- // ------------ Notifications for JMX ----------------
-
- void notifyAdd(Object o) {
- }
-
- void notifyRemove(Object o) {
- }
-
- public void setServerDir(String dir) {
- this.serverDirName = dir;
- }
-
- public File getWork() {
- if (workDir == null) {
- if (serverDirName == null) {
- serverDirName = "./";
- }
- File rootDirFile = new File(serverDirName);
- workDir = new File(rootDirFile, "tomcat-work");
- if (workDir.exists()) {
- workDir.mkdirs();
- }
- }
- return workDir;
- }
-
- /**
- * Init
- *
- * @throws ServletException
- * @throws IOException
- */
- public void init() throws ServletException, IOException {
- getObjectManager().bind("TomcatLite", this);
- if (contexts.size() == 0) {
- setContext("/:./webapps/ROOT");
- }
- getConnector().setObjectManager(getObjectManager());
- Iterator i1 = contexts.iterator();
- while (i1.hasNext()) {
- ServletContextImpl ctx = (ServletContextImpl) i1.next();
- try {
- ctx.init();
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- }
-
- /**
- * Initialize an webapp and add it to the server.
- * - load web.xml
- * - call
- *
- * @param rootDir
- * @param path
- * @param deployServlet
- */
- public void init(String rootDir, String path)
- throws ServletException, IOException {
-
- long t0 = System.currentTimeMillis();
-
- ServletContextImpl ctx =
- (ServletContextImpl)addServletContext(null,
- rootDir,
- path);
- ctx.init();
-
- long t1 = System.currentTimeMillis();
-
- // At this point all config is loaded. Contexts are not yet init()
- // - this will happen on start.
- System.err.println("Context.init() " + path + " " + (t1-t0));
- }
-
- /**
- * Get an empty request/response pair ( response available
- * as getResponse() ). Optional set input and output buffers.
- *
- * This can be used for a connector-less interface to tomcat lite.
- *
- * TODO: make it independent of coyote !
- */
-
- public ServletRequestImpl createMessage() {
- ServletRequestImpl req = new ServletRequestImpl();
- ServletResponseImpl res = req.getResponse();
-
- getConnector().initRequest(req, res);
-
- req.getHttpRequest().method().setString("GET");
- req.getHttpRequest().protocol().setString("HTTP/1.1");
-
- return req;
- }
-
- /**
- * Used internally for mapping.
- */
- private ServletRequestImpl createMessage(ServletContextImpl deployCtx,
- String ctxPath,
- String reqPath) {
- ServletRequestImpl req = createMessage();
- req.setContextPath(ctxPath);
- req.setContext(deployCtx);
- req.setRequestURI(ctxPath + reqPath);
- return req;
- }
-
-
- /**
- * Set a global filter that will be used for context mapping.
- *
- * The filter will get a request, with requestUri and hostname set.
- *
- * It needs to compute the context path and set it as an attribute.
- *
- * Advanced features may include on-demand loading of webapps, large scale
- * virtual hosting, etc.
- */
- public void setContextMapper(Filter hostMapper2) {
- this.hostMapper = hostMapper2;
- }
-
- public void endRequest(ServletRequestImpl req,
- ServletResponseImpl res) throws IOException {
- res.outputBuffer.flush();
- req.getConnector().finishResponse(res);
- }
-
- public Connector getConnector() {
- if (connector == null) {
- connector = (Connector) getObjectManager().get(Connector.class);
- setConnector(connector);
- }
- return connector;
- }
-
- public void setConnector(Connector c) {
- connector = c;
- connector.setTomcatLite(this);
- getObjectManager().bind("Connector", connector);
- }
-
-
- public void setDaemon(boolean d) {
- getConnector();
- if (connector != null) {
- connector.setDaemon(d);
- }
- }
-
- public void startConnector() throws IOException {
- getConnector();
- if (connector != null) {
- connector.start();
- }
- }
-
- public void stopConnector() throws Exception {
- if (connector != null) {
- connector.stop();
- }
- }
-
- public void run() {
- try {
- execute();
- } catch (ServletException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public void execute() throws ServletException, IOException {
- init();
- start();
- startConnector();
- }
-}
+++ /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.coyote.servlet;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.mapper.MappingData;
-
-/**
- * This handles host and context mapping.
- *
- * The default implementation for tomcat lite is very limitted -
- * no support for virtual hosts, no support for contexts deeper than
- * 1 level. The intention is to override this with more advanced mappers.
- *
- * With 'ConfigurableHosts' interface it is possible for a smart
- * mapper to load/unload virtual hosts at runtime, maybe from a
- * database. It should be possible to use databases to store huge number
- * of hosts or webapps.
- *
- */
-public class WebappContextMapper implements Filter {
-
- ServletContext rootContext;
- Map<String, ServletContext> contexts = new HashMap();
-
- public WebappContextMapper() {
- }
-
- public void addHost(String name, String[] aliases) {
- }
-
- /**
- * Add a new Context to an existing Host.
- *
- * @param hostName Virtual host name this context belongs to
- * @param contextPath Context path
- * @param context Context object
- * @param welcomeResources Welcome files defined for this context
- * @param resources Static resources of the context
- */
- public void addContext(String hostName,
- ServletContext context)
- throws ServletException
- {
- String path = context.getContextPath();
- if (path.lastIndexOf("/") > 0) {
- throw new ServletException("Base context mapper supports only one level");
- }
- if ("/".equals(path)) {
- rootContext = context;
- }
- MessageBytes mb = MessageBytes.newInstance();
- mb.setChars(path.toCharArray(), 0, path.length());
- contexts.put(mb.toString(), context);
- }
-
-
- /**
- * Remove a context from an existing host.
- *
- * @param hostName Virtual host name this context belongs to
- * @param path Context path
- */
- public void removeContext(String hostName, String path)
- throws ServletException {
- if ("/".equals(path)) {
- rootContext = null;
- }
- contexts.remove(path);
- }
-
- /**
- * Map the specified URI.
- */
- private void mapContext(ServletRequestImpl req)
- throws IOException, ServletException {
- MessageBytes uriMB = req.getDecodedRequestURIMB();
- MappingData mappingData = req.getMappingData();
- uriMB.toChars();
- CharChunk uri = uriMB.getCharChunk();
-
-
- if (uri.length() < 2 || contexts.size() == 0) {
- mappingData.context = rootContext;
- if (rootContext != null) {
- mappingData.contextPath.setString(rootContext.getContextPath());
- }
- return;
- }
-
- int nextSlash = uri.indexOf('/', 1);
- if (nextSlash == -1) {
- nextSlash = uri.length();
- }
- mappingData.contextPath.setChars(uri.getChars(), 0, nextSlash);
- ServletContext servletContext = contexts.get(mappingData.contextPath.toString());
-
- if (servletContext != null) {
- mappingData.context = servletContext;
- } else {
- mappingData.context = rootContext;
- if (rootContext != null) {
- mappingData.contextPath.setString(rootContext.getContextPath());
- }
- }
- }
-
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
- public void doFilter(ServletRequest request,
- ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
- ServletRequestImpl req = (ServletRequestImpl)request;
- mapContext(req);
- }
-
- public void destroy() {
- }
-}
\ 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.coyote.servlet;
-
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.tomcat.servlets.util.RequestUtil;
-
-/**
- * First filter after the context and servlet are mapped. It will add
- * web.xml-defined filters.
- *
- * costin: This is another mapping - done in RequestDispatcher or initial
- * mapping.
- * Also: StandardHostValve - sets attribute for error pages,
- * StandardWrapperValve - mapping per invocation
- *
- * @author Greg Murray
- * @author Remy Maucherat
- */
-public class WebappFilterMapper implements Filter {
-
-
- // -------------------------------------------------------------- Constants
-
-
- public static final int ERROR = 1;
- public static final Integer ERROR_INTEGER = new Integer(ERROR);
- public static final int FORWARD = 2;
- public static final Integer FORWARD_INTEGER = new Integer(FORWARD);
- public static final int INCLUDE = 4;
- public static final Integer INCLUDE_INTEGER = new Integer(INCLUDE);
- public static final int REQUEST = 8;
- public static final Integer REQUEST_INTEGER = new Integer(REQUEST);
-
- /**
- * Request dispatcher state.
- */
- public static final String DISPATCHER_TYPE_ATTR =
- "org.apache.catalina.core.DISPATCHER_TYPE";
-
- /**
- * Request dispatcher path.
- */
- public static final String DISPATCHER_REQUEST_PATH_ATTR =
- "org.apache.catalina.core.DISPATCHER_REQUEST_PATH";
-
-
- // ----------------------------------------------------------- Constructors
- ServletContextImpl servletContext;
-
- public WebappFilterMapper() {
- }
-
- public WebappFilterMapper(ServletContextImpl impl) {
- servletContext = impl;
- }
-
- public void setServletContext(ServletContextImpl sc) {
- servletContext = sc;
- }
-
- // --------------------------------------------------------- Public Methods
-
- ArrayList filterMaps = new ArrayList();
-
- public void addMapping(String filterName,
- String url,
- String servletName,
- String type[], boolean isMatchAfter) {
- FilterMap map = new FilterMap();
- map.setURLPattern(url);
- map.setFilterName(filterName);
- map.setServletName(servletName);
- if (isMatchAfter) {
- filterMaps.add(map);
- } else {
- filterMaps.add(0, map);
- }
- }
-
- /**
- * Construct and return a FilterChain implementation that will wrap the
- * execution of the specified servlet instance. If we should not execute
- * a filter chain at all, return <code>null</code>.
- *
- * @param request The servlet request we are processing
- * @param servlet The servlet instance to be wrapped
- */
- public FilterChainImpl createFilterChain(ServletRequest request,
- ServletConfigImpl wrapper,
- Servlet servlet) {
-
- // If there is no servlet to execute, return null
- if (servlet == null)
- return (null);
-
- // get the dispatcher type
- int dispatcher = -1;
- if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
- Integer dispatcherInt =
- (Integer) request.getAttribute(DISPATCHER_TYPE_ATTR);
- dispatcher = dispatcherInt.intValue();
- }
- String requestPath = null;
- Object attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR);
-
- if (attribute != null){
- requestPath = attribute.toString();
- }
-
- HttpServletRequest hreq = null;
- if (request instanceof HttpServletRequest)
- hreq = (HttpServletRequest)request;
-
- // Create and initialize a filter chain object
- FilterChainImpl filterChain = null;
- if ((request instanceof ServletRequestImpl)) {
- ServletRequestImpl req = (ServletRequestImpl) request;
- filterChain = (FilterChainImpl) req.getFilterChain();
- filterChain.release();
- } else {
- // Security: Do not recycle
- filterChain = new FilterChainImpl();
- }
-
- filterChain.setServlet(wrapper, servlet);
-
- // If there are no filter mappings, we are done
- if ((filterMaps.size() == 0))
- return (filterChain);
-
- // Acquire the information we will need to match filter mappings
- String servletName = wrapper.getServletName();
-
- int n = 0;
-
- // TODO(costin): optimize: separate in 2 lists, one for url-mapped, one for
- // servlet-name. Maybe even separate list for dispatcher and
- // non-dispatcher
-
- // TODO(costin): optimize: set the FilterConfig in the FilterMap, to
- // avoid second hash lookup
-
- // Add the relevant path-mapped filters to this filter chain
- for (int i = 0; i < filterMaps.size(); i++) {
- FilterMap filterMap = (FilterMap)filterMaps.get(i);
- if (!matchDispatcher(filterMap ,dispatcher)) {
- continue;
- }
- if (!matchFiltersURL(filterMap, requestPath))
- continue;
- FilterConfigImpl filterConfig =
- servletContext.getFilter(filterMap.getFilterName());
- if (filterConfig == null) {
- // FIXME - log configuration problem
- continue;
- }
- filterChain.addFilter(filterConfig);
- n++;
- }
-
- // Add filters that match on servlet name second
- for (int i = 0; i < filterMaps.size(); i++) {
- FilterMap filterMap = (FilterMap)filterMaps.get(i);
- if (!matchDispatcher(filterMap ,dispatcher)) {
- continue;
- }
- if (!matchFiltersServlet(filterMap, servletName))
- continue;
- FilterConfigImpl filterConfig =
- servletContext.getFilter(filterMap.getFilterName());
- if (filterConfig == null) {
- ; // FIXME - log configuration problem
- continue;
- }
- filterChain.addFilter(filterConfig);
- n++;
- }
-
- // Return the completed filter chain
- return (filterChain);
-
- }
-
-
- // -------------------------------------------------------- Private Methods
-
-
- /**
- * Return <code>true</code> if the context-relative request path
- * matches the requirements of the specified filter mapping;
- * otherwise, return <code>null</code>.
- *
- * @param filterMap Filter mapping being checked
- * @param requestPath Context-relative request path of this request
- */
- private boolean matchFiltersURL(FilterMap filterMap, String requestPath) {
-
- if (requestPath == null)
- return (false);
-
- // Match on context relative request path
- String testPath = filterMap.getURLPattern();
- if (testPath == null)
- return (false);
-
- // Case 1 - Exact Match
- if (testPath.equals(requestPath))
- return (true);
-
- // Case 2 - Path Match ("/.../*")
- if (testPath.equals("/*"))
- return (true);
- if (testPath.endsWith("/*")) {
- if (testPath.regionMatches(0, requestPath, 0,
- testPath.length() - 2)) {
- if (requestPath.length() == (testPath.length() - 2)) {
- return (true);
- } else if ('/' == requestPath.charAt(testPath.length() - 2)) {
- return (true);
- }
- }
- return (false);
- }
-
- // Case 3 - Extension Match
- if (testPath.startsWith("*.")) {
- int slash = requestPath.lastIndexOf('/');
- int period = requestPath.lastIndexOf('.');
- if ((slash >= 0) && (period > slash)
- && (period != requestPath.length() - 1)
- && ((requestPath.length() - period)
- == (testPath.length() - 1))) {
- return (testPath.regionMatches(2, requestPath, period + 1,
- testPath.length() - 2));
- }
- }
-
- // Case 4 - "Default" Match
- return (false); // NOTE - Not relevant for selecting filters
-
- }
-
-
- /**
- * Return <code>true</code> if the specified servlet name matches
- * the requirements of the specified filter mapping; otherwise
- * return <code>false</code>.
- *
- * @param filterMap Filter mapping being checked
- * @param servletName Servlet name being checked
- */
- private boolean matchFiltersServlet(FilterMap filterMap,
- String servletName) {
-
- if (servletName == null) {
- return (false);
- } else {
- if (servletName.equals(filterMap.getServletName())) {
- return (true);
- } else {
- return false;
- }
- }
-
- }
-
-
- /**
- * Convienience method which returns true if the dispatcher type
- * matches the dispatcher types specified in the FilterMap
- */
- private boolean matchDispatcher(FilterMap filterMap, int dispatcher) {
- switch (dispatcher) {
- case FORWARD : {
- if (filterMap.getDispatcherMapping() == FilterMap.FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) {
- return true;
- }
- break;
- }
- case INCLUDE : {
- if (filterMap.getDispatcherMapping() == FilterMap.INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) {
- return true;
- }
- break;
- }
- case REQUEST : {
- if (filterMap.getDispatcherMapping() == FilterMap.REQUEST ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE) {
- return true;
- }
- break;
- }
- case ERROR : {
- if (filterMap.getDispatcherMapping() == FilterMap.ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
- filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE) {
- return true;
- }
- break;
- }
- }
- return false;
- }
-
-
- // -------------------- Map elements -----------------------
-
- public static class FilterMap implements Serializable {
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * The name of this filter to be executed when this mapping matches
- * a particular request.
- */
-
- public static final int ERROR = 1;
- public static final int FORWARD = 2;
- public static final int FORWARD_ERROR =3;
- public static final int INCLUDE = 4;
- public static final int INCLUDE_ERROR = 5;
- public static final int INCLUDE_ERROR_FORWARD =6;
- public static final int INCLUDE_FORWARD = 7;
- public static final int REQUEST = 8;
- public static final int REQUEST_ERROR = 9;
- public static final int REQUEST_ERROR_FORWARD = 10;
- public static final int REQUEST_ERROR_FORWARD_INCLUDE = 11;
- public static final int REQUEST_ERROR_INCLUDE = 12;
- public static final int REQUEST_FORWARD = 13;
- public static final int REQUEST_INCLUDE = 14;
- public static final int REQUEST_FORWARD_INCLUDE= 15;
-
- // represents nothing having been set. This will be seen
- // as equal to a REQUEST
- private static final int NOT_SET = -1;
-
- private int dispatcherMapping=NOT_SET;
-
- private String filterName = null;
-
- /**
- * The URL pattern this mapping matches.
- */
- private String urlPattern = null;
-
- /**
- * The servlet name this mapping matches.
- */
- private String servletName = null;
-
-
-
- public String getFilterName() {
- return (this.filterName);
- }
-
- public void setFilterName(String filterName) {
- this.filterName = filterName;
- }
-
-
- public String getServletName() {
- return (this.servletName);
- }
-
- public void setServletName(String servletName) {
- this.servletName = servletName;
- }
-
-
- public String getURLPattern() {
- return (this.urlPattern);
- }
-
- public void setURLPattern(String urlPattern) {
- this.urlPattern = RequestUtil.URLDecode(urlPattern);
- }
-
- /**
- *
- * This method will be used to set the current state of the FilterMap
- * representing the state of when filters should be applied:
- *
- * ERROR
- * FORWARD
- * FORWARD_ERROR
- * INCLUDE
- * INCLUDE_ERROR
- * INCLUDE_ERROR_FORWARD
- * REQUEST
- * REQUEST_ERROR
- * REQUEST_ERROR_INCLUDE
- * REQUEST_ERROR_FORWARD_INCLUDE
- * REQUEST_INCLUDE
- * REQUEST_FORWARD,
- * REQUEST_FORWARD_INCLUDE
- *
- */
- public void setDispatcher(String dispatcherString) {
- String dispatcher = dispatcherString.toUpperCase();
-
- if (dispatcher.equals("FORWARD")) {
-
- // apply FORWARD to the global dispatcherMapping.
- switch (dispatcherMapping) {
- case NOT_SET : dispatcherMapping = FORWARD; break;
- case ERROR : dispatcherMapping = FORWARD_ERROR; break;
- case INCLUDE : dispatcherMapping = INCLUDE_FORWARD; break;
- case INCLUDE_ERROR : dispatcherMapping = INCLUDE_ERROR_FORWARD; break;
- case REQUEST : dispatcherMapping = REQUEST_FORWARD; break;
- case REQUEST_ERROR : dispatcherMapping = REQUEST_ERROR_FORWARD; break;
- case REQUEST_ERROR_INCLUDE : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break;
- case REQUEST_INCLUDE : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break;
- }
- } else if (dispatcher.equals("INCLUDE")) {
- // apply INCLUDE to the global dispatcherMapping.
- switch (dispatcherMapping) {
- case NOT_SET : dispatcherMapping = INCLUDE; break;
- case ERROR : dispatcherMapping = INCLUDE_ERROR; break;
- case FORWARD : dispatcherMapping = INCLUDE_FORWARD; break;
- case FORWARD_ERROR : dispatcherMapping = INCLUDE_ERROR_FORWARD; break;
- case REQUEST : dispatcherMapping = REQUEST_INCLUDE; break;
- case REQUEST_ERROR : dispatcherMapping = REQUEST_ERROR_INCLUDE; break;
- case REQUEST_ERROR_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break;
- case REQUEST_FORWARD : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break;
- }
- } else if (dispatcher.equals("REQUEST")) {
- // apply REQUEST to the global dispatcherMapping.
- switch (dispatcherMapping) {
- case NOT_SET : dispatcherMapping = REQUEST; break;
- case ERROR : dispatcherMapping = REQUEST_ERROR; break;
- case FORWARD : dispatcherMapping = REQUEST_FORWARD; break;
- case FORWARD_ERROR : dispatcherMapping = REQUEST_ERROR_FORWARD; break;
- case INCLUDE : dispatcherMapping = REQUEST_INCLUDE; break;
- case INCLUDE_ERROR : dispatcherMapping = REQUEST_ERROR_INCLUDE; break;
- case INCLUDE_FORWARD : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break;
- case INCLUDE_ERROR_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break;
- }
- } else if (dispatcher.equals("ERROR")) {
- // apply ERROR to the global dispatcherMapping.
- switch (dispatcherMapping) {
- case NOT_SET : dispatcherMapping = ERROR; break;
- case FORWARD : dispatcherMapping = FORWARD_ERROR; break;
- case INCLUDE : dispatcherMapping = INCLUDE_ERROR; break;
- case INCLUDE_FORWARD : dispatcherMapping = INCLUDE_ERROR_FORWARD; break;
- case REQUEST : dispatcherMapping = REQUEST_ERROR; break;
- case REQUEST_INCLUDE : dispatcherMapping = REQUEST_ERROR_INCLUDE; break;
- case REQUEST_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD; break;
- case REQUEST_FORWARD_INCLUDE : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break;
- }
- }
- }
-
- public int getDispatcherMapping() {
- // per the SRV.6.2.5 absence of any dispatcher elements is
- // equivelant to a REQUEST value
- if (dispatcherMapping == NOT_SET) return REQUEST;
- else return dispatcherMapping;
- }
-
- }
-
-
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
- }
-
-
- public void destroy() {
- }
-
-}
+++ /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.coyote.servlet;
-
-import java.io.File;
-import java.io.IOException;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-import org.apache.tomcat.util.buf.Ascii;
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.mapper.MappingData;
-
-/**
- * Mapper, which implements the servlet API mapping rules (which are derived
- * from the HTTP rules).
- *
- * Based on catalina mapper - but simplified. All host and context mappings
- * is done in HostMapper - this is just dealing with web.xml.
- *
- * For corner cases ( very large number of rules, dynamic rules, etc ) you
- * can override the mapper for a context with a class extending this.
- *
- * TODO: remove, use coyote-level mapper or user-space
- */
-public class WebappServletMapper implements Filter {
-
- /**
- * Context associated with this wrapper, used for wrapper mapping.
- */
- public ContextMapElement contextMapElement = new ContextMapElement();
-
-
- // --------------------------------------------------------- Public Methods
- public WebappServletMapper() {
- }
-
- public void setServletContext(ServletContextImpl impl) {
- contextMapElement.object = impl;
- contextMapElement.name = impl.getContextPath();
- }
-
-
- /** Set context, used for wrapper mapping (request dispatcher).
- *
- * @param welcomeResources Welcome files defined for this context
- * @param resources Static resources of the context
- */
- public void setContext(String path, String[] welcomeResources,
- File resources) {
- contextMapElement.name = path;
- contextMapElement.welcomeResources = welcomeResources;
- contextMapElement.resources = resources;
- }
-
-
- /**
- * Add a wrapper to the context associated with this wrapper.
- *
- * @param path Wrapper mapping
- * @param wrapper The Wrapper object
- */
- public void addWrapper(String path, Object wrapper) {
- addWrapper(contextMapElement, path, wrapper);
- }
-
-
- public void addWrapper(String path, Object wrapper, boolean jspWildCard) {
- addWrapper(contextMapElement, path, wrapper, jspWildCard);
- }
-
-
- public void addWrapper(ContextMapElement context, String path, Object wrapper) {
- addWrapper(context, path, wrapper, false);
- }
-
-
- /**
- * Adds a wrapper to the given context.
- *
- * @param context The context to which to add the wrapper
- * @param path Wrapper mapping
- * @param wrapper The Wrapper object
- * @param jspWildCard true if the wrapper corresponds to the JspServlet
- * and the mapping path contains a wildcard; false otherwise
- */
- protected void addWrapper(ContextMapElement context, String path, Object wrapper,
- boolean jspWildCard) {
-
- synchronized (context) {
- WrapperMapElement newWrapper = new WrapperMapElement();
- newWrapper.object = wrapper;
- newWrapper.jspWildCard = jspWildCard;
- if (path.endsWith("/*")) {
- // Wildcard wrapper
- newWrapper.name = path.substring(0, path.length() - 2);
- WrapperMapElement[] oldWrappers = context.wildcardWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length + 1];
- if (insertMap(oldWrappers, newWrappers, newWrapper)) {
- context.wildcardWrappers = newWrappers;
- int slashCount = slashCount(newWrapper.name);
- if (slashCount > context.nesting) {
- context.nesting = slashCount;
- }
- }
- } else if (path.startsWith("*.")) {
- // Extension wrapper
- newWrapper.name = path.substring(2);
- WrapperMapElement[] oldWrappers = context.extensionWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length + 1];
- if (insertMap(oldWrappers, newWrappers, newWrapper)) {
- context.extensionWrappers = newWrappers;
- }
- } else if (path.equals("/")) {
- // Default wrapper
- newWrapper.name = "";
- context.defaultWrapper = newWrapper;
- } else {
- // Exact wrapper
- newWrapper.name = path;
- WrapperMapElement[] oldWrappers = context.exactWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length + 1];
- if (insertMap(oldWrappers, newWrappers, newWrapper)) {
- context.exactWrappers = newWrappers;
- }
- }
- }
- }
-
-
- /**
- * Remove a wrapper from the context associated with this wrapper.
- *
- * @param path Wrapper mapping
- */
- public void removeWrapper(String path) {
- removeWrapper(contextMapElement, path);
- }
-
-
- protected void removeWrapper(ContextMapElement context, String path) {
- synchronized (context) {
- if (path.endsWith("/*")) {
- // Wildcard wrapper
- String name = path.substring(0, path.length() - 2);
- WrapperMapElement[] oldWrappers = context.wildcardWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length - 1];
- if (removeMap(oldWrappers, newWrappers, name)) {
- // Recalculate nesting
- context.nesting = 0;
- for (int i = 0; i < newWrappers.length; i++) {
- int slashCount = slashCount(newWrappers[i].name);
- if (slashCount > context.nesting) {
- context.nesting = slashCount;
- }
- }
- context.wildcardWrappers = newWrappers;
- }
- } else if (path.startsWith("*.")) {
- // Extension wrapper
- String name = path.substring(2);
- WrapperMapElement[] oldWrappers = context.extensionWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length - 1];
- if (removeMap(oldWrappers, newWrappers, name)) {
- context.extensionWrappers = newWrappers;
- }
- } else if (path.equals("/")) {
- // Default wrapper
- context.defaultWrapper = null;
- } else {
- // Exact wrapper
- String name = path;
- WrapperMapElement[] oldWrappers = context.exactWrappers;
- WrapperMapElement[] newWrappers =
- new WrapperMapElement[oldWrappers.length - 1];
- if (removeMap(oldWrappers, newWrappers, name)) {
- context.exactWrappers = newWrappers;
- }
- }
- }
- }
-
- /**
- * Map the specified URI relative to the context,
- * mutating the given mapping data.
- *
- * @param uri URI
- * @param mappingData This structure will contain the result of the mapping
- * operation
- */
- public void map(MessageBytes uri, MappingData mappingData)
- throws Exception {
-
- uri.toChars();
- CharChunk uricc = uri.getCharChunk();
- //uricc.setLimit(-1);
- internalMapWrapper(contextMapElement, uricc, mappingData);
-
- }
-
-
- // -------------------------------------------------------- Private Methods
-
-
- /**
- * Wrapper mapping.
- */
- private final void internalMapWrapper(ContextMapElement context,
- CharChunk path,
- MappingData mappingData)
- throws Exception {
-
- int pathOffset = path.getOffset();
- int pathEnd = path.getEnd();
- int servletPath = pathOffset;
- boolean noServletPath = false;
-
- int length = context.name.length();
- if (length == 1) length--;
- if (length != (pathEnd - pathOffset)) {
- servletPath = pathOffset + length;
- } else {
- noServletPath = true;
- // What is this doing ???
- path.append('/');
- pathOffset = path.getOffset();
- pathEnd = path.getEnd();
- servletPath = pathOffset+length;
- }
-
- path.setOffset(servletPath);
-
- // Rule 1 -- Exact Match
- WrapperMapElement[] exactWrappers = context.exactWrappers;
- internalMapExactWrapper(exactWrappers, path, mappingData);
-
- // Rule 2 -- Prefix Match
- boolean checkJspWelcomeFiles = false;
- WrapperMapElement[] wildcardWrappers = context.wildcardWrappers;
- if (mappingData.wrapper == null) {
- internalMapWildcardWrapper(wildcardWrappers, context.nesting,
- path, mappingData);
- if (mappingData.wrapper != null && mappingData.jspWildCard) {
- char[] buf = path.getBuffer();
- if (buf[pathEnd - 1] == '/') {
- /*
- * Path ending in '/' was mapped to JSP servlet based on
- * wildcard match (e.g., as specified in url-pattern of a
- * jsp-property-group.
- * Force the context's welcome files, which are interpreted
- * as JSP files (since they match the url-pattern), to be
- * considered. See Bugzilla 27664.
- */
- mappingData.wrapper = null;
- checkJspWelcomeFiles = true;
- } else {
- // See Bugzilla 27704
- mappingData.wrapperPath.setChars(buf, path.getStart(),
- path.getLength());
- mappingData.pathInfo.recycle();
- }
- }
- }
-
- if(mappingData.wrapper == null && noServletPath) {
- // The path is empty, redirect to "/"
- mappingData.redirectPath.setChars
- (path.getBuffer(), pathOffset, pathEnd);
- path.setEnd(pathEnd - 1);
- return;
- }
-
- // Rule 3 -- Extension Match
- WrapperMapElement[] extensionWrappers = context.extensionWrappers;
- if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
- internalMapExtensionWrapper(extensionWrappers, path, mappingData);
- }
-
- File file = null;
- // Rule 4 -- Welcome resources processing for servlets
- if (mappingData.wrapper == null) {
- boolean checkWelcomeFiles = checkJspWelcomeFiles;
- if (!checkWelcomeFiles) {
- char[] buf = path.getBuffer();
- checkWelcomeFiles = (buf[pathEnd - 1] == '/');
- }
- if (checkWelcomeFiles) {
- for (int i = 0; (i < context.welcomeResources.length)
- && (mappingData.wrapper == null); i++) {
- path.setOffset(pathOffset);
- path.setEnd(pathEnd);
- path.append(context.welcomeResources[i], 0,
- context.welcomeResources[i].length());
- path.setOffset(servletPath);
-
- // Rule 4a -- Welcome resources processing for exact macth
- internalMapExactWrapper(exactWrappers, path, mappingData);
-
- // Rule 4b -- Welcome resources processing for prefix match
- if (mappingData.wrapper == null) {
- internalMapWildcardWrapper
- (wildcardWrappers, context.nesting,
- path, mappingData);
- }
-
- // Rule 4c -- Welcome resources processing
- // for physical folder
- if (mappingData.wrapper == null
- && context.resources != null) {
- // Default servlet: check if it's file or dir to apply
- // welcome files rules.
- // TODO: Save the File in attributes,
- // to avoid duplication in DefaultServlet.
-
- String pathStr = path.toString();
- file = new File(context.resources, pathStr);
- if (file.exists() && !(file.isDirectory()) ) {
-
- internalMapExtensionWrapper(extensionWrappers,
- path, mappingData);
- if (mappingData.wrapper == null
- && context.defaultWrapper != null) {
- mappingData.wrapper =
- context.defaultWrapper.object;
- mappingData.requestPath.setChars
- (path.getBuffer(), path.getStart(),
- path.getLength());
- mappingData.wrapperPath.setChars
- (path.getBuffer(), path.getStart(),
- path.getLength());
- mappingData.requestPath.setString(pathStr);
- mappingData.wrapperPath.setString(pathStr);
- }
- }
- }
- }
-
- path.setOffset(servletPath);
- path.setEnd(pathEnd);
- }
-
- }
-
-
- // Rule 7 -- Default servlet
- if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
- if (context.defaultWrapper != null) {
- mappingData.wrapper = context.defaultWrapper.object;
- mappingData.requestPath.setChars
- (path.getBuffer(), path.getStart(), path.getLength());
- mappingData.wrapperPath.setChars
- (path.getBuffer(), path.getStart(), path.getLength());
- }
- // Redirection to a folder
- char[] buf = path.getBuffer();
- if (context.resources != null && buf[pathEnd -1 ] != '/') {
- String pathStr = path.toString();
- file = new File( context.resources, pathStr);
- if (file.exists() && file.isDirectory()) {
- // Note: this mutates the path: do not do any processing
- // after this (since we set the redirectPath, there
- // shouldn't be any)
- path.setOffset(pathOffset);
- path.append('/');
- mappingData.redirectPath.setChars
- (path.getBuffer(), path.getStart(), path.getLength());
- } else {
- mappingData.requestPath.setString(pathStr);
- mappingData.wrapperPath.setString(pathStr);
- }
- }
- }
-
- path.setOffset(pathOffset);
- path.setEnd(pathEnd);
- }
-
-
- /**
- * Exact mapping.
- */
- private final void internalMapExactWrapper
- (WrapperMapElement[] wrappers, CharChunk path, MappingData mappingData) {
- int pos = find(wrappers, path);
- if ((pos != -1) && (path.equals(wrappers[pos].name))) {
- mappingData.requestPath.setString(wrappers[pos].name);
- mappingData.wrapperPath.setString(wrappers[pos].name);
- mappingData.wrapper = wrappers[pos].object;
- }
- }
-
-
- /**
- * Wildcard mapping.
- */
- private final void internalMapWildcardWrapper
- (WrapperMapElement[] wrappers, int nesting, CharChunk path,
- MappingData mappingData) {
-
- int pathEnd = path.getEnd();
- int pathOffset = path.getOffset();
-
- int lastSlash = -1;
- int length = -1;
- int pos = find(wrappers, path);
- if (pos != -1) {
- boolean found = false;
- while (pos >= 0) {
- if (path.startsWith(wrappers[pos].name)) {
- length = wrappers[pos].name.length();
- if (path.getLength() == length) {
- found = true;
- break;
- } else if (path.startsWithIgnoreCase("/", length)) {
- found = true;
- break;
- }
- }
- if (lastSlash == -1) {
- lastSlash = nthSlash(path, nesting + 1);
- } else {
- lastSlash = lastSlash(path);
- }
- path.setEnd(lastSlash);
- pos = find(wrappers, path);
- }
- path.setEnd(pathEnd);
- if (found) {
- mappingData.wrapperPath.setString(wrappers[pos].name);
- if (path.getLength() > length) {
- mappingData.pathInfo.setChars
- (path.getBuffer(),
- path.getOffset() + length,
- path.getLength() - length);
- }
- mappingData.requestPath.setChars
- (path.getBuffer(), path.getOffset(), path.getLength());
- mappingData.wrapper = wrappers[pos].object;
- mappingData.jspWildCard = wrappers[pos].jspWildCard;
- }
- }
- }
-
-
- /**
- * Extension mappings.
- */
- private final void internalMapExtensionWrapper
- (WrapperMapElement[] wrappers, CharChunk path, MappingData mappingData) {
- char[] buf = path.getBuffer();
- int pathEnd = path.getEnd();
- int servletPath = path.getOffset();
- int slash = -1;
- for (int i = pathEnd - 1; i >= servletPath; i--) {
- if (buf[i] == '/') {
- slash = i;
- break;
- }
- }
- if (slash == -1 ) slash = 0;
- if (slash >= 0) {
- int period = -1;
- for (int i = pathEnd - 1; i > slash; i--) {
- if (buf[i] == '.') {
- period = i;
- break;
- }
- }
- if (period >= 0) {
- path.setOffset(period + 1);
- path.setEnd(pathEnd);
- int pos = find(wrappers, path);
- if ((pos != -1)
- && (path.equals(wrappers[pos].name))) {
- mappingData.wrapperPath.setChars
- (buf, servletPath, pathEnd - servletPath);
- mappingData.requestPath.setChars
- (buf, servletPath, pathEnd - servletPath);
- mappingData.wrapper = wrappers[pos].object;
- }
- path.setOffset(servletPath);
- path.setEnd(pathEnd);
- }
- }
- }
-
-
- /**
- * Find a map elemnt given its name in a sorted array of map elements.
- * This will return the index for the closest inferior or equal item in the
- * given array.
- */
- public static final int find(MapElement[] map, CharChunk name) {
- return find(map, name, name.getStart(), name.getEnd());
- }
-
-
- /**
- * Find a map elemnt given its name in a sorted array of map elements.
- * This will return the index for the closest inferior or equal item in the
- * given array.
- */
- private static final int find(MapElement[] map, CharChunk name,
- int start, int end) {
-
- int a = 0;
- int b = map.length - 1;
-
- // Special cases: -1 and 0
- if (b == -1) {
- return -1;
- }
-
- if (compare(name, start, end, map[0].name) < 0 ) {
- return -1;
- }
- if (b == 0) {
- return 0;
- }
-
- int i = 0;
- while (true) {
- i = (b + a) / 2;
- int result = compare(name, start, end, map[i].name);
- if (result == 1) {
- a = i;
- } else if (result == 0) {
- return i;
- } else {
- b = i;
- }
- if ((b - a) == 1) {
- int result2 = compare(name, start, end, map[b].name);
- if (result2 < 0) {
- return a;
- } else {
- return b;
- }
- }
- }
-
- }
-
- /**
- * Find a map elemnt given its name in a sorted array of map elements.
- * This will return the index for the closest inferior or equal item in the
- * given array.
- */
- private static final int findIgnoreCase(MapElement[] map, CharChunk name) {
- return findIgnoreCase(map, name, name.getStart(), name.getEnd());
- }
-
-
- /**
- * Find a map elemnt given its name in a sorted array of map elements.
- * This will return the index for the closest inferior or equal item in the
- * given array.
- */
- private static final int findIgnoreCase(MapElement[] map, CharChunk name,
- int start, int end) {
-
- int a = 0;
- int b = map.length - 1;
-
- // Special cases: -1 and 0
- if (b == -1) {
- return -1;
- }
- if (compareIgnoreCase(name, start, end, map[0].name) < 0 ) {
- return -1;
- }
- if (b == 0) {
- return 0;
- }
-
- int i = 0;
- while (true) {
- i = (b + a) / 2;
- int result = compareIgnoreCase(name, start, end, map[i].name);
- if (result == 1) {
- a = i;
- } else if (result == 0) {
- return i;
- } else {
- b = i;
- }
- if ((b - a) == 1) {
- int result2 = compareIgnoreCase(name, start, end, map[b].name);
- if (result2 < 0) {
- return a;
- } else {
- return b;
- }
- }
- }
-
- }
-
-
- /**
- * Find a map elemnt given its name in a sorted array of map elements.
- * This will return the index for the closest inferior or equal item in the
- * given array.
- */
- public static final int find(MapElement[] map, String name) {
-
- int a = 0;
- int b = map.length - 1;
-
- // Special cases: -1 and 0
- if (b == -1) {
- return -1;
- }
-
- if (name.compareTo(map[0].name) < 0) {
- return -1;
- }
- if (b == 0) {
- return 0;
- }
-
- int i = 0;
- while (true) {
- i = (b + a) / 2;
- int result = name.compareTo(map[i].name);
- if (result > 0) {
- a = i;
- } else if (result == 0) {
- return i;
- } else {
- b = i;
- }
- if ((b - a) == 1) {
- int result2 = name.compareTo(map[b].name);
- if (result2 < 0) {
- return a;
- } else {
- return b;
- }
- }
- }
-
- }
-
-
- /**
- * Compare given char chunk with String.
- * Return -1, 0 or +1 if inferior, equal, or superior to the String.
- */
- private static final int compare(CharChunk name, int start, int end,
- String compareTo) {
- int result = 0;
- char[] c = name.getBuffer();
- int len = compareTo.length();
- if ((end - start) < len) {
- len = end - start;
- }
- for (int i = 0; (i < len) && (result == 0); i++) {
- if (c[i + start] > compareTo.charAt(i)) {
- result = 1;
- } else if (c[i + start] < compareTo.charAt(i)) {
- result = -1;
- }
- }
- if (result == 0) {
- if (compareTo.length() > (end - start)) {
- result = -1;
- } else if (compareTo.length() < (end - start)) {
- result = 1;
- }
- }
- return result;
- }
-
-
- /**
- * Compare given char chunk with String ignoring case.
- * Return -1, 0 or +1 if inferior, equal, or superior to the String.
- */
- private static final int compareIgnoreCase(CharChunk name, int start, int end,
- String compareTo) {
- int result = 0;
- char[] c = name.getBuffer();
- int len = compareTo.length();
- if ((end - start) < len) {
- len = end - start;
- }
- for (int i = 0; (i < len) && (result == 0); i++) {
- if (Ascii.toLower(c[i + start]) > Ascii.toLower(compareTo.charAt(i))) {
- result = 1;
- } else if (Ascii.toLower(c[i + start]) < Ascii.toLower(compareTo.charAt(i))) {
- result = -1;
- }
- }
- if (result == 0) {
- if (compareTo.length() > (end - start)) {
- result = -1;
- } else if (compareTo.length() < (end - start)) {
- result = 1;
- }
- }
- return result;
- }
-
-
- /**
- * Find the position of the last slash in the given char chunk.
- */
- public static final int lastSlash(CharChunk name) {
-
- char[] c = name.getBuffer();
- int end = name.getEnd();
- int start = name.getStart();
- int pos = end;
-
- while (pos > start) {
- if (c[--pos] == '/') {
- break;
- }
- }
-
- return (pos);
-
- }
-
-
- /**
- * Find the position of the nth slash, in the given char chunk.
- */
- public static final int nthSlash(CharChunk name, int n) {
-
- char[] c = name.getBuffer();
- int end = name.getEnd();
- int start = name.getStart();
- int pos = start;
- int count = 0;
-
- while (pos < end) {
- if ((c[pos++] == '/') && ((++count) == n)) {
- pos--;
- break;
- }
- }
-
- return (pos);
-
- }
-
-
- /**
- * Return the slash count in a given string.
- */
- public static final int slashCount(String name) {
- int pos = -1;
- int count = 0;
- while ((pos = name.indexOf('/', pos + 1)) != -1) {
- count++;
- }
- return count;
- }
-
-
- /**
- * Insert into the right place in a sorted MapElement array, and prevent
- * duplicates.
- */
- public static final boolean insertMap
- (MapElement[] oldMap, MapElement[] newMap, MapElement newElement) {
- int pos = find(oldMap, newElement.name);
- if ((pos != -1) && (newElement.name.equals(oldMap[pos].name))) {
- return false;
- }
- System.arraycopy(oldMap, 0, newMap, 0, pos + 1);
- newMap[pos + 1] = newElement;
- System.arraycopy
- (oldMap, pos + 1, newMap, pos + 2, oldMap.length - pos - 1);
- return true;
- }
-
-
- /**
- * Insert into the right place in a sorted MapElement array.
- */
- public static final boolean removeMap
- (MapElement[] oldMap, MapElement[] newMap, String name) {
- int pos = find(oldMap, name);
- if ((pos != -1) && (name.equals(oldMap[pos].name))) {
- System.arraycopy(oldMap, 0, newMap, 0, pos);
- System.arraycopy(oldMap, pos + 1, newMap, pos,
- oldMap.length - pos - 1);
- return true;
- }
- return false;
- }
-
-
- // ------------------------------------------------- MapElement Inner Class
-
-
- protected static abstract class MapElement {
- /** hostname or path
- */
- public String name = null;
- public Object object = null;
-
- public String toString() {
- return "MapElement: \"" + name +"\"";
- }
- }
-
-
- // ---------------------------------------------------- Context Inner Class
-
-
- public static final class ContextMapElement
- extends MapElement {
-
- public String[] welcomeResources = new String[0];
- public File resources = null;
- public WrapperMapElement defaultWrapper = null;
- public WrapperMapElement[] exactWrappers = new WrapperMapElement[0];
- public WrapperMapElement[] wildcardWrappers = new WrapperMapElement[0];
- public WrapperMapElement[] extensionWrappers = new WrapperMapElement[0];
- public int nesting = 0;
-
- public String toString() {
- return "ContextMapElement {" +
- "name: \"" + name +
- "\"\nnesting: \"" + nesting +
- "\"\n}";
- }
- }
-
-
- // ---------------------------------------------------- Wrapper Inner Class
-
-
- public static class WrapperMapElement
- extends MapElement {
- public boolean jspWildCard = false;
- }
-
-
- public void destroy() {
- }
-
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException,
- ServletException {
- }
-
-
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
-
-}
+++ /dev/null
-# Support for PropertiesSpi - the 'dummy' framework used for tomcat-lite
-# If tomcat is used with a proper framework, you need to bind and configure
-# those objects in the framework.
-
-Main.(class)=org.apache.coyote.servlet.TomcatLite
-
-Jmx.(class)=org.apache.tomcat.integration.jmx.JmxObjectManagerSpi
-
-# --- Class names for required plugin interfaces ---
-
-org.apache.coyote.servlet.WebappServletMapper.(class)=org.apache.coyote.servlet.WebappServletMapper
-org.apache.coyote.servlet.WebappFilterMapper.(class)=org.apache.coyote.servlet.WebappFilterMapper
-
-# Sessions
-org.apache.tomcat.servlets.session.UserSessionManager.(class)=org.apache.tomcat.servlets.session.SimpleSessionManager
-
-# Loader for web.xml - you can have your own custom class using a more efficient
-# or hardcoded.
-org.apache.coyote.servlet.ContextPreinitListener.(class)=org.apache.coyote.servlet.webxml.TomcatLiteWebXmlConfig
-
-# Connector class
-org.apache.coyote.servlet.Connector.(class)=org.apache.coyote.servlet.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.coyote.servlet;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.coyote.OutputBuffer;
-import org.apache.coyote.Response;
-import org.apache.tomcat.lite.SimpleServlet;
-import org.apache.tomcat.util.buf.ByteChunk;
-
-public class LiteTestHelper {
-
- public static void addContext(TomcatLite lite) throws ServletException {
- ServletContextImpl ctx =
- (ServletContextImpl) lite.addServletContext(null, null, "/test1");
-
- ctx.addServlet("test", new SimpleServlet());
- ctx.addMapping("/1stTest", "test");
-
- ctx.addServlet("testException", new HttpServlet() {
- public void doGet(HttpServletRequest req, HttpServletResponse res)
- throws IOException {
- throw new NullPointerException();
- }
- });
- ctx.addMapping("/testException", "testException");
- }
-
- public static void initServletsAndRun(TomcatLite lite, int port) throws ServletException, IOException {
- addContext(lite);
- lite.init();
- lite.start();
-
-
- if (port > 0) {
- // This should be added after all local initialization to avoid
- // the server from responding.
- // Alternatively, you can load this early but set it to return
- // 'unavailable' if load balancers depend on this.
- addConnector(lite, port, true);
-
- // At this point we can add contexts and inject requests, if we want to
- // do it over HTTP need to start the connector as well.
- lite.startConnector();
- }
- }
-
- public static void addConnector(TomcatLite lite,
- int port, boolean daemon) {
- CoyoteConnector coyoteAdapter = (CoyoteConnector) lite.getConnector();
- coyoteAdapter.setPort(port);
- coyoteAdapter.setDaemon(daemon);
- }
-
- /**
- * Get url using URLConnection.
- */
- public static ByteChunk getUrl(String path) throws IOException {
-
- ByteChunk out = new ByteChunk();
-
- URL url = new URL(path);
- URLConnection connection = url.openConnection();
- connection.setReadTimeout(5000);
- connection.connect();
- InputStream is = connection.getInputStream();
- BufferedInputStream bis = new BufferedInputStream(is);
- byte[] buf = new byte[2048];
- int rd = 0;
- while((rd = bis.read(buf)) > 0) {
- out.append(buf, 0, rd);
- }
- return out;
- }
-
- static class ByteChunkOutputBuffer implements OutputBuffer {
-
- protected ByteChunk output = null;
-
- public ByteChunkOutputBuffer(ByteChunk output) {
- this.output = output;
- }
-
- public int doWrite(ByteChunk chunk, Response response)
- throws IOException {
- output.append(chunk);
- return chunk.getLength();
- }
- }
-
-
-}
+++ /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.coyote.servlet;
-
-
-import junit.framework.Test;
-
-public class LiteWatchdogJspTests extends LiteWatchdogServletTests {
-
- public LiteWatchdogJspTests() {
- super();
- port = 8017;
- testMatch =
- //"precompileNegativeTest";
- null;
- // Test we know are failing - need to fix at some point.
- exclude = new String[] {
- "negativeDuplicateExtendsFatalTranslationErrorTest",
- "negativeDuplicateErrorPageFatalTranslationErrorTest",
- "negativeDuplicateInfoFatalTranslationErrorTest",
- "negativeDuplicateLanguageFatalTranslationErrorTest",
- "negativeDuplicateSessionFatalTranslationErrorTest",
- "positiveIncludeCtxRelativeHtmlTest",
- "precompileNegativeTest"
- };
- file = getWatchdogdir() + "/src/conf/jsp-gtest.xml";
- goldenDir =
- getWatchdogdir() + "/src/clients/org/apache/jcheck/jsp/client/";
- targetMatch = "jsp-test";
-
- }
-
- public static Test suite() {
- return new LiteWatchdogJspTests().getSuite(8017);
- }
-
-}
-
+++ /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.coyote.servlet;
-
-import java.io.File;
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-
-import junit.framework.Test;
-import junit.framework.TestResult;
-
-import org.apache.tomcat.test.watchdog.WatchdogClient;
-
-
-public class LiteWatchdogServletTests extends WatchdogClient {
-
-
- public LiteWatchdogServletTests() {
- port = 8115;
- goldenDir = getWatchdogdir() + "/src/clients/org/apache/jcheck/servlet/client/";
- testMatch =
- //"HttpServletResponseWrapperSetStatusMsgTest";
- //"ServletContextAttributeAddedEventTest";
- null;
- // ex: "ServletToJSP";
- file = getWatchdogdir() + "/src/conf/servlet-gtest.xml";
- targetMatch = "gtestservlet-test";
- }
-
- protected void beforeSuite() {
- // required for the tests
- System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
- "true");
-
- try {
- initServerWithWatchdog(getWatchdogdir());
- } catch (ServletException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- int port = 8115;
-
- protected void addConnector(TomcatLite liteServer) {
- LiteTestHelper.addConnector(liteServer, port, true);
- }
-
- public void initServerWithWatchdog(String wdDir) throws ServletException,
- IOException {
-
- File f = new File(wdDir + "/build/webapps");
-
- //CoyoteServer connector = new CoyoteServer();
- //connector.addAdapter("/", new MapperAdapter());
-
- TomcatLite liteServer = new TomcatLite();
- addConnector(liteServer);
- liteServer.init("webapps/ROOT", "/");
-
- for (String s : new String[] {
- "servlet-compat",
- "servlet-tests",
- "jsp-tests"} ) {
- liteServer.init(f.getCanonicalPath() + "/" + s,
- "/" + s);
- }
-
- //connector.init();
- liteServer.init();
- liteServer.start();
-
- liteServer.startConnector();
- }
-
-
-
- protected void afterSuite(TestResult res) {
- // no need to stop it - using daemon threads.
- System.err.println("DONE");
- }
-
-
- /**
- * Magic JUnit method
- */
- public static Test suite() {
- // The individual targets are dups - and bad ones,
- // RequestWrapper are missing part of the URL
- return new LiteWatchdogServletTests().getSuite(8115);
- }
-}
+++ /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.coyote.servlet;
-
-import junit.framework.TestCase;
-
-import org.apache.tomcat.util.buf.ByteChunk;
-
-public class TomcatLiteSimpleTest extends TestCase {
-
- protected TomcatLite lite = new TomcatLite();
-
- public void setUp() throws Exception {
- LiteTestHelper.initServletsAndRun(lite, 8804);
- }
-
- public void tearDown() throws Exception {
- lite.stop();
- }
-
- public void testSimpleRequest() throws Exception {
- ByteChunk resb =
- LiteTestHelper.getUrl("http://localhost:8804/test1/1stTest");
- assertTrue(resb.getLength() > 0);
- assertEquals("Hello world", resb.toString());
- }
-
-
-}