diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java index a6fb0d5a908..fee0a67bbd9 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java @@ -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(); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index ad03a373dc8..1c653d15dc1 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -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 *

* 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. *

*

- * 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()} *

*

- * 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 * */ public final static Trie CACHE = new ArrayTrie<>(2048); - + // States public enum State { @@ -132,7 +133,7 @@ public class HttpParser private final static EnumSet __idleStates = EnumSet.of(State.START,State.END,State.CLOSE,State.CLOSED); private final static EnumSet __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.CONTENT.ordinal() && _state.ordinal()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. diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index 290b8613ada..dbdd4b83c67 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -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) diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java index 38c17cb1d5b..75ccc054302 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java @@ -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 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")); - } - } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java index ec497008af8..3e142371c75 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java @@ -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); } } diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java index 207a5e49f16..a8d53ddec15 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java @@ -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 - * 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); } - + } } diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Licensing.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Licensing.java index 055951fbce6..b907d71c33b 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Licensing.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Licensing.java @@ -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; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java index 9b4174ef469..a414d7567e2 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java @@ -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: - * + * *

  *  + 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.
  * 
- * + * * 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 *
  • Prompting for a password *
  • Using promptDft if nothing was entered. * - * + * * @param realm The realm name for the password, used as a SystemProperty * name. * @param dft The default password.