You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/08/11 08:14:21 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util ArrayEnumerator.java Ascii.java DateTool.java MessageBytes.java MimeHeaderField.java
costin 00/08/10 23:14:20
Modified: . build.xml
src/share/org/apache/tomcat/context DefaultCMSetter.java
src/share/org/apache/tomcat/core ContextManager.java
OutputBuffer.java Request.java RequestImpl.java
Response.java ResponseImpl.java
src/share/org/apache/tomcat/facade
HttpServletResponseFacade.java
ServletOutputStreamFacade.java
ServletWriterFacade.java
src/share/org/apache/tomcat/request AccessInterceptor.java
SimpleMapper1.java StaticInterceptor.java
src/share/org/apache/tomcat/service/connector
Ajp12ConnectionHandler.java
Ajp13ConnectorRequest.java
JNIConnectionHandler.java
src/share/org/apache/tomcat/service/http
HttpRequestAdapter.java HttpResponseAdapter.java
src/share/org/apache/tomcat/util ArrayEnumerator.java
Ascii.java DateTool.java MessageBytes.java
MimeHeaderField.java
Log:
This is a big change, I couldn't find a good way of spliting it
( most changes are related with each other ).
This is just a start for a big refactoring - the goal is security and
performance.
This change:
- For all internal Handlers, use a per/thread re-usable StringBuffer.
The buffer is not converted toString, so it generates no garbage.
- use OutputBuffer - the code from BufferedServletOutputStream is now here,
plus addition to write a StringBuffer ( without the expensive toString())
( still need to make sure the char/byte mixing works in all cases - this
is the DEV branch )
- removed the old ByteBuffer code - interesting experiment, too complex.
- enhanced MessageBytes ( used as an efficient way to store headers ).
Also use MessageBytes for efficient storage of request fields.
This still require a lot of work, but we are getting very close to 0 GC.
( at least for requests without params and without cookies - those will
also need to be converted to recyclable structures )
- also few small cosmetic changes in RequestImpl to allow better visibility.
Most fields will disapear soon, it will be a very simple class.
- Same for response - only OutputBuffer is used in Request and core, the
Output/Writer is handled by facade.
- few minor optimizations ( cache, avoid GC )
- a bit of cleanup ( more to come )
- few optimizations in HttpRequest
Revision Changes Path
1.59 +1 -1 jakarta-tomcat/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat/build.xml,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- build.xml 2000/08/05 15:56:06 1.58
+++ build.xml 2000/08/11 06:14:02 1.59
@@ -10,7 +10,7 @@
<property name="tomcat.build" value="../build/tomcat"/>
<property name="tomcat.home" value="../dist/tomcat"/>
<property name="j2ee.home" value="../j2ee/build/unix"/>
- <property name="optimize" value="true" />
+ <property name="optimize" value="false" />
<property name="jaxp" value="../jaxp1.0.1" />
</target>
1.48 +65 -43 jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java
Index: DefaultCMSetter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- DefaultCMSetter.java 2000/08/02 02:17:06 1.47
+++ DefaultCMSetter.java 2000/08/11 06:14:04 1.48
@@ -137,7 +137,8 @@
class NotFoundHandler extends Handler {
static StringManager sm=StringManager.
getManager("org.apache.tomcat.resources");
-
+ int sbNote=0;
+
NotFoundHandler() {
initialized=true;
internal=true;
@@ -155,8 +156,20 @@
if (requestURI == null) {
requestURI = req.getRequestURI();
}
+
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "NotFoundHandler.buff");
+ }
- StringBuffer buf = new StringBuffer();
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
+
buf.append("<head><title>")
.append(sm.getString("defaulterrorpage.notfound404"))
.append("</title></head>\r\n");
@@ -167,25 +180,17 @@
.append( requestURI );
buf.append("</body>\r\n");
- String body = buf.toString();
+ res.setContentLength(buf.length());
- res.setContentLength(body.length());
-
- if( res.isUsingStream() ) {
- ServletOutputStream out = res.getOutputStream();
- out.print(body);
- out.flush();
- } else {
- PrintWriter out = res.getWriter();
- out.print(body);
- out.flush();
- }
+ res.getBuffer().write( buf );
+ buf.setLength(0);
}
}
class ExceptionHandler extends Handler {
static StringManager sm=StringManager.
getManager("org.apache.tomcat.resources");
+ int sbNote=0;
ExceptionHandler() {
initialized=true;
@@ -208,7 +213,18 @@
res.setContentType("text/html");
res.setStatus( 500 );
- StringBuffer buf = new StringBuffer();
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "ExceptionHandler.buff");
+ }
+
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
buf.append("<h1>");
if( res.isIncluded() ) {
buf.append(sm.getString("defaulterrorpage.includedservlet") ).
@@ -240,19 +256,15 @@
buf.append("\r\n");
- if( res.isUsingStream() ) {
- ServletOutputStream out = res.getOutputStream();
- out.print(buf.toString());
- } else {
- PrintWriter out = res.getWriter();
- out.print(buf.toString());
- }
+ res.getBuffer().write( buf );
+ buf.setLength(0);
}
}
class StatusHandler extends Handler {
static StringManager sm=StringManager.
getManager("org.apache.tomcat.resources");
+ int sbNote=0;
StatusHandler() {
initialized=true;
@@ -272,7 +284,18 @@
// status is already set
int sc=res.getStatus();
- StringBuffer buf = new StringBuffer();
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "StatusHandler.buff");
+ }
+
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
buf.append("<h1>");
if( res.isIncluded() ) {
buf.append(sm.getString("defaulterrorpage.includedservlet") );
@@ -293,19 +316,16 @@
.append(msg)
.append("</b><br>");
- if( res.isUsingStream() ) {
- ServletOutputStream out = res.getOutputStream();
- out.print(buf.toString());
- } else {
- PrintWriter out = res.getWriter();
- out.print(buf.toString());
- }
+ res.setContentLength(buf.length());
+ res.getBuffer().write( buf );
+ buf.setLength(0);
}
}
class RedirectHandler extends Handler {
static StringManager sm=StringManager.
getManager("org.apache.tomcat.resources");
+ int sbNote=0;
RedirectHandler() {
initialized=true;
@@ -329,7 +349,18 @@
res.setContentType("text/html"); // ISO-8859-1 default
res.setHeader("Location", location);
- StringBuffer buf = new StringBuffer();
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "RedirectHandler.buff");
+ }
+
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
buf.append("<head><title>").
append(sm.getString("defaulterrorpage.documentmoved")).
append("</title></head>\r\n<body><h1>").
@@ -340,19 +371,10 @@
append(location).
append("\">here</a>.<p>\r\n</body>\r\n");
- String body = buf.toString();
+ res.setContentLength(buf.length());
+ res.getBuffer().write( buf );
+ buf.setLength(0);
- res.setContentLength(body.length());
-
- if( res.isUsingStream() ) {
- ServletOutputStream out = res.getOutputStream();
- out.print(body);
- out.flush();
- } else {
- PrintWriter out = res.getWriter();
- out.print(body);
- out.flush();
- }
}
// XXX Move it to URLUtil !!!
1.110 +1 -1 jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
Index: ContextManager.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -r1.109 -r1.110
--- ContextManager.java 2000/08/09 13:43:48 1.109
+++ ContextManager.java 2000/08/11 06:14:06 1.110
@@ -640,7 +640,7 @@
if( status >= 400 ) {
if( debug > 0)
log( "Error reading request " + req + " " + status);
- handleStatus( req, res, status );
+ handleStatus( req, res, status );
return;
}
1.2 +265 -32 jakarta-tomcat/src/share/org/apache/tomcat/core/OutputBuffer.java
Index: OutputBuffer.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/OutputBuffer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- OutputBuffer.java 2000/07/31 02:35:15 1.1
+++ OutputBuffer.java 2000/08/11 06:14:06 1.2
@@ -56,11 +56,10 @@
* [Additional notices, if required by prior licensing conditions]
*
*/
-
-
package org.apache.tomcat.core;
import java.io.*;
+import java.util.*;
/**
* The buffer used by tomcat response. It allows writting chars and
@@ -71,17 +70,25 @@
*
* @author Costin Manolache
*/
-public final class OutputBuffer {
+public final class OutputBuffer extends Writer {
public static final int DEFAULT_BUFFER_SIZE = 8*1024;
int defaultBufferSize = DEFAULT_BUFFER_SIZE;
+ int defaultCharBufferSize = DEFAULT_BUFFER_SIZE / 2 ;
+
+ // The buffer can be used for byte[] and char[] writing
+ // ( this is needed to support ServletOutputStream and for
+ // efficient implementations of templating systems )
+ public final int INITIAL_STATE=0;
+ public final int CHAR_STATE=1;
+ public final int BYTE_STATE=2;
+ int state=0;
+
+ static final int debug=0;
int bytesWritten = 0;
/** The buffer
*/
public byte buf[];
-
- public int start;
- public int end;
/**
* The index one greater than the index of the last valid byte in
@@ -89,7 +96,6 @@
*/
public int count;
- final static int debug=0;
Response resp;
Request req;
@@ -97,37 +103,37 @@
public OutputBuffer(Response resp) {
buf=new byte[defaultBufferSize];
+ cbuf=new char[defaultCharBufferSize];
this.resp=resp;
req=resp.getRequest();
cm=req.getContextManager();
}
+ void log( String s ) {
+ System.out.println("OutputBuffer: " + s );
+ }
+
public void recycle() {
+ if( debug > 0 ) log("recycle()");
+ state=INITIAL_STATE;
bytesWritten=0;
+ charsWritten=0;
+ ccount=0;
count=0;
}
-
- /** This method will call the interceptors and then write the buf[]
- * to the adapter's doWrite.
- */
- void doWrite( byte buf[], int off, int count ) throws IOException {
- cm.doWrite( req, resp, buf, off, count );
- }
- // -------------------- Adding to the buffer --------------------
+ // -------------------- Adding bytes to the buffer --------------------
// Like BufferedOutputStream, without sync
- public void write(int b) throws IOException {
- if( debug>1 )System.out.write( b );
- if (count >= buf.length) {
- flush();
- }
- buf[count++] = (byte)b;
- bytesWritten++;
- }
-
public void write(byte b[], int off, int len) throws IOException {
- if( debug>1 ) System.out.write( b, off, len );
+ if( state==CHAR_STATE )
+ flushChars();
+ state=BYTE_STATE;
+ writeBytes( b, off, len );
+ }
+
+ public void writeBytes(byte b[], int off, int len) throws IOException {
+ if( debug > 0 ) log("write(b,off,len)");
int avail=buf.length - count;
bytesWritten += len;
@@ -153,7 +159,7 @@
*/
System.arraycopy(b, off, buf, count, avail);
count += avail;
- flush();
+ flushBytes();
System.arraycopy(b, off+avail, buf, count, len - avail);
count+= len - avail;
@@ -162,17 +168,191 @@
}
// len > buf.length + avail
- flush();
- doWrite( b, off, len );
+ flushBytes();
+ cm.doWrite( req, resp, b, off, len );
return;
}
- // -------------------- BufferedOutputStream compatibility
+ // XXX Char or byte ?
+ public void writeByte(int b) throws IOException {
+ if( state==CHAR_STATE )
+ flushChars();
+ state=BYTE_STATE;
+ if( debug > 0 ) log("write(b)");
+ if (count >= buf.length) {
+ flushBytes();
+ }
+ buf[count++] = (byte)b;
+ bytesWritten++;
+ }
+
+
+ // -------------------- Adding chars to the buffer
+ String enc;
+ boolean gotEnc=false;
+ public char cbuf[];
+ public int ccount;
+ int charsWritten;
+
+
+ public void write( int c ) throws IOException {
+ state=CHAR_STATE;
+ if( debug > 0 ) log("writeChar(b)");
+ if (ccount >= cbuf.length) {
+ flushChars();
+ }
+ cbuf[ccount++] = (char)c;
+ charsWritten++;
+ }
+
+ public void write( char c[] ) throws IOException {
+ write( c, 0, c.length );
+ }
+
+ public void write(char c[], int off, int len) throws IOException {
+ state=CHAR_STATE;
+ if( debug > 0 ) log("write(c,off,len)");
+ int avail=cbuf.length - ccount;
+
+ charsWritten += len;
+
+ // fit in buffer, great.
+ if( len <= avail ) {
+ System.arraycopy(c, off, cbuf, ccount, len);
+ ccount += len;
+ return;
+ }
+
+ if (len - avail < cbuf.length) {
+ /* If the request length exceeds the size of the output buffer,
+ flush the output buffer and then write the data directly.
+ We can't avoid 2 writes, but we can write more on the second
+ */
+ System.arraycopy(c, off, cbuf, ccount, avail);
+ ccount += avail;
+ flushChars();
+
+ System.arraycopy(c, off+avail, cbuf, ccount, len - avail);
+ ccount+= len - avail;
+ charsWritten += len - avail;
+ return;
+ }
+
+ // len > buf.length + avail
+ flushChars();
+ cWrite( c, off, len );
+ return;
+ }
+
+ private int min(int a, int b) {
+ if (a < b) return a;
+ return b;
+ }
+
+ public void write( StringBuffer sb ) throws IOException {
+ state=CHAR_STATE;
+ if( debug > 0 ) log("write(s,off,len)");
+ int len=sb.length();
+ charsWritten += len;
+
+ int off=0;
+ int b = off;
+ int t = off + len;
+ while (b < t) {
+ int d = min(cbuf.length - ccount, t - b);
+ sb.getChars( b, b+d, cbuf, ccount);
+ b += d;
+ ccount += d;
+ if (ccount >= cbuf.length)
+ flushChars();
+ }
+ return;
+ }
+
+ public void write(String s, int off, int len) throws IOException {
+ state=CHAR_STATE;
+ if( debug > 0 ) log("write(s,off,len)");
+ charsWritten += len;
+ if (s==null) s="null";
+
+ // different strategy: we can't write more then cbuf[]
+ // because of conversions. Writing in 8k chunks is not bad.
+ int b = off;
+ int t = off + len;
+ while (b < t) {
+ int d = min(cbuf.length - ccount, t - b);
+ s.getChars( b, b+d, cbuf, ccount);
+ b += d;
+ ccount += d;
+ if (ccount >= cbuf.length)
+ flushChars();
+ }
+ return;
+ }
+
+ public void write(String s) throws IOException {
+ state=CHAR_STATE;
+ if (s==null) s="null";
+ write( s, 0, s.length() );
+ }
+
+ public void flushChars() throws IOException {
+ if( debug > 0 ) log("flushChars() " + ccount);
+ if( ccount > 0) {
+ cWrite( cbuf, 0, ccount );
+ ccount=0;
+ }
+ }
+
+ public void close() throws IOException {
+ //nothing
+ }
+
public void flush() throws IOException {
+ System.out.println("No flush ");
+ }
+
+ Hashtable encoders=new Hashtable();
+ WriteConvertor conv;
+
+ void cWrite( char c[], int off, int len ) throws IOException {
+ if( debug > 0 ) log("cWrite(c,o,l) " + ccount);
+ if( !gotEnc ) setConverter();
+
+ conv.write(c, off, len);
+ conv.flush();
+ }
+
+ private void setConverter() {
+ enc = resp.getCharacterEncoding();
+ gotEnc=true;
+ if(enc==null) enc="8859_1";
+ conv=(WriteConvertor)encoders.get(enc);
+ if(conv==null) {
+ IntermediateOutputStream ios=new IntermediateOutputStream(this);
+ try {
+ conv=new WriteConvertor(ios,enc);
+ encoders.put(enc, conv);
+ } catch(UnsupportedEncodingException ex ) {
+ conv=(WriteConvertor)encoders.get("8859_1");
+ if(conv==null) {
+ try {
+ conv=new WriteConvertor(ios, "8859_1");
+ encoders.put("8859_1", conv);
+ } catch( UnsupportedEncodingException e ) {}
+ }
+ }
+ }
+ }
+
+ // -------------------- BufferedOutputStream compatibility
+
+ public void flushBytes() throws IOException {
+ if( debug > 0 ) log("flushBytes() " + count);
if( count > 0) {
- doWrite( buf, 0, count );
+ cm.doWrite( req, resp, buf, 0, count );
count=0;
}
}
@@ -199,8 +379,61 @@
// -------------------- Utils
- void log( String s ) {
- System.out.println("OutputBuffer: " + s );
+}
+
+class WriteConvertor extends OutputStreamWriter {
+ /* Has a private, internal byte[8192]
+ */
+ public WriteConvertor( OutputStream out, String enc )
+ throws UnsupportedEncodingException
+ {
+ super( out, enc );
}
+
+ public void close() throws IOException {
+ // NOTHING
+ // Calling super.close() would reset out and cb.
+ }
+
+ public void flush() throws IOException {
+ // Will flushBuffer and out()
+ // flushBuffer put any remaining chars in the byte[]
+ super.flush();
+ }
+
+ public void write(char cbuf[], int off, int len) throws IOException {
+ // will do the conversion and call write on the output stream
+ super.write( cbuf, off, len );
+ }
+}
+
+
+class IntermediateOutputStream extends OutputStream {
+ OutputBuffer tbuff;
+ public IntermediateOutputStream(OutputBuffer tbuff) {
+ this.tbuff=tbuff;
+ }
+
+ public void close() throws IOException {
+ // shouldn't be called - we filter it out in writer
+ System.out.println("close() called - shouldn't happen ");
+ throw new IOException("close() called - shouldn't happen ");
+ }
+
+ public void flush() throws IOException {
+ // nothing - write will go directly to the buffer,
+ // we don't keep any state
+ }
+
+ public void write(byte cbuf[], int off, int len) throws IOException {
+ // System.out.println("IOS: " + len );
+ tbuff.writeBytes( cbuf, off, len );
+ }
+
+ public void write( int i ) throws IOException {
+ System.out.println("write(int ) called - shouldn't happen ");
+ throw new IOException("write(int ) called - shouldn't happen ");
+ }
}
+
1.50 +0 -5 jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java
Index: Request.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- Request.java 2000/08/02 02:17:11 1.49
+++ Request.java 2000/08/11 06:14:06 1.50
@@ -340,11 +340,6 @@
/** This is the top request ( for a sub-request )
*/
public Request getTop();
- // -------------------- Buffers --------------------
-
- // public ByteBuffer getInputBuffer();
-
- // public void setInputBuffer(ByteBuffer buf);
// -------------------- Notes --------------------
/** Add a per/request internal attribute.
1.57 +82 -92 jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java
Index: RequestImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- RequestImpl.java 2000/08/02 02:17:11 1.56
+++ RequestImpl.java 2000/08/11 06:14:07 1.57
@@ -83,53 +83,64 @@
*/
public class RequestImpl implements Request {
+ protected int serverPort;
+ protected String remoteAddr;
+ protected String remoteHost;
+ protected String localHost;
+
+ // Request components represented as MB.
+ // MB are also used for headers - it allows lazy
+ // byte->char conversion so we can add the encoding
+ // that is known only after header parsing. Work in progress.
+ protected MessageBytes schemeMB=new MessageBytes();
+ protected MessageBytes methodMB=new MessageBytes();
+ protected MessageBytes uriMB=new MessageBytes();
+ protected MessageBytes queryMB=new MessageBytes();
+ protected MessageBytes protoMB=new MessageBytes();
+ // uri components
+ protected MessageBytes contextMB=new MessageBytes();
+ protected MessageBytes servletPathMB=new MessageBytes();
+ protected MessageBytes pathInfoMB=new MessageBytes();
+
// GS, used by the load balancing layer in the Web Servers
// jvmRoute == the name of the JVM inside the plugin.
protected String jvmRoute;
- // XXX used by forward to override, need a better
- // mechanism
- protected String requestURI;
- protected String queryString;
-
- // RequestAdapterImpl Hints
- protected String serverName=null;
+ protected Hashtable attributes = new Hashtable();
+ protected MimeHeaders headers;
protected Vector cookies = new Vector();
- protected String contextPath;
- protected String lookupPath; // everything after contextPath before ?
- protected String servletPath;
- protected String pathInfo;
- protected String pathTranslated;
- // Need to distinguish between null pathTranslated and
- // lazy-computed pathTranlsated
- protected boolean pathTranslatedIsSet=false;
-
+ // Processed information ( redundant ! )
protected Hashtable parameters = new Hashtable();
+
+
protected int contentLength = -1;
protected String contentType = null;
protected String charEncoding = null;
+ protected String serverName=null;
+
+ // auth infor
protected String authType;
boolean notAuthenticated=true;
protected String remoteUser;
-
protected Principal principal;
// active roles for the current user
protected String userRoles[];
protected String reqRoles[];
- // Request
+ // Association with other tomcat comp.
protected Response response;
- protected HttpServletRequest requestFacade;
- protected Context context;
protected ContextManager contextM;
- protected Hashtable attributes = new Hashtable();
+ protected Context context;
protected boolean didReadFormData;
protected boolean didParameters;
protected boolean didCookies;
// end "Request" variables
+ // @deprecated
+ protected HttpServletRequest requestFacade;
+
// Session
// set by interceptors - the session id
protected String reqSessionId;
@@ -137,44 +148,54 @@
// cache- avoid calling SessionManager for each getSession()
protected HttpSession serverSession;
-
- // LookupResult - used by sub-requests and
- // set by interceptors
- protected String servletName;
protected Handler handler = null;
Container container;
- protected String mappedPath = null;
-
- protected String scheme;
- protected String method;
- protected String protocol;
- protected MimeHeaders headers;
protected ServletInputStream in;
-
- protected int serverPort;
- protected String remoteAddr;
- protected String remoteHost;
- protected String localHost;
- protected ByteBuffer bBuffer;
+ // sub-request support
Request top;
Request parent;
Request child;
+ // ResourceBundle
protected static StringManager sm =
StringManager.getManager("org.apache.tomcat.core");
+ // @deprecated
+ protected String method;
+ protected String requestURI;
+ protected String queryString;
+ protected String protocol;
+ protected String servletName;
+
+ protected String mappedPath = null;
+ protected String contextPath;
+ protected String lookupPath; // everything after contextPath before ?
+ protected String servletPath;
+ protected String pathInfo;
+ protected String pathTranslated;
+ // Need to distinguish between null pathTranslated and
+ // lazy-computed pathTranlsated
+ protected boolean pathTranslatedIsSet=false;
+
public RequestImpl() {
- // log("XXX new ri " );
headers = new MimeHeaders();
recycle(); // XXX need better placement-super()
}
+ /** Called by mapper interceptors after the context
+ is found or directly by server adapters when
+ this is known in advance
+ */
public void setContext(Context context) {
this.context = context;
}
+ public Context getContext() {
+ return context;
+ }
+
public void setContextManager( ContextManager cm ) {
contextM=cm;
}
@@ -183,8 +204,16 @@
return contextM;
}
+ public MessageBytes getSchemeMB() {
+ return schemeMB;
+ }
+
public String getScheme() {
- return scheme;
+ return schemeMB.toString();
+ }
+
+ public void setScheme( String scheme ) {
+ schemeMB.setString(scheme);
}
public String getMethod() {
@@ -294,6 +323,7 @@
return contentType;
}
+
/** All adapters that know the PT needs to call this method,
in order to set pathTranslatedIsSet, otherwise tomcat
will try to compute it again
@@ -347,7 +377,7 @@
public boolean isSecure() {
// The adapter is responsible for providing this information
- return getScheme().equalsIgnoreCase("HTTPS");
+ return schemeMB.equalsIgnoreCase("HTTPS");
}
public void setUserPrincipal( Principal p ) {
@@ -414,10 +444,6 @@
return requestFacade;
}
- public Context getContext() {
- return context;
- }
-
public void setResponse(Response response) {
this.response = response;
}
@@ -468,7 +494,7 @@
// context.log("RequestImpl: created new session!");
contextM.doNewSessionRequest( this, response );
if ( serverSession == null ) {
- log("RequestImpl: no session created!");
+ // context.log("RequestImpl: no session created!");
return null;
}
@@ -712,7 +738,6 @@
container=null;
handler=null;
jvmRoute = null;
- scheme = "http";// no need to use Constants
method = "GET";
requestURI="/";
queryString=null;
@@ -730,7 +755,6 @@
remoteAddr="127.0.0.1";
remoteHost="localhost";
localHost="localhost";
- if( bBuffer != null ) bBuffer.recycle();
for( int i=0; i<ACCOUNTS; i++ ) accTable[i]=0;
for( int i=0; i<ContextManager.MAX_NOTES; i++ ) notes[i]=null;
parent=null;
@@ -740,6 +764,16 @@
userRoles=null;
reqRoles=null;
in=null;
+
+ uriMB.recycle();
+ contextMB.recycle();
+ pathInfoMB.recycle();
+ servletPathMB.recycle();
+ queryMB.recycle();
+ methodMB.recycle();
+ protoMB.recycle();
+ schemeMB.setString("http");
+
}
public MimeHeaders getMimeHeaders() {
@@ -754,15 +788,6 @@
return headers.names();
}
- public ByteBuffer getInputBuffer() {
- return bBuffer;
- }
-
- public void setInputBuffer(ByteBuffer buf) {
- bBuffer=buf;
- }
-
-
public ServletInputStream getInputStream() throws IOException {
// will be removed from here
return getFacade().getInputStream();
@@ -815,10 +840,6 @@
return null;
}
- public void setScheme( String scheme ) {
- this.scheme=scheme;
- }
-
public void setMethod( String method ) {
this.method=method;
}
@@ -831,10 +852,6 @@
this.headers=headers;
}
- public void setBody( StringBuffer body ) {
- // ???
- }
-
public void setServerPort(int serverPort ) {
this.serverPort=serverPort;
}
@@ -872,18 +889,6 @@
return sb.toString();
}
- public String toStringDebug() {
- StringBuffer sb=new StringBuffer();
- sb.append( "Request( " + context ).append("\n");
- sb.append( " URI:" + getRequestURI() ).append("\n");
- sb.append( " SP:" + getServletPath() );
- sb.append( ",PI:" + getPathInfo() );
- sb.append( ",LP:" + getLookupPath() );
- sb.append( ",MP:" + getMappedPath() );
- sb.append( "," + getWrapper() +") ");
- return sb.toString();
- }
-
// -------------------- Accounting --------------------
// XXX Will be implemented as a note !
public static final int ACC_PRE_CMAP=0;
@@ -905,7 +910,7 @@
return accTable[pos];
}
- // -------------------- Per-Container "notes"
+ // -------------------- Per-Request "notes"
Object notes[]=new Object[ContextManager.MAX_NOTES];
public void setNote( int pos, Object value ) {
@@ -916,19 +921,4 @@
return notes[pos];
}
- Logger.Helper loghelper = new Logger.Helper("tc_log", this);
-
- protected void log(String s) {
- log(s, null);
- }
- protected void log(String s, Throwable t) {
- if (context != null) {
- loghelper.setLogger(context.getLoggerHelper().getLogger());
- }
- else if (contextM != null) {
- loghelper.setLogger(contextM.getLoggerHelper().getLogger());
- }
- loghelper.log(s);
- }
-
}
1.25 +19 -25 jakarta-tomcat/src/share/org/apache/tomcat/core/Response.java
Index: Response.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Response.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- Response.java 2000/08/02 02:17:12 1.24
+++ Response.java 2000/08/11 06:14:07 1.25
@@ -100,23 +100,23 @@
*/
public boolean isStarted() ;
- /** True if getOutputStream was called.
- * Used to avoid the ugly try getWriter() catch getOutputStream.
- */
- public boolean isUsingStream();
-
- /** The output stream is used.
- */
- public void setUsingStream( boolean stream );
-
- /** Stream/Writer control
- */
- public boolean isUsingWriter();
+// /** True if getOutputStream was called.
+// * Used to avoid the ugly try getWriter() catch getOutputStream.
+// */
+// public boolean isUsingStream();
+
+// /** The output stream is used.
+// */
+// public void setUsingStream( boolean stream );
+
+// /** Stream/Writer control
+// */
+// public boolean isUsingWriter();
+
+// /** Stream/Writer control
+// */
+// public void setUsingWriter( boolean writer );
- /** Stream/Writer control
- */
- public void setUsingWriter( boolean writer );
-
/** Signal that we're done with a particular request, the
* server can go on and read more requests or close the socket
@@ -126,14 +126,14 @@
/** Either re-implement getOutputStream or return BufferedServletOutputStream(this)
* and implement doWrite();
*/
- public ServletOutputStream getOutputStream() throws IOException;
+// public ServletOutputStream getOutputStream() throws IOException;
public void setServletOutputStream(ServletOutputStream s );
- public void setWriter( PrintWriter w );
+// public void setWriter( PrintWriter w );
public void doWrite( byte buffer[], int pos, int count) throws IOException;
- public PrintWriter getWriter() throws IOException ;
+// public PrintWriter getWriter() throws IOException ;
/** True if we are in an included servlet
*/
@@ -211,12 +211,6 @@
public OutputBuffer getBuffer();
- // @deprecated
- // public ByteBuffer getOutputBuffer();
-
- // public void setOutputBuffer(ByteBuffer buf);
-
-
// -------------------- Internal methods --------------------
/** One-to-one with Facade.
* You can use HttpResponseFacade.
1.38 +77 -57 jakarta-tomcat/src/share/org/apache/tomcat/core/ResponseImpl.java
Index: ResponseImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ResponseImpl.java,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- ResponseImpl.java 2000/08/02 02:17:12 1.37
+++ ResponseImpl.java 2000/08/11 06:14:07 1.38
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ResponseImpl.java,v 1.37 2000/08/02 02:17:12 costin Exp $
- * $Revision: 1.37 $
- * $Date: 2000/08/02 02:17:12 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ResponseImpl.java,v 1.38 2000/08/11 06:14:07 costin Exp $
+ * $Revision: 1.38 $
+ * $Date: 2000/08/11 06:14:07 $
*
* ====================================================================
*
@@ -209,11 +209,12 @@
}
public void finish() throws IOException {
- if (usingWriter && (writer != null)) {
- writer.flush();
- writer.close();
- }
- oBuffer.flush();
+ // if (usingWriter && (writer != null)) {
+ // writer.flush();
+ // writer.close();
+ // }
+ oBuffer.flushChars();
+ oBuffer.flushBytes();
// if( bBuffer != null) {
// bBuffer.flush();
@@ -252,59 +253,61 @@
// if( out!=null ) out.setUsingWriter(true);
}
- public void setWriter( PrintWriter w ) {
- this.writer=w;
- }
+// public void setWriter( PrintWriter w ) {
+// this.writer=w;
+// }
- public PrintWriter getWriter() throws IOException {
- // usingWriter
- if( writer != null )
- return writer;
+// public PrintWriter getWriter() throws IOException {
+// // usingWriter
+// if( writer != null )
+// return writer;
- sos=getFacade().getOutputStream();
+// sos=getFacade().getOutputStream();
- writer=getWriter( sos );
+// writer=getWriter( sos );
- return writer;
+// return writer;
- // if( out !=null )
- // return getWriter( out );
+// // if( out !=null )
+// // return getWriter( out );
- // it will know what to do. This method is here
- // just to keep old code happy ( internal error handlers)
- //if( usingStream ) {
- // return getWriter( getFacade().getOutputStream());
- //}
- //return getFacade().getWriter();
- }
+// // it will know what to do. This method is here
+// // just to keep old code happy ( internal error handlers)
+// //if( usingStream ) {
+// // return getWriter( getFacade().getOutputStream());
+// //}
+// //return getFacade().getWriter();
+// }
- public PrintWriter getWriter(ServletOutputStream outs) throws IOException {
- if(writer!=null) return writer;
- // it already did all the checkings
+// public PrintWriter getWriter(ServletOutputStream outs) throws IOException {
- started = true;
- usingWriter = true;
+// if(writer!=null) return writer;
+// // it already did all the checkings
- writer = new ServletWriterFacade( getConverter(outs), this);
- return writer;
- }
-
- public Writer getConverter( ServletOutputStream outs ) throws IOException {
- String encoding = getCharacterEncoding();
+// started = true;
+// usingWriter = true;
+
+// // writer = new ServletWriterFacade( getConverter(outs), this);
+// writer = new ServletWriterFacade( oBuffer, this);
+// return writer;
+// }
- if (encoding == null) {
- // use default platform encoding - is this correct ?
- return new OutputStreamWriter(outs);
- } else {
- try {
- return new OutputStreamWriter(outs, encoding);
- } catch (java.io.UnsupportedEncodingException ex) {
- log("Unsuported encoding: " + encoding, Logger.ERROR );
+// public Writer getConverter( ServletOutputStream outs ) throws IOException {
+// String encoding = getCharacterEncoding();
- return new OutputStreamWriter(outs);
- }
- }
- }
+// if (encoding == null) {
+// // use default platform encoding - is this correct ?
+// return new OutputStreamWriter(outs);
+// } else {
+// try {
+// return new OutputStreamWriter(outs, encoding);
+// } catch (java.io.UnsupportedEncodingException ex) {
+// log("Unsuported encoding: " + encoding, Logger.ERROR );
+
+// return new OutputStreamWriter(outs);
+// }
+// }
+// }
public OutputBuffer getBuffer() {
return oBuffer;
@@ -347,14 +350,22 @@
public void setHeader(String name, String value) {
if( ! notIncluded ) return; // we are in included sub-request
- if( ! checkSpecialHeader(name, value) )
- headers.putHeader(name, value);
+ char cc=name.charAt(0);
+ if( cc=='C' || cc=='c' ) {
+ if( checkSpecialHeader(name, value) )
+ return;
+ }
+ headers.putHeader(name, value);
}
public void addHeader(String name, String value) {
if( ! notIncluded ) return; // we are in included sub-request
- if( ! checkSpecialHeader(name, value) )
- headers.addHeader(name, value);
+ char cc=name.charAt(0);
+ if( cc=='C' || cc=='c' ) {
+ if( checkSpecialHeader(name, value) )
+ return;
+ }
+ headers.addHeader(name, value);
}
@@ -471,10 +482,11 @@
public void flushBuffer() throws IOException {
// if( notIncluded) {
- if (usingWriter == true && writer != null)
- writer.flush();
+ // if (usingWriter == true && writer != null)
+ // writer.flush();
- oBuffer.flush();
+ oBuffer.flushChars();
+ oBuffer.flushBytes();
// if( out!=null ) out.reallyFlush();
// if(bBuffer!=null) bBuffer.flush();
//}
@@ -634,6 +646,8 @@
static String st_200=null;
static String st_302=null;
+ static String st_400=null;
+ static String st_404=null;
// utility method - should be in a different class
public static String getMessage( int status ) {
@@ -647,6 +661,12 @@
case 302:
if( st_302==null ) st_302=sm.getString( "sc.302");
return st_302;
+ case 400:
+ if( st_400==null ) st_400=sm.getString( "sc.400");
+ return st_400;
+ case 404:
+ if( st_404==null ) st_404=sm.getString( "sc.404");
+ return st_404;
}
return sm.getString("sc."+ status);
}
1.12 +13 -10 jakarta-tomcat/src/share/org/apache/tomcat/facade/HttpServletResponseFacade.java
Index: HttpServletResponseFacade.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/facade/HttpServletResponseFacade.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- HttpServletResponseFacade.java 2000/08/02 02:17:25 1.11
+++ HttpServletResponseFacade.java 2000/08/11 06:14:09 1.12
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/facade/HttpServletResponseFacade.java,v 1.11 2000/08/02 02:17:25 costin Exp $
- * $Revision: 1.11 $
- * $Date: 2000/08/02 02:17:25 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/facade/HttpServletResponseFacade.java,v 1.12 2000/08/11 06:14:09 costin Exp $
+ * $Revision: 1.12 $
+ * $Date: 2000/08/11 06:14:09 $
*
* ====================================================================
*
@@ -103,7 +103,7 @@
void recycle() {
usingStream = false;
usingWriter= false;
- writer=null;
+ // writer=null; // no need - the OutputBuffer will deal with enc
if( osFacade != null ) osFacade.recycle();
}
@@ -160,12 +160,12 @@
throw new IllegalStateException(msg);
}
usingStream=true;
- response.setUsingStream( true );
+ // response.setUsingStream( true );
if( osFacade!=null) return osFacade;
//if( response.getOutputBuffer() != null ) {
osFacade=new ServletOutputStreamFacade(response);
- response.setServletOutputStream( osFacade );
+ // response.setServletOutputStream( osFacade );
//}
return osFacade;
@@ -180,7 +180,7 @@
throw new IllegalStateException(msg);
}
usingWriter= true ;
- response.setUsingWriter( true );
+ // response.setUsingWriter( true );
// old mechanism
// if( osFacade==null && response.getOutputBuffer() == null )
@@ -191,9 +191,12 @@
osFacade=new ServletOutputStreamFacade(response);
}
- writer=((ResponseImpl)response).getWriter( osFacade );
- response.setServletOutputStream( osFacade );
- response.setWriter( writer );
+ OutputBuffer oBuffer= response.getBuffer();
+ writer = new ServletWriterFacade( oBuffer, response);
+
+ // writer=((ResponseImpl)response).getWriter( osFacade );
+ // response.setServletOutputStream( osFacade );
+ // response.setWriter( writer );
return writer;
}
1.7 +22 -66 jakarta-tomcat/src/share/org/apache/tomcat/facade/ServletOutputStreamFacade.java
Index: ServletOutputStreamFacade.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/facade/ServletOutputStreamFacade.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ServletOutputStreamFacade.java 2000/07/31 02:35:16 1.6
+++ ServletOutputStreamFacade.java 2000/08/11 06:14:09 1.7
@@ -70,18 +70,10 @@
*
*/
final class ServletOutputStreamFacade extends ServletOutputStream {
- // Use the strings from core
- protected StringManager sm = StringManager.
- getManager("org.apache.tomcat.core");
-
- // encoding
- private Writer writer=null;
-
protected boolean closed = false;
Response resA;
OutputBuffer ob;
- //ByteBuffer bb;
/** Encoding - first time print() is used.
IMPORTANT: print() is _bad_, if you want to write Strings and mix
@@ -96,15 +88,12 @@
protected ServletOutputStreamFacade( Response resA) {
this.resA=resA;
ob=resA.getBuffer();
- // bb=resA.getOutputBuffer();
- // bb.addBufferListener( new BufferResponseAdapter());
}
// -------------------- Write methods --------------------
public void write(int i) throws IOException {
- // bb.write(i);
- ob.write(i);
+ ob.writeByte(i);
}
public void write(byte[] b) throws IOException {
@@ -112,7 +101,6 @@
}
public void write(byte[] b, int off, int len) throws IOException {
- // bb.write( b, off, len );
ob.write( b, off, len );
}
@@ -128,37 +116,36 @@
Please use getWriter() if you want to send strings.
*/
public void print(String s) throws IOException {
- if (s==null) s="null";
- byte b[]=null;
- if( !gotEnc ) {
- enc = resA.getCharacterEncoding();
- gotEnc=true;
- if ( Constants.DEFAULT_CHAR_ENCODING.equals(enc) )
- enc=null;
- }
- if( enc==null)
- b=s.getBytes();
- else
- try {
- b=s.getBytes( enc );
- } catch (java.io.UnsupportedEncodingException ex) {
- b=s.getBytes();
- enc=null;
- }
+// if (s==null) s="null";
+// byte b[]=null;
+// if( !gotEnc ) {
+// enc = resA.getCharacterEncoding();
+// gotEnc=true;
+// if ( Constants.DEFAULT_CHAR_ENCODING.equals(enc) )
+// enc=null;
+// }
+// if( enc==null)
+// b=s.getBytes();
+// else
+// try {
+// b=s.getBytes( enc );
+// } catch (java.io.UnsupportedEncodingException ex) {
+// b=s.getBytes();
+// enc=null;
+// }
- write( b );
+// write( b );
+ ob.write(s);
}
/** Will send the buffer to the client.
*/
public void flush() throws IOException {
- // bb.flush(); // send it now !
- ob.flush();
+ ob.flushBytes();
}
public void close() throws IOException {
- // bb.flush(); // send it now !
- ob.flush();
+ ob.flushBytes();
closed = true;
}
@@ -166,40 +153,9 @@
* Called from BSOS
*/
void recycle() {
- writer=null;
closed = false;
enc=null;
gotEnc=false;
}
-
-// // -------------------- ByteBuffer
-// // Initial experimental support - this will change.
-// // This is an adapter between ByteBuffer and server adapters implementing
-// // doWrite
-// class BufferResponseAdapter implements BufferListener {
-// BufferResponseAdapter() {
-// }
-
-// public void bufferEmpty( BufferEvent ev ) {
-// return;
-// }
-
-// public void bufferFull( BufferEvent ev ) {
-// try {
-// // Find if this is the first chunk , if so do send head
-// // log( "Buffer full event ");
-// ByteBuffer bb=(ByteBuffer)ev.getSource();
-// Response res=(Response)bb.getParent();
-// Request request=res.getRequest();
-// request.getContextManager().doWrite( request, res,
-// ev.getByteBuffer(),
-// ev.getOffset(),
-// ev.getLength() );
-// } catch( IOException ex ) {
-// ex.printStackTrace();
-// // XXX mark exception ?
-// }
-// }
-// }
}
1.4 +4 -26 jakarta-tomcat/src/share/org/apache/tomcat/facade/ServletWriterFacade.java
Index: ServletWriterFacade.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/facade/ServletWriterFacade.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ServletWriterFacade.java 2000/06/30 20:21:34 1.3
+++ ServletWriterFacade.java 2000/08/11 06:14:09 1.4
@@ -80,56 +80,34 @@
// XXX hack - public will be removed after we add the CharBuffer and we fix the converter
public final class ServletWriterFacade extends PrintWriter {
Response resA;
- RequestImpl req;
- static final boolean ACCT=false;// a smart compiler will remove all in/out
+ OutputBuffer ob;
- public ServletWriterFacade( Writer w, Response resp ) {
- super( w );
+ public ServletWriterFacade( OutputBuffer ob, Response resp ) {
+ super( ob );
this.resA=resp;
- req=(RequestImpl)resA.getRequest();
+ this.ob=ob;
}
// -------------------- Write methods --------------------
public void flush() {
- if( ACCT ) in();
super.flush();
- if( ACCT ) out();
}
public void print( String str ) {
- if( ACCT ) in();
super.print( str );
- if( ACCT ) out();
}
public void println( String str ) {
- if( ACCT ) in();
super.println( str );
- if( ACCT ) out();
}
public void write( char buf[], int offset, int count ) {
- if( ACCT ) in();
super.write( buf, offset, count );
- if( ACCT ) out();
}
public void write( String str ) {
- if( ACCT ) in();
super.write( str );
- if( ACCT ) out();
- }
-
- private void in() {
- req.setAccount( RequestImpl.ACC_IN_OUT, System.currentTimeMillis() );
- }
-
- private void out() {
- long l=System.currentTimeMillis();
- long l1=req.getAccount( RequestImpl.ACC_IN_OUT);
- long l3=req.getAccount( RequestImpl.ACC_OUT_COUNT);
- req.setAccount( RequestImpl.ACC_OUT_COUNT, l - l1 + l3 );
}
/** Reuse the object instance, avoid GC
1.17 +15 -12 jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java
Index: AccessInterceptor.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- AccessInterceptor.java 2000/08/05 16:01:20 1.16
+++ AccessInterceptor.java 2000/08/11 06:14:11 1.17
@@ -329,6 +329,7 @@
}
class BasicAuthHandler extends Handler {
+ int sbNote=0;
BasicAuthHandler() {
initialized=true;
@@ -349,22 +350,24 @@
// and notify the user they are not authorized if BasicAuth fails
res.setContentType("text/html"); // ISO-8859-1 default
- StringBuffer buf = new StringBuffer();
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "BasicAuthHandler.buff");
+ }
+
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
buf.append("<html><head><title>Not Authorized</title></head>");
buf.append("<body>Not Authorized</body></html>");
- String body = buf.toString();
+
res.setContentLength(buf.length());
-
- if( res.isUsingStream() ) {
- ServletOutputStream out = res.getOutputStream();
- out.print(body);
- out.flush();
- } else {
- PrintWriter out = res.getWriter();
- out.print(body);
- out.flush();
- }
+ res.getBuffer().write( buf );
}
}
1.17 +10 -1 jakarta-tomcat/src/share/org/apache/tomcat/request/SimpleMapper1.java
Index: SimpleMapper1.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/SimpleMapper1.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- SimpleMapper1.java 2000/07/11 03:48:51 1.16
+++ SimpleMapper1.java 2000/08/11 06:14:11 1.17
@@ -255,7 +255,16 @@
throw new RuntimeException("ASSERT: ? in requestURI");
try {
- String host=req.getServerName();
+ String host=null;
+
+// MimeHeaders headers=req.getMimeHeaders();
+// MimeHeaderField hostH=headers.find("host");
+
+ host=req.getServerName();
+
+// if( hostH==null ) host=req.getLocalHost();
+// if(hostH==null) host="localhost";
+
if(debug>0) cm.log("Host = " + host);
Container container =(Container)map.getLongestPrefixMatch( host,
1.12 +23 -27 jakarta-tomcat/src/share/org/apache/tomcat/request/StaticInterceptor.java
Index: StaticInterceptor.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/StaticInterceptor.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- StaticInterceptor.java 2000/08/02 02:17:27 1.11
+++ StaticInterceptor.java 2000/08/11 06:14:11 1.12
@@ -270,24 +270,13 @@
try {
in = new FileInputStream(file);
- if( res.isUsingWriter() ) {
- InputStreamReader r = new InputStreamReader(in);
- PrintWriter out=res.getWriter();
- char[] buf = new char[1024];
- int read = 0;
-
- while ((read = r.read(buf)) != -1) {
- out.write(buf, 0, read);
- }
- } else {
- OutputStream out=res.getOutputStream();
- byte[] buf = new byte[1024];
- int read = 0;
-
- while ((read = in.read(buf)) != -1) {
- out.write(buf, 0, read);
- }
- }
+ OutputBuffer out=res.getBuffer();
+ byte[] buf = new byte[1024];
+ int read = 0;
+
+ while ((read = in.read(buf)) != -1) {
+ out.write(buf, 0, read);
+ }
} catch (FileNotFoundException e) {
// Figure out what we're serving
context.getContextManager().handleStatus( req, res, 404);
@@ -342,6 +331,7 @@
class DirHandler extends Handler {
private static final String datePattern = "EEE, dd MMM yyyyy HH:mm z";
int realFileNote;
+ int sbNote=0;
DirHandler() {
initialized=true;
@@ -385,8 +375,19 @@
}
}
- StringBuffer buf = new StringBuffer();
-
+ if( sbNote==0 ) {
+ sbNote=req.getContextManager().getNoteId(ContextManager.REQUEST_NOTE,
+ "RedirectHandler.buff");
+ }
+
+ // we can recycle it because
+ // we don't call toString();
+ StringBuffer buf=(StringBuffer)req.getNote( sbNote );
+ if( buf==null ) {
+ buf = new StringBuffer();
+ req.setNote( sbNote, buf );
+ }
+
if (! inInclude) {
res.setContentType("text/html");
buf.append("<html>\r\n");
@@ -538,13 +539,8 @@
if (! inInclude) buf.append("</body></html>\r\n");
- if( res.isUsingWriter() ) {
- PrintWriter out=res.getWriter();
- out.print(buf);
- } else {
- ServletOutputStream out=res.getOutputStream();
- out.print(buf.toString());
- }
+ res.getBuffer().write(buf);
+ buf.setLength(0);
}
void displaySize( StringBuffer buf, int filesize ) {
1.31 +30 -23 jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp12ConnectionHandler.java
Index: Ajp12ConnectionHandler.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp12ConnectionHandler.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- Ajp12ConnectionHandler.java 2000/07/29 18:25:18 1.30
+++ Ajp12ConnectionHandler.java 2000/08/11 06:14:13 1.31
@@ -181,6 +181,12 @@
boolean isPing=false;
boolean doLog;
+ // Debug only - use only to debug this component
+ void d( String s ) {
+ System.out.print("Ajp12RequestAdapter: ");
+ System.out.println( s );
+ }
+
public int doRead() throws IOException {
return ajpin.read();
}
@@ -233,55 +239,55 @@
// combination to hang with a 404!!!
// if("ROOT".equals( contextPath ) ) contextPath="";
if("ROOT".equalsIgnoreCase( contextPath ) ) contextPath=null;
- if( doLog ) log("AJP: CP=" + contextPath);
+ if( doLog ) d("AJP: CP=" + contextPath);
if( contextPath!= null )
context=contextM.getContext( contextPath );
- if( doLog ) log("AJP: context=" + context );
+ if( doLog ) d("AJP: context=" + context );
servletName = readString(ajpin, null); //Servlet
- if( doLog ) log("AJP: servlet=" + servletName );
+ if( doLog ) d("AJP: servlet=" + servletName );
serverName = readString(ajpin, null); //Server hostname
- if( doLog ) log("AJP: serverName=" + serverName );
+ if( doLog ) d("AJP: serverName=" + serverName );
dummy = readString(ajpin, null); //Apache document root
pathInfo = readString(ajpin, null); //Apache parsed path-info
- if( doLog ) log("AJP: PI=" + pathInfo );
+ if( doLog ) d("AJP: PI=" + pathInfo );
// XXX Bug in mod_jserv !!!!!
pathTranslated = readString(ajpin, null); //Apache parsed path-translated
- if( doLog ) log("AJP: PT=" + pathTranslated );
+ if( doLog ) d("AJP: PT=" + pathTranslated );
queryString = readString(ajpin, null); //query string
- if( doLog ) log("AJP: QS=" + queryString );
+ if( doLog ) d("AJP: QS=" + queryString );
remoteAddr = readString(ajpin, ""); //remote address
- if( doLog ) log("AJP: RA=" + remoteAddr );
+ if( doLog ) d("AJP: RA=" + remoteAddr );
remoteHost = readString(ajpin, ""); //remote host
- if( doLog ) log("AJP: RH=" + remoteHost );
+ if( doLog ) d("AJP: RH=" + remoteHost );
remoteUser = readString(ajpin, null); //remote user
- if( doLog ) log("AJP: RU=" + remoteUser);
+ if( doLog ) d("AJP: RU=" + remoteUser);
authType = readString(ajpin, null); //auth type
- if( doLog ) log("AJP: AT=" + authType);
+ if( doLog ) d("AJP: AT=" + authType);
dummy = readString(ajpin, null); //remote port
method = readString(ajpin, null); //request method
- if( doLog ) log("AJP: Meth=" + method );
+ if( doLog ) d("AJP: Meth=" + method );
requestURI = readString(ajpin, ""); //request uri
- if( doLog ) log("AJP: URI: " + requestURI + " CP:" + contextPath + " LP: " + lookupPath);
+ if( doLog ) d("AJP: URI: " + requestURI + " CP:" + contextPath + " LP: " + lookupPath);
// XXX don't set lookup path - problems with URL rewriting.
// need to be fixed.
// if(contextPath!=null && contextPath.length() >0 )
// lookupPath=requestURI.substring( contextPath.length() + 1 );
- if( doLog ) log("AJP: URI: " + requestURI + " CP:" + contextPath + " LP: " + lookupPath);
+ if( doLog ) d("AJP: URI: " + requestURI + " CP:" + contextPath + " LP: " + lookupPath);
dummy = readString(ajpin, null); //script filename
// System.out.println("AJP: Script filen=" + dummy);
@@ -290,7 +296,7 @@
// System.out.println("AJP: Script name=" + dummy);
serverName = readString(ajpin, ""); //server name
- if( doLog ) log("AJP: serverName=" + serverName );
+ if( doLog ) d("AJP: serverName=" + serverName );
try {
serverPort = Integer.parseInt(readString(ajpin, "80")); //server port
} catch (Exception any) {
@@ -307,7 +313,7 @@
if(jvmRoute.length() == 0) {
jvmRoute = null;
}
- if( doLog ) log("AJP: Server jvmRoute=" + jvmRoute);
+ if( doLog ) d("AJP: Server jvmRoute=" + jvmRoute);
/**
@@ -370,7 +376,7 @@
socket.getOutputStream().write(0); // PING reply
sin.close();
} catch (IOException ignored) {
- log("Exception closing, ignored", ignored);
+ contextM.log("Exception closing, ignored", ignored);
}
isPing = true;
return;
@@ -394,7 +400,8 @@
return;
}
} catch (Exception ignored) {
- log("Ignored exception processing signal " + signal, ignored);
+ contextM.log("Ignored exception processing signal " +
+ signal, ignored);
}
}
return;
@@ -417,21 +424,21 @@
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
- log("Uncaught exception handling request", e);
+ contextM.log("Uncaught exception handling request", e);
}
// REQUEST_URI includes query string
int indexQ=requestURI.indexOf("?");
int rLen=requestURI.length();
if ( (indexQ >-1) && ( indexQ < rLen) ) {
- if(doLog) log("Orig QS " + queryString );
+ if(doLog) d("Orig QS " + queryString );
queryString = requestURI.substring(indexQ + 1, requestURI.length());
- if(doLog) log("New QS " + queryString );
+ if(doLog) d("New QS " + queryString );
requestURI = requestURI.substring(0, indexQ);
}
- if( doLog ) log("Request: " + requestURI );
- if( doLog ) log ("Query: " + queryString );
+ if( doLog ) d("Request: " + requestURI );
+ if( doLog ) d("Query: " + queryString );
// System.out.println("ENV: " + env_vars );
// System.out.println("HEADERS: " + headers_in );
// System.out.println("PARAMETERS: " + parameters );
1.8 +4 -5 jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp13ConnectorRequest.java
Index: Ajp13ConnectorRequest.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp13ConnectorRequest.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Ajp13ConnectorRequest.java 2000/07/29 18:44:01 1.7
+++ Ajp13ConnectorRequest.java 2000/08/11 06:14:13 1.8
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp13ConnectorRequest.java,v 1.7 2000/07/29 18:44:01 costin Exp $
- * $Revision: 1.7 $
- * $Date: 2000/07/29 18:44:01 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/Ajp13ConnectorRequest.java,v 1.8 2000/08/11 06:14:13 costin Exp $
+ * $Revision: 1.8 $
+ * $Date: 2000/08/11 06:14:13 $
*
* ====================================================================
*
@@ -179,7 +179,7 @@
break;
case SC_A_SERVLET_PATH :
- log("SC_A_SERVLET_PATH not in use " + msg.getString());
+ //log("SC_A_SERVLET_PATH not in use " + msg.getString());
break;
case SC_A_REMOTE_USER :
@@ -261,7 +261,6 @@
for(int i = off ; i < (len + off) ; i++) {
int a = doRead();
if(-1 == a) {
- log("Y");
return i-off;
}
b[i] = (byte)a;
1.12 +5 -5 jakarta-tomcat/src/share/org/apache/tomcat/service/connector/JNIConnectionHandler.java
Index: JNIConnectionHandler.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/JNIConnectionHandler.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- JNIConnectionHandler.java 2000/07/29 18:44:01 1.11
+++ JNIConnectionHandler.java 2000/08/11 06:14:13 1.12
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/JNIConnectionHandler.java,v 1.11 2000/07/29 18:44:01 costin Exp $
- * $Revision: 1.11 $
- * $Date: 2000/07/29 18:44:01 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/connector/JNIConnectionHandler.java,v 1.12 2000/08/11 06:14:13 costin Exp $
+ * $Revision: 1.12 $
+ * $Date: 2000/08/11 06:14:13 $
*
* ====================================================================
*
@@ -264,11 +264,11 @@
serverPort = Integer.parseInt(env[6]);
authType = env[7];
remoteUser = env[8];
- scheme = env[9];
+ schemeMB.setString(env[9]);
protocol = env[10];
// response.setServerHeader(env[11]);
- if(scheme.equalsIgnoreCase("https")) {
+ if(schemeMB.equalsIgnoreCase("https")) {
if(null != env[12]) {
attributes.put("javax.servlet.request.X509Certificate",
env[12]);
1.22 +43 -15 jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpRequestAdapter.java
Index: HttpRequestAdapter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpRequestAdapter.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- HttpRequestAdapter.java 2000/07/29 18:44:03 1.21
+++ HttpRequestAdapter.java 2000/08/11 06:14:15 1.22
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpRequestAdapter.java,v 1.21 2000/07/29 18:44:03 costin Exp $
- * $Revision: 1.21 $
- * $Date: 2000/07/29 18:44:03 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpRequestAdapter.java,v 1.22 2000/08/11 06:14:15 costin Exp $
+ * $Revision: 1.22 $
+ * $Date: 2000/08/11 06:14:15 $
*
* ====================================================================
*
@@ -344,6 +344,7 @@
return -1;
}
+
private void processRequestLine(Response response)
throws IOException
{
@@ -372,34 +373,61 @@
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
-
- method= new String( buf, startMethod, endMethod - startMethod );
+ methodMB.setBytes( buf, startMethod, endMethod - startMethod );
+ method=null;
+ if( Ascii.toLower( buf[startMethod]) == 'g' ) {
+ if( methodMB.equalsIgnoreCase( "get" ))
+ method="GET";
+ }
+ if( Ascii.toLower( buf[startMethod]) == 'p' ) {
+ if( methodMB.equalsIgnoreCase( "post" ))
+ method="POST";
+ if( methodMB.equalsIgnoreCase( "put" ))
+ method="PUT";
+ }
+
+ if( method==null )
+ method= new String( buf, startMethod, endMethod - startMethod );
+
+ protocol=null;
if( endReq < 0 ) {
- protocol=null;
endReq=count;
} else {
if( endProto < 0 ) endProto = count;
- protocol=new String( buf, startProto, endProto-startProto );
+ protoMB.setBytes( buf, startProto, endProto-startProto);
+ if( protoMB.equalsIgnoreCase( "http/1.0" ))
+ protocol="HTTP/1.0";
+ if( protoMB.equalsIgnoreCase( "http/1.1" ))
+ protocol="HTTP/1.1";
+
+ if( protocol==null)
+ protocol=new String( buf, startProto, endProto-startProto );
}
int qryIdx= findChar( '?', startReq, endReq );
if( qryIdx <0 ) {
- requestURI = new String( buf, startReq, endReq - startReq );
+ uriMB.setBytes(buf, startReq, endReq - startReq );
+ //= new String( buf, startReq, endReq - startReq );
} else {
- requestURI = new String( buf, startReq, qryIdx - startReq );
- queryString = new String( buf, qryIdx+1, endReq - qryIdx -1 );
+ uriMB.setBytes( buf, startReq, qryIdx - startReq );
+ queryMB.setBytes( buf, qryIdx+1, endReq - qryIdx -1 );
}
+ // temp. fix until the rest of the code is changed
+ requestURI=uriMB.toString();
+ queryString=queryMB.toString();
+
// Perform URL decoding only if necessary
- if ((requestURI != null) &&
- ((requestURI.indexOf('%') >= 0) || (requestURI.indexOf('+') >= 0))) {
+ if ((uriMB.indexOf('%') >= 0) || (uriMB.indexOf('+') >= 0)) {
try {
- requestURI = RequestUtil.URLDecode(requestURI);
+ // XXX rewrite URLDecode to avoid allocation
+ requestURI = uriMB.toString();
+ requestURI = RequestUtil.URLDecode(requestURI);
} catch (Exception e) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
}
}
1.14 +7 -3 jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpResponseAdapter.java
Index: HttpResponseAdapter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpResponseAdapter.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- HttpResponseAdapter.java 2000/07/31 02:35:16 1.13
+++ HttpResponseAdapter.java 2000/08/11 06:14:15 1.14
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpResponseAdapter.java,v 1.13 2000/07/31 02:35:16 costin Exp $
- * $Revision: 1.13 $
- * $Date: 2000/07/31 02:35:16 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/service/http/HttpResponseAdapter.java,v 1.14 2000/08/11 06:14:15 costin Exp $
+ * $Revision: 1.14 $
+ * $Date: 2000/08/11 06:14:15 $
*
* ====================================================================
*
@@ -134,6 +134,10 @@
printHead("HTTP/1.0 ");
switch( status ) {
case 200: printHead("200");
+ break;
+ case 400: printHead("400");
+ break;
+ case 404: printHead("404");
break;
default:
1.3 +11 -3 jakarta-tomcat/src/share/org/apache/tomcat/util/ArrayEnumerator.java
Index: ArrayEnumerator.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/ArrayEnumerator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ArrayEnumerator.java 2000/06/16 17:59:10 1.2
+++ ArrayEnumerator.java 2000/08/11 06:14:18 1.3
@@ -70,24 +70,32 @@
Object array[];
int pos;
+ int end;
public ArrayEnumerator( Object array[] ) {
this.array=array;
pos=0;
+ end=array.length;
}
+
+ public ArrayEnumerator( Object array[], int start, int end ) {
+ this.array=array;
+ pos=start;
+ this.end=end;
+ }
public Object nextElement( ) {
synchronized( array ) {
- if( pos < array.length )
+ if( pos < end )
return array[ pos ++ ];
}
throw new NoSuchElementException( "No more elements: " +
- pos + " / " + array.length);
+ pos + " / " + end);
}
public boolean hasMoreElements() {
- return pos < array.length;
+ return pos < end;
}
}
1.5 +24 -40 jakarta-tomcat/src/share/org/apache/tomcat/util/Ascii.java
Index: Ascii.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Ascii.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Ascii.java 2000/05/24 18:57:10 1.4
+++ Ascii.java 2000/08/11 06:14:18 1.5
@@ -1,8 +1,4 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Ascii.java,v 1.4 2000/05/24 18:57:10 costin Exp $
- * $Revision: 1.4 $
- * $Date: 2000/05/24 18:57:10 $
- *
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -61,7 +57,6 @@
*
*/
-
package org.apache.tomcat.util;
/**
@@ -70,10 +65,7 @@
* @author dac@eng.sun.com
* @author James Todd [gonzo@eng.sun.com]
*/
-
-public class Ascii {
- static StringManager sm =
- StringManager.getManager("org.apache.tomcat.util");
+public final class Ascii {
/*
* Character translation tables.
*/
@@ -187,26 +179,20 @@
* @param len the length of the bytes
* @exception NumberFormatException if the integer format was invalid
*/
-
public static int parseInt(byte[] b, int off, int len)
throws NumberFormatException
{
int c;
if (b == null || len <= 0 || !isDigit(c = b[off++])) {
- String msg = sm.getString("ascii.parseInit.nfe", b);
- throw new NumberFormatException(msg);
+ throw new NumberFormatException();
}
int n = c - '0';
while (--len > 0) {
if (!isDigit(c = b[off++])) {
- StringManager sm =
- StringManager.getManager("org.apache.tomcat.util");
- String msg = sm.getString("ascii.parseInit.nfe", b);
-
- throw new NumberFormatException(msg);
+ throw new NumberFormatException();
}
n = n * 10 + c - '0';
}
@@ -214,31 +200,29 @@
return n;
}
- /**
- * Compares this message string to the specified subarray of bytes.
- * Case is ignored in the comparison.
- * @param b the bytes to compare
- * @param off the start offset of the bytes
- * @param len the length of the bytes
- * @return true if the comparison succeeded, false otherwise
- */
- public static boolean equalsIgnoreCase(String str, MessageBytes mB ) {
- byte[] b=mB.getBytes();
- int off=mB.getOffset();
- int len=mB.getLength();
- if (str != null) {
- String s = str;
- if (len != s.length()) {
- return false;
- }
- for (int i = 0; i < len; i++) {
- if (Ascii.toLower(b[off++]) != Ascii.toLower(s.charAt(i))) {
- return false;
- }
+ public static int parseInt(char[] b, int off, int len)
+ throws NumberFormatException
+ {
+ int c;
+
+ if (b == null || len <= 0 || !isDigit(c = b[off++])) {
+ throw new NumberFormatException();
+ }
+
+ int n = c - '0';
+
+ while (--len > 0) {
+ if (!isDigit(c = b[off++])) {
+ throw new NumberFormatException();
}
- return true;
+ n = n * 10 + c - '0';
}
- return false;
+
+ return n;
+ }
+
+ public static boolean equalsIgnoreCase(String str, MessageBytes mB ) {
+ return mB.equalsIgnoreCase( str );
}
1.4 +3 -6 jakarta-tomcat/src/share/org/apache/tomcat/util/DateTool.java
Index: DateTool.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/DateTool.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DateTool.java 2000/07/11 03:28:30 1.3
+++ DateTool.java 2000/08/11 06:14:18 1.4
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/DateTool.java,v 1.3 2000/07/11 03:28:30 alex Exp $
- * $Revision: 1.3 $
- * $Date: 2000/07/11 03:28:30 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/DateTool.java,v 1.4 2000/08/11 06:14:18 costin Exp $
+ * $Revision: 1.4 $
+ * $Date: 2000/08/11 06:14:18 $
*
* ====================================================================
*
@@ -79,9 +79,6 @@
* @author Costin Manolache
*/
public class DateTool {
-
- private static StringManager sm =
- StringManager.getManager("org.apache.tomcat.util");
/** US locale - all HTTP dates are in english
*/
1.6 +396 -159 jakarta-tomcat/src/share/org/apache/tomcat/util/MessageBytes.java
Index: MessageBytes.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/MessageBytes.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- MessageBytes.java 2000/05/24 18:57:10 1.5
+++ MessageBytes.java 2000/08/11 06:14:19 1.6
@@ -1,8 +1,4 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/MessageBytes.java,v 1.5 2000/05/24 18:57:10 costin Exp $
- * $Revision: 1.5 $
- * $Date: 2000/05/24 18:57:10 $
- *
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -61,62 +57,91 @@
*
*/
-
package org.apache.tomcat.util;
-import java.io.OutputStream;
-import java.io.IOException;
-import org.apache.tomcat.core.Constants;
+import java.text.*;
+import java.util.*;
/**
* This class is used to represent a subarray of bytes in an HTTP message.
*
* @author dac@eng.sun.com
* @author James Todd [gonzo@eng.sun.com]
+ * @author Costin Manolache
*/
-public class MessageBytes {
-
- private StringManager sm =
- StringManager.getManager("org.apache.tomcat.util");
-
- /**
- * The message bytes.
- */
- protected byte[] bytes;
-
- /**
- * The start offset of the bytes.
- */
- protected int offset;
-
+public final class MessageBytes implements Cloneable {
+ public static final String DEFAULT_CHAR_ENCODING="8859_1";
+
+ // primary type ( whatever is set as original value )
+ private int type = T_NULL;
+
+ public static final int T_NULL = 0;
+ public static final int T_STR = 1;
+ public static final int T_BYTES = 2;
+ public static final int T_CHARS = 3;
+
+ private int hashCode=0;
+ private boolean hasHashCode=false;
+
+ private boolean caseSensitive=true;
+
+ // byte[]
+ private byte[] bytes;
+ private int bytesOff;
+ private int bytesLen;
+ private String enc;
+ private boolean hasByteValue=false;
+
+ // Caching the result of a conversion
+
+ // char[]
+ private char chars[];
+ private int charsOff;
+ private int charsLen;
+ private boolean hasCharValue=false;
+
+ // String
+ private String strValue;
+ private boolean hasStrValue=false;
+
/**
- * The length of the bytes.
- */
- protected int length;
-
- /**
* Creates a new, uninitialized MessageBytes object.
*/
public MessageBytes() {
}
- /**
- * Creates a new MessageBytes object with the specified bytes.
- * @param b the bytes
- * @param off the start offset of the bytes
- * @param len the length of the bytes
- */
- public MessageBytes(byte[] b, int off, int len) {
- setBytes(b, off, len);
+ public void setCaseSenitive( boolean b ) {
+ caseSensitive=b;
}
+ public MessageBytes getClone() {
+ try {
+ return (MessageBytes)this.clone();
+ } catch( Exception ex) {
+ return null;
+ }
+ }
+
+ public void reset() {
+ recycle();
+ }
/**
* Resets the message bytes to an uninitialized state.
*/
- public void reset() {
+ public void recycle() {
bytes = null;
+ strValue=null;
+ // chars=null;
+ caseSensitive=true;
+
+ enc=null;
+ hasByteValue=false;
+ hasStrValue=false;
+ hasCharValue=false;
+ hasHashCode=false;
}
+
/**
* Sets the message bytes to the specified subarray of bytes.
* @param b the ascii bytes
@@ -125,10 +150,78 @@
*/
public void setBytes(byte[] b, int off, int len) {
bytes = b;
- offset = off;
- length = len;
+ bytesOff = off;
+ bytesLen = len;
+ type=T_BYTES;
+ hasByteValue=true;
+ }
+
+ public void setEncoding( String enc ) {
+ this.enc=enc;
+ }
+
+ public void setChars( char[] c, int off, int len ) {
+ chars=c;
+ charsOff=off;
+ charsLen=len;
+ type=T_CHARS;
+ hasCharValue=true;
+ }
+
+ public void setString( String s ) {
+ strValue=s;
+ hasStrValue=true;
+ type=T_STR;
}
+ // -------------------- Conversion and getters --------------------
+ public String toString() {
+ if( hasStrValue ) return strValue;
+
+ switch (type) {
+ case T_CHARS:
+ strValue=new String( chars, charsOff, charsLen);
+ hasStrValue=true;
+ return strValue;
+ case T_BYTES:
+ try {
+ if( enc==null )
+ strValue=toStringUTF8();
+ else
+ strValue=new String(bytes, bytesOff, bytesLen, enc);
+ hasStrValue=true;
+ return strValue;
+ } catch (java.io.UnsupportedEncodingException e) {
+ return null; // can't happen
+ }
+ default:
+ return null;
+ }
+ }
+
+ private String toStringUTF8() {
+ if (null == bytes) {
+ return null;
+ }
+ if( chars==null || bytesLen > chars.length ) {
+ chars=new char[bytesLen];
+ }
+
+ int j=bytesOff;
+ for( int i=0; i< bytesLen; i++ ) {
+ chars[i]=(char)bytes[j++];
+ }
+ charsLen=bytesLen;
+ charsOff=0;
+ hasCharValue=true;
+ return new String( chars, 0, bytesLen);
+ }
+
+ //----------------------------------------
+ public int getType() {
+ return type;
+ }
+
/**
* Returns the message bytes.
*/
@@ -137,181 +230,325 @@
}
/**
- * Puts the message bytes in buf starting at buf_offset.
- * @return the number of bytes added to buf.
- */
- public int getBytes(byte buf[],
- int buf_offset)
- {
- if (bytes != null)
- System.arraycopy(bytes, offset, buf, buf_offset, length);
- return length;
- }
-
- /**
* Returns the start offset of the bytes.
*/
public int getOffset() {
- return offset;
+ if(type==T_BYTES)
+ return bytesOff;
+ if(type==T_CHARS)
+ return charsOff;
+ return 0;
}
/**
* Returns the length of the bytes.
*/
public int getLength() {
- return length;
+ if(type==T_BYTES)
+ return bytesLen;
+ if(type==T_CHARS)
+ return charsLen;
+ if(type==T_STR)
+ return strValue.length();
+ return 0;
}
- /**
- * Returns true if the message bytes have been set.
- */
- public boolean isSet() {
- return bytes != null;
- }
+ // -------------------- equals --------------------
/**
- * Returns the message bytes parsed as an unsigned integer.
- * @exception NumberFormatException if the integer format was invalid
- */
- public int toInteger() throws NumberFormatException {
- return Ascii.parseInt(bytes, offset, length);
- }
-
- /**
- * Compares the message bytes to the specified subarray of bytes.
- * @param b the bytes to compare
- * @param off the start offset of the bytes
- * @param len the length of the bytes
+ * Compares the message bytes to the specified String object.
+ * @param s the String to compare
* @return true if the comparison succeeded, false otherwise
*/
- public boolean equals(byte[] b, int off, int len) {
- byte[] b1 = bytes;
- if (b1 == null || len != length) {
- return false;
- }
- int off1 = offset;
- while (len-- > 0) {
- if (b[off++] != b1[off1++]) {
+ public boolean equals(String s) {
+ if( ! caseSensitive )
+ return equalsIgnoreCase( s );
+ switch (type) {
+ case T_STR:
+ return strValue.equals( s );
+ case T_CHARS:
+ char[] c = chars;
+ int len = charsLen;
+ if (c == null || len != s.length()) {
+ return false;
+ }
+ int off = charsOff;
+ for (int i = 0; i < len; i++) {
+ if (c[off++] != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ case T_BYTES:
+ byte[] b = bytes;
+ int blen = bytesLen;
+ if (b == null || blen != s.length()) {
return false;
}
+ int boff = bytesOff;
+ for (int i = 0; i < blen; i++) {
+ if (b[boff++] != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ default:
+ return false;
}
- return true;
}
/**
- * Compares the message bytes to the specified subarray of bytes.
- * Case is ignored in the comparison.
- * @param b the bytes to compare
- * @param off the start offset of the bytes
- * @param len the length of the bytes
+ * Compares the message bytes to the specified String object.
+ * @param s the String to compare
* @return true if the comparison succeeded, false otherwise
*/
- public boolean equalsIgnoreCase(byte[] b, int off, int len) {
- byte[] b1 = bytes;
- if (b1 == null || len != length) {
- return false;
- }
- int off1 = offset;
- while (len-- > 0) {
- if (Ascii.toLower(b[off++]) != Ascii.toLower(b1[off1++])) {
+ public boolean equalsIgnoreCase(String s) {
+ switch (type) {
+ case T_STR:
+ return strValue.equalsIgnoreCase( s );
+ case T_CHARS:
+ char[] c = chars;
+ int len = charsLen;
+ if (c == null || len != s.length()) {
return false;
}
+ int off = charsOff;
+ for (int i = 0; i < len; i++) {
+ if (Ascii.toLower( c[off++] ) != Ascii.toLower( s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ case T_BYTES:
+ byte[] b = bytes;
+ int blen = bytesLen;
+ if (b == null || blen != s.length()) {
+ return false;
+ }
+ int boff = bytesOff;
+ for (int i = 0; i < blen; i++) {
+ if (Ascii.toLower(b[boff++]) != Ascii.toLower(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ default:
+ return false;
}
- return true;
}
- /**
- * Writes the message bytes to the specified output stream.
- * @param out the output stream
- * @exception IOException if an I/O error has occurred
- */
- public void write(OutputStream out) throws IOException {
- if (bytes != null) {
- out.write(bytes, offset, length);
+ public boolean equals(MessageBytes mb) {
+ switch (type) {
+ case T_STR:
+ return mb.equals( strValue );
}
- }
- /**
- * Returns the length of the message bytes.
- */
- public int length() {
- return bytes != null ? length : 0;
- }
+ if( mb.type != T_CHARS && mb.type!= T_BYTES ) {
+ // it's a string or int/date string value
+ return equals( mb.toString() );
+ }
- // --------------------
- /**
- * Returns the message bytes as a String object.
- */
- public String toString() {
- if (null == bytes) {
- return null;
- }
+ if( mb.type == T_CHARS && type==T_CHARS ) {
+ char b1[]=chars;
+ char b2[]=mb.chars;
+ if (b1== null || b2==null || mb.charsLen != charsLen) {
+ return false;
+ }
+ int off1 = charsOff;
+ int off2 = mb.charsOff;
+ int len=charsLen;
+ while ( len-- > 0) {
+ if (b1[off1++] != b2[off2++]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if( mb.type==T_BYTES && type== T_BYTES ) {
+ byte b1[]=bytes;
+ byte b2[]=mb.bytes;
+ if (b1== null || b2==null || mb.bytesLen != bytesLen) {
+ return false;
+ }
+ int off1 = bytesOff;
+ int off2 = mb.bytesOff;
+ int len=bytesLen;
+ while ( len-- > 0) {
+ if (b1[off1++] != b2[off2++]) {
+ return false;
+ }
+ }
+ return true;
+ }
- try {
- return new String(bytes, offset, length, Constants.DEFAULT_CHAR_ENCODING);
- } catch (java.io.UnsupportedEncodingException e) {
- return null; // could return something - but why?
- }
- }
+ // char/byte or byte/char
+ MessageBytes mbB=this;
+ MessageBytes mbC=mb;
+
+ if( type == T_CHARS && mb.type==T_BYTES ) {
+ mbB=mb;
+ mbC=this;
+ }
- /**
- * Compares the message bytes to the specified String object.
- * @param s the String to compare
- * @return true if the comparison succeeded, false otherwise
- */
- public boolean equals(String s) {
- byte[] b = bytes;
- int len = length;
- if (b == null || len != s.length()) {
+ byte b1[]=mbB.bytes;
+ char b2[]=mbC.chars;
+ if (b1== null || b2==null || mbB.bytesLen != mbC.charsLen) {
return false;
}
- int off = offset;
- for (int i = 0; i < len; i++) {
- if (b[off++] != s.charAt(i)) {
+ int off1 = mbB.bytesOff;
+ int off2 = mbC.charsOff;
+ int len=mbB.bytesLen;
+
+ while ( len-- > 0) {
+ if ( (char)b1[off1++] != b2[off2++]) {
return false;
}
}
return true;
}
+
/**
- * Compares the message bytes to the specified String object. Case is
- * ignored in the comparison.
- * @param s the String to compare
- * @return true if the comparison succeeded, false otherwise
+ * Returns true if the message bytes starts with the specified string.
+ * @param s the string
*/
- public boolean equalsIgnoreCase(String s) {
- byte[] b = bytes;
- int len = length;
- if (b == null || len != s.length()) {
+ public boolean startsWith(String s) {
+ switch (type) {
+ case T_STR:
+ return strValue.startsWith( s );
+ case T_CHARS:
+ char[] c = chars;
+ int len = s.length();
+ if (c == null || len > charsLen) {
+ return false;
+ }
+ int off = charsOff;
+ for (int i = 0; i < len; i++) {
+ if (c[off++] != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ case T_BYTES:
+ byte[] b = bytes;
+ int blen = s.length();
+ if (b == null || blen > bytesLen) {
+ return false;
+ }
+ int boff = bytesOff;
+ for (int i = 0; i < blen; i++) {
+ if (b[boff++] != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ default:
return false;
}
- int off = offset;
- for (int i = 0; i < len; i++) {
- if (Ascii.toLower(b[off++]) != Ascii.toLower((byte)s.charAt(i))) {
- return false;
+ }
+
+
+
+ // -------------------- Hash code --------------------
+ public int hashCode() {
+ if( hasHashCode ) return hashCode;
+ int code = 0;
+
+ if( caseSensitive )
+ code=hash();
+ else
+ code=hashIgnoreCase();
+ hashCode=code;
+ hasHashCode=true;
+ return code;
+ }
+
+ // normal hash.
+ private int hash() {
+ int code=0;
+ switch (type) {
+ case T_STR:
+ for (int i = 0; i < strValue.length(); i++) {
+ code = code * 37 + strValue.charAt( i );
}
+ return code;
+ case T_CHARS:
+ for (int i = charsOff; i < charsOff + charsLen; i++) {
+ code = code * 37 + chars[i];
+ }
+ return code;
+ case T_BYTES:
+ return hashBytes( bytes, bytesOff, bytesLen);
+ default:
+ return 0;
}
- return true;
}
+ // hash ignoring case
+ private int hashIgnoreCase() {
+ int code=0;
+ switch (type) {
+ case T_STR:
+ for (int i = 0; i < strValue.length(); i++) {
+ code = code * 37 + Ascii.toLower(strValue.charAt( i ));
+ }
+ return code;
+ case T_CHARS:
+ for (int i = charsOff; i < charsOff + charsLen; i++) {
+ code = code * 37 + Ascii.toLower(chars[i]);
+ }
+ return code;
+ case T_BYTES:
+ return hashBytesIC( bytes, bytesOff, bytesLen );
+ default:
+ return 0;
+ }
+ }
+
+ private static int hashBytes( byte bytes[], int bytesOff, int bytesLen ) {
+ int max=bytesOff+bytesLen;
+ byte bb[]=bytes;
+ int code=0;
+ for (int i = bytesOff; i < max ; i++) {
+ code = code * 37 + bb[i];
+ }
+ return code;
+ }
+
+ private static int hashBytesIC( byte bytes[], int bytesOff, int bytesLen ) {
+ int max=bytesOff+bytesLen;
+ byte bb[]=bytes;
+ int code=0;
+ for (int i = bytesOff; i < max ; i++) {
+ code = code * 37 + Ascii.toLower(bb[i]);
+ }
+ return code;
+ }
+
/**
* Returns true if the message bytes starts with the specified string.
* @param s the string
*/
- public boolean startsWith(String s) {
- byte[] b = bytes;
- int len = s.length();
- if (b == null || len > length) {
- return false;
- }
- int off = offset;
- for (int i = 0; i < len; i++) {
- if (b[off++] != s.charAt(i)) {
- return false;
+ public int indexOf(char c) {
+ switch (type) {
+ case T_STR:
+ return strValue.indexOf( c );
+ case T_CHARS:
+ for (int i = charsOff; i < charsOff + charsLen; i++) {
+ if( c == chars[i] ) return i;
+ }
+ return -1;
+ case T_BYTES:
+ int max=bytesOff+bytesLen;
+ byte bb[]=bytes;
+ for (int i = bytesOff; i < max ; i++) {
+ if( (byte)c == bb[i]) return i;
}
+ return -1;
+ default:
+ return -1;
}
- return true;
}
+
}
1.11 +8 -5 jakarta-tomcat/src/share/org/apache/tomcat/util/MimeHeaderField.java
Index: MimeHeaderField.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/MimeHeaderField.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- MimeHeaderField.java 2000/06/23 02:16:29 1.10
+++ MimeHeaderField.java 2000/08/11 06:14:19 1.11
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/MimeHeaderField.java,v 1.10 2000/06/23 02:16:29 costin Exp $
- * $Revision: 1.10 $
- * $Date: 2000/06/23 02:16:29 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/MimeHeaderField.java,v 1.11 2000/08/11 06:14:19 costin Exp $
+ * $Revision: 1.11 $
+ * $Date: 2000/08/11 06:14:19 $
*
* ====================================================================
*
@@ -291,7 +291,10 @@
case T_CHARS:
return valueC.toInteger();
case T_BYTES:
- return valueB.toInteger();
+ if(valueB.getType() == MessageBytes.T_BYTES )
+ return Ascii.parseInt(valueB.getBytes(), valueB.getOffset(),
+ valueB.getLength());
+ return Integer.parseInt(valueB.toString());
default:
String msg = sm.getString("mimeHeaderField.int.nfe");
@@ -370,7 +373,7 @@
case T_CHARS:
return nameC.equalsIgnoreCase(s);
case T_BYTES:
- return Ascii.equalsIgnoreCase( s, nameB );
+ return nameB.equalsIgnoreCase( s );
default:
return false;
}