changeset 1057:afc9610dc12e

remove AbstractGenerator
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 08 Nov 2016 04:05:04 -0700
parents 7d872cc72ec2
children 419bf9c03d84
files src/org/eclipse/jetty/http/AbstractGenerator.java src/org/eclipse/jetty/http/HttpGenerator.java
diffstat 2 files changed, 326 insertions(+), 397 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/eclipse/jetty/http/AbstractGenerator.java	Tue Nov 08 01:19:36 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.http;
-
-import java.io.IOException;
-
-import org.eclipse.jetty.io.JBuffer;
-import org.eclipse.jetty.io.Buffers;
-import org.eclipse.jetty.io.BufferUtil;
-import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.EofException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/* ------------------------------------------------------------ */
-/**
- * Abstract Generator. Builds HTTP Messages.
- *
- * Currently this class uses a system parameter "jetty.direct.writers" to control
- * two optional writer to byte conversions. buffer.writers=true will probably be
- * faster, but will consume more memory.   This option is just for testing and tuning.
- *
- */
-abstract class AbstractGenerator
-{
-	private static final Logger LOG = LoggerFactory.getLogger(AbstractGenerator.class);
-
-	public static final boolean LAST=true;
-	public static final boolean MORE=false;
-
-	// states
-	final static int STATE_HEADER = 0;
-	final static int STATE_CONTENT = 2;
-	final static int STATE_FLUSHING = 3;
-	final static int STATE_END = 4;
-
-	// data
-
-	final Buffers _buffers; // source of buffers
-	final EndPoint _endp;
-
-	int _state = STATE_HEADER;
-
-	int _status = 0;
-	int _version = HttpVersions.HTTP_1_1_ORDINAL;
-	JBuffer _reason;
-	JBuffer _method;
-	String _uri;
-
-	long _contentWritten = 0;
-	long _contentLength = HttpTokens.UNKNOWN_CONTENT;
-	boolean _last = false;
-	boolean _head = false;
-	boolean _noContent = false;
-	Boolean _persistent = null;
-
-	JBuffer _header; // JBuffer for HTTP header (and maybe small _content)
-	JBuffer _buffer; // JBuffer for copy of passed _content
-	JBuffer _content; // JBuffer passed to addContent
-
-
-	/* ------------------------------------------------------------------------------- */
-	/**
-	 * Constructor.
-	 *
-	 * @param buffers buffer pool
-	 * @param io the end point
-	 */
-	AbstractGenerator(Buffers buffers, EndPoint io)
-	{
-		this._buffers = buffers;
-		this._endp = io;
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * Add content.
-	 * 
-	 * @param content
-	 * @param last
-	 * @throws IllegalArgumentException if <code>content</code> is {@link JBuffer#isImmutable immutable}.
-	 * @throws IllegalStateException If the request is not expecting any more content,
-	 *   or if the buffers are full and cannot be flushed.
-	 * @throws IOException if there is a problem flushing the buffers.
-	 */
-	public abstract void addContent(JBuffer content, boolean last) throws IOException;
-
-	abstract boolean isRequest();
-
-	public final boolean isOpen()
-	{
-		return _endp.isOpen();
-	}
-
-	public final void resetBuffer()
-	{
-		if(_state>=STATE_FLUSHING)
-			throw new IllegalStateException("Flushed");
-
-		_last = false;
-		_persistent = null;
-		_contentWritten = 0;
-		_contentLength = HttpTokens.UNKNOWN_CONTENT;
-		_content=null;
-		if (_buffer!=null)
-			_buffer.clear();
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * @return Returns the contentBufferSize.
-	 */
-	public final int getContentBufferSize()
-	{
-		if (_buffer==null)
-			_buffer = _buffers.getBuffer();
-		return _buffer.capacity();
-	}
-
-	public final JBuffer getUncheckedBuffer()
-	{
-		return _buffer;
-	}
-
-	public final boolean isComplete()
-	{
-		return _state == STATE_END;
-	}
-
-	public final boolean isIdle()
-	{
-		return _state == STATE_HEADER && _method==null && _status==0;
-	}
-
-	public final boolean isCommitted()
-	{
-		return _state != STATE_HEADER;
-	}
-
-	public final void setContentLength(long value)
-	{
-		if (value<0)
-			_contentLength=HttpTokens.UNKNOWN_CONTENT;
-		else
-			_contentLength=value;
-	}
-
-	public final void setHead(boolean head)
-	{
-		_head = head;
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * @return <code>false</code> if the connection should be closed after a request has been read,
-	 * <code>true</code> if it should be used for additional requests.
-	 */
-	public final boolean isPersistent()
-	{
-		return _persistent!=null
-		?_persistent.booleanValue()
-		:(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL);
-	}
-
-	public final void setPersistent(boolean persistent)
-	{
-		_persistent = persistent;
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * @param version The version of the client the response is being sent to (NB. Not the version
-	 *            in the response, which is the version of the server).
-	 */
-	public final void setVersion(int version)
-	{
-		if (_state != STATE_HEADER)
-			throw new IllegalStateException("STATE!=START "+_state);
-		_version = version;
-		if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null)
-			_noContent=true;
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * @param status The status code to send.
-	 * @param reason the status message to send.
-	 */
-	public final void setResponse(int status, String reason)
-	{
-		if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START");
-		_method=null;
-		_status = status;
-		if (reason!=null)
-		{
-			int len=reason.length();
-
-			// TODO don't hard code
-			if (len>1024)
-				len=1024;
-			_reason = BufferUtil.newBuffer(len);
-			for (int i=0;i<len;i++)
-			{
-				char ch = reason.charAt(i);
-				if (ch!='\r'&&ch!='\n')
-					_reason.put((byte)ch);
-				else
-					_reason.put((byte)' ');
-			}
-		}
-	}
-
-	public final void completeUncheckedAddContent()
-	{
-		if (_noContent)
-		{
-			if(_buffer!=null)
-				_buffer.clear();
-		}
-		else
-		{
-			_contentWritten+=_buffer.remaining();
-			if (_head)
-				_buffer.clear();
-		}
-	}
-
-	public boolean isBufferFull()
-	{
-		if (_buffer != null && _buffer.space()==0)
-		{
-			if (_buffer.remaining()==0)
-				_buffer.compact();
-			return _buffer.space()==0;
-		}
-
-		return _content!=null && _content.remaining()>0;
-	}
-
-	public final boolean isWritten()
-	{
-		return _contentWritten>0;
-	}
-
-	public final boolean isAllContentWritten()
-	{
-		return _contentLength>=0 && _contentWritten>=_contentLength;
-	}
-
-	public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException;
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * Complete the message.
-	 *
-	 * @throws IOException
-	 */
-	public void complete() throws IOException
-	{
-		if (_state == STATE_HEADER)
-		{
-			throw new IllegalStateException("State==HEADER");
-		}
-
-		if (_contentLength >= 0 && _contentLength != _contentWritten && !_head)
-		{
-			if (LOG.isDebugEnabled())
-				LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength);
-			_persistent = false;
-		}
-	}
-
-	public abstract int flushBuffer() throws IOException;
-
-
-	public final void flush(long maxIdleTime) throws IOException
-	{
-		// block until everything is flushed
-		long now=System.currentTimeMillis();
-		long end=now+maxIdleTime;
-		JBuffer content = _content;
-		JBuffer buffer = _buffer;
-		if (content!=null && content.remaining()>0 || buffer!=null && buffer.remaining()>0 || isBufferFull())
-		{
-			flushBuffer();
-
-			while (now<end && (content!=null && content.remaining()>0 ||buffer!=null && buffer.remaining()>0) && _endp.isOpen()&& !_endp.isOutputShutdown())
-			{
-				blockForOutput(end-now);
-				now=System.currentTimeMillis();
-			}
-		}
-	}
-
-	/* ------------------------------------------------------------ */
-	/**
-	 * Utility method to send an error response. If the builder is not committed, this call is
-	 * equivalent to a setResponse, addContent and complete call.
-	 *
-	 * @param code The error code
-	 * @param reason The error reason
-	 * @param content Contents of the error page
-	 * @param close True if the connection should be closed
-	 * @throws IOException if there is a problem flushing the response
-	 */
-	public final void sendError(int code, String reason, String content, boolean close) throws IOException
-	{
-		if (close)
-			_persistent=false;
-		if (isCommitted())
-		{
-			LOG.debug("sendError on committed: {} {}",code,reason);
-		}
-		else
-		{
-			LOG.debug("sendError: {} {}",code,reason);
-			setResponse(code, reason);
-			if (content != null)
-			{
-				completeHeader(null, false);
-				addContent(BufferUtil.wrap(content), LAST);
-			}
-			else if (code>=400)
-			{
-				completeHeader(null, false);
-				addContent(BufferUtil.wrap("Error: "+(reason==null?(""+code):reason)), LAST);
-			}
-			else
-			{
-				completeHeader(null, true);
-			}
-			complete();
-		}
-	}
-
-	public final long getContentWritten()
-	{
-		return _contentWritten;
-	}
-
-
-	public final void blockForOutput(long maxIdleTime) throws IOException
-	{
-		if (_endp.isBlocking())
-		{
-			try
-			{
-				flushBuffer();
-			}
-			catch(IOException e)
-			{
-				_endp.close();
-				throw e;
-			}
-		}
-		else
-		{
-			if (!_endp.blockWritable(maxIdleTime))
-			{
-				_endp.close();
-				throw new EofException("timeout");
-			}
-
-			flushBuffer();
-		}
-	}
-
-}
--- a/src/org/eclipse/jetty/http/HttpGenerator.java	Tue Nov 08 01:19:36 2016 -0700
+++ b/src/org/eclipse/jetty/http/HttpGenerator.java	Tue Nov 08 04:05:04 2016 -0700
@@ -39,7 +39,7 @@
  *
  *
  */
-public final class HttpGenerator extends AbstractGenerator
+public final class HttpGenerator
 {
 	private static final Logger LOG = LoggerFactory.getLogger(HttpGenerator.class);
 
@@ -101,11 +101,6 @@
 	private boolean _bufferChunked = false;
 
 
-	public HttpGenerator(Buffers buffers, EndPoint io)
-	{
-		super(buffers,io);
-	}
-
 	public void shutdown() {
 		if (_persistent!=null && !_persistent && _endp!=null && !_endp.isOutputShutdown())
 		{
@@ -235,11 +230,10 @@
 		return _buffer.space()-(_contentLength == HttpTokens.CHUNKED_CONTENT?CHUNK_SPACE:0);
 	}
 
-	@Override
 	public boolean isBufferFull()
 	{
 		// Should we flush the buffers?
-		return super.isBufferFull() || _bufferChunked || _bypass  || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE);
+		return isBufferFull2() || _bufferChunked || _bypass  || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE);
 	}
 
 	public void send1xx(int code) throws IOException
@@ -279,7 +273,6 @@
 		}
 	}
 
-	@Override
 	boolean isRequest()
 	{
 		return _method!=null;
@@ -290,7 +283,6 @@
 		return _method==null;
 	}
 
-	@Override
 	public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
 	{
 		if (_state != STATE_HEADER)
@@ -701,13 +693,12 @@
 	 *
 	 * @throws IOException
 	 */
-	@Override
 	public void complete() throws IOException
 	{
 		if (_state == STATE_END)
 			return;
 
-		super.complete();
+		complete2();
 
 		if (_state < STATE_FLUSHING)
 		{
@@ -719,7 +710,6 @@
 		flushBuffer();
 	}
 
-	@Override
 	public int flushBuffer() throws IOException
 	{
 		try
@@ -993,4 +983,327 @@
 				buffer == null ? -1 : buffer.remaining(),
 				content == null ? -1 : content.remaining());
 	}
+
+
+
+
+
+
+
+
+
+
+
+
+	// AbstractGenerator
+
+	public static final boolean LAST=true;
+	public static final boolean MORE=false;
+
+	// states
+	private final static int STATE_HEADER = 0;
+	private final static int STATE_CONTENT = 2;
+	private final static int STATE_FLUSHING = 3;
+	private final static int STATE_END = 4;
+
+	// data
+
+	private final Buffers _buffers; // source of buffers
+	private final EndPoint _endp;
+
+	private int _state = STATE_HEADER;
+
+	private int _status = 0;
+	private int _version = HttpVersions.HTTP_1_1_ORDINAL;
+	private JBuffer _reason;
+	private JBuffer _method;
+	private String _uri;
+
+	private long _contentWritten = 0;
+	private long _contentLength = HttpTokens.UNKNOWN_CONTENT;
+	private boolean _last = false;
+	private boolean _head = false;
+	private boolean _noContent = false;
+	private Boolean _persistent = null;
+
+	private JBuffer _header; // JBuffer for HTTP header (and maybe small _content)
+	private JBuffer _buffer; // JBuffer for copy of passed _content
+	private JBuffer _content; // JBuffer passed to addContent
+
+
+	public HttpGenerator(Buffers buffers, EndPoint io)
+	{
+		this._buffers = buffers;
+		this._endp = io;
+	}
+
+	public final boolean isOpen()
+	{
+		return _endp.isOpen();
+	}
+
+	public final void resetBuffer()
+	{
+		if(_state>=STATE_FLUSHING)
+			throw new IllegalStateException("Flushed");
+
+		_last = false;
+		_persistent = null;
+		_contentWritten = 0;
+		_contentLength = HttpTokens.UNKNOWN_CONTENT;
+		_content=null;
+		if (_buffer!=null)
+			_buffer.clear();
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the contentBufferSize.
+	 */
+	public final int getContentBufferSize()
+	{
+		if (_buffer==null)
+			_buffer = _buffers.getBuffer();
+		return _buffer.capacity();
+	}
+
+	public final JBuffer getUncheckedBuffer()
+	{
+		return _buffer;
+	}
+
+	public final boolean isComplete()
+	{
+		return _state == STATE_END;
+	}
+
+	public final boolean isIdle()
+	{
+		return _state == STATE_HEADER && _method==null && _status==0;
+	}
+
+	public final boolean isCommitted()
+	{
+		return _state != STATE_HEADER;
+	}
+
+	public final void setContentLength(long value)
+	{
+		if (value<0)
+			_contentLength=HttpTokens.UNKNOWN_CONTENT;
+		else
+			_contentLength=value;
+	}
+
+	public final void setHead(boolean head)
+	{
+		_head = head;
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return <code>false</code> if the connection should be closed after a request has been read,
+	 * <code>true</code> if it should be used for additional requests.
+	 */
+	public final boolean isPersistent()
+	{
+		return _persistent!=null
+		?_persistent.booleanValue()
+		:(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL);
+	}
+
+	public final void setPersistent(boolean persistent)
+	{
+		_persistent = persistent;
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param version The version of the client the response is being sent to (NB. Not the version
+	 *            in the response, which is the version of the server).
+	 */
+	public final void setVersion(int version)
+	{
+		if (_state != STATE_HEADER)
+			throw new IllegalStateException("STATE!=START "+_state);
+		_version = version;
+		if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null)
+			_noContent=true;
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param status The status code to send.
+	 * @param reason the status message to send.
+	 */
+	public final void setResponse(int status, String reason)
+	{
+		if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START");
+		_method=null;
+		_status = status;
+		if (reason!=null)
+		{
+			int len=reason.length();
+
+			// TODO don't hard code
+			if (len>1024)
+				len=1024;
+			_reason = BufferUtil.newBuffer(len);
+			for (int i=0;i<len;i++)
+			{
+				char ch = reason.charAt(i);
+				if (ch!='\r'&&ch!='\n')
+					_reason.put((byte)ch);
+				else
+					_reason.put((byte)' ');
+			}
+		}
+	}
+
+	public final void completeUncheckedAddContent()
+	{
+		if (_noContent)
+		{
+			if(_buffer!=null)
+				_buffer.clear();
+		}
+		else
+		{
+			_contentWritten+=_buffer.remaining();
+			if (_head)
+				_buffer.clear();
+		}
+	}
+
+	private boolean isBufferFull2()
+	{
+		if (_buffer != null && _buffer.space()==0)
+		{
+			if (_buffer.remaining()==0)
+				_buffer.compact();
+			return _buffer.space()==0;
+		}
+
+		return _content!=null && _content.remaining()>0;
+	}
+
+	public final boolean isWritten()
+	{
+		return _contentWritten>0;
+	}
+
+	public final boolean isAllContentWritten()
+	{
+		return _contentLength>=0 && _contentWritten>=_contentLength;
+	}
+
+
+	private void complete2() throws IOException
+	{
+		if (_state == STATE_HEADER)
+		{
+			throw new IllegalStateException("State==HEADER");
+		}
+
+		if (_contentLength >= 0 && _contentLength != _contentWritten && !_head)
+		{
+			if (LOG.isDebugEnabled())
+				LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength);
+			_persistent = false;
+		}
+	}
+
+
+	public final void flush(long maxIdleTime) throws IOException
+	{
+		// block until everything is flushed
+		long now=System.currentTimeMillis();
+		long end=now+maxIdleTime;
+		JBuffer content = _content;
+		JBuffer buffer = _buffer;
+		if (content!=null && content.remaining()>0 || buffer!=null && buffer.remaining()>0 || isBufferFull())
+		{
+			flushBuffer();
+
+			while (now<end && (content!=null && content.remaining()>0 ||buffer!=null && buffer.remaining()>0) && _endp.isOpen()&& !_endp.isOutputShutdown())
+			{
+				blockForOutput(end-now);
+				now=System.currentTimeMillis();
+			}
+		}
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * Utility method to send an error response. If the builder is not committed, this call is
+	 * equivalent to a setResponse, addContent and complete call.
+	 *
+	 * @param code The error code
+	 * @param reason The error reason
+	 * @param content Contents of the error page
+	 * @param close True if the connection should be closed
+	 * @throws IOException if there is a problem flushing the response
+	 */
+	public final void sendError(int code, String reason, String content, boolean close) throws IOException
+	{
+		if (close)
+			_persistent=false;
+		if (isCommitted())
+		{
+			LOG.debug("sendError on committed: {} {}",code,reason);
+		}
+		else
+		{
+			LOG.debug("sendError: {} {}",code,reason);
+			setResponse(code, reason);
+			if (content != null)
+			{
+				completeHeader(null, false);
+				addContent(BufferUtil.wrap(content), LAST);
+			}
+			else if (code>=400)
+			{
+				completeHeader(null, false);
+				addContent(BufferUtil.wrap("Error: "+(reason==null?(""+code):reason)), LAST);
+			}
+			else
+			{
+				completeHeader(null, true);
+			}
+			complete();
+		}
+	}
+
+	public final long getContentWritten()
+	{
+		return _contentWritten;
+	}
+
+
+	public final void blockForOutput(long maxIdleTime) throws IOException
+	{
+		if (_endp.isBlocking())
+		{
+			try
+			{
+				flushBuffer();
+			}
+			catch(IOException e)
+			{
+				_endp.close();
+				throw e;
+			}
+		}
+		else
+		{
+			if (!_endp.blockWritable(maxIdleTime))
+			{
+				_endp.close();
+				throw new EofException("timeout");
+			}
+
+			flushBuffer();
+		}
+	}
+
 }