jetty-9 removed HttpParser.isPersistent

This commit is contained in:
Greg Wilkins 2012-08-17 22:06:55 +10:00
parent e7cad67ace
commit 7c94fd5f3c
11 changed files with 115 additions and 81 deletions

View File

@ -1262,5 +1262,36 @@ public class HttpFields implements Iterable<HttpFields.Field>
{ {
return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]");
} }
/* ------------------------------------------------------------ */
public boolean contains(String value)
{
if (_value==null)
return false;
if (value.equalsIgnoreCase(_value))
return true;
String[] split = _value.split("\\s*,\\s*");
for (String s : split)
{
if (value.equalsIgnoreCase(s))
return true;
}
if (_next!=null)
return _next.contains(value);
return false;
}
}
/* ------------------------------------------------------------ */
public boolean contains(HttpHeader header, String value)
{
Field field = getField(header);
if (field==null)
return false;
return field.contains(value);
} }
} }

View File

@ -62,7 +62,6 @@ public class HttpParser
private HttpHeaderValue _value; private HttpHeaderValue _value;
private String _valueString; private String _valueString;
private int _responseStatus; private int _responseStatus;
private boolean _persistent;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
private State _state=State.START; private State _state=State.START;
@ -186,12 +185,6 @@ public class HttpParser
return _state == state; return _state == state;
} }
/* ------------------------------------------------------------------------------- */
public boolean isPersistent()
{
return _persistent;
}
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/* Quick lookahead for the start state looking for a request method or a HTTP version, /* Quick lookahead for the start state looking for a request method or a HTTP version,
* otherwise skip white space until something else to parse. * otherwise skip white space until something else to parse.
@ -218,7 +211,6 @@ public class HttpParser
if (_version!=null) if (_version!=null)
{ {
buffer.position(buffer.position()+_version.asString().length()+1); buffer.position(buffer.position()+_version.asString().length()+1);
_persistent=_version.getVerion()>=HttpVersion.HTTP_1_1.getVerion();
_state=State.SPACE1; _state=State.SPACE1;
return; return;
} }
@ -309,7 +301,6 @@ public class HttpParser
badMessage(buffer, "Unknown Version"); badMessage(buffer, "Unknown Version");
return true; return true;
} }
_persistent=_version.getVerion()>=HttpVersion.HTTP_1_1.getVerion();
_state=State.SPACE1; _state=State.SPACE1;
} }
else if (ch < HttpTokens.SPACE && ch>=0) else if (ch < HttpTokens.SPACE && ch>=0)
@ -377,10 +368,9 @@ public class HttpParser
_uri=_utf8.toString(); _uri=_utf8.toString();
_utf8.reset(); _utf8.reset();
return_from_parse|=_requestHandler.startRequest(_method,_methodString,_uri,null); return_from_parse|=_requestHandler.startRequest(_method,_methodString,_uri,null);
_persistent=false;
_state=State.END; _state=State.END;
BufferUtil.clear(buffer); BufferUtil.clear(buffer);
return_from_parse|=_handler.headerComplete(false,_persistent); return_from_parse|=_handler.headerComplete();
return_from_parse|=_handler.messageComplete(_contentPosition); return_from_parse|=_handler.messageComplete(_contentPosition);
} }
else else
@ -410,7 +400,6 @@ public class HttpParser
_string.setLength(0); _string.setLength(0);
buffer.position(buffer.position()+_version.asString().length()-1); buffer.position(buffer.position()+_version.asString().length()-1);
_eol=buffer.get(); _eol=buffer.get();
_persistent=_version.getVerion()>=HttpVersion.HTTP_1_1.getVerion();
_state=State.HEADER; _state=State.HEADER;
return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version); return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version);
} }
@ -429,10 +418,9 @@ public class HttpParser
{ {
// HTTP/0.9 // HTTP/0.9
return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, null); return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, null);
_persistent=false;
_state=State.END; _state=State.END;
BufferUtil.clear(buffer); BufferUtil.clear(buffer);
return_from_parse|=_handler.headerComplete(false,_persistent); return_from_parse|=_handler.headerComplete();
return_from_parse|=_handler.messageComplete(_contentPosition); return_from_parse|=_handler.messageComplete(_contentPosition);
} }
} }
@ -450,7 +438,6 @@ public class HttpParser
} }
_eol=ch; _eol=ch;
_persistent=_version.getVerion()>=HttpVersion.HTTP_1_1.getVerion();
_state=State.HEADER; _state=State.HEADER;
return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version); return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version);
continue; continue;
@ -568,37 +555,6 @@ public class HttpParser
} }
} }
break; break;
case CONNECTION:
switch(_value==null?HttpHeaderValue.UNKNOWN:_value)
{
case CLOSE:
_persistent=false;
break;
case KEEP_ALIVE:
_persistent=true;
break;
default: // No match, may be multi valued
{
for (String v : _valueString.toString().split(","))
{
HttpHeaderValue val=HttpHeaderValue.CACHE.get(v.trim());
switch(val==null?HttpHeaderValue.UNKNOWN:val)
{
case CLOSE:
_persistent=false;
break;
case KEEP_ALIVE:
_persistent=true;
break;
}
}
break;
}
}
} }
} }
@ -634,24 +590,23 @@ public class HttpParser
{ {
case EOF_CONTENT: case EOF_CONTENT:
_state=State.EOF_CONTENT; _state=State.EOF_CONTENT;
_persistent=false; return_from_parse|=_handler.headerComplete();
return_from_parse|=_handler.headerComplete(true,_persistent);
break; break;
case CHUNKED_CONTENT: case CHUNKED_CONTENT:
_state=State.CHUNKED_CONTENT; _state=State.CHUNKED_CONTENT;
return_from_parse|=_handler.headerComplete(true,_persistent); return_from_parse|=_handler.headerComplete();
break; break;
case NO_CONTENT: case NO_CONTENT:
return_from_parse|=_handler.headerComplete(false,_persistent); return_from_parse|=_handler.headerComplete();
_state=State.END; _state=State.END;
return_from_parse|=_handler.messageComplete(_contentPosition); return_from_parse|=_handler.messageComplete(_contentPosition);
break; break;
default: default:
_state=State.CONTENT; _state=State.CONTENT;
return_from_parse|=_handler.headerComplete(true,_persistent); return_from_parse|=_handler.headerComplete();
break; break;
} }
} }
@ -1103,7 +1058,6 @@ public class HttpParser
private void badMessage(ByteBuffer buffer, String reason) private void badMessage(ByteBuffer buffer, String reason)
{ {
BufferUtil.clear(buffer); BufferUtil.clear(buffer);
_persistent=false;
_state=State.END; _state=State.END;
_handler.badMessage(400, reason); _handler.badMessage(400, reason);
} }
@ -1111,8 +1065,6 @@ public class HttpParser
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public void inputShutdown() public void inputShutdown()
{ {
_persistent=false;
// was this unexpected? // was this unexpected?
switch(_state) switch(_state)
{ {
@ -1139,15 +1091,18 @@ public class HttpParser
{ {
if (_state!=State.END && _state!=State.CLOSED) if (_state!=State.END && _state!=State.CLOSED)
LOG.warn("Closing {}",this); LOG.warn("Closing {}",this);
_persistent=false; _state=State.CLOSED;
reset(); _endOfContent=EndOfContent.UNKNOWN_CONTENT;
_contentPosition=0;
_responseStatus=0;
_contentChunk=null;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public void reset() public void reset()
{ {
// reset state // reset state
_state=_persistent?State.START:State.CLOSED; _state=State.START;
_endOfContent=EndOfContent.UNKNOWN_CONTENT; _endOfContent=EndOfContent.UNKNOWN_CONTENT;
_contentPosition=0; _contentPosition=0;
_responseStatus=0; _responseStatus=0;
@ -1159,19 +1114,16 @@ public class HttpParser
{ {
this._state=state; this._state=state;
_endOfContent=EndOfContent.UNKNOWN_CONTENT; _endOfContent=EndOfContent.UNKNOWN_CONTENT;
if (state==State.CLOSED)
_persistent=false;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
@Override @Override
public String toString() public String toString()
{ {
return String.format("%s{s=%s,c=%d,p=%b}", return String.format("%s{s=%s,c=%d}",
getClass().getSimpleName(), getClass().getSimpleName(),
_state, _state,
_contentLength, _contentLength);
_persistent);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -1185,7 +1137,7 @@ public class HttpParser
{ {
public boolean content(ByteBuffer ref); public boolean content(ByteBuffer ref);
public boolean headerComplete(boolean hasBody,boolean persistent); public boolean headerComplete();
public boolean messageComplete(long contentLength); public boolean messageComplete(long contentLength);

View File

@ -112,9 +112,8 @@ public class HttpTester
} }
@Override @Override
public boolean headerComplete(boolean hasBody, boolean persistent) public boolean headerComplete()
{ {
if (hasBody)
_content=new ByteArrayOutputStream(); _content=new ByteArrayOutputStream();
return false; return false;
} }

View File

@ -436,4 +436,25 @@ public class HttpFieldsTest
} }
@Test
public void testContains() throws Exception
{
HttpFields header = new HttpFields();
header.add("0", "");
header.add("1", ",");
header.add("2", ",,");
header.add("3", "abc");
header.add("4", "def");
header.add("5", "abc,def,hig");
header.add("6", "abc");
header.add("6", "def");
header.add("6", "hig");
for (int i=0;i<7;i++)
{
assertFalse(""+i,header.getField(""+i).contains("xyz"));
assertEquals(""+i,i>=4,header.getField(""+i).contains("def"));
}
}
} }

View File

@ -60,7 +60,7 @@ public class HttpGeneratorServerTest
} }
@Override @Override
public boolean headerComplete(boolean hasBody,boolean persistent) public boolean headerComplete()
{ {
_content= null; _content= null;
return false; return false;

View File

@ -735,7 +735,7 @@ public class HttpParserTest
} }
@Override @Override
public boolean headerComplete(boolean hasBody,boolean persistent) public boolean headerComplete()
{ {
//System.err.println("headerComplete"); //System.err.println("headerComplete");
_content= null; _content= null;

View File

@ -500,14 +500,17 @@ public abstract class HttpChannel
} }
@Override @Override
public boolean headerComplete(boolean hasBody,boolean persistent) public boolean headerComplete()
{ {
_requests++; _requests++;
boolean persistent;
switch (_version) switch (_version)
{ {
case HTTP_0_9: case HTTP_0_9:
persistent=false;
break; break;
case HTTP_1_0: case HTTP_1_0:
persistent=_request.getHttpFields().contains(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE.asString());
if (persistent) if (persistent)
_response.getHttpFields().add(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE); _response.getHttpFields().add(HttpHeader.CONNECTION,HttpHeaderValue.KEEP_ALIVE);
@ -516,6 +519,7 @@ public abstract class HttpChannel
break; break;
case HTTP_1_1: case HTTP_1_1:
persistent=!_request.getHttpFields().contains(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE.asString());
if (!persistent) if (!persistent)
_response.getHttpFields().add(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE); _response.getHttpFields().add(HttpHeader.CONNECTION,HttpHeaderValue.CLOSE);
@ -537,8 +541,11 @@ public abstract class HttpChannel
break; break;
default: default:
throw new IllegalStateException();
} }
_request.setPersistent(persistent);
// Either handle now or wait for first content/message complete // Either handle now or wait for first content/message complete
if (_expect100Continue) if (_expect100Continue)
return true; return true;

View File

@ -252,16 +252,19 @@ public class HttpConnection extends AbstractConnection
// Parse the buffer // Parse the buffer
if (_parser.parseNext(_requestBuffer)) if (_parser.parseNext(_requestBuffer))
{ {
// reset header count
_headerBytes=0;
// For most requests, there will not be a body, so we can try to recycle the buffer now // For most requests, there will not be a body, so we can try to recycle the buffer now
releaseRequestBuffer(); releaseRequestBuffer();
_headerBytes=0; if (!_channel.getRequest().isPersistent())
_generator.setPersistent(false);
// The parser returned true, which indicates the channel is ready // The parser returned true, which indicates the channel is ready
// to handle a request. Call the channel and this will either handle the // to handle a request. Call the channel and this will either handle the
// request/response to completion OR if the request suspends, the channel // request/response to completion OR if the request suspends, the channel
// will be left in !idle state so our outer loop will exit. // will be left in !idle state so our outer loop will exit.
if (!_parser.isPersistent())
_generator.setPersistent(false);
_channel.handle(); _channel.handle();
// Return if the channel is still processing the request // Return if the channel is still processing the request

View File

@ -159,6 +159,7 @@ public class Request implements HttpServletRequest
private SessionManager _sessionManager; private SessionManager _sessionManager;
private long _timeStamp; private long _timeStamp;
private long _dispatchTime; private long _dispatchTime;
private boolean _persistent;
private HttpURI _uri; private HttpURI _uri;
@ -185,6 +186,18 @@ public class Request implements HttpServletRequest
return _in; return _in;
} }
/* ------------------------------------------------------------ */
public boolean isPersistent()
{
return _persistent;
}
/* ------------------------------------------------------------ */
public void setPersistent(boolean persistent)
{
_persistent = persistent;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void addEventListener(final EventListener listener) public void addEventListener(final EventListener listener)
{ {

View File

@ -47,7 +47,9 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.session.HashSessionIdManager; import org.eclipse.jetty.server.session.HashSessionIdManager;
import org.eclipse.jetty.server.session.HashSessionManager; import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.server.session.HashedSession; import org.eclipse.jetty.server.session.HashedSession;
import org.hamcrest.Matchers;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -585,6 +587,7 @@ public class ResponseTest
{ {
server.setHandler(new AbstractHandler() server.setHandler(new AbstractHandler()
{ {
@Override
public void handle(String string, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String string, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
response.setStatus(200); response.setStatus(200);
@ -607,14 +610,14 @@ public class ResponseTest
LineNumberReader reader = new LineNumberReader(new InputStreamReader(socket.getInputStream())); LineNumberReader reader = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
String line = reader.readLine(); String line = reader.readLine();
assertTrue(line!=null && line.startsWith("HTTP/1.1 200 OK")); Assert.assertThat(line,Matchers.startsWith("HTTP/1.1 200 OK"));
// look for blank line // look for blank line
while (line!=null && line.length()>0) while (line!=null && line.length()>0)
line = reader.readLine(); line = reader.readLine();
// Read the first line of the GET // Read the first line of the GET
line = reader.readLine(); line = reader.readLine();
assertTrue(line!=null && line.startsWith("HTTP/1.1 200 OK")); Assert.assertThat(line,Matchers.startsWith("HTTP/1.1 200 OK"));
String last=null; String last=null;
while (line!=null) while (line!=null)

View File

@ -16,10 +16,10 @@ package org.eclipse.jetty.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** AttributesMap. /** AttributesMap.
@ -33,7 +33,7 @@ public class AttributesMap implements Attributes
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public AttributesMap() public AttributesMap()
{ {
_map=new HashMap<String,Object>(); _map=new ConcurrentHashMap<String,Object>();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -45,13 +45,14 @@ public class AttributesMap implements Attributes
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public AttributesMap(AttributesMap map) public AttributesMap(AttributesMap map)
{ {
_map=new HashMap<String,Object>(map._map); _map=new ConcurrentHashMap<String,Object>(map._map);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.util.Attributes#removeAttribute(java.lang.String) * @see org.eclipse.jetty.util.Attributes#removeAttribute(java.lang.String)
*/ */
@Override
public void removeAttribute(String name) public void removeAttribute(String name)
{ {
_map.remove(name); _map.remove(name);
@ -61,6 +62,7 @@ public class AttributesMap implements Attributes
/* /*
* @see org.eclipse.jetty.util.Attributes#setAttribute(java.lang.String, java.lang.Object) * @see org.eclipse.jetty.util.Attributes#setAttribute(java.lang.String, java.lang.Object)
*/ */
@Override
public void setAttribute(String name, Object attribute) public void setAttribute(String name, Object attribute)
{ {
if (attribute==null) if (attribute==null)
@ -73,6 +75,7 @@ public class AttributesMap implements Attributes
/* /*
* @see org.eclipse.jetty.util.Attributes#getAttribute(java.lang.String) * @see org.eclipse.jetty.util.Attributes#getAttribute(java.lang.String)
*/ */
@Override
public Object getAttribute(String name) public Object getAttribute(String name)
{ {
return _map.get(name); return _map.get(name);
@ -82,6 +85,7 @@ public class AttributesMap implements Attributes
/* /*
* @see org.eclipse.jetty.util.Attributes#getAttributeNames() * @see org.eclipse.jetty.util.Attributes#getAttributeNames()
*/ */
@Override
public Enumeration<String> getAttributeNames() public Enumeration<String> getAttributeNames()
{ {
return Collections.enumeration(_map.keySet()); return Collections.enumeration(_map.keySet());
@ -120,6 +124,7 @@ public class AttributesMap implements Attributes
/* /*
* @see org.eclipse.jetty.util.Attributes#clear() * @see org.eclipse.jetty.util.Attributes#clear()
*/ */
@Override
public void clearAttributes() public void clearAttributes()
{ {
_map.clear(); _map.clear();