Miscellaneous refactorings.

This commit is contained in:
Simone Bordet 2014-06-17 16:04:08 +02:00
parent 85cb290e1c
commit 2b494fde0e
9 changed files with 106 additions and 176 deletions

View File

@ -18,10 +18,6 @@
package org.eclipse.jetty.fcgi.server;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
@ -31,7 +27,6 @@ import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -54,7 +49,7 @@ public class HttpChannelOverFCGI extends HttpChannel
private String path;
private String query;
private String version;
private HostPortHttpField host;
private HostPortHttpField hostPort;
public HttpChannelOverFCGI(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput input)
{
@ -72,13 +67,19 @@ public class HttpChannelOverFCGI extends HttpChannel
query = field.getValue();
else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(field.getName()))
version = field.getValue();
else if (field.getHeader()==HttpHeader.HOST)
{
host=new HostPortHttpField(HttpHeader.HOST,HttpHeader.HOST.asString(),field.getValue());
fields.add(host);
}
else
fields.add(field);
processField(field);
}
private void processField(HttpField field)
{
HttpField httpField = convertHeader(field);
if (httpField != null)
{
fields.add(httpField);
if (HttpHeader.HOST.is(httpField.getName()))
hostPort = (HostPortHttpField)httpField;
}
}
public void onRequest()
@ -86,11 +87,7 @@ public class HttpChannelOverFCGI extends HttpChannel
String uri = path;
if (query != null && query.length() > 0)
uri += "?" + query;
if (host==null)
onRequest(new MetaData.Request(HttpVersion.fromString(version),method,new HttpURI(uri),fields,null,0));
else
onRequest(new MetaData.Request(HttpVersion.fromString(version),method,new HttpURI(uri),fields,host.getHost(),host.getPort()));
onRequest(new MetaData.Request(HttpVersion.fromString(version), method, new HttpURI(uri), fields, hostPort));
}
private HttpField convertHeader(HttpField field)
@ -109,7 +106,11 @@ public class HttpChannelOverFCGI extends HttpChannel
httpName.append(Character.toUpperCase(part.charAt(0)));
httpName.append(part.substring(1).toLowerCase(Locale.ENGLISH));
}
return new HttpField(httpName.toString(), field.getValue());
String headerName = httpName.toString();
if (HttpHeader.HOST.is(headerName))
return new HostPortHttpField(field.getValue());
else
return new HttpField(httpName.toString(), field.getValue());
}
return null;
}

View File

@ -16,37 +16,36 @@
// ========================================================================
//
package org.eclipse.jetty.http;
/* ------------------------------------------------------------------------------- */
public class BadMessage extends Error
public class BadMessageException extends RuntimeException
{
final int _code;
final String _reason;
public BadMessage()
public BadMessageException()
{
this(400,null);
}
public BadMessage(int code)
public BadMessageException(int code)
{
this(code,null);
}
public BadMessage(String reason)
public BadMessageException(String reason)
{
this(400,reason);
}
public BadMessage(int code,String reason)
public BadMessageException(int code, String reason)
{
_code=code;
_reason=reason;
}
public BadMessage(int code,String reason,Throwable cause)
public BadMessageException(int code, String reason, Throwable cause)
{
super(cause);
_code=code;
@ -62,6 +61,4 @@ public class BadMessage extends Error
{
return _reason;
}
}
}

View File

@ -27,20 +27,15 @@ import org.eclipse.jetty.util.StringUtil;
/**
*/
public class HostPortHttpField extends HttpField
{
public final String _host;
public final int _port;
{
private final String _host;
private final int _port;
public HostPortHttpField(String authority)
{
this(HttpHeader.HOST,HttpHeader.HOST.asString(),authority);
}
public HostPortHttpField(HttpHeader header, String authority)
{
this(header,header.asString(),authority);
}
public HostPortHttpField(HttpHeader header, String name, String authority)
{
super(header,name,authority);
@ -52,13 +47,13 @@ public class HostPortHttpField extends HttpField
// ipv6reference
int close=authority.lastIndexOf(']');
if (close<0)
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad ipv6");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad ipv6");
_host=authority.substring(1,close);
if (authority.length()>close+1)
{
if (authority.charAt(close+1)!=':')
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad ipv6 port");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad ipv6 port");
_port=StringUtil.toInt(authority,close+2);
}
else
@ -80,13 +75,13 @@ public class HostPortHttpField extends HttpField
}
}
}
catch (BadMessage bm)
catch (BadMessageException bm)
{
throw bm;
}
catch(Exception e)
{
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad HostPort",e);
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad HostPort",e);
}
}

View File

@ -25,7 +25,6 @@ import org.eclipse.jetty.http.HttpTokens.EndOfContent;
import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.ArrayTrie;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
@ -339,7 +338,7 @@ public class HttpParser
if (_cr)
{
if (ch!=HttpTokens.LINE_FEED)
throw new BadMessage("Bad EOL");
throw new BadMessageException("Bad EOL");
_cr=false;
return ch;
}
@ -354,7 +353,7 @@ public class HttpParser
_headerBytes++;
ch=buffer.get();
if (ch!=HttpTokens.LINE_FEED)
throw new BadMessage("Bad EOL");
throw new BadMessageException("Bad EOL");
}
else
{
@ -366,7 +365,7 @@ public class HttpParser
}
// Only LF or TAB acceptable special characters
else if (!(ch==HttpTokens.LINE_FEED || ch==HttpTokens.TAB))
throw new BadMessage("Illegal character");
throw new BadMessageException("Illegal character");
}
return ch;
@ -416,13 +415,13 @@ public class HttpParser
else if (ch==0)
break;
else if (ch<0)
throw new BadMessage();
throw new BadMessageException();
// count this white space as a header byte to avoid DOS
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
{
LOG.warn("padding is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.BAD_REQUEST_400);
throw new BadMessageException(HttpStatus.BAD_REQUEST_400);
}
}
return false;
@ -466,7 +465,7 @@ public class HttpParser
if (_state==State.URI)
{
LOG.warn("URI is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414);
throw new BadMessageException(HttpStatus.REQUEST_URI_TOO_LONG_414);
}
else
{
@ -474,7 +473,7 @@ public class HttpParser
LOG.warn("request is too large >"+_maxHeaderBytes);
else
LOG.warn("response is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413);
throw new BadMessageException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413);
}
}
@ -491,7 +490,7 @@ public class HttpParser
setState(State.SPACE1);
}
else if (ch < HttpTokens.SPACE)
throw new BadMessage(ch<0?"Illegal character":"No URI");
throw new BadMessageException(ch<0?"Illegal character":"No URI");
else
_string.append((char)ch);
break;
@ -503,11 +502,11 @@ public class HttpParser
String version=takeString();
_version=HttpVersion.CACHE.get(version);
if (_version==null)
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Unknown Version");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Unknown Version");
setState(State.SPACE1);
}
else if (ch < HttpTokens.SPACE)
throw new BadMessage(ch<0?"Illegal character":"No Status");
throw new BadMessageException(ch<0?"Illegal character":"No Status");
else
_string.append((char)ch);
break;
@ -540,7 +539,7 @@ public class HttpParser
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
{
LOG.warn("URI is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414);
throw new BadMessageException(HttpStatus.REQUEST_URI_TOO_LONG_414);
}
if (_uri.remaining()<=len)
{
@ -558,7 +557,7 @@ public class HttpParser
}
else if (ch < HttpTokens.SPACE)
{
throw new BadMessage(HttpStatus.BAD_REQUEST_400,_requestHandler!=null?"No URI":"No Status");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,_requestHandler!=null?"No URI":"No Status");
}
break;
@ -578,7 +577,7 @@ public class HttpParser
}
else
{
throw new BadMessage();
throw new BadMessageException();
}
break;
@ -591,7 +590,7 @@ public class HttpParser
{
// HTTP/0.9
_uri.flip();
throw new BadMessage("HTTP/0.9 not supported");
throw new BadMessageException("HTTP/0.9 not supported");
}
else
{
@ -631,7 +630,7 @@ public class HttpParser
if (_method==HttpMethod.PROXY)
{
if (!(_requestHandler instanceof ProxyHandler))
throw new BadMessage();
throw new BadMessageException();
_uri.flip();
String protocol=BufferUtil.toString(_uri);
@ -682,11 +681,11 @@ public class HttpParser
{
// HTTP/0.9
_uri.flip();
throw new BadMessage("HTTP/0.9 not supported");
throw new BadMessageException("HTTP/0.9 not supported");
}
}
else if (ch<0)
throw new BadMessage();
throw new BadMessageException();
break;
case REQUEST_VERSION:
@ -698,7 +697,7 @@ public class HttpParser
_version=HttpVersion.CACHE.get(takeString());
}
if (_version==null)
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Unknown Version");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Unknown Version");
// Should we try to cache header fields?
if (_connectionFields==null && _version.getVersion()>=HttpVersion.HTTP_1_1.getVersion())
@ -721,7 +720,7 @@ public class HttpParser
else if (ch>=HttpTokens.SPACE)
_string.append((char)ch);
else
throw new BadMessage();
throw new BadMessageException();
break;
@ -741,7 +740,7 @@ public class HttpParser
_length=_string.length();
}
else
throw new BadMessage();
throw new BadMessageException();
break;
default:
@ -774,7 +773,7 @@ public class HttpParser
catch(NumberFormatException e)
{
LOG.ignore(e);
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad Content-Length");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad Content-Length");
}
if (_contentLength <= 0)
_endOfContent=EndOfContent.NO_CONTENT;
@ -792,7 +791,7 @@ public class HttpParser
_endOfContent=EndOfContent.CHUNKED_CONTENT;
else if (_valueString.contains(HttpHeaderValue.CHUNKED.toString()))
{
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad chunking");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad chunking");
}
}
break;
@ -865,7 +864,7 @@ public class HttpParser
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
{
LOG.warn("Header is too large >"+_maxHeaderBytes);
throw new BadMessage(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413);
throw new BadMessageException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413);
}
switch (_state)
@ -876,7 +875,7 @@ public class HttpParser
case HttpTokens.COLON:
case HttpTokens.SPACE:
case HttpTokens.TAB:
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"Bad Continuation");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad Continuation");
case HttpTokens.LINE_FEED:
{
@ -887,7 +886,7 @@ public class HttpParser
// Was there a required host header?
if (!_host && _version!=HttpVersion.HTTP_1_0 && _requestHandler!=null)
{
throw new BadMessage(HttpStatus.BAD_REQUEST_400,"No Host");
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"No Host");
}
// is it a response that cannot have a body?
@ -940,7 +939,7 @@ public class HttpParser
{
// now handle the ch
if (ch<=HttpTokens.SPACE)
throw new BadMessage();
throw new BadMessageException();
if (buffer.hasRemaining())
{
@ -1057,7 +1056,7 @@ public class HttpParser
break;
}
throw new BadMessage("Illegal character");
throw new BadMessageException("Illegal character");
case HEADER_VALUE:
if (ch>HttpTokens.SPACE || ch<0)
@ -1071,7 +1070,7 @@ public class HttpParser
if (ch==HttpTokens.SPACE || ch==HttpTokens.TAB)
break;
throw new BadMessage();
throw new BadMessageException();
case HEADER_IN_VALUE:
if (ch>=HttpTokens.SPACE || ch<0 || ch==HttpTokens.TAB)
@ -1100,7 +1099,7 @@ public class HttpParser
setState(State.HEADER);
break;
}
throw new BadMessage("Illegal character");
throw new BadMessageException("Illegal character");
default:
throw new IllegalStateException(_state.toString());
@ -1228,7 +1227,7 @@ public class HttpParser
return false;
}
catch(BadMessage e)
catch(BadMessageException e)
{
BufferUtil.clear(buffer);
@ -1597,6 +1596,6 @@ public class HttpParser
return _string.toString();
_string.append((char)ch);
}
throw new BadMessage();
throw new BadMessageException();
}
}

View File

@ -16,16 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.http;
import java.util.Iterator;
import java.util.List;
/* ------------------------------------------------------------ */
/**
*/
public class MetaData implements Iterable<HttpField>
{
private final HttpVersion _version;
@ -63,73 +57,50 @@ public class MetaData implements Iterable<HttpField>
return _fields;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof MetaData))
return false;
MetaData m = (MetaData)o;
HttpFields lm=m.getFields();
int s=0;
for (HttpField field: this)
{
s++;
if (!lm.contains(field))
return false;
}
if (s!=lm.size())
return false;
return true;
}
@Override
public String toString()
{
StringBuilder out = new StringBuilder();
for (HttpField field: this)
out.append(field).append('\n');
out.append(field).append(System.lineSeparator());
return out.toString();
}
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
/* -------------------------------------------------------- */
public static class Request extends MetaData
{
private final String _method;
private final HttpScheme _scheme;
private final String _host;
private final int _port;
private final HttpURI _uri;
private final HostPortHttpField _hostPort;
private final HttpScheme _scheme;
public Request(HttpVersion version, String method, HttpURI uri, HttpFields fields,String host, int port)
public Request(HttpVersion version, String method, HttpURI uri, HttpFields fields, HostPortHttpField hostPort)
{
super(version,fields);
_host=host;
_port=port;
_method=method;
_uri=uri;
String scheme=uri.getScheme();
if (scheme==null)
_scheme=HttpScheme.HTTP;
_hostPort = hostPort;
String scheme = uri.getScheme();
if (scheme == null)
{
_scheme = HttpScheme.HTTP;
}
else
{
HttpScheme s = HttpScheme.CACHE.get(scheme);
_scheme=s==null?HttpScheme.HTTP:s;
_scheme = s == null ? HttpScheme.HTTP : s;
}
}
// TODO: review this constructor: host/port parameters are ignored, and code duplication should be avoided.
public Request(HttpVersion version, HttpScheme scheme, String method, String authority, String host, int port, String path, HttpFields fields)
{
super(version,fields);
_host=host;
_port=port;
_method=method;
_uri=new HttpURI(path); // TODO - this is not so efficient!
_hostPort = new HostPortHttpField(authority);
_scheme=scheme;
}
@ -157,12 +128,12 @@ public class MetaData implements Iterable<HttpField>
public String getHost()
{
return _host;
return _hostPort.getHost();
}
public int getPort()
{
return _port;
return _hostPort.getPort();
}
public HttpURI getURI()
@ -170,25 +141,12 @@ public class MetaData implements Iterable<HttpField>
return _uri;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Request))
return false;
Request r = (Request)o;
if (!_method.equals(r._method) ||
!_scheme.equals(r._scheme) ||
!_uri.equals(r._uri))
return false;
return super.equals(o);
}
@Override
public String toString()
{
return _method+" "+_scheme+"://"+_host+':'+_port+_uri+" HTTP/2\n"+super.toString();
return String.format("%s %s://%s:%d%s HTTP/2%s%s",
getMethod(), getScheme(), getHost(), getPort(), getURI(), System.lineSeparator(), super.toString());
}
}
/* -------------------------------------------------------- */
@ -221,20 +179,10 @@ public class MetaData implements Iterable<HttpField>
return _status;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Response))
return false;
Response r = (Response)o;
if (_status!=r._status)
return false;
return super.equals(o);
}
@Override
public String toString()
{
return "HTTP/2 "+_status+"\n"+super.toString();
return String.format("HTTP/2 %d%s%s", getStatus(), System.lineSeparator(), super.toString());
}
}
}

View File

@ -66,7 +66,7 @@ public class HttpChannelOverHTTP2 extends HttpChannel
// Based on that, some browser does not send the header, but it's
// important that applications can find it (e.g. GzipFilter).
HttpFields fields = request.getFields();
if (!fields.contains(ACCEPT_ENCODING_GZIP))
if (!fields.contains(HttpHeader.ACCEPT_ENCODING, "gzip"))
fields.add(ACCEPT_ENCODING_GZIP);
onRequest(request);

View File

@ -29,7 +29,7 @@ import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.http.BadMessage;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator;
@ -500,7 +500,7 @@ public class HttpChannel implements Runnable
_request.setRequestURI("");
}
else
throw new BadMessage(400,"Bad URI");
throw new BadMessageException(400,"Bad URI");
}
_request.setPathInfo(info);

View File

@ -295,10 +295,7 @@ class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandl
if (!persistent)
_httpConnection._generator.setPersistent(false);
if (_hostPort==null)
onRequest(new MetaData.Request(_version,_method,_uri,_fields,null,0));
else
onRequest(new MetaData.Request(_version,_method,_uri,_fields,_hostPort.getHost(),_hostPort.getPort()));
onRequest(new MetaData.Request(_version,_method,_uri,_fields,_hostPort));
return true;
}
@ -332,4 +329,4 @@ class HttpChannelOverHttp extends HttpChannel implements HttpParser.RequestHandl
{
return getHttpConfiguration().getHeaderCacheSize();
}
}
}

View File

@ -20,10 +20,10 @@ package org.eclipse.jetty.spdy.server.http;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
@ -106,15 +106,11 @@ public class HttpChannelOverSPDY extends HttpChannel
LOG.debug("HTTP > {} {} {}", httpMethod, uriHeader.getValue(), httpVersion);
String scheme = "http";
Fields.Field schemeHeader = headers.get(HTTPSPDYHeader.SCHEME.name(version));
if (schemeHeader != null)
{
scheme = schemeHeader.getValue();
getRequest().setScheme(scheme);
}
getRequest().setScheme(schemeHeader.getValue());
String authority = null;
HostPortHttpField hostPort = null;
HttpFields fields = new HttpFields();
for (Fields.Field header : headers)
{
@ -128,7 +124,7 @@ public class HttpChannelOverSPDY extends HttpChannel
continue;
name = "host";
authority = header.getValue();
hostPort = new HostPortHttpField(header.getValue());
}
switch (name)
@ -138,8 +134,13 @@ public class HttpChannelOverSPDY extends HttpChannel
case "proxy-connection":
case "transfer-encoding":
{
// Spec says to ignore these headers
continue;
// Spec says to ignore these headers.
break;
}
case "host":
{
// Do not add it now.
break;
}
default:
{
@ -152,24 +153,16 @@ public class HttpChannelOverSPDY extends HttpChannel
}
}
String host = null;
int port = 0;
if (authority != null)
if (hostPort == null)
{
int colon = authority.indexOf(':');
if (colon > 0)
{
host = authority.substring(0, colon);
port = Integer.valueOf(authority.substring(colon + 1));
}
else
{
host = authority;
port = HttpScheme.HTTPS.is(scheme) ? 443 : 80;
}
onBadMessage(400, "Missing Host header");
return false;
}
MetaData.Request request = new MetaData.Request(httpVersion, httpMethod.asString(), uri, fields, host, port);
// At last, add the Host header.
fields.add(hostPort);
MetaData.Request request = new MetaData.Request(httpVersion, httpMethod.asString(), uri, fields, hostPort);
onRequest(request);
return true;
}