jetty-9 work in progress on remaking connection contracts

This commit is contained in:
Greg Wilkins 2012-03-16 10:06:23 +11:00
parent 10cc4ca498
commit c04a195256
12 changed files with 104 additions and 74 deletions

View File

@ -634,6 +634,17 @@ public class HttpFields implements Iterable<HttpFields.Field>
_names.put(header.toString(), field);
}
/* ------------------------------------------------------------ */
/**
* Remove a field.
*
* @param name
*/
public void remove(HttpHeader name)
{
remove(name.toString());
}
/* ------------------------------------------------------------ */
/**
* Remove a field.

View File

@ -19,6 +19,7 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.http.HttpTokens.Content;
/* ------------------------------------------------------------ */
/**
@ -36,29 +37,28 @@ public class HttpGenerator
public enum Action { FLUSH, COMPLETE, PREPARE };
public enum State { START, COMMITTING, COMMITTING_COMPLETING, COMMITTED, COMPLETING, END };
public enum Result { NEED_CHUNK,NEED_HEADER,NEED_BUFFER,FLUSH,FLUSH_CONTENT,OK,SHUTDOWN_OUT};
public enum Content { UNKNOWN_CONTENT,NO_CONTENT,EOF_CONTENT,CONTENT_LENGTH,CHUNKED_CONTENT,SELF_DEFINING_CONTENT };
// other statics
public static final int CHUNK_SIZE = 12;
interface Info
public interface Info
{
HttpVersion getHttpVersion();
HttpFields getHttpFields();
boolean isHead();
long getContentLength();
}
interface RequestInfo extends Info
public interface RequestInfo extends Info
{
String getMethod();
String getURI();
}
interface ResponseInfo extends Info
public interface ResponseInfo extends Info
{
int getStatus();
String getReason();
boolean isHead();
}
// data

View File

@ -147,6 +147,12 @@ public enum HttpHeader
return _bytesColonSpace;
}
/* ------------------------------------------------------------ */
public boolean is(String s)
{
return _string.equalsIgnoreCase(s);
}
/* ------------------------------------------------------------ */
@Override
public String toString()

View File

@ -21,7 +21,7 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.http.HttpGenerator.Content;
import org.eclipse.jetty.http.HttpTokens.Content;
public class HttpParser
{

View File

@ -52,10 +52,17 @@ public enum HttpScheme
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public boolean is(String s)
{
return _string.equalsIgnoreCase(s);
}
/* ------------------------------------------------------------ */
@Override
public String toString()
{
return _string;
}
}

View File

@ -28,5 +28,7 @@ public interface HttpTokens
static final byte TAB= 0x09;
public enum Content { UNKNOWN_CONTENT,NO_CONTENT,EOF_CONTENT,CONTENT_LENGTH,CHUNKED_CONTENT,SELF_DEFINING_CONTENT }
}

View File

@ -70,6 +70,12 @@ public class MimeTypes
return _buffer.asReadOnlyBuffer();
}
/* ------------------------------------------------------------ */
public boolean is(String s)
{
return _string.equalsIgnoreCase(s);
}
/* ------------------------------------------------------------ */
@Override
public String toString()

View File

@ -55,12 +55,6 @@ public class HttpGeneratorClientTest
return _fields;
}
@Override
public boolean isHead()
{
return false;
}
@Override
public long getContentLength()
{

View File

@ -16,6 +16,8 @@ package org.eclipse.jetty.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import javax.servlet.DispatcherType;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;

View File

@ -95,7 +95,6 @@ public abstract class HttpServerConnection extends AbstractConnection
protected final Connector _connector;
protected final Server _server;
protected final HttpURI _uri;
protected final HttpFields _requestFields;
protected final Request _request;

View File

@ -64,12 +64,11 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.NIOBuffer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.util.Attributes;
@ -115,7 +114,7 @@ import org.eclipse.jetty.util.log.Logger;
*
*
*/
public class Request implements HttpServletRequest
public class Request implements HttpServletRequest, HttpGenerator.RequestInfo
{
public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig";
private static final Logger LOG = Log.getLogger(Request.class);
@ -154,7 +153,7 @@ public class Request implements HttpServletRequest
private boolean _paramsExtracted;
private String _pathInfo;
private int _port;
private String _protocol = HttpVersion.HTTP_1_1;
private String _protocol = HttpVersion.HTTP_1_1.toString();
private String _queryEncoding;
private String _queryString;
private BufferedReader _reader;
@ -250,7 +249,7 @@ public class Request implements HttpServletRequest
{
content_type = HttpFields.valueParameters(content_type,null);
if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE
if (MimeTypes.Type.FORM_ENCODED.is(content_type) && _inputState == __NONE
&& (HttpMethod.POST.equals(getMethod()) || HttpMethod.PUT.equals(getMethod())))
{
int content_length = getContentLength();
@ -419,9 +418,10 @@ public class Request implements HttpServletRequest
*/
public int getContentLength()
{
return (int)_connection.getRequestFields().getLongField(HttpHeader.CONTENT_LENGTH_BUFFER);
return (int)_connection.getRequestFields().getLongField(HttpHeader.CONTENT_LENGTH.toString());
}
/* ------------------------------------------------------------ */
public long getContentRead()
{
if (_connection == null || _connection.getParser() == null)
@ -436,7 +436,7 @@ public class Request implements HttpServletRequest
*/
public String getContentType()
{
return _connection.getRequestFields().getStringField(HttpHeader.CONTENT_TYPE_BUFFER);
return _connection.getRequestFields().getStringField(HttpHeader.CONTENT_TYPE);
}
/* ------------------------------------------------------------ */
@ -468,7 +468,7 @@ public class Request implements HttpServletRequest
_cookiesExtracted = true;
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.COOKIE_BUFFER);
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.COOKIE.toString());
// Handle no cookies
if (enm != null)
@ -576,7 +576,7 @@ public class Request implements HttpServletRequest
*/
public Locale getLocale()
{
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE,HttpFields.__separators);
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
// handle no locale
if (enm == null || !enm.hasMoreElements())
@ -613,7 +613,7 @@ public class Request implements HttpServletRequest
public Enumeration getLocales()
{
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE,HttpFields.__separators);
Enumeration enm = _connection.getRequestFields().getValues(HttpHeader.ACCEPT_LANGUAGE.toString(),HttpFields.__separators);
// handle no locale
if (enm == null || !enm.hasMoreElements())
@ -1020,22 +1020,22 @@ public class Request implements HttpServletRequest
return _serverName;
// Return host from header field
ByteBuffer hostPort = _connection.getRequestFields().get(HttpHeader.HOST_BUFFER);
String hostPort = _connection.getRequestFields().getStringField(HttpHeader.HOST);
if (hostPort != null)
{
loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();)
loop: for (int i = hostPort.length(); i-- > 0;)
{
char ch = (char)(0xff & hostPort.peek(i));
char ch = (char)(0xff & hostPort.charAt(i));
switch (ch)
{
case ']':
break loop;
case ':':
_serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex()));
_serverName = hostPort.substring(0,i);
try
{
_port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1));
_port = StringUtil.toInt(hostPort.substring(i+1));
}
catch (NumberFormatException e)
{
@ -1052,9 +1052,10 @@ public class Request implements HttpServletRequest
return _serverName;
}
}
if (_serverName == null || _port < 0)
{
_serverName = BufferUtil.to8859_1_String(hostPort);
_serverName = hostPort;
_port = 0;
}
@ -1404,7 +1405,7 @@ public class Request implements HttpServletRequest
_method = null;
_pathInfo = null;
_port = 0;
_protocol = HttpVersion.HTTP_1_1;
_protocol = HttpVersion.HTTP_1_1.toString();
_queryEncoding = null;
_queryString = null;
_requestedSessionId = null;
@ -1515,8 +1516,7 @@ public class Request implements HttpServletRequest
final ByteBuffer byteBuffer = (ByteBuffer)value;
synchronized (byteBuffer)
{
NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true);
((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(byteBuffer);
}
}
catch (IOException e)
@ -1627,7 +1627,7 @@ public class Request implements HttpServletRequest
*/
public void setContentType(String contentType)
{
_connection.getRequestFields().put(HttpHeader.CONTENT_TYPE_BUFFER,contentType);
_connection.getRequestFields().put(HttpHeader.CONTENT_TYPE,contentType);
}

View File

@ -35,7 +35,6 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.BufferCache.CachedBuffer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
@ -78,7 +77,6 @@ public class Response implements HttpServletResponse
private String _reason;
private Locale _locale;
private String _mimeType;
private CachedBuffer _cachedMimeType;
private String _characterEncoding;
private boolean _explicitEncoding;
private String _contentType;
@ -105,7 +103,6 @@ public class Response implements HttpServletResponse
_reason=null;
_locale=null;
_mimeType=null;
_cachedMimeType=null;
_characterEncoding=null;
_explicitEncoding=false;
_contentType=null;
@ -181,7 +178,7 @@ public class Response implements HttpServletResponse
path = (path == null?"":path);
int port=uri.getPort();
if (port<0)
port = HttpScheme.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
port = HttpScheme.HTTPS.toString().equalsIgnoreCase(uri.getScheme())?443:80;
if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
request.getServerPort()!=port ||
!path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts
@ -250,13 +247,13 @@ public class Response implements HttpServletResponse
if (suffix<0)
{
return url+
((HttpScheme.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpScheme.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
sessionURLPrefix+id;
}
return url.substring(0,suffix)+
((HttpScheme.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpScheme.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
sessionURLPrefix+id+url.substring(suffix);
}
@ -334,7 +331,7 @@ public class Response implements HttpServletResponse
else
{
setHeader(HttpHeader.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
setContentType(MimeTypes.TEXT_HTML_8859_1);
setContentType(MimeTypes.Type.TEXT_HTML_8859_1.toString());
ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048);
if (message != null)
{
@ -382,7 +379,6 @@ public class Response implements HttpServletResponse
_connection.getRequestFields().remove(HttpHeader.CONTENT_LENGTH);
_characterEncoding=null;
_mimeType=null;
_cachedMimeType=null;
}
complete();
@ -494,13 +490,37 @@ public class Response implements HttpServletResponse
_connection.getResponseFields().addDateField(name, date);
}
/* ------------------------------------------------------------ */
/*
* @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
*/
public void setHeader(HttpHeader name, String value)
{
if (HttpHeader.CONTENT_TYPE == name)
setContentType(value);
else
{
if (_connection.isIncluding())
return;
_connection.getResponseFields().put(name, value);
if (HttpHeader.CONTENT_LENGTH==name)
{
if (value==null)
_connection._generator.setContentLength(-1);
else
_connection._generator.setContentLength(Long.parseLong(value));
}
}
}
/* ------------------------------------------------------------ */
/*
* @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
*/
public void setHeader(String name, String value)
{
if (HttpHeader.CONTENT_TYPE.equalsIgnoreCase(name))
if (HttpHeader.CONTENT_TYPE.is(name))
setContentType(value);
else
{
@ -512,7 +532,7 @@ public class Response implements HttpServletResponse
return;
}
_connection.getResponseFields().put(name, value);
if (HttpHeader.CONTENT_LENGTH.equalsIgnoreCase(name))
if (HttpHeader.CONTENT_LENGTH.is(name))
{
if (value==null)
_connection._generator.setContentLength(-1);
@ -565,7 +585,7 @@ public class Response implements HttpServletResponse
}
_connection.getResponseFields().add(name, value);
if (HttpHeader.CONTENT_LENGTH.equalsIgnoreCase(name))
if (HttpHeader.CONTENT_LENGTH.is(name))
_connection._generator.setContentLength(Long.parseLong(value));
}
@ -578,7 +598,7 @@ public class Response implements HttpServletResponse
if (!_connection.isIncluding())
{
_connection.getResponseFields().putLongField(name, value);
if (HttpHeader.CONTENT_LENGTH.equalsIgnoreCase(name))
if (HttpHeader.CONTENT_LENGTH.is(name))
_connection._generator.setContentLength(value);
}
}
@ -592,7 +612,7 @@ public class Response implements HttpServletResponse
if (!_connection.isIncluding())
{
_connection.getResponseFields().addLongField(name, value);
if (HttpHeader.CONTENT_LENGTH.equalsIgnoreCase(name))
if (HttpHeader.CONTENT_LENGTH.is(name))
_connection._generator.setContentLength(value);
}
}
@ -690,10 +710,6 @@ public class Response implements HttpServletResponse
if (encoding==null)
{
/* implementation of educated defaults */
if(_cachedMimeType != null)
encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType);
if (encoding==null)
encoding = StringUtil.__ISO_8859_1;
@ -726,10 +742,7 @@ public class Response implements HttpServletResponse
if (_characterEncoding!=null)
{
_characterEncoding=null;
if (_cachedMimeType!=null)
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_cachedMimeType);
else
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_mimeType);
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_mimeType);
}
}
else
@ -742,15 +755,6 @@ public class Response implements HttpServletResponse
if (i0<0)
{
_contentType=null;
if(_cachedMimeType!=null)
{
CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
if (content_type!=null)
{
_contentType=content_type.toString();
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,content_type);
}
}
if (_contentType==null)
{
@ -848,7 +852,6 @@ public class Response implements HttpServletResponse
if (_locale==null)
_characterEncoding=null;
_mimeType=null;
_cachedMimeType=null;
_contentType=null;
_connection.getResponseFields().remove(HttpHeader.CONTENT_TYPE);
}
@ -863,7 +866,7 @@ public class Response implements HttpServletResponse
// Extract params off mimetype
_mimeType=contentType.substring(0,i0).trim();
_cachedMimeType=MimeTypes.CACHE.get(_mimeType);
MimeTypes.Type mime_type=MimeTypes.CACHE.get(_mimeType);
// Look for charset
int i1=contentType.indexOf("charset=",i0+1);
@ -878,9 +881,9 @@ public class Response implements HttpServletResponse
// strip the charset and ignore;
if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
{
if (_cachedMimeType!=null)
if (mime_type!=null)
{
CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
CachedBuffer content_type = mime_type.getAssociate(_characterEncoding);
if (content_type!=null)
{
_contentType=content_type.toString();
@ -912,12 +915,12 @@ public class Response implements HttpServletResponse
else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
{
// The params are just the char encoding
_cachedMimeType=MimeTypes.CACHE.get(_mimeType);
mime_type=MimeTypes.CACHE.get(_mimeType);
_characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
if (_cachedMimeType!=null)
if (mime_type!=null)
{
CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
CachedBuffer content_type = mime_type.getAssociate(_characterEncoding);
if (content_type!=null)
{
_contentType=content_type.toString();
@ -950,7 +953,7 @@ public class Response implements HttpServletResponse
}
else // No encoding in the params.
{
_cachedMimeType=null;
mime_type=null;
_contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
_connection.getResponseFields().put(HttpHeader.CONTENT_TYPE,_contentType);
}