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...@apache.org on 2005/11/06 04:13:09 UTC
svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./
adapters/ standalone/
Author: costin
Date: Sat Nov 5 19:13:06 2005
New Revision: 331062
URL: http://svn.apache.org/viewcvs?rev=331062&view=rev
Log:
Code for testing ( and using ) coyote standalone.
The adapters are very simple, more as example. The goal is to have a
minimal http connector, and play with nio and other apis in a simpler
environment
About MessageWriter and MessageReader - they are copies of
Catalina/connector/OutputBuffer and InputBuffer. Renamed to avoid
confusion. Long term, they should be part of o.a.coyote package, there
is no dep on catalina and are usefull in in connector.
Added:
tomcat/sandbox/java/org/apache/coyote/
tomcat/sandbox/java/org/apache/coyote/adapters/
tomcat/sandbox/java/org/apache/coyote/adapters/Counters.java
tomcat/sandbox/java/org/apache/coyote/adapters/FileAdapter.java
tomcat/sandbox/java/org/apache/coyote/adapters/HelloWorldAdapter.java
tomcat/sandbox/java/org/apache/coyote/adapters/JsAdapter.java
tomcat/sandbox/java/org/apache/coyote/adapters/Mapper.java
tomcat/sandbox/java/org/apache/coyote/standalone/
tomcat/sandbox/java/org/apache/coyote/standalone/ClientAbortException.java
tomcat/sandbox/java/org/apache/coyote/standalone/Main.java
tomcat/sandbox/java/org/apache/coyote/standalone/MessageReader.java
tomcat/sandbox/java/org/apache/coyote/standalone/MessageWriter.java
Added: tomcat/sandbox/java/org/apache/coyote/adapters/Counters.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/adapters/Counters.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/adapters/Counters.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/adapters/Counters.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,78 @@
+package org.apache.coyote.adapters;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+
+/**
+ * Used to collect statistics to evaluate performance of the coyote layer.
+ *
+ */
+public class Counters implements Adapter {
+
+ // per thread
+ public static class CountData {
+ public long time;
+ public long requests;
+ public int exceptions;
+ }
+
+ // quick hack - need to move the per-thread code from tomcat
+ List counters=new ArrayList();
+ ThreadLocal tl=new ThreadLocal();
+
+ Adapter next;
+
+ public Counters() {
+ }
+
+ public void setNext( Adapter adapter ) {
+ next=adapter;
+ }
+
+ public Adapter getNext( ) {
+ return next;
+ }
+
+ public void service(Request req, final Response res) throws Exception {
+ long t0=System.currentTimeMillis();
+ CountData cnt=(CountData)tl.get();
+ if( cnt == null ) {
+ cnt=new CountData();
+ counters.add( cnt );
+ tl.set( cnt );
+ // TODO: deal with thread death
+ }
+
+ cnt.requests++;
+ try {
+ next.service(req,res);
+ } catch( Exception ex ) {
+ cnt.exceptions++;
+ throw ex;
+ } finally {
+ long t1=System.currentTimeMillis();
+ cnt.time+=( t1-t0);
+ }
+
+ }
+
+ /** Returns statistics for the server.
+ * TODO: make it per thread, agregate all threads
+ *
+ * @return
+ */
+ public CountData getCounts() {
+ CountData total=new CountData();
+ for( int i=0; i< counters.size(); i++ ) {
+ CountData cd=((CountData)counters.get(i));
+ total.requests+= cd.requests;
+ total.time+=cd.time;
+ total.exceptions+=cd.exceptions;
+ }
+ return total;
+ }
+}
\ No newline at end of file
Added: tomcat/sandbox/java/org/apache/coyote/adapters/FileAdapter.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/adapters/FileAdapter.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/adapters/FileAdapter.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/adapters/FileAdapter.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,127 @@
+package org.apache.coyote.adapters;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.coyote.standalone.MessageWriter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.C2BConverter;
+
+/**
+ * Serve a static file. This is the traditional method, a separate adapter could
+ * use Sendfile.
+ *
+ * No fancy things. Not sure if it should have dir support even.
+ */
+public class FileAdapter implements Adapter {
+ Log log = LogFactory.getLog("coyote.file");
+
+ private String baseDir = "html/";
+
+ private File baseDirF;
+
+ public FileAdapter() {
+ init();
+ }
+
+ public void setBaseDir(String s) {
+ baseDir = s;
+ }
+
+ public void init() {
+ baseDirF = new File(baseDir);
+ try {
+ baseDir = baseDirF.getCanonicalPath();
+ } catch (IOException e) {
+ }
+ }
+
+ public void service(Request req, final Response res) throws Exception {
+
+ String uri = req.requestURI().toString();
+ if (uri.indexOf("..") >= 0) {
+ // not supported, too dangerous
+ // what else to escape ?
+ log.info("Invalid .. in " + uri);
+ res.setStatus(404);
+ return;
+ }
+
+ // local file
+ File f = new File(baseDirF, uri);
+
+ // extra check
+ if (!f.getCanonicalPath().startsWith(baseDir)) {
+ log.info("File outside basedir " + baseDir + " " + f);
+ res.setStatus(404);
+ return;
+ }
+
+ if (f.isDirectory()) {
+ // check for index.html, redirect if exists
+ // list dir if not
+
+ f = new File(f, "index.html");
+ }
+
+ if (!f.exists()) {
+ log.info("File not found " + f);
+ res.setStatus(404);
+ return;
+ }
+
+ res.setStatus(200);
+
+ // TODO: read from a resources in classpath !
+ // TODO: refactor to allow sendfile
+ // TODO: read mime types
+
+ int dot=uri.lastIndexOf(".");
+ if( dot > 0 ) {
+ String ext=uri.substring(dot+1);
+ String ct=getContentType(ext);
+ if( ct!=null) {
+ res.setContentType(ct);
+ }
+ }
+
+ res.setContentLength(f.length());
+
+ res.sendHeaders();
+
+ // not used - writes directly to response
+ // MessageWriter out = MessageWriter.getWriter(req, res, 0);
+
+ FileInputStream fis = new FileInputStream(f);
+ byte b[] = new byte[4096];
+ ByteChunk mb = new ByteChunk();
+ int rd = 0;
+ while ((rd = fis.read(b)) > 0) {
+ mb.setBytes(b, 0, rd);
+ res.doWrite(mb);
+ }
+
+ }
+
+ static Properties contentTypes=new Properties();
+ static {
+ initContentTypes();
+ }
+ static void initContentTypes() {
+ contentTypes.put("html", "text/html");
+ contentTypes.put("txt", "text/plain");
+ contentTypes.put("xul", "application/vnd.mozilla.xul+xml");
+ }
+
+ public String getContentType( String ext ) {
+ return contentTypes.getProperty( ext, "text/plain" );
+ }
+
+}
\ No newline at end of file
Added: tomcat/sandbox/java/org/apache/coyote/adapters/HelloWorldAdapter.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/adapters/HelloWorldAdapter.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/adapters/HelloWorldAdapter.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/adapters/HelloWorldAdapter.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,15 @@
+package org.apache.coyote.adapters;
+
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.coyote.standalone.MessageWriter;
+
+public class HelloWorldAdapter implements Adapter {
+ public void service(Request req, Response res) throws Exception {
+ MessageWriter out=MessageWriter.getWriter(req, res, 0);
+ res.setContentType("text/html");
+
+ out.write("<h1>Hello world</h1>");
+ }
+}
Added: tomcat/sandbox/java/org/apache/coyote/adapters/JsAdapter.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/adapters/JsAdapter.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/adapters/JsAdapter.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/adapters/JsAdapter.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,240 @@
+package org.apache.coyote.adapters;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.coyote.http11.Http11BaseProtocol;
+import org.apache.coyote.standalone.Main;
+import org.apache.coyote.standalone.MessageWriter;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.WrappedException;
+
+/**
+ * Will load the 'default.js' and execute init. In init you can set params on
+ * the server and handler.
+ *
+ * Entry points:
+ * <ul>
+ * <li>init() - called the first time, can set the port and other
+ * properties in the "server" object
+ * <li>initThread() - called per thread.
+ * <li>service( req, res, out)
+ * </ul>
+ *
+ * Defined objects:
+ * <ul>
+ * <li>log - commons logger log for this adapter
+ * <li>server - the http connector
+ * <li>jsAdapter, counterAdapter, fileAdapter, mapperAdapter - adapters.
+ * </ul>
+ *
+ * Note: this is just an example, you can extend it or create your own
+ * with different semantics. After the coyote API is cleaned up and converted
+ * to NIO - I'll also define a better JS API.
+ *
+ */
+public class JsAdapter extends Main implements Adapter {
+
+ // Js file to interpret
+ static String filename = "js-bin/default.js";
+
+ // to support reloading of the js file
+ static long lastModif = 0;
+
+ // Javascript main context and scope
+ private Context mainCx;
+
+ private Scriptable mainScope;
+
+ private Log log = LogFactory.getLog("js");
+
+ // we store them per thread. Need a way to manage the tokens
+ public static final int SCOPE_NOTE = 12;
+
+ public static final int ADAPTER_NOTES = 11;
+
+ boolean reload = true;
+
+ public JsAdapter() {
+ }
+
+ public boolean getReload() {
+ return reload;
+ }
+
+ public void setReload(boolean reload) {
+ this.reload = reload;
+ }
+
+ public void service(Request req, final Response res) throws Exception {
+ // Per thread.
+ Context cx = (Context) req.getNote(JsAdapter.ADAPTER_NOTES);
+ Scriptable scope = (Scriptable) req.getNote(JsAdapter.SCOPE_NOTE);
+ MessageWriter out = MessageWriter.getWriter(req, res, 0);
+
+ if (cx == null) {
+ cx = Context.enter();
+ req.setNote(JsAdapter.ADAPTER_NOTES, cx);
+ // TODO: exit on thread death
+
+ // Each thread will have an associated context, and an associated
+ // scope.
+ // The scope will hold the proxies for req, res and the other
+ // objects
+ // Because the req and response never change for a thread - we don't
+ // need to bind them again.
+
+ scope = cx.newObject(mainScope);
+ scope.setPrototype(mainScope);
+
+ req.setNote(JsAdapter.SCOPE_NOTE, scope);
+
+ Object fObj = mainScope.get("initThread", mainScope);
+ if ((fObj instanceof Function)) {
+ Object functionArgs[] = { req, res, out };
+ Function f = (Function) fObj;
+ Object result = f.call(mainCx, mainScope, mainScope,
+ functionArgs);
+ }
+ }
+
+ // The file was loaded in initJS(), at server startup. We will only
+ // check if it changed, if we are in devel mode and reload it.
+ if (reload) {
+ load(filename);
+ }
+
+ // Now call the service() js function
+ Object fObj = ScriptableObject.getProperty(scope, "service");
+ if (!(fObj instanceof Function)) {
+ log.info("service is undefined or not a function. " + fObj);
+ log.info("Not found in scope... " + scope);
+ log.info("Parent: " + mainScope.get("service", mainScope));
+ fObj = mainScope.get("service", mainScope);
+ }
+
+ Object functionArgs[] = { req, res, out };
+ Function f = (Function) fObj;
+ Object result = f.call(cx, scope, scope, functionArgs);
+
+ }
+
+ /**
+ * Initialize. Will run the init() method in the script
+ *
+ * @param proto
+ */
+ public void initJS() {
+ mainCx = Context.enter();
+ mainScope = mainCx.initStandardObjects();
+
+ Object jsOut;
+
+ jsOut = Context.javaToJS(log, mainScope);
+ ScriptableObject.putProperty(mainScope, "log", jsOut);
+
+ jsOut = Context.javaToJS(proto, mainScope);
+ ScriptableObject.putProperty(mainScope, "server", jsOut);
+
+ Counters ct = (Counters) proto.getAdapter();
+ Mapper mp = (Mapper) ct.getNext();
+ FileAdapter fa = (FileAdapter) mp.getDefaultAdapter();
+
+ jsOut = Context.javaToJS(ct, mainScope);
+ ScriptableObject.putProperty(mainScope, "countersAdapter", jsOut);
+
+ jsOut = Context.javaToJS(mp, mainScope);
+ ScriptableObject.putProperty(mainScope, "mapperAdapter", jsOut);
+
+ jsOut = Context.javaToJS(fa, mainScope);
+ ScriptableObject.putProperty(mainScope, "fileAdapter", jsOut);
+
+ jsOut = Context.javaToJS(this, mainScope);
+ ScriptableObject.putProperty(mainScope, "jsAdapter", jsOut);
+
+ load(filename);
+
+ Object fObj = mainScope.get("init", mainScope);
+ if ((fObj instanceof Function)) {
+ Object functionArgs[] = {};
+ Function f = (Function) fObj;
+ Object result = f.call(mainCx, mainScope, mainScope, functionArgs);
+ }
+ }
+
+ /**
+ * Load a script.
+ */
+ private void load(String filename) {
+
+ FileReader in = null;
+ try {
+ File scriptF = new File(filename);
+
+ if (lastModif != 0 && scriptF.lastModified() <= lastModif) {
+ // already loaded
+ return;
+ }
+ lastModif = scriptF.lastModified();
+ in = new FileReader(filename);
+ } catch (FileNotFoundException ex) {
+ System.err.println("JS file not found " + ex);
+ return;
+ }
+
+ try {
+ // Here we evalute the entire contents of the file as
+ // a script. Text is printed only if the print() function
+ // is called.
+ Object result = mainCx.evaluateReader(mainScope, in, filename, 1,
+ null);
+ } catch (WrappedException we) {
+ System.err.println(we.getWrappedException().toString());
+ we.printStackTrace();
+ } catch (EvaluatorException ee) {
+ System.err.println("js: " + ee.getMessage());
+ } catch (JavaScriptException jse) {
+ System.err.println("js: " + jse.getMessage());
+ } catch (IOException ioe) {
+ System.err.println(ioe.toString());
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ioe) {
+ System.err.println(ioe.toString());
+ }
+ }
+ }
+
+ public void setProtocol(Http11BaseProtocol proto) {
+ this.proto = proto;
+ }
+
+ // ------------ Example on how to run it --------------------
+
+ public void init() {
+ super.init();
+ JsAdapter js = this; // new JsAdapter();
+ js.setProtocol(proto);
+ js.initJS();
+ mainAdapter.addAdapter("/js-bin", js);
+ }
+
+ public static void main(String args[]) {
+ JsAdapter sa = new JsAdapter();
+ sa.run(); // in Main - will call init first
+ }
+
+}
\ No newline at end of file
Added: tomcat/sandbox/java/org/apache/coyote/adapters/Mapper.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/adapters/Mapper.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/adapters/Mapper.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/adapters/Mapper.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,125 @@
+package org.apache.coyote.adapters;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.coyote.Adapter;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.coyote.http11.Http11BaseProtocol;
+import org.apache.coyote.standalone.MessageWriter;
+import org.apache.tomcat.util.loader.Loader;
+import org.apache.tomcat.util.loader.Repository;
+
+/**
+ * Very, very simple mapper for standalone coyote. Used to test and experiment
+ * various low level changes, or for very simple http servers.
+ *
+ * It currently supports only prefix mapping, using the first url component.
+ */
+public class Mapper implements Adapter {
+
+ // TODO: add extension mappings
+ // Key = prefix, one level only, value= class name of Adapter
+ // key starts with a / and has no other / ( /foo - but not /foo/bar )
+ Hashtable prefixMap=new Hashtable();
+
+ String fileAdapterCN="org.apache.coyote.adapters.FileAdapter";
+ Adapter defaultAdapter=new FileAdapter();
+
+ public Mapper() {
+ }
+
+ public void service(Request req, final Response res)
+ throws Exception {
+ try {
+ String uri=req.requestURI().toString();
+ if( uri.equals("/") ) uri="index.html";
+ String ctx="";
+ String local=uri;
+ if( uri.length() > 1 ) {
+ int idx=uri.indexOf('/', 1);
+ if( idx > 0 ) {
+ ctx=uri.substring(0, idx);
+ local=uri.substring( idx );
+ }
+ }
+ Adapter h=(Adapter)prefixMap.get( ctx );
+ if( h != null ) {
+ h.service( req, res );
+ } else {
+ defaultAdapter.service( req, res );
+ }
+ } catch( Throwable t ) {
+ t.printStackTrace();
+ }
+
+ //out.flushBuffer();
+ //out.getByteChunk().flushBuffer(); - part of res.finish()
+ // final processing
+ MessageWriter.getWriter(req, res, 0).flush();
+ res.finish();
+
+ req.recycle();
+ res.recycle();
+
+ }
+
+ /** Load the handler table. Just a hack, I'll find a better solution
+ */
+ public void initHandlers() {
+
+ prefixMap=new Hashtable();
+ Enumeration keys=System.getProperties().keys();
+
+ Loader loader=null;
+ if( loader == null ) {
+ // Not started from loader, we are embedded - create the loader, so we
+ // can do reloading.
+ //LoaderProperties.setPropertiesFile("");
+ try {
+ loader=new Loader();
+ ClassLoader myL=this.getClass().getClassLoader();
+ loader.setParentClassLoader( myL );
+ loader.init();
+ } catch( Throwable t ) {
+ t.printStackTrace();
+ }
+ }
+
+ Repository sR=loader.getRepository("shared");
+ // Construct handlers. Handlers will be created, they can get the protocol
+ // if they need additional init
+
+ while( keys.hasMoreElements()) {
+ String n=(String)keys.nextElement();
+ if( n.startsWith("handler.")) {
+ String cls=System.getProperty( n );
+ String map=n.substring(8);
+ Adapter hC=null;
+ try {
+ // use the loader's server common repository
+ Class c=sR.getClassLoader().loadClass(cls);
+ //Class c=Class.forName(cls);
+ hC=(Adapter)c.newInstance();
+ prefixMap.put( map, hC );
+ } catch( Throwable t ) {
+ t.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public void addAdapter( String prefix, Adapter adapter ) {
+ prefixMap.put(prefix, adapter);
+ }
+
+ public void setDefaultAdapter(Adapter adapter) {
+ defaultAdapter=adapter;
+ }
+
+ public Adapter getDefaultAdapter() {
+ return defaultAdapter;
+ }
+
+}
\ No newline at end of file
Added: tomcat/sandbox/java/org/apache/coyote/standalone/ClientAbortException.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/standalone/ClientAbortException.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/standalone/ClientAbortException.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/standalone/ClientAbortException.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.coyote.standalone;
+
+import java.io.IOException;
+
+/**
+ * Wrap an IOException identifying it as being caused by an abort
+ * of a request by a remote client.
+ *
+ * @author Glenn L. Nielsen
+ * @version $Revision: 304063 $ $Date: 2005-08-18 06:25:18 -0700 (Thu, 18 Aug 2005) $
+ */
+
+public final class ClientAbortException extends IOException {
+
+
+ //------------------------------------------------------------ Constructors
+
+
+ /**
+ * Construct a new ClientAbortException with no other information.
+ */
+ public ClientAbortException() {
+
+ this(null, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message.
+ *
+ * @param message Message describing this exception
+ */
+ public ClientAbortException(String message) {
+
+ this(message, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified throwable.
+ *
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(Throwable throwable) {
+
+ this(null, throwable);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message
+ * and throwable.
+ *
+ * @param message Message describing this exception
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(String message, Throwable throwable) {
+
+ super();
+ this.message = message;
+ this.throwable = throwable;
+
+ }
+
+
+ //------------------------------------------------------ Instance Variables
+
+
+ /**
+ * The error message passed to our constructor (if any)
+ */
+ protected String message = null;
+
+
+ /**
+ * The underlying exception or error passed to our constructor (if any)
+ */
+ protected Throwable throwable = null;
+
+
+ //---------------------------------------------------------- Public Methods
+
+
+ /**
+ * Returns the message associated with this exception, if any.
+ */
+ public String getMessage() {
+
+ return (message);
+
+ }
+
+
+ /**
+ * Returns the cause that caused this exception, if any.
+ */
+ public Throwable getCause() {
+
+ return (throwable);
+
+ }
+
+
+ /**
+ * Return a formatted string that describes this exception.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("ClientAbortException: ");
+ if (message != null) {
+ sb.append(message);
+ if (throwable != null) {
+ sb.append(": ");
+ }
+ }
+ if (throwable != null) {
+ sb.append(throwable.toString());
+ }
+ return (sb.toString());
+
+ }
+
+
+}
Added: tomcat/sandbox/java/org/apache/coyote/standalone/Main.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/standalone/Main.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/standalone/Main.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/standalone/Main.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,66 @@
+package org.apache.coyote.standalone;
+
+import org.apache.coyote.adapters.Counters;
+import org.apache.coyote.adapters.HelloWorldAdapter;
+import org.apache.coyote.adapters.Mapper;
+import org.apache.coyote.http11.Http11BaseProtocol;
+
+
+/**
+ * Simple example of embeding coyote.
+ *
+ */
+public class Main {
+
+ protected Http11BaseProtocol proto;
+ protected Mapper mainAdapter;
+
+ public Main() {
+ }
+
+ public Http11BaseProtocol getProtocol() {
+ return proto;
+ }
+
+ public void init() {
+ proto = new Http11BaseProtocol();
+
+ mainAdapter = new Mapper();
+ mainAdapter.addAdapter("/hello", new HelloWorldAdapter());
+
+ Counters cnt=new Counters();
+ cnt.setNext( mainAdapter );
+
+ //proto.setAdapter(mainAdapter);
+ proto.setAdapter(cnt);
+ }
+
+ /**
+ */
+ public void run() {
+ init();
+
+ if( proto.getPort() == 0 )
+ proto.setPort(8800);
+
+ try {
+ proto.init();
+
+ proto.getThreadPool().setDaemon(false);
+
+ proto.start();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ // ------------------- Main ---------------------
+ public static void main( String args[]) {
+ Main sa=new Main();
+ sa.run();
+ }
+
+
+}
\ No newline at end of file
Added: tomcat/sandbox/java/org/apache/coyote/standalone/MessageReader.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/standalone/MessageReader.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/standalone/MessageReader.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/standalone/MessageReader.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,503 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.coyote.standalone;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+
+import org.apache.coyote.Request;
+import org.apache.tomcat.util.buf.B2CConverter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.CharChunk;
+
+/**
+ * Refactored from catalina.connector.InputBuffer. Renamed to avoid conflict
+ * with coyote class.
+ *
+ * TODO: move to coyote package.
+ */
+
+/**
+ * The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3
+ * OutputBuffer, adapted to handle input instead of output. This allows
+ * complete recycling of the facade objects (the ServletInputStream and the
+ * BufferedReader).
+ *
+ * @author Remy Maucherat
+ */
+public class MessageReader extends Reader
+ implements ByteChunk.ByteInputChannel, CharChunk.CharInputChannel,
+ CharChunk.CharOutputChannel {
+
+
+ // -------------------------------------------------------------- Constants
+
+
+ public static final String DEFAULT_ENCODING =
+ org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+
+ // The buffer can be used for byte[] and char[] reading
+ // ( this is needed to support ServletInputStream and BufferedReader )
+ public final int INITIAL_STATE = 0;
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The byte buffer.
+ */
+ private ByteChunk bb;
+
+
+ /**
+ * The chunk buffer.
+ */
+ 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;
+
+
+ /**
+ * Byte chunk used to input bytes.
+ */
+ private ByteChunk inputChunk = new ByteChunk();
+
+
+ /**
+ * Encoding to use.
+ */
+ private String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ private boolean gotEnc = false;
+
+
+ /**
+ * List of encoders.
+ */
+ protected HashMap encoders = new HashMap();
+
+
+ /**
+ * Current byte to char converter.
+ */
+ protected B2CConverter conv;
+
+
+ /**
+ * Associated Coyote request.
+ */
+ private Request coyoteRequest;
+
+
+ /**
+ * Buffer position.
+ */
+ private int markPos = -1;
+
+
+ /**
+ * Buffer size.
+ */
+ private int size = -1;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer size.
+ */
+ public MessageReader() {
+
+ this(DEFAULT_BUFFER_SIZE);
+
+ }
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer size.
+ *
+ * @param size Buffer size to use
+ */
+ public MessageReader(int size) {
+
+ this.size = size;
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteInputChannel(this);
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setOptimizedWrite(false);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+
+ }
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Associated Coyote request.
+ *
+ * @param coyoteRequest Associated Coyote request
+ */
+ public void setRequest(Request coyoteRequest) {
+ this.coyoteRequest = coyoteRequest;
+ }
+
+
+ /**
+ * Get associated Coyote request.
+ *
+ * @return the associated Coyote request
+ */
+ public Request getRequest() {
+ return this.coyoteRequest;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+
+ state = INITIAL_STATE;
+ bytesRead = 0;
+ charsRead = 0;
+
+ // If usage of mark made the buffer too big, reallocate it
+ if (cb.getChars().length > size) {
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+ } else {
+ cb.recycle();
+ }
+ markPos = -1;
+ bb.recycle();
+ closed = false;
+
+ if (conv != null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ }
+
+
+ /**
+ * Close the input buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+ closed = true;
+ }
+
+
+ public int available()
+ throws IOException {
+ if (state == BYTE_STATE) {
+ return bb.getLength();
+ } else if (state == CHAR_STATE) {
+ return cb.getLength();
+ } else {
+ return 0;
+ }
+ }
+
+
+ // ------------------------------------------------- Bytes Handling Methods
+
+
+ /**
+ * Reads new bytes in the byte chunk.
+ *
+ * @param cbuf Byte buffer to be written to the response
+ * @param off Offset
+ * @param len Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public int realReadBytes(byte cbuf[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return -1;
+ if (coyoteRequest == null)
+ return -1;
+
+ state = BYTE_STATE;
+
+ int result = coyoteRequest.doRead(bb);
+
+ return result;
+
+ }
+
+
+ public int readByte()
+ throws IOException {
+ return bb.substract();
+ }
+
+
+ public int read(byte[] b, int off, int len)
+ throws IOException {
+ return bb.substract(b, off, len);
+ }
+
+
+ // ------------------------------------------------- Chars Handling Methods
+
+
+ /**
+ * Since the converter will use append, it is possible to get chars to
+ * be removed from the buffer for "writing". Since the chars have already
+ * been read before, they are ignored. If a mark was set, then the
+ * mark is lost.
+ */
+ public void realWriteChars(char c[], int off, int len)
+ throws IOException {
+ markPos = -1;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+
+ 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);
+ 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();
+ }
+ }
+
+
+ public void checkConverter()
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ }
+
+
+ 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) {
+ if (packageDefinitionEnabled && System.getSecurityManager() != null) {
+ //SecurityUtil.isPackageProtectionEnabled()){
+ try{
+ conv = (B2CConverter)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ return new B2CConverter(enc);
+ }
+
+ }
+ );
+ }catch(PrivilegedActionException ex){
+ Exception e = ex.getException();
+ if (e instanceof IOException)
+ throw (IOException)e;
+ }
+ } else {
+ conv = new B2CConverter(enc);
+ }
+ encoders.put(enc, conv);
+ }
+
+ }
+
+ private static boolean packageDefinitionEnabled =
+ (System.getProperty("package.definition") == null &&
+ System.getProperty("package.access") == null) ? false : true;
+
+}
Added: tomcat/sandbox/java/org/apache/coyote/standalone/MessageWriter.java
URL: http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/coyote/standalone/MessageWriter.java?rev=331062&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/standalone/MessageWriter.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/standalone/MessageWriter.java Sat Nov 5 19:13:06 2005
@@ -0,0 +1,677 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.coyote.standalone;
+
+
+import java.io.IOException;
+import java.io.Writer;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+
+import org.apache.coyote.ActionCode;
+import org.apache.coyote.Request;
+import org.apache.coyote.Response;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.C2BConverter;
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
+
+/*
+ * Refactoring: original code in catalina.connector.
+ * - renamed to OutputWriter to avoid confusion with coyote OutputBuffer
+ * -
+ * TODO: move it to coyote, add Response.getWriter
+ *
+ */
+
+/**
+ * The buffer used by Tomcat response. This is a derivative of the Tomcat 3.3
+ * OutputBuffer, with the removal of some of the state handling (which in
+ * Coyote is mostly the Processor's responsability).
+ *
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ */
+public class MessageWriter extends Writer
+ implements ByteChunk.ByteOutputChannel, CharChunk.CharOutputChannel {
+
+ // used in getWriter, until a method is added to res.
+ private static final int WRITER_NOTE = 3;
+
+ // -------------------------------------------------------------- Constants
+
+
+ public static final String DEFAULT_ENCODING =
+ org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+
+
+ // The buffer can be used for byte[] and char[] writing
+ // ( this is needed to support ServletOutputStream and for
+ // efficient implementations of templating systems )
+ public final int INITIAL_STATE = 0;
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The byte buffer.
+ */
+ private ByteChunk bb;
+
+
+ /**
+ * The chunk buffer.
+ */
+ private CharChunk cb;
+
+
+ /**
+ * State of the output buffer.
+ */
+ private int state = 0;
+
+
+ /**
+ * Number of bytes written.
+ */
+ private int bytesWritten = 0;
+
+
+ /**
+ * Number of chars written.
+ */
+ private int charsWritten = 0;
+
+
+ /**
+ * Flag which indicates if the output buffer is closed.
+ */
+ private boolean closed = false;
+
+
+ /**
+ * Do a flush on the next operation.
+ */
+ private boolean doFlush = false;
+
+
+ /**
+ * Byte chunk used to output bytes.
+ */
+ private ByteChunk outputChunk = new ByteChunk();
+
+
+ /**
+ * Encoding to use.
+ */
+ private String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ private boolean gotEnc = false;
+
+
+ /**
+ * List of encoders.
+ */
+ protected HashMap encoders = new HashMap();
+
+
+ /**
+ * Current char to byte converter.
+ */
+ protected C2BConverter conv;
+
+
+ /**
+ * Associated Coyote response.
+ */
+ private Response coyoteResponse;
+
+
+ /**
+ * Suspended flag. All output bytes will be swallowed if this is true.
+ */
+ private boolean suspended = false;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer size.
+ */
+ public MessageWriter() {
+
+ this(DEFAULT_BUFFER_SIZE);
+
+ }
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer size.
+ *
+ * @param size Buffer size to use
+ */
+ public MessageWriter(int size) {
+
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteOutputChannel(this);
+ cb = new CharChunk(size);
+ cb.setCharOutputChannel(this);
+ cb.setLimit(size);
+
+ }
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Associated Coyote response.
+ *
+ * @param coyoteResponse Associated Coyote response
+ */
+ public void setResponse(Response coyoteResponse) {
+ this.coyoteResponse = coyoteResponse;
+ }
+
+
+ /**
+ * Get associated Coyote response.
+ *
+ * @return the associated Coyote response
+ */
+ public Response getResponse() {
+ return this.coyoteResponse;
+ }
+
+
+ /**
+ * Is the response output suspended ?
+ *
+ * @return suspended flag value
+ */
+ public boolean isSuspended() {
+ return this.suspended;
+ }
+
+
+ /**
+ * Set the suspended flag.
+ *
+ * @param suspended New suspended flag value
+ */
+ public void setSuspended(boolean suspended) {
+ this.suspended = suspended;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+
+ state = INITIAL_STATE;
+ bytesWritten = 0;
+ charsWritten = 0;
+
+ cb.recycle();
+ bb.recycle();
+ closed = false;
+ suspended = false;
+
+ if (conv!= null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ }
+
+
+ /**
+ * Close the output buffer. This tries to calculate the response size if
+ * the response has not been committed yet.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+
+ if (closed)
+ return;
+ if (suspended)
+ return;
+
+ if ((!coyoteResponse.isCommitted())
+ && (coyoteResponse.getContentLengthLong() == -1)) {
+ // Flushing the char buffer
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ }
+ // If this didn't cause a commit of the response, the final content
+ // length can be calculated
+ if (!coyoteResponse.isCommitted()) {
+ coyoteResponse.setContentLength(bb.getLength());
+ }
+ }
+
+ doFlush(false);
+ closed = true;
+
+ coyoteResponse.finish();
+
+ }
+
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void flush()
+ throws IOException {
+ doFlush(true);
+ }
+
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ protected void doFlush(boolean realFlush)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ doFlush = true;
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ bb.flushBuffer();
+ state = BYTE_STATE;
+ } else if (state == BYTE_STATE) {
+ bb.flushBuffer();
+ } else if (state == INITIAL_STATE) {
+ // If the buffers are empty, commit the response header
+ coyoteResponse.sendHeaders();
+ }
+ doFlush = false;
+
+ if (realFlush) {
+ coyoteResponse.action(ActionCode.ACTION_CLIENT_FLUSH,
+ coyoteResponse);
+ // If some exception occurred earlier, or if some IOE occurred
+ // here, notify the servlet with an IOE
+ if (coyoteResponse.isExceptionPresent()) {
+ throw new ClientAbortException
+ (coyoteResponse.getErrorException());
+ }
+ }
+
+ }
+
+
+ // ------------------------------------------------- Bytes Handling Methods
+
+
+ /**
+ * Sends the buffer data to the client output, checking the
+ * state of Response and calling the right interceptors.
+ *
+ * @param buf Byte buffer to be written to the response
+ * @param off Offset
+ * @param cnt Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void realWriteBytes(byte buf[], int off, int cnt)
+ throws IOException {
+
+ if (closed)
+ return;
+ if (coyoteResponse == null)
+ return;
+
+ // If we really have something to write
+ if (cnt > 0) {
+ // real write to the adapter
+ outputChunk.setBytes(buf, off, cnt);
+ try {
+ coyoteResponse.doWrite(outputChunk);
+ } catch (IOException e) {
+ // An IOException on a write is almost always due to
+ // the remote client aborting the request. Wrap this
+ // so that it can be handled better by the error dispatcher.
+ throw new ClientAbortException(e);
+ }
+ }
+
+ }
+
+
+ public void write(byte b[], int off, int len) throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ writeBytes(b, off, len);
+
+ }
+
+
+ private void writeBytes(byte b[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return;
+
+ bb.append(b, off, len);
+ bytesWritten += len;
+
+ // if called from within flush(), then immediately flush
+ // remaining bytes
+ if (doFlush) {
+ bb.flushBuffer();
+ }
+
+ }
+
+
+ public void writeByte(int b)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ bb.append( (byte)b );
+ bytesWritten++;
+
+ }
+
+
+ // ------------------------------------------------- Chars Handling Methods
+
+
+ public void write(int c)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ cb.append((char) c);
+ charsWritten++;
+
+ }
+
+
+ public void write(char c[])
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ write(c, 0, c.length);
+
+ }
+
+
+ public void write(char c[], int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ cb.append(c, off, len);
+ charsWritten += len;
+
+ }
+
+
+ public void write(StringBuffer sb)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ int len = sb.length();
+ charsWritten += len;
+ cb.append(sb);
+
+ }
+
+
+ /**
+ * Append a string to the buffer
+ */
+ public void write(String s, int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state=CHAR_STATE;
+
+ charsWritten += len;
+ if (s==null)
+ s="null";
+ cb.append( s, off, len );
+
+ }
+
+
+ public void write(String s)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+ if (s==null)
+ s="null";
+ write(s, 0, s.length());
+
+ }
+
+
+ public void flushChars()
+ throws IOException {
+
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ }
+
+
+ public boolean flushCharsNeeded() {
+ return state == CHAR_STATE;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+
+ public void realWriteChars(char c[], int off, int len)
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ conv.convert(c, off, len);
+ conv.flushBuffer(); // ???
+
+ }
+
+
+ public void checkConverter()
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ }
+
+
+ protected void setConverter()
+ throws IOException {
+
+ if (coyoteResponse != null)
+ enc = coyoteResponse.getCharacterEncoding();
+
+ gotEnc = true;
+ if (enc == null)
+ enc = DEFAULT_ENCODING;
+ conv = (C2BConverter) encoders.get(enc);
+ if (conv == null) {
+
+ if (System.getSecurityManager() != null){
+ try{
+ conv = (C2BConverter)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ return new C2BConverter(bb, enc);
+ }
+
+ }
+ );
+ }catch(PrivilegedActionException ex){
+ Exception e = ex.getException();
+ if (e instanceof IOException)
+ throw (IOException)e;
+ }
+ } else {
+ conv = new C2BConverter(bb, enc);
+ }
+
+ encoders.put(enc, conv);
+
+ }
+ }
+
+
+ // -------------------- BufferedOutputStream compatibility
+
+
+ /**
+ * Real write - this buffer will be sent to the client
+ */
+ public void flushBytes()
+ throws IOException {
+
+ bb.flushBuffer();
+
+ }
+
+
+ public int getBytesWritten() {
+ return bytesWritten;
+ }
+
+
+ public int getCharsWritten() {
+ return charsWritten;
+ }
+
+
+ public int getContentWritten() {
+ return bytesWritten + charsWritten;
+ }
+
+
+ /**
+ * True if this buffer hasn't been used ( since recycle() ) -
+ * i.e. no chars or bytes have been added to the buffer.
+ */
+ public boolean isNew() {
+ return (bytesWritten == 0) && (charsWritten == 0);
+ }
+
+
+ public void setBufferSize(int size) {
+ if (size > bb.getLimit()) {// ??????
+ bb.setLimit(size);
+ }
+ }
+
+
+ public void reset() {
+
+ //count=0;
+ bb.recycle();
+ bytesWritten = 0;
+ cb.recycle();
+ charsWritten = 0;
+ gotEnc = false;
+ enc = null;
+ state = INITIAL_STATE;
+ }
+
+
+ public int getBufferSize() {
+ return bb.getLimit();
+ }
+
+
+ public static MessageWriter getWriter(Request req, Response res, int size)
+ {
+ MessageWriter out=(MessageWriter)req.getNote(MessageWriter.WRITER_NOTE);
+ if( out == null ) {
+ if( size<=0 ) {
+ out=new MessageWriter();
+ } else {
+ out=new MessageWriter(size);
+ }
+ out.setResponse(res);
+ req.setNote(MessageWriter.WRITER_NOTE, out );
+ }
+ return out;
+ }
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
Posted by Costin Manolache <co...@gmail.com>.
My understanding is that tomcat can't _distribute_ code that isn't
apache license compatible,
and we shouldn't depend on such code to compile or run a functional tomcat.
Talking about agendas :-), I think that any code that is not required
to have a working servlet container should be in a separate add-on
module. SSL modules are excelent examples. Actually, a lot of the
things that are in the normal tomcat distro would be make good add-on
modules. Firefox is a good example.
Costin
On 11/6/05, Bill Barker <wb...@wilshire.com> wrote:
> Actually (having spent way too much time in Gump-land recently :), Tomcat
> depends on rhino in Gump.
>
> What I'm looking for is a clear statement from the Tomcat PMC about MPL
> compatibility. Sorry about hijacking your commit for my agenda ;-). It
> looks like Christina can't contribute her code for BZ #36133. However, it
> looks like a fun project if I can do it myself.
>
> ----- Original Message -----
> From: "Costin Manolache" <co...@gmail.com>
> To: "Tomcat Developers List" <de...@tomcat.apache.org>
> Sent: Saturday, November 05, 2005 10:33 PM
> Subject: Re: svn commit: r331062 - in
> /tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
>
>
> I think cocoon is also using rhino, and few other projects - ant is
> using it via BSF.
>
> In any case - it is just an example, not required in any way - it's
> easier to do some tests and experiments in a scripting language. The
> build.xml file will just detect if js.jar is available and skip this
> file otherwise ( nothing depends on the JsAdapter ).
>
> Costin
>
> On 11/5/05, Bill Barker <wb...@wilshire.com> wrote:
> >
> > ----- Original Message -----
> > From: <co...@apache.org>
> > To: <to...@jakarta.apache.org>
> > Sent: Saturday, November 05, 2005 7:13 PM
> > Subject: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote:
> > ./
> > adapters/ standalone/
> >
> >
> > > Author: costin
> > > Date: Sat Nov 5 19:13:06 2005
> > > New Revision: 331062
> > >
> > > URL: http://svn.apache.org/viewcvs?rev=331062&view=rev
> > > Log:
> > > Code for testing ( and using ) coyote standalone.
> > <snip/>
> > > +import org.mozilla.javascript.Context;
> > > +import org.mozilla.javascript.EvaluatorException;
> > > +import org.mozilla.javascript.Function;
> > > +import org.mozilla.javascript.JavaScriptException;
> > > +import org.mozilla.javascript.Scriptable;
> > > +import org.mozilla.javascript.ScriptableObject;
> > > +import org.mozilla.javascript.WrappedException;
> >
> > I take it that MPL is compatible with ASF? For those that don't want to
> > search the archives, my vote is +1 on this issue. I just wanted to make
> > certain that everyone is aware of this, since it is buried in a long
> > commit
> > message.
> >
> >
> >
> > This message is intended only for the use of the person(s) listed above as
> > the intended recipient(s), and may contain information that is PRIVILEGED
> > and CONFIDENTIAL. If you are not an intended recipient, you may not read,
> > copy, or distribute this message or any attachment. If you received this
> > communication in error, please notify us immediately by e-mail and then
> > delete all copies of this message and any attachments.
> >
> > In addition you should be aware that ordinary (unencrypted) e-mail sent
> > through the Internet is not secure. Do not send confidential or sensitive
> > information, such as social security numbers, account numbers, personal
> > identification numbers and passwords, to us via ordinary (unencrypted)
> > e-mail.
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: dev-help@tomcat.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
>
>
>
> This message is intended only for the use of the person(s) listed above as the intended recipient(s), and may contain information that is PRIVILEGED and CONFIDENTIAL. If you are not an intended recipient, you may not read, copy, or distribute this message or any attachment. If you received this communication in error, please notify us immediately by e-mail and then delete all copies of this message and any attachments.
>
> In addition you should be aware that ordinary (unencrypted) e-mail sent through the Internet is not secure. Do not send confidential or sensitive information, such as social security numbers, account numbers, personal identification numbers and passwords, to us via ordinary (unencrypted) e-mail.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote:
./ adapters/ standalone/
Posted by Mark Thomas <ma...@apache.org>.
Bill Barker wrote:
> What I'm looking for is a clear statement from the Tomcat PMC about MPL
> compatibility.
The short answer is we can distribute unmodified MPL licenced binaries
with some caveats. See Special Order 6B in this link.
http://www.apache.org/foundation/records/minutes/2005/board_minutes_2005_08_17.txt
For a very unofficial summary of the various licences see
http://wiki.apache.org/jakarta/LicenceIssues
There is also the legal discuss mailing list where we can ask for
clarifications if required.
http://mail-archives.apache.org/mod_mbox/www-legal-discuss/
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
Posted by Bill Barker <wb...@wilshire.com>.
Actually (having spent way too much time in Gump-land recently :), Tomcat
depends on rhino in Gump.
What I'm looking for is a clear statement from the Tomcat PMC about MPL
compatibility. Sorry about hijacking your commit for my agenda ;-). It
looks like Christina can't contribute her code for BZ #36133. However, it
looks like a fun project if I can do it myself.
----- Original Message -----
From: "Costin Manolache" <co...@gmail.com>
To: "Tomcat Developers List" <de...@tomcat.apache.org>
Sent: Saturday, November 05, 2005 10:33 PM
Subject: Re: svn commit: r331062 - in
/tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
I think cocoon is also using rhino, and few other projects - ant is
using it via BSF.
In any case - it is just an example, not required in any way - it's
easier to do some tests and experiments in a scripting language. The
build.xml file will just detect if js.jar is available and skip this
file otherwise ( nothing depends on the JsAdapter ).
Costin
On 11/5/05, Bill Barker <wb...@wilshire.com> wrote:
>
> ----- Original Message -----
> From: <co...@apache.org>
> To: <to...@jakarta.apache.org>
> Sent: Saturday, November 05, 2005 7:13 PM
> Subject: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote:
> ./
> adapters/ standalone/
>
>
> > Author: costin
> > Date: Sat Nov 5 19:13:06 2005
> > New Revision: 331062
> >
> > URL: http://svn.apache.org/viewcvs?rev=331062&view=rev
> > Log:
> > Code for testing ( and using ) coyote standalone.
> <snip/>
> > +import org.mozilla.javascript.Context;
> > +import org.mozilla.javascript.EvaluatorException;
> > +import org.mozilla.javascript.Function;
> > +import org.mozilla.javascript.JavaScriptException;
> > +import org.mozilla.javascript.Scriptable;
> > +import org.mozilla.javascript.ScriptableObject;
> > +import org.mozilla.javascript.WrappedException;
>
> I take it that MPL is compatible with ASF? For those that don't want to
> search the archives, my vote is +1 on this issue. I just wanted to make
> certain that everyone is aware of this, since it is buried in a long
> commit
> message.
>
>
>
> This message is intended only for the use of the person(s) listed above as
> the intended recipient(s), and may contain information that is PRIVILEGED
> and CONFIDENTIAL. If you are not an intended recipient, you may not read,
> copy, or distribute this message or any attachment. If you received this
> communication in error, please notify us immediately by e-mail and then
> delete all copies of this message and any attachments.
>
> In addition you should be aware that ordinary (unencrypted) e-mail sent
> through the Internet is not secure. Do not send confidential or sensitive
> information, such as social security numbers, account numbers, personal
> identification numbers and passwords, to us via ordinary (unencrypted)
> e-mail.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
This message is intended only for the use of the person(s) listed above as the intended recipient(s), and may contain information that is PRIVILEGED and CONFIDENTIAL. If you are not an intended recipient, you may not read, copy, or distribute this message or any attachment. If you received this communication in error, please notify us immediately by e-mail and then delete all copies of this message and any attachments.
In addition you should be aware that ordinary (unencrypted) e-mail sent through the Internet is not secure. Do not send confidential or sensitive information, such as social security numbers, account numbers, personal identification numbers and passwords, to us via ordinary (unencrypted) e-mail.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
Posted by Costin Manolache <co...@gmail.com>.
I think cocoon is also using rhino, and few other projects - ant is
using it via BSF.
In any case - it is just an example, not required in any way - it's
easier to do some tests and experiments in a scripting language. The
build.xml file will just detect if js.jar is available and skip this
file otherwise ( nothing depends on the JsAdapter ).
Costin
On 11/5/05, Bill Barker <wb...@wilshire.com> wrote:
>
> ----- Original Message -----
> From: <co...@apache.org>
> To: <to...@jakarta.apache.org>
> Sent: Saturday, November 05, 2005 7:13 PM
> Subject: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./
> adapters/ standalone/
>
>
> > Author: costin
> > Date: Sat Nov 5 19:13:06 2005
> > New Revision: 331062
> >
> > URL: http://svn.apache.org/viewcvs?rev=331062&view=rev
> > Log:
> > Code for testing ( and using ) coyote standalone.
> <snip/>
> > +import org.mozilla.javascript.Context;
> > +import org.mozilla.javascript.EvaluatorException;
> > +import org.mozilla.javascript.Function;
> > +import org.mozilla.javascript.JavaScriptException;
> > +import org.mozilla.javascript.Scriptable;
> > +import org.mozilla.javascript.ScriptableObject;
> > +import org.mozilla.javascript.WrappedException;
>
> I take it that MPL is compatible with ASF? For those that don't want to
> search the archives, my vote is +1 on this issue. I just wanted to make
> certain that everyone is aware of this, since it is buried in a long commit
> message.
>
>
>
> This message is intended only for the use of the person(s) listed above as the intended recipient(s), and may contain information that is PRIVILEGED and CONFIDENTIAL. If you are not an intended recipient, you may not read, copy, or distribute this message or any attachment. If you received this communication in error, please notify us immediately by e-mail and then delete all copies of this message and any attachments.
>
> In addition you should be aware that ordinary (unencrypted) e-mail sent through the Internet is not secure. Do not send confidential or sensitive information, such as social security numbers, account numbers, personal identification numbers and passwords, to us via ordinary (unencrypted) e-mail.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./ adapters/ standalone/
Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message -----
From: <co...@apache.org>
To: <to...@jakarta.apache.org>
Sent: Saturday, November 05, 2005 7:13 PM
Subject: svn commit: r331062 - in /tomcat/sandbox/java/org/apache/coyote: ./
adapters/ standalone/
> Author: costin
> Date: Sat Nov 5 19:13:06 2005
> New Revision: 331062
>
> URL: http://svn.apache.org/viewcvs?rev=331062&view=rev
> Log:
> Code for testing ( and using ) coyote standalone.
<snip/>
> +import org.mozilla.javascript.Context;
> +import org.mozilla.javascript.EvaluatorException;
> +import org.mozilla.javascript.Function;
> +import org.mozilla.javascript.JavaScriptException;
> +import org.mozilla.javascript.Scriptable;
> +import org.mozilla.javascript.ScriptableObject;
> +import org.mozilla.javascript.WrappedException;
I take it that MPL is compatible with ASF? For those that don't want to
search the archives, my vote is +1 on this issue. I just wanted to make
certain that everyone is aware of this, since it is buried in a long commit
message.
This message is intended only for the use of the person(s) listed above as the intended recipient(s), and may contain information that is PRIVILEGED and CONFIDENTIAL. If you are not an intended recipient, you may not read, copy, or distribute this message or any attachment. If you received this communication in error, please notify us immediately by e-mail and then delete all copies of this message and any attachments.
In addition you should be aware that ordinary (unencrypted) e-mail sent through the Internet is not secure. Do not send confidential or sensitive information, such as social security numbers, account numbers, personal identification numbers and passwords, to us via ordinary (unencrypted) e-mail.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org