Merged branch 'jetty-9.2.x' into 'jetty-9.3.x'.
This commit is contained in:
commit
6306f06e2f
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -445,7 +446,7 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
|
|||
});
|
||||
|
||||
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme.toUpperCase())
|
||||
.scheme(scheme.toUpperCase(Locale.ENGLISH))
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
|
||||
|
|
|
@ -18,15 +18,11 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
|
||||
import static org.eclipse.jetty.http.HttpTokens.LINE_FEED;
|
||||
import static org.eclipse.jetty.http.HttpTokens.SPACE;
|
||||
import static org.eclipse.jetty.http.HttpTokens.TAB;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.http.HttpTokens.EndOfContent;
|
||||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
|
@ -38,35 +34,40 @@ import org.eclipse.jetty.util.Utf8StringBuilder;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
|
||||
import static org.eclipse.jetty.http.HttpTokens.LINE_FEED;
|
||||
import static org.eclipse.jetty.http.HttpTokens.SPACE;
|
||||
import static org.eclipse.jetty.http.HttpTokens.TAB;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** A Parser for 1.0 and 1.1 as defined by RFC7230
|
||||
* <p>
|
||||
* This parser parses HTTP client and server messages from buffers
|
||||
* passed in the {@link #parseNext(ByteBuffer)} method. The parsed
|
||||
* elements of the HTTP message are passed as event calls to the
|
||||
* elements of the HTTP message are passed as event calls to the
|
||||
* {@link HttpHandler} instance the parser is constructed with.
|
||||
* If the passed handler is a {@link RequestHandler} then server side
|
||||
* parsing is performed and if it is a {@link ResponseHandler}, then
|
||||
* parsing is performed and if it is a {@link ResponseHandler}, then
|
||||
* client side parsing is done.
|
||||
* </p>
|
||||
* <p>
|
||||
* The contract of the {@link HttpHandler} API is that if a call returns
|
||||
* true then the call to {@link #parseNext(ByteBuffer)} will return as
|
||||
* The contract of the {@link HttpHandler} API is that if a call returns
|
||||
* true then the call to {@link #parseNext(ByteBuffer)} will return as
|
||||
* soon as possible also with a true response. Typically this indicates
|
||||
* that the parsing has reached a stage where the caller should process
|
||||
* that the parsing has reached a stage where the caller should process
|
||||
* the events accumulated by the handler. It is the preferred calling
|
||||
* style that handling such as calling a servlet to process a request,
|
||||
* style that handling such as calling a servlet to process a request,
|
||||
* should be done after a true return from {@link #parseNext(ByteBuffer)}
|
||||
* rather than from within the scope of a call like
|
||||
* rather than from within the scope of a call like
|
||||
* {@link RequestHandler#messageComplete()}
|
||||
* </p>
|
||||
* <p>
|
||||
* For performance, the parse is heavily dependent on the
|
||||
* For performance, the parse is heavily dependent on the
|
||||
* {@link Trie#getBest(ByteBuffer, int, int)} method to look ahead in a
|
||||
* single pass for both the structure ( : and CRLF ) and semantic (which
|
||||
* header and value) of a header. Specifically the static {@link HttpHeader#CACHE}
|
||||
* is used to lookup common combinations of headers and values
|
||||
* is used to lookup common combinations of headers and values
|
||||
* (eg. "Connection: close"), or just header names (eg. "Connection:" ).
|
||||
* For headers who's value is not known statically (eg. Host, COOKIE) then a
|
||||
* per parser dynamic Trie of {@link HttpFields} from previous parsed messages
|
||||
|
@ -84,7 +85,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
public class HttpParser
|
||||
{
|
||||
public static final Logger LOG = Log.getLogger(HttpParser.class);
|
||||
public final static boolean __STRICT=Boolean.getBoolean("org.eclipse.jetty.http.HttpParser.STRICT");
|
||||
public final static boolean __STRICT=Boolean.getBoolean("org.eclipse.jetty.http.HttpParser.STRICT");
|
||||
public final static int INITIAL_URI_LENGTH=256;
|
||||
|
||||
/**
|
||||
|
@ -100,7 +101,7 @@ public class HttpParser
|
|||
* </ul>
|
||||
*/
|
||||
public final static Trie<HttpField> CACHE = new ArrayTrie<>(2048);
|
||||
|
||||
|
||||
// States
|
||||
public enum State
|
||||
{
|
||||
|
@ -132,7 +133,7 @@ public class HttpParser
|
|||
|
||||
private final static EnumSet<State> __idleStates = EnumSet.of(State.START,State.END,State.CLOSE,State.CLOSED);
|
||||
private final static EnumSet<State> __completeStates = EnumSet.of(State.END,State.CLOSE,State.CLOSED);
|
||||
|
||||
|
||||
private final boolean DEBUG=LOG.isDebugEnabled(); // Cache debug to help branch prediction
|
||||
private final HttpHandler _handler;
|
||||
private final RequestHandler _requestHandler;
|
||||
|
@ -190,22 +191,22 @@ public class HttpParser
|
|||
CACHE.put(new HttpField(HttpHeader.CONTENT_ENCODING,"deflate"));
|
||||
CACHE.put(new HttpField(HttpHeader.TRANSFER_ENCODING,"chunked"));
|
||||
CACHE.put(new HttpField(HttpHeader.EXPIRES,"Fri, 01 Jan 1990 00:00:00 GMT"));
|
||||
|
||||
|
||||
// Add common Content types as fields
|
||||
for (String type : new String[]{"text/plain","text/html","text/xml","text/json","application/json","application/x-www-form-urlencoded"})
|
||||
{
|
||||
HttpField field=new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type);
|
||||
CACHE.put(field);
|
||||
|
||||
|
||||
for (String charset : new String[]{"utf-8","iso-8859-1"})
|
||||
{
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+";charset="+charset));
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+"; charset="+charset));
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+";charset="+charset.toUpperCase()));
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+"; charset="+charset.toUpperCase()));
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+";charset="+charset.toUpperCase(Locale.ENGLISH)));
|
||||
CACHE.put(new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,type+"; charset="+charset.toUpperCase(Locale.ENGLISH)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add headers with null values so HttpParser can avoid looking up name again for unknown values
|
||||
for (HttpHeader h:HttpHeader.values())
|
||||
if (!CACHE.put(new HttpField(h,(String)null)))
|
||||
|
@ -241,7 +242,7 @@ public class HttpParser
|
|||
{
|
||||
this(handler,maxHeaderBytes,__STRICT);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public HttpParser(RequestHandler handler,int maxHeaderBytes,boolean strict)
|
||||
{
|
||||
|
@ -365,14 +366,14 @@ public class HttpParser
|
|||
// comment = "(" *( ctext / quoted-pair / comment ) ")"
|
||||
// ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text
|
||||
// quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
|
||||
|
||||
|
||||
__charState=new CharState[256];
|
||||
Arrays.fill(__charState,CharState.ILLEGAL);
|
||||
__charState[LINE_FEED]=CharState.LF;
|
||||
__charState[CARRIAGE_RETURN]=CharState.CR;
|
||||
__charState[TAB]=CharState.LEGAL;
|
||||
__charState[SPACE]=CharState.LEGAL;
|
||||
|
||||
|
||||
__charState['!']=CharState.LEGAL;
|
||||
__charState['#']=CharState.LEGAL;
|
||||
__charState['$']=CharState.LEGAL;
|
||||
|
@ -388,9 +389,9 @@ public class HttpParser
|
|||
__charState['`']=CharState.LEGAL;
|
||||
__charState['|']=CharState.LEGAL;
|
||||
__charState['~']=CharState.LEGAL;
|
||||
|
||||
|
||||
__charState['"']=CharState.LEGAL;
|
||||
|
||||
|
||||
__charState['\\']=CharState.LEGAL;
|
||||
__charState['(']=CharState.LEGAL;
|
||||
__charState[')']=CharState.LEGAL;
|
||||
|
@ -398,24 +399,24 @@ public class HttpParser
|
|||
Arrays.fill(__charState,0x2A,0x5B+1,CharState.LEGAL);
|
||||
Arrays.fill(__charState,0x5D,0x7E+1,CharState.LEGAL);
|
||||
Arrays.fill(__charState,0x80,0xFF+1,CharState.LEGAL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
private byte next(ByteBuffer buffer)
|
||||
{
|
||||
byte ch = buffer.get();
|
||||
|
||||
|
||||
CharState s = __charState[0xff & ch];
|
||||
switch(s)
|
||||
{
|
||||
case ILLEGAL:
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
|
||||
|
||||
case LF:
|
||||
_cr=false;
|
||||
break;
|
||||
|
||||
|
||||
case CR:
|
||||
if (_cr)
|
||||
throw new BadMessageException("Bad EOL");
|
||||
|
@ -427,26 +428,26 @@ public class HttpParser
|
|||
_headerBytes++;
|
||||
return next(buffer);
|
||||
}
|
||||
|
||||
// Can return 0 here to indicate the need for more characters,
|
||||
// because a real 0 in the buffer would cause a BadMessage below
|
||||
|
||||
// Can return 0 here to indicate the need for more characters,
|
||||
// because a real 0 in the buffer would cause a BadMessage below
|
||||
return 0;
|
||||
|
||||
|
||||
case LEGAL:
|
||||
if (_cr)
|
||||
throw new BadMessageException("Bad EOL");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/* Quick lookahead for the start state looking for a request method or a HTTP version,
|
||||
* otherwise skip white space until something else to parse.
|
||||
*/
|
||||
private boolean quickStart(ByteBuffer buffer)
|
||||
{
|
||||
{
|
||||
if (_requestHandler!=null)
|
||||
{
|
||||
_method = HttpMethod.lookAheadGet(buffer);
|
||||
|
@ -454,7 +455,7 @@ public class HttpParser
|
|||
{
|
||||
_methodString = _method.asString();
|
||||
buffer.position(buffer.position()+_methodString.length()+1);
|
||||
|
||||
|
||||
setState(State.SPACE1);
|
||||
return false;
|
||||
}
|
||||
|
@ -469,7 +470,7 @@ public class HttpParser
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Quick start look
|
||||
while (_state==State.START && buffer.hasRemaining())
|
||||
{
|
||||
|
@ -486,7 +487,7 @@ public class HttpParser
|
|||
break;
|
||||
else if (ch<0)
|
||||
throw new BadMessageException();
|
||||
|
||||
|
||||
// count this white space as a header byte to avoid DOS
|
||||
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
|
||||
{
|
||||
|
@ -504,7 +505,7 @@ public class HttpParser
|
|||
_string.append(s);
|
||||
_length=s.length();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
private String takeString()
|
||||
{
|
||||
|
@ -610,7 +611,7 @@ public class HttpParser
|
|||
|
||||
int len=i-p;
|
||||
_headerBytes+=len;
|
||||
|
||||
|
||||
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
|
||||
{
|
||||
LOG.warn("URI is too large >"+_maxHeaderBytes);
|
||||
|
@ -685,7 +686,7 @@ public class HttpParser
|
|||
version=HttpVersion.lookAheadGet(buffer.array(),buffer.arrayOffset()+buffer.position()-1,buffer.arrayOffset()+buffer.limit());
|
||||
else
|
||||
version=HttpVersion.CACHE.getBest(buffer,0,buffer.remaining());
|
||||
|
||||
|
||||
if (version!=null)
|
||||
{
|
||||
int pos = buffer.position()+version.asString().length()-1;
|
||||
|
@ -736,16 +737,16 @@ public class HttpParser
|
|||
}
|
||||
if (_version==null)
|
||||
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() && _handler.getHeaderCacheSize()>0)
|
||||
{
|
||||
int header_cache = _handler.getHeaderCacheSize();
|
||||
_connectionFields=new ArrayTernaryTrie<>(header_cache);
|
||||
_connectionFields=new ArrayTernaryTrie<>(header_cache);
|
||||
}
|
||||
|
||||
setState(State.HEADER);
|
||||
|
||||
|
||||
handle=_requestHandler.startRequest(_methodString,_uri.toString(), _version)||handle;
|
||||
continue;
|
||||
}
|
||||
|
@ -770,7 +771,7 @@ public class HttpParser
|
|||
_string.append((char)ch);
|
||||
if (ch!=' '&&ch!='\t')
|
||||
_length=_string.length();
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new BadMessageException();
|
||||
break;
|
||||
|
@ -836,12 +837,12 @@ public class HttpParser
|
|||
add_to_connection_trie=_connectionFields!=null;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CONNECTION:
|
||||
// Don't cache if not persistent
|
||||
if (_valueString!=null && _valueString.contains("close"))
|
||||
_connectionFields=null;
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case AUTHORIZATION:
|
||||
|
@ -854,10 +855,10 @@ public class HttpParser
|
|||
case USER_AGENT:
|
||||
add_to_connection_trie=_connectionFields!=null && _field==null;
|
||||
break;
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
if (add_to_connection_trie && !_connectionFields.isFull() && _header!=null && _valueString!=null)
|
||||
{
|
||||
if (_field==null)
|
||||
|
@ -867,14 +868,14 @@ public class HttpParser
|
|||
}
|
||||
_handler.parsedHeader(_field!=null?_field:new HttpField(_header,_headerString,_valueString));
|
||||
}
|
||||
|
||||
|
||||
_headerString=_valueString=null;
|
||||
_header=null;
|
||||
_value=null;
|
||||
_field=null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/*
|
||||
* Parse the message headers and return true if the handler has signaled for a return
|
||||
|
@ -890,7 +891,7 @@ public class HttpParser
|
|||
byte ch=next(buffer);
|
||||
if (ch==0)
|
||||
break;
|
||||
|
||||
|
||||
if (_maxHeaderBytes>0 && ++_headerBytes>_maxHeaderBytes)
|
||||
{
|
||||
LOG.warn("Header is too large >"+_maxHeaderBytes);
|
||||
|
@ -920,7 +921,7 @@ public class HttpParser
|
|||
}
|
||||
|
||||
// is it a response that cannot have a body?
|
||||
if (_responseHandler !=null && // response
|
||||
if (_responseHandler !=null && // response
|
||||
(_responseStatus == 304 || // not-modified response
|
||||
_responseStatus == 204 || // no-content response
|
||||
_responseStatus < 200)) // 1xx response
|
||||
|
@ -999,7 +1000,7 @@ public class HttpParser
|
|||
else
|
||||
{
|
||||
n=field.getName();
|
||||
v=field.getValue();
|
||||
v=field.getValue();
|
||||
}
|
||||
|
||||
_header=field.getHeader();
|
||||
|
@ -1021,7 +1022,7 @@ public class HttpParser
|
|||
byte b=buffer.get(pos);
|
||||
|
||||
if (b==HttpTokens.CARRIAGE_RETURN || b==HttpTokens.LINE_FEED)
|
||||
{
|
||||
{
|
||||
_field=field;
|
||||
_valueString=v;
|
||||
setState(State.HEADER_IN_VALUE);
|
||||
|
@ -1069,7 +1070,7 @@ public class HttpParser
|
|||
setState(State.HEADER_VALUE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ch>HttpTokens.SPACE)
|
||||
{
|
||||
if (_header!=null)
|
||||
|
@ -1095,7 +1096,7 @@ public class HttpParser
|
|||
setState(State.HEADER_IN_VALUE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ch==HttpTokens.SPACE || ch==HttpTokens.TAB)
|
||||
break;
|
||||
|
||||
|
@ -1105,7 +1106,7 @@ public class HttpParser
|
|||
_string.setLength(0);
|
||||
_valueString=null;
|
||||
_length=-1;
|
||||
|
||||
|
||||
parsedHeader();
|
||||
setState(State.HEADER);
|
||||
break;
|
||||
|
@ -1126,7 +1127,7 @@ public class HttpParser
|
|||
_length=_string.length();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ch==HttpTokens.LINE_FEED)
|
||||
{
|
||||
if (_length > 0)
|
||||
|
@ -1141,7 +1142,7 @@ public class HttpParser
|
|||
}
|
||||
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(_state.toString());
|
||||
|
||||
|
@ -1174,7 +1175,7 @@ public class HttpParser
|
|||
if (quickStart(buffer))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Request/response line
|
||||
if (_state.ordinal()>= State.START.ordinal() && _state.ordinal()<State.HEADER.ordinal())
|
||||
{
|
||||
|
@ -1188,7 +1189,7 @@ public class HttpParser
|
|||
if (parseHeaders(buffer))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// parse content
|
||||
if (_state.ordinal()>= State.CONTENT.ordinal() && _state.ordinal()<State.END.ordinal())
|
||||
{
|
||||
|
@ -1204,7 +1205,7 @@ public class HttpParser
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// handle end states
|
||||
if (_state==State.END)
|
||||
{
|
||||
|
@ -1231,7 +1232,7 @@ public class HttpParser
|
|||
{
|
||||
BufferUtil.clear(buffer);
|
||||
}
|
||||
|
||||
|
||||
// Handle EOF
|
||||
if (_eof && !buffer.hasRemaining())
|
||||
{
|
||||
|
@ -1239,17 +1240,17 @@ public class HttpParser
|
|||
{
|
||||
case CLOSED:
|
||||
break;
|
||||
|
||||
|
||||
case START:
|
||||
setState(State.CLOSED);
|
||||
_handler.earlyEOF();
|
||||
break;
|
||||
|
||||
|
||||
case END:
|
||||
case CLOSE:
|
||||
setState(State.CLOSED);
|
||||
break;
|
||||
|
||||
|
||||
case EOF_CONTENT:
|
||||
setState(State.CLOSED);
|
||||
return _handler.messageComplete();
|
||||
|
@ -1277,9 +1278,9 @@ public class HttpParser
|
|||
BufferUtil.clear(buffer);
|
||||
|
||||
Throwable cause = e.getCause();
|
||||
boolean stack = LOG.isDebugEnabled() ||
|
||||
boolean stack = LOG.isDebugEnabled() ||
|
||||
(!(cause instanceof NumberFormatException ) && (cause instanceof RuntimeException || cause instanceof Error));
|
||||
|
||||
|
||||
if (stack)
|
||||
LOG.warn("bad HTTP parsed: "+e._code+(e.getReason()!=null?" "+e.getReason():"")+" for "+_handler,e);
|
||||
else
|
||||
|
@ -1293,7 +1294,7 @@ public class HttpParser
|
|||
LOG.warn("parse exception: {} in {} for {}",e.toString(),_state,_handler);
|
||||
if (DEBUG)
|
||||
LOG.debug(e);
|
||||
|
||||
|
||||
switch(_state)
|
||||
{
|
||||
case CLOSED:
|
||||
|
@ -1339,7 +1340,7 @@ public class HttpParser
|
|||
return _handler.messageComplete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle _content
|
||||
byte ch;
|
||||
while (_state.ordinal() < State.END.ordinal() && remaining>0)
|
||||
|
@ -1457,7 +1458,7 @@ public class HttpParser
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CHUNK_END:
|
||||
{
|
||||
// TODO handle chunk trailer
|
||||
|
@ -1471,18 +1472,18 @@ public class HttpParser
|
|||
}
|
||||
throw new IllegalCharacterException(_state,ch,buffer);
|
||||
}
|
||||
|
||||
|
||||
case CLOSED:
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
remaining=buffer.remaining();
|
||||
}
|
||||
return false;
|
||||
|
@ -1490,16 +1491,16 @@ public class HttpParser
|
|||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public boolean isAtEOF()
|
||||
|
||||
|
||||
{
|
||||
return _eof;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/** Signal that the associated data source is at EOF
|
||||
*/
|
||||
public void atEOF()
|
||||
{
|
||||
{
|
||||
if (DEBUG)
|
||||
LOG.debug("atEOF {}", this);
|
||||
_eof=true;
|
||||
|
@ -1514,7 +1515,7 @@ public class HttpParser
|
|||
LOG.debug("close {}", this);
|
||||
setState(State.CLOSE);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void reset()
|
||||
{
|
||||
|
@ -1524,7 +1525,7 @@ public class HttpParser
|
|||
// reset state
|
||||
if (_state==State.CLOSE || _state==State.CLOSED)
|
||||
return;
|
||||
|
||||
|
||||
setState(State.START);
|
||||
_endOfContent=EndOfContent.UNKNOWN_CONTENT;
|
||||
_contentLength=-1;
|
||||
|
@ -1554,18 +1555,18 @@ public class HttpParser
|
|||
{
|
||||
_string.setLength(0);
|
||||
_length=0;
|
||||
|
||||
|
||||
while (buffer.hasRemaining())
|
||||
{
|
||||
// process each character
|
||||
byte ch=next(buffer);
|
||||
if (ch<=' ')
|
||||
return _string.toString();
|
||||
_string.append((char)ch);
|
||||
_string.append((char)ch);
|
||||
}
|
||||
throw new BadMessageException();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
@Override
|
||||
public String toString()
|
||||
|
@ -1583,7 +1584,7 @@ public class HttpParser
|
|||
/* Event Handler interface
|
||||
* These methods return true if the caller should process the events
|
||||
* so far received (eg return from parseNext and call HttpChannel.handle).
|
||||
* If multiple callbacks are called in sequence (eg
|
||||
* If multiple callbacks are called in sequence (eg
|
||||
* headerComplete then messageComplete) from the same point in the parsing
|
||||
* then it is sufficient for the caller to process the events only once.
|
||||
*/
|
||||
|
@ -1600,7 +1601,7 @@ public class HttpParser
|
|||
* @param field The field parsed
|
||||
*/
|
||||
public void parsedHeader(HttpField field);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Called to signal that an EOF was received unexpectedly
|
||||
* during the parsing of a HTTP message
|
||||
|
@ -1613,7 +1614,7 @@ public class HttpParser
|
|||
* @param reason The textual reason for badness
|
||||
*/
|
||||
public void badMessage(int status, String reason);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** @return the size in bytes of the per parser header cache
|
||||
*/
|
||||
|
@ -1627,7 +1628,7 @@ public class HttpParser
|
|||
{
|
||||
/**
|
||||
* This is the method called by parser when the HTTP request line is parsed
|
||||
* @param method The method
|
||||
* @param method The method
|
||||
* @param uri The raw bytes of the URI. These are copied into a ByteBuffer that will not be changed until this parser is reset and reused.
|
||||
* @param version the http version in use
|
||||
* @return true if handling parsing should return.
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.MissingResourceException;
|
||||
|
@ -40,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MimeTypes
|
||||
{
|
||||
|
@ -58,16 +59,16 @@ public class MimeTypes
|
|||
|
||||
TEXT_HTML_8859_1("text/html;charset=iso-8859-1",TEXT_HTML),
|
||||
TEXT_HTML_UTF_8("text/html;charset=utf-8",TEXT_HTML),
|
||||
|
||||
|
||||
TEXT_PLAIN_8859_1("text/plain;charset=iso-8859-1",TEXT_PLAIN),
|
||||
TEXT_PLAIN_UTF_8("text/plain;charset=utf-8",TEXT_PLAIN),
|
||||
|
||||
|
||||
TEXT_XML_8859_1("text/xml;charset=iso-8859-1",TEXT_XML),
|
||||
TEXT_XML_UTF_8("text/xml;charset=utf-8",TEXT_XML),
|
||||
|
||||
|
||||
TEXT_JSON_8859_1("text/json;charset=iso-8859-1",TEXT_JSON),
|
||||
TEXT_JSON_UTF_8("text/json;charset=utf-8",TEXT_JSON),
|
||||
|
||||
|
||||
APPLICATION_JSON_8859_1("text/json;charset=iso-8859-1",APPLICATION_JSON),
|
||||
APPLICATION_JSON_UTF_8("text/json;charset=utf-8",APPLICATION_JSON);
|
||||
|
||||
|
@ -91,7 +92,7 @@ public class MimeTypes
|
|||
_charsetString=null;
|
||||
_assumedCharset=false;
|
||||
_field=new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,_string);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
Type(String s,Type base)
|
||||
|
@ -101,7 +102,7 @@ public class MimeTypes
|
|||
_base=base;
|
||||
int i=s.indexOf(";charset=");
|
||||
_charset=Charset.forName(s.substring(i+9));
|
||||
_charsetString=_charset==null?null:_charset.toString().toLowerCase();
|
||||
_charsetString=_charset.toString().toLowerCase(Locale.ENGLISH);
|
||||
_assumedCharset=false;
|
||||
_field=new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,_string);
|
||||
}
|
||||
|
@ -113,7 +114,7 @@ public class MimeTypes
|
|||
_base=this;
|
||||
_buffer=BufferUtil.toBuffer(s);
|
||||
_charset=cs;
|
||||
_charsetString=_charset==null?null:_charset.toString().toLowerCase();
|
||||
_charsetString=_charset==null?null:_charset.toString().toLowerCase(Locale.ENGLISH);
|
||||
_assumedCharset=true;
|
||||
_field=new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,_string);
|
||||
}
|
||||
|
@ -123,23 +124,23 @@ public class MimeTypes
|
|||
{
|
||||
return _buffer.asReadOnlyBuffer();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Charset getCharset()
|
||||
{
|
||||
return _charset;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getCharsetString()
|
||||
{
|
||||
return _charsetString;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean is(String s)
|
||||
{
|
||||
return _string.equalsIgnoreCase(s);
|
||||
return _string.equalsIgnoreCase(s);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -147,7 +148,7 @@ public class MimeTypes
|
|||
{
|
||||
return _string;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
|
@ -261,7 +262,7 @@ public class MimeTypes
|
|||
_mimeMap.put(StringUtil.asciiToLowerCase(ext.getKey()),normalizeMimeType(ext.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the MIME type by filename extension.
|
||||
* @param filename A file name
|
||||
|
@ -316,7 +317,7 @@ public class MimeTypes
|
|||
{
|
||||
return new HashSet<>(__dftMimeMap.values());
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private static String normalizeMimeType(String type)
|
||||
{
|
||||
|
@ -401,7 +402,7 @@ public class MimeTypes
|
|||
{
|
||||
return __encodings.get(value);
|
||||
}
|
||||
|
||||
|
||||
public static String getContentTypeWithoutCharset(String value)
|
||||
{
|
||||
int end=value.length();
|
||||
|
@ -424,7 +425,7 @@ public class MimeTypes
|
|||
{
|
||||
quote=true;
|
||||
}
|
||||
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 11:
|
||||
|
@ -438,11 +439,11 @@ public class MimeTypes
|
|||
break;
|
||||
default:
|
||||
start=i;
|
||||
state=0;
|
||||
state=0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (quote)
|
||||
{
|
||||
if (builder!=null && state!=10)
|
||||
|
|
|
@ -18,16 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.http;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -35,9 +29,13 @@ import org.hamcrest.Matchers;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class HttpFieldsTest
|
||||
{
|
||||
@Test
|
||||
|
@ -69,7 +67,6 @@ public class HttpFieldsTest
|
|||
assertEquals(true, e.hasMoreElements());
|
||||
assertEquals(e.nextElement(), "value:0");
|
||||
assertEquals(false, e.hasMoreElements());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -106,7 +103,7 @@ public class HttpFieldsTest
|
|||
assertEquals("value1",header.get("name1"));
|
||||
assertEquals("value1",header.get("Name1"));
|
||||
assertEquals(null,header.get("Name2"));
|
||||
|
||||
|
||||
assertEquals("value0",header.getField("name0").getValue());
|
||||
assertEquals("value0",header.getField("Name0").getValue());
|
||||
assertEquals("value1",header.getField("name1").getValue());
|
||||
|
@ -121,9 +118,9 @@ public class HttpFieldsTest
|
|||
Assert.fail();
|
||||
}
|
||||
catch(NoSuchElementException e)
|
||||
{}
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetKnown() throws Exception
|
||||
{
|
||||
|
@ -134,10 +131,10 @@ public class HttpFieldsTest
|
|||
|
||||
assertEquals("value0",header.get(HttpHeader.CONNECTION));
|
||||
assertEquals("value1",header.get(HttpHeader.ACCEPT));
|
||||
|
||||
|
||||
assertEquals("value0",header.getField(HttpHeader.CONNECTION).getValue());
|
||||
assertEquals("value1",header.getField(HttpHeader.ACCEPT).getValue());
|
||||
|
||||
|
||||
assertEquals(null,header.getField(HttpHeader.AGE));
|
||||
assertEquals(null,header.get(HttpHeader.AGE));
|
||||
}
|
||||
|
@ -174,11 +171,11 @@ public class HttpFieldsTest
|
|||
BufferUtil.flipToFill(buffer);
|
||||
HttpGenerator.putTo(header,buffer);
|
||||
BufferUtil.flipToFlush(buffer,0);
|
||||
String out = BufferUtil.toString(buffer).toLowerCase();
|
||||
String out = BufferUtil.toString(buffer).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.CONNECTION+": "+HttpHeaderValue.KEEP_ALIVE).toLowerCase()));
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.TRANSFER_ENCODING+": "+HttpHeaderValue.CHUNKED).toLowerCase()));
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.CONTENT_ENCODING+": "+HttpHeaderValue.GZIP).toLowerCase()));
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.CONNECTION+": "+HttpHeaderValue.KEEP_ALIVE).toLowerCase(Locale.ENGLISH)));
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.TRANSFER_ENCODING+": "+HttpHeaderValue.CHUNKED).toLowerCase(Locale.ENGLISH)));
|
||||
Assert.assertThat(out,Matchers.containsString((HttpHeader.CONTENT_ENCODING+": "+HttpHeaderValue.GZIP).toLowerCase(Locale.ENGLISH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -302,7 +299,6 @@ public class HttpFieldsTest
|
|||
assertEquals(false, e.hasMoreElements());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetValues() throws Exception
|
||||
{
|
||||
|
@ -330,7 +326,7 @@ public class HttpFieldsTest
|
|||
assertEquals(true, e.hasMoreElements());
|
||||
assertEquals(e.nextElement(), "value0D");
|
||||
assertEquals(false, e.hasMoreElements());
|
||||
|
||||
|
||||
e = fields.getValues("name1",",");
|
||||
assertEquals(true, e.hasMoreElements());
|
||||
assertEquals(e.nextElement(), "value1A");
|
||||
|
@ -343,7 +339,6 @@ public class HttpFieldsTest
|
|||
assertEquals(false, e.hasMoreElements());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetQualityValues() throws Exception
|
||||
{
|
||||
|
@ -355,7 +350,7 @@ public class HttpFieldsTest
|
|||
fields.add("name", "nothing;q=0");
|
||||
fields.add("name", "one;q=0.4");
|
||||
fields.add("name", "three;x=y;q=0.2;a=b,two;q=0.3");
|
||||
|
||||
|
||||
List<String> list = HttpFields.qualityList(fields.getValues("name",","));
|
||||
assertEquals("zero",HttpFields.valueParameters(list.get(0),null));
|
||||
assertEquals("one",HttpFields.valueParameters(list.get(1),null));
|
||||
|
@ -363,7 +358,7 @@ public class HttpFieldsTest
|
|||
assertEquals("three",HttpFields.valueParameters(list.get(3),null));
|
||||
assertEquals("four",HttpFields.valueParameters(list.get(4),null));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDateFields() throws Exception
|
||||
{
|
||||
|
@ -446,9 +441,9 @@ public class HttpFieldsTest
|
|||
{
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
|
||||
long i3=header.getLongField("I3");
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
header.getLongField("I4");
|
||||
|
@ -484,7 +479,6 @@ public class HttpFieldsTest
|
|||
header.putLongField("I6",-47);
|
||||
assertEquals("46",header.get("I5"));
|
||||
assertEquals("-47",header.get("I6"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -512,8 +506,8 @@ public class HttpFieldsTest
|
|||
assertFalse(""+i,header.contains("n"+i,"xyz"));
|
||||
assertEquals(""+i,i>=4,header.contains("n"+i,"def"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
assertTrue(header.contains(new HttpField("N5","def")));
|
||||
assertTrue(header.contains(new HttpField("accept","abc")));
|
||||
assertTrue(header.contains(HttpHeader.ACCEPT,"abc"));
|
||||
|
@ -521,9 +515,7 @@ public class HttpFieldsTest
|
|||
assertFalse(header.contains(new HttpField("N8","def")));
|
||||
assertFalse(header.contains(HttpHeader.ACCEPT,"def"));
|
||||
assertFalse(header.contains(HttpHeader.AGE,"abc"));
|
||||
|
||||
|
||||
assertFalse(header.containsKey("n11"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.http2.frames;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.http2.ErrorCode;
|
||||
|
||||
public class ResetFrame extends Frame
|
||||
|
@ -46,7 +48,7 @@ public class ResetFrame extends Frame
|
|||
public String toString()
|
||||
{
|
||||
ErrorCode errorCode = ErrorCode.from(error);
|
||||
String reason = errorCode == null ? "error=" + error : errorCode.name().toLowerCase();
|
||||
String reason = errorCode == null ? "error=" + error : errorCode.name().toLowerCase(Locale.ENGLISH);
|
||||
return String.format("%s#%d{%s}", super.toString(), streamId, reason);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.http2.hpack;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
|
@ -37,7 +38,7 @@ public class HuffmanTest
|
|||
{"D.6.1l","9d29ad171863c78f0b97c8e9ae82ae43d3","https://www.example.com"},
|
||||
{"D.6.2te","640cff","303"},
|
||||
};
|
||||
|
||||
|
||||
@Test
|
||||
public void testDecode() throws Exception
|
||||
{
|
||||
|
@ -48,7 +49,7 @@ public class HuffmanTest
|
|||
Assert.assertEquals(test[0],test[2],decoded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDecodeTrailingFF() throws Exception
|
||||
{
|
||||
|
@ -59,7 +60,7 @@ public class HuffmanTest
|
|||
Assert.assertEquals(test[0],test[2],decoded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncode() throws Exception
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ public class HuffmanTest
|
|||
int pos=BufferUtil.flipToFill(buf);
|
||||
Huffman.encode(buf,test[2]);
|
||||
BufferUtil.flipToFlush(buf,pos);
|
||||
String encoded=TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase();
|
||||
String encoded=TypeUtil.toHexString(BufferUtil.toArray(buf)).toLowerCase(Locale.ENGLISH);
|
||||
Assert.assertEquals(test[0],test[1],encoded);
|
||||
Assert.assertEquals(test[1].length()/2,Huffman.octetsNeeded(test[2]));
|
||||
}
|
||||
|
@ -82,7 +83,7 @@ public class HuffmanTest
|
|||
for (int i=0;i<bad.length;i++)
|
||||
{
|
||||
String s="bad '"+bad[i]+"'";
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Huffman.octetsNeeded(s);
|
||||
|
@ -91,7 +92,7 @@ public class HuffmanTest
|
|||
catch(IllegalArgumentException e)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Huffman.encode(BufferUtil.allocate(32),s);
|
||||
|
@ -102,6 +103,6 @@ public class HuffmanTest
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.http2.client.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.client.HttpChannel;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
|
@ -109,7 +110,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
|
|||
return;
|
||||
|
||||
ErrorCode error = ErrorCode.from(frame.getError());
|
||||
String reason = error == null ? "reset" : error.name().toLowerCase();
|
||||
String reason = error == null ? "reset" : error.name().toLowerCase(Locale.ENGLISH);
|
||||
exchange.getRequest().abort(new IOException(reason));
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.quickstart;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -101,7 +103,7 @@ public class PreconfigureQuickStartWar
|
|||
|
||||
if (xml != null)
|
||||
{
|
||||
if (xml.isDirectory() || !xml.toString().toLowerCase().endsWith(".xml"))
|
||||
if (xml.isDirectory() || !xml.toString().toLowerCase(Locale.ENGLISH).endsWith(".xml"))
|
||||
error("Bad context.xml: "+xml);
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(xml.getURL());
|
||||
xmlConfiguration.configure(webapp);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.quickstart;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -28,14 +29,11 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
|
||||
/**
|
||||
* QuickStartWar
|
||||
*
|
||||
*/
|
||||
public class QuickStartWebApp extends WebAppContext
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(QuickStartWebApp.class);
|
||||
|
||||
|
||||
|
||||
public static final String[] __configurationClasses = new String[]
|
||||
{
|
||||
org.eclipse.jetty.quickstart.QuickStartConfiguration.class.getCanonicalName(),
|
||||
|
@ -44,13 +42,11 @@ public class QuickStartWebApp extends WebAppContext
|
|||
org.eclipse.jetty.webapp.JettyWebXmlConfiguration.class.getCanonicalName()
|
||||
};
|
||||
|
||||
|
||||
private boolean _preconfigure=false;
|
||||
private boolean _autoPreconfigure=false;
|
||||
private boolean _startWebapp=false;
|
||||
private PreconfigureDescriptorProcessor _preconfigProcessor;
|
||||
|
||||
|
||||
public static final String[] __preconfigurationClasses = new String[]
|
||||
{
|
||||
org.eclipse.jetty.webapp.WebInfConfiguration.class.getCanonicalName(),
|
||||
|
@ -74,8 +70,8 @@ public class QuickStartWebApp extends WebAppContext
|
|||
return _preconfigure;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Preconfigure webapp
|
||||
/**
|
||||
* Preconfigure webapp
|
||||
* @param preconfigure If true, then starting the webapp will generate
|
||||
* the WEB-INF/quickstart-web.xml rather than start the webapp.
|
||||
*/
|
||||
|
@ -104,8 +100,6 @@ public class QuickStartWebApp extends WebAppContext
|
|||
super.startWebapp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void stopWebapp() throws Exception
|
||||
{
|
||||
|
@ -114,7 +108,7 @@ public class QuickStartWebApp extends WebAppContext
|
|||
|
||||
super.stopWebapp();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
|
@ -128,7 +122,7 @@ public class QuickStartWebApp extends WebAppContext
|
|||
|
||||
if (base.isDirectory())
|
||||
dir=base;
|
||||
else if (base.toString().toLowerCase().endsWith(".war"))
|
||||
else if (base.toString().toLowerCase(Locale.ENGLISH).endsWith(".war"))
|
||||
{
|
||||
war=base;
|
||||
String w=war.toString();
|
||||
|
@ -176,7 +170,6 @@ public class QuickStartWebApp extends WebAppContext
|
|||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
public void generateQuickstartWebXml(String extraXML) throws Exception
|
||||
{
|
||||
Resource descriptor = getWebInf().addPath(QuickStartDescriptorGenerator.DEFAULT_QUICKSTART_DESCRIPTOR_NAME);
|
||||
|
@ -187,7 +180,5 @@ public class QuickStartWebApp extends WebAppContext
|
|||
{
|
||||
generator.generateQuickStartWebXml(fos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.net.URLClassLoader;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
|
@ -89,8 +90,6 @@ public class Runner
|
|||
protected boolean _enableStats=false;
|
||||
protected String _statsPropFile;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Classpath
|
||||
*/
|
||||
|
@ -118,8 +117,9 @@ public class Runner
|
|||
addJars(item);
|
||||
else
|
||||
{
|
||||
if (path.toLowerCase().endsWith(".jar") ||
|
||||
path.toLowerCase().endsWith(".zip"))
|
||||
String lowerCasePath = path.toLowerCase(Locale.ENGLISH);
|
||||
if (lowerCasePath.endsWith(".jar") ||
|
||||
lowerCasePath.endsWith(".zip"))
|
||||
{
|
||||
URL url = item.getURL();
|
||||
_classpath.add(url);
|
||||
|
@ -148,7 +148,6 @@ public class Runner
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate helpful usage message and exit
|
||||
*
|
||||
|
@ -187,8 +186,6 @@ public class Runner
|
|||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Configure a jetty instance and deploy the webapps presented as args
|
||||
*
|
||||
|
@ -424,7 +421,7 @@ public class Runner
|
|||
contextPath = "/" + contextPath;
|
||||
|
||||
// Configure the context
|
||||
if (!ctx.isDirectory() && ctx.toString().toLowerCase().endsWith(".xml"))
|
||||
if (!ctx.isDirectory() && ctx.toString().toLowerCase(Locale.ENGLISH).endsWith(".xml"))
|
||||
{
|
||||
// It is a context config file
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(ctx.getURL());
|
||||
|
@ -481,7 +478,6 @@ public class Runner
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected void prependHandler (Handler handler, HandlerCollection handlers)
|
||||
{
|
||||
if (handler == null || handlers == null)
|
||||
|
@ -494,16 +490,12 @@ public class Runner
|
|||
handlers.setHandlers(children);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void run() throws Exception
|
||||
{
|
||||
_server.start();
|
||||
_server.join();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Establish a classloader with custom paths (if any)
|
||||
*/
|
||||
|
@ -524,9 +516,6 @@ public class Runner
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Runner runner = new Runner();
|
||||
|
|
|
@ -85,7 +85,7 @@ public class ResponseTest
|
|||
_channel = new HttpChannel(connector, new HttpConfiguration(), endp, new HttpTransport()
|
||||
{
|
||||
private Throwable _channelError;
|
||||
|
||||
|
||||
@Override
|
||||
public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
|
@ -100,12 +100,12 @@ public class ResponseTest
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void push(org.eclipse.jetty.http.MetaData.Request request)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCompleted()
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ public class ResponseTest
|
|||
response.setContentType("text/json");
|
||||
response.getWriter();
|
||||
assertEquals("text/json", response.getContentType());
|
||||
|
||||
|
||||
response.recycle();
|
||||
response.setContentType("text/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
|
@ -230,7 +230,7 @@ public class ResponseTest
|
|||
response.recycle();
|
||||
response.addHeader("Content-Type","text/something");
|
||||
assertEquals("text/something",response.getContentType());
|
||||
|
||||
|
||||
response.recycle();
|
||||
response.addHeader("Content-Type","application/json");
|
||||
response.getWriter();
|
||||
|
@ -248,7 +248,7 @@ public class ResponseTest
|
|||
response.setContentType("text/html;charset=utf-8;charset=UTF-8");
|
||||
response.getWriter();
|
||||
assertEquals("text/html;charset=utf-8;charset=UTF-8",response.getContentType());
|
||||
assertEquals("utf-8",response.getCharacterEncoding().toLowerCase());
|
||||
assertEquals("utf-8",response.getCharacterEncoding().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -447,7 +447,7 @@ public class ResponseTest
|
|||
writer.println("test");
|
||||
writer.flush();
|
||||
Assert.assertFalse(writer.checkError());
|
||||
|
||||
|
||||
Throwable cause = new IOException("problem at mill");
|
||||
_channel.abort(cause);
|
||||
writer.println("test");
|
||||
|
@ -461,7 +461,7 @@ public class ResponseTest
|
|||
{
|
||||
Assert.assertEquals(cause,e.getCause());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -733,7 +733,7 @@ public class ResponseTest
|
|||
assertEquals("null=",fields.get("Set-Cookie"));
|
||||
|
||||
fields.clear();
|
||||
|
||||
|
||||
response.addSetCookie("minimal","value",null,null,-1,null,false,false,-1);
|
||||
assertEquals("minimal=value",fields.get("Set-Cookie"));
|
||||
|
||||
|
@ -748,7 +748,7 @@ public class ResponseTest
|
|||
assertFalse(e.hasMoreElements());
|
||||
assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.get("Expires"));
|
||||
assertFalse(e.hasMoreElements());
|
||||
|
||||
|
||||
//test cookies with same name, different domain
|
||||
fields.clear();
|
||||
response.addSetCookie("everything","other","domain1","path",0,"blah",true,true,0);
|
||||
|
@ -759,7 +759,7 @@ public class ResponseTest
|
|||
assertTrue(e.hasMoreElements());
|
||||
assertEquals("everything=value;Version=1;Path=path;Domain=domain2;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0;Secure;HttpOnly;Comment=comment",e.nextElement());
|
||||
assertFalse(e.hasMoreElements());
|
||||
|
||||
|
||||
//test cookies with same name, same path, one with domain, one without
|
||||
fields.clear();
|
||||
response.addSetCookie("everything","other","domain1","path",0,"blah",true,true,0);
|
||||
|
@ -770,8 +770,8 @@ public class ResponseTest
|
|||
assertTrue(e.hasMoreElements());
|
||||
assertEquals("everything=value;Version=1;Path=path;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0;Secure;HttpOnly;Comment=comment",e.nextElement());
|
||||
assertFalse(e.hasMoreElements());
|
||||
|
||||
|
||||
|
||||
|
||||
//test cookies with same name, different path
|
||||
fields.clear();
|
||||
response.addSetCookie("everything","other","domain1","path1",0,"blah",true,true,0);
|
||||
|
@ -782,7 +782,7 @@ public class ResponseTest
|
|||
assertTrue(e.hasMoreElements());
|
||||
assertEquals("everything=value;Version=1;Path=path2;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0;Secure;HttpOnly;Comment=comment",e.nextElement());
|
||||
assertFalse(e.hasMoreElements());
|
||||
|
||||
|
||||
//test cookies with same name, same domain, one with path, one without
|
||||
fields.clear();
|
||||
response.addSetCookie("everything","other","domain1","path1",0,"blah",true,true,0);
|
||||
|
@ -793,7 +793,7 @@ public class ResponseTest
|
|||
assertTrue(e.hasMoreElements());
|
||||
assertEquals("everything=value;Version=1;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0;Secure;HttpOnly;Comment=comment",e.nextElement());
|
||||
assertFalse(e.hasMoreElements());
|
||||
|
||||
|
||||
//test cookies same name only, no path, no domain
|
||||
fields.clear();
|
||||
response.addSetCookie("everything","other","","",0,"blah",true,true,0);
|
||||
|
@ -841,7 +841,7 @@ public class ResponseTest
|
|||
assertEquals("name=value%=",setCookie);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Response newResponse()
|
||||
{
|
||||
_channel.recycle();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -35,37 +36,37 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
/* ------------------------------------------------------------ */
|
||||
/** Servlet handling JSP Property Group mappings
|
||||
* <p>
|
||||
* This servlet is mapped to by any URL pattern for a JSP property group.
|
||||
* This servlet is mapped to by any URL pattern for a JSP property group.
|
||||
* Resources handled by this servlet that are not directories will be passed
|
||||
* directly to the JSP servlet. Resources that are directories will be
|
||||
* directly to the JSP servlet. Resources that are directories will be
|
||||
* passed directly to the default servlet.
|
||||
*/
|
||||
public class JspPropertyGroupServlet extends GenericServlet
|
||||
{
|
||||
private static final long serialVersionUID = 3681783214726776945L;
|
||||
|
||||
|
||||
public final static String NAME = "__org.eclipse.jetty.servlet.JspPropertyGroupServlet__";
|
||||
private final ServletHandler _servletHandler;
|
||||
private final ContextHandler _contextHandler;
|
||||
private ServletHolder _dftServlet;
|
||||
private ServletHolder _jspServlet;
|
||||
private boolean _starJspMapped;
|
||||
|
||||
|
||||
public JspPropertyGroupServlet(ContextHandler context, ServletHandler servletHandler)
|
||||
{
|
||||
_contextHandler=context;
|
||||
_servletHandler=servletHandler;
|
||||
_servletHandler=servletHandler;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException
|
||||
{
|
||||
{
|
||||
String jsp_name = "jsp";
|
||||
ServletMapping servlet_mapping =_servletHandler.getServletMapping("*.jsp");
|
||||
if (servlet_mapping!=null)
|
||||
{
|
||||
_starJspMapped=true;
|
||||
|
||||
|
||||
//now find the jsp servlet, ignoring the mapping that is for ourself
|
||||
ServletMapping[] mappings = _servletHandler.getServletMappings();
|
||||
for (ServletMapping m:mappings)
|
||||
|
@ -80,11 +81,11 @@ public class JspPropertyGroupServlet extends GenericServlet
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jsp_name=servlet_mapping.getServletName();
|
||||
}
|
||||
_jspServlet=_servletHandler.getServlet(jsp_name);
|
||||
|
||||
|
||||
String dft_name="default";
|
||||
ServletMapping default_mapping=_servletHandler.getServletMapping("/");
|
||||
if (default_mapping!=null)
|
||||
|
@ -94,7 +95,7 @@ public class JspPropertyGroupServlet extends GenericServlet
|
|||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
|
||||
{
|
||||
{
|
||||
HttpServletRequest request = null;
|
||||
if (req instanceof HttpServletRequest)
|
||||
request = (HttpServletRequest)req;
|
||||
|
@ -118,27 +119,27 @@ public class JspPropertyGroupServlet extends GenericServlet
|
|||
servletPath = request.getServletPath();
|
||||
pathInfo = request.getPathInfo();
|
||||
}
|
||||
|
||||
|
||||
String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
|
||||
|
||||
|
||||
if (pathInContext.endsWith("/"))
|
||||
{
|
||||
_dftServlet.getServlet().service(req,res);
|
||||
}
|
||||
else if (_starJspMapped && pathInContext.toLowerCase().endsWith(".jsp"))
|
||||
else if (_starJspMapped && pathInContext.toLowerCase(Locale.ENGLISH).endsWith(".jsp"))
|
||||
{
|
||||
_jspServlet.getServlet().service(req,res);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
Resource resource = _contextHandler.getResource(pathInContext);
|
||||
if (resource!=null && resource.isDirectory())
|
||||
_dftServlet.getServlet().service(req,res);
|
||||
else
|
||||
_jspServlet.getServlet().service(req,res);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.BufferedReader;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -40,7 +41,7 @@ public class Licensing
|
|||
// skip, no license
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (licenseMap.containsKey(module.getName()))
|
||||
{
|
||||
// skip, already being tracked
|
||||
|
@ -61,7 +62,7 @@ public class Licensing
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
System.err.printf("%nALERT: There are enabled module(s) with licenses.%n");
|
||||
System.err.printf("The following %d module(s):%n", licenseMap.size());
|
||||
System.err.printf(" + contains software not provided by the Eclipse Foundation!%n");
|
||||
|
@ -96,7 +97,7 @@ public class Licensing
|
|||
System.err.printf("%nProceed (y/N)? ");
|
||||
String response = input.readLine();
|
||||
|
||||
licenseAck = (Utils.isNotBlank(response) && response.toLowerCase().startsWith("y"));
|
||||
licenseAck = (Utils.isNotBlank(response) && response.toLowerCase(Locale.ENGLISH).startsWith("y"));
|
||||
}
|
||||
|
||||
return licenseAck;
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.util.security;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -28,15 +29,15 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Password utility class.
|
||||
*
|
||||
*
|
||||
* This utility class gets a password or pass phrase either by:
|
||||
*
|
||||
*
|
||||
* <PRE>
|
||||
* + Password is set as a system property.
|
||||
* + The password is prompted for and read from standard input
|
||||
* + A program is run to get the password.
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* Passwords that begin with OBF: are de obfuscated. Passwords can be obfuscated
|
||||
* by run org.eclipse.util.Password as a main class. Obfuscated password are
|
||||
* required if a system needs to recover the full password (eg. so that it may
|
||||
|
@ -50,8 +51,8 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* a secure(ish) way to store passwords that only need to be checked rather than
|
||||
* recovered. Note that it is not strong security - specially if simple
|
||||
* passwords are used.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Password extends Credential
|
||||
{
|
||||
|
@ -66,7 +67,7 @@ public class Password extends Credential
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param password The String password.
|
||||
*/
|
||||
public Password(String password)
|
||||
|
@ -112,10 +113,10 @@ public class Password extends Credential
|
|||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (null == o)
|
||||
if (null == o)
|
||||
return false;
|
||||
|
||||
if (o instanceof Password)
|
||||
|
@ -125,7 +126,7 @@ public class Password extends Credential
|
|||
return p._pw == _pw || (null != _pw && _pw.equals(p._pw));
|
||||
}
|
||||
|
||||
if (o instanceof String)
|
||||
if (o instanceof String)
|
||||
return o.equals(_pw);
|
||||
|
||||
return false;
|
||||
|
@ -151,8 +152,8 @@ public class Password extends Credential
|
|||
byte b2 = b[b.length - (i + 1)];
|
||||
if (b1<0 || b2<0)
|
||||
{
|
||||
int i0 = (0xff&b1)*256 + (0xff&b2);
|
||||
String x = Integer.toString(i0, 36).toLowerCase();
|
||||
int i0 = (0xff&b1)*256 + (0xff&b2);
|
||||
String x = Integer.toString(i0, 36).toLowerCase(Locale.ENGLISH);
|
||||
buf.append("U0000",0,5-x.length());
|
||||
buf.append(x);
|
||||
}
|
||||
|
@ -161,13 +162,13 @@ public class Password extends Credential
|
|||
int i1 = 127 + b1 + b2;
|
||||
int i2 = 127 + b1 - b2;
|
||||
int i0 = i1 * 256 + i2;
|
||||
String x = Integer.toString(i0, 36).toLowerCase();
|
||||
String x = Integer.toString(i0, 36).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
int j0 = Integer.parseInt(x, 36);
|
||||
int j1 = (i0 / 256);
|
||||
int j2 = (i0 % 256);
|
||||
byte bx = (byte) ((j1 + j2 - 254) / 2);
|
||||
|
||||
|
||||
buf.append("000",0,4-x.length());
|
||||
buf.append(x);
|
||||
}
|
||||
|
@ -216,7 +217,7 @@ public class Password extends Credential
|
|||
* <LI>Prompting for a password
|
||||
* <LI>Using promptDft if nothing was entered.
|
||||
* </UL>
|
||||
*
|
||||
*
|
||||
* @param realm The realm name for the password, used as a SystemProperty
|
||||
* name.
|
||||
* @param dft The default password.
|
||||
|
|
Loading…
Reference in New Issue