Mercurial Hosting > luan
changeset 1080:0d884377e923
eliminate other head
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 10 Nov 2016 21:37:04 -0700 |
parents | 53e77f60b789 (diff) ebb0f1343ef6 (current diff) |
children | ccc4573979de |
files | lib/slf4j-api-1.7.21.jar lib/slf4j-log4j12-1.7.21.jar scripts/build-luan.sh src/luan/LuanJavaFunction.java src/luan/modules/PackageLuan.java src/luan/modules/ThreadLuan.java src/luan/modules/http/AuthenticationHandler.java src/luan/modules/http/Http.luan src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java src/luan/modules/http/NotFound.java src/luan/modules/http/Server.luan src/org/eclipse/jetty/http/HttpCookie.java src/org/eclipse/jetty/http/HttpException.java src/org/eclipse/jetty/http/HttpFields.java src/org/eclipse/jetty/http/HttpGenerator.java src/org/eclipse/jetty/http/HttpHeaderValues.java src/org/eclipse/jetty/http/HttpHeaders.java src/org/eclipse/jetty/http/HttpMethods.java src/org/eclipse/jetty/http/HttpParser.java src/org/eclipse/jetty/http/HttpStatus.java src/org/eclipse/jetty/http/HttpTokens.java src/org/eclipse/jetty/http/HttpURI.java src/org/eclipse/jetty/http/HttpVersions.java src/org/eclipse/jetty/http/MimeTypes.java src/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java src/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java src/org/eclipse/jetty/http/mime.properties src/org/eclipse/jetty/http/ssl/SslContextFactory.java src/org/eclipse/jetty/http/useragents src/org/eclipse/jetty/io/AbstractConnection.java src/org/eclipse/jetty/io/AsyncEndPoint.java src/org/eclipse/jetty/io/BufferUtil.java src/org/eclipse/jetty/io/Buffers.java src/org/eclipse/jetty/io/Connection.java src/org/eclipse/jetty/io/EndPoint.java src/org/eclipse/jetty/io/EofException.java src/org/eclipse/jetty/io/RuntimeIOException.java src/org/eclipse/jetty/io/StringCache.java src/org/eclipse/jetty/io/WriterOutputStream.java src/org/eclipse/jetty/io/nio/AsyncConnection.java src/org/eclipse/jetty/io/nio/ChannelEndPoint.java src/org/eclipse/jetty/io/nio/SaneSelector.java src/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java src/org/eclipse/jetty/io/nio/SelectorManager.java src/org/eclipse/jetty/io/nio/SslConnection.java src/org/eclipse/jetty/jetty-dir.css src/org/eclipse/jetty/server/AbstractHttpConnection.java src/org/eclipse/jetty/server/AsyncHttpConnection.java src/org/eclipse/jetty/server/BlockingHttpConnection.java src/org/eclipse/jetty/server/Connector.java src/org/eclipse/jetty/server/CookieCutter.java src/org/eclipse/jetty/server/Handler.java src/org/eclipse/jetty/server/HandlerContainer.java src/org/eclipse/jetty/server/HttpWriter.java src/org/eclipse/jetty/server/Request.java src/org/eclipse/jetty/server/Response.java src/org/eclipse/jetty/server/Server.java src/org/eclipse/jetty/server/handler/AbstractHandler.java src/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java src/org/eclipse/jetty/server/handler/ContextHandler.java src/org/eclipse/jetty/server/handler/DefaultHandler.java src/org/eclipse/jetty/server/handler/GzipHandler.java src/org/eclipse/jetty/server/handler/HandlerCollection.java src/org/eclipse/jetty/server/handler/HandlerList.java src/org/eclipse/jetty/server/handler/HandlerWrapper.java src/org/eclipse/jetty/server/handler/RequestLogHandler.java src/org/eclipse/jetty/server/handler/ResourceHandler.java src/org/eclipse/jetty/server/handler/ShutdownHandler.java src/org/eclipse/jetty/server/nio/BlockingChannelConnector.java src/org/eclipse/jetty/server/nio/SelectChannelConnector.java src/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties src/org/eclipse/jetty/server/ssl/ServletSSL.java src/org/eclipse/jetty/server/ssl/SslCertificates.java src/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java src/org/eclipse/jetty/util/ArrayQueue.java src/org/eclipse/jetty/util/Attributes.java src/org/eclipse/jetty/util/AttributesMap.java src/org/eclipse/jetty/util/ByteArrayISO8859Writer.java src/org/eclipse/jetty/util/ByteArrayOutputStream2.java src/org/eclipse/jetty/util/IO.java src/org/eclipse/jetty/util/LazyList.java src/org/eclipse/jetty/util/MultiException.java src/org/eclipse/jetty/util/MultiMap.java src/org/eclipse/jetty/util/MultiPartInputStream.java src/org/eclipse/jetty/util/MultiPartOutputStream.java src/org/eclipse/jetty/util/MultiPartWriter.java src/org/eclipse/jetty/util/QuotedStringTokenizer.java src/org/eclipse/jetty/util/ReadLineInputStream.java src/org/eclipse/jetty/util/StringUtil.java src/org/eclipse/jetty/util/TypeUtil.java src/org/eclipse/jetty/util/URIUtil.java src/org/eclipse/jetty/util/UrlEncoded.java src/org/eclipse/jetty/util/Utf8Appendable.java src/org/eclipse/jetty/util/Utf8StringBuffer.java src/org/eclipse/jetty/util/Utf8StringBuilder.java src/org/eclipse/jetty/util/component/AbstractLifeCycle.java src/org/eclipse/jetty/util/component/AggregateLifeCycle.java src/org/eclipse/jetty/util/component/Destroyable.java src/org/eclipse/jetty/util/component/Dumpable.java src/org/eclipse/jetty/util/component/LifeCycle.java src/org/eclipse/jetty/util/component/jmx/AggregateLifeCycle-mbean.properties src/org/eclipse/jetty/util/component/jmx/Dumpable-mbean.properties src/org/eclipse/jetty/util/component/jmx/LifeCycle-mbean.properties src/org/eclipse/jetty/util/resource/BadResource.java src/org/eclipse/jetty/util/resource/FileResource.java src/org/eclipse/jetty/util/resource/JarFileResource.java src/org/eclipse/jetty/util/resource/JarResource.java src/org/eclipse/jetty/util/resource/Resource.java src/org/eclipse/jetty/util/resource/ResourceCollection.java src/org/eclipse/jetty/util/resource/ResourceFactory.java src/org/eclipse/jetty/util/resource/URLResource.java src/org/eclipse/jetty/util/security/CertificateUtils.java src/org/eclipse/jetty/util/security/CertificateValidator.java src/org/eclipse/jetty/util/security/Constraint.java src/org/eclipse/jetty/util/security/Credential.java src/org/eclipse/jetty/util/security/Password.java src/org/eclipse/jetty/util/security/UnixCrypt.java src/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java src/org/eclipse/jetty/util/ssl/AliasedX509KeyManager.java src/org/eclipse/jetty/util/ssl/SslContextFactory.java src/org/eclipse/jetty/util/thread/jmx/QueuedThreadPool-mbean.properties src/org/eclipse/jetty/util/thread/jmx/ThreadPool-mbean.properties |
diffstat | 130 files changed, 77 insertions(+), 31351 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/build-luan.sh Thu Nov 10 03:08:20 2016 -0700 +++ b/scripts/build-luan.sh Thu Nov 10 21:37:04 2016 -0700 @@ -20,7 +20,7 @@ for i in $LUAN_HOME/lib/* ; do CLASSPATH=$CLASSPATH:$i ; done cd src javac -classpath $CLASSPATH `find . -name *.java` -jar cvf $LUAN_BUILD/luan/jars/luan-$VERSION.jar `find . -name *.class -o -name *.luan -o -name *.css -o -name *.properties` +jar cvf $LUAN_BUILD/luan/jars/luan-$VERSION.jar `find . -name *.class -o -name *.luan` cp $LUAN_HOME/lib/* $LUAN_BUILD/luan/jars cp $LUAN_HOME/scripts/install.sh $LUAN_BUILD/luan
--- a/src/luan/LuanJavaFunction.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/LuanJavaFunction.java Thu Nov 10 21:37:04 2016 -0700 @@ -110,36 +110,36 @@ if( !type.isInstance(arg) ) { String expected; if( i==a.length-1 && method.isVarArgs() ) - expected = type(paramType.getComponentType())+"..."; + expected = fixType(paramType.getComponentType().getSimpleName())+"..."; else - expected = type(paramType); + expected = fixType(paramType.getSimpleName()); if( arg==null ) { if( paramType.isPrimitive() ) throw new LuanException("bad argument #"+(i+1-start)+" ("+expected+" expected, got nil)"); } else { - String got = type(arg.getClass()); + String got = fixType(arg.getClass().getSimpleName()); throw new LuanException("bad argument #"+(i+1-start)+" ("+expected+" expected, got "+got+")"); } } } } - private static final Class byteArray = new byte[0].getClass(); - - private static String type(Class cls) { - if( LuanFunction.class.isAssignableFrom(cls) ) - return "function"; - if( Boolean.class.isAssignableFrom(cls) ) + private static String fixType(String type) { + if( type.equals("byte[]") ) + return "binary"; + if( type.equals("Double") ) + return "number"; + if( type.equals("LuanTable") ) + return "table"; + if( type.equals("Boolean") ) return "boolean"; - if( String.class.isAssignableFrom(cls) ) + if( type.equals("String") ) return "string"; - if( Number.class.isAssignableFrom(cls) ) - return "number"; - if( LuanTable.class.isAssignableFrom(cls) ) - return "table"; - if( byteArray.isAssignableFrom(cls) ) - return "binary"; - return cls.getName(); + if( type.equals("Closure") ) + return "function"; + if( type.equals("LuanJavaFunction") ) + return "function"; + return type; } private Object[] fixArgs(LuanState luan,Object[] args) throws LuanException {
--- a/src/luan/modules/PackageLuan.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/PackageLuan.java Thu Nov 10 21:37:04 2016 -0700 @@ -45,8 +45,6 @@ if( mod == null ) { if( modName.startsWith("java:") ) { mod = JavaLuan.load(luan,modName.substring(5)); - if( mod == null ) - mod = Boolean.FALSE; } else { String src = read(luan,modName); if( src == null ) {
--- a/src/luan/modules/ThreadLuan.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/ThreadLuan.java Thu Nov 10 21:37:04 2016 -0700 @@ -84,7 +84,7 @@ public long timeout = 60000L; // one minute private Map<String,Value> map = new LinkedHashMap<String,Value>() { - @Override protected boolean removeEldestEntry(Map.Entry<String,Value> eldest) { + protected boolean removeEldestEntry(Map.Entry<String,Value> eldest) { return eldest.getValue().time < System.currentTimeMillis() - timeout; } };
--- a/src/luan/modules/Time.luan Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/Time.luan Thu Nov 10 21:37:04 2016 -0700 @@ -4,6 +4,8 @@ local Luan = require "luan:Luan.luan" local error = Luan.error local ipairs = Luan.ipairs or error() +local Math = require "luan:Math.luan" +local floor = Math.floor or error() local Table = require "luan:Table.luan" local System = require "java:java.lang.System" local Calendar = require "java:java.util.Calendar" @@ -29,8 +31,8 @@ cal.setTimeInMillis(time) local rtn = {} for i, v in ipairs{...} do - local fld = fields[v.lower()] - fld or error("invalid field: "+v) + local fld = fields[v] + fld or error("invalid field: "..v) local n = cal.get(fld) if fld == "month" then n = n + 1 @@ -68,4 +70,27 @@ return SimpleDateFormat.new(pattern).parse(source).getTime() end + +local count_times = { + days = M.period{days=1} + hours = M.period{hours=1} + minutes = M.period{minutes=1} + seconds = M.period{seconds=1} +} + +function M.count( time, ... ) + local cal = Calendar.getInstance() + cal.setTimeInMillis(time) + local rtn = {} + for i, v in ipairs{...} do + local t = count_times[v] + t or error("invalid field: "..v) + rtn[#rtn+1] = floor(time/t) + time = time%t + end + rtn[#rtn+1] = time + return Table.unpack(rtn) +end + + return M
--- a/src/luan/modules/http/AuthenticationHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/AuthenticationHandler.java Thu Nov 10 21:37:04 2016 -0700 @@ -1,10 +1,11 @@ package luan.modules.http; import java.io.IOException; -import java.util.Base64; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.util.B64Code; public class AuthenticationHandler extends AbstractHandler { @@ -19,8 +20,7 @@ this.password = password; } - @Override - public void handle(String target,Request request,HttpServletResponse response) + public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) throws IOException { if( !target.startsWith(path) ) @@ -30,10 +30,10 @@ return; response.setHeader("WWW-Authenticate","Basic realm=\""+path+"\""); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - request.setHandled(true); + baseRequest.setHandled(true); } - private static String getPassword(Request request) { + private static String getPassword(HttpServletRequest request) { String auth = request.getHeader("Authorization"); if( auth==null ) return null; @@ -42,7 +42,7 @@ throw new RuntimeException("auth = "+auth); if( !a[0].equals("Basic") ) throw new RuntimeException("auth = "+auth); - auth = new String(Base64.getDecoder().decode(a[1])); + auth = new String(B64Code.decode(a[1])); a = auth.split(":"); if( a.length != 2 ) throw new RuntimeException("auth = "+auth);
--- a/src/luan/modules/http/Http.luan Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/Http.luan Thu Nov 10 21:37:04 2016 -0700 @@ -153,7 +153,7 @@ end function M.clear_session() - M.response.remove_cookie "session" + M.request.java.getSession().removeAttribute("luan") end
--- a/src/luan/modules/http/HttpServicer.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/HttpServicer.java Thu Nov 10 21:37:04 2016 -0700 @@ -5,7 +5,6 @@ import java.io.PrintWriter; import java.io.IOException; import java.util.Map; -import java.util.LinkedHashMap; import java.util.Set; import java.util.List; import java.util.ArrayList; @@ -14,12 +13,12 @@ import java.util.Enumeration; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.ServletOutputStream; import javax.servlet.ServletException; import javax.servlet.http.Cookie; -import org.eclipse.jetty.server.Request; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import javax.servlet.http.Part; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,15 +40,7 @@ public final class HttpServicer { private static final Logger logger = LoggerFactory.getLogger(HttpServicer.class); - public static long sessionTimeout = 60*60*1000L; // one hour - private static AtomicInteger sessionCounter = new AtomicInteger(); - private static Map<String,LuanState> sessionMap = new LinkedHashMap<String,LuanState>() { - @Override protected boolean removeEldestEntry(Map.Entry<String,LuanState> eldest) { - return (Long)eldest.getValue().registry().get("sessionTimeout") < System.currentTimeMillis(); - } - }; - - public static boolean service(LuanState luan,Request request,HttpServletResponse response,String modName) + public static boolean service(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName) throws LuanException { LuanFunction fn; @@ -63,19 +54,14 @@ if( !(mod instanceof LuanFunction) ) throw new LuanException( "module '"+modName+"' must return a function" ); if( Boolean.TRUE.equals(per_session_pages.rawGet(mod)) ) { - LuanState sessionLuan = null; - Cookie cookie = getCookie(request,"session"); - if( cookie != null ) - sessionLuan = sessionMap.get(cookie.getValue()); + HttpSession session = request.getSession(); + LuanState sessionLuan = (LuanState)session.getAttribute("luan"); if( sessionLuan!=null ) { luan = sessionLuan; } else { LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); luan = (LuanState)cloner.clone(luan); - luan.registry().put( "sessionTimeout", System.currentTimeMillis() + sessionTimeout ); - String key = Integer.toString(sessionCounter.incrementAndGet()); - setCookie(request,response,"session",key,false,null); - sessionMap.put(key,luan); + session.setAttribute("luan",luan); } fn = (LuanFunction)PackageLuan.require(luan,modName); } else { @@ -118,7 +104,8 @@ } else { // multipart try { InputStream in = new BufferedInputStream(request.getInputStream()); - final MultiPartInputStream mpis = new MultiPartInputStream(in,contentType); + final MultiPartInputStream mpis = new MultiPartInputStream(in,contentType,null,null); + mpis.setDeleteOnExit(true); for( Part p : mpis.getParts() ) { final MultiPartInputStream.MultiPart part = (MultiPartInputStream.MultiPart)p; String name = part.getName(); @@ -265,7 +252,7 @@ return value.replaceAll("%3B", ";"); } - private static Cookie getCookie(Request request,String name) { + private static Cookie getCookie(HttpServletRequest request,String name) { Cookie[] cookies = request.getCookies(); if( cookies == null ) return null; @@ -276,7 +263,7 @@ return null; } - public static void setCookie(Request request,HttpServletResponse response,String name,String value,boolean isPersistent, String domain) { + public static void setCookie(HttpServletRequest request,HttpServletResponse response,String name,String value,boolean isPersistent, String domain) { Cookie cookie = getCookie(request,name); if( cookie==null || !cookie.getValue().equals(value) ) { cookie = new Cookie(name, escape(value)); @@ -289,7 +276,7 @@ } } - public static void removeCookie(Request request, + public static void removeCookie(HttpServletRequest request, HttpServletResponse response, String name, String domain
--- a/src/luan/modules/http/LuanHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/LuanHandler.java Thu Nov 10 21:37:04 2016 -0700 @@ -5,6 +5,7 @@ import java.net.BindException; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,11 +51,9 @@ } } - @Override - public void handle(String target,Request request,HttpServletResponse response) + @Override public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) throws IOException { -//Thread.dumpStack(); if( target.endsWith("/") ) target += welcomeFile; Thread thread = Thread.currentThread(); @@ -73,7 +72,7 @@ lock.readLock().unlock(); thread.setName(oldName); } - request.setHandled(true); + baseRequest.setHandled(true); } public void setWelcomeFile(String welcomeFile) { @@ -168,4 +167,5 @@ throw new LuanException(e.toString()); } } + }
--- a/src/luan/modules/http/NotFound.java Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/NotFound.java Thu Nov 10 21:37:04 2016 -0700 @@ -1,6 +1,7 @@ package luan.modules.http; import java.io.IOException; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; @@ -13,11 +14,10 @@ this.luanHandler = luanHandler; } - @Override - public void handle(String target,Request request,HttpServletResponse response) + @Override public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response) throws IOException { - luanHandler.handle("/not_found",request,response); + luanHandler.handle("/not_found",baseRequest,request,response); } }
--- a/src/luan/modules/http/Server.luan Thu Nov 10 03:08:20 2016 -0700 +++ b/src/luan/modules/http/Server.luan Thu Nov 10 21:37:04 2016 -0700 @@ -14,6 +14,7 @@ java() local Server = require "java:org.eclipse.jetty.server.Server" +local NCSARequestLog = require "java:org.eclipse.jetty.server.NCSARequestLog" local DefaultHandler = require "java:org.eclipse.jetty.server.handler.DefaultHandler" local HandlerList = require "java:org.eclipse.jetty.server.handler.HandlerList" local HandlerCollection = require "java:org.eclipse.jetty.server.handler.HandlerCollection" @@ -22,6 +23,7 @@ local ContextHandler = require "java:org.eclipse.jetty.server.handler.ContextHandler" local GzipHandler = require "java:org.eclipse.jetty.server.handler.GzipHandler" local HandlerWrapper = require "java:org.eclipse.jetty.server.handler.HandlerWrapper" +local SessionHandler = require "java:org.eclipse.jetty.server.session.SessionHandler" local AuthenticationHandler = require "java:luan.modules.http.AuthenticationHandler" local LuanHandler = require "java:luan.modules.http.LuanHandler" local NotFound = require "java:luan.modules.http.NotFound" @@ -62,14 +64,17 @@ M.handler_wrapper.setHandler(h) end +M.log = NCSARequestLog.new() +M.log.setExtended(false) M.log_handler = RequestLogHandler.new() +M.log_handler.setRequestLog(M.log) function M.set_log_file(file_name) M.log.setFilename(file_name) end local hc = HandlerCollection.new() -hc.setHandlers { M.handler_wrapper, DefaultHandler.new(), M.log_handler } +hc.setHandlers { SessionHandler.new(), M.handler_wrapper, DefaultHandler.new(), M.log_handler } function M.init(dir)
--- a/src/org/eclipse/jetty/http/HttpCookie.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -public class HttpCookie -{ - private final String _name; - private final String _value; - private final String _comment; - private final String _domain; - private final int _maxAge; - private final String _path; - private final boolean _secure; - private final int _version; - private final boolean _httpOnly; - - /* ------------------------------------------------------------ */ - public HttpCookie(String name, String value) - { - super(); - _name = name; - _value = value; - _comment = null; - _domain = null; - _httpOnly = false; - _maxAge = -1; - _path = null; - _secure = false; - _version = 0; - } - - /* ------------------------------------------------------------ */ - public HttpCookie(String name, String value, String domain, String path) - { - super(); - _name = name; - _value = value; - _comment = null; - _domain = domain; - _httpOnly = false; - _maxAge = -1; - _path = path; - _secure = false; - _version = 0; - - } - - /* ------------------------------------------------------------ */ - public HttpCookie(String name, String value, int maxAge) - { - super(); - _name = name; - _value = value; - _comment = null; - _domain = null; - _httpOnly = false; - _maxAge = maxAge; - _path = null; - _secure = false; - _version = 0; - } - - /* ------------------------------------------------------------ */ - public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure) - { - super(); - _comment = null; - _domain = domain; - _httpOnly = httpOnly; - _maxAge = maxAge; - _name = name; - _path = path; - _secure = secure; - _value = value; - _version = 0; - } - - /* ------------------------------------------------------------ */ - public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure, String comment, int version) - { - super(); - _comment = comment; - _domain = domain; - _httpOnly = httpOnly; - _maxAge = maxAge; - _name = name; - _path = path; - _secure = secure; - _value = value; - _version = version; - } - - /* ------------------------------------------------------------ */ - /** Get the name. - * @return the name - */ - public String getName() - { - return _name; - } - - /* ------------------------------------------------------------ */ - /** Get the value. - * @return the value - */ - public String getValue() - { - return _value; - } - - /* ------------------------------------------------------------ */ - /** Get the comment. - * @return the comment - */ - public String getComment() - { - return _comment; - } - - /* ------------------------------------------------------------ */ - /** Get the domain. - * @return the domain - */ - public String getDomain() - { - return _domain; - } - - /* ------------------------------------------------------------ */ - /** Get the maxAge. - * @return the maxAge - */ - public int getMaxAge() - { - return _maxAge; - } - - /* ------------------------------------------------------------ */ - /** Get the path. - * @return the path - */ - public String getPath() - { - return _path; - } - - /* ------------------------------------------------------------ */ - /** Get the secure. - * @return the secure - */ - public boolean isSecure() - { - return _secure; - } - - /* ------------------------------------------------------------ */ - /** Get the version. - * @return the version - */ - public int getVersion() - { - return _version; - } - - /* ------------------------------------------------------------ */ - /** Get the isHttpOnly. - * @return the isHttpOnly - */ - public boolean isHttpOnly() - { - return _httpOnly; - } - - -}
--- a/src/org/eclipse/jetty/http/HttpException.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; - -public class HttpException extends IOException -{ - int _status; - String _reason; - - /* ------------------------------------------------------------ */ - public HttpException(int status) - { - _status=status; - _reason=null; - } - - /* ------------------------------------------------------------ */ - public HttpException(int status,String reason) - { - _status=status; - _reason=reason; - } - - /* ------------------------------------------------------------ */ - public HttpException(int status,String reason, Throwable rootCause) - { - _status=status; - _reason=reason; - initCause(rootCause); - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the reason. - */ - public String getReason() - { - return _reason; - } - - /* ------------------------------------------------------------ */ - /** - * @param reason The reason to set. - */ - public void setReason(String reason) - { - _reason = reason; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the status. - */ - public int getStatus() - { - return _status; - } - - /* ------------------------------------------------------------ */ - /** - * @param status The status to set. - */ - public void setStatus(int status) - { - _status = status; - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return ("HttpException("+_status+","+_reason+","+super.getCause()+")"); - } - - -}
--- a/src/org/eclipse/jetty/http/HttpFields.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1026 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Collection; -import java.util.Date; -import java.util.Enumeration; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; -import java.util.TimeZone; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * HTTP Fields. A collection of HTTP header and or Trailer fields. - * - * <p>This class is not synchronized as it is expected that modifications will only be performed by a - * single thread. - * - * - */ -public final class HttpFields -{ - private static final Logger LOG = LoggerFactory.getLogger(HttpFields.class); - - private static final String __COOKIE_DELIM="\"\\\n\r\t\f\b%+ ;="; - private static final TimeZone __GMT = TimeZone.getTimeZone("GMT"); - - private static final String[] DAYS = - { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - private static final String[] MONTHS = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"}; - - - private static class DateGenerator - { - private final StringBuilder buf = new StringBuilder(32); - private final GregorianCalendar gc = new GregorianCalendar(__GMT); - - /** - * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" - */ - public String formatDate(long date) - { - buf.setLength(0); - gc.setTimeInMillis(date); - - int day_of_week = gc.get(Calendar.DAY_OF_WEEK); - int day_of_month = gc.get(Calendar.DAY_OF_MONTH); - int month = gc.get(Calendar.MONTH); - int year = gc.get(Calendar.YEAR); - int century = year / 100; - year = year % 100; - - int hours = gc.get(Calendar.HOUR_OF_DAY); - int minutes = gc.get(Calendar.MINUTE); - int seconds = gc.get(Calendar.SECOND); - - buf.append(DAYS[day_of_week]); - buf.append(','); - buf.append(' '); - StringUtil.append2digits(buf, day_of_month); - - buf.append(' '); - buf.append(MONTHS[month]); - buf.append(' '); - StringUtil.append2digits(buf, century); - StringUtil.append2digits(buf, year); - - buf.append(' '); - StringUtil.append2digits(buf, hours); - buf.append(':'); - StringUtil.append2digits(buf, minutes); - buf.append(':'); - StringUtil.append2digits(buf, seconds); - buf.append(" GMT"); - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - /** - * Format "EEE, dd-MMM-yy HH:mm:ss 'GMT'" for cookies - */ - public void formatCookieDate(StringBuilder buf, long date) - { - gc.setTimeInMillis(date); - - int day_of_week = gc.get(Calendar.DAY_OF_WEEK); - int day_of_month = gc.get(Calendar.DAY_OF_MONTH); - int month = gc.get(Calendar.MONTH); - int year = gc.get(Calendar.YEAR); - year = year % 10000; - - int epoch = (int) ((date / 1000) % (60 * 60 * 24)); - int seconds = epoch % 60; - epoch = epoch / 60; - int minutes = epoch % 60; - int hours = epoch / 60; - - buf.append(DAYS[day_of_week]); - buf.append(','); - buf.append(' '); - StringUtil.append2digits(buf, day_of_month); - - buf.append('-'); - buf.append(MONTHS[month]); - buf.append('-'); - StringUtil.append2digits(buf, year/100); - StringUtil.append2digits(buf, year%100); - - buf.append(' '); - StringUtil.append2digits(buf, hours); - buf.append(':'); - StringUtil.append2digits(buf, minutes); - buf.append(':'); - StringUtil.append2digits(buf, seconds); - buf.append(" GMT"); - } - } - - private static final ThreadLocal<DateGenerator> __dateGenerator = new ThreadLocal<DateGenerator>() - { - @Override - protected DateGenerator initialValue() - { - return new DateGenerator(); - } - }; - - /* ------------------------------------------------------------ */ - /** - * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" - */ - private static String formatDate(long date) - { - return __dateGenerator.get().formatDate(date); - } - - /* ------------------------------------------------------------ */ - /** - * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies - */ - private static void formatCookieDate(StringBuilder buf, long date) - { - __dateGenerator.get().formatCookieDate(buf,date); - } - - /* ------------------------------------------------------------ */ - /** - * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies - */ - private static String formatCookieDate(long date) - { - StringBuilder buf = new StringBuilder(28); - formatCookieDate(buf, date); - return buf.toString(); - } - - private final static String __dateReceiveFmt[] = - { - "EEE, dd MMM yyyy HH:mm:ss zzz", - "EEE, dd-MMM-yy HH:mm:ss", - "EEE MMM dd HH:mm:ss yyyy", - - "EEE, dd MMM yyyy HH:mm:ss", "EEE dd MMM yyyy HH:mm:ss zzz", - "EEE dd MMM yyyy HH:mm:ss", "EEE MMM dd yyyy HH:mm:ss zzz", "EEE MMM dd yyyy HH:mm:ss", - "EEE MMM-dd-yyyy HH:mm:ss zzz", "EEE MMM-dd-yyyy HH:mm:ss", "dd MMM yyyy HH:mm:ss zzz", - "dd MMM yyyy HH:mm:ss", "dd-MMM-yy HH:mm:ss zzz", "dd-MMM-yy HH:mm:ss", "MMM dd HH:mm:ss yyyy zzz", - "MMM dd HH:mm:ss yyyy", "EEE MMM dd HH:mm:ss yyyy zzz", - "EEE, MMM dd HH:mm:ss yyyy zzz", "EEE, MMM dd HH:mm:ss yyyy", "EEE, dd-MMM-yy HH:mm:ss zzz", - "EEE dd-MMM-yy HH:mm:ss zzz", "EEE dd-MMM-yy HH:mm:ss", - }; - - private static class DateParser - { - final SimpleDateFormat _dateReceive[] = new SimpleDateFormat[__dateReceiveFmt.length]; - - long parse(final String dateVal) - { - for (int i = 0; i < _dateReceive.length; i++) - { - if (_dateReceive[i] == null) - { - _dateReceive[i] = new SimpleDateFormat(__dateReceiveFmt[i], Locale.US); - _dateReceive[i].setTimeZone(__GMT); - } - - try - { - Date date = (Date) _dateReceive[i].parseObject(dateVal); - return date.getTime(); - } - catch (java.lang.Exception e) - { - // LOG.ignore(e); - } - } - - if (dateVal.endsWith(" GMT")) - { - final String val = dateVal.substring(0, dateVal.length() - 4); - - for (int i = 0; i < _dateReceive.length; i++) - { - try - { - Date date = (Date) _dateReceive[i].parseObject(val); - return date.getTime(); - } - catch (java.lang.Exception e) - { - // LOG.ignore(e); - } - } - } - return -1; - } - } - - private static final ThreadLocal<DateParser> __dateParser =new ThreadLocal<DateParser>() - { - @Override - protected DateParser initialValue() - { - return new DateParser(); - } - }; - - private final static String __01Jan1970 = formatDate(0); - private final static String __01Jan1970_COOKIE = formatCookieDate(0).trim(); - - - - - - - private final ArrayList<Field> _fields = new ArrayList<Field>(); - private final HashMap<String,Field> _names = new HashMap<String,Field>(); - - - /* -------------------------------------------------------------- */ - /** - * Get Collection of header names. - */ - public Collection<String> getFieldNamesCollection() - { - final List<String> list = new ArrayList<String>(_fields.size()); - - for (Field f : _fields) - { - if (f!=null) - list.add(f._name.toString()); - } - return list; - } - - /* -------------------------------------------------------------- */ - /** - * Get enumeration of header _names. Returns an enumeration of strings representing the header - * _names for this request. - */ - public Enumeration<String> getFieldNames() - { - final Enumeration<?> buffers = Collections.enumeration(_names.keySet()); - return new Enumeration<String>() - { - public String nextElement() - { - return buffers.nextElement().toString(); - } - - public boolean hasMoreElements() - { - return buffers.hasMoreElements(); - } - }; - } - - /* ------------------------------------------------------------ */ - public int size() - { - return _fields.size(); - } - - /* ------------------------------------------------------------ */ - /** - * Get a Field by index. - * @return A Field value or null if the Field value has not been set - * - */ - public Field getField(int i) - { - return _fields.get(i); - } - - private Field getField(String name) - { - return _names.get(name.toLowerCase()); - } - - public boolean containsKey(String name) - { - return _names.containsKey(name.toLowerCase()); - } - - /* -------------------------------------------------------------- */ - /** - * @return the value of a field, or null if not found. For multiple fields of the same name, - * only the first is returned. - * @param name the case-insensitive field name - */ - public String getStringField(String name) - { - Field field = getField(name); - return field==null ? null : field.getValue(); - } - - /* -------------------------------------------------------------- */ - /** - * Get multi headers - * - * @return Enumeration of the values, or null if no such header. - * @param name the case-insensitive field name - */ - public Collection<String> getValuesCollection(String name) - { - Field field = getField(name); - if (field==null) - return null; - - final List<String> list = new ArrayList<String>(); - - while(field!=null) - { - list.add(field.getValue()); - field=field._next; - } - return list; - } - - /* -------------------------------------------------------------- */ - /** - * Get multi headers - * - * @return Enumeration of the values - * @param name the case-insensitive field name - */ - public Enumeration<String> getValues(String name) - { - final Field field = getField(name); - if (field == null) - { - List<String> empty=Collections.emptyList(); - return Collections.enumeration(empty); - } - - return new Enumeration<String>() - { - Field f = field; - - public boolean hasMoreElements() - { - return f != null; - } - - public String nextElement() throws NoSuchElementException - { - if (f == null) throw new NoSuchElementException(); - Field n = f; - f = f._next; - return n.getValue(); - } - }; - } - - /* -------------------------------------------------------------- */ - /** - * Get multi field values with separator. The multiple values can be represented as separate - * headers of the same name, or by a single header using the separator(s), or a combination of - * both. Separators may be quoted. - * - * @param name the case-insensitive field name - * @param separators String of separators. - * @return Enumeration of the values, or null if no such header. - */ - public Enumeration<String> getValues(String name, final String separators) - { - final Enumeration<String> e = getValues(name); - if (e == null) - return null; - return new Enumeration<String>() - { - QuotedStringTokenizer tok = null; - - public boolean hasMoreElements() - { - if (tok != null && tok.hasMoreElements()) return true; - while (e.hasMoreElements()) - { - String value = e.nextElement(); - tok = new QuotedStringTokenizer(value, separators, false, false); - if (tok.hasMoreElements()) return true; - } - tok = null; - return false; - } - - public String nextElement() throws NoSuchElementException - { - if (!hasMoreElements()) throw new NoSuchElementException(); - String next = (String) tok.nextElement(); - if (next != null) next = next.trim(); - return next; - } - }; - } - - - /* -------------------------------------------------------------- */ - /** - * Set a field. - * - * @param name the name of the field - * @param value the value of the field. If null the field is cleared. - */ - public void put(String name, String value) - { - String nameLower = name.toLowerCase(); - removeLower(nameLower); - if (value == null) - return; - - // new value; - Field field = new Field(name, value); - _fields.add(field); - _names.put(nameLower, field); - } - - /* -------------------------------------------------------------- */ - /** - * Add to or set a field. If the field is allowed to have multiple values, add will add multiple - * headers of the same name. - * - * @param name the name of the field - * @param value the value of the field. - * @exception IllegalArgumentException If the name is a single valued field and already has a - * value. - */ - public void add(String name, String value) throws IllegalArgumentException - { - if (value == null) throw new IllegalArgumentException("null value"); - - String nameLower = name.toLowerCase(); - - Field field = _names.get(nameLower); - Field last = null; - while (field != null) - { - last = field; - field = field._next; - } - - // create the field - field = new Field(name, value); - _fields.add(field); - - // look for chain to add too - if (last != null) - last._next = field; - else - _names.put(nameLower, field); - } - - /* ------------------------------------------------------------ */ - /** - * Remove a field. - * - * @param name - */ - public void remove(String name) - { - removeLower(name.toLowerCase()); - } - - private void removeLower(String nameLower) { - Field field = _names.remove(nameLower); - while (field != null) - { - _fields.remove(field); - field = field._next; - } - } - - /* -------------------------------------------------------------- */ - /** - * Get a header as an long value. Returns the value of an integer field or -1 if not found. The - * case of the field name is ignored. - * - * @param name the case-insensitive field name - * @exception NumberFormatException If bad long found - */ - public long getLongField(String name) throws NumberFormatException - { - Field field = getField(name); - return field==null?-1L:field.getLongValue(); - } - - /* -------------------------------------------------------------- */ - /** - * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case - * of the field name is ignored. - * - * @param name the case-insensitive field name - */ - public long getDateField(String name) - { - Field field = getField(name); - if (field == null) - return -1; - - String val = valueParameters(field._value, null); - if (val == null) - return -1; - - final long date = __dateParser.get().parse(val); - if (date==-1) - throw new IllegalArgumentException("Cannot convert date: " + val); - return date; - } - - /* -------------------------------------------------------------- */ - /** - * Sets the value of an long field. - * - * @param name the field name - * @param value the field long value - */ - public void putLongField(String name, long value) - { - String v = Long.toString(value); - put(name, v); - } - - /* -------------------------------------------------------------- */ - /** - * Sets the value of an long field. - * - * @param name the field name - * @param value the field long value - */ - public void addLongField(String name, long value) - { - String v = Long.toString(value); - add(name, v); - } - - /* -------------------------------------------------------------- */ - /** - * Sets the value of a date field. - * - * @param name the field name - * @param date the field date value - */ - public void putDateField(String name, long date) - { - String d = formatDate(date); - put(name, d); - } - - /* -------------------------------------------------------------- */ - /** - * Sets the value of a date field. - * - * @param name the field name - * @param date the field date value - */ - public void addDateField(String name, long date) - { - String d = formatDate(date); - add(name, d); - } - - /* ------------------------------------------------------------ */ - /** - * Format a set cookie value - * - * @param cookie The cookie. - */ - public void addSetCookie(HttpCookie cookie) - { - addSetCookie( - cookie.getName(), - cookie.getValue(), - cookie.getDomain(), - cookie.getPath(), - cookie.getMaxAge(), - cookie.getComment(), - cookie.isSecure(), - cookie.isHttpOnly(), - cookie.getVersion()); - } - - /** - * Format a set cookie value - * - * @param name the name - * @param value the value - * @param domain the domain - * @param path the path - * @param maxAge the maximum age - * @param comment the comment (only present on versions > 0) - * @param isSecure true if secure cookie - * @param isHttpOnly true if for http only - * @param version version of cookie logic to use (0 == default behavior) - */ - public void addSetCookie( - final String name, - final String value, - final String domain, - final String path, - final long maxAge, - final String comment, - final boolean isSecure, - final boolean isHttpOnly, - int version) - { - String delim=__COOKIE_DELIM; - - // Check arguments - if (name == null || name.length() == 0) - throw new IllegalArgumentException("Bad cookie name"); - - // Format value and params - StringBuilder buf = new StringBuilder(128); - String name_value_params; - QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); - buf.append('='); - String start=buf.toString(); - boolean hasDomain = false; - boolean hasPath = false; - - if (value != null && value.length() > 0) - QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); - - if (comment != null && comment.length() > 0) - { - buf.append(";Comment="); - QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); - } - - if (path != null && path.length() > 0) - { - hasPath = true; - buf.append(";Path="); - if (path.trim().startsWith("\"")) - buf.append(path); - else - QuotedStringTokenizer.quoteIfNeeded(buf,path,delim); - } - if (domain != null && domain.length() > 0) - { - hasDomain = true; - buf.append(";Domain="); - QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(Locale.ENGLISH),delim); - } - - if (maxAge >= 0) - { - // Always add the expires param as some browsers still don't handle max-age - buf.append(";Expires="); - if (maxAge == 0) - buf.append(__01Jan1970_COOKIE); - else - formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); - - if (version >0) - { - buf.append(";Max-Age="); - buf.append(maxAge); - } - } - - if (isSecure) - buf.append(";Secure"); - if (isHttpOnly) - buf.append(";HttpOnly"); - - name_value_params = buf.toString(); - - // remove existing set-cookie of same name - Field field = getField(HttpHeaders.SET_COOKIE); - Field last=null; - while (field!=null) - { - String val = (field._value == null ? null : field._value.toString()); - if (val!=null && val.startsWith(start)) - { - //existing cookie has same name, does it also match domain and path? - if (((!hasDomain && !val.contains("Domain")) || (hasDomain && val.contains("Domain="+domain))) && - ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path="+path)))) - { - _fields.remove(field); - if (last==null) - _names.put(HttpHeaders.SET_COOKIE,field._next); - else - last._next=field._next; - break; - } - } - last=field; - field=field._next; - } - - add(HttpHeaders.SET_COOKIE, name_value_params); - - // Expire responses with set-cookie headers so they do not get cached. - put(HttpHeaders.EXPIRES, __01Jan1970); - } - - @Override - public String toString() - { - try - { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < _fields.size(); i++) - { - Field field = (Field) _fields.get(i); - if (field != null) - { - String tmp = field.getName(); - if (tmp != null) buffer.append(tmp); - buffer.append(": "); - tmp = field.getValue(); - if (tmp != null) buffer.append(tmp); - buffer.append("\r\n"); - } - } - buffer.append("\r\n"); - return buffer.toString(); - } - catch (Exception e) - { - LOG.warn("",e); - return e.toString(); - } - } - - /* ------------------------------------------------------------ */ - /** - * Clear the header. - */ - public void clear() - { - _fields.clear(); - _names.clear(); - } - - /* ------------------------------------------------------------ */ - /** - * Add fields from another HttpFields instance. Single valued fields are replaced, while all - * others are added. - * - * @param fields - */ - public void add(HttpFields fields) - { - if (fields == null) return; - - Enumeration e = fields.getFieldNames(); - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - Enumeration values = fields.getValues(name); - while (values.hasMoreElements()) - add(name, (String) values.nextElement()); - } - } - - /* ------------------------------------------------------------ */ - /** - * Get field value parameters. Some field values can have parameters. This method separates the - * value from the parameters and optionally populates a map with the parameters. For example: - * - * <PRE> - * - * FieldName : Value ; param1=val1 ; param2=val2 - * - * </PRE> - * - * @param value The Field value, possibly with parameteres. - * @param parameters A map to populate with the parameters, or null - * @return The value. - */ - public static String valueParameters(String value, Map<String,String> parameters) - { - if (value == null) return null; - - int i = value.indexOf(';'); - if (i < 0) return value; - if (parameters == null) return value.substring(0, i).trim(); - - StringTokenizer tok1 = new QuotedStringTokenizer(value.substring(i), ";", false, true); - while (tok1.hasMoreTokens()) - { - String token = tok1.nextToken(); - StringTokenizer tok2 = new QuotedStringTokenizer(token, "= "); - if (tok2.hasMoreTokens()) - { - String paramName = tok2.nextToken(); - String paramVal = null; - if (tok2.hasMoreTokens()) paramVal = tok2.nextToken(); - parameters.put(paramName, paramVal); - } - } - - return value.substring(0, i).trim(); - } - - /* ------------------------------------------------------------ */ - private static final Float __zero = Float.valueOf("0.0"); - - /* ------------------------------------------------------------ */ - public static float getQuality(String value) - { - if (value == null) return 0f; - - if( value.indexOf(";") == -1 ) - return 1f; - - Map params = new HashMap(); - valueParameters(value, params); - String qs = (String) params.get("q"); - try { - return Float.parseFloat(qs); - } catch (NumberFormatException e) { - return 1f; - } - } - - /* ------------------------------------------------------------ */ - /** - * List values in quality order. - * - * @param e Enumeration of values with quality parameters - * @return values in quality order. - */ - public static List qualityList(Enumeration e) - { - if (e == null || !e.hasMoreElements()) return Collections.EMPTY_LIST; - - Object list = null; - Object qual = null; - - // Assume list will be well ordered and just add nonzero - while (e.hasMoreElements()) - { - String v = e.nextElement().toString(); - Float q = getQuality(v); - - if (q.floatValue() >= 0.001) - { - list = LazyList.add(list, v); - qual = LazyList.add(qual, q); - } - } - - List vl = LazyList.getList(list, false); - if (vl.size() < 2) return vl; - - List ql = LazyList.getList(qual, false); - - // sort list with swaps - Float last = __zero; - for (int i = vl.size(); i-- > 0;) - { - Float q = (Float) ql.get(i); - if (last.compareTo(q) > 0) - { - Object tmp = vl.get(i); - vl.set(i, vl.get(i + 1)); - vl.set(i + 1, tmp); - ql.set(i, ql.get(i + 1)); - ql.set(i + 1, q); - last = __zero; - i = vl.size(); - continue; - } - last = q; - } - ql.clear(); - return vl; - } - - - public static final class Field - { - private final String _name; - private final String _value; - private Field _next; - - private Field(String name, String value) - { - _name = name; - _value = value; - _next = null; - } - - public void putTo(ByteBuffer buffer) throws IOException - { - byte[] nameBytes = StringUtil.getBytes(_name); - if (getNameOrdinal() >=0 ) - buffer.put(nameBytes); - else - { - for( byte b : nameBytes ) { - switch(b) - { - case '\r': - case '\n': - case ':' : - continue; - default: - buffer.put(b); - } - } - } - - buffer.put((byte) ':'); - buffer.put((byte) ' '); - - byte[] valueBytes = StringUtil.getBytes(_value); - if (getValueOrdinal() >= 0) - buffer.put(valueBytes); - else - { - for( byte b : valueBytes ) { - switch(b) - { - case '\r': - case '\n': - continue; - default: - buffer.put(b); - } - } - } - - buffer.put((byte)'\r'); - buffer.put((byte)'\n'); - } - - private String getName() - { - return _name.toString(); - } - - public int getNameOrdinal() - { - return HttpHeaders.CACHE.getOrdinal(_name); - } - - public String getValue() - { - return _value; - } - - public int getValueOrdinal() - { - return HttpHeaderValues.CACHE.getOrdinal(_value); - } - - public int getIntValue() - { - return (int) getLongValue(); - } - - public long getLongValue() - { - return BufferUtil.toLong(_value); - } - - @Override - public String toString() - { - return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); - } - } -}
--- a/src/org/eclipse/jetty/http/HttpGenerator.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1151 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.nio.ByteBuffer; -import java.util.Arrays; - -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.server.Server; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * HttpGenerator. Builds HTTP Messages. - * - * - * - */ -public final class HttpGenerator -{ - private static final Logger LOG = LoggerFactory.getLogger(HttpGenerator.class); - - // Build cache of response lines for status - private static class Status - { - byte[] _schemeCode; - byte[] _responseLine; - } - private static final Status[] __status = new Status[HttpStatus.MAX_CODE+1]; - static - { - final int versionLength=HttpVersions.HTTP_1_1_BYTES.length; - - for (int i=0;i<__status.length;i++) - { - HttpStatus.Code code = HttpStatus.getCode(i); - if (code==null) - continue; - String reason=code.getMessage(); - byte[] bytes=new byte[versionLength+5+reason.length()+2]; -// HttpVersions.HTTP_1_1_BUFFER.peek(0,bytes, 0, versionLength); - System.arraycopy(HttpVersions.HTTP_1_1_BYTES,0,bytes,0,versionLength); - bytes[versionLength+0]=' '; - bytes[versionLength+1]=(byte)('0'+i/100); - bytes[versionLength+2]=(byte)('0'+(i%100)/10); - bytes[versionLength+3]=(byte)('0'+(i%10)); - bytes[versionLength+4]=' '; - for (int j=0;j<reason.length();j++) - bytes[versionLength+5+j]=(byte)reason.charAt(j); - bytes[versionLength+5+reason.length()]=HttpTokens.CARRIAGE_RETURN; - bytes[versionLength+6+reason.length()]=HttpTokens.LINE_FEED; - - __status[i] = new Status(); - __status[i]._schemeCode = Arrays.copyOf(bytes,versionLength+5); - __status[i]._responseLine = bytes; - } - } - - - // common _content - private static final byte[] LAST_CHUNK = - { (byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'}; - private static final byte[] CONTENT_LENGTH_0 = StringUtil.getBytes("Content-Length: 0\015\012"); - private static final byte[] CONNECTION_KEEP_ALIVE = StringUtil.getBytes("Connection: keep-alive\015\012"); - private static final byte[] CONNECTION_CLOSE = StringUtil.getBytes("Connection: close\015\012"); - private static final byte[] CONNECTION_ = StringUtil.getBytes("Connection: "); - private static final byte[] CRLF = StringUtil.getBytes("\015\012"); - private static final byte[] TRANSFER_ENCODING_CHUNKED = StringUtil.getBytes("Transfer-Encoding: chunked\015\012"); - private static byte[] SERVER = StringUtil.getBytes("Server: Jetty("+Server.version+")\015\012"); - - // other statics - private static final int CHUNK_SPACE = 12; - - // data - private boolean _bypass = false; // True if _content buffer can be written directly to endp and bypass the content buffer - private boolean _needCRLF = false; - private boolean _needEOC = false; - private boolean _bufferChunked = false; - - - public void shutdown() { - if (_persistent!=null && !_persistent && !_endp.isOutputShutdown()) - { - try - { - _endp.shutdownOutput(); - } - catch(IOException e) - { - LOG.trace("",e); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Add content. - * - * @param content - * @param last - * @throws IllegalStateException If the request is not expecting any more content, - * or if the buffers are full and cannot be flushed. - * @throws IOException if there is a problem flushing the buffers. - */ - public void addContent(ByteBuffer content, boolean last) throws IOException - { - if (_noContent) - throw new IllegalStateException("NO CONTENT"); - - if (_last || _state==STATE_END) - { - LOG.warn("Ignoring extra content {}",content); -// content.clear(); - return; - } - _last = last; - - // Handle any unfinished business? - if (_content!=null && _content.hasRemaining() || _bufferChunked) - { - if (_endp.isOutputShutdown()) - throw new EofException(); - flushBuffer(); - if (_content != null && _content.hasRemaining()) - { - if (_bufferChunked) - { - ByteBuffer nc = _buffers.getBuffer(_content.remaining()+CHUNK_SPACE+content.remaining()); - nc.put(_content); - nc.put(HttpTokens.CRLF); - BufferUtil.putHexInt(nc, content.remaining()); - nc.put(HttpTokens.CRLF); - nc.put(content); - nc.flip(); - content = nc; - } - else - { - ByteBuffer nc = _buffers.getBuffer(_content.remaining()+content.remaining()); - nc.put(_content); - nc.put(content); - nc.flip(); - content = nc; - } - } - } - - _content = content; - _contentWritten += content.remaining(); - - // Handle the _content - if (_head) - { -// content.clear(); - _content = null; - } - else if ((_buffer.position()==0) && _content.hasRemaining() && (_last || isCommitted() && _content.remaining()>1024)) - { - _bypass = true; - } - else if (!_bufferChunked) - { -//System.out.println("qqqqqqqqqqqqqqqqqqq c"); - // Copy _content to buffer; - _buffer.put(_content); - if (!_content.hasRemaining()) - _content = null; - } - } - - /* ------------------------------------------------------------ */ - /** Prepare buffer for unchecked writes. - * Prepare the generator buffer to receive unchecked writes - * @return the available space in the buffer. - * @throws IOException - */ - public void prepareUncheckedAddContent() throws IOException - { - if (_noContent) -// return -1; - throw new RuntimeException("_noContent"); - - if (_last || _state==STATE_END) -// return -1; - throw new RuntimeException("_last"); - - // Handle any unfinished business? - if (_content != null && _content.hasRemaining() || _bufferChunked) - { - flushBuffer(); - if (_content != null && _content.hasRemaining() || _bufferChunked) - throw new IllegalStateException("FULL"); - } - - _contentWritten -= _buffer.position(); - } - - public boolean isBufferFull() - { - // Should we flush the buffers? - return isBufferFull2() || _bufferChunked || _bypass /* || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer.remaining() < CHUNK_SPACE)*/; - } - - public void send1xx(int code) throws IOException - { - if (_state != STATE_HEADER) - return; - - if (code<100||code>199) - throw new IllegalArgumentException("!1xx"); - Status status = __status[code]; - if (status==null) - throw new IllegalArgumentException(code+"?"); - - _header.put(status._responseLine); - _header.put(HttpTokens.CRLF); - - try - { - // nasty semi busy flush! - _header.flip(); - while(_header.remaining()>0) - { - int len = _endp.flush(_header); - if (len<0) - throw new EofException(); - if (len==0) - Thread.sleep(100); - } - } - catch(InterruptedException e) - { - LOG.debug("",e); - throw new InterruptedIOException(e.toString()); - } - } - - public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException - { - if (_state != STATE_HEADER) - return; - - // handle a reset - if (_status==0) - throw new EofException(); - - if (_last && !allContentAdded) - throw new IllegalStateException("last?"); - _last = _last | allContentAdded; - - boolean has_server = false; - - try - { - // Responses - if (_version == HttpVersions.HTTP_0_9_ORDINAL) - { - _persistent = false; - _contentLength = HttpTokens.EOF_CONTENT; - _state = STATE_CONTENT; - return; - } - else - { - if (_persistent==null) - _persistent = (_version > HttpVersions.HTTP_1_0_ORDINAL); - - // add response line - Status status = _status<__status.length?__status[_status]:null; - - if (status==null) - { - _header.put(HttpVersions.HTTP_1_1_BYTES); - _header.put((byte) ' '); - _header.put((byte) ('0' + _status / 100)); - _header.put((byte) ('0' + (_status % 100) / 10)); - _header.put((byte) ('0' + (_status % 10))); - _header.put((byte) ' '); - if (_reason==null) - { - _header.put((byte) ('0' + _status / 100)); - _header.put((byte) ('0' + (_status % 100) / 10)); - _header.put((byte) ('0' + (_status % 10))); - } - else - _header.put(_reason); - _header.put(HttpTokens.CRLF); - } - else - { - if (_reason==null) - _header.put(status._responseLine); - else - { - _header.put(status._schemeCode); - _header.put(_reason); - _header.put(HttpTokens.CRLF); - } - } - - if (_status<200 && _status>=100 ) - { - _noContent = true; - _content = null; - _buffer.clear(); - // end the header. - - if (_status!=101 ) - { - _header.put(HttpTokens.CRLF); - _state = STATE_CONTENT; - return; - } - } - else if (_status==204 || _status==304) - { - _noContent = true; - _content = null; - _buffer.clear(); - } - } - - // key field values - HttpFields.Field content_length = null; - HttpFields.Field transfer_encoding = null; - boolean keep_alive = false; - boolean close=false; - boolean content_type=false; - StringBuilder connection = null; - - if (fields != null) - { - int s=fields.size(); - for (int f=0;f<s;f++) - { - HttpFields.Field field = fields.getField(f); - if (field==null) - continue; - - switch (field.getNameOrdinal()) - { - case HttpHeaders.CONTENT_LENGTH_ORDINAL: - content_length = field; - _contentLength = field.getLongValue(); - - if (_contentLength < _contentWritten || _last && _contentLength != _contentWritten) - content_length = null; - - // write the field to the header buffer - field.putTo(_header); - break; - - case HttpHeaders.CONTENT_TYPE_ORDINAL: -// if (BufferUtil.isPrefix(MimeTypes.MULTIPART_BYTERANGES_BUFFER, field.getValueBuffer())) - if (field.getValue().startsWith(MimeTypes.MULTIPART_BYTERANGES)) - _contentLength = HttpTokens.SELF_DEFINING_CONTENT; - - // write the field to the header buffer - content_type=true; - field.putTo(_header); - break; - - case HttpHeaders.TRANSFER_ENCODING_ORDINAL: - if (_version == HttpVersions.HTTP_1_1_ORDINAL) - transfer_encoding = field; - // Do NOT add yet! - break; - - case HttpHeaders.CONNECTION_ORDINAL: - int connection_value = field.getValueOrdinal(); - switch (connection_value) - { - case -1: - { - String[] values = field.getValue().split(","); - for (int i=0;values!=null && i<values.length;i++) - { - int ord = HttpHeaderValues.CACHE.getOrdinal(values[i].trim()); - - if (ord != -1) - { - switch(ord) - { - case HttpHeaderValues.CLOSE_ORDINAL: - close=true; - _persistent = false; - keep_alive=false; - if (!_persistent && _contentLength == HttpTokens.UNKNOWN_CONTENT) - _contentLength = HttpTokens.EOF_CONTENT; - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - if (_version == HttpVersions.HTTP_1_0_ORDINAL) - { - keep_alive = true; - _persistent = true; - } - break; - - default: - if (connection==null) - connection=new StringBuilder(); - else - connection.append(','); - connection.append(values[i]); - } - } - else - { - if (connection==null) - connection=new StringBuilder(); - else - connection.append(','); - connection.append(values[i]); - } - } - - break; - } - case HttpHeaderValues.UPGRADE_ORDINAL: - { - // special case for websocket connection ordering - field.putTo(_header); - continue; - } - case HttpHeaderValues.CLOSE_ORDINAL: - { - close=true; - _persistent=false; - if (!_persistent && _contentLength == HttpTokens.UNKNOWN_CONTENT) - _contentLength = HttpTokens.EOF_CONTENT; - break; - } - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - { - if (_version == HttpVersions.HTTP_1_0_ORDINAL) - { - keep_alive = true; - _persistent=true; - } - break; - } - default: - { - if (connection==null) - connection=new StringBuilder(); - else - connection.append(','); - connection.append(field.getValue()); - } - } - - // Do NOT add yet! - break; - - case HttpHeaders.SERVER_ORDINAL: - has_server=true; - field.putTo(_header); - break; - - default: - // write the field to the header buffer - field.putTo(_header); - } - } - } - - // Calculate how to end _content and connection, _content length and transfer encoding - // settings. - // From RFC 2616 4.4: - // 1. No body for 1xx, 204, 304 & HEAD response - // 2. Force _content-length? - // 3. If Transfer-Encoding!=identity && HTTP/1.1 && !HttpConnection==close then chunk - // 4. Content-Length - // 5. multipart/byteranges - // 6. close - switch ((int) _contentLength) - { - case HttpTokens.UNKNOWN_CONTENT: - // It may be that we have no _content, or perhaps _content just has not been - // written yet? - - // Response known not to have a body - if (_contentWritten == 0 && (_status < 200 || _status == 204 || _status == 304)) - _contentLength = HttpTokens.NO_CONTENT; - else if (_last) - { - // we have seen all the _content there is - _contentLength = _contentWritten; - if (content_length == null && !_noContent) - { - // known length but not actually set. - _header.put(HttpHeaders.CONTENT_LENGTH_BYTES); - _header.put(HttpTokens.COLON); - _header.put((byte) ' '); - BufferUtil.putDecLong(_header, _contentLength); - _header.put(HttpTokens.CRLF); - } - } - else - { - // No idea, so we must assume that a body is coming - _contentLength = (!_persistent || _version < HttpVersions.HTTP_1_1_ORDINAL ) ? HttpTokens.EOF_CONTENT : HttpTokens.CHUNKED_CONTENT; - } - break; - - case HttpTokens.NO_CONTENT: - if (content_length == null && _status >= 200 && _status != 204 && _status != 304) - _header.put(CONTENT_LENGTH_0); - break; - - case HttpTokens.EOF_CONTENT: - _persistent = false; - break; - - case HttpTokens.CHUNKED_CONTENT: - break; - - default: - // TODO - maybe allow forced chunking by setting te ??? - break; - } - - // Add transfer_encoding if needed - if (_contentLength == HttpTokens.CHUNKED_CONTENT) - { - // try to use user supplied encoding as it may have other values. - if (transfer_encoding != null && HttpHeaderValues.CHUNKED_ORDINAL != transfer_encoding.getValueOrdinal()) - { - String c = transfer_encoding.getValue(); - if (c.endsWith(HttpHeaderValues.CHUNKED)) - transfer_encoding.putTo(_header); - else - throw new IllegalArgumentException("BAD TE"); - } - else - _header.put(TRANSFER_ENCODING_CHUNKED); - } - - // Handle connection if need be - if (_contentLength==HttpTokens.EOF_CONTENT) - { - keep_alive=false; - _persistent=false; - } - - if (!_persistent && (close || _version > HttpVersions.HTTP_1_0_ORDINAL)) - { - _header.put(CONNECTION_CLOSE); - if (connection!=null) - { - _header.position(_header.position()-2); - _header.put((byte)','); - _header.put(connection.toString().getBytes()); - _header.put(CRLF); - } - } - else if (keep_alive) - { - _header.put(CONNECTION_KEEP_ALIVE); - if (connection!=null) - { - _header.position(_header.position()-2); - _header.put((byte)','); - _header.put(connection.toString().getBytes()); - _header.put(CRLF); - } - } - else if (connection!=null) - { - _header.put(CONNECTION_); - _header.put(connection.toString().getBytes()); - _header.put(CRLF); - } - - if (!has_server && _status>199) - _header.put(SERVER); - - // end the header. - _header.put(HttpTokens.CRLF); - _state = STATE_CONTENT; - - } - catch(ArrayIndexOutOfBoundsException e) - { - throw new RuntimeException("Header>"+_header.remaining(),e); - } - } - - /* ------------------------------------------------------------ */ - /** - * Complete the message. - * - * @throws IOException - */ - public void complete() throws IOException - { - if (_state == STATE_END) - return; - - complete2(); - - if (_state < STATE_FLUSHING) - { - _state = STATE_FLUSHING; - if (_contentLength == HttpTokens.CHUNKED_CONTENT) - _needEOC = true; - } - - flushBuffer(); - } - - public int flushBuffer() throws IOException - { - try - { - - if (_state == STATE_HEADER) - throw new IllegalStateException("State==HEADER"); - - prepareBuffers(); - - int total= 0; - - int len = -1; - int to_flush = flushMask(); - int last_flush; - - do - { - last_flush = to_flush; - switch (to_flush) - { -//qqq - case 7: - throw new IllegalStateException(); // should never happen! - case 6: - _header.flip(); - _buffer.flip(); - len = _endp.flush(_header, _buffer, null); - _header.compact(); - _buffer.compact(); - break; - case 5: - _header.flip(); - len = _endp.flush(_header, _content, null); - _header.compact(); - break; - case 4: - _header.flip(); - len = _endp.flush(_header); - _header.compact(); - break; - case 3: - _buffer.flip(); - len = _endp.flush(_buffer, _content, null); - _buffer.compact(); - break; - case 2: - _buffer.flip(); - len = _endp.flush(_buffer); - _buffer.compact(); - break; - case 1: - len = _endp.flush(_content); - break; - case 0: - { - len = 0; - // Nothing more we can write now. - _header.clear(); - - _bypass = false; - _bufferChunked = false; - - _buffer.clear(); // ? - if (_contentLength == HttpTokens.CHUNKED_CONTENT) - { - // Special case handling for small left over buffer from - // an addContent that caused a buffer flush. - if (_content != null && _content.remaining() < _buffer.remaining() && _state != STATE_FLUSHING) - { - _buffer.put(_content); - _content = null; - } - } - - // Are we completely finished for now? - if (!_needCRLF && !_needEOC && (_content==null || !_content.hasRemaining())) - { - if (_state == STATE_FLUSHING) - _state = STATE_END; - - if (_state==STATE_END && _persistent != null && !_persistent && _status!=100) - _endp.shutdownOutput(); - } - else - // Try to prepare more to write. - prepareBuffers(); - } - - } - - if (len > 0) - total+=len; - - to_flush = flushMask(); - } - // loop while progress is being made (OR we have prepared some buffers that might make progress) - while (len>0 || (to_flush!=0 && last_flush==0)); - - return total; - } - catch (IOException e) - { - LOG.trace("",e); - throw (e instanceof EofException) ? e : new EofException(e); - } - } - - private int flushMask() - { - return ((_header.position() > 0)?4:0) - | ((_buffer.position() > 0)?2:0) - | ((_bypass && _content != null && _content.hasRemaining())?1:0); - } - - private void prepareBuffers() - { - // if we are not flushing an existing chunk - if (!_bufferChunked) - { - // Refill buffer if possible - if (!_bypass && _content != null && _content.hasRemaining() && _buffer.hasRemaining()) - { - _buffer.put(_content); - if (!_content.hasRemaining()) - _content = null; - } - - // Chunk buffer if need be - if (_contentLength == HttpTokens.CHUNKED_CONTENT) - { - if (_bypass && _buffer.position()==0 && _content!=null) - { - // this is a bypass write - int size = _content.remaining(); - _bufferChunked = true; - - // if we need CRLF add this to header - if (_needCRLF) - { - if (_header.position() > 0) throw new IllegalStateException("EOC"); - _header.put(HttpTokens.CRLF); - _needCRLF = false; - } - // Add the chunk size to the header - BufferUtil.putHexInt(_header, size); - _header.put(HttpTokens.CRLF); - - // Need a CRLF after the content - _needCRLF = true; - } - else - { - int size = _buffer.position(); - if (size > 0) - { - // Prepare a chunk! - _bufferChunked = true; - - if (_needCRLF) - { - if (_header.position() > 0) throw new IllegalStateException("EOC"); - _header.put(HttpTokens.CRLF); - _needCRLF = false; - } - BufferUtil.putHexInt(_header, size); - _header.put(HttpTokens.CRLF); - - // Add end chunk trailer. - if (_buffer.remaining() >= 2) - _buffer.put(HttpTokens.CRLF); - else - _needCRLF = true; - } - } - - // If we need EOC and everything written - if (_needEOC && (_content == null || !_content.hasRemaining())) - { - if (_needCRLF && _buffer.remaining() >= HttpTokens.CRLF.length) { - _buffer.put(HttpTokens.CRLF); - _needCRLF = false; - } - - if (!_needCRLF && _needEOC && _buffer.remaining() >= LAST_CHUNK.length) { - if (!_head) - { - _buffer.put(LAST_CHUNK); - _bufferChunked = true; - } - _needEOC = false; - } - } - } - } - - if (_content != null && !_content.hasRemaining()) - _content = null; - - } - - @Override - public String toString() - { - ByteBuffer header = _header; - ByteBuffer buffer = _buffer; - ByteBuffer content = _content; - return String.format("%s{s=%d,h=%d,b=%d,c=%d}", - getClass().getSimpleName(), - _state, - header == null ? -1 : header.position(), - buffer == null ? -1 : buffer.position(), - content == null ? -1 : content.remaining()); - } - - - - - - - - - - - - - // AbstractGenerator - - public static final boolean LAST=true; - public static final boolean MORE=false; - - // states - private final static int STATE_HEADER = 0; - private final static int STATE_CONTENT = 2; - private final static int STATE_FLUSHING = 3; - private final static int STATE_END = 4; - - // data - - private final Buffers _buffers; // source of buffers - private final EndPoint _endp; - - private int _state = STATE_HEADER; - - private int _status = 0; - private int _version = HttpVersions.HTTP_1_1_ORDINAL; - private ByteBuffer _reason; - - private long _contentWritten = 0; - private long _contentLength = HttpTokens.UNKNOWN_CONTENT; - private boolean _last = false; - private boolean _head = false; - private boolean _noContent = false; - private Boolean _persistent = null; - - private final ByteBuffer _header; // ByteBuffer for HTTP header (and maybe small _content) - private final ByteBuffer _buffer; // ByteBuffer for copy of passed _content - private ByteBuffer _content; // ByteBuffer passed to addContent - - - public HttpGenerator(Buffers buffers, EndPoint io) - { - this._buffers = buffers; - this._endp = io; - _header = _buffers.getHeader(); - _buffer = _buffers.getBuffer(); - } - - public final boolean isOpen() - { - return _endp.isOpen(); - } - - public final void resetBuffer() - { - if(_state>=STATE_FLUSHING) - throw new IllegalStateException("Flushed"); - - _last = false; - _persistent = null; - _contentWritten = 0; - _contentLength = HttpTokens.UNKNOWN_CONTENT; - _content = null; - _buffer.clear(); - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the contentBufferSize. - */ - public final int getContentBufferSize() - { - return _buffer.capacity(); - } - - public final ByteBuffer getUncheckedBuffer() - { - return _buffer; - } - - public final boolean isComplete() - { - return _state == STATE_END; - } - - public final boolean isIdle() - { - return _state == STATE_HEADER && _status==0; - } - - public final boolean isCommitted() - { - return _state != STATE_HEADER; - } - - public final void setContentLength(long value) - { - if (value<0) - _contentLength = HttpTokens.UNKNOWN_CONTENT; - else - _contentLength = value; - } - - public final void setHead(boolean head) - { - _head = head; - } - - /* ------------------------------------------------------------ */ - /** - * @return <code>false</code> if the connection should be closed after a request has been read, - * <code>true</code> if it should be used for additional requests. - */ - public final boolean isPersistent() - { - return _persistent!=null ? _persistent.booleanValue() : _version>HttpVersions.HTTP_1_0_ORDINAL; - } - - public final void setPersistent(boolean persistent) - { - _persistent = persistent; - } - - /* ------------------------------------------------------------ */ - /** - * @param version The version of the client the response is being sent to (NB. Not the version - * in the response, which is the version of the server). - */ - public final void setVersion(int version) - { - if (_state != STATE_HEADER) - throw new IllegalStateException("STATE!=START "+_state); - _version = version; - } - - /* ------------------------------------------------------------ */ - /** - * @param status The status code to send. - * @param reason the status message to send. - */ - public final void setResponse(int status, String reason) - { - if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START"); - _status = status; - if (reason!=null) - { - int len = reason.length(); - - // TODO don't hard code - if (len>1024) - len=1024; - _reason = ByteBuffer.allocate(len); - for (int i=0;i<len;i++) - { - char ch = reason.charAt(i); - if (ch!='\r'&&ch!='\n') - _reason.put((byte)ch); - else - _reason.put((byte)' '); - } - _reason.flip(); - } - } - - public final void completeUncheckedAddContent() - { - _contentWritten += _buffer.position(); - if (_head) - _buffer.clear(); - } - - private boolean isBufferFull2() - { - return !_buffer.hasRemaining() || _content!=null && _content.remaining()>0; - } - - public final boolean isWritten() - { - return _contentWritten>0; - } - - public final boolean isAllContentWritten() - { - return _contentLength>=0 && _contentWritten>=_contentLength; - } - - - private void complete2() throws IOException - { - if (_state == STATE_HEADER) - { - throw new IllegalStateException("State==HEADER"); - } - - if (_contentLength >= 0 && _contentLength != _contentWritten && !_head) - { - if (LOG.isDebugEnabled()) - LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength); - _persistent = false; - } - } - - - public final void flush(long maxIdleTime) throws IOException - { - // block until everything is flushed - long now = System.currentTimeMillis(); - long end = now+maxIdleTime; - ByteBuffer content = _content; - ByteBuffer buffer = _buffer; - if (content!=null && content.remaining()>0 || buffer.position()>0 || isBufferFull()) - { - flushBuffer(); - - while (now<end && (content!=null && content.remaining()>0 || buffer.position()>0) && _endp.isOpen()&& !_endp.isOutputShutdown()) - { - blockForOutput(end-now); - now = System.currentTimeMillis(); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Utility method to send an error response. If the builder is not committed, this call is - * equivalent to a setResponse, addContent and complete call. - * - * @param code The error code - * @param reason The error reason - * @param content Contents of the error page - * @param close True if the connection should be closed - * @throws IOException if there is a problem flushing the response - */ - public final void sendError(int code, String reason, String content, boolean close) throws IOException - { - if (close) - _persistent=false; - if (isCommitted()) - { - LOG.debug("sendError on committed: {} {}",code,reason); - } - else - { - LOG.debug("sendError: {} {}",code,reason); - setResponse(code, reason); - if (content != null) - { - completeHeader(null, false); - addContent(BufferUtil.wrap(content), LAST); - } - else if (code>=400) - { - completeHeader(null, false); - addContent(BufferUtil.wrap("Error: "+(reason==null?(""+code):reason)), LAST); - } - else - { - completeHeader(null, true); - } - complete(); - } - } - - public final long getContentWritten() - { - return _contentWritten; - } - - - public final void blockForOutput(long maxIdleTime) throws IOException - { - if (_endp.isBlocking()) - { - try - { - flushBuffer(); - } - catch(IOException e) - { - _endp.close(); - throw e; - } - } - else - { - if (!_endp.blockWritable(maxIdleTime)) - { - _endp.close(); - throw new EofException("timeout"); - } - - flushBuffer(); - } - } - -}
--- a/src/org/eclipse/jetty/http/HttpHeaderValues.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.StringCache; - -/** - * Cached HTTP Header values. - * The resource "/org/eclipse/jetty/useragents" is checked for a list of common user agents, so that repeated - * creation of strings for these agents can be avoided. - * - * - */ -public final class HttpHeaderValues -{ - public final static String - CLOSE="close", - CHUNKED="chunked", - GZIP="gzip", - IDENTITY="identity", - KEEP_ALIVE="keep-alive", - CONTINUE="100-continue", - PROCESSING="102-processing", - TE="TE", - BYTES="bytes", - NO_CACHE="no-cache", - UPGRADE="Upgrade"; - - public final static int - CLOSE_ORDINAL=1, - CHUNKED_ORDINAL=2, - GZIP_ORDINAL=3, - IDENTITY_ORDINAL=4, - KEEP_ALIVE_ORDINAL=5, - CONTINUE_ORDINAL=6, - PROCESSING_ORDINAL=7, - TE_ORDINAL=8, - BYTES_ORDINAL=9, - NO_CACHE_ORDINAL=10, - UPGRADE_ORDINAL=11; - - public final static StringCache CACHE = new StringCache(); - - public final static byte[] - CLOSE_BYTES=CACHE.add(CLOSE,CLOSE_ORDINAL), - CHUNKED_BYTES=CACHE.add(CHUNKED,CHUNKED_ORDINAL), - GZIP_BYTES=CACHE.add(GZIP,GZIP_ORDINAL), - IDENTITY_BYTES=CACHE.add(IDENTITY,IDENTITY_ORDINAL), - KEEP_ALIVE_BYTES=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL), - CONTINUE_BYTES=CACHE.add(CONTINUE, CONTINUE_ORDINAL), - PROCESSING_BYTES=CACHE.add(PROCESSING, PROCESSING_ORDINAL), - TE_BYTES=CACHE.add(TE,TE_ORDINAL), - BYTES_BYTES=CACHE.add(BYTES,BYTES_ORDINAL), - NO_CACHE_BYTES=CACHE.add(NO_CACHE,NO_CACHE_ORDINAL), - UPGRADE_BYTES=CACHE.add(UPGRADE,UPGRADE_ORDINAL); - -}
--- a/src/org/eclipse/jetty/http/HttpHeaders.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.StringCache; - - -public final class HttpHeaders -{ - /* ------------------------------------------------------------ */ - /** General Fields. - */ - public final static String - CONNECTION= "Connection", - CACHE_CONTROL= "Cache-Control", - DATE= "Date", - PRAGMA= "Pragma", - PROXY_CONNECTION = "Proxy-Connection", - TRAILER= "Trailer", - TRANSFER_ENCODING= "Transfer-Encoding", - UPGRADE= "Upgrade", - VIA= "Via", - WARNING= "Warning", - NEGOTIATE= "Negotiate"; - - /* ------------------------------------------------------------ */ - /** Entity Fields. - */ - public final static String ALLOW= "Allow", - CONTENT_ENCODING= "Content-Encoding", - CONTENT_LANGUAGE= "Content-Language", - CONTENT_LENGTH= "Content-Length", - CONTENT_LOCATION= "Content-Location", - CONTENT_MD5= "Content-MD5", - CONTENT_RANGE= "Content-Range", - CONTENT_TYPE= "Content-Type", - EXPIRES= "Expires", - LAST_MODIFIED= "Last-Modified"; - - /* ------------------------------------------------------------ */ - /** Request Fields. - */ - public final static String ACCEPT= "Accept", - ACCEPT_CHARSET= "Accept-Charset", - ACCEPT_ENCODING= "Accept-Encoding", - ACCEPT_LANGUAGE= "Accept-Language", - AUTHORIZATION= "Authorization", - EXPECT= "Expect", - FORWARDED= "Forwarded", - FROM= "From", - HOST= "Host", - IF_MATCH= "If-Match", - IF_MODIFIED_SINCE= "If-Modified-Since", - IF_NONE_MATCH= "If-None-Match", - IF_RANGE= "If-Range", - IF_UNMODIFIED_SINCE= "If-Unmodified-Since", - KEEP_ALIVE= "Keep-Alive", - MAX_FORWARDS= "Max-Forwards", - PROXY_AUTHORIZATION= "Proxy-Authorization", - RANGE= "Range", - REQUEST_RANGE= "Request-Range", - REFERER= "Referer", - TE= "TE", - USER_AGENT= "User-Agent", - X_FORWARDED_FOR= "X-Forwarded-For", - X_FORWARDED_PROTO= "X-Forwarded-Proto", - X_FORWARDED_SERVER= "X-Forwarded-Server", - X_FORWARDED_HOST= "X-Forwarded-Host"; - - /* ------------------------------------------------------------ */ - /** Response Fields. - */ - public final static String ACCEPT_RANGES= "Accept-Ranges", - AGE= "Age", - ETAG= "ETag", - LOCATION= "Location", - PROXY_AUTHENTICATE= "Proxy-Authenticate", - RETRY_AFTER= "Retry-After", - SERVER= "Server", - SERVLET_ENGINE= "Servlet-Engine", - VARY= "Vary", - WWW_AUTHENTICATE= "WWW-Authenticate"; - - /* ------------------------------------------------------------ */ - /** Other Fields. - */ - public final static String COOKIE= "Cookie", - SET_COOKIE= "Set-Cookie", - SET_COOKIE2= "Set-Cookie2", - MIME_VERSION= "MIME-Version", - IDENTITY= "identity"; - - public final static int CONNECTION_ORDINAL= 1, - DATE_ORDINAL= 2, - PRAGMA_ORDINAL= 3, - TRAILER_ORDINAL= 4, - TRANSFER_ENCODING_ORDINAL= 5, - UPGRADE_ORDINAL= 6, - VIA_ORDINAL= 7, - WARNING_ORDINAL= 8, - ALLOW_ORDINAL= 9, - CONTENT_ENCODING_ORDINAL= 10, - CONTENT_LANGUAGE_ORDINAL= 11, - CONTENT_LENGTH_ORDINAL= 12, - CONTENT_LOCATION_ORDINAL= 13, - CONTENT_MD5_ORDINAL= 14, - CONTENT_RANGE_ORDINAL= 15, - CONTENT_TYPE_ORDINAL= 16, - EXPIRES_ORDINAL= 17, - LAST_MODIFIED_ORDINAL= 18, - ACCEPT_ORDINAL= 19, - ACCEPT_CHARSET_ORDINAL= 20, - ACCEPT_ENCODING_ORDINAL= 21, - ACCEPT_LANGUAGE_ORDINAL= 22, - AUTHORIZATION_ORDINAL= 23, - EXPECT_ORDINAL= 24, - FORWARDED_ORDINAL= 25, - FROM_ORDINAL= 26, - HOST_ORDINAL= 27, - IF_MATCH_ORDINAL= 28, - IF_MODIFIED_SINCE_ORDINAL= 29, - IF_NONE_MATCH_ORDINAL= 30, - IF_RANGE_ORDINAL= 31, - IF_UNMODIFIED_SINCE_ORDINAL= 32, - KEEP_ALIVE_ORDINAL= 33, - MAX_FORWARDS_ORDINAL= 34, - PROXY_AUTHORIZATION_ORDINAL= 35, - RANGE_ORDINAL= 36, - REQUEST_RANGE_ORDINAL= 37, - REFERER_ORDINAL= 38, - TE_ORDINAL= 39, - USER_AGENT_ORDINAL= 40, - X_FORWARDED_FOR_ORDINAL= 41, - ACCEPT_RANGES_ORDINAL= 42, - AGE_ORDINAL= 43, - ETAG_ORDINAL= 44, - LOCATION_ORDINAL= 45, - PROXY_AUTHENTICATE_ORDINAL= 46, - RETRY_AFTER_ORDINAL= 47, - SERVER_ORDINAL= 48, - SERVLET_ENGINE_ORDINAL= 49, - VARY_ORDINAL= 50, - WWW_AUTHENTICATE_ORDINAL= 51, - COOKIE_ORDINAL= 52, - SET_COOKIE_ORDINAL= 53, - SET_COOKIE2_ORDINAL= 54, - MIME_VERSION_ORDINAL= 55, - IDENTITY_ORDINAL= 56, - CACHE_CONTROL_ORDINAL=57, - PROXY_CONNECTION_ORDINAL=58, - X_FORWARDED_PROTO_ORDINAL=59, - X_FORWARDED_SERVER_ORDINAL=60, - X_FORWARDED_HOST_ORDINAL=61; - - public final static StringCache CACHE= new StringCache(); - - public final static byte[] - HOST_BYTES=CACHE.add(HOST,HOST_ORDINAL), - ACCEPT_BYTES=CACHE.add(ACCEPT,ACCEPT_ORDINAL), - ACCEPT_CHARSET_BYTES=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL), - ACCEPT_ENCODING_BYTES=CACHE.add(ACCEPT_ENCODING,ACCEPT_ENCODING_ORDINAL), - ACCEPT_LANGUAGE_BYTES=CACHE.add(ACCEPT_LANGUAGE,ACCEPT_LANGUAGE_ORDINAL), - - CONTENT_LENGTH_BYTES=CACHE.add(CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL), - CONNECTION_BYTES=CACHE.add(CONNECTION,CONNECTION_ORDINAL), - CACHE_CONTROL_BYTES=CACHE.add(CACHE_CONTROL,CACHE_CONTROL_ORDINAL), - DATE_BYTES=CACHE.add(DATE,DATE_ORDINAL), - PRAGMA_BYTES=CACHE.add(PRAGMA,PRAGMA_ORDINAL), - TRAILER_BYTES=CACHE.add(TRAILER,TRAILER_ORDINAL), - TRANSFER_ENCODING_BYTES=CACHE.add(TRANSFER_ENCODING,TRANSFER_ENCODING_ORDINAL), - UPGRADE_BYTES=CACHE.add(UPGRADE,UPGRADE_ORDINAL), - VIA_BYTES=CACHE.add(VIA,VIA_ORDINAL), - WARNING_BYTES=CACHE.add(WARNING,WARNING_ORDINAL), - ALLOW_BYTES=CACHE.add(ALLOW,ALLOW_ORDINAL), - CONTENT_ENCODING_BYTES=CACHE.add(CONTENT_ENCODING,CONTENT_ENCODING_ORDINAL), - CONTENT_LANGUAGE_BYTES=CACHE.add(CONTENT_LANGUAGE,CONTENT_LANGUAGE_ORDINAL), - CONTENT_LOCATION_BYTES=CACHE.add(CONTENT_LOCATION,CONTENT_LOCATION_ORDINAL), - CONTENT_MD5_BYTES=CACHE.add(CONTENT_MD5,CONTENT_MD5_ORDINAL), - CONTENT_RANGE_BYTES=CACHE.add(CONTENT_RANGE,CONTENT_RANGE_ORDINAL), - CONTENT_TYPE_BYTES=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL), - EXPIRES_BYTES=CACHE.add(EXPIRES,EXPIRES_ORDINAL), - LAST_MODIFIED_BYTES=CACHE.add(LAST_MODIFIED,LAST_MODIFIED_ORDINAL), - AUTHORIZATION_BYTES=CACHE.add(AUTHORIZATION,AUTHORIZATION_ORDINAL), - EXPECT_BYTES=CACHE.add(EXPECT,EXPECT_ORDINAL), - FORWARDED_BYTES=CACHE.add(FORWARDED,FORWARDED_ORDINAL), - FROM_BYTES=CACHE.add(FROM,FROM_ORDINAL), - IF_MATCH_BYTES=CACHE.add(IF_MATCH,IF_MATCH_ORDINAL), - IF_MODIFIED_SINCE_BYTES=CACHE.add(IF_MODIFIED_SINCE,IF_MODIFIED_SINCE_ORDINAL), - IF_NONE_MATCH_BYTES=CACHE.add(IF_NONE_MATCH,IF_NONE_MATCH_ORDINAL), - IF_RANGE_BYTES=CACHE.add(IF_RANGE,IF_RANGE_ORDINAL), - IF_UNMODIFIED_SINCE_BYTES=CACHE.add(IF_UNMODIFIED_SINCE,IF_UNMODIFIED_SINCE_ORDINAL), - KEEP_ALIVE_BYTES=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL), - MAX_FORWARDS_BYTES=CACHE.add(MAX_FORWARDS,MAX_FORWARDS_ORDINAL), - PROXY_AUTHORIZATION_BYTES=CACHE.add(PROXY_AUTHORIZATION,PROXY_AUTHORIZATION_ORDINAL), - RANGE_BYTES=CACHE.add(RANGE,RANGE_ORDINAL), - REQUEST_RANGE_BYTES=CACHE.add(REQUEST_RANGE,REQUEST_RANGE_ORDINAL), - REFERER_BYTES=CACHE.add(REFERER,REFERER_ORDINAL), - TE_BYTES=CACHE.add(TE,TE_ORDINAL), - USER_AGENT_BYTES=CACHE.add(USER_AGENT,USER_AGENT_ORDINAL), - X_FORWARDED_FOR_BYTES=CACHE.add(X_FORWARDED_FOR,X_FORWARDED_FOR_ORDINAL), - X_FORWARDED_PROTO_BYTES=CACHE.add(X_FORWARDED_PROTO,X_FORWARDED_PROTO_ORDINAL), - X_FORWARDED_SERVER_BYTES=CACHE.add(X_FORWARDED_SERVER,X_FORWARDED_SERVER_ORDINAL), - X_FORWARDED_HOST_BYTES=CACHE.add(X_FORWARDED_HOST,X_FORWARDED_HOST_ORDINAL), - ACCEPT_RANGES_BYTES=CACHE.add(ACCEPT_RANGES,ACCEPT_RANGES_ORDINAL), - AGE_BYTES=CACHE.add(AGE,AGE_ORDINAL), - ETAG_BYTES=CACHE.add(ETAG,ETAG_ORDINAL), - LOCATION_BYTES=CACHE.add(LOCATION,LOCATION_ORDINAL), - PROXY_AUTHENTICATE_BYTES=CACHE.add(PROXY_AUTHENTICATE,PROXY_AUTHENTICATE_ORDINAL), - RETRY_AFTER_BYTES=CACHE.add(RETRY_AFTER,RETRY_AFTER_ORDINAL), - SERVER_BYTES=CACHE.add(SERVER,SERVER_ORDINAL), - SERVLET_ENGINE_BYTES=CACHE.add(SERVLET_ENGINE,SERVLET_ENGINE_ORDINAL), - VARY_BYTES=CACHE.add(VARY,VARY_ORDINAL), - WWW_AUTHENTICATE_BYTES=CACHE.add(WWW_AUTHENTICATE,WWW_AUTHENTICATE_ORDINAL), - COOKIE_BYTES=CACHE.add(COOKIE,COOKIE_ORDINAL), - SET_COOKIE_BYTES=CACHE.add(SET_COOKIE,SET_COOKIE_ORDINAL), - SET_COOKIE2_BYTES=CACHE.add(SET_COOKIE2,SET_COOKIE2_ORDINAL), - MIME_VERSION_BYTES=CACHE.add(MIME_VERSION,MIME_VERSION_ORDINAL), - IDENTITY_BYTES=CACHE.add(IDENTITY,IDENTITY_ORDINAL), - PROXY_CONNECTION_BYTES=CACHE.add(PROXY_CONNECTION,PROXY_CONNECTION_ORDINAL); - -}
--- a/src/org/eclipse/jetty/http/HttpMethods.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.StringCache; - - -public final class HttpMethods -{ - public final static String GET= "GET", - POST= "POST", - HEAD= "HEAD", - PUT= "PUT", - OPTIONS= "OPTIONS", - DELETE= "DELETE", - TRACE= "TRACE", - CONNECT= "CONNECT", - MOVE= "MOVE"; - - public final static int GET_ORDINAL= 1, - POST_ORDINAL= 2, - HEAD_ORDINAL= 3, - PUT_ORDINAL= 4, - OPTIONS_ORDINAL= 5, - DELETE_ORDINAL= 6, - TRACE_ORDINAL= 7, - CONNECT_ORDINAL= 8, - MOVE_ORDINAL= 9; - - public final static StringCache CACHE = new StringCache(); - - public final static byte[] - GET_BYTES= CACHE.add(GET, GET_ORDINAL), - POST_BYTES= CACHE.add(POST, POST_ORDINAL), - HEAD_BYTES= CACHE.add(HEAD, HEAD_ORDINAL), - PUT_BYTES= CACHE.add(PUT, PUT_ORDINAL), - OPTIONS_BYTES= CACHE.add(OPTIONS, OPTIONS_ORDINAL), - DELETE_BYTES= CACHE.add(DELETE, DELETE_ORDINAL), - TRACE_BYTES= CACHE.add(TRACE, TRACE_ORDINAL), - CONNECT_BYTES= CACHE.add(CONNECT, CONNECT_ORDINAL), - MOVE_BYTES= CACHE.add(MOVE, MOVE_ORDINAL); - -}
--- a/src/org/eclipse/jetty/http/HttpParser.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1114 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; -import java.nio.ByteBuffer; - -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class HttpParser -{ - private static final Logger LOG = LoggerFactory.getLogger(HttpParser.class); - - // States - private static final int STATE_START = -14; - private static final int STATE_FIELD0 = -13; - private static final int STATE_SPACE1 = -12; - private static final int STATE_STATUS = -11; - private static final int STATE_URI = -10; - private static final int STATE_SPACE2 = -9; - private static final int STATE_FIELD2 = -6; - private static final int STATE_HEADER = -5; - private static final int STATE_HEADER_NAME = -4; - private static final int STATE_HEADER_IN_NAME = -3; - private static final int STATE_HEADER_VALUE = -2; - private static final int STATE_HEADER_IN_VALUE = -1; - private static final int STATE_END = 0; - private static final int STATE_EOF_CONTENT = 1; - private static final int STATE_CONTENT = 2; - private static final int STATE_CHUNKED_CONTENT = 3; - private static final int STATE_CHUNK_SIZE = 4; - private static final int STATE_CHUNK_PARAMS = 5; - private static final int STATE_CHUNK = 6; - private static final int STATE_SEEKING_EOF = 7; - - private final EventHandler _handler; - private final EndPoint _endp; - public final ByteBuffer _header; // ByteBuffer for header data (and small _content) - private final ByteBuffer _body; // ByteBuffer for large content - private ByteBuffer _buffer; // The current buffer in use (either _header or _content) - private int _mark = -1; - private String _cached; - private String _tok0 = ""; // Saved token: header name, request method or response version - private String _tok1 = ""; // Saved token: header value, request URI or response code - private String _multiLineValue; - private int _responseStatus; // If >0 then we are parsing a response - private boolean _persistent; - - private ByteBuffer _contentView = BufferUtil.EMPTY_BUFFER; // View of the content in the buffer for {@link Input} - private int _state = STATE_START; - private byte _eol; - private int _length; - private long _contentLength; - private long _contentPosition; - private int _chunkLength; - private int _chunkPosition; - private boolean _headResponse; - - public HttpParser(ByteBuffer headerBuffer,ByteBuffer bodyBuffer, EndPoint endp, EventHandler handler) - { - _header = headerBuffer; - _header.limit(0); - _body = bodyBuffer; - _body.limit(0); - _endp = endp; - _handler = handler; - } - - private void mark() { - _mark = _buffer.position() - 1; - } - - private String sliceFromMark() { - ByteBuffer buf = _buffer.duplicate(); - buf.position(_mark); - buf.limit(_buffer.position()-1); - _mark = -1; - return BufferUtil.getString(buf); - } - - private void clear() { - _buffer.limit(0); - _mark = -1; - } - - private void compact() { - if( _mark == -1 ) { - BufferUtil.compact(_buffer); - } else if( _mark > 0 ) { - int old = _buffer.position(); - _buffer.position(_mark); - BufferUtil.compact(_buffer); - _buffer.position( old - _mark ); - _mark = 0; - } - } - - private ByteBuffer getBuffer(int length) { - ByteBuffer dup = _buffer.duplicate(); - int end = _buffer.position() + length; - dup.limit(end); - _buffer.position(end); - return dup; - } - - private byte peek() { - return _buffer.get(_buffer.position()); - } - - private String bufferToString(int index, int length) { - ByteBuffer dup = _buffer.duplicate(); - dup.limit(index+length); - dup.position(index); - return BufferUtil.getString(dup); - } - - - public long getContentLength() - { - return _contentLength; - } - - public long getContentRead() - { - return _contentPosition; - } - - /* ------------------------------------------------------------ */ - /** Set if a HEAD response is expected - * @param head - */ - public void setHeadResponse(boolean head) - { - _headResponse = head; - } - - public boolean isChunking() - { - return _contentLength==HttpTokens.CHUNKED_CONTENT; - } - - public boolean isIdle() - { - return _state==STATE_START; - } - - public boolean isComplete() - { - return _state==STATE_END; - } - - public boolean isPersistent() - { - return _persistent; - } - - public void setPersistent(boolean persistent) - { - _persistent = persistent; - if (!_persistent &&(_state==STATE_END || _state==STATE_START)) - _state = STATE_SEEKING_EOF; - } - - /* ------------------------------------------------------------------------------- */ - /** - * Parse until END state. - * This method will parse any remaining content in the current buffer as long as there is - * no unconsumed content. It does not care about the {@link #getState current state} of the parser. - * @see #parse - * @see #parseNext - */ - public boolean parseAvailable() throws IOException - { - boolean progress = parseNext() > 0; - - // continue parsing - while (!isComplete() && _buffer!=null && _buffer.remaining()>0 && !_contentView.hasRemaining()) - { - progress |= parseNext()>0; - } - return progress; - } - - - /* ------------------------------------------------------------------------------- */ - /** - * Parse until next Event. - * @return an indication of progress <0 EOF, 0 no progress, >0 progress. - */ - private int parseNext() throws IOException - { - try - { - int progress = 0; - - if (_state == STATE_END) { - return 0; - } - - if (_buffer==null) - _buffer = _header; - - - if (_state == STATE_CONTENT && _contentPosition == _contentLength) - { - _state = STATE_END; - _handler.messageComplete(_contentPosition); - return 1; - } - - int length = _buffer.remaining(); - - // Fill buffer if we can - if (length == 0) - { - int filled = -1; - IOException ex = null; - try - { - filled = fill(); - LOG.debug("filled {}/{}",filled,_buffer.remaining()); - } - catch(IOException e) - { - LOG.debug(this.toString(),e); - ex=e; - } - - if (filled > 0 ) - progress++; - else if (filled < 0 ) - { - _persistent = false; - - // do we have content to deliver? - if (_state>STATE_END) - { - if (_buffer.remaining()>0 && !_headResponse) - { - ByteBuffer chunk = getBuffer(_buffer.remaining()); - _contentPosition += chunk.remaining(); - _contentView = chunk; - _handler.content(); // May recurse here - } - } - - // was this unexpected? - switch(_state) - { - case STATE_END: - case STATE_SEEKING_EOF: - _state = STATE_END; - break; - - case STATE_EOF_CONTENT: - _state = STATE_END; - _handler.messageComplete(_contentPosition); - break; - - default: - _state = STATE_END; - if (!_headResponse) - _handler.earlyEOF(); - _handler.messageComplete(_contentPosition); - } - - if (ex!=null) - throw ex; - - if (!isComplete() && !isIdle()) - throw new EofException(); - - return -1; - } - length = _buffer.remaining(); - } - - - // Handle header states - byte ch; - byte[] array = _buffer.hasArray() ? _buffer.array() : null; - int last = _state; - while (_state<STATE_END && length-->0) - { - if (last!=_state) - { - progress++; - last = _state; - } - - ch = _buffer.get(); - - if (_eol == HttpTokens.CARRIAGE_RETURN) - { - if (ch == HttpTokens.LINE_FEED) - { - _eol=HttpTokens.LINE_FEED; - continue; - } - throw new HttpException(HttpStatus.BAD_REQUEST_400); - } - _eol=0; - - switch (_state) - { - case STATE_START: - _contentLength = HttpTokens.UNKNOWN_CONTENT; - _cached = null; - if (ch > HttpTokens.SPACE || ch<0) - { - mark(); - _state = STATE_FIELD0; - } - break; - - case STATE_FIELD0: - if (ch == HttpTokens.SPACE) - { - _tok0 = bufferToString(_mark, _buffer.position() - 1 - _mark); - _responseStatus = !HttpVersions.CACHE.contains(_tok0)?-1:0; - _state=STATE_SPACE1; - continue; - } - else if (ch < HttpTokens.SPACE && ch>=0) - { - throw new HttpException(HttpStatus.BAD_REQUEST_400); - } - break; - - case STATE_SPACE1: - if (ch > HttpTokens.SPACE || ch<0) - { - mark(); - if (_responseStatus>=0) - { - _state = STATE_STATUS; - _responseStatus=ch-'0'; - } - else - _state=STATE_URI; - } - else if (ch < HttpTokens.SPACE) - { - throw new HttpException(HttpStatus.BAD_REQUEST_400); - } - break; - - case STATE_STATUS: - if (ch == HttpTokens.SPACE) - { - _tok1 = bufferToString(_mark, _buffer.position() - 1 - _mark); - _state = STATE_SPACE2; - continue; - } - else if (ch>='0' && ch<='9') - { - _responseStatus=_responseStatus*10+(ch-'0'); - continue; - } - else if (ch < HttpTokens.SPACE && ch>=0) - { - _eol=ch; - _state = STATE_HEADER; - _tok0 = ""; - _tok1 = ""; - _multiLineValue=null; - continue; - } - // not a digit, so must be a URI - _state=STATE_URI; - _responseStatus=-1; - break; - - case STATE_URI: - if (ch == HttpTokens.SPACE) - { - _tok1 = bufferToString(_mark, _buffer.position() - 1 - _mark); - _state=STATE_SPACE2; - continue; - } - else if (ch < HttpTokens.SPACE && ch>=0) - { - // HTTP/0.9 - _handler.startRequest(_tok0, sliceFromMark(), null); - _persistent = false; - _state = STATE_SEEKING_EOF; - _handler.headerComplete(); - _handler.messageComplete(_contentPosition); - return 1; - } - break; - - case STATE_SPACE2: - if (ch > HttpTokens.SPACE || ch<0) - { - mark(); - _state=STATE_FIELD2; - } - else if (ch < HttpTokens.SPACE) - { - if (_responseStatus>0) - { - _eol=ch; - _state=STATE_HEADER; - _tok0 = ""; - _tok1 = ""; - _multiLineValue=null; - } - else - { - // HTTP/0.9 - _handler.startRequest(_tok0, _tok1, null); - _persistent = false; - _state = STATE_SEEKING_EOF; - _handler.headerComplete(); - _handler.messageComplete(_contentPosition); - return 1; - } - } - break; - - case STATE_FIELD2: - if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) - { - String version; - if (_responseStatus > 0) -// _handler.startResponse(version=HttpVersions.CACHE.lookup(_tok0), _responseStatus,sliceFromMark()); - version = _tok0; - else - _handler.startRequest(_tok0, _tok1, version=sliceFromMark()); - _eol=ch; - _persistent = HttpVersions.CACHE.getOrdinal(version) >= HttpVersions.HTTP_1_1_ORDINAL; - _state=STATE_HEADER; - _tok0 = ""; - _tok1 = ""; - _multiLineValue=null; - continue; - } - break; - - case STATE_HEADER: - switch(ch) - { - case HttpTokens.COLON: - case HttpTokens.SPACE: - case HttpTokens.TAB: - { - // header value without name - continuation? - _length=-1; - _state=STATE_HEADER_VALUE; - break; - } - - default: - { - // handler last header if any - if (_cached!=null || _tok0.length() > 0 || _tok1.length() > 0 || _multiLineValue != null) - { - String header = _cached!=null ? _cached : _tok0; - _cached = null; - String value = _multiLineValue == null ? _tok1 : _multiLineValue; - - int ho = HttpHeaders.CACHE.getOrdinal(header); - if (ho >= 0) - { - int vo; - - switch (ho) - { - case HttpHeaders.CONTENT_LENGTH_ORDINAL: - if (_contentLength != HttpTokens.CHUNKED_CONTENT ) - { - try - { - _contentLength = BufferUtil.toLong(value); - } - catch(NumberFormatException e) - { - LOG.trace("",e); - throw new HttpException(HttpStatus.BAD_REQUEST_400); - } - if (_contentLength <= 0) - _contentLength=HttpTokens.NO_CONTENT; - } - break; - - case HttpHeaders.TRANSFER_ENCODING_ORDINAL: -// value=HttpHeaderValues.CACHE.lookup(value); - vo = HttpHeaderValues.CACHE.getOrdinal(value); - if (HttpHeaderValues.CHUNKED_ORDINAL == vo) - _contentLength = HttpTokens.CHUNKED_CONTENT; - else - { - if (value.endsWith(HttpHeaderValues.CHUNKED)) - _contentLength = HttpTokens.CHUNKED_CONTENT; - - else if (value.indexOf(HttpHeaderValues.CHUNKED) >= 0) - throw new HttpException(400,null); - } - break; - - case HttpHeaders.CONNECTION_ORDINAL: - switch(HttpHeaderValues.CACHE.getOrdinal(value)) - { - case HttpHeaderValues.CLOSE_ORDINAL: - _persistent = false; - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - _persistent = true; - break; - - case -1: // No match, may be multi valued - { - for (String v : value.split(",")) - { - switch(HttpHeaderValues.CACHE.getOrdinal(v.trim())) - { - case HttpHeaderValues.CLOSE_ORDINAL: - _persistent = false; - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - _persistent = true; - break; - } - } - break; - } - } - } - } - - _handler.parsedHeader(header, value); - _tok0 = ""; - _tok1 = ""; - _multiLineValue=null; - } - _mark = -1; - - // now handle ch - if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) - { - // is it a response that cannot have a body? - if (_responseStatus > 0 && // response - (_responseStatus == 304 || // not-modified response - _responseStatus == 204 || // no-content response - _responseStatus < 200)) // 1xx response - _contentLength=HttpTokens.NO_CONTENT; // ignore any other headers set - // else if we don't know framing - else if (_contentLength == HttpTokens.UNKNOWN_CONTENT) - { - if (_responseStatus == 0 // request - || _responseStatus == 304 // not-modified response - || _responseStatus == 204 // no-content response - || _responseStatus < 200) // 1xx response - _contentLength=HttpTokens.NO_CONTENT; - else - _contentLength=HttpTokens.EOF_CONTENT; - } - - _contentPosition=0; - _eol=ch; - if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasRemaining() && peek()==HttpTokens.LINE_FEED) - _eol=_buffer.get(); - - // We convert _contentLength to an int for this switch statement because - // we don't care about the amount of data available just whether there is some. - switch (_contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) _contentLength) - { - case HttpTokens.EOF_CONTENT: - _state=STATE_EOF_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - - case HttpTokens.CHUNKED_CONTENT: - _state=STATE_CHUNKED_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - - case HttpTokens.NO_CONTENT: - _handler.headerComplete(); - _state = _persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - - default: - _state=STATE_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - } - return 1; - } - else - { - // New header - _length = 1; - mark(); - _state = STATE_HEADER_NAME; - - // try cached name! - if (array!=null) - { - String s = new String(array, _mark, length+1); - _cached = HttpHeaders.CACHE.getBest(s); - - if (_cached!=null) - { - _length = _cached.length(); - _buffer.position(_mark+_length); - length = _buffer.remaining(); - } - } - } - } - } - - break; - - case STATE_HEADER_NAME: - switch(ch) - { - case HttpTokens.CARRIAGE_RETURN: - case HttpTokens.LINE_FEED: - if (_length > 0) { - _tok0 = bufferToString(_mark, _length); - } - _eol=ch; - _state=STATE_HEADER; - break; - case HttpTokens.COLON: - if (_length > 0 && _cached==null) { - _tok0 = bufferToString(_mark, _length); - } - _length=-1; - _state=STATE_HEADER_VALUE; - break; - case HttpTokens.SPACE: - case HttpTokens.TAB: - break; - default: - { - _cached = null; - if (_length == -1) - mark(); - _length = _buffer.position() - _mark; - _state = STATE_HEADER_IN_NAME; - } - } - - break; - - case STATE_HEADER_IN_NAME: - switch(ch) - { - case HttpTokens.CARRIAGE_RETURN: - case HttpTokens.LINE_FEED: - if (_length > 0) { - _tok0 = bufferToString(_mark,_length); - } - _eol=ch; - _state=STATE_HEADER; - break; - case HttpTokens.COLON: - if (_length > 0 && _cached==null) { - _tok0 = bufferToString(_mark,_length); - } - _length=-1; - _state=STATE_HEADER_VALUE; - break; - case HttpTokens.SPACE: - case HttpTokens.TAB: - _state=STATE_HEADER_NAME; - break; - default: - { - _cached = null; - _length++; - } - } - break; - - case STATE_HEADER_VALUE: - switch(ch) - { - case HttpTokens.CARRIAGE_RETURN: - case HttpTokens.LINE_FEED: - if (_length > 0) - { - if (_tok1.length() == 0) -// _tok1.update(_mark, _mark + _length); - _tok1 = bufferToString(_mark, _length); - else - { - // Continuation line! - if (_multiLineValue == null) _multiLineValue = _tok1; -// _tok1.update(_mark, _mark + _length); - _tok1 = bufferToString(_mark, _length); - _multiLineValue += " " + _tok1; - } - } - _eol=ch; - _state=STATE_HEADER; - break; - case HttpTokens.SPACE: - case HttpTokens.TAB: - break; - default: - { - if (_length == -1) - mark(); - _length = _buffer.position() - _mark; - _state = STATE_HEADER_IN_VALUE; - } - } - break; - - case STATE_HEADER_IN_VALUE: - switch(ch) - { - case HttpTokens.CARRIAGE_RETURN: - case HttpTokens.LINE_FEED: - if (_length > 0) - { - if (_tok1.length() == 0) -// _tok1.update(_mark, _mark + _length); - _tok1 = bufferToString(_mark, _length); - else - { - // Continuation line! - if (_multiLineValue == null) _multiLineValue = _tok1; -// _tok1.update(_mark, _mark + _length); - _tok1 = bufferToString(_mark, _length); - _multiLineValue += " " + _tok1; - } - } - _eol=ch; - _state=STATE_HEADER; - break; - case HttpTokens.SPACE: - case HttpTokens.TAB: - _state=STATE_HEADER_VALUE; - break; - default: - _length++; - } - break; - } - } // end of HEADER states loop - - // ========================== - - // Handle HEAD response - if (_responseStatus>0 && _headResponse) - { - _state = _persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentLength); - } - - - // ========================== - - // Handle _content - length=_buffer.remaining(); - last=_state; - while (_state > STATE_END && length > 0) - { - if (last!=_state) - { - progress++; - last=_state; - } - - if (_eol == HttpTokens.CARRIAGE_RETURN && peek() == HttpTokens.LINE_FEED) - { - _eol=_buffer.get(); - length=_buffer.remaining(); - continue; - } - _eol=0; - switch (_state) - { - case STATE_EOF_CONTENT: - { - ByteBuffer chunk = getBuffer(_buffer.remaining()); - _contentPosition += chunk.remaining(); - _contentView = chunk; - _handler.content(); // May recurse here - // TODO adjust the _buffer to keep unconsumed content - return 1; - } - - case STATE_CONTENT: - { - long remaining = _contentLength - _contentPosition; - if (remaining == 0) - { - _state = _persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - - if (length > remaining) - { - // We can cast reamining to an int as we know that it is smaller than - // or equal to length which is already an int. - length=(int)remaining; - } - - ByteBuffer chunk = getBuffer(length); - _contentPosition += chunk.remaining(); - _contentView = chunk; - _handler.content(); // May recurse here - - if(_contentPosition == _contentLength) - { - _state = _persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - } - // TODO adjust the _buffer to keep unconsumed content - return 1; - } - - case STATE_CHUNKED_CONTENT: - { - ch=peek(); - if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) - _eol=_buffer.get(); - else if (ch <= HttpTokens.SPACE) - _buffer.get(); - else - { - _chunkLength=0; - _chunkPosition=0; - _state = STATE_CHUNK_SIZE; - } - break; - } - - case STATE_CHUNK_SIZE: - { - ch=_buffer.get(); - if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) - { - _eol=ch; - - if (_chunkLength == 0) - { - if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasRemaining() && peek()==HttpTokens.LINE_FEED) - _eol=_buffer.get(); - _state = _persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - else - _state = STATE_CHUNK; - } - else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON) - _state=STATE_CHUNK_PARAMS; - else if (ch >= '0' && ch <= '9') - _chunkLength=_chunkLength * 16 + (ch - '0'); - else if (ch >= 'a' && ch <= 'f') - _chunkLength=_chunkLength * 16 + (10 + ch - 'a'); - else if (ch >= 'A' && ch <= 'F') - _chunkLength=_chunkLength * 16 + (10 + ch - 'A'); - else - throw new IOException("bad chunk char: " + ch); - break; - } - - case STATE_CHUNK_PARAMS: - { - ch=_buffer.get(); - if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED) - { - _eol=ch; - if (_chunkLength == 0) - { - if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasRemaining() && peek()==HttpTokens.LINE_FEED) - _eol=_buffer.get(); - _state = _persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - else - _state=STATE_CHUNK; - } - break; - } - - case STATE_CHUNK: - { - int remaining=_chunkLength - _chunkPosition; - if (remaining == 0) - { - _state=STATE_CHUNKED_CONTENT; - break; - } - else if (length > remaining) - length=remaining; - ByteBuffer chunk = getBuffer(length); - _contentPosition += chunk.remaining(); - _chunkPosition += chunk.remaining(); - _contentView = chunk; - _handler.content(); // May recurse here - // TODO adjust the _buffer to keep unconsumed content - return 1; - } - - case STATE_SEEKING_EOF: - { - // Close if there is more data than CRLF - if (_buffer.remaining()>2) - { - _state = STATE_END; - _endp.close(); - } - else - { - // or if the data is not white space - while (_buffer.remaining()>0) - if (!Character.isWhitespace(_buffer.get())) - { - _state = STATE_END; - _endp.close(); - clear(); - } - } - - clear(); - break; - } - } - - length = _buffer.remaining(); - } - - return progress; - } - catch(HttpException e) - { - _persistent = false; - _state = STATE_SEEKING_EOF; - throw e; - } - } - - /* ------------------------------------------------------------------------------- */ - /** fill the buffers from the endpoint - * - */ - private int fill() throws IOException - { - // Do we have a buffer? - if (_buffer==null) - _buffer = _header; - - // Is there unconsumed content in body buffer - if (_state>STATE_END && _buffer==_header && !_header.hasRemaining() && _body.hasRemaining()) - { - _buffer = _body; - return _buffer.remaining(); - } - - // Shall we switch to a body buffer? - if (_buffer==_header && _state>STATE_END && _header.remaining()==0 && ((_contentLength-_contentPosition)>_header.capacity())) - { - _buffer = _body; - } - - // Shall we compact the body? - if (_buffer==_body || _state>STATE_END) - { - compact(); - } - - // Are we full? - if (_buffer.limit() == _buffer.capacity()) - { - LOG.warn("HttpParser Full for {} ",_endp); - clear(); - throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large: "+(_buffer==_body?"body":"head")); - } -/* why? - try - { - int filled = _endp.fill(_buffer); - return filled; - } - catch(IOException e) - { - LOG.debug("",e); - throw (e instanceof EofException) ? e:new EofException(e); - } -*/ - return _endp.fill(_buffer); - } - - @Override - public String toString() - { - return String.format("%s{s=%d,l=%d,c=%d}", - getClass().getSimpleName(), - _state, - _length, - _contentLength); - } - - public ByteBuffer blockForContent(long maxIdleTime) throws IOException - { - if (_contentView.remaining()>0) - return _contentView; - - if (_state <= STATE_END || _state==STATE_SEEKING_EOF) - return null; - - try - { - parseNext(); - - // parse until some progress is made (or IOException thrown for timeout) - while(_contentView.remaining() == 0 && !(_state==STATE_END||_state==STATE_SEEKING_EOF) && _endp.isOpen()) - { - if (!_endp.isBlocking()) - { - if (parseNext()>0) - continue; - - if (!_endp.blockReadable(maxIdleTime)) - { - _endp.close(); - throw new EofException("timeout"); - } - } - - parseNext(); - } - } - catch(IOException e) - { - // TODO is this needed? - _endp.close(); - throw e; - } - - return _contentView.remaining()>0 ? _contentView : null; - } - - /* ------------------------------------------------------------ */ - /* (non-Javadoc) - * @see java.io.InputStream#available() - */ - public int available() throws IOException - { - if (_contentView.remaining()>0) - return _contentView.remaining(); - - if (_endp.isBlocking()) - { - return 0; - } - - parseNext(); - return _contentView.remaining(); - } - - - public interface EventHandler - { - public abstract void content() throws IOException; - - public void headerComplete() throws IOException; - - public void messageComplete(long contentLength) throws IOException; - - /** - * This is the method called by parser when a HTTP Header name and value is found - */ - public void parsedHeader(String name, String value) throws IOException; - - /** - * This is the method called by parser when the HTTP request line is parsed - */ - public abstract void startRequest(String method, String url, String version) - throws IOException; - - public void earlyEOF(); - } - - - - -}
--- a/src/org/eclipse/jetty/http/HttpStatus.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1036 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -/** - * <p> - * HttpStatusCode enum class, for status codes based on various HTTP RFCs. (see - * table below) - * </p> - * - * <table border="1" cellpadding="5"> - * <tr> - * <th>Enum</th> - * <th>Code</th> - * <th>Message</th> - * <th> - * <a href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a></th> - * <th> - * <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a></th> - * <th> - * <a href="http://tools.ietf.org/html/rfc2518">RFC 2518 - WEBDAV</a></th> - * </tr> - * - * <tr> - * <td><strong><code>Informational - 1xx</code></strong></td> - * <td colspan="5">{@link #isInformational(int)}</td> - * </tr> - * - * <tr> - * <td>{@link #CONTINUE_100}</td> - * <td>100</td> - * <td>Continue</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.1.1">Sec. 10.1.1</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #SWITCHING_PROTOCOLS_101}</td> - * <td>101</td> - * <td>Switching Protocols</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.1.2">Sec. 10.1.2</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #PROCESSING_102}</td> - * <td>102</td> - * <td>Processing</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.1">Sec. 10.1</a></td> - * </tr> - * - * <tr> - * <td><strong><code>Success - 2xx</code></strong></td> - * <td colspan="5">{@link #isSuccess(int)}</td> - * </tr> - * - * <tr> - * <td>{@link #OK_200}</td> - * <td>200</td> - * <td>OK</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.1">Sec. 10.2.1</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #CREATED_201}</td> - * <td>201</td> - * <td>Created</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.2">Sec. 10.2.2</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #ACCEPTED_202}</td> - * <td>202</td> - * <td>Accepted</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.3">Sec. 10.2.3</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NON_AUTHORITATIVE_INFORMATION_203}</td> - * <td>203</td> - * <td>Non Authoritative Information</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.4">Sec. 10.2.4</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NO_CONTENT_204}</td> - * <td>204</td> - * <td>No Content</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.5">Sec. 10.2.5</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #RESET_CONTENT_205}</td> - * <td>205</td> - * <td>Reset Content</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.6">Sec. 10.2.6</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #PARTIAL_CONTENT_206}</td> - * <td>206</td> - * <td>Partial Content</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.7">Sec. 10.2.7</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #MULTI_STATUS_207}</td> - * <td>207</td> - * <td>Multi-Status</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.2">Sec. 10.2</a></td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>207</strike></td> - * <td><strike>Partial Update OK</strike></td> - * <td> </td> - * <td> - * <a href= - * "http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-rev-01.txt" - * >draft/01</a></td> - * <td> </td> - * </tr> - * - * <tr> - * <td><strong><code>Redirection - 3xx</code></strong></td> - * <td colspan="5">{@link #isRedirection(int)}</td> - * </tr> - * - * <tr> - * <td>{@link #MULTIPLE_CHOICES_300}</td> - * <td>300</td> - * <td>Multiple Choices</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.1">Sec. 10.3.1</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #MOVED_PERMANENTLY_301}</td> - * <td>301</td> - * <td>Moved Permanently</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.2">Sec. 10.3.2</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #MOVED_TEMPORARILY_302}</td> - * <td>302</td> - * <td>Moved Temporarily</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td> - * <td>(now "<code>302 Found</code>")</td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #FOUND_302}</td> - * <td>302</td> - * <td>Found</td> - * <td>(was "<code>302 Moved Temporarily</code>")</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.3">Sec. 10.3.3</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #SEE_OTHER_303}</td> - * <td>303</td> - * <td>See Other</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.4">Sec. 10.3.4</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NOT_MODIFIED_304}</td> - * <td>304</td> - * <td>Not Modified</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.5">Sec. 10.3.5</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #USE_PROXY_305}</td> - * <td>305</td> - * <td>Use Proxy</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.6">Sec. 10.3.6</a></td> - * <td> </td> - * </tr> - * <tr> - * <td> </td> - * <td>306</td> - * <td><em>(Unused)</em></td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.7">Sec. 10.3.7</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #TEMPORARY_REDIRECT_307}</td> - * <td>307</td> - * <td>Temporary Redirect</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.8">Sec. 10.3.8</a></td> - * <td> </td> - * </tr> - * - * <tr> - * <td><strong><code>Client Error - 4xx</code></strong></td> - * <td colspan="5">{@link #isClientError(int)}</td> - * </tr> - * - * <tr> - * <td>{@link #BAD_REQUEST_400}</td> - * <td>400</td> - * <td>Bad Request</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.1">Sec. 10.4.1</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #UNAUTHORIZED_401}</td> - * <td>401</td> - * <td>Unauthorized</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.2">Sec. 10.4.2</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #PAYMENT_REQUIRED_402}</td> - * <td>402</td> - * <td>Payment Required</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.3">Sec. 10.4.3</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #FORBIDDEN_403}</td> - * <td>403</td> - * <td>Forbidden</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.4">Sec. 10.4.4</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NOT_FOUND_404}</td> - * <td>404</td> - * <td>Not Found</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.5">Sec. 10.4.5</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #METHOD_NOT_ALLOWED_405}</td> - * <td>405</td> - * <td>Method Not Allowed</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.6">Sec. 10.4.6</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NOT_ACCEPTABLE_406}</td> - * <td>406</td> - * <td>Not Acceptable</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.7">Sec. 10.4.7</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #PROXY_AUTHENTICATION_REQUIRED_407}</td> - * <td>407</td> - * <td>Proxy Authentication Required</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.8">Sec. 10.4.8</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #REQUEST_TIMEOUT_408}</td> - * <td>408</td> - * <td>Request Timeout</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.9">Sec. 10.4.9</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #CONFLICT_409}</td> - * <td>409</td> - * <td>Conflict</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.10">Sec. 10.4.10</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #GONE_410}</td> - * <td>410</td> - * <td>Gone</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.11">Sec. 10.4.11</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #LENGTH_REQUIRED_411}</td> - * <td>411</td> - * <td>Length Required</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.12">Sec. 10.4.12</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #PRECONDITION_FAILED_412}</td> - * <td>412</td> - * <td>Precondition Failed</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.13">Sec. 10.4.13</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #REQUEST_ENTITY_TOO_LARGE_413}</td> - * <td>413</td> - * <td>Request Entity Too Large</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.14">Sec. 10.4.14</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #REQUEST_URI_TOO_LONG_414}</td> - * <td>414</td> - * <td>Request-URI Too Long</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.15">Sec. 10.4.15</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #UNSUPPORTED_MEDIA_TYPE_415}</td> - * <td>415</td> - * <td>Unsupported Media Type</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.16">Sec. 10.4.16</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #REQUESTED_RANGE_NOT_SATISFIABLE_416}</td> - * <td>416</td> - * <td>Requested Range Not Satisfiable</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.17">Sec. 10.4.17</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #EXPECTATION_FAILED_417}</td> - * <td>417</td> - * <td>Expectation Failed</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.18">Sec. 10.4.18</a> - * </td> - * <td> </td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>418</strike></td> - * <td><strike>Reauthentication Required</strike></td> - * <td> </td> - * <td> - * <a href= - * "http://tools.ietf.org/html/draft-ietf-http-v11-spec-rev-01#section-10.4.19" - * >draft/01</a></td> - * <td> </td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>418</strike></td> - * <td><strike>Unprocessable Entity</strike></td> - * <td> </td> - * <td> </td> - * <td> - * <a href= - * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.3" - * >draft/05</a></td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>419</strike></td> - * <td><strike>Proxy Reauthentication Required</stike></td> - * <td> </td> - * <td> - * <a href= - * "http://tools.ietf.org/html/draft-ietf-http-v11-spec-rev-01#section-10.4.20" - * >draft/01</a></td> - * <td> </td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>419</strike></td> - * <td><strike>Insufficient Space on Resource</stike></td> - * <td> </td> - * <td> </td> - * <td> - * <a href= - * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.4" - * >draft/05</a></td> - * </tr> - * <tr> - * <td> </td> - * <td><strike>420</strike></td> - * <td><strike>Method Failure</strike></td> - * <td> </td> - * <td> </td> - * <td> - * <a href= - * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.5" - * >draft/05</a></td> - * </tr> - * <tr> - * <td> </td> - * <td>421</td> - * <td><em>(Unused)</em></td> - * <td> </td> - * <td> </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #UNPROCESSABLE_ENTITY_422}</td> - * <td>422</td> - * <td>Unprocessable Entity</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.3">Sec. 10.3</a></td> - * </tr> - * <tr> - * <td>{@link #LOCKED_423}</td> - * <td>423</td> - * <td>Locked</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.4">Sec. 10.4</a></td> - * </tr> - * <tr> - * <td>{@link #FAILED_DEPENDENCY_424}</td> - * <td>424</td> - * <td>Failed Dependency</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.5">Sec. 10.5</a></td> - * </tr> - * - * <tr> - * <td><strong><code>Server Error - 5xx</code></strong></td> - * <td colspan="5">{@link #isServerError(int)}</td> - * </tr> - * - * <tr> - * <td>{@link #INTERNAL_SERVER_ERROR_500}</td> - * <td>500</td> - * <td>Internal Server Error</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.1">Sec. 10.5.1</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #NOT_IMPLEMENTED_501}</td> - * <td>501</td> - * <td>Not Implemented</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.2">Sec. 10.5.2</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #BAD_GATEWAY_502}</td> - * <td>502</td> - * <td>Bad Gateway</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.3">Sec. 10.5.3</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #SERVICE_UNAVAILABLE_503}</td> - * <td>503</td> - * <td>Service Unavailable</td> - * <td> - * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.4">Sec. 10.5.4</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #GATEWAY_TIMEOUT_504}</td> - * <td>504</td> - * <td>Gateway Timeout</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.5">Sec. 10.5.5</a></td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #HTTP_VERSION_NOT_SUPPORTED_505}</td> - * <td>505</td> - * <td>HTTP Version Not Supported</td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.6">Sec. 10.5.6</a></td> - * <td> </td> - * </tr> - * <tr> - * <td> </td> - * <td>506</td> - * <td><em>(Unused)</em></td> - * <td> </td> - * <td> </td> - * <td> </td> - * </tr> - * <tr> - * <td>{@link #INSUFFICIENT_STORAGE_507}</td> - * <td>507</td> - * <td>Insufficient Storage</td> - * <td> </td> - * <td> </td> - * <td> - * <a href="http://tools.ietf.org/html/rfc2518#section-10.6">Sec. 10.6</a></td> - * </tr> - * - * </table> - * - * @version $Id$ - */ -public class HttpStatus -{ - public final static int CONTINUE_100 = 100; - public final static int SWITCHING_PROTOCOLS_101 = 101; - public final static int PROCESSING_102 = 102; - - public final static int OK_200 = 200; - public final static int CREATED_201 = 201; - public final static int ACCEPTED_202 = 202; - public final static int NON_AUTHORITATIVE_INFORMATION_203 = 203; - public final static int NO_CONTENT_204 = 204; - public final static int RESET_CONTENT_205 = 205; - public final static int PARTIAL_CONTENT_206 = 206; - public final static int MULTI_STATUS_207 = 207; - - public final static int MULTIPLE_CHOICES_300 = 300; - public final static int MOVED_PERMANENTLY_301 = 301; - public final static int MOVED_TEMPORARILY_302 = 302; - public final static int FOUND_302 = 302; - public final static int SEE_OTHER_303 = 303; - public final static int NOT_MODIFIED_304 = 304; - public final static int USE_PROXY_305 = 305; - public final static int TEMPORARY_REDIRECT_307 = 307; - - public final static int BAD_REQUEST_400 = 400; - public final static int UNAUTHORIZED_401 = 401; - public final static int PAYMENT_REQUIRED_402 = 402; - public final static int FORBIDDEN_403 = 403; - public final static int NOT_FOUND_404 = 404; - public final static int METHOD_NOT_ALLOWED_405 = 405; - public final static int NOT_ACCEPTABLE_406 = 406; - public final static int PROXY_AUTHENTICATION_REQUIRED_407 = 407; - public final static int REQUEST_TIMEOUT_408 = 408; - public final static int CONFLICT_409 = 409; - public final static int GONE_410 = 410; - public final static int LENGTH_REQUIRED_411 = 411; - public final static int PRECONDITION_FAILED_412 = 412; - public final static int REQUEST_ENTITY_TOO_LARGE_413 = 413; - public final static int REQUEST_URI_TOO_LONG_414 = 414; - public final static int UNSUPPORTED_MEDIA_TYPE_415 = 415; - public final static int REQUESTED_RANGE_NOT_SATISFIABLE_416 = 416; - public final static int EXPECTATION_FAILED_417 = 417; - public final static int UNPROCESSABLE_ENTITY_422 = 422; - public final static int LOCKED_423 = 423; - public final static int FAILED_DEPENDENCY_424 = 424; - - public final static int INTERNAL_SERVER_ERROR_500 = 500; - public final static int NOT_IMPLEMENTED_501 = 501; - public final static int BAD_GATEWAY_502 = 502; - public final static int SERVICE_UNAVAILABLE_503 = 503; - public final static int GATEWAY_TIMEOUT_504 = 504; - public final static int HTTP_VERSION_NOT_SUPPORTED_505 = 505; - public final static int INSUFFICIENT_STORAGE_507 = 507; - - public static final int MAX_CODE = 507; - - - private static final Code[] codeMap = new Code[MAX_CODE+1]; - - static - { - for (Code code : Code.values()) - { - codeMap[code._code] = code; - } - } - - - public enum Code - { - /* - * -------------------------------------------------------------------- - * Informational messages in 1xx series. As defined by ... RFC 1945 - - * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV - */ - - /** <code>100 Continue</code> */ - CONTINUE(CONTINUE_100, "Continue"), - /** <code>101 Switching Protocols</code> */ - SWITCHING_PROTOCOLS(SWITCHING_PROTOCOLS_101, "Switching Protocols"), - /** <code>102 Processing</code> */ - PROCESSING(PROCESSING_102, "Processing"), - - /* - * -------------------------------------------------------------------- - * Success messages in 2xx series. As defined by ... RFC 1945 - HTTP/1.0 - * RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV - */ - - /** <code>200 OK</code> */ - OK(OK_200, "OK"), - /** <code>201 Created</code> */ - CREATED(CREATED_201, "Created"), - /** <code>202 Accepted</code> */ - ACCEPTED(ACCEPTED_202, "Accepted"), - /** <code>203 Non Authoritative Information</code> */ - NON_AUTHORITATIVE_INFORMATION(NON_AUTHORITATIVE_INFORMATION_203, "Non Authoritative Information"), - /** <code>204 No Content</code> */ - NO_CONTENT(NO_CONTENT_204, "No Content"), - /** <code>205 Reset Content</code> */ - RESET_CONTENT(RESET_CONTENT_205, "Reset Content"), - /** <code>206 Partial Content</code> */ - PARTIAL_CONTENT(PARTIAL_CONTENT_206, "Partial Content"), - /** <code>207 Multi-Status</code> */ - MULTI_STATUS(MULTI_STATUS_207, "Multi-Status"), - - /* - * -------------------------------------------------------------------- - * Redirection messages in 3xx series. As defined by ... RFC 1945 - - * HTTP/1.0 RFC 2616 - HTTP/1.1 - */ - - /** <code>300 Mutliple Choices</code> */ - MULTIPLE_CHOICES(MULTIPLE_CHOICES_300, "Multiple Choices"), - /** <code>301 Moved Permanently</code> */ - MOVED_PERMANENTLY(MOVED_PERMANENTLY_301, "Moved Permanently"), - /** <code>302 Moved Temporarily</code> */ - MOVED_TEMPORARILY(MOVED_TEMPORARILY_302, "Moved Temporarily"), - /** <code>302 Found</code> */ - FOUND(FOUND_302, "Found"), - /** <code>303 See Other</code> */ - SEE_OTHER(SEE_OTHER_303, "See Other"), - /** <code>304 Not Modified</code> */ - NOT_MODIFIED(NOT_MODIFIED_304, "Not Modified"), - /** <code>305 Use Proxy</code> */ - USE_PROXY(USE_PROXY_305, "Use Proxy"), - /** <code>307 Temporary Redirect</code> */ - TEMPORARY_REDIRECT(TEMPORARY_REDIRECT_307, "Temporary Redirect"), - - /* - * -------------------------------------------------------------------- - * Client Error messages in 4xx series. As defined by ... RFC 1945 - - * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV - */ - - /** <code>400 Bad Request</code> */ - BAD_REQUEST(BAD_REQUEST_400, "Bad Request"), - /** <code>401 Unauthorized</code> */ - UNAUTHORIZED(UNAUTHORIZED_401, "Unauthorized"), - /** <code>402 Payment Required</code> */ - PAYMENT_REQUIRED(PAYMENT_REQUIRED_402, "Payment Required"), - /** <code>403 Forbidden</code> */ - FORBIDDEN(FORBIDDEN_403, "Forbidden"), - /** <code>404 Not Found</code> */ - NOT_FOUND(NOT_FOUND_404, "Not Found"), - /** <code>405 Method Not Allowed</code> */ - METHOD_NOT_ALLOWED(METHOD_NOT_ALLOWED_405, "Method Not Allowed"), - /** <code>406 Not Acceptable</code> */ - NOT_ACCEPTABLE(NOT_ACCEPTABLE_406, "Not Acceptable"), - /** <code>407 Proxy Authentication Required</code> */ - PROXY_AUTHENTICATION_REQUIRED(PROXY_AUTHENTICATION_REQUIRED_407, "Proxy Authentication Required"), - /** <code>408 Request Timeout</code> */ - REQUEST_TIMEOUT(REQUEST_TIMEOUT_408, "Request Timeout"), - /** <code>409 Conflict</code> */ - CONFLICT(CONFLICT_409, "Conflict"), - /** <code>410 Gone</code> */ - GONE(GONE_410, "Gone"), - /** <code>411 Length Required</code> */ - LENGTH_REQUIRED(LENGTH_REQUIRED_411, "Length Required"), - /** <code>412 Precondition Failed</code> */ - PRECONDITION_FAILED(PRECONDITION_FAILED_412, "Precondition Failed"), - /** <code>413 Request Entity Too Large</code> */ - REQUEST_ENTITY_TOO_LARGE(REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large"), - /** <code>414 Request-URI Too Long</code> */ - REQUEST_URI_TOO_LONG(REQUEST_URI_TOO_LONG_414, "Request-URI Too Long"), - /** <code>415 Unsupported Media Type</code> */ - UNSUPPORTED_MEDIA_TYPE(UNSUPPORTED_MEDIA_TYPE_415, "Unsupported Media Type"), - /** <code>416 Requested Range Not Satisfiable</code> */ - REQUESTED_RANGE_NOT_SATISFIABLE(REQUESTED_RANGE_NOT_SATISFIABLE_416, "Requested Range Not Satisfiable"), - /** <code>417 Expectation Failed</code> */ - EXPECTATION_FAILED(EXPECTATION_FAILED_417, "Expectation Failed"), - /** <code>422 Unprocessable Entity</code> */ - UNPROCESSABLE_ENTITY(UNPROCESSABLE_ENTITY_422, "Unprocessable Entity"), - /** <code>423 Locked</code> */ - LOCKED(LOCKED_423, "Locked"), - /** <code>424 Failed Dependency</code> */ - FAILED_DEPENDENCY(FAILED_DEPENDENCY_424, "Failed Dependency"), - - /* - * -------------------------------------------------------------------- - * Server Error messages in 5xx series. As defined by ... RFC 1945 - - * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV - */ - - /** <code>500 Server Error</code> */ - INTERNAL_SERVER_ERROR(INTERNAL_SERVER_ERROR_500, "Server Error"), - /** <code>501 Not Implemented</code> */ - NOT_IMPLEMENTED(NOT_IMPLEMENTED_501, "Not Implemented"), - /** <code>502 Bad Gateway</code> */ - BAD_GATEWAY(BAD_GATEWAY_502, "Bad Gateway"), - /** <code>503 Service Unavailable</code> */ - SERVICE_UNAVAILABLE(SERVICE_UNAVAILABLE_503, "Service Unavailable"), - /** <code>504 Gateway Timeout</code> */ - GATEWAY_TIMEOUT(GATEWAY_TIMEOUT_504, "Gateway Timeout"), - /** <code>505 HTTP Version Not Supported</code> */ - HTTP_VERSION_NOT_SUPPORTED(HTTP_VERSION_NOT_SUPPORTED_505, "HTTP Version Not Supported"), - /** <code>507 Insufficient Storage</code> */ - INSUFFICIENT_STORAGE(INSUFFICIENT_STORAGE_507, "Insufficient Storage"); - - private final int _code; - private final String _message; - - private Code(int code, String message) - { - this._code = code; - _message=message; - } - - public int getCode() - { - return _code; - } - - public String getMessage() - { - return _message; - } - - - public boolean equals(int code) - { - return (this._code == code); - } - - @Override - public String toString() - { - return String.format("[%03d %s]",this._code,this.getMessage()); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Informational</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, - * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - - * HTTP/1.1</a>. - * - * @return true if within range of codes that belongs to - * <code>Informational</code> messages. - */ - public boolean isInformational() - { - return HttpStatus.isInformational(this._code); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Success</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, - * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - - * HTTP/1.1</a>. - * - * @return true if within range of codes that belongs to - * <code>Success</code> messages. - */ - public boolean isSuccess() - { - return HttpStatus.isSuccess(this._code); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Redirection</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, - * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - - * HTTP/1.1</a>. - * - * @return true if within range of codes that belongs to - * <code>Redirection</code> messages. - */ - public boolean isRedirection() - { - return HttpStatus.isRedirection(this._code); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Client Error</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, - * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - - * HTTP/1.1</a>. - * - * @return true if within range of codes that belongs to - * <code>Client Error</code> messages. - */ - public boolean isClientError() - { - return HttpStatus.isClientError(this._code); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Server Error</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, - * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - - * HTTP/1.1</a>. - * - * @return true if within range of codes that belongs to - * <code>Server Error</code> messages. - */ - public boolean isServerError() - { - return HttpStatus.isServerError(this._code); - } - } - - - /** - * Get the HttpStatusCode for a specific code - * - * @param code - * the code to lookup. - * @return the {@link HttpStatus} if found, or null if not found. - */ - public static Code getCode(int code) - { - if (code <= MAX_CODE) - { - return codeMap[code]; - } - return null; - } - - /** - * Get the status message for a specific code. - * - * @param code - * the code to look up - * @return the specific message, or the code number itself if code - * does not match known list. - */ - public static String getMessage(int code) - { - Code codeEnum = getCode(code); - if (codeEnum != null) - { - return codeEnum.getMessage(); - } - else - { - return Integer.toString(code); - } - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Informational</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a - * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>. - * - * @param code - * the code to test. - * @return true if within range of codes that belongs to - * <code>Informational</code> messages. - */ - public static boolean isInformational(int code) - { - return ((100 <= code) && (code <= 199)); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Success</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a - * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>. - * - * @param code - * the code to test. - * @return true if within range of codes that belongs to - * <code>Success</code> messages. - */ - public static boolean isSuccess(int code) - { - return ((200 <= code) && (code <= 299)); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Redirection</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a - * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>. - * - * @param code - * the code to test. - * @return true if within range of codes that belongs to - * <code>Redirection</code> messages. - */ - public static boolean isRedirection(int code) - { - return ((300 <= code) && (code <= 399)); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Client Error</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a - * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>. - * - * @param code - * the code to test. - * @return true if within range of codes that belongs to - * <code>Client Error</code> messages. - */ - public static boolean isClientError(int code) - { - return ((400 <= code) && (code <= 499)); - } - - /** - * Simple test against an code to determine if it falls into the - * <code>Server Error</code> message category as defined in the <a - * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a - * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>. - * - * @param code - * the code to test. - * @return true if within range of codes that belongs to - * <code>Server Error</code> messages. - */ - public static boolean isServerError(int code) - { - return ((500 <= code) && (code <= 599)); - } -}
--- a/src/org/eclipse/jetty/http/HttpTokens.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -/** - * HTTP constants - */ -public interface HttpTokens -{ - // Terminal symbols. - static final byte COLON= (byte)':'; - static final byte SPACE= 0x20; - static final byte CARRIAGE_RETURN= 0x0D; - static final byte LINE_FEED= 0x0A; - static final byte[] CRLF = {CARRIAGE_RETURN,LINE_FEED}; - static final byte SEMI_COLON= (byte)';'; - static final byte TAB= 0x09; - - public static final int SELF_DEFINING_CONTENT= -4; - public static final int UNKNOWN_CONTENT= -3; - public static final int CHUNKED_CONTENT= -2; - public static final int EOF_CONTENT= -1; - public static final int NO_CONTENT= 0; - - -}
--- a/src/org/eclipse/jetty/http/HttpURI.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,771 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.UnsupportedEncodingException; -import java.net.URI; - -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.Utf8StringBuilder; - - -/* ------------------------------------------------------------ */ -/** Http URI. - * Parse a HTTP URI from a string or byte array. Given a URI - * <code>http://user@host:port/path/info;param?query#fragment</code> - * this class will split it into the following undecoded optional elements:<ul> - * <li>{@link #getScheme()} - http:</li> - * <li>{@link #getAuthority()} - //name@host:port</li> - * <li>{@link #getHost()} - host</li> - * <li>{@link #getPort()} - port</li> - * <li>{@link #getPath()} - /path/info</li> - * <li>{@link #getParam()} - param</li> - * <li>{@link #getQuery()} - query</li> - * <li>{@link #getFragment()} - fragment</li> - * </ul> - * - */ -public class HttpURI -{ - private static final byte[] __empty={}; - private final static int - START=0, - AUTH_OR_PATH=1, - SCHEME_OR_PATH=2, - AUTH=4, - IPV6=5, - PORT=6, - PATH=7, - PARAM=8, - QUERY=9, - ASTERISK=10; - - boolean _partial=false; - byte[] _raw=__empty; - String _rawString; - int _scheme; - int _authority; - int _host; - int _port; - int _portValue; - int _path; - int _param; - int _query; - int _fragment; - int _end; - boolean _encoded=false; - - final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64); - - public HttpURI() - { - - } - - /* ------------------------------------------------------------ */ - /** - * @param parsePartialAuth If True, parse auth without prior scheme, else treat all URIs starting with / as paths - */ - public HttpURI(boolean parsePartialAuth) - { - _partial=parsePartialAuth; - } - - public HttpURI(String raw) - { - _rawString=raw; - byte[] b; - try - { - b = raw.getBytes(StringUtil.__UTF8); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e.getMessage()); - } - parse(b,0,b.length); - } - - public HttpURI(byte[] raw,int offset, int length) - { - parse2(raw,offset,length); - } - - public HttpURI(URI uri) - { - parse(uri.toASCIIString()); - } - - public void parse(String raw) - { - byte[] b = raw.getBytes(); - parse2(b,0,b.length); - _rawString=raw; - } - - public void parse(byte[] raw,int offset, int length) - { - _rawString=null; - parse2(raw,offset,length); - } - - - public void parseConnect(byte[] raw,int offset, int length) - { - _rawString=null; - _encoded=false; - _raw=raw; - int i=offset; - int e=offset+length; - int state=AUTH; - _end=offset+length; - _scheme=offset; - _authority=offset; - _host=offset; - _port=_end; - _portValue=-1; - _path=_end; - _param=_end; - _query=_end; - _fragment=_end; - - loop: while (i<e) - { - char c=(char)(0xff&_raw[i]); - int s=i++; - - switch (state) - { - case AUTH: - { - switch (c) - { - case ':': - { - _port = s; - break loop; - } - case '[': - { - state = IPV6; - break; - } - } - continue; - } - - case IPV6: - { - switch (c) - { - case '/': - { - throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); - } - case ']': - { - state = AUTH; - break; - } - } - - continue; - } - } - } - - if (_port<_path) - _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); - else - throw new IllegalArgumentException("No port"); - _path=offset; - } - - - private void parse2(byte[] raw,int offset, int length) - { - _encoded=false; - _raw=raw; - int i=offset; - int e=offset+length; - int state=START; - int m=offset; - _end=offset+length; - _scheme=offset; - _authority=offset; - _host=offset; - _port=offset; - _portValue=-1; - _path=offset; - _param=_end; - _query=_end; - _fragment=_end; - while (i<e) - { - char c=(char)(0xff&_raw[i]); - int s=i++; - - state: switch (state) - { - case START: - { - m=s; - switch(c) - { - case '/': - state=AUTH_OR_PATH; - break; - case ';': - _param=s; - state=PARAM; - break; - case '?': - _param=s; - _query=s; - state=QUERY; - break; - case '#': - _param=s; - _query=s; - _fragment=s; - break; - case '*': - _path=s; - state=ASTERISK; - break; - - default: - state=SCHEME_OR_PATH; - } - - continue; - } - - case AUTH_OR_PATH: - { - if ((_partial||_scheme!=_authority) && c=='/') - { - _host=i; - _port=_end; - _path=_end; - state=AUTH; - } - else if (c==';' || c=='?' || c=='#') - { - i--; - state=PATH; - } - else - { - _host=m; - _port=m; - state=PATH; - } - continue; - } - - case SCHEME_OR_PATH: - { - // short cut for http and https - if (length>6 && c=='t') - { - if (_raw[offset+3]==':') - { - s=offset+3; - i=offset+4; - c=':'; - } - else if (_raw[offset+4]==':') - { - s=offset+4; - i=offset+5; - c=':'; - } - else if (_raw[offset+5]==':') - { - s=offset+5; - i=offset+6; - c=':'; - } - } - - switch (c) - { - case ':': - { - m = i++; - _authority = m; - _path = m; - c = (char)(0xff & _raw[i]); - if (c == '/') - state = AUTH_OR_PATH; - else - { - _host = m; - _port = m; - state = PATH; - } - break; - } - - case '/': - { - state = PATH; - break; - } - - case ';': - { - _param = s; - state = PARAM; - break; - } - - case '?': - { - _param = s; - _query = s; - state = QUERY; - break; - } - - case '#': - { - _param = s; - _query = s; - _fragment = s; - break; - } - } - continue; - } - - case AUTH: - { - switch (c) - { - - case '/': - { - m = s; - _path = m; - _port = _path; - state = PATH; - break; - } - case '@': - { - _host = i; - break; - } - case ':': - { - _port = s; - state = PORT; - break; - } - case '[': - { - state = IPV6; - break; - } - } - continue; - } - - case IPV6: - { - switch (c) - { - case '/': - { - throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET)); - } - case ']': - { - state = AUTH; - break; - } - } - - continue; - } - - case PORT: - { - if (c=='/') - { - m=s; - _path=m; - if (_port<=_authority) - _port=_path; - state=PATH; - } - continue; - } - - case PATH: - { - switch (c) - { - case ';': - { - _param = s; - state = PARAM; - break; - } - case '?': - { - _param = s; - _query = s; - state = QUERY; - break; - } - case '#': - { - _param = s; - _query = s; - _fragment = s; - break state; - } - case '%': - { - _encoded=true; - } - } - continue; - } - - case PARAM: - { - switch (c) - { - case '?': - { - _query = s; - state = QUERY; - break; - } - case '#': - { - _query = s; - _fragment = s; - break state; - } - } - continue; - } - - case QUERY: - { - if (c=='#') - { - _fragment=s; - break state; - } - continue; - } - - case ASTERISK: - { - throw new IllegalArgumentException("only '*'"); - } - } - } - - if (_port<_path) - _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10); - } - - private String toUtf8String(int offset,int length) - { - _utf8b.reset(); - _utf8b.append(_raw,offset,length); - return _utf8b.toString(); - } - - public String getScheme() - { - if (_scheme==_authority) - return null; - int l=_authority-_scheme; - if (l==5 && - _raw[_scheme]=='h' && - _raw[_scheme+1]=='t' && - _raw[_scheme+2]=='t' && - _raw[_scheme+3]=='p' ) - return "http"; - if (l==6 && - _raw[_scheme]=='h' && - _raw[_scheme+1]=='t' && - _raw[_scheme+2]=='t' && - _raw[_scheme+3]=='p' && - _raw[_scheme+4]=='s' ) - return "https"; - - return toUtf8String(_scheme,_authority-_scheme-1); - } - - public String getAuthority() - { - if (_authority==_path) - return null; - return toUtf8String(_authority,_path-_authority); - } - - public String getHost() - { - if (_host==_port) - return null; - return toUtf8String(_host,_port-_host); - } - - public int getPort() - { - return _portValue; - } - - public String getPath() - { - if (_path==_param) - return null; - return toUtf8String(_path,_param-_path); - } - - public String getDecodedPath() - { - if (_path==_param) - return null; - - int length = _param-_path; - boolean decoding=false; - - for (int i=_path;i<_param;i++) - { - byte b = _raw[i]; - - if (b=='%') - { - if (!decoding) - { - _utf8b.reset(); - _utf8b.append(_raw,_path,i-_path); - decoding=true; - } - - if ((i+2)>=_param) - throw new IllegalArgumentException("Bad % encoding: "+this); - if (_raw[i+1]=='u') - { - if ((i+5)>=_param) - throw new IllegalArgumentException("Bad %u encoding: "+this); - try - { - String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); - _utf8b.getStringBuilder().append(unicode); - i+=5; - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - else - { - b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); - _utf8b.append(b); - i+=2; - } - continue; - } - else if (decoding) - { - _utf8b.append(b); - } - } - - if (!decoding) - return toUtf8String(_path,length); - return _utf8b.toString(); - } - - public String getDecodedPath(String encoding) - { - if (_path==_param) - return null; - - int length = _param-_path; - byte[] bytes=null; - int n=0; - - for (int i=_path;i<_param;i++) - { - byte b = _raw[i]; - - if (b=='%') - { - if (bytes==null) - { - bytes=new byte[length]; - System.arraycopy(_raw,_path,bytes,0,n); - } - - if ((i+2)>=_param) - throw new IllegalArgumentException("Bad % encoding: "+this); - if (_raw[i+1]=='u') - { - if ((i+5)>=_param) - throw new IllegalArgumentException("Bad %u encoding: "+this); - - try - { - String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16))); - byte[] encoded = unicode.getBytes(encoding); - System.arraycopy(encoded,0,bytes,n,encoded.length); - n+=encoded.length; - i+=5; - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - else - { - b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16)); - bytes[n++]=b; - i+=2; - } - continue; - } - else if (bytes==null) - { - n++; - continue; - } - - bytes[n++]=b; - } - - - if (bytes==null) - return StringUtil.toString(_raw,_path,_param-_path,encoding); - - return StringUtil.toString(bytes,0,n,encoding); - } - - - - - - - - public String getPathAndParam() - { - if (_path==_query) - return null; - return toUtf8String(_path,_query-_path); - } - - public String getCompletePath() - { - if (_path==_end) - return null; - return toUtf8String(_path,_end-_path); - } - - public String getParam() - { - if (_param==_query) - return null; - return toUtf8String(_param+1,_query-_param-1); - } - - public String getQuery() - { - if (_query==_fragment) - return null; - return toUtf8String(_query+1,_fragment-_query-1); - } - - public String getQuery(String encoding) - { - if (_query==_fragment) - return null; - return StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding); - } - - public boolean hasQuery() - { - return (_fragment>_query); - } - - public String getFragment() - { - if (_fragment==_end) - return null; - return toUtf8String(_fragment+1,_end-_fragment-1); - } - - public void decodeQueryTo(MultiMap parameters) - { - if (_query==_fragment) - return; - _utf8b.reset(); - UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b); - } - - public void decodeQueryTo(MultiMap parameters, String encoding) - throws UnsupportedEncodingException - { - if (_query==_fragment) - return; - - if (encoding==null || StringUtil.isUTF8(encoding)) - UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters); - else - UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding); - } - - public void clear() - { - _scheme=_authority=_host=_port=_path=_param=_query=_fragment=_end=0; - _raw=__empty; - _rawString=""; - _encoded=false; - } - - @Override - public String toString() - { - if (_rawString==null) - _rawString=toUtf8String(_scheme,_end-_scheme); - return _rawString; - } - - public void writeTo(Utf8StringBuilder buf) - { - buf.append(_raw,_scheme,_end-_scheme); - } - -}
--- a/src/org/eclipse/jetty/http/HttpVersions.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.StringCache; - - -public final class HttpVersions -{ - public final static String - HTTP_0_9 = "", - HTTP_1_0 = "HTTP/1.0", - HTTP_1_1 = "HTTP/1.1"; - - public final static int - HTTP_0_9_ORDINAL=9, - HTTP_1_0_ORDINAL=10, - HTTP_1_1_ORDINAL=11; - - public final static StringCache CACHE = new StringCache(); - - public final static byte[] - HTTP_0_9_BYTES=CACHE.add(HTTP_0_9,HTTP_0_9_ORDINAL), - HTTP_1_0_BYTES=CACHE.add(HTTP_1_0,HTTP_1_0_ORDINAL), - HTTP_1_1_BYTES=CACHE.add(HTTP_1_1,HTTP_1_1_ORDINAL); -}
--- a/src/org/eclipse/jetty/http/MimeTypes.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,332 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -import org.eclipse.jetty.io.StringCache; -import org.eclipse.jetty.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public final class MimeTypes -{ - private static final Logger LOG = LoggerFactory.getLogger(MimeTypes.class); - - public final static String - FORM_ENCODED="application/x-www-form-urlencoded", - MESSAGE_HTTP="message/http", - MULTIPART_BYTERANGES="multipart/byteranges", - - TEXT_HTML="text/html", - TEXT_PLAIN="text/plain", - TEXT_XML="text/xml", - TEXT_JSON="text/json", - - TEXT_HTML_8859_1="text/html;charset=ISO-8859-1", - TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1", - TEXT_XML_8859_1="text/xml;charset=ISO-8859-1", - - TEXT_HTML_UTF_8="text/html;charset=UTF-8", - TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8", - TEXT_XML_UTF_8="text/xml;charset=UTF-8", - TEXT_JSON_UTF_8="text/json;charset=UTF-8"; - - private final static String - TEXT_HTML__8859_1="text/html; charset=ISO-8859-1", - TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1", - TEXT_XML__8859_1="text/xml; charset=ISO-8859-1", - TEXT_HTML__UTF_8="text/html; charset=UTF-8", - TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8", - TEXT_XML__UTF_8="text/xml; charset=UTF-8", - TEXT_JSON__UTF_8="text/json; charset=UTF-8"; - - private final static int - FORM_ENCODED_ORDINAL=1, - MESSAGE_HTTP_ORDINAL=2, - MULTIPART_BYTERANGES_ORDINAL=3, - - TEXT_HTML_ORDINAL=4, - TEXT_PLAIN_ORDINAL=5, - TEXT_XML_ORDINAL=6, - TEXT_JSON_ORDINAL=7, - - TEXT_HTML_8859_1_ORDINAL=8, - TEXT_PLAIN_8859_1_ORDINAL=9, - TEXT_XML_8859_1_ORDINAL=10, - - TEXT_HTML_UTF_8_ORDINAL=11, - TEXT_PLAIN_UTF_8_ORDINAL=12, - TEXT_XML_UTF_8_ORDINAL=13, - TEXT_JSON_UTF_8_ORDINAL=14; - - private static int __index=15; - - public final static StringCache CACHE = new StringCache(); - - public final static byte[] - FORM_ENCODED_BYTES=CACHE.add(FORM_ENCODED,FORM_ENCODED_ORDINAL), - MESSAGE_HTTP_BYTES=CACHE.add(MESSAGE_HTTP, MESSAGE_HTTP_ORDINAL), - MULTIPART_BYTERANGES_BYTES=CACHE.add(MULTIPART_BYTERANGES,MULTIPART_BYTERANGES_ORDINAL), - - TEXT_HTML_BYTES=CACHE.add(TEXT_HTML,TEXT_HTML_ORDINAL), - TEXT_PLAIN_BYTES=CACHE.add(TEXT_PLAIN,TEXT_PLAIN_ORDINAL), - TEXT_XML_BYTES=CACHE.add(TEXT_XML,TEXT_XML_ORDINAL), - TEXT_JSON_BYTES=CACHE.add(TEXT_JSON,TEXT_JSON_ORDINAL), - - TEXT_HTML_8859_1_BYTES=CACHE.add(TEXT_HTML_8859_1,TEXT_HTML_8859_1_ORDINAL), - TEXT_PLAIN_8859_1_BYTES=CACHE.add(TEXT_PLAIN_8859_1,TEXT_PLAIN_8859_1_ORDINAL), - TEXT_XML_8859_1_BYTES=CACHE.add(TEXT_XML_8859_1,TEXT_XML_8859_1_ORDINAL), - - TEXT_HTML_UTF_8_BYTES=CACHE.add(TEXT_HTML_UTF_8,TEXT_HTML_UTF_8_ORDINAL), - TEXT_PLAIN_UTF_8_BYTES=CACHE.add(TEXT_PLAIN_UTF_8,TEXT_PLAIN_UTF_8_ORDINAL), - TEXT_XML_UTF_8_BYTES=CACHE.add(TEXT_XML_UTF_8,TEXT_XML_UTF_8_ORDINAL), - TEXT_JSON_UTF_8_BYTES=CACHE.add(TEXT_JSON_UTF_8,TEXT_JSON_UTF_8_ORDINAL), - - TEXT_HTML__8859_1_BYTES=CACHE.add(TEXT_HTML__8859_1,TEXT_HTML_8859_1_ORDINAL), - TEXT_PLAIN__8859_1_BYTES=CACHE.add(TEXT_PLAIN__8859_1,TEXT_PLAIN_8859_1_ORDINAL), - TEXT_XML__8859_1_BYTES=CACHE.add(TEXT_XML__8859_1,TEXT_XML_8859_1_ORDINAL), - - TEXT_HTML__UTF_8_BYTES=CACHE.add(TEXT_HTML__UTF_8,TEXT_HTML_UTF_8_ORDINAL), - TEXT_PLAIN__UTF_8_BYTES=CACHE.add(TEXT_PLAIN__UTF_8,TEXT_PLAIN_UTF_8_ORDINAL), - TEXT_XML__UTF_8_BYTES=CACHE.add(TEXT_XML__UTF_8,TEXT_XML_UTF_8_ORDINAL), - TEXT_JSON__UTF_8_BYTES=CACHE.add(TEXT_JSON__UTF_8,TEXT_JSON_UTF_8_ORDINAL); - - - private final static Map<String,String> __dftMimeMap = new HashMap<String,String>(); - private final static Map<String,String> __encodings = new HashMap<String,String>(); - static - { - try - { - ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime"); - Enumeration i = mime.getKeys(); - while(i.hasMoreElements()) - { - String ext = (String)i.nextElement(); - String m = mime.getString(ext); -// __dftMimeMap.put(ext.toLowerCase(),normalizeMimeType(m)); - __dftMimeMap.put(ext.toLowerCase(),m); - } - } - catch(MissingResourceException e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - } - - __encodings.put("text/html","ISO-8859-1"); - __encodings.put("text/plain","ISO-8859-1"); - __encodings.put("text/xml","UTF-8"); - __encodings.put("text/json","UTF-8"); - -/* - TEXT_HTML_BUFFER.setAssociate("ISO-8859-1",TEXT_HTML_8859_1_BUFFER); - TEXT_HTML_BUFFER.setAssociate("ISO_8859_1",TEXT_HTML_8859_1_BUFFER); - TEXT_HTML_BUFFER.setAssociate("iso-8859-1",TEXT_HTML_8859_1_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("ISO-8859-1",TEXT_PLAIN_8859_1_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("ISO_8859_1",TEXT_PLAIN_8859_1_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("iso-8859-1",TEXT_PLAIN_8859_1_BUFFER); - TEXT_XML_BUFFER.setAssociate("ISO-8859-1",TEXT_XML_8859_1_BUFFER); - TEXT_XML_BUFFER.setAssociate("ISO_8859_1",TEXT_XML_8859_1_BUFFER); - TEXT_XML_BUFFER.setAssociate("iso-8859-1",TEXT_XML_8859_1_BUFFER); - - TEXT_HTML_BUFFER.setAssociate("UTF-8",TEXT_HTML_UTF_8_BUFFER); - TEXT_HTML_BUFFER.setAssociate("UTF8",TEXT_HTML_UTF_8_BUFFER); - TEXT_HTML_BUFFER.setAssociate("utf8",TEXT_HTML_UTF_8_BUFFER); - TEXT_HTML_BUFFER.setAssociate("utf-8",TEXT_HTML_UTF_8_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("UTF-8",TEXT_PLAIN_UTF_8_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("UTF8",TEXT_PLAIN_UTF_8_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("utf8",TEXT_PLAIN_UTF_8_BUFFER); - TEXT_PLAIN_BUFFER.setAssociate("utf-8",TEXT_PLAIN_UTF_8_BUFFER); - TEXT_XML_BUFFER.setAssociate("UTF-8",TEXT_XML_UTF_8_BUFFER); - TEXT_XML_BUFFER.setAssociate("UTF8",TEXT_XML_UTF_8_BUFFER); - TEXT_XML_BUFFER.setAssociate("utf8",TEXT_XML_UTF_8_BUFFER); - TEXT_XML_BUFFER.setAssociate("utf-8",TEXT_XML_UTF_8_BUFFER); - TEXT_JSON_BUFFER.setAssociate("UTF-8",TEXT_JSON_UTF_8_BUFFER); - TEXT_JSON_BUFFER.setAssociate("UTF8",TEXT_JSON_UTF_8_BUFFER); - TEXT_JSON_BUFFER.setAssociate("utf8",TEXT_JSON_UTF_8_BUFFER); - TEXT_JSON_BUFFER.setAssociate("utf-8",TEXT_JSON_UTF_8_BUFFER); -*/ - } - - // replace setAssociate() - - private static final Map<String,String> association = new HashMap<String,String>(); - - private static String key(String type,String charEncoding) { - return (type+'~'+charEncoding).toLowerCase(); - } - - private static void setAssociate(String type,String charEncoding,String result) { - association.put( key(type,charEncoding), result ); - } - - public static String getAssociate(String type,String charEncoding) { - return association.get( key(type,charEncoding) ); - } - - static { - setAssociate(TEXT_HTML,"ISO-8859-1",TEXT_HTML_8859_1); - setAssociate(TEXT_HTML,"ISO_8859_1",TEXT_HTML_8859_1); - setAssociate(TEXT_PLAIN,"ISO-8859-1",TEXT_PLAIN_8859_1); - setAssociate(TEXT_PLAIN,"ISO_8859_1",TEXT_PLAIN_8859_1); - setAssociate(TEXT_XML,"ISO-8859-1",TEXT_XML_8859_1); - setAssociate(TEXT_XML,"ISO_8859_1",TEXT_XML_8859_1); - - setAssociate(TEXT_HTML,"UTF-8",TEXT_HTML_UTF_8); - setAssociate(TEXT_HTML,"UTF8",TEXT_HTML_UTF_8); - setAssociate(TEXT_PLAIN,"UTF-8",TEXT_PLAIN_UTF_8); - setAssociate(TEXT_PLAIN,"UTF8",TEXT_PLAIN_UTF_8); - setAssociate(TEXT_XML,"UTF-8",TEXT_XML_UTF_8); - setAssociate(TEXT_XML,"UTF8",TEXT_XML_UTF_8); - setAssociate(TEXT_JSON,"UTF-8",TEXT_JSON_UTF_8); - setAssociate(TEXT_JSON,"UTF8",TEXT_JSON_UTF_8); - } - - - - /* ------------------------------------------------------------ */ - /** Get the MIME type by filename extension. - * @param filename A file name - * @return MIME type matching the longest dot extension of the - * file name. - */ - public String getMimeByExtension(String filename) - { - String type=null; - - if (filename!=null) - { - int i=-1; - while(type==null) - { - i=filename.indexOf(".",i+1); - - if (i<0 || i>=filename.length()) - break; - - String ext = filename.substring(i+1).toLowerCase(); - type = __dftMimeMap.get(ext); - } - } - - if (type==null) - { - type = __dftMimeMap.get("*"); - } - - return type; - } -/* - private static synchronized Buffer normalizeMimeType(String type) - { - Buffer b = CACHE.get(type); - if (b==null) - b = CACHE.add(type,__index++); - return b; - } -*/ - public static String getCharsetFromContentType(String value) - { - switch(CACHE.getOrdinal(value)) - { - case TEXT_HTML_8859_1_ORDINAL: - case TEXT_PLAIN_8859_1_ORDINAL: - case TEXT_XML_8859_1_ORDINAL: - return StringUtil.__ISO_8859_1; - - case TEXT_HTML_UTF_8_ORDINAL: - case TEXT_PLAIN_UTF_8_ORDINAL: - case TEXT_XML_UTF_8_ORDINAL: - case TEXT_JSON_UTF_8_ORDINAL: - return StringUtil.__UTF8; - } - - int i = 0; - int end = value.length(); - int state=0; - int start=0; - boolean quote=false; - for (;i<end;i++) - { - char b = value.charAt(i); - - if (quote && state!=10) - { - if ('"'==b) - quote=false; - continue; - } - - switch(state) - { - case 0: - if ('"'==b) - { - quote=true; - break; - } - if (';'==b) - state=1; - break; - - case 1: if ('c'==b) state=2; else if (' '!=b) state=0; break; - case 2: if ('h'==b) state=3; else state=0;break; - case 3: if ('a'==b) state=4; else state=0;break; - case 4: if ('r'==b) state=5; else state=0;break; - case 5: if ('s'==b) state=6; else state=0;break; - case 6: if ('e'==b) state=7; else state=0;break; - case 7: if ('t'==b) state=8; else state=0;break; - - case 8: if ('='==b) state=9; else if (' '!=b) state=0; break; - - case 9: - if (' '==b) - break; - if ('"'==b) - { - quote=true; - start=i+1; - state=10; - break; - } - start=i; - state=10; - break; - - case 10: - if (!quote && (';'==b || ' '==b )|| - (quote && '"'==b )) - return value.substring(start,i); - } - } - - if (state==10) - return value.substring(start,i); - - return __encodings.get(value.toLowerCase()); - } -}
--- a/src/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.gzip; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.zip.DeflaterOutputStream; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.util.ByteArrayOutputStream2; - -/* ------------------------------------------------------------ */ -/** - * Skeletal implementation of a CompressedStream. This class adds compression features to a ServletOutputStream and takes care of setting response headers, etc. - * Major work and configuration is done here. Subclasses using different kinds of compression only have to implement the abstract methods doCompress() and - * setContentEncoding() using the desired compression and setting the appropriate Content-Encoding header string. - */ -public abstract class AbstractCompressedStream extends ServletOutputStream -{ - private final String _encoding; - protected final String _vary; - protected final CompressedResponseWrapper _wrapper; - protected final HttpServletResponse _response; - protected OutputStream _out; - protected ByteArrayOutputStream2 _bOut; - protected DeflaterOutputStream _compressedOutputStream; - protected boolean _closed; - protected boolean _doNotCompress; - - /** - * Instantiates a new compressed stream. - * - */ - public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper,String vary) - throws IOException - { - _encoding=encoding; - _wrapper = wrapper; - _response = (HttpServletResponse)wrapper.getResponse(); - _vary=vary; - - if (_wrapper.getMinCompressSize()==0) - doCompress(); - } - - /* ------------------------------------------------------------ */ - /** - * Reset buffer. - */ - public void resetBuffer() - { - if (_response.isCommitted() || _compressedOutputStream!=null ) - throw new IllegalStateException("Committed"); - _closed = false; - _out = null; - _bOut = null; - _doNotCompress = false; - } - - /* ------------------------------------------------------------ */ - public void setBufferSize(int bufferSize) - { - if (_bOut!=null && _bOut.getBuf().length<bufferSize) - { - ByteArrayOutputStream2 b = new ByteArrayOutputStream2(bufferSize); - b.write(_bOut.getBuf(),0,_bOut.size()); - _bOut=b; - } - } - - /* ------------------------------------------------------------ */ - public void setContentLength() - { - if (_doNotCompress) - { - long length=_wrapper.getContentLength(); - if (length>=0) - { - if (length < Integer.MAX_VALUE) - _response.setContentLength((int)length); - else - _response.setHeader("Content-Length",Long.toString(length)); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#flush() - */ - @Override - public void flush() throws IOException - { - if (_out == null || _bOut != null) - { - long length=_wrapper.getContentLength(); - if (length > 0 && length < _wrapper.getMinCompressSize()) - doNotCompress(false); - else - doCompress(); - } - - _out.flush(); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#close() - */ - @Override - public void close() throws IOException - { - if (_closed) - return; - - if (_wrapper.getRequest().getAttribute("javax.servlet.include.request_uri") != null) - flush(); - else - { - if (_bOut != null) - { - long length=_wrapper.getContentLength(); - if (length < 0) - { - length = _bOut.getCount(); - _wrapper.setContentLength(length); - } - if (length < _wrapper.getMinCompressSize()) - doNotCompress(false); - else - doCompress(); - } - else if (_out == null) - { - // No output - doNotCompress(false); - } - - if (_compressedOutputStream != null) - _compressedOutputStream.close(); - else - _out.close(); - _closed = true; - } - } - - /** - * Finish. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void finish() throws IOException - { - if (!_closed) - { - if (_out == null || _bOut != null) - { - long length=_wrapper.getContentLength(); - if (length >= 0 && length < _wrapper.getMinCompressSize()) - doNotCompress(false); - else - doCompress(); - } - - if (_compressedOutputStream != null && !_closed) - { - _closed = true; - _compressedOutputStream.close(); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(int) - */ - @Override - public void write(int b) throws IOException - { - checkOut(1); - _out.write(b); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(byte[]) - */ - @Override - public void write(byte b[]) throws IOException - { - checkOut(b.length); - _out.write(b); - } - - /* ------------------------------------------------------------ */ - /** - * @see java.io.OutputStream#write(byte[], int, int) - */ - @Override - public void write(byte b[], int off, int len) throws IOException - { - checkOut(len); - _out.write(b,off,len); - } - - /** - * Do compress. - * - * @throws IOException Signals that an I/O exception has occurred. - */ - public void doCompress() throws IOException - { - if (_compressedOutputStream==null) - { - if (_response.isCommitted()) - throw new IllegalStateException(); - - if (_encoding!=null) - { - setHeader("Content-Encoding", _encoding); - if (_response.containsHeader("Content-Encoding")) - { - addHeader("Vary",_vary); - _out=_compressedOutputStream=createStream(); - if (_out!=null) - { - if (_bOut!=null) - { - _out.write(_bOut.getBuf(),0,_bOut.getCount()); - _bOut=null; - } - - String etag=_wrapper.getETag(); - if (etag!=null) - setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"'); - return; - } - } - } - - doNotCompress(true); // Send vary as it could have been compressed if encoding was present - } - } - - /** - * Do not compress. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void doNotCompress(boolean sendVary) throws IOException - { - if (_compressedOutputStream != null) - throw new IllegalStateException("Compressed output stream is already assigned."); - if (_out == null || _bOut != null) - { - if (sendVary) - addHeader("Vary",_vary); - if (_wrapper.getETag()!=null) - setHeader("ETag",_wrapper.getETag()); - - _doNotCompress = true; - - _out = _response.getOutputStream(); - setContentLength(); - - if (_bOut != null) - _out.write(_bOut.getBuf(),0,_bOut.getCount()); - _bOut = null; - } - } - - /** - * Check out. - * - * @param lengthToWrite - * the length - * @throws IOException - * Signals that an I/O exception has occurred. - */ - private void checkOut(int lengthToWrite) throws IOException - { - if (_closed) - throw new IOException("CLOSED"); - - if (_out == null) - { - // If this first write is larger than buffer size, then we are committing now - if (lengthToWrite>_wrapper.getBufferSize()) - { - // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress - long length=_wrapper.getContentLength(); - if (length>=0 && length<_wrapper.getMinCompressSize()) - doNotCompress(false); // Not compressing by size, so no vary on request headers - else - doCompress(); - } - else - { - // start aggregating writes into a buffered output stream - _out = _bOut = new ByteArrayOutputStream2(_wrapper.getBufferSize()); - } - } - // else are we aggregating writes? - else if (_bOut !=null) - { - // We are aggregating into the buffered output stream. - - // If this write fills the buffer, then we are committing - if (lengthToWrite>=(_bOut.getBuf().length - _bOut.getCount())) - { - // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress - long length=_wrapper.getContentLength(); - if (length>=0 && length<_wrapper.getMinCompressSize()) - doNotCompress(false); // Not compressing by size, so no vary on request headers - else - doCompress(); - } - } - } - - /** - * @see org.eclipse.jetty.http.gzip.CompressedStream#getOutputStream() - */ - public OutputStream getOutputStream() - { - return _out; - } - - /** - * @see org.eclipse.jetty.http.gzip.CompressedStream#isClosed() - */ - public boolean isClosed() - { - return _closed; - } - - /** - * Allows derived implementations to replace PrintWriter implementation. - */ - protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException - { - return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); - } - - protected void addHeader(String name,String value) - { - _response.addHeader(name, value); - } - - protected void setHeader(String name,String value) - { - _response.setHeader(name, value); - } - - /** - * Create the stream fitting to the underlying compression type. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - protected abstract DeflaterOutputStream createStream() throws IOException; - - -}
--- a/src/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,487 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.gzip; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.Set; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.eclipse.jetty.util.StringUtil; - -/*------------------------------------------------------------ */ -/** - */ -public abstract class CompressedResponseWrapper extends HttpServletResponseWrapper -{ - - public static final int DEFAULT_BUFFER_SIZE = 8192; - public static final int DEFAULT_MIN_COMPRESS_SIZE = 256; - - private Set<String> _mimeTypes; - private int _bufferSize=DEFAULT_BUFFER_SIZE; - private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE; - protected HttpServletRequest _request; - - private PrintWriter _writer; - private AbstractCompressedStream _compressedStream; - private String _etag; - private long _contentLength=-1; - private boolean _noCompression; - - /* ------------------------------------------------------------ */ - public CompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response) - { - super(response); - _request = request; - } - - - /* ------------------------------------------------------------ */ - public long getContentLength() - { - return _contentLength; - } - - /* ------------------------------------------------------------ */ - public int getBufferSize() - { - return _bufferSize; - } - - /* ------------------------------------------------------------ */ - public int getMinCompressSize() - { - return _minCompressSize; - } - - /* ------------------------------------------------------------ */ - public String getETag() - { - return _etag; - } - - /* ------------------------------------------------------------ */ - public HttpServletRequest getRequest() - { - return _request; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) - */ - public void setMimeTypes(Set<String> mimeTypes) - { - _mimeTypes = mimeTypes; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int) - */ - @Override - public void setBufferSize(int bufferSize) - { - _bufferSize = bufferSize; - if (_compressedStream!=null) - _compressedStream.setBufferSize(bufferSize); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int) - */ - public void setMinCompressSize(int minCompressSize) - { - _minCompressSize = minCompressSize; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String) - */ - @Override - public void setContentType(String ct) - { - super.setContentType(ct); - - if (!_noCompression) - { - if (ct!=null) - { - int colon=ct.indexOf(";"); - if (colon>0) - ct=ct.substring(0,colon); - } - - if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && - (_mimeTypes==null && ct!=null && ct.contains("gzip") || - _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) - { - noCompression(); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) - */ - @Override - public void setStatus(int sc, String sm) - { - super.setStatus(sc,sm); - if (sc<200 || sc==204 || sc==205 || sc>=300) - noCompression(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int) - */ - @Override - public void setStatus(int sc) - { - super.setStatus(sc); - if (sc<200 || sc==204 || sc==205 || sc>=300) - noCompression(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int) - */ - @Override - public void setContentLength(int length) - { - if (_noCompression) - super.setContentLength(length); - else - setContentLength((long)length); - } - - /* ------------------------------------------------------------ */ - protected void setContentLength(long length) - { - _contentLength=length; - if (_compressedStream!=null) - _compressedStream.setContentLength(); - else if (_noCompression && _contentLength>=0) - { - HttpServletResponse response = (HttpServletResponse)getResponse(); - if(_contentLength<Integer.MAX_VALUE) - { - response.setContentLength((int)_contentLength); - } - else - { - response.setHeader("Content-Length", Long.toString(_contentLength)); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String) - */ - @Override - public void addHeader(String name, String value) - { - if ("content-length".equalsIgnoreCase(name)) - { - _contentLength=Long.parseLong(value); - if (_compressedStream!=null) - _compressedStream.setContentLength(); - } - else if ("content-type".equalsIgnoreCase(name)) - { - setContentType(value); - } - else if ("content-encoding".equalsIgnoreCase(name)) - { - super.addHeader(name,value); - if (!isCommitted()) - { - noCompression(); - } - } - else if ("etag".equalsIgnoreCase(name)) - _etag=value; - else - super.addHeader(name,value); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#flushBuffer() - */ - @Override - public void flushBuffer() throws IOException - { - if (_writer!=null) - _writer.flush(); - if (_compressedStream!=null) - _compressedStream.flush(); - else - getResponse().flushBuffer(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#reset() - */ - @Override - public void reset() - { - super.reset(); - if (_compressedStream!=null) - _compressedStream.resetBuffer(); - _writer=null; - _compressedStream=null; - _noCompression=false; - _contentLength=-1; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#resetBuffer() - */ - @Override - public void resetBuffer() - { - super.resetBuffer(); - if (_compressedStream!=null) - _compressedStream.resetBuffer(); - _writer=null; - _compressedStream=null; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int, java.lang.String) - */ - @Override - public void sendError(int sc, String msg) throws IOException - { - resetBuffer(); - super.sendError(sc,msg); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int) - */ - @Override - public void sendError(int sc) throws IOException - { - resetBuffer(); - super.sendError(sc); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String) - */ - @Override - public void sendRedirect(String location) throws IOException - { - resetBuffer(); - super.sendRedirect(location); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#noCompression() - */ - public void noCompression() - { - if (!_noCompression) - setDeferredHeaders(); - _noCompression=true; - if (_compressedStream!=null) - { - try - { - _compressedStream.doNotCompress(false); - } - catch (IOException e) - { - throw new IllegalStateException(e); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#finish() - */ - public void finish() throws IOException - { - if (_writer!=null && !_compressedStream.isClosed()) - _writer.flush(); - if (_compressedStream!=null) - _compressedStream.finish(); - else - setDeferredHeaders(); - } - - /* ------------------------------------------------------------ */ - private void setDeferredHeaders() - { - if (!isCommitted()) - { - if (_contentLength>=0) - { - if (_contentLength < Integer.MAX_VALUE) - super.setContentLength((int)_contentLength); - else - super.setHeader("Content-Length",Long.toString(_contentLength)); - } - if(_etag!=null) - super.setHeader("ETag",_etag); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String) - */ - @Override - public void setHeader(String name, String value) - { - if (_noCompression) - super.setHeader(name,value); - else if ("content-length".equalsIgnoreCase(name)) - { - setContentLength(Long.parseLong(value)); - } - else if ("content-type".equalsIgnoreCase(name)) - { - setContentType(value); - } - else if ("content-encoding".equalsIgnoreCase(name)) - { - super.setHeader(name,value); - if (!isCommitted()) - { - noCompression(); - } - } - else if ("etag".equalsIgnoreCase(name)) - _etag=value; - else - super.setHeader(name,value); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean containsHeader(String name) - { - if (!_noCompression && "etag".equalsIgnoreCase(name) && _etag!=null) - return true; - return super.containsHeader(name); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getOutputStream() - */ - @Override - public ServletOutputStream getOutputStream() throws IOException - { - if (_compressedStream==null) - { - if (getResponse().isCommitted() || _noCompression) - return getResponse().getOutputStream(); - - _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse()); - } - else if (_writer!=null) - throw new IllegalStateException("getWriter() called"); - - return _compressedStream; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getWriter() - */ - @Override - public PrintWriter getWriter() throws IOException - { - if (_writer==null) - { - if (_compressedStream!=null) - throw new IllegalStateException("getOutputStream() called"); - - if (getResponse().isCommitted() || _noCompression) - return getResponse().getWriter(); - - _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse()); - _writer=newWriter(_compressedStream,getCharacterEncoding()); - } - return _writer; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int) - */ - @Override - public void setIntHeader(String name, int value) - { - if ("content-length".equalsIgnoreCase(name)) - { - _contentLength=value; - if (_compressedStream!=null) - _compressedStream.setContentLength(); - } - else - super.setIntHeader(name,value); - } - - /* ------------------------------------------------------------ */ - /** - * Allows derived implementations to replace PrintWriter implementation. - * - * @param out the out - * @param encoding the encoding - * @return the prints the writer - * @throws UnsupportedEncodingException the unsupported encoding exception - */ - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); - } - - /* ------------------------------------------------------------ */ - /** - *@return the underlying CompressedStream implementation - */ - protected abstract AbstractCompressedStream newCompressedStream(HttpServletRequest _request, HttpServletResponse response) throws IOException; - -}
--- a/src/org/eclipse/jetty/http/mime.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -ai = application/postscript -aif = audio/x-aiff -aifc = audio/x-aiff -aiff = audio/x-aiff -apk = application/vnd.android.package-archive -asc = text/plain -asf = video/x.ms.asf -asx = video/x.ms.asx -au = audio/basic -avi = video/x-msvideo -bcpio = application/x-bcpio -bin = application/octet-stream -cab = application/x-cabinet -cdf = application/x-netcdf -class = application/java-vm -cpio = application/x-cpio -cpt = application/mac-compactpro -crt = application/x-x509-ca-cert -csh = application/x-csh -css = text/css -csv = text/comma-separated-values -dcr = application/x-director -dir = application/x-director -dll = application/x-msdownload -dms = application/octet-stream -doc = application/msword -dtd = application/xml-dtd -dvi = application/x-dvi -dxr = application/x-director -eps = application/postscript -etx = text/x-setext -exe = application/octet-stream -ez = application/andrew-inset -gif = image/gif -gtar = application/x-gtar -gz = application/gzip -gzip = application/gzip -hdf = application/x-hdf -hqx = application/mac-binhex40 -htc = text/x-component -htm = text/html -html = text/html -ice = x-conference/x-cooltalk -ico = image/x-icon -ief = image/ief -iges = model/iges -igs = model/iges -jad = text/vnd.sun.j2me.app-descriptor -jar = application/java-archive -java = text/plain -jnlp = application/x-java-jnlp-file -jpe = image/jpeg -jpeg = image/jpeg -jpg = image/jpeg -js = application/x-javascript -jsp = text/html -kar = audio/midi -latex = application/x-latex -lha = application/octet-stream -lzh = application/octet-stream -man = application/x-troff-man -mathml = application/mathml+xml -me = application/x-troff-me -mesh = model/mesh -mid = audio/midi -midi = audio/midi -mif = application/vnd.mif -mol = chemical/x-mdl-molfile -mov = video/quicktime -movie = video/x-sgi-movie -mp2 = audio/mpeg -mp3 = audio/mpeg -mpe = video/mpeg -mpeg = video/mpeg -mpg = video/mpeg -mpga = audio/mpeg -ms = application/x-troff-ms -msh = model/mesh -msi = application/octet-stream -nc = application/x-netcdf -oda = application/oda -odb = application/vnd.oasis.opendocument.database -odc = application/vnd.oasis.opendocument.chart -odf = application/vnd.oasis.opendocument.formula -odg = application/vnd.oasis.opendocument.graphics -odi = application/vnd.oasis.opendocument.image -odm = application/vnd.oasis.opendocument.text-master -odp = application/vnd.oasis.opendocument.presentation -ods = application/vnd.oasis.opendocument.spreadsheet -odt = application/vnd.oasis.opendocument.text -ogg = application/ogg -otc = application/vnd.oasis.opendocument.chart-template -otf = application/vnd.oasis.opendocument.formula-template -otg = application/vnd.oasis.opendocument.graphics-template -oth = application/vnd.oasis.opendocument.text-web -oti = application/vnd.oasis.opendocument.image-template -otp = application/vnd.oasis.opendocument.presentation-template -ots = application/vnd.oasis.opendocument.spreadsheet-template -ott = application/vnd.oasis.opendocument.text-template -pbm = image/x-portable-bitmap -pdb = chemical/x-pdb -pdf = application/pdf -pgm = image/x-portable-graymap -pgn = application/x-chess-pgn -png = image/png -pnm = image/x-portable-anymap -ppm = image/x-portable-pixmap -pps = application/vnd.ms-powerpoint -ppt = application/vnd.ms-powerpoint -ps = application/postscript -qt = video/quicktime -ra = audio/x-pn-realaudio -ram = audio/x-pn-realaudio -ras = image/x-cmu-raster -rdf = application/rdf+xml -rgb = image/x-rgb -rm = audio/x-pn-realaudio -roff = application/x-troff -rpm = application/x-rpm -rtf = application/rtf -rtx = text/richtext -rv = video/vnd.rn-realvideo -ser = application/java-serialized-object -sgm = text/sgml -sgml = text/sgml -sh = application/x-sh -shar = application/x-shar -silo = model/mesh -sit = application/x-stuffit -skd = application/x-koan -skm = application/x-koan -skp = application/x-koan -skt = application/x-koan -smi = application/smil -smil = application/smil -snd = audio/basic -spl = application/x-futuresplash -src = application/x-wais-source -sv4cpio = application/x-sv4cpio -sv4crc = application/x-sv4crc -svg = image/svg+xml -swf = application/x-shockwave-flash -t = application/x-troff -tar = application/x-tar -tar.gz = application/x-gtar -tcl = application/x-tcl -tex = application/x-tex -texi = application/x-texinfo -texinfo = application/x-texinfo -tgz = application/x-gtar -tif = image/tiff -tiff = image/tiff -tr = application/x-troff -tsv = text/tab-separated-values -txt = text/plain -ustar = application/x-ustar -vcd = application/x-cdlink -vrml = model/vrml -vxml = application/voicexml+xml -wav = audio/x-wav -wbmp = image/vnd.wap.wbmp -wml = text/vnd.wap.wml -wmlc = application/vnd.wap.wmlc -wmls = text/vnd.wap.wmlscript -wmlsc = application/vnd.wap.wmlscriptc -wrl = model/vrml -wtls-ca-certificate = application/vnd.wap.wtls-ca-certificate -xbm = image/x-xbitmap -xht = application/xhtml+xml -xhtml = application/xhtml+xml -xls = application/vnd.ms-excel -xml = application/xml -xpm = image/x-xpixmap -xsd = application/xml -xsl = application/xml -xslt = application/xslt+xml -xul = application/vnd.mozilla.xul+xml -xwd = image/x-xwindowdump -xyz = chemical/x-xyz -z = application/compress -zip = application/zip
--- a/src/org/eclipse/jetty/http/ssl/SslContextFactory.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.ssl; - -/* ------------------------------------------------------------ */ -/** - * @deprecated Use org.eclipse.jetty.util.ssl.SslContextFactory - */ -public class SslContextFactory extends org.eclipse.jetty.util.ssl.SslContextFactory -{ - public SslContextFactory() - { - super(); - } - - public SslContextFactory(boolean trustAll) - { - super(trustAll); - } - - public SslContextFactory(String keyStorePath) - { - super(keyStorePath); - } -}
--- a/src/org/eclipse/jetty/io/AbstractConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public abstract class AbstractConnection implements Connection -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractConnection.class); - - public final EndPoint _endp; - - protected AbstractConnection(EndPoint endp) - { - _endp = endp; - } -}
--- a/src/org/eclipse/jetty/io/AsyncEndPoint.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - - -public interface AsyncEndPoint extends EndPoint -{ - /* ------------------------------------------------------------ */ - /** - * Dispatch the endpoint if it is not already dispatched - * - */ - public void dispatch(); - - /* ------------------------------------------------------------ */ - /** - * @return True if IO has been successfully performed since the last call to {@link #hasProgressed()} - */ - public boolean hasProgressed(); -}
--- a/src/org/eclipse/jetty/io/BufferUtil.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import org.eclipse.jetty.util.StringUtil; - - -/* ------------------------------------------------------------------------------- */ -/** Buffer utility methods. - * - * - */ -public final class BufferUtil -{ - private static final byte[] DIGIT= - {(byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7',(byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F'}; - - - /** - * Convert string to an long. - * Parses up to the first non-numeric character. If no number is found an - * IllegalArgumentException is thrown - */ - public static long toLong(String s) - { - long val = 0; - boolean started= false; - boolean minus= false; - for (int i = 0; i < s.length(); i++) - { - char c = s.charAt(i); - if (c <= ' ') - { - if (started) - break; - } - else if (c >= '0' && c <= '9') - { - val= val * 10L + (c - '0'); - started= true; - } - else if (c == '-' && !started) - { - minus= true; - } - else - break; - } - - if (started) - return minus ? (-val) : val; - throw new NumberFormatException(s); - } - - public static void putHexInt(ByteBuffer buffer, int n) - { - - if (n < 0) - { - buffer.put((byte)'-'); - - if (n == Integer.MIN_VALUE) - { - buffer.put((byte)(0x7f&'8')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - buffer.put((byte)(0x7f&'0')); - - return; - } - n= -n; - } - - if (n < 0x10) - { - buffer.put(DIGIT[n]); - } - else - { - boolean started= false; - // This assumes constant time int arithmatic - for (int i= 0; i < hexDivisors.length; i++) - { - if (n < hexDivisors[i]) - { - if (started) - buffer.put((byte)'0'); - continue; - } - - started= true; - int d = n / hexDivisors[i]; - buffer.put(DIGIT[d]); - n= n - d * hexDivisors[i]; - } - } - } - - public static void putDecLong(ByteBuffer buffer, long n) - { - if (n < 0) - { - buffer.put((byte)'-'); - - if (n == Long.MIN_VALUE) - { - buffer.put((byte)'9'); - n = 223372036854775808L; - } - else - n = -n; - } - - if (n < 10) - { - buffer.put(DIGIT[(int)n]); - } - else - { - boolean started= false; - // This assumes constant time int arithmatic - for (int i= 0; i < decDivisorsL.length; i++) - { - if (n < decDivisorsL[i]) - { - if (started) - buffer.put((byte)'0'); - continue; - } - - started= true; - long d= n / decDivisorsL[i]; - buffer.put(DIGIT[(int)d]); - n= n - d * decDivisorsL[i]; - } - } - } - - private final static int[] hexDivisors= - { - 0x10000000, - 0x1000000, - 0x100000, - 0x10000, - 0x1000, - 0x100, - 0x10, - 0x1 - }; - - private final static long[] decDivisorsL= - { - 1000000000000000000L, - 100000000000000000L, - 10000000000000000L, - 1000000000000000L, - 100000000000000L, - 10000000000000L, - 1000000000000L, - 100000000000L, - 10000000000L, - 1000000000L, - 100000000L, - 10000000L, - 1000000L, - 100000L, - 10000L, - 1000L, - 100L, - 10L, - 1L - }; - - - - public static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0); - - public static ByteBuffer wrap(String s) { - byte[] bytes = StringUtil.getBytes(s); - return ByteBuffer.wrap(bytes).asReadOnlyBuffer(); - } - - - - private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - - public static String getString(ByteBuffer buffer) { - byte[] bytes = new byte[buffer.remaining()]; - buffer.get(bytes); - return new String(bytes,ISO_8859_1); - } - - public static void compact(ByteBuffer buffer) { - buffer.compact(); - buffer.limit(buffer.position()); - buffer.position(0); - } -}
--- a/src/org/eclipse/jetty/io/Buffers.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.nio.ByteBuffer; - - -/* ------------------------------------------------------------ */ -/** BufferSource. - * Represents a pool or other source of buffers and abstracts the creation - * of specific types of buffers (eg NIO). The concept of big and little buffers - * is supported, but these terms have no absolute meaning and must be determined by context. - * - */ -public interface Buffers -{ - ByteBuffer getHeader(); - ByteBuffer getBuffer(); - ByteBuffer getBuffer(int size); -}
--- a/src/org/eclipse/jetty/io/Connection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; - -/* ------------------------------------------------------------ */ -/** Abstract Connection used by Jetty Connectors. - * <p> - * Jetty will call the handle method of a connection when there is work - * to be done on the connection. For blocking connections, this is soon - * as the connection is open and handle will keep being called until the - * connection is closed. For non-blocking connections, handle will only - * be called if there are bytes to be read or the connection becomes writable - * after being write blocked. - * - * @see org.eclipse.jetty.io.nio.SelectorManager - */ -public interface Connection -{ - /* ------------------------------------------------------------ */ - /** - * Handle the connection. - * @throws IOException if the handling of I/O operations fail - */ - void handle() throws IOException; -}
--- a/src/org/eclipse/jetty/io/EndPoint.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; - - -/** - * - * A transport EndPoint - */ -public interface EndPoint -{ - /** - * Shutdown any backing output stream associated with the endpoint - */ - void shutdownOutput() throws IOException; - - boolean isOutputShutdown(); - - /** - * Shutdown any backing input stream associated with the endpoint - */ - void shutdownInput() throws IOException; - - boolean isInputShutdown(); - - /** - * Close any backing stream associated with the endpoint - */ - void close() throws IOException; - - /** - * Fill the buffer from the current putIndex to it's capacity from whatever - * byte source is backing the buffer. The putIndex is increased if bytes filled. - * The buffer may chose to do a compact before filling. - * @return an <code>int</code> value indicating the number of bytes - * filled or -1 if EOF is reached. - * @throws EofException If input is shutdown or the endpoint is closed. - */ - int fill(ByteBuffer buffer) throws IOException; - - - /** - * Flush the buffer from the current getIndex to it's putIndex using whatever byte - * sink is backing the buffer. The getIndex is updated with the number of bytes flushed. - * Any mark set is cleared. - * If the entire contents of the buffer are flushed, then an implicit empty() is done. - * - * @param buffer The buffer to flush. This buffers getIndex is updated. - * @return the number of bytes written - * @throws EofException If the endpoint is closed or output is shutdown. - */ - int flush(ByteBuffer buffer) throws IOException; - - /** - * Flush the buffer from the current getIndex to it's putIndex using whatever byte - * sink is backing the buffer. The getIndex is updated with the number of bytes flushed. - * Any mark set is cleared. - * If the entire contents of the buffer are flushed, then an implicit empty() is done. - * The passed header/trailer buffers are written before/after the contents of this buffer. This may be done - * either as gather writes, as a poke into this buffer or as several writes. The implementation is free to - * select the optimal mechanism. - * @param header A buffer to write before flushing this buffer. This buffers getIndex is updated. - * @param buffer The buffer to flush. This buffers getIndex is updated. - * @param trailer A buffer to write after flushing this buffer. This buffers getIndex is updated. - * @return the total number of bytes written. - */ - int flush(ByteBuffer header, ByteBuffer buffer, ByteBuffer trailer) throws IOException; - - - /* ------------------------------------------------------------ */ - /** - * @return The local IP address to which this <code>EndPoint</code> is bound, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getLocalAddr(); - - /* ------------------------------------------------------------ */ - /** - * @return The local host name to which this <code>EndPoint</code> is bound, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getLocalHost(); - - /* ------------------------------------------------------------ */ - /** - * @return The local port number on which this <code>EndPoint</code> is listening, or <code>0</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public int getLocalPort(); - - /* ------------------------------------------------------------ */ - /** - * @return The remote IP address to which this <code>EndPoint</code> is connected, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getRemoteAddr(); - - /* ------------------------------------------------------------ */ - /** - * @return The host name of the remote machine to which this <code>EndPoint</code> is connected, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getRemoteHost(); - - /* ------------------------------------------------------------ */ - /** - * @return The remote port number to which this <code>EndPoint</code> is connected, or <code>0</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public int getRemotePort(); - - public boolean isBlocking(); - - public boolean blockReadable(long millisecs) throws IOException; - - public boolean blockWritable(long millisecs) throws IOException; - - public boolean isOpen(); - - public SocketChannel getChannel(); - - /* ------------------------------------------------------------ */ - /** Flush any buffered output. - * May fail to write all data if endpoint is non-blocking - * @throws EofException If the endpoint is closed or output is shutdown. - */ - public void flush() throws IOException; - - /* ------------------------------------------------------------ */ - /** Get the max idle time in ms. - * <p>The max idle time is the time the endpoint can be idle before - * extraordinary handling takes place. This loosely corresponds to - * the {@link java.net.Socket#getSoTimeout()} for blocking connections, - * but {@link AsyncEndPoint} implementations must use other mechanisms - * to implement the max idle time. - * @return the max idle time in ms or if ms <= 0 implies an infinite timeout - */ - public int getMaxIdleTime(); - - /* ------------------------------------------------------------ */ - /** Set the max idle time. - * @param timeMs the max idle time in MS. Timeout <= 0 implies an infinite timeout - * @throws IOException if the timeout cannot be set. - */ - public void setMaxIdleTime(int timeMs) throws IOException; - - - -}
--- a/src/org/eclipse/jetty/io/EofException.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.EOFException; - - -/* ------------------------------------------------------------ */ -/** A Jetty specialization of EOFException. - * <p> This is thrown by Jetty to distinguish between EOF received from - * the connection, vs and EOF thrown by some application talking to some other file/socket etc. - * The only difference in handling is that Jetty EOFs are logged less verbosely. - */ -public class EofException extends EOFException -{ - public EofException() - { - } - - public EofException(String reason) - { - super(reason); - } - - public EofException(Throwable th) - { - if (th!=null) - initCause(th); - } -}
--- a/src/org/eclipse/jetty/io/RuntimeIOException.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - - -package org.eclipse.jetty.io; - -/* ------------------------------------------------------------ */ -/** - * Subclass of {@link java.lang.RuntimeException} used to signal that there - * was an {@link java.io.IOException} thrown by underlying {@link java.io.Writer} - */ -public class RuntimeIOException extends RuntimeException -{ - public RuntimeIOException() - { - super(); - } - - public RuntimeIOException(String message) - { - super(message); - } - - public RuntimeIOException(Throwable cause) - { - super(cause); - } - - public RuntimeIOException(String message, Throwable cause) - { - super(message,cause); - } -}
--- a/src/org/eclipse/jetty/io/StringCache.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -// to replace BufferCache - -package org.eclipse.jetty.io; - -import java.util.Map; -import java.util.HashMap; -import java.util.TreeMap; -import org.eclipse.jetty.util.StringUtil; - - -public final class StringCache { - private final Map<String,Integer> stringToOrdinal = new HashMap<String,Integer>(); -// private final Map<Integer,String> ordinalToString = new HashMap<Integer,String>(); - private final TreeMap<String,String> stringMap = new TreeMap<String,String>(); - - public byte[] add(String value, int ordinal) { - String valueLower = value.toLowerCase(); - stringToOrdinal.put(valueLower, ordinal); -// ordinalToString.put(ordinal, value); - stringMap.put(valueLower,value); - return StringUtil.getBytes(value); - } - - public int getOrdinal(String value) { - Integer i = stringToOrdinal.get(value.toLowerCase()); - return i==null ? -1 : i; - } - - public boolean contains(String value) { - return stringToOrdinal.containsKey(value.toLowerCase()); - } - - public String get(String value) - { - return stringMap.get(value.toLowerCase()); - } - - public String getBest(String key) { - key = key.toLowerCase(); - String rtn = stringMap.get(key); - if( rtn != null ) - return rtn; - Map.Entry<String,String> floor = stringMap.floorEntry(key); - Map.Entry<String,String> ceiling = stringMap.ceilingEntry(key); - if( floor==null ) { - if( ceiling==null ) - return null; - String ceilingKey = ceiling.getKey(); - return key.charAt(0) == ceilingKey.charAt(0) ? ceiling.getValue() : null; - } else { - String floorKey = (String)floor.getKey(); - if( ceiling==null ) - return key.charAt(0) == floorKey.charAt(0) ? floor.getValue() : null; - String ceilingKey = ceiling.getKey(); - int n = Math.min( key.length(), Math.min( floorKey.length(), ceilingKey.length() ) ); - int i = 0; - while( ++i <= n && key.regionMatches(0,floorKey,0,i) && key.regionMatches(0,ceilingKey,0,i) ); - return key.regionMatches(0,floorKey,0,i) ? floor.getValue() : key.regionMatches(0,ceilingKey,0,i) || i > 1 ? ceiling.getValue() : null; - } - } - -}
--- a/src/org/eclipse/jetty/io/WriterOutputStream.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; - - -/* ------------------------------------------------------------ */ -/** Wrap a Writer as an OutputStream. - * When all you have is a Writer and only an OutputStream will do. - * Try not to use this as it indicates that your design is a dogs - * breakfast (JSP made me write it). - * - */ -public class WriterOutputStream extends OutputStream -{ - protected final Writer _writer; - protected final String _encoding; - private final byte[] _buf=new byte[1]; - - /* ------------------------------------------------------------ */ - public WriterOutputStream(Writer writer, String encoding) - { - _writer=writer; - _encoding=encoding; - } - - /* ------------------------------------------------------------ */ - public WriterOutputStream(Writer writer) - { - _writer=writer; - _encoding=null; - } - - /* ------------------------------------------------------------ */ - @Override - public void close() - throws IOException - { - _writer.close(); - } - - /* ------------------------------------------------------------ */ - @Override - public void flush() - throws IOException - { - _writer.flush(); - } - - /* ------------------------------------------------------------ */ - @Override - public void write(byte[] b) - throws IOException - { - if (_encoding==null) - _writer.write(new String(b)); - else - _writer.write(new String(b,_encoding)); - } - - /* ------------------------------------------------------------ */ - @Override - public void write(byte[] b, int off, int len) - throws IOException - { - if (_encoding==null) - _writer.write(new String(b,off,len)); - else - _writer.write(new String(b,off,len,_encoding)); - } - - /* ------------------------------------------------------------ */ - @Override - public synchronized void write(int b) - throws IOException - { - _buf[0]=(byte)b; - write(_buf); - } -} -
--- a/src/org/eclipse/jetty/io/nio/AsyncConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; - -import org.eclipse.jetty.io.Connection; - -public interface AsyncConnection extends Connection -{ - void onInputShutdown() throws IOException; - - /** - * <p>The semantic of this method is to return true to indicate interest in further reads, - * or false otherwise, but it is misnamed and should be really called <code>isReadInterested()</code>.</p> - * - * @return true to indicate interest in further reads, false otherwise - */ - // TODO: rename to isReadInterested() in the next release - boolean isSuspended(); -}
--- a/src/org/eclipse/jetty/io/nio/ChannelEndPoint.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.channels.ByteChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.SocketChannel; - -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Channel End Point. - * <p>Holds the channel and socket for an NIO endpoint. - * - */ -public class ChannelEndPoint implements EndPoint -{ - private static final Logger LOG = LoggerFactory.getLogger(ChannelEndPoint.class); - - private final SocketChannel _channel; - protected final Socket _socket; - private final InetSocketAddress _local; - private final InetSocketAddress _remote; - protected volatile int _maxIdleTime; - private volatile boolean _ishut = false; - private volatile boolean _oshut = false; - - protected ChannelEndPoint(SocketChannel channel, int maxIdleTime) throws IOException - { - this._channel = channel; - _maxIdleTime = maxIdleTime; - _socket = channel.socket(); - _local = (InetSocketAddress)_socket.getLocalSocketAddress(); - _remote = (InetSocketAddress)_socket.getRemoteSocketAddress(); - _socket.setSoTimeout(_maxIdleTime); - } - - @Override - public final boolean isBlocking() - { - return _channel.isBlocking(); - } - - @Override - public boolean blockReadable(long millisecs) throws IOException - { - return true; - } - - @Override - public boolean blockWritable(long millisecs) throws IOException - { - return true; - } - - @Override - public final boolean isOpen() - { - return _channel.isOpen(); - } - - @Override - public final void shutdownInput() throws IOException - { - LOG.debug("ishut {}", this); - _ishut = true; - if (_channel.isOpen()) - { - try - { - if (!_socket.isInputShutdown()) - { - _socket.shutdownInput(); - } - } - catch (SocketException e) - { - LOG.debug(e.toString()); - LOG.trace("",e); - } - finally - { - if (_oshut) - { - close(); - } - } - } - } - - @Override - public final void shutdownOutput() throws IOException - { - LOG.debug("oshut {}",this); - _oshut = true; - if (_channel.isOpen()) - { - try - { - if (!_socket.isOutputShutdown()) - { - _socket.shutdownOutput(); - } - } - catch (SocketException e) - { - LOG.debug(e.toString()); - LOG.trace("",e); - } - finally - { - if (_ishut) - { - close(); - } - } - } - } - - @Override - public final boolean isOutputShutdown() - { - return _oshut || !_channel.isOpen() || _socket.isOutputShutdown(); - } - - @Override - public final boolean isInputShutdown() - { - return _ishut || !_channel.isOpen() || _socket.isInputShutdown(); - } - - @Override - public void close() throws IOException - { -//Thread.dumpStack(); - LOG.debug("close {}",this); - _channel.close(); - } - - @Override - public int fill(ByteBuffer buffer) throws IOException - { - if (_ishut) - return -1; - int len = 0; - final ByteBuffer bbuf = buffer.duplicate(); - - //noinspection SynchronizationOnLocalVariableOrMethodParameter - try - { - bbuf.limit(bbuf.capacity()); - bbuf.position(buffer.limit()); - len = _channel.read(bbuf); - buffer.limit(bbuf.position()); - - if (len<0 && isOpen()) - { - if (!isInputShutdown()) - shutdownInput(); - if (isOutputShutdown()) - _channel.close(); - } - } - catch (IOException x) - { - LOG.debug("Exception while filling", x); - try - { - if (_channel.isOpen()) - _channel.close(); - } - catch (Exception xx) - { - LOG.trace("",xx); - } - - if (len>0) - throw x; - len = -1; - } - - return len; - } - - @Override - public int flush(ByteBuffer buffer) throws IOException - { - return _channel.write(buffer); - } - - @Override - public int flush(ByteBuffer header, ByteBuffer buffer, ByteBuffer trailer) throws IOException - { - int length=0; - - if (_channel instanceof GatheringByteChannel && - header!=null && header.remaining()!=0 && - buffer!=null && buffer.remaining()!=0) - { - length = gatheringFlush(header,buffer); - } - else - { - // flush header - if (header!=null && header.remaining()>0) - length=flush(header); - - // flush buffer - if ((header==null || header.remaining()==0) && - buffer!=null && buffer.remaining()>0) - length+=flush(buffer); - - // flush trailer - if ((header==null || header.remaining()==0) && - (buffer==null || buffer.remaining()==0) && - trailer!=null && trailer.remaining()>0) - length+=flush(trailer); - } - - return length; - } - - private synchronized int gatheringFlush(ByteBuffer header, ByteBuffer buffer) throws IOException - { - return (int)_channel.write(new ByteBuffer[]{header,buffer}); - } - - public final SocketChannel getChannel() - { - return _channel; - } - - @Override - public final String getLocalAddr() - { - if (_local.getAddress()==null || _local.getAddress().isAnyLocalAddress()) - return StringUtil.ALL_INTERFACES; - return _local.getAddress().getHostAddress(); - } - - @Override - public final String getLocalHost() - { - if (_local.getAddress()==null || _local.getAddress().isAnyLocalAddress()) - return StringUtil.ALL_INTERFACES; - return _local.getAddress().getCanonicalHostName(); - } - - @Override - public final int getLocalPort() - { - return _local.getPort(); - } - - @Override - public final String getRemoteAddr() - { - return _remote.getAddress().getHostAddress(); - } - - @Override - public final String getRemoteHost() - { - return _remote.getAddress().getCanonicalHostName(); - } - - @Override - public final int getRemotePort() - { - return _remote.getPort(); - } - - @Override - public void flush() - throws IOException - { - } - - @Override - public final int getMaxIdleTime() - { - return _maxIdleTime; - } - - @Override - public void setMaxIdleTime(int timeMs) throws IOException - { - if (timeMs!=_maxIdleTime) - _socket.setSoTimeout(timeMs>0?timeMs:0); - _maxIdleTime=timeMs; - } -}
--- a/src/org/eclipse/jetty/io/nio/SaneSelector.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* -Thread synchronization in java.nio.channels.Selector is completely fucked up, unsurprisingly since NIO was developed in this demented century. This class works around the modern insanity. -*/ - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.nio.channels.Selector; -import java.nio.channels.SelectionKey; -import java.nio.channels.SelectableChannel; -import java.nio.channels.ClosedChannelException; -import java.util.Set; - - -public final class SaneSelector { - private final Selector selector; - private boolean inSelect = false; - private boolean inUpdate = false; - - public SaneSelector() throws IOException { - selector = Selector.open(); - } - - public void close() throws IOException { - selector.close(); - } - - public boolean isOpen() { - return selector.isOpen(); - } - - public int select() throws IOException { - synchronized(this) { - inSelect = true; - } - try { - while(true) { - int n = selector.select(); - synchronized(this) { - boolean wasInUpdate = inUpdate; - inUpdate = false; - if( n > 0 || !wasInUpdate ) - return n; - } - } - } finally { - synchronized(this) { - inSelect = false; - } - } - } - - public Set<SelectionKey> selectedKeys() { - return selector.selectedKeys(); - } - - public Set<SelectionKey> keys() { - return selector.keys(); - } - - public synchronized SelectionKey register(SelectableChannel channel,int ops,Object att) throws ClosedChannelException { - update(); - return channel.register(selector,ops,att); - } - - public synchronized void update() { - if( inSelect ) { - inUpdate = true; - selector.wakeup(); - } - } -} \ No newline at end of file
--- a/src/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,449 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.util.Locale; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.EofException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** - * An Endpoint that can be scheduled by {@link SelectorManager}. - */ -public final class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint -{ - public static final Logger LOG=LoggerFactory.getLogger("org.eclipse.jetty.io.nio"); - - private final SelectorManager _manager; - private final SelectionKey _key; - private final Runnable _handler = new Runnable() - { - public void run() { handle(); } - }; - - /** - * The connection instance is the handler for any IO activity on the endpoint. - * There is a different type of connection for HTTP, AJP, WebSocket and - * ProxyConnect. The connection may change for an SCEP as it is upgraded - * from HTTP to proxy connect or websocket. - */ - private final AsyncConnection _connection; -/* - private static final int STATE_NEEDS_DISPATCH = -1; - private static final int STATE_UNDISPATCHED = 0; - private static final int STATE_DISPATCHED = 1; - private int _state; -*/ - private boolean isDispatched = false; - - /** true if the last write operation succeed and wrote all offered bytes */ - private volatile boolean _writable = true; - - /** True if a thread has is blocked in {@link #blockReadable(long)} */ - private boolean _readBlocked; - - /** True if a thread has is blocked in {@link #blockWritable(long)} */ - private boolean _writeBlocked; - - private boolean _ishut = false; - - public SelectChannelEndPoint(SocketChannel channel, SelectorManager manager, SelectionKey key, int maxIdleTime) - throws IOException - { - super(channel, maxIdleTime); - - _manager = manager; - _key = key; - _connection = manager.newConnection(channel,this); - } - - /* ------------------------------------------------------------ */ - /** Called by selectSet to schedule handling - * - */ - public synchronized void schedule() - { - if (!_key.isValid()) - { -/* - _readBlocked = false; - _writeBlocked = false; - this.notifyAll(); -*/ - _key.cancel(); - return; - } - - // If there are threads dispatched reading and writing - if (_readBlocked || _writeBlocked) - { - // assert _dispatched; - if (_readBlocked && _key.isReadable()) - _readBlocked = false; - if (_writeBlocked && _key.isWritable()) - _writeBlocked = false; - - // wake them up is as good as a dispatched. - this.notifyAll(); - - // we are not interested in further selecting - _key.interestOps(0); - if( !isDispatched ) - updateKey(); - return; - } - - // Remove writeable op - if ((_key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) - { - // Remove writeable op - int interestOps = _key.interestOps() & ~SelectionKey.OP_WRITE; - _key.interestOps(interestOps); - _writable = true; // Once writable is in ops, only removed with dispatch. - } - - // If dispatched, then deregister interest - if (isDispatched) - _key.interestOps(0); - else - { - // other wise do the dispatch - dispatch(); - } - } - - @Override - public synchronized void dispatch() - { - if( !isDispatched ) - { - isDispatched = true; - try { - _manager.execute(_handler); - } catch(RejectedExecutionException e) { - isDispatched = false; - LOG.warn("Dispatched Failed! "+this+" to "+_manager); -// updateKey(); - } - } - } - - @Override - public int fill(ByteBuffer buffer) throws IOException - { - int fill=super.fill(buffer); - return fill; - } - - @Override - public int flush(ByteBuffer header, ByteBuffer buffer, ByteBuffer trailer) throws IOException - { - int l = super.flush(header, buffer, trailer); - - // If there was something to write and it wasn't written, then we are not writable. - if (l==0 && ( header!=null && header.hasRemaining() || buffer!=null && buffer.hasRemaining() || trailer!=null && trailer.hasRemaining())) - { - synchronized (this) - { - _writable = false; - if( !isDispatched ) - updateKey(); - } - } - else if (l>0) - { - _writable = true; - } - return l; - } - - @Override - public int flush(ByteBuffer buffer) throws IOException - { - int l = super.flush(buffer); - - // If there was something to write and it wasn't written, then we are not writable. - if (l==0 && buffer!=null && buffer.hasRemaining()) - { - synchronized (this) - { - _writable = false; - if( !isDispatched ) - updateKey(); - } - } - else if (l>0) - { - _writable = true; - } - - return l; - } - - /* ------------------------------------------------------------ */ - /* - * Allows thread to block waiting for further events. - */ - @Override - public synchronized boolean blockReadable(long timeoutMs) throws IOException - { - if (isInputShutdown()) - throw new EofException(); - - long now = _manager.getNow(); - long end = now+timeoutMs; - try - { - _readBlocked = true; - while (!isInputShutdown() && _readBlocked) - { - try - { - updateKey(); - this.wait(timeoutMs>0?(end-now):10000); - } - catch (final InterruptedException e) - { - LOG.warn("",e); - } - finally - { - now = _manager.getNow(); - } - - if (_readBlocked && timeoutMs>0 && now>=end) - return false; - } - } - finally - { - _readBlocked = false; - } - return true; - } - - /* ------------------------------------------------------------ */ - /* - * Allows thread to block waiting for further events. - */ - @Override - public synchronized boolean blockWritable(long timeoutMs) throws IOException - { - if (isOutputShutdown()) - throw new EofException(); - - long now=_manager.getNow(); - long end=now+timeoutMs; - try - { - _writeBlocked = true; - while (_writeBlocked && !isOutputShutdown()) - { - try - { - updateKey(); - this.wait(timeoutMs>0?(end-now):10000); - } - catch (final InterruptedException e) - { - LOG.warn("",e); - } - finally - { - now = _manager.getNow(); - } - if (_writeBlocked && timeoutMs>0 && now>=end) - return false; - } - } - finally - { - _writeBlocked = false; - } - return true; - } - - @Override - public boolean hasProgressed() - { - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Updates selection key. Adds operations types to the selection key as needed. No operations - * are removed as this is only done during dispatch. This method records the new key and - * schedules a call to doUpdateKey to do the keyChange - */ - private synchronized void updateKey() - { - if( getChannel().isOpen() && _key.isValid()) - { - boolean read_interest = _readBlocked || (!isDispatched && !_connection.isSuspended()); - boolean write_interest = _writeBlocked || (!isDispatched && !_writable); -// boolean write_interest = _writeBlocked || !isDispatched; -// boolean write_interest = true; - - int interestOps = - ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0) - | ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0); - if( _key.interestOps() != interestOps ) { - _key.interestOps(interestOps); - _manager.getSelector().update(); - } - } else { - _key.cancel(); - // update needed? - } - } - - - private void handle() - { - try - { - try - { - _connection.handle(); - } - catch (ClosedChannelException e) - { - LOG.warn("",e); -// LOG.trace("",e); - } - catch (EofException e) - { - LOG.warn("EOF", e); -// LOG.debug("EOF", e); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - catch (IOException e) - { - LOG.warn("",e); -// LOG.warn(e.toString()); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - catch (Throwable e) - { - LOG.warn("handle failed", e); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - finally - { - if (!_ishut && isInputShutdown() && isOpen()) - { - _ishut = true; - try - { - _connection.onInputShutdown(); - } - catch(Throwable x) - { - LOG.warn("onInputShutdown failed", x); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - } - } - } - finally - { - isDispatched = false; - updateKey(); - } - } - - @Override - public void close() throws IOException - { - try - { - super.close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - finally - { - updateKey(); - } - } - - @Override - public String toString() - { - // Do NOT use synchronized (this) - // because it's very easy to deadlock when debugging is enabled. - // We do a best effort to print the right toString() and that's it. - SelectionKey key = _key; - String keyString = ""; - if (key.isValid()) - { - if (key.isReadable()) - keyString += "r"; - if (key.isWritable()) - keyString += "w"; - } - else - { - keyString += "!"; - } - return String.format("SCEP@%x{l(%s)<->r(%s),dispatched=%b,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%s}-{%s}", - hashCode(), - _socket.getRemoteSocketAddress(), - _socket.getLocalSocketAddress(), - isDispatched, - isOpen(), - isInputShutdown(), - isOutputShutdown(), - _readBlocked, - _writeBlocked, - _writable, - keyString, - _connection); - } - - /* ------------------------------------------------------------ */ - /** - * Don't set the SoTimeout - * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int) - */ - @Override - public void setMaxIdleTime(int timeMs) throws IOException - { - _maxIdleTime = timeMs; - } - -}
--- a/src/org/eclipse/jetty/io/nio/SelectorManager.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,279 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.nio.channels.CancelledKeyException; -import java.nio.channels.Channel; -import java.nio.channels.ClosedSelectorException; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.ArrayList; -import java.util.List; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** - * The Selector Manager manages and number of SelectSets to allow - * NIO scheduling to scale to large numbers of connections. - * <p> - */ -public final class SelectorManager extends AbstractLifeCycle implements Dumpable -{ - public static final Logger LOG = LoggerFactory.getLogger("org.eclipse.jetty.io.nio"); - - private final SelectChannelConnector scc; - private volatile long _now = System.currentTimeMillis(); - private SaneSelector _selector; - - /* ------------------------------------------------------------ */ - /** - * @param maxIdleTime The maximum period in milli seconds that a connection may be idle before it is closed. - * @see #setLowResourcesMaxIdleTime(long) - */ - public SelectorManager(SelectChannelConnector scc) - { - this.scc = scc; - } - - /* ------------------------------------------------------------ */ - /** Register a channel - * @param channel - */ - public final void register(SocketChannel channel) - { -/* - SelectSet set = _selectSet; - if (set!=null) - { - set.addChange(channel); - } -*/ - try { - SelectionKey key = _selector.register(channel,0,null); - SelectChannelEndPoint endpoint = new SelectChannelEndPoint(channel,this,key, scc.getMaxIdleTime()); - key.attach(endpoint); - _selector.update(); -//System.out.println("qqqqqqqqqqqqqqqqqqqqqqqqqqqqq b"); - endpoint.schedule(); - } catch(IOException e) { - LOG.warn("",e); - try { - channel.close(); - } catch(IOException e2) { - LOG.warn("",e2); - } - } - } - - - public void execute(Runnable task) { - scc.server.threadPool.execute(task); - } - - - @Override - protected void doStart() throws Exception - { - _selector = new SaneSelector(); - - super.doStart(); - - // start a thread to Select - execute(new Runnable() - { - public void run() - { - String name=Thread.currentThread().getName(); - try - { - if (_selector==null) - return; - - Thread.currentThread().setName(name+" Selector"); - LOG.debug("Starting {} on {}",Thread.currentThread(),this); - while (isRunning()) - { - try - { - doSelect(); - } - catch(IOException e) - { - LOG.trace("",e); - } - catch(Exception e) - { - LOG.warn("",e); - } - } - } - finally - { - _selector = null; - LOG.debug("Stopped {} on {}",Thread.currentThread(),this); - Thread.currentThread().setName(name); - } - } - - }); - } - - - @Override - protected synchronized void doStop() throws Exception - { - if (_selector!=null) - { - // close endpoints and selector - for (SelectionKey key : _selector.keys()) - { - EndPoint endpoint = (EndPoint)key.attachment(); - try - { - endpoint.close(); - } - catch(IOException e) - { - LOG.trace("",e); - } - } - - try - { - _selector.close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - } - super.doStop(); - } - - public AsyncConnection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint) { - return scc.newConnection(channel,endpoint); - } - - @Override - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - @Override - public void dump(Appendable out, String indent) throws IOException - { - AggregateLifeCycle.dumpObject(out,this); -// AggregateLifeCycle.dump(out,indent,Collections.emptyList()); - } - - - // from SelectSet - - private void doSelect() throws IOException - { - try - { - _selector.select(); - - // Look for things to do - for (SelectionKey key: _selector.selectedKeys()) - { - try - { - if (!key.isValid()) - { - key.cancel(); - continue; - } - - if (key.isReadable()||key.isWritable()) { - SelectChannelEndPoint endpoint = (SelectChannelEndPoint)key.attachment(); - endpoint.schedule(); - } - } - catch (CancelledKeyException e) - { - // LOG.trace("",e); - LOG.warn("",e); - } - catch (Exception e) - { - LOG.warn("",e); - } - } - - // Everything always handled - _selector.selectedKeys().clear(); - - _now = System.currentTimeMillis(); - } - catch (ClosedSelectorException e) - { - if (isRunning()) - LOG.warn("",e); - else - LOG.trace("",e); - } - catch (CancelledKeyException e) - { - LOG.trace("",e); - } - } - - public final long getNow() - { - return _now; - } - - final SaneSelector getSelector() - { - return _selector; - } - - @Override - public final String toString() - { - SaneSelector selector=_selector; - return String.format("%s keys=%d selected=%d", - super.toString(), - selector != null && selector.isOpen() ? selector.keys().size() : -1, - selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1); - } - -}
--- a/src/org/eclipse/jetty/io/nio/SslConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,732 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; -import java.util.concurrent.atomic.AtomicBoolean; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; -import javax.net.ssl.SSLEngineResult.HandshakeStatus; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSession; - -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.AsyncHttpConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** SSL Connection. - * An AysyncConnection that acts as an interceptor between and EndPoint and another - * Connection, that implements TLS encryption using an {@link SSLEngine}. - * <p> - * The connector uses an {@link AsyncEndPoint} (like {@link SelectChannelEndPoint}) as - * it's source/sink of encrypted data. It then provides {@link #getSslEndPoint()} to - * expose a source/sink of unencrypted data to another connection (eg HttpConnection). - */ -public final class SslConnection extends AbstractConnection implements AsyncConnection -{ - private final Logger _logger = LoggerFactory.getLogger("org.eclipse.jetty.io.nio.ssl"); - - private static final ByteBuffer __ZERO_BUFFER = BufferUtil.EMPTY_BUFFER; - - private static final ThreadLocal<SslBuffers> __buffers = new ThreadLocal<SslBuffers>(); - private final SSLEngine _engine; - private final SSLSession _session; - private AsyncHttpConnection _connection; - private final SslEndPoint _sslEndPoint; - private int _allocations; - private SslBuffers _buffers; - private ByteBuffer _inbound; - private ByteBuffer _unwrapBuf; - private ByteBuffer _outbound; - private final AsyncEndPoint _aEndp; - private boolean _allowRenegotiate = true; - private boolean _handshook; - private boolean _ishut; - private boolean _oshut; - private final AtomicBoolean _progressed = new AtomicBoolean(); - - /* ------------------------------------------------------------ */ - /* this is a half baked buffer pool - */ - private static class SslBuffers - { - final ByteBuffer _in; - final ByteBuffer _out; - final ByteBuffer _unwrap; - - SslBuffers(int packetSize, int appSize) - { - _in = ByteBuffer.allocate(packetSize); - _in.limit(0); - _out = ByteBuffer.allocate(packetSize); - _out.limit(0); - _unwrap = ByteBuffer.allocate(appSize); - _unwrap.limit(0); - } - } - - public SslConnection(SSLEngine engine,AsyncEndPoint endp) - { - super(endp); - _engine = engine; - _session = _engine.getSession(); - _aEndp = endp; - _sslEndPoint = new SslEndPoint(); - } - - /* ------------------------------------------------------------ */ - /** - * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered - * a vulnerability in SSL/TLS with re-negotiation. If your JVM - * does not have CVE-2009-3555 fixed, then re-negotiation should - * not be allowed. CVE-2009-3555 was fixed in Sun java 1.6 with a ban - * of renegotiates in u19 and with RFC5746 in u22. - * - * @param allowRenegotiate - * true if re-negotiation is allowed (default false) - */ - public void setAllowRenegotiate(boolean allowRenegotiate) - { - _allowRenegotiate = allowRenegotiate; - } - - private void allocateBuffers() - { - synchronized (this) - { - if (_allocations++==0) - { - if (_buffers==null) - { - _buffers=__buffers.get(); - if (_buffers==null) - _buffers=new SslBuffers(_session.getPacketBufferSize()*2,_session.getApplicationBufferSize()*2); - _inbound = _buffers._in; - _outbound = _buffers._out; - _unwrapBuf = _buffers._unwrap; - __buffers.set(null); - } - } - } - } - - private void releaseBuffers() - { - synchronized (this) - { - if (--_allocations==0) - { - if (_buffers!=null && - _inbound.remaining()==0 && - _outbound.remaining()==0 && - _unwrapBuf.remaining()==0) - { - _inbound = null; - _outbound = null; - _unwrapBuf=null; - __buffers.set(_buffers); - _buffers=null; - } - } - } - } - - @Override - public void handle() throws IOException - { - try - { - allocateBuffers(); - - boolean progress=true; - - while (progress) - { - progress=false; - - // If we are handshook let the delegate connection - if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING) - progress = process(null,null); - - // handle the delegate connection - _connection.handle(); - - _logger.debug("{} handle {} progress={}", _session, this, progress); - } - } - finally - { - releaseBuffers(); - - if (!_ishut && _sslEndPoint.isInputShutdown() && _sslEndPoint.isOpen()) - { - _ishut=true; - try - { - _connection.onInputShutdown(); - } - catch(Throwable x) - { - _logger.warn("onInputShutdown failed", x); - try{_sslEndPoint.close();} - catch(IOException e2){ - _logger.trace("",e2);} - } - } - } - } - - @Override - public boolean isSuspended() - { - return false; - } - - @Override - public void onInputShutdown() throws IOException - { - } - - private void put_unwrapBuf(ByteBuffer toFill) { - ByteBuffer dup = toFill.duplicate(); - dup.position(dup.limit()); - dup.limit(dup.capacity()); - dup.put(_unwrapBuf); - toFill.limit(dup.position()); - } - - private synchronized boolean process(ByteBuffer toFill, ByteBuffer toFlush) throws IOException - { - boolean some_progress=false; - try - { - // We need buffers to progress - allocateBuffers(); - - // if we don't have a buffer to put received data into - if (toFill==null) - { - // use the unwrapbuffer to hold received data. - BufferUtil.compact(_unwrapBuf); - toFill = _unwrapBuf; - } - // Else if the fill buffer is too small for the SSL session - else if (toFill.capacity()<_session.getApplicationBufferSize()) - { - // fill to the temporary unwrapBuffer - boolean progress = process(null,toFlush); - - // if we received any data, - if (_unwrapBuf!=null && _unwrapBuf.hasRemaining()) - { - // transfer from temp buffer to fill buffer -// _unwrapBuf.skip(toFill.putJ(_unwrapBuf)); - put_unwrapBuf(toFill); - return true; - } - else - // return progress from recursive call - return progress; - } - // Else if there is some temporary data - else if (_unwrapBuf!=null && _unwrapBuf.hasRemaining()) - { - // transfer from temp buffer to fill buffer -// _unwrapBuf.skip(toFill.putJ(_unwrapBuf)); - put_unwrapBuf(toFill); - return true; - } - - // If we are here, we have a buffer ready into which we can put some read data. - - // If we have no data to flush, flush the empty buffer - if (toFlush==null) - toFlush = __ZERO_BUFFER; - - // While we are making progress processing SSL engine - boolean progress=true; - while (progress) - { - progress=false; - - // Do any real IO - int filled=0,flushed=0; - try - { - // Read any available data - if (_inbound.capacity()>_inbound.limit() && (filled=_endp.fill(_inbound))>0) - progress = true; - - // flush any output data - if (_outbound.hasRemaining() && (flushed=_endp.flush(_outbound))>0) - progress = true; - } - catch (IOException e) - { - _endp.close(); - throw e; - } - finally - { - _logger.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.remaining(),flushed,_outbound.remaining()); - } - - // handle the current hand share status - switch(_engine.getHandshakeStatus()) - { - case FINISHED: - throw new IllegalStateException(); - - case NOT_HANDSHAKING: - { - // Try unwrapping some application data - if (toFill.capacity()>toFill.limit() && _inbound.hasRemaining() && unwrap(toFill)) - progress=true; - - // Try wrapping some application data - if (toFlush.hasRemaining() && _outbound.capacity()>_outbound.limit() && wrap(toFlush)) - progress=true; - } - break; - - case NEED_TASK: - { - // A task needs to be run, so run it! - Runnable task; - while ((task=_engine.getDelegatedTask())!=null) - { - progress=true; - task.run(); - } - - } - break; - - case NEED_WRAP: - { - // The SSL needs to send some handshake data to the other side - if (_handshook && !_allowRenegotiate) - _endp.close(); - else if (wrap(toFlush)) - progress=true; - } - break; - - case NEED_UNWRAP: - { - // The SSL needs to receive some handshake data from the other side - if (_handshook && !_allowRenegotiate) - _endp.close(); - else if (!_inbound.hasRemaining()&&filled==-1) - { - // No more input coming - _endp.shutdownInput(); - } - else if (unwrap(toFill)) - progress=true; - } - break; - } - - // pass on ishut/oshut state - if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasRemaining()) - closeInbound(); - - if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasRemaining()) - _endp.shutdownOutput(); - - // remember if any progress has been made - some_progress|=progress; - } - - // If we are reading into the temp buffer and it has some content, then we should be dispatched. - if (toFill==_unwrapBuf && _unwrapBuf.hasRemaining() && !_connection.isSuspended()) - _aEndp.dispatch(); - } - finally - { - releaseBuffers(); - if (some_progress) - _progressed.set(true); - } - return some_progress; - } - - private void closeInbound() - { - try - { - _engine.closeInbound(); - } - catch (SSLException x) - { - _logger.debug("",x); - } - } - - private synchronized boolean wrap(final ByteBuffer buffer) throws IOException - { - final SSLEngineResult result; - - synchronized(buffer) - { - BufferUtil.compact(_outbound); - ByteBuffer out_buffer = _outbound.duplicate(); - synchronized(out_buffer) - { - try - { - out_buffer.position(_outbound.limit()); - out_buffer.limit(out_buffer.capacity()); - result = _engine.wrap(buffer,out_buffer); - if (_logger.isDebugEnabled()) - _logger.debug("{} wrap {} {} consumed={} produced={}", - _session, - result.getStatus(), - result.getHandshakeStatus(), - result.bytesConsumed(), - result.bytesProduced()); - - _outbound.limit(_outbound.limit()+result.bytesProduced()); - } - catch(SSLException e) - { - _logger.debug(String.valueOf(_endp), e); - _endp.close(); - throw e; - } - } - } - - switch(result.getStatus()) - { - case BUFFER_UNDERFLOW: - throw new IllegalStateException(); - - case BUFFER_OVERFLOW: - break; - - case OK: - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _handshook=true; - break; - - case CLOSED: - _logger.debug("wrap CLOSE {} {}",this,result); - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _endp.close(); - break; - - default: - _logger.debug("{} wrap default {}",_session,result); - throw new IOException(result.toString()); - } - - return result.bytesConsumed()>0 || result.bytesProduced()>0; - } - - private synchronized boolean unwrap(final ByteBuffer buffer) throws IOException - { - if (!_inbound.hasRemaining()) - return false; - - ByteBuffer bbuf = buffer.duplicate(); - final SSLEngineResult result; - - synchronized(bbuf) - { - synchronized(_inbound) - { - try - { - bbuf.position(buffer.limit()); - bbuf.limit(buffer.capacity()); - - result=_engine.unwrap(_inbound,bbuf); - if (_logger.isDebugEnabled()) - _logger.debug("{} unwrap {} {} consumed={} produced={}", - _session, - result.getStatus(), - result.getHandshakeStatus(), - result.bytesConsumed(), - result.bytesProduced()); - - BufferUtil.compact(_inbound); - buffer.limit(buffer.limit()+result.bytesProduced()); - } - catch(SSLException e) - { - _logger.debug(String.valueOf(_endp), e); - _endp.close(); - throw e; - } - } - } - - switch(result.getStatus()) - { - case BUFFER_UNDERFLOW: - if (_endp.isInputShutdown()) - _inbound.limit(0); - break; - - case BUFFER_OVERFLOW: - break; - - case OK: - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _handshook=true; - break; - - case CLOSED: - _logger.debug("unwrap CLOSE {} {}",this,result); - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _endp.close(); - break; - - default: - _logger.debug("{} wrap default {}",_session,result); - throw new IOException(result.toString()); - } - - //if (LOG.isDebugEnabled() && result.bytesProduced()>0) - // LOG.debug("{} unwrapped '{}'",_session,buffer); - - return result.bytesConsumed()>0 || result.bytesProduced()>0; - } - - public SslEndPoint getSslEndPoint() - { - return _sslEndPoint; - } - - public String toString() - { - return String.format("%s %s", super.toString(), _sslEndPoint); - } - - - public final class SslEndPoint implements AsyncEndPoint - { - public SSLEngine getSslEngine() - { - return _engine; - } - - public AsyncEndPoint getEndpoint() - { - return _aEndp; - } - - public void shutdownOutput() throws IOException - { - synchronized (SslConnection.this) - { - _logger.debug("{} ssl endp.oshut {}",_session,this); - _engine.closeOutbound(); - _oshut=true; - } - flush(); - } - - public boolean isOutputShutdown() - { - synchronized (SslConnection.this) - { - return _oshut||!isOpen()||_engine.isOutboundDone(); - } - } - - public void shutdownInput() throws IOException - { - _logger.debug("{} ssl endp.ishut!",_session); - // We do not do a closeInput here, as SSL does not support half close. - // isInputShutdown works it out itself from buffer state and underlying endpoint state. - } - - public boolean isInputShutdown() - { - synchronized (SslConnection.this) - { - return _endp.isInputShutdown() && - !(_unwrapBuf!=null&&_unwrapBuf.hasRemaining()) && - !(_inbound!=null&&_inbound.hasRemaining()); - } - } - - public void close() throws IOException - { - _logger.debug("{} ssl endp.close",_session); - _endp.close(); - } - - public int fill(ByteBuffer buffer) throws IOException - { - int size = buffer.remaining(); - process(buffer, null); - - int filled=buffer.remaining()-size; - - if (filled==0 && isInputShutdown()) - return -1; - return filled; - } - - public int flush(ByteBuffer buffer) throws IOException - { - int size = buffer.remaining(); - process(null, buffer); - return size-buffer.remaining(); - } - - public int flush(ByteBuffer header, ByteBuffer buffer, ByteBuffer trailer) throws IOException - { - if (header!=null && header.hasRemaining()) - return flush(header); - if (buffer!=null && buffer.hasRemaining()) - return flush(buffer); - if (trailer!=null && trailer.hasRemaining()) - return flush(trailer); - return 0; - } - - public boolean blockReadable(long millisecs) throws IOException - { - long now = System.currentTimeMillis(); - long end=millisecs>0?(now+millisecs):Long.MAX_VALUE; - - while (now<end) - { - if (process(null,null)) - break; - _endp.blockReadable(end-now); - now = System.currentTimeMillis(); - } - - return now<end; - } - - public boolean blockWritable(long millisecs) throws IOException - { - return _endp.blockWritable(millisecs); - } - - public boolean isOpen() - { - return _endp.isOpen(); - } - - public SocketChannel getChannel() - { - return _endp.getChannel(); - } - - public void flush() throws IOException - { - process(null, null); - } - - public void dispatch() - { - _aEndp.dispatch(); - } - - public boolean hasProgressed() - { - return _progressed.getAndSet(false); - } - - public String getLocalAddr() - { - return _aEndp.getLocalAddr(); - } - - public String getLocalHost() - { - return _aEndp.getLocalHost(); - } - - public int getLocalPort() - { - return _aEndp.getLocalPort(); - } - - public String getRemoteAddr() - { - return _aEndp.getRemoteAddr(); - } - - public String getRemoteHost() - { - return _aEndp.getRemoteHost(); - } - - public int getRemotePort() - { - return _aEndp.getRemotePort(); - } - - public boolean isBlocking() - { - return false; - } - - public int getMaxIdleTime() - { - return _aEndp.getMaxIdleTime(); - } - - public void setMaxIdleTime(int timeMs) throws IOException - { - _aEndp.setMaxIdleTime(timeMs); - } - - public void setConnection(AsyncHttpConnection connection) - { - _connection = connection; - } - - public String toString() - { - // Do NOT use synchronized (SslConnection.this) - // because it's very easy to deadlock when debugging is enabled. - // We do a best effort to print the right toString() and that's it. - ByteBuffer inbound = _inbound; - ByteBuffer outbound = _outbound; - ByteBuffer unwrap = _unwrapBuf; - int i = inbound == null? -1 : inbound.remaining(); - int o = outbound == null ? -1 : outbound.remaining(); - int u = unwrap == null ? -1 : unwrap.remaining(); - return String.format("SSL %s i/o/u=%d/%d/%d ishut=%b oshut=%b {%s}", - _engine.getHandshakeStatus(), - i, o, u, - _ishut, _oshut, - _connection); - } - - } -}
--- a/src/org/eclipse/jetty/jetty-dir.css Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -body -{ - background-color: #FFFFFF; - margin: 10px; - padding: 5px; -} - -h1 -{ - text-shadow: #000000 -1px -1px 1px; - color: #FC390E; - font-weight: bold; -} - -a -{ - color: #7036be; - font-weight: bold; - font-style: normal; - text-decoration: none; - font-size:inherit; -} - -td -{ - font-style: italic; - padding: 2px 15px 2px 0px; -} - - -
--- a/src/org/eclipse/jetty/server/AbstractHttpConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,907 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.Writer; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; - -import javax.servlet.ServletInputStream; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpException; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.http.HttpHeaderValues; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.HttpParser; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.http.HttpVersions; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.util.ByteArrayOutputStream2; -import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.eclipse.jetty.util.resource.Resource; - -/** - * <p>A HttpConnection represents the connection of a HTTP client to the server - * and is created by an instance of a {@link Connector}. It's prime function is - * to associate {@link Request} and {@link Response} instances with a {@link EndPoint}. - * </p> - * <p> - * A connection is also the prime mechanism used by jetty to recycle objects without - * pooling. The {@link Request}, {@link Response}, {@link HttpParser}, {@link HttpGenerator} - * and {@link HttpFields} instances are all recycled for the duraction of - * a connection. Where appropriate, allocated buffers are also kept associated - * with the connection via the parser and/or generator. - * </p> - * <p> - * The connection state is held by 3 separate state machines: The request state, the - * response state and the continuation state. All three state machines must be driven - * to completion for every request, and all three can complete in any order. - * </p> - * <p> - * The HttpConnection support protocol upgrade. If on completion of a request, the - * response code is 101 (switch protocols), then the org.eclipse.jetty.io.Connection - * request attribute is checked to see if there is a new Connection instance. If so, - * the new connection is returned from {@link #handle()} and is used for future - * handling of the underlying connection. Note that for switching protocols that - * don't use 101 responses (eg CONNECT), the response should be sent and then the - * status code changed to 101 before returning from the handler. Implementors - * of new Connection types should be careful to extract any buffered data from - * (HttpParser)http.getParser()).getHeaderBuffer() and - * (HttpParser)http.getParser()).getBodyBuffer() to initialise their new connection. - * </p> - * - */ -public abstract class AbstractHttpConnection extends AbstractConnection -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpConnection.class); - - private final Connector _connector; - private final Server _server; - protected final HttpURI _uri = new HttpURI(); - - protected volatile HttpParser _parser; - protected final HttpFields _requestFields = new HttpFields(); - public volatile Request _request; - private volatile ServletInputStream _in; - - protected volatile HttpGenerator _generator; - final HttpFields _responseFields = new HttpFields(); - protected volatile Response _response; - private volatile Output _out; - private volatile HttpWriter _writer; - private volatile PrintWriter _printWriter; - - private int _version = -2; // UNKNOWN - - private String _charset; - private boolean _expect = false; - private boolean _expect100Continue = false; - private boolean _head = false; - private boolean _host = false; - private boolean _delayedHandling = false; - private boolean _earlyEOF = false; - - protected AbstractHttpConnection(Connector connector, EndPoint endpoint) - { - super(endpoint); - _connector = connector; - _server = connector.server; - init(); - } - - void initParser() { - Buffers buffers = _connector.getRequestBuffers(); - _parser = new HttpParser(buffers.getHeader(), buffers.getBuffer(), _endp, new RequestHandler()); - } - - void initGenerator() { - if( _generator != null ) - _generator.shutdown(); - _generator = new HttpGenerator(_connector.getResponseBuffers(), _endp); - } - - private void init() { - initParser(); - initGenerator(); - _request = new Request(this); - _response = new Response(this); - } - - public final Connector getConnector() - { - return _connector; - } - - public final Request getRequest() - { - return _request; - } - - public final Response getResponse() - { - return _response; - } - - /* ------------------------------------------------------------ */ - /** - * Get the inputStream from the connection. - * <p> - * If the associated response has the Expect header set to 100 Continue, - * then accessing the input stream indicates that the handler/servlet - * is ready for the request body and thus a 100 Continue response is sent. - * - * @return The input stream for this connection. - * The stream will be created if it does not already exist. - * @throws IOException if the input stream cannot be retrieved - */ - public final ServletInputStream getInputStream() throws IOException - { - // If the client is expecting 100 CONTINUE, then send it now. - if (_expect100Continue) - { - // is content missing? - if (_parser._header.remaining()<2) - { - if (_generator.isCommitted()) - throw new IllegalStateException("Committed before 100 Continues"); - - _generator.send1xx(HttpStatus.CONTINUE_100); - } - _expect100Continue=false; - } - - if (_in == null) - _in = new HttpInput(); - return _in; - } - - /* ------------------------------------------------------------ */ - /** - * @return The output stream for this connection. The stream will be created if it does not already exist. - */ - public final ServletOutputStream getOutputStream() - { - if (_out == null) - _out = new Output(); - return _out; - } - - /* ------------------------------------------------------------ */ - /** - * @param encoding the PrintWriter encoding - * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it - * does not already exist. - */ - public final PrintWriter getPrintWriter(String encoding) - { - getOutputStream(); - if (_writer==null) - { - _writer = new HttpWriter(_out); - _printWriter = new PrintWriter(_writer) - { - public void close() - { - synchronized (lock) - { - try - { - out.close(); - } - catch (IOException e) - { - setError(); - } - } - } - }; - } - _writer.setCharacterEncoding(encoding); - return _printWriter; - } - - protected void reset() - { - _requestFields.clear(); - _responseFields.clear(); - _uri.clear(); - _writer = null; - _earlyEOF = false; - init(); - } - - private void handleRequest() throws IOException - { - boolean error = false; - - try - { - // Loop here to handle async request redispatches. - // The loop is controlled by the call to async.unhandle in the - // finally block below. If call is from a non-blocking connector, - // then the unhandle will return false only if an async dispatch has - // already happened when unhandle is called. For a blocking connector, - // the wait for the asynchronous dispatch or timeout actually happens - // within the call to unhandle(). - - _request.setHandled(false); - - String info=null; - try - { - _uri.getPort(); - String path = null; - - try - { - path = _uri.getDecodedPath(); - } - catch (Exception e) - { - LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1"); - LOG.trace("",e); - path = _uri.getDecodedPath(StringUtil.__ISO_8859_1); - } - - info = URIUtil.canonicalPath(path); - if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT)) - { - if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null) - { - info="/"; - _request.setRequestURI(""); - } - else - throw new HttpException(400); - } - _request.setPathInfo(info); - - if (_out!=null) - _out.reopen(); - - _connector.customize(this); - _server.handle(this); - } - catch (EofException e) - { - LOG.debug("",e); - error=true; - _request.setHandled(true); - if (!_response.isCommitted()) - _generator.sendError(500, null, null, true); - } - catch (RuntimeIOException e) - { - LOG.debug("",e); - error=true; - _request.setHandled(true); - } - catch (HttpException e) - { - LOG.debug("",e); - error=true; - _request.setHandled(true); - _response.sendError(e.getStatus(), e.getReason()); - } - catch (Throwable e) - { - LOG.warn(String.valueOf(_uri),e); - error=true; - _request.setHandled(true); - _generator.sendError(info==null?400:500, null, null, true); - - } - } - finally - { - if (_expect100Continue) - { - LOG.debug("100 continues not sent"); - // We didn't send 100 continues, but the latest interpretation - // of the spec (see httpbis) is that the client will either - // send the body anyway, or close. So we no longer need to - // do anything special here other than make the connection not persistent - _expect100Continue = false; - if (!_response.isCommitted()) - _generator.setPersistent(false); - } - - if(_endp.isOpen()) - { - if (error) - { - _endp.shutdownOutput(); - _generator.setPersistent(false); - if (!_generator.isComplete()) - _response.complete(); - } - else - { - if (!_response.isCommitted() && !_request.isHandled()) - _response.sendError(HttpServletResponse.SC_NOT_FOUND); - _response.complete(); - } - } - else - { - _response.complete(); - } - - _request.setHandled(true); - } - } - - - public final void commitResponse(boolean last) throws IOException - { - if (!_generator.isCommitted()) - { - _generator.setResponse(_response.getStatus(), _response.getReason()); - try - { - // If the client was expecting 100 continues, but we sent something - // else, then we need to close the connection - if (_expect100Continue && _response.getStatus()!=100) - _generator.setPersistent(false); - _generator.completeHeader(_responseFields, last); - } - catch(RuntimeException e) - { - LOG.warn("header full: " + e); - - _response.reset(); - initGenerator(); - _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null); - _generator.completeHeader(_responseFields,HttpGenerator.LAST); - _generator.complete(); - throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500); - } - - } - if (last) - _generator.complete(); - } - - public final void completeResponse() throws IOException - { - if (!_generator.isCommitted()) - { - _generator.setResponse(_response.getStatus(), _response.getReason()); - try - { - _generator.completeHeader(_responseFields, HttpGenerator.LAST); - } - catch(RuntimeException e) - { - LOG.warn("header full: "+e); - LOG.debug("",e); - - _response.reset(); - initGenerator(); - _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null); - _generator.completeHeader(_responseFields,HttpGenerator.LAST); - _generator.complete(); - throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500); - } - } - - _generator.complete(); - } - - public final void flushResponse() throws IOException - { - try - { - commitResponse(HttpGenerator.MORE); - _generator.flushBuffer(); - } - catch(IOException e) - { - throw (e instanceof EofException) ? e:new EofException(e); - } - } - - public final int getMaxIdleTime() - { - if (_connector.server.isLowOnThreads() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime()) - return 0; - if (_endp.getMaxIdleTime()>0) - return _endp.getMaxIdleTime(); - return _connector.getMaxIdleTime(); - } - - @Override - public String toString() - { - return String.format("%s,g=%s,p=%s", - super.toString(), - _generator, - _parser); - } - - private void startRequest(String method, String uri, String version) throws IOException - { - _host = false; - _expect = false; - _expect100Continue = false; - _delayedHandling=false; - _charset=null; - - if(_request.getTimeStamp()==0) - _request.setTimeStamp(System.currentTimeMillis()); - _request.setMethod(method); - - try - { - _head = false; - byte[] bytes = StringUtil.getBytes(uri); - switch (HttpMethods.CACHE.getOrdinal(method)) - { - case HttpMethods.CONNECT_ORDINAL: - _uri.parseConnect(bytes, 0, bytes.length); - break; - - case HttpMethods.HEAD_ORDINAL: - _head = true; - _uri.parse(bytes, 0, bytes.length); - break; - - default: - _uri.parse(bytes, 0, bytes.length); - } - - _request.setUri(_uri); - - if (version==null) - { - _request.setProtocol(HttpVersions.HTTP_0_9); - _version = HttpVersions.HTTP_0_9_ORDINAL; - } - else - { - if (!HttpVersions.CACHE.contains(version)) - throw new HttpException(HttpStatus.BAD_REQUEST_400,null); - _version = HttpVersions.CACHE.getOrdinal(version); - if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL; - _request.setProtocol(version.toString()); - } - } - catch (Exception e) - { - LOG.debug("",e); - if (e instanceof HttpException) - throw (HttpException)e; - throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e); - } - } - - private void parsedHeader(String name, String value) throws IOException - { - int ho = HttpHeaders.CACHE.getOrdinal(name); - switch (ho) - { - case HttpHeaders.HOST_ORDINAL: - // TODO check if host matched a host in the URI. - _host = true; - break; - - case HttpHeaders.EXPECT_ORDINAL: - if (_version>=HttpVersions.HTTP_1_1_ORDINAL) - { -// value = HttpHeaderValues.CACHE.lookup(value); - switch(HttpHeaderValues.CACHE.getOrdinal(value)) - { - case HttpHeaderValues.CONTINUE_ORDINAL: - _expect100Continue = true; - break; - - default: - String[] values = value.toString().split(","); - for (int i=0;values!=null && i<values.length;i++) - { - int cb = HttpHeaderValues.CACHE.getOrdinal(values[i].trim()); - if (cb == -1) - _expect = true; - else - { - switch(cb) - { - case HttpHeaderValues.CONTINUE_ORDINAL: - _expect100Continue = true; - break; - default: - _expect = true; - } - } - } - } - } - break; - - case HttpHeaders.ACCEPT_ENCODING_ORDINAL: - case HttpHeaders.USER_AGENT_ORDINAL: -// value = HttpHeaderValues.CACHE.lookup(value); - break; - - case HttpHeaders.CONTENT_TYPE_ORDINAL: -// value = MimeTypes.CACHE.lookup(value); - _charset = MimeTypes.getCharsetFromContentType(value); - break; - } - - _requestFields.add(name, value); - } - - private void headerComplete() throws IOException - { - // Handle idle race - if (_endp.isOutputShutdown()) - { - _endp.close(); - return; - } - - _generator.setVersion(_version); - switch (_version) - { - case HttpVersions.HTTP_0_9_ORDINAL: - break; - case HttpVersions.HTTP_1_0_ORDINAL: - _generator.setHead(_head); - if (_parser.isPersistent()) - { - _responseFields.add(HttpHeaders.CONNECTION, HttpHeaderValues.KEEP_ALIVE); - _generator.setPersistent(true); - } - else if (HttpMethods.CONNECT.equals(_request.getMethod())) - { - _generator.setPersistent(true); - _parser.setPersistent(true); - } - break; - - case HttpVersions.HTTP_1_1_ORDINAL: - _generator.setHead(_head); - - if (!_parser.isPersistent()) - { - _responseFields.add(HttpHeaders.CONNECTION,HttpHeaderValues.CLOSE); - _generator.setPersistent(false); - } - - if (!_host) - { - LOG.debug("!host {}",this); - _generator.setResponse(HttpStatus.BAD_REQUEST_400, null); - _responseFields.put(HttpHeaders.CONNECTION, HttpHeaderValues.CLOSE); - _generator.completeHeader(_responseFields, true); - _generator.complete(); - return; - } - - if (_expect) - { - LOG.debug("!expectation {}",this); - _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null); - _responseFields.put(HttpHeaders.CONNECTION, HttpHeaderValues.CLOSE); - _generator.completeHeader(_responseFields, true); - _generator.complete(); - return; - } - - break; - default: - } - - if(_charset!=null) - _request.setCharacterEncodingUnchecked(_charset); - - // Either handle now or wait for first content - if ((_parser.getContentLength()<=0 && !_parser.isChunking())||_expect100Continue) - handleRequest(); - else - _delayedHandling = true; - } - - private void content() throws IOException - { - if (_delayedHandling) - { - _delayedHandling = false; - handleRequest(); - } - } - - private void messageComplete(long contentLength) throws IOException - { - if (_delayedHandling) - { - _delayedHandling = false; - handleRequest(); - } - } - - private void earlyEOF() - { - _earlyEOF = true; - } - - - private class RequestHandler implements HttpParser.EventHandler - { - @Override - public void startRequest(String method, String uri, String version) throws IOException - { - AbstractHttpConnection.this.startRequest(method, uri, version); - } - - @Override - public void parsedHeader(String name, String value) throws IOException - { - AbstractHttpConnection.this.parsedHeader(name, value); - } - - @Override - public void headerComplete() throws IOException - { - AbstractHttpConnection.this.headerComplete(); - } - - @Override - public void content() throws IOException - { - AbstractHttpConnection.this.content(); - } - - @Override - public void messageComplete(long contentLength) throws IOException - { - AbstractHttpConnection.this.messageComplete(contentLength); - } - - @Override - public void earlyEOF() - { - AbstractHttpConnection.this.earlyEOF(); - } - } - - - public final class Output extends ServletOutputStream - { - private boolean _closed; - private ByteBuffer _onebyte; - - // These are held here for reuse by Writer - String _characterEncoding; - Writer _converter; - char[] _chars; - ByteArrayOutputStream2 _bytes; - - public final void reopen() - { - _closed = false; - } - - @Override - public final void write(byte[] b, int off, int len) throws IOException - { - write(ByteBuffer.wrap(b,off,len)); - } - - @Override - public final void write(byte[] b) throws IOException - { - write(ByteBuffer.wrap(b)); - } - - @Override - public final void write(int b) throws IOException - { - if (_onebyte==null) - _onebyte = ByteBuffer.allocate(1); - else - _onebyte.clear(); - _onebyte.put((byte)b); - write(_onebyte); - } - - private void write(ByteBuffer buffer) throws IOException - { - if (_closed) - throw new IOException("Closed"); - if (!_generator.isOpen()) - throw new EofException(); - - // Block until we can add _content. - while (_generator.isBufferFull()) - { - _generator.blockForOutput(getMaxIdleTime()); - if (_closed) - throw new IOException("Closed"); - if (!_generator.isOpen()) - throw new EofException(); - } - - // Add the _content - _generator.addContent(buffer, HttpGenerator.MORE); - - // Have to flush and complete headers? - - if (_generator.isAllContentWritten()) - { - flush(); - close(); - } - else if (_generator.isBufferFull()) - commitResponse(HttpGenerator.MORE); - - // Block until our buffer is free - while (buffer.remaining() > 0 && _generator.isOpen()) - { - _generator.blockForOutput(getMaxIdleTime()); - } - } - - - - /* ------------------------------------------------------------ */ - /* - * @see java.io.OutputStream#close() - */ - @Override - public void close() throws IOException - { - if (_closed) - return; - - if (!_generator.isCommitted()) - commitResponse(HttpGenerator.LAST); - else - flushResponse(); - - _closed = true; - } - - - /* ------------------------------------------------------------ */ - /* - * @see java.io.OutputStream#flush() - */ - @Override - public void flush() throws IOException - { - if (!_generator.isCommitted()) - commitResponse(HttpGenerator.MORE); - _generator.flush(getMaxIdleTime()); - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletOutputStream#print(java.lang.String) - */ - @Override - public void print(String s) throws IOException - { - if (_closed) - throw new IOException("Closed"); - PrintWriter writer = getPrintWriter(null); - writer.print(s); - } - - public final void sendContent(InputStream in) throws IOException - { - if (_closed) - throw new IOException("Closed"); - - if (_generator.isWritten()) - throw new IllegalStateException("!empty"); - - try - { - ReadableByteChannel chan = Channels.newChannel(in); - ByteBuffer buffer = _generator.getUncheckedBuffer(); - - while (true) - { - _generator.prepareUncheckedAddContent(); - - int n = chan.read(buffer); - if( n == -1 ) - break; - - _generator.completeUncheckedAddContent(); - _out.flush(); - } -/* - _generator.completeUncheckedAddContent(); - _out.flush(); -*/ - } - finally - { - in.close(); - } - } - } - - private final class HttpInput extends ServletInputStream - { - /* ------------------------------------------------------------ */ - /* - * @see java.io.InputStream#read() - */ - @Override - public int read() throws IOException - { - byte[] bytes = new byte[1]; - int read = read(bytes, 0, 1); - return read < 0 ? -1 : 0xff & bytes[0]; - } - - /* ------------------------------------------------------------ */ - /* - * @see java.io.InputStream#read(byte[], int, int) - */ - @Override - public int read(byte[] b, int off, int len) throws IOException - { - ByteBuffer content = _parser.blockForContent(getMaxIdleTime()); - if (content!=null) { - int remaining = content.remaining(); - if( remaining == 0 ) - return -1; - if( len > remaining ) - len = remaining; - content.get(b, off, len); - return len; - } else if (_earlyEOF) - throw new EofException("early EOF"); - else - return -1; - } - - @Override - public int available() throws IOException - { - return _parser.available(); - } - } - -}
--- a/src/org/eclipse/jetty/server/AsyncHttpConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; - -import org.eclipse.jetty.http.HttpException; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.nio.AsyncConnection; -import org.eclipse.jetty.io.nio.SelectChannelEndPoint; -import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** Asychronous Server HTTP connection - * - */ -public final class AsyncHttpConnection extends AbstractHttpConnection implements AsyncConnection -{ - private final static int NO_PROGRESS_INFO = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_INFO",100); - private final static int NO_PROGRESS_CLOSE = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_CLOSE",200); - - private static final Logger LOG = LoggerFactory.getLogger(AsyncHttpConnection.class); - private int _total_no_progress; - private final AsyncEndPoint _asyncEndp; - private boolean _readInterested = true; - - public AsyncHttpConnection(SelectChannelConnector connector, AsyncEndPoint endpoint) - { - super(connector,endpoint); - _asyncEndp = endpoint; - } - - @Override - public void handle() throws IOException - { - boolean some_progress = false; - boolean progress = true; - - try - { - // While progress and the connection has not changed - while (progress) - { - progress=false; - try - { - // Parse more input - if (!_parser.isComplete() && _parser.parseAvailable()) - progress = true; - - // Generate more output - if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown()) - if (_generator.flushBuffer()>0) - progress = true; - - // Flush output - _endp.flush(); - - // Has any IO been done by the endpoint itself since last loop - if (_asyncEndp.hasProgressed()) - progress = true; - } - catch (HttpException e) - { - if (LOG.isDebugEnabled()) - { - LOG.debug("uri="+_uri); - LOG.debug("fields="+_requestFields); - LOG.debug("",e); - } - progress = true; - _generator.sendError(e.getStatus(), e.getReason(), null, true); - } - finally - { - some_progress |= progress; - // Is this request/response round complete and are fully flushed? - boolean parserComplete = _parser.isComplete(); - boolean generatorComplete = _generator.isComplete(); - boolean complete = parserComplete && generatorComplete; - if (parserComplete) - { - if (generatorComplete) - { - // Reset the parser/generator - progress=true; - - reset(); - - // TODO Is this still required? - if (!_generator.isPersistent() && !_endp.isOutputShutdown()) - { - LOG.warn("Safety net oshut!!! IF YOU SEE THIS, PLEASE RAISE BUGZILLA"); - _endp.shutdownOutput(); - } - } - else - { - // We have finished parsing, but not generating so - // we must not be interested in reading until we - // have finished generating and we reset the generator - _readInterested = false; - LOG.debug("Disabled read interest while writing response {}", _endp); - } - } - } - } - } - finally - { - // Safety net to catch spinning - if (some_progress) - _total_no_progress = 0; - else - { - _total_no_progress++; - if (NO_PROGRESS_INFO>0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE)) - LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this); - if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE) - { - LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this); - if (_endp instanceof SelectChannelEndPoint) - _endp.getChannel().close(); - } - } - } - } - - @Override - public final void onInputShutdown() throws IOException - { - // If we don't have a committed response and we are not suspended - if (_generator.isIdle()) - { - // then no more can happen, so close. - _endp.close(); - } - - // Make idle parser seek EOF - if (_parser.isIdle()) - _parser.setPersistent(false); - } - - @Override - protected void reset() - { - _readInterested = true; - LOG.debug("Enabled read interest {}", _endp); - super.reset(); - } - - @Override - public boolean isSuspended() - { - return !_readInterested; - } -}
--- a/src/org/eclipse/jetty/server/BlockingHttpConnection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; - -import org.eclipse.jetty.http.HttpException; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.nio.ChannelEndPoint; -import org.eclipse.jetty.server.nio.BlockingChannelConnector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** Blocking Server HTTP Connection - */ -public final class BlockingHttpConnection extends AbstractHttpConnection -{ - private static final Logger LOG = LoggerFactory.getLogger(BlockingHttpConnection.class); - - public BlockingHttpConnection(BlockingChannelConnector connector, ChannelEndPoint endpoint) - { - super(connector,endpoint); - } - - @Override - public void handle() throws IOException - { - // do while the endpoint is open - // AND the connection has not changed - while (_endp.isOpen()) - { - try - { - // If we are not ended then parse available - if (!_parser.isComplete() && !_endp.isInputShutdown()) - _parser.parseAvailable(); - - // Do we have more generating to do? - // Loop here because some writes may take multiple steps and - // we need to flush them all before potentially blocking in the - // next loop. - if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown()) - _generator.flushBuffer(); - - // Flush buffers - _endp.flush(); - } - catch (HttpException e) - { - if (LOG.isDebugEnabled()) - { - LOG.debug("uri="+_uri); - LOG.debug("fields="+_requestFields); - LOG.debug("",e); - } - _generator.sendError(e.getStatus(), e.getReason(), null, true); - initParser(); - _endp.shutdownOutput(); - } - finally - { - // Is this request/response round complete and are fully flushed? - if (_parser.isComplete() && _generator.isComplete()) - { - // Reset the parser/generator - reset(); - - // TODO Is this required? - if (!_generator.isPersistent() && !_endp.isOutputShutdown()) - { - LOG.warn("Safety net oshut!!! Please open a bugzilla"); - _endp.shutdownOutput(); - } - } - - // If we don't have a committed response and we are not suspended - if (_endp.isInputShutdown() && _generator.isIdle()) - { - // then no more can happen, so close. - _endp.close(); - } - } - } - } -}
--- a/src/org/eclipse/jetty/server/Connector.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,282 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.nio.channels.ServerSocketChannel; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicLong; - -import javax.servlet.ServletRequest; - -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Abstract Connector implementation. This abstract implementation of the Connector interface provides: - * <ul> - * <li>AbstractLifeCycle implementation</li> - * <li>Implementations for connector getters and setters</li> - * <li>ByteBuffer management</li> - * <li>Socket configuration</li> - * <li>Base acceptor thread</li> - * <li>Optional reverse proxy headers checking</li> - * </ul> - */ -public abstract class Connector extends AggregateLifeCycle implements Dumpable, Runnable -{ - private static final Logger LOG = LoggerFactory.getLogger(Connector.class); - - private String _name; - - public final Server server; - private String _host; - public final int port; - - protected final int _maxIdleTime = 200000; - protected int _soLingerTime = -1; - - // from child classes - protected transient ServerSocketChannel _acceptChannel; - - protected Connector(Server server,int port) { - this.server = server; - this.port = port; - server.connectors.add(this); - } - - public final void setHost(String host) - { - _host = host; - } - - public final String getHost() - { - return _host; - } - - public final int getMaxIdleTime() - { - return _maxIdleTime; - } - - /* ------------------------------------------------------------ */ - /** - * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations - * other mechanisms may be used to implement the timeout. The max idle time is applied: - * <ul> - * <li>When waiting for a new request to be received on a connection</li> - * <li>When reading the headers and content of a request</li> - * <li>When writing the headers and content of a response</li> - * </ul> - * Jetty interprets this value as the maximum time between some progress being made on the connection. So if a single byte is read or written, then the - * timeout (if implemented by jetty) is reset. However, in many instances, the reading/writing is delegated to the JVM, and the semantic is more strictly - * enforced as the maximum time a single read/write operation can take. Note, that as Jetty supports writes of memory mapped file buffers, then a write may - * take many 10s of seconds for large content written to a slow device. - * <p> - * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so - * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand). - * - * @param maxIdleTime - * The maxIdleTime to set. - */ - - public final int getSoLingerTime() - { - return _soLingerTime; - } - - /* ------------------------------------------------------------ */ - /** - * @param soLingerTime - * The soLingerTime to set or -1 to disable. - */ - public final void setSoLingerTime(int soLingerTime) - { - _soLingerTime = soLingerTime; - } - - @Override - protected void doStart() throws Exception - { - super.doStart(); - - // Start selector thread - ThreadPoolExecutor _threadPool = server.threadPool; - _threadPool.execute(this); - if (server.isLowOnThreads()) - LOG.warn("insufficient threads configured for {}",this); - - LOG.info("Started {}",this); - } - - @Override - protected synchronized void doStop() throws Exception - { - try - { - if (_acceptChannel != null) - _acceptChannel.close(); - _acceptChannel=null; - } - catch (IOException e) - { - LOG.warn("",e); - } - - super.doStop(); - } - - - protected final void configure(Socket socket) throws IOException - { - socket.setTcpNoDelay(true); - if (_soLingerTime >= 0) - socket.setSoLinger(true,_soLingerTime / 1000); - else - socket.setSoLinger(false,0); - } - - public abstract void customize(AbstractHttpConnection con) throws IOException; - - public boolean isConfidential() - { - return false; - } - - protected abstract void accept() throws IOException, InterruptedException; - - @Override - public String toString() - { - return String.format("%s@%s:%d", - getClass().getSimpleName(), - getHost()==null?"0.0.0.0":getHost(), - port); - } - - - @Override - public void run() - { - Thread current = Thread.currentThread(); - String name = current.getName(); - current.setName(name + " Acceptor" + " " + Connector.this); - - try - { - while (isRunning() && _acceptChannel != null) - { - try - { - accept(); - } - catch (EofException e) - { - LOG.trace("",e); - } - catch (IOException e) - { - LOG.trace("",e); - } - catch (InterruptedException x) - { - // Connector has been stopped - LOG.trace("",x); - } - catch (Throwable e) - { - LOG.warn("",e); - } - } - } - finally - { - current.setName(name); - } - } - - public final String getName() - { - if (_name == null) - _name = (getHost() == null?"0.0.0.0":getHost()) + ":" + port; - return _name; - } - - - - // from HttpBuffersImpl - - protected int _requestHeaderSize = 6*1024; - protected int _requestBufferSize = 16*1024; - private final int _responseHeaderSize = 6*1024; - private final int _responseBufferSize = 32*1024; - - public final Buffers getRequestBuffers() - { - return new MyBuffers(_requestHeaderSize,_requestBufferSize); - } - - public final Buffers getResponseBuffers() - { - return new MyBuffers(_responseHeaderSize,_responseBufferSize); - } - - - // my own buffers - - protected ByteBuffer newBuffer(int size) { - return ByteBuffer.allocateDirect(size); - } - - private class MyBuffers implements Buffers { - private final int headerSize; - private final int bufferSize; - - MyBuffers(int headerSize,int bufferSize) { - this.headerSize = headerSize; - this.bufferSize = bufferSize; - } - - @Override - public ByteBuffer getHeader() { - return ByteBuffer.allocate(headerSize); - } - - @Override - public ByteBuffer getBuffer() { - return newBuffer(bufferSize); - } - - @Override - public ByteBuffer getBuffer(int size) { - return newBuffer(size); - } - } -}
--- a/src/org/eclipse/jetty/server/CookieCutter.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,335 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; -import java.util.Locale; - -import javax.servlet.http.Cookie; - -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** Cookie parser - * <p>Optimized stateful cookie parser. Cookies fields are added with the - * {@link #addCookieField(String)} method and parsed on the next subsequent - * call to {@link #getCookies()}. - * If the added fields are identical to those last added (as strings), then the - * cookies are not re parsed. - * - * - */ -public class CookieCutter -{ - private static final Logger LOG = LoggerFactory.getLogger(CookieCutter.class); - - - private Cookie[] _cookies; - private Cookie[] _lastCookies; - Object _lazyFields; - int _fields; - - public CookieCutter() - { - } - - public Cookie[] getCookies() - { - if (_cookies!=null) - return _cookies; - - if (_lastCookies!=null && - _lazyFields!=null && - _fields==LazyList.size(_lazyFields)) - _cookies=_lastCookies; - else - parseFields(); - _lastCookies=_cookies; - return _cookies; - } - - public void setCookies(Cookie[] cookies) - { - _cookies=cookies; - _lastCookies=null; - _lazyFields=null; - _fields=0; - } - - public void reset() - { - _cookies=null; - _fields=0; - } - - public void addCookieField(String f) - { - if (f==null) - return; - f=f.trim(); - if (f.length()==0) - return; - - if (LazyList.size(_lazyFields)>_fields) - { - if (f.equals(LazyList.get(_lazyFields,_fields))) - { - _fields++; - return; - } - - while (LazyList.size(_lazyFields)>_fields) - _lazyFields=LazyList.remove(_lazyFields,_fields); - } - _cookies=null; - _lastCookies=null; - _lazyFields=LazyList.add(_lazyFields,_fields++,f); - } - - - protected void parseFields() - { - _lastCookies=null; - _cookies=null; - - Object cookies = null; - - int version = 0; - - // delete excess fields - while (LazyList.size(_lazyFields)>_fields) - _lazyFields=LazyList.remove(_lazyFields,_fields); - - // For each cookie field - for (int f=0;f<_fields;f++) - { - String hdr = LazyList.get(_lazyFields,f); - - // Parse the header - String name = null; - String value = null; - - Cookie cookie = null; - - boolean invalue=false; - boolean quoted=false; - boolean escaped=false; - int tokenstart=-1; - int tokenend=-1; - for (int i = 0, length = hdr.length(), last=length-1; i < length; i++) - { - char c = hdr.charAt(i); - - // Handle quoted values for name or value - if (quoted) - { - if (escaped) - { - escaped=false; - continue; - } - - switch (c) - { - case '"': - tokenend=i; - quoted=false; - - // handle quote as last character specially - if (i==last) - { - if (invalue) - value = hdr.substring(tokenstart, tokenend+1); - else - { - name = hdr.substring(tokenstart, tokenend+1); - value = ""; - } - } - break; - - case '\\': - escaped=true; - continue; - default: - continue; - } - } - else - { - // Handle name and value state machines - if (invalue) - { - // parse the value - switch (c) - { - case ' ': - case '\t': - continue; - - case '"': - if (tokenstart<0) - { - quoted=true; - tokenstart=i; - } - tokenend=i; - if (i==last) - { - value = hdr.substring(tokenstart, tokenend+1); - break; - } - continue; - - case ';': - // case ',': - if (tokenstart>=0) - value = hdr.substring(tokenstart, tokenend+1); - else - value=""; - tokenstart = -1; - invalue=false; - break; - - default: - if (tokenstart<0) - tokenstart=i; - tokenend=i; - if (i==last) - { - value = hdr.substring(tokenstart, tokenend+1); - break; - } - continue; - } - } - else - { - // parse the name - switch (c) - { - case ' ': - case '\t': - continue; - - case '"': - if (tokenstart<0) - { - quoted=true; - tokenstart=i; - } - tokenend=i; - if (i==last) - { - name = hdr.substring(tokenstart, tokenend+1); - value = ""; - break; - } - continue; - - case ';': - // case ',': - if (tokenstart>=0) - { - name = hdr.substring(tokenstart, tokenend+1); - value = ""; - } - tokenstart = -1; - break; - - case '=': - if (tokenstart>=0) - name = hdr.substring(tokenstart, tokenend+1); - tokenstart = -1; - invalue=true; - continue; - - default: - if (tokenstart<0) - tokenstart=i; - tokenend=i; - if (i==last) - { - name = hdr.substring(tokenstart, tokenend+1); - value = ""; - break; - } - continue; - } - } - } - - // If after processing the current character we have a value and a name, then it is a cookie - if (value!=null && name!=null) - { - // TODO handle unquoting during parsing! But quoting is uncommon - name=QuotedStringTokenizer.unquoteOnly(name); - value=QuotedStringTokenizer.unquoteOnly(value); - - try - { - if (name.startsWith("$")) - { - String lowercaseName = name.toLowerCase(Locale.ENGLISH); - if ("$path".equals(lowercaseName)) - { - if (cookie!=null) - cookie.setPath(value); - } - else if ("$domain".equals(lowercaseName)) - { - if (cookie!=null) - cookie.setDomain(value); - } - else if ("$port".equals(lowercaseName)) - { - if (cookie!=null) - cookie.setComment("$port="+value); - } - else if ("$version".equals(lowercaseName)) - { - version = Integer.parseInt(value); - } - } - else - { - cookie = new Cookie(name, value); - if (version > 0) - cookie.setVersion(version); - cookies = LazyList.add(cookies, cookie); - } - } - catch (Exception e) - { - LOG.debug("",e); - } - - name = null; - value = null; - } - } - } - - _cookies = (Cookie[]) LazyList.toArray(cookies,Cookie.class); - _lastCookies=_cookies; - } - -}
--- a/src/org/eclipse/jetty/server/Handler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.component.LifeCycle; - -/* ------------------------------------------------------------ */ -/** A Jetty Server Handler. - * - * A Handler instance is required by a {@link Server} to handle incoming - * HTTP requests. A Handler may: <ul> - * <li>Completely generate the HTTP Response</li> - * <li>Examine/modify the request and call another Handler (see {@link HandlerWrapper}). - * <li>Pass the request to one or more other Handlers (see {@link HandlerCollection}). - * </ul> - * - * Handlers are passed the servlet API request and response object, but are - * not Servlets. The servlet container is implemented by handlers for - * context, security, session and servlet that modify the request object - * before passing it to the next stage of handling. - * - */ -public interface Handler extends LifeCycle, Destroyable -{ - /* ------------------------------------------------------------ */ - /** Handle a request. - * @param target The target of the request - either a URI or a name. - * @param baseRequest The original unwrapped request object. - * @param request The request either as the {@link Request} - * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()} - * method can be used access the Request object if required. - * @param response The response as the {@link Response} - * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()} - * method can be used access the Response object if required. - * @throws IOException - * @throws ServletException - */ - public void handle(String target, Request request, HttpServletResponse response) - throws IOException, ServletException; - - public void setServer(Server server); - public Server getServer(); - - public void destroy(); - -} -
--- a/src/org/eclipse/jetty/server/HandlerContainer.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import org.eclipse.jetty.util.component.LifeCycle; - -/** - * A Handler that contains other Handlers. - * <p> - * The contained handlers may be one (see @{link {@link org.eclipse.jetty.server.handler.HandlerWrapper}) - * or many (see {@link org.eclipse.jetty.server.handler.HandlerList} or {@link org.eclipse.jetty.server.handler.HandlerCollection}. - * - */ -public interface HandlerContainer extends LifeCycle -{ - /* ------------------------------------------------------------ */ - /** - * @return array of handlers directly contained by this handler. - */ - public Handler[] getHandlers(); - - /* ------------------------------------------------------------ */ - /** - * @return array of all handlers contained by this handler and it's children - */ - public Handler[] getChildHandlers(); - - /* ------------------------------------------------------------ */ - /** - * @param byclass - * @return array of all handlers contained by this handler and it's children of the passed type. - */ - public Handler[] getChildHandlersByClass(Class<?> byclass); - - /* ------------------------------------------------------------ */ - /** - * @param byclass - * @return first handler of all handlers contained by this handler and it's children of the passed type. - */ - public <T extends Handler> T getChildHandlerByClass(Class<T> byclass); -}
--- a/src/org/eclipse/jetty/server/HttpWriter.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,290 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; - -import org.eclipse.jetty.http.HttpGenerator; -import org.eclipse.jetty.util.ByteArrayOutputStream2; -import org.eclipse.jetty.util.StringUtil; - -/** OutputWriter. - * A writer that can wrap a {@link AbstractHttpConnection.Output} stream and provide - * character encodings. - * - * The UTF-8 encoding is done by this class and no additional - * buffers or Writers are used. - * The UTF-8 code was inspired by http://javolution.org - */ -public final class HttpWriter extends Writer -{ - private static final int MAX_OUTPUT_CHARS = 512; - - private static final int WRITE_CONV = 0; - private static final int WRITE_ISO1 = 1; - private static final int WRITE_UTF8 = 2; - - private final AbstractHttpConnection.Output _out; - private int _writeMode; - private int _surrogate; - - public HttpWriter(AbstractHttpConnection.Output out) - { - _out = out; - _surrogate = 0; // AS lastUTF16CodePoint - } - - public void setCharacterEncoding(String encoding) - { - if (encoding == null || StringUtil.__ISO_8859_1.equalsIgnoreCase(encoding)) - { - _writeMode = WRITE_ISO1; - } - else if (StringUtil.__UTF8.equalsIgnoreCase(encoding)) - { - _writeMode = WRITE_UTF8; - } - else - { - _writeMode = WRITE_CONV; - if (_out._characterEncoding == null || !_out._characterEncoding.equalsIgnoreCase(encoding)) - _out._converter = null; // Set lazily in getConverter() - } - - _out._characterEncoding = encoding; - if (_out._bytes==null) - _out._bytes = new ByteArrayOutputStream2(MAX_OUTPUT_CHARS); - } - - @Override - public void close() throws IOException - { - _out.close(); - } - - @Override - public void flush() throws IOException - { - _out.flush(); - } - - @Override - public void write (String s,int offset, int length) throws IOException - { - while (length > MAX_OUTPUT_CHARS) - { - write(s, offset, MAX_OUTPUT_CHARS); - offset += MAX_OUTPUT_CHARS; - length -= MAX_OUTPUT_CHARS; - } - - if (_out._chars==null) - { - _out._chars = new char[MAX_OUTPUT_CHARS]; - } - char[] chars = _out._chars; - s.getChars(offset, offset + length, chars, 0); - write(chars, 0, length); - } - - @Override - public void write (char[] s,int offset, int length) throws IOException - { - while (length > 0) - { - _out._bytes.reset(); - int chars = length>MAX_OUTPUT_CHARS?MAX_OUTPUT_CHARS:length; - - switch (_writeMode) - { - case WRITE_CONV: - { - Writer converter = getConverter(); - converter.write(s, offset, chars); - converter.flush(); - } - break; - - case WRITE_ISO1: - { - byte[] buffer = _out._bytes.getBuf(); - int bytes = _out._bytes.getCount(); - - if (chars>buffer.length-bytes) - chars=buffer.length-bytes; - - for (int i = 0; i < chars; i++) - { - int c = s[offset+i]; - buffer[bytes++]=(byte)(c<256?c:'?'); // ISO-1 and UTF-8 match for 0 - 255 - } - if (bytes>=0) - _out._bytes.setCount(bytes); - - break; - } - - case WRITE_UTF8: - { - byte[] buffer = _out._bytes.getBuf(); - int bytes = _out._bytes.getCount(); - - if (bytes+chars>buffer.length) - chars=buffer.length-bytes; - - for (int i = 0; i < chars; i++) - { - int code = s[offset+i]; - - // Do we already have a surrogate? - if(_surrogate==0) - { - // No - is this char code a surrogate? - if(Character.isHighSurrogate((char)code)) - { - _surrogate=code; // UCS-? - continue; - } - } - // else handle a low surrogate - else if(Character.isLowSurrogate((char)code)) - { - code = Character.toCodePoint((char)_surrogate, (char)code); // UCS-4 - } - // else UCS-2 - else - { - code=_surrogate; // UCS-2 - _surrogate=0; // USED - i--; - } - - if ((code & 0xffffff80) == 0) - { - // 1b - if (bytes>=buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(code); - } - else - { - if((code&0xfffff800)==0) - { - // 2b - if (bytes+2>buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(0xc0|(code>>6)); - buffer[bytes++]=(byte)(0x80|(code&0x3f)); - } - else if((code&0xffff0000)==0) - { - // 3b - if (bytes+3>buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(0xe0|(code>>12)); - buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f)); - buffer[bytes++]=(byte)(0x80|(code&0x3f)); - } - else if((code&0xff200000)==0) - { - // 4b - if (bytes+4>buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(0xf0|(code>>18)); - buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f)); - buffer[bytes++]=(byte)(0x80|(code&0x3f)); - } - else if((code&0xf4000000)==0) - { - // 5b - if (bytes+5>buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(0xf8|(code>>24)); - buffer[bytes++]=(byte)(0x80|((code>>18)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f)); - buffer[bytes++]=(byte)(0x80|(code&0x3f)); - } - else if((code&0x80000000)==0) - { - // 6b - if (bytes+6>buffer.length) - { - chars=i; - break; - } - buffer[bytes++]=(byte)(0xfc|(code>>30)); - buffer[bytes++]=(byte)(0x80|((code>>24)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>18)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f)); - buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f)); - buffer[bytes++]=(byte)(0x80|(code&0x3f)); - } - else - { - buffer[bytes++]=(byte)('?'); - } - - _surrogate=0; // USED - - if (bytes==buffer.length) - { - chars=i+1; - break; - } - } - } - _out._bytes.setCount(bytes); - break; - } - default: - throw new IllegalStateException(); - } - - _out._bytes.writeTo(_out); - length-=chars; - offset+=chars; - } - } - - private Writer getConverter() throws IOException - { - if (_out._converter == null) - _out._converter = new OutputStreamWriter(_out._bytes, _out._characterEncoding); - return _out._converter; - } -}
--- a/src/org/eclipse/jetty/server/Request.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1040 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.security.Principal; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.TimeZone; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; - -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestAttributeEvent; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpParser; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.http.HttpVersions; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.Attributes; -import org.eclipse.jetty.util.AttributesMap; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.UrlEncoded; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * Jetty Request. - * <p> - * Implements {@link javax.servlet.http.HttpServletRequest} from the <code>javax.servlet.http</code> package. - * </p> - * <p> - * The standard interface of mostly getters, is extended with setters so that the request is mutable by the handlers that it is passed to. This allows the - * request object to be as lightweight as possible and not actually implement any significant behavior. For example - * <ul> - * - * <li>The {@link Request#getContextPath()} method will return null, until the request has been passed to a {@link ContextHandler} which matches the - * {@link Request#getPathInfo()} with a context path and calls {@link Request#setContextPath(String)} as a result.</li> - * - * <li>The {@link Request#getServletPath()} method will return null until the request has been passed to a <code>org.eclipse.jetty.servlet.ServletHandler</code> - * and the pathInfo matched against the servlet URL patterns and {@link Request#setServletPath(String)} called as a result.</li> - * </ul> - * - * A request instance is created for each {@link AbstractHttpConnection} accepted by the server and recycled for each HTTP request received via that connection. - * An effort is made to avoid reparsing headers and cookies that are likely to be the same for requests from the same connection. - * - * <p> - * The form content that a request can process is limited to protect from Denial of Service attacks. The size in bytes is limited by - * {@link ContextHandler#getMaxFormContentSize()} or if there is no context then the "org.eclipse.jetty.server.Request.maxFormContentSize" {@link Server} - * attribute. The number of parameters keys is limited by {@link ContextHandler#getMaxFormKeys()} or if there is no context then the - * "org.eclipse.jetty.server.Request.maxFormKeys" {@link Server} attribute. - * - * - */ -public final class Request implements HttpServletRequest -{ - private static final Logger LOG = LoggerFactory.getLogger(Request.class); - - private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); - private static final int __NONE = 0, _STREAM = 1; - - private volatile Attributes _attributes; - private MultiMap<String> _baseParameters; - private String _characterEncoding; - protected final AbstractHttpConnection _connection; - public ContextHandler _contextHandler = null; - private String _contextPath; - private CookieCutter _cookies; - private boolean _cookiesExtracted = false; - private final EndPoint _endp; - private boolean _handled = false; - private int _inputState = __NONE; - private String _method; - private MultiMap<String> _parameters; - private boolean _paramsExtracted; - private String _pathInfo; - private int _port; - private String _protocol = HttpVersions.HTTP_1_1; - private String _queryString; - private String _readerEncoding; - private String _requestURI; - private String _scheme = "http"; - private String _serverName; - private long _timeStamp; - - private HttpURI _uri; - - public Request(AbstractHttpConnection connection) - { - _connection = connection; - _endp = connection._endp; - } - - /* ------------------------------------------------------------ */ - /** - * Extract Parameters from query string and/or form _content. - */ - private void extractParameters() - { - if (_baseParameters == null) - _baseParameters = new MultiMap(16); - - if (_paramsExtracted) - { - if (_parameters == null) - _parameters = _baseParameters; - return; - } - - _paramsExtracted = true; - - try - { - // Handle query string - if (_uri != null && _uri.hasQuery()) - { - _uri.decodeQueryTo(_baseParameters); - } - - // handle any _content. - String encoding = getCharacterEncoding(); - String content_type = getContentType(); - if (content_type != null && content_type.length() > 0) - { - content_type = HttpFields.valueParameters(content_type,null); - - if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE - && ("POST".equals(getMethod()) || "PUT".equals(getMethod()))) - { - int content_length = getContentLength(); - if (content_length != 0) - { - try - { - int maxFormContentSize = -1; - int maxFormKeys = -1; - - if (maxFormContentSize < 0) - { - maxFormContentSize = 200000; - } - - if (maxFormKeys < 0) - { - maxFormKeys = 1000; - } - - if (content_length > maxFormContentSize && maxFormContentSize > 0) - { - throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize); - } - InputStream in = getInputStream(); - - // Add form params to query params - UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys); - } - catch (IOException e) - { - if (LOG.isDebugEnabled()) - LOG.warn("",e); - else - LOG.warn(e.toString()); - } - } - } - - } - - if (_parameters == null) - _parameters = _baseParameters; - else if (_parameters != _baseParameters) - { - // Merge parameters (needed if parameters extracted after a forward). - Iterator iter = _baseParameters.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry entry = (Map.Entry)iter.next(); - String name = (String)entry.getKey(); - Object values = entry.getValue(); - for (int i = 0; i < LazyList.size(values); i++) - _parameters.add(name,LazyList.get(values,i)); - } - } - } - finally - { - // ensure params always set (even if empty) after extraction - if (_parameters == null) - _parameters = _baseParameters; - } - } - - @Override - public AsyncContext getAsyncContext() - { - throw new UnsupportedOperationException(); - } - - @Override - public Object getAttribute(String name) - { - return (_attributes == null)?null:_attributes.getAttribute(name); - } - - @Override - public Enumeration getAttributeNames() - { - if (_attributes == null) - return Collections.enumeration(Collections.EMPTY_LIST); - - return AttributesMap.getAttributeNamesCopy(_attributes); - } - - @Override - public String getAuthType() - { - return null; - } - - @Override - public String getCharacterEncoding() - { - return _characterEncoding; - } - - @Override - public int getContentLength() - { - return (int)_connection._requestFields.getLongField(HttpHeaders.CONTENT_LENGTH); - } - - @Override - public String getContentType() - { - return _connection._requestFields.getStringField(HttpHeaders.CONTENT_TYPE); - } - - @Override - public String getContextPath() - { - return _contextPath; - } - - @Override - public Cookie[] getCookies() - { - if (_cookiesExtracted) - return _cookies == null?null:_cookies.getCookies(); - - _cookiesExtracted = true; - - Enumeration enm = _connection._requestFields.getValues(HttpHeaders.COOKIE); - - // Handle no cookies - if (enm != null) - { - if (_cookies == null) - _cookies = new CookieCutter(); - - while (enm.hasMoreElements()) - { - String c = (String)enm.nextElement(); - _cookies.addCookieField(c); - } - } - - return _cookies == null?null:_cookies.getCookies(); - } - - @Override - public long getDateHeader(String name) - { - return _connection._requestFields.getDateField(name); - } - - @Override - public DispatcherType getDispatcherType() - { - throw new UnsupportedOperationException(); - } - - @Override - public String getHeader(String name) - { - return _connection._requestFields.getStringField(name); - } - - @Override - public Enumeration getHeaderNames() - { - return _connection._requestFields.getFieldNames(); - } - - @Override - public Enumeration getHeaders(String name) - { - Enumeration e = _connection._requestFields.getValues(name); - if (e == null) - return Collections.enumeration(Collections.EMPTY_LIST); - return e; - } - - @Override - public ServletInputStream getInputStream() throws IOException - { - _inputState = _STREAM; - return _connection.getInputStream(); - } - - @Override - public int getIntHeader(String name) - { - return (int)_connection._requestFields.getLongField(name); - } - - @Override - public String getLocalAddr() - { - return _endp.getLocalAddr(); - } - - @Override - public Locale getLocale() - { - Enumeration enm = _connection._requestFields.getValues( "Accept-Language", ", \t" ); - - // handle no locale - if (enm == null || !enm.hasMoreElements()) - return Locale.getDefault(); - - // sort the list in quality order - List acceptLanguage = HttpFields.qualityList(enm); - if (acceptLanguage.size() == 0) - return Locale.getDefault(); - - int size = acceptLanguage.size(); - - if (size > 0) - { - String language = (String)acceptLanguage.get(0); - language = HttpFields.valueParameters(language,null); - String country = ""; - int dash = language.indexOf('-'); - if (dash > -1) - { - country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); - } - return new Locale(language,country); - } - - return Locale.getDefault(); - } - - @Override - public Enumeration getLocales() - { - - Enumeration enm = _connection._requestFields.getValues( "Accept-Language", ", \t" ); - - // handle no locale - if (enm == null || !enm.hasMoreElements()) - return Collections.enumeration(__defaultLocale); - - // sort the list in quality order - List acceptLanguage = HttpFields.qualityList(enm); - - if (acceptLanguage.size() == 0) - return Collections.enumeration(__defaultLocale); - - Object langs = null; - int size = acceptLanguage.size(); - - // convert to locals - for (int i = 0; i < size; i++) - { - String language = (String)acceptLanguage.get(i); - language = HttpFields.valueParameters(language,null); - String country = ""; - int dash = language.indexOf('-'); - if (dash > -1) - { - country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); - } - langs = LazyList.ensureSize(langs,size); - langs = LazyList.add(langs,new Locale(language,country)); - } - - if (LazyList.size(langs) == 0) - return Collections.enumeration(__defaultLocale); - - return Collections.enumeration(LazyList.getList(langs)); - } - - @Override - public String getLocalName() - { - String local = _endp.getLocalAddr(); - if (local != null && local.indexOf(':') >= 0) - local = "[" + local + "]"; - return local; - } - - @Override - public int getLocalPort() - { - return _endp.getLocalPort(); - } - - @Override - public String getMethod() - { - return _method; - } - - @Override - public String getParameter(String name) - { - if (!_paramsExtracted) - extractParameters(); - return (String)_parameters.getValue(name,0); - } - - @Override - public Map<String,String[]> getParameterMap() - { - if (!_paramsExtracted) - extractParameters(); - - return Collections.unmodifiableMap(_parameters.toStringArrayMap()); - } - - @Override - public Enumeration getParameterNames() - { - if (!_paramsExtracted) - extractParameters(); - return Collections.enumeration(_parameters.keySet()); - } - - @Override - public String[] getParameterValues(String name) - { - if (!_paramsExtracted) - extractParameters(); - List<Object> vals = _parameters.getValues(name); - if (vals == null) - return null; - return vals.toArray(new String[vals.size()]); - } - - @Override - public String getPathInfo() - { - return _pathInfo; - } - - @Override - public String getPathTranslated() - { - return null; - } - - @Override - public String getProtocol() - { - return _protocol; - } - - @Override - public String getQueryString() - { - if (_queryString == null && _uri != null) - { - _queryString = _uri.getQuery(); - } - return _queryString; - } - - @Override - public BufferedReader getReader() throws IOException - { - throw new UnsupportedOperationException(); - } - - @Override - public String getRealPath(String path) - { - return null; - } - - @Override - public String getRemoteAddr() - { - return _endp.getRemoteAddr(); - } - - @Override - public String getRemoteHost() - { - return getRemoteAddr(); - } - - @Override - public int getRemotePort() - { - return _endp.getRemotePort(); - } - - @Override - public String getRemoteUser() - { - return null; - } - - @Override - public RequestDispatcher getRequestDispatcher(String path) - { - throw new UnsupportedOperationException(); - } - - @Override - public String getRequestedSessionId() - { - throw new UnsupportedOperationException(); - } - - @Override - public String getRequestURI() - { - if (_requestURI == null && _uri != null) - _requestURI = _uri.getPathAndParam(); - return _requestURI; - } - - @Override - public StringBuffer getRequestURL() - { - final StringBuffer url = new StringBuffer(48); - synchronized (url) - { - String scheme = getScheme(); - int port = getServerPort(); - - url.append(scheme); - url.append("://"); - url.append(getServerName()); - if (_port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) - { - url.append(':'); - url.append(_port); - } - - url.append(getRequestURI()); - return url; - } - } - - /* ------------------------------------------------------------ */ - /** - * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a - * path. - * <p> - * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters. - * - * This method is useful for creating redirect messages and for reporting errors. - * - * @return "scheme://host:port" - */ - public StringBuilder getRootURL() - { - StringBuilder url = new StringBuilder(48); - String scheme = getScheme(); - int port = getServerPort(); - - url.append(scheme); - url.append("://"); - url.append(getServerName()); - - if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) - { - url.append(':'); - url.append(port); - } - return url; - } - - @Override - public String getScheme() - { - return _scheme; - } - - @Override - public String getServerName() - { - // Return already determined host - if (_serverName != null) - return _serverName; - - if (_uri == null) - throw new IllegalStateException("No uri"); - - // Return host from absolute URI - _serverName = _uri.getHost(); - _port = _uri.getPort(); - if (_serverName != null) - return _serverName; - - // Return host from header field - String hostPort = _connection._requestFields.getStringField(HttpHeaders.HOST); - if (hostPort != null) - { - loop: for (int i = hostPort.length(); i-- > 0;) - { - char ch = hostPort.charAt(i); - switch (ch) - { - case ']': - break loop; - - case ':': - _serverName = hostPort.substring(0,i); - try - { - _port = Integer.parseInt(hostPort.substring(i + 1)); - } - catch (NumberFormatException e) - { - try - { - _connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true); - } - catch (IOException e1) - { - throw new RuntimeException(e1); - } - } - return _serverName; - } - } - if (_serverName == null || _port < 0) - { - _serverName = hostPort; - _port = 0; - } - - return _serverName; - } - - // Return host from connection - _serverName = getLocalName(); - _port = getLocalPort(); - if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName)) - return _serverName; - - // Return the local host - try - { - _serverName = InetAddress.getLocalHost().getHostAddress(); - } - catch (java.net.UnknownHostException e) - { - LOG.trace("",e); - } - return _serverName; - } - - @Override - public int getServerPort() - { - if (_port <= 0) - { - if (_serverName == null) - getServerName(); - - if (_port <= 0) - { - if (_serverName != null && _uri != null) - _port = _uri.getPort(); - else - _port = _endp.getLocalPort(); - } - } - - if (_port <= 0) - { - if (getScheme().equalsIgnoreCase("https")) - return 443; - return 80; - } - return _port; - } - - @Override - public ServletContext getServletContext() - { - throw new UnsupportedOperationException(); - } - - @Override - public String getServletPath() - { - throw new UnsupportedOperationException(); - } - - @Override - public HttpSession getSession() - { - throw new UnsupportedOperationException(); - } - - @Override - public HttpSession getSession(boolean create) - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - /** - * Get Request TimeStamp - * - * @return The time that the request was received. - */ - public long getTimeStamp() - { - return _timeStamp; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the uri. - */ - public HttpURI getUri() - { - return _uri; - } - - @Override - public Principal getUserPrincipal() - { - return null; - } - - public boolean isHandled() - { - return _handled; - } - - @Override - public boolean isAsyncStarted() - { - return false; - } - - @Override - public boolean isAsyncSupported() - { - return false; - } - - @Override - public boolean isRequestedSessionIdFromCookie() - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdFromUrl() - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdFromURL() - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdValid() - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isSecure() - { - return _connection.getConnector().isConfidential(); - } - - @Override - public boolean isUserInRole(String role) - { - return false; - } -/* - protected void recycle() - { - _handled = false; - if (_contextHandler != null) - throw new IllegalStateException("Request in context!"); - if (_attributes != null) - _attributes.clearAttributes(); - _characterEncoding = null; - _contextPath = null; - if (_cookies != null) - _cookies.reset(); - _cookiesExtracted = false; - _serverName = null; - _method = null; - _pathInfo = null; - _port = 0; - _protocol = HttpVersions.HTTP_1_1; - _queryString = null; - _requestURI = null; - _scheme = "http"; - _timeStamp = 0; - _uri = null; - if (_baseParameters != null) - _baseParameters.clear(); - _parameters = null; - _paramsExtracted = false; - _inputState = __NONE; - } -*/ - @Override - public void removeAttribute(String name) - { - if (_attributes != null) - _attributes.removeAttribute(name); - } - - /* ------------------------------------------------------------ */ - /* - * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to - * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link - * #flushResponseBuffer}. - * - * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) - */ - @Override - public void setAttribute(String name, Object value) - { - if (_attributes == null) - _attributes = new AttributesMap(); - _attributes.setAttribute(name,value); - } - - @Override - public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException - { - if (_inputState != __NONE) - return; - - _characterEncoding = encoding; - - // check encoding is supported - if (!StringUtil.isUTF8(encoding)) - // noinspection ResultOfMethodCallIgnored - "".getBytes(encoding); - } - - public void setCharacterEncodingUnchecked(String encoding) - { - _characterEncoding = encoding; - } - - public void setContextPath(String contextPath) - { - _contextPath = contextPath; - } - -/* - public void setCookies(Cookie[] cookies) - { - if (_cookies == null) - _cookies = new CookieCutter(); - _cookies.setCookies(cookies); - } -*/ - - public void setHandled(boolean h) - { - _handled = h; - } - - public void setMethod(String method) - { - _method = method; - } - - private void setParameters(MultiMap<String> parameters) - { - _parameters = (parameters == null)?_baseParameters:parameters; - if (_paramsExtracted && _parameters == null) - throw new IllegalStateException(); - } - - public void setPathInfo(String pathInfo) - { - _pathInfo = pathInfo; - } - - public void setProtocol(String protocol) - { - _protocol = protocol; - } - - public void setRequestURI(String requestURI) - { - _requestURI = requestURI; - } - - public void setScheme(String scheme) - { - _scheme = scheme; - } - - public void setTimeStamp(long ts) - { - _timeStamp = ts; - } - - public void setUri(HttpURI uri) - { - _uri = uri; - } - - @Override - public AsyncContext startAsync() throws IllegalStateException - { - throw new UnsupportedOperationException(); - } - - @Override - public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException - { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() - { - return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString(); - } - - @Override - public boolean authenticate(HttpServletResponse response) throws IOException, ServletException - { - throw new UnsupportedOperationException(); - } - - @Override - public Part getPart(String name) throws IOException, ServletException - { - throw new UnsupportedOperationException(); - } - - @Override - public Collection<Part> getParts() throws IOException, ServletException - { - throw new UnsupportedOperationException(); - } - - @Override - public void login(String username, String password) throws ServletException - { - throw new UnsupportedOperationException(); - } - - @Override - public void logout() throws ServletException - { - throw new UnsupportedOperationException(); - } - -}
--- a/src/org/eclipse/jetty/server/Response.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,887 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Collection; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Enumeration; -import java.util.Locale; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletOutputStream; -import javax.servlet.SessionTrackingMode; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpHeaderValues; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.http.HttpVersions; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.ByteArrayISO8859Writer; -import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Response. - * <p> - * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package. - * </p> - */ -public final class Response implements HttpServletResponse -{ - private static final Logger LOG = LoggerFactory.getLogger(Response.class); - - - public static final int - NONE=0, - STREAM=1, - WRITER=2; - - /** - * If a header name starts with this string, the header (stripped of the prefix) - * can be set during include using only {@link #setHeader(String, String)} or - * {@link #addHeader(String, String)}. - */ - public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include."; - - /** - * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie - * will be set as HTTP ONLY. - */ - public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__"; - - private final AbstractHttpConnection _connection; - private int _status = SC_OK; - private String _reason; - private Locale _locale; - private String _mimeType; - private String _cachedMimeType; - private String _characterEncoding; - private boolean _explicitEncoding; - private String _contentType; - private volatile int _outputState; - private PrintWriter _writer; - - public Response(AbstractHttpConnection connection) - { - _connection = connection; - } - - public void addCookie(HttpCookie cookie) - { - _connection._responseFields.addSetCookie(cookie); - } - - @Override - public void addCookie(Cookie cookie) - { - String comment=cookie.getComment(); - boolean http_only=false; - - if (comment!=null) - { - int i=comment.indexOf(HTTP_ONLY_COMMENT); - if (i>=0) - { - http_only=true; - comment=comment.replace(HTTP_ONLY_COMMENT,"").trim(); - if (comment.length()==0) - comment=null; - } - } - _connection._responseFields.addSetCookie(cookie.getName(), - cookie.getValue(), - cookie.getDomain(), - cookie.getPath(), - cookie.getMaxAge(), - comment, - cookie.getSecure(), - http_only || cookie.isHttpOnly(), - cookie.getVersion()); - } - - @Override - public boolean containsHeader(String name) - { - return _connection._responseFields.containsKey(name); - } - - @Override - public String encodeURL(String url) - { - throw new UnsupportedOperationException(); - } - - @Override - public String encodeRedirectURL(String url) - { - throw new UnsupportedOperationException(); - } - - @Override - @Deprecated - public String encodeUrl(String url) - { - throw new UnsupportedOperationException(); - } - - @Override - @Deprecated - public String encodeRedirectUrl(String url) - { - throw new UnsupportedOperationException(); - } - - @Override - public void sendError(int code, String message) throws IOException - { - if (isCommitted()) - LOG.warn("Committed before "+code+" "+message); - - resetBuffer(); - _characterEncoding = null; - setHeader(HttpHeaders.EXPIRES,null); - setHeader(HttpHeaders.LAST_MODIFIED,null); - setHeader(HttpHeaders.CACHE_CONTROL,null); - setHeader(HttpHeaders.CONTENT_TYPE,null); - setHeader(HttpHeaders.CONTENT_LENGTH,null); - - _outputState = NONE; - setStatus(code,message); - - if (message==null) - message=HttpStatus.getMessage(code); - - // If we are allowed to have a body - if (code!=SC_NO_CONTENT && - code!=SC_NOT_MODIFIED && - code!=SC_PARTIAL_CONTENT && - code>=SC_OK) - { - Request request = _connection.getRequest(); - - setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store"); - setContentType(MimeTypes.TEXT_HTML_8859_1); - ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048); - if (message != null) - { - message= StringUtil.replace(message, "&", "&"); - message= StringUtil.replace(message, "<", "<"); - message= StringUtil.replace(message, ">", ">"); - } - String uri= request.getRequestURI(); - if (uri!=null) - { - uri= StringUtil.replace(uri, "&", "&"); - uri= StringUtil.replace(uri, "<", "<"); - uri= StringUtil.replace(uri, ">", ">"); - } - - writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n"); - writer.write("<title>Error "); - writer.write(Integer.toString(code)); - writer.write(' '); - if (message==null) - message=HttpStatus.getMessage(code); - writer.write(message); - writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: "); - writer.write(Integer.toString(code)); - writer.write("</h2>\n<p>Problem accessing "); - writer.write(uri); - writer.write(". Reason:\n<pre> "); - writer.write(message); - writer.write("</pre>"); - writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>"); - - for (int i= 0; i < 20; i++) - writer.write("\n "); - writer.write("\n</body>\n</html>\n"); - - writer.flush(); - setContentLength(writer.size()); - writer.writeTo(getOutputStream()); - writer.destroy(); - } - else if (code!=SC_PARTIAL_CONTENT) - { - _connection._requestFields.remove(HttpHeaders.CONTENT_TYPE); - _connection._requestFields.remove(HttpHeaders.CONTENT_LENGTH); - _characterEncoding = null; - _mimeType = null; - _cachedMimeType = null; - } - - complete(); - } - - @Override - public void sendError(int sc) throws IOException - { - sendError(sc,null); - } - - @Override - public void sendRedirect(String location) throws IOException - { - if (location==null) - throw new IllegalArgumentException(); - - if (!URIUtil.hasScheme(location)) - { - StringBuilder buf = _connection.getRequest().getRootURL(); - if (location.startsWith("/")) - buf.append(location); - else - { - String path=_connection.getRequest().getRequestURI(); - String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path); - location=URIUtil.addPaths(parent,location); - if(location==null) - throw new IllegalStateException("path cannot be above root"); - if (!location.startsWith("/")) - buf.append('/'); - buf.append(location); - } - - location=buf.toString(); - HttpURI uri = new HttpURI(location); - String path=uri.getDecodedPath(); - String canonical=URIUtil.canonicalPath(path); - if (canonical==null) - throw new IllegalArgumentException(); - if (!canonical.equals(path)) - { - buf = _connection.getRequest().getRootURL(); - buf.append(URIUtil.encodePath(canonical)); - String param=uri.getParam(); - if (param!=null) - { - buf.append(';'); - buf.append(param); - } - String query=uri.getQuery(); - if (query!=null) - { - buf.append('?'); - buf.append(query); - } - String fragment=uri.getFragment(); - if (fragment!=null) - { - buf.append('#'); - buf.append(fragment); - } - location=buf.toString(); - } - } - - resetBuffer(); - setHeader(HttpHeaders.LOCATION,location); - setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); - complete(); - - } - - @Override - public void setDateHeader(String name, long date) - { - _connection._responseFields.putDateField(name, date); - } - - @Override - public void addDateHeader(String name, long date) - { - _connection._responseFields.addDateField(name, date); - } - - @Override - public void setHeader(String name, String value) - { - if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) - setContentType(value); - else - { - _connection._responseFields.put(name, value); - if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) - { - if (value==null) - _connection._generator.setContentLength(-1); - else - _connection._generator.setContentLength(Long.parseLong(value)); - } - } - } - - - @Override - public Collection<String> getHeaderNames() - { - final HttpFields fields=_connection._responseFields; - return fields.getFieldNamesCollection(); - } - - @Override - public String getHeader(String name) - { - return _connection._responseFields.getStringField(name); - } - - @Override - public Collection<String> getHeaders(String name) - { - final HttpFields fields=_connection._responseFields; - Collection<String> i = fields.getValuesCollection(name); - if (i==null) - return Collections.EMPTY_LIST; - return i; - } - - @Override - public void addHeader(String name, String value) - { - - if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) - { - setContentType(value); - return; - } - - _connection._responseFields.add(name, value); - if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) - _connection._generator.setContentLength(Long.parseLong(value)); - } - - @Override - public void setIntHeader(String name, int value) - { - _connection._responseFields.putLongField(name, value); - if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) - _connection._generator.setContentLength(value); - } - - @Override - public void addIntHeader(String name, int value) - { - _connection._responseFields.addLongField(name, value); - if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) - _connection._generator.setContentLength(value); - } - - @Override - public void setStatus(int sc) - { - setStatus(sc,null); - } - - @Override - public void setStatus(int sc, String sm) - { - if (sc<=0) - throw new IllegalArgumentException(); - _status = sc; - _reason = sm; - } - - @Override - public String getCharacterEncoding() - { - if (_characterEncoding==null) - _characterEncoding = StringUtil.__ISO_8859_1; - return _characterEncoding; - } - - @Override - public String getContentType() - { - return _contentType; - } - - @Override - public ServletOutputStream getOutputStream() throws IOException - { - if (_outputState!=NONE && _outputState!=STREAM) - throw new IllegalStateException("WRITER"); - - ServletOutputStream out = _connection.getOutputStream(); - _outputState = STREAM; - return out; - } - - @Override - public PrintWriter getWriter() throws IOException - { - if (_outputState!=NONE && _outputState!=WRITER) - throw new IllegalStateException("STREAM"); - - /* if there is no writer yet */ - if (_writer==null) - { - /* get encoding from Content-Type header */ - String encoding = _characterEncoding; - - if (encoding==null) - { - /* implementation of educated defaults */ - if(_cachedMimeType != null) - encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType); - - if (encoding==null) - encoding = StringUtil.__ISO_8859_1; - - setCharacterEncoding(encoding); - } - - /* construct Writer using correct encoding */ - _writer = _connection.getPrintWriter(encoding); - } - _outputState=WRITER; - return _writer; - } - - @Override - public void setCharacterEncoding(String encoding) - { - if (this._outputState==0 && !isCommitted()) - { - _explicitEncoding = true; - - if (encoding==null) - { - // Clear any encoding. - if (_characterEncoding!=null) - { - _characterEncoding=null; - if (_cachedMimeType!=null) - _contentType = _cachedMimeType; - else if (_mimeType!=null) - _contentType = _mimeType; - else - _contentType = null; - - if (_contentType==null) - _connection._responseFields.remove(HttpHeaders.CONTENT_TYPE); - else - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else - { - // No, so just add this one to the mimetype - _characterEncoding=encoding; - if (_contentType!=null) - { - int i0=_contentType.indexOf(';'); - if (i0<0) - { - _contentType=null; - if(_cachedMimeType!=null) - { - String content_type = MimeTypes.getAssociate(_cachedMimeType,_characterEncoding); - if (content_type!=null) - { - _contentType = content_type; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - - if (_contentType==null) - { - _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else - { - int i1=_contentType.indexOf("charset=",i0); - if (i1<0) - { - _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - } - else - { - int i8=i1+8; - int i2=_contentType.indexOf(" ",i8); - if (i2<0) - _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - else - _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2); - } - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - } - } - } - - @Override - public void setContentLength(int len) - { - // Protect from setting after committed as default handling - // of a servlet HEAD request ALWAYS sets _content length, even - // if the getHandling committed the response! - if (isCommitted()) - return; - _connection._generator.setContentLength(len); - if (len>0) - { - _connection._responseFields.putLongField(HttpHeaders.CONTENT_LENGTH, len); - if (_connection._generator.isAllContentWritten()) - { - if (_outputState==WRITER) - _writer.close(); - else if (_outputState==STREAM) - { - try - { - getOutputStream().close(); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } - } - } - } - - @Override - public void setContentType(String contentType) - { - if (isCommitted()) - return; - - // Yes this method is horribly complex.... but there are lots of special cases and - // as this method is called on every request, it is worth trying to save string creation. - // - - if (contentType==null) - { - if (_locale==null) - _characterEncoding = null; - _mimeType = null; - _cachedMimeType = null; - _contentType=null; - _connection._responseFields.remove(HttpHeaders.CONTENT_TYPE); - } - else - { - // Look for encoding in contentType - int i0=contentType.indexOf(';'); - - if (i0>0) - { - // we have content type parameters - - // Extract params off mimetype - _mimeType = contentType.substring(0,i0).trim(); - _cachedMimeType = MimeTypes.CACHE.get(_mimeType); - - // Look for charset - int i1=contentType.indexOf("charset=",i0+1); - if (i1>=0) - { - _explicitEncoding = true; - int i8=i1+8; - int i2 = contentType.indexOf(' ',i8); - - if (_outputState==WRITER) - { - // strip the charset and ignore; - if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) - { - if (_cachedMimeType!=null) - { - String content_type = MimeTypes.getAssociate(_cachedMimeType,_characterEncoding); - if (content_type!=null) - { - _contentType=content_type; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _contentType = _mimeType+";charset="+_characterEncoding; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else - { - _contentType = _mimeType+";charset="+_characterEncoding; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else if (i2<0) - { - _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) - { - // The params are just the char encoding - _cachedMimeType = MimeTypes.CACHE.get(_mimeType); - _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); - - if (_cachedMimeType!=null) - { - String content_type = MimeTypes.getAssociate(_cachedMimeType,_characterEncoding); - if (content_type!=null) - { - _contentType=content_type; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _contentType=contentType; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else - { - _contentType=contentType; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else if (i2>0) - { - _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2)); - _contentType=contentType; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); - _contentType=contentType; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else // No encoding in the params. - { - _cachedMimeType = null; - _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else // No params at all - { - _mimeType = contentType; - _cachedMimeType = MimeTypes.CACHE.get(_mimeType); - - if (_characterEncoding!=null) - { - if (_cachedMimeType!=null) - { - String content_type = MimeTypes.getAssociate(_cachedMimeType,_characterEncoding); - if (content_type!=null) - { - _contentType=content_type; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else - { - _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - else if (_cachedMimeType!=null) - { - _contentType = _cachedMimeType.toString(); - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - else - { - _contentType=contentType; - _connection._responseFields.put(HttpHeaders.CONTENT_TYPE,_contentType); - } - } - } - } - - @Override - public void setBufferSize(int size) - { - throw new UnsupportedOperationException(); - } - - @Override - public int getBufferSize() - { - return _connection._generator.getContentBufferSize(); - } - - @Override - public void flushBuffer() throws IOException - { - _connection.flushResponse(); - } - - @Override - public void reset() - { - resetBuffer(); - fwdReset(); - _status = 200; - _reason = null; - - HttpFields response_fields=_connection._responseFields; - - response_fields.clear(); - String connection=_connection._requestFields.getStringField(HttpHeaders.CONNECTION); - if (connection!=null) - { - String[] values = connection.split(","); - for (int i=0;values!=null && i<values.length;i++) - { - int cb = HttpHeaderValues.CACHE.getOrdinal(values[0].trim()); - - if (cb != -1) - { - switch(cb) - { - case HttpHeaderValues.CLOSE_ORDINAL: - response_fields.put(HttpHeaders.CONNECTION,HttpHeaderValues.CLOSE); - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol())) - response_fields.put(HttpHeaders.CONNECTION,HttpHeaderValues.KEEP_ALIVE); - break; - case HttpHeaderValues.TE_ORDINAL: - response_fields.put(HttpHeaders.CONNECTION,HttpHeaderValues.TE); - break; - } - } - } - } - } - - - private void fwdReset() - { - resetBuffer(); - - _writer=null; - _outputState=NONE; - } - - @Override - public void resetBuffer() - { - if (isCommitted()) - throw new IllegalStateException("Committed"); - _connection._generator.resetBuffer(); - } - - @Override - public boolean isCommitted() - { - return _connection._generator.isCommitted(); - } - - - @Override - public void setLocale(Locale locale) - { - if (locale == null || isCommitted()) - return; - - _locale = locale; - _connection._responseFields.put(HttpHeaders.CONTENT_LANGUAGE,locale.toString().replace('_','-')); - } - - @Override - public Locale getLocale() - { - if (_locale==null) - return Locale.getDefault(); - return _locale; - } - - /* ------------------------------------------------------------ */ - /** - * @return The HTTP status code that has been set for this request. This will be <code>200<code> - * ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the <code>setStatus</code> methods. - */ - public int getStatus() - { - return _status; - } - - /* ------------------------------------------------------------ */ - /** - * @return The reason associated with the current {@link #getStatus() status}. This will be <code>null</code>, - * unless one of the <code>setStatus</code> methods have been called. - */ - public String getReason() - { - return _reason; - } - - public void complete() - throws IOException - { - _connection.completeResponse(); - } - - /* ------------------------------------------------------------- */ - /** - * @return the number of bytes actually written in response body - */ - public long getContentCount() - { - if (_connection==null) - return -1; - return _connection._generator.getContentWritten(); - } - - public HttpFields getHttpFields() - { - return _connection._responseFields; - } - - @Override - public String toString() - { - return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+ - _connection._responseFields.toString(); - } - -}
--- a/src/org/eclipse/jetty/server/Server.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.ArrayList; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import javax.servlet.ServletException; - -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.server.nio.BlockingChannelConnector; -import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.component.Destroyable; -import org.eclipse.jetty.util.component.LifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** Jetty HTTP Servlet Server. - * This class is the main class for the Jetty HTTP Servlet server. - * It aggregates Connectors (HTTP request receivers) and request Handlers. - * The server is itself a handler and a ThreadPool. Connectors use the ThreadPool methods - * to run jobs that will eventually call the handle method. - * - * @org.apache.xbean.XBean description="Creates an embedded Jetty web server" - */ -public final class Server extends HandlerWrapper -{ - private static final Logger LOG = LoggerFactory.getLogger(Server.class); - - public static final String version = "8"; - - public final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(256, 256, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); - final List<Connector> connectors = new ArrayList<Connector>(); - - - public Server() { - setServer(this); - } - - public Server(int port) - { - setServer(this); -// new SelectChannelConnector(this,port); - new BlockingChannelConnector(this,port); - } - - @Override - protected void doStart() throws Exception - { - LOG.info("jetty-"+version); - - MultiException mex=new MultiException(); - - try - { - super.doStart(); - } - catch(Throwable e) - { - mex.add(e); - } - - if (mex.size()==0) { - for( Connector connector : connectors ) { - try{connector.start();} - catch(Throwable e) - { - mex.add(e); - } - } - } - mex.ifExceptionThrow(); - } - - @Override - protected void doStop() throws Exception - { - MultiException mex=new MultiException(); -/* - if (_graceful>0) - { - LOG.info("Graceful shutdown {}",connector); - try{connector.close();}catch(Throwable e){mex.add(e);} - - Handler[] contexts = getChildHandlersByClass(Graceful.class); - for (int c=0;c<contexts.length;c++) - { - Graceful context=(Graceful)contexts[c]; - LOG.info("Graceful shutdown {}",context); - context.setShutdown(true); - } - Thread.sleep(_graceful); - } -*/ - for( Connector connector : connectors ) { - try{connector.stop();}catch(Throwable e){mex.add(e);} - } - - threadPool.shutdownNow(); - - try {super.doStop(); } catch(Throwable e) { mex.add(e);} - - mex.ifExceptionThrow(); - } - - /* ------------------------------------------------------------ */ - /* Handle a request from a connection. - * Called to handle a request on the connection when either the header has been received, - * or after the entire request has been received (for short requests of known length), or - * on the dispatch of an async request. - */ - public void handle(AbstractHttpConnection connection) throws IOException, ServletException - { - final String target = connection.getRequest().getPathInfo(); - final Request request = connection.getRequest(); - final Response response = connection.getResponse(); - handle(target, request, response); - } -/* - public void join() throws InterruptedException - { - threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); - } -*/ - - @Override - public void dump(Appendable out,String indent) throws IOException - { - dumpThis(out); - dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),connectors); - } - - - /* ------------------------------------------------------------ */ - /* A handler that can be gracefully shutdown. - * Called by doStop if a {@link #setGracefulShutdown} period is set. - * TODO move this somewhere better - */ -/* - public interface Graceful extends Handler - { - public void setShutdown(boolean shutdown); - } -*/ - - public final boolean isLowOnThreads() - { - // getActiveCount() locks the thread pool, so execute it last - return threadPool.getPoolSize() == threadPool.getMaximumPoolSize() && - threadPool.getQueue().size() >= threadPool.getPoolSize() - threadPool.getActiveCount(); - } - - - public static void main(String...args) throws Exception - { - System.err.println(version); - } -}
--- a/src/org/eclipse/jetty/server/handler/AbstractHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - - -import java.io.IOException; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** AbstractHandler. - * - * - */ -public abstract class AbstractHandler extends AggregateLifeCycle implements Handler -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractHandler.class); - - private Server _server; - - /* ------------------------------------------------------------ */ - /** - * - */ - public AbstractHandler() - { - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.LifeCycle#start() - */ - @Override - protected void doStart() throws Exception - { - LOG.debug("starting {}",this); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.LifeCycle#stop() - */ - @Override - protected void doStop() throws Exception - { - LOG.debug("stopping {}",this); - super.doStop(); - } - - /* ------------------------------------------------------------ */ - public void setServer(Server server) - { - _server=server; - } - - /* ------------------------------------------------------------ */ - public Server getServer() - { - return _server; - } - - /* ------------------------------------------------------------ */ - public void destroy() - { - if (!isStopped()) - throw new IllegalStateException("!STOPPED"); - super.destroy(); - } - - /* ------------------------------------------------------------ */ - public void dumpThis(Appendable out) throws IOException - { - out.append(toString()).append(" - ").append(getState()).append('\n'); - } - -}
--- a/src/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - - -import java.io.IOException; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HandlerContainer; -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.TypeUtil; - - -/* ------------------------------------------------------------ */ -/** Abstract Handler Container. - * This is the base class for handlers that may contain other handlers. - * - */ -public abstract class AbstractHandlerContainer extends AbstractHandler implements HandlerContainer -{ - /* ------------------------------------------------------------ */ - public AbstractHandlerContainer() - { - } - - /* ------------------------------------------------------------ */ - public Handler[] getChildHandlers() - { - Object list = expandChildren(null,null); - return (Handler[])LazyList.toArray(list, Handler.class); - } - - /* ------------------------------------------------------------ */ - public Handler[] getChildHandlersByClass(Class<?> byclass) - { - Object list = expandChildren(null,byclass); - return (Handler[])LazyList.toArray(list, byclass); - } - - /* ------------------------------------------------------------ */ - public <T extends Handler> T getChildHandlerByClass(Class<T> byclass) - { - // TODO this can be more efficient? - Object list = expandChildren(null,byclass); - if (list==null) - return null; - return (T)LazyList.get(list, 0); - } - - /* ------------------------------------------------------------ */ - protected Object expandChildren(Object list, Class<?> byClass) - { - return list; - } - - /* ------------------------------------------------------------ */ - protected Object expandHandler(Handler handler, Object list, Class<Handler> byClass) - { - if (handler==null) - return list; - - if (byClass==null || byClass.isAssignableFrom(handler.getClass())) - list=LazyList.add(list, handler); - - if (handler instanceof AbstractHandlerContainer) - list=((AbstractHandlerContainer)handler).expandChildren(list, byClass); - else if (handler instanceof HandlerContainer) - { - HandlerContainer container = (HandlerContainer)handler; - Handler[] handlers=byClass==null?container.getChildHandlers():container.getChildHandlersByClass(byClass); - list=LazyList.addArray(list, handlers); - } - - return list; - } - - /* ------------------------------------------------------------ */ - public static <T extends HandlerContainer> T findContainerOf(HandlerContainer root,Class<T>type, Handler handler) - { - if (root==null || handler==null) - return null; - - Handler[] branches=root.getChildHandlersByClass(type); - if (branches!=null) - { - for (Handler h:branches) - { - T container = (T)h; - Handler[] candidates = container.getChildHandlersByClass(handler.getClass()); - if (candidates!=null) - { - for (Handler c:candidates) - if (c==handler) - return container; - } - } - } - return null; - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out,String indent) throws IOException - { - dumpThis(out); - dump(out,indent,getBeans(),TypeUtil.asList(getHandlers())); - } -}
--- a/src/org/eclipse/jetty/server/handler/ContextHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.security.AccessController; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextAttributeEvent; -import javax.servlet.ServletContextAttributeListener; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.descriptor.JspConfigDescriptor; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpException; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.server.AbstractHttpConnection; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HandlerContainer; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.AttributesMap; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.eclipse.jetty.util.resource.Resource; - -/* ------------------------------------------------------------ */ -/** - * ContextHandler. - * - * This handler wraps a call to handle by setting the context and servlet path. - * - */ -public final class ContextHandler extends HandlerWrapper -{ - private static final Logger LOG = LoggerFactory.getLogger(ContextHandler.class); - - private String _contextPath = "/"; - private Resource _baseResource; - private Logger _logger; - - public ContextHandler() - { - super(); - } - - public ContextHandler(String contextPath) - { - this(); - setContextPath(contextPath); - } - - public ContextHandler(HandlerContainer parent, String contextPath) - { - this(); - setContextPath(contextPath); - if (parent instanceof HandlerWrapper) - ((HandlerWrapper)parent).setHandler(this); - else if (parent instanceof HandlerCollection) - ((HandlerCollection)parent).addHandler(this); - } - - @Override - public void dump(Appendable out, String indent) throws IOException - { - dumpThis(out); - dump(out,indent,TypeUtil.asList(getHandlers()),getBeans()); - } - - public String getContextPath() - { - return _contextPath; - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - if (_contextPath == null) - throw new IllegalStateException("Null contextPath"); - - _logger = LoggerFactory.getLogger(getContextPath()); - - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - LOG.info("stopped {}",this); - } - - private boolean checkContext(final String target, final Request request, final HttpServletResponse response) throws IOException, ServletException - { - if (request.isHandled()) - return false; - - // Are we not the root context? - if (_contextPath.length() > 1) - { - // reject requests that are not for us - if (!target.startsWith(_contextPath)) - return false; - if (target.length() > _contextPath.length() && target.charAt(_contextPath.length()) != '/') - return false; - - // redirect null path infos - if (_contextPath.length() == target.length()) - { - // context request must end with / - request.setHandled(true); - if (request.getQueryString() != null) - response.sendRedirect(URIUtil.addPaths(request.getRequestURI(),"/") + "?" + request.getQueryString()); - else - response.sendRedirect(URIUtil.addPaths(request.getRequestURI(),"/")); - return false; - } - } - - return true; - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - String old_context_path = null; - String old_path_info = null; - String pathInfo = target; - - ContextHandler oldContextHandler = request._contextHandler; - - // Are we already in this context? - if (oldContextHandler != this) - { - if (!checkContext(target,request,response)) - return; - - if (target.length() > _contextPath.length()) - { - if (_contextPath.length() > 1) - target = target.substring(_contextPath.length()); - pathInfo = target; - } - else if (_contextPath.length() == 1) - { - target = "/"; - pathInfo = "/"; - } - else - { - target = "/"; - pathInfo = null; - } - } - - try - { - old_context_path = request.getContextPath(); - old_path_info = request.getPathInfo(); - - // Update the paths - request._contextHandler = this; - if (target.startsWith("/")) - { - if (_contextPath.length() == 1) - request.setContextPath(""); - else - request.setContextPath(_contextPath); - request.setPathInfo(pathInfo); - } - - try - { - super.handle(target,request,response); - } - catch (HttpException e) - { - LOG.debug("",e); - request.setHandled(true); - response.sendError(e.getStatus(),e.getReason()); - } - } - finally - { - if (oldContextHandler != this) - { - // reset the context and servlet path. - request._contextHandler = oldContextHandler; - request.setContextPath(old_context_path); - request.setPathInfo(old_path_info); - } - } - } - - public void setContextPath(String contextPath) - { - if (contextPath != null && contextPath.length() > 1 && contextPath.endsWith("/")) - throw new IllegalArgumentException("ends with /"); - _contextPath = contextPath; - } - - public Resource getBaseResource() - { - return _baseResource; - } - - public String getResourceBase() - { - if (_baseResource == null) - return null; - return _baseResource.toString(); - } - - public void setBaseResource(Resource base) - { - _baseResource = base; - } - - public void setResourceBase(String resourceBase) - { - try - { - setBaseResource(Resource.newResource(resourceBase)); - } - catch (Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - throw new IllegalArgumentException(resourceBase); - } - } - - @Override - public String toString() - { - StringBuilder b = new StringBuilder(); - - Package pkg = getClass().getPackage(); - if (pkg != null) - { - String p = pkg.getName(); - if (p != null && p.length() > 0) - { - String[] ss = p.split("\\."); - for (String s : ss) - b.append(s.charAt(0)).append('.'); - } - } - b.append(getClass().getSimpleName()); - b.append('{').append(getContextPath()).append(',').append(getBaseResource()); - - b.append('}'); - - return b.toString(); - } - - public Resource getResource(String path) throws MalformedURLException - { - if (path == null || !path.startsWith("/")) - throw new MalformedURLException(path); - - if (_baseResource == null) - return null; - - try - { - path = URIUtil.canonicalPath(path); - Resource resource = _baseResource.addPath(path); - - if (resource.getAlias() == null) // check not alias - return resource; - return null; - } - catch (Exception e) - { - LOG.trace("",e); - } - - return null; - } - - public Set<String> getResourcePaths(String path) - { - try - { - path = URIUtil.canonicalPath(path); - Resource resource = getResource(path); - - if (resource != null && resource.exists()) - { - if (!path.endsWith("/")) - path = path + "/"; - - String[] l = resource.list(); - if (l != null) - { - HashSet<String> set = new HashSet<String>(); - for (int i = 0; i < l.length; i++) - set.add(path + l[i]); - return set; - } - } - } - catch (Exception e) - { - LOG.trace("",e); - } - return Collections.emptySet(); - } -}
--- a/src/org/eclipse/jetty/server/handler/DefaultHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.URL; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.ByteArrayISO8859Writer; -import org.eclipse.jetty.util.IO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.eclipse.jetty.util.resource.Resource; - - -/* ------------------------------------------------------------ */ -/** Default Handler. - * - * This handle will deal with unhandled requests in the server. - * For requests for favicon.ico, the Jetty icon is served. - * For reqests to '/' a 404 with a list of known contexts is served. - * For all other requests a normal 404 is served. - * TODO Implement OPTIONS and TRACE methods for the server. - * - * - * @org.apache.xbean.XBean - */ -public class DefaultHandler extends AbstractHandler -{ - private static final Logger LOG = LoggerFactory.getLogger(DefaultHandler.class); - - boolean _showContexts=true; - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - if (response.isCommitted() || request.isHandled()) - return; - - request.setHandled(true); - - String method=request.getMethod(); - - if (!method.equals(HttpMethods.GET) || !request.getRequestURI().equals("/")) - { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - return; - } - - response.setStatus(HttpServletResponse.SC_NOT_FOUND); - response.setContentType(MimeTypes.TEXT_HTML); - - ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500); - - writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found"); - writer.write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n"); - writer.write("No context on this server matched or handled this request.<BR>"); - - if (_showContexts) - { - writer.write("Contexts known to this server are: <ul>"); - - Server server = getServer(); - Handler[] handlers = server==null?null:server.getChildHandlersByClass(ContextHandler.class); - - for (int i=0;handlers!=null && i<handlers.length;i++) - { - ContextHandler context = (ContextHandler)handlers[i]; - if (context.isRunning()) - { - writer.write("<li><a href=\""); - writer.write(context.getContextPath()); - if (context.getContextPath().length()>1 && context.getContextPath().endsWith("/")) - writer.write("/"); - writer.write("\">"); - writer.write(context.getContextPath()); - writer.write(" ---> "); - writer.write(context.toString()); - writer.write("</a></li>\n"); - } - else - { - writer.write("<li>"); - writer.write(context.getContextPath()); - writer.write(" ---> "); - writer.write(context.toString()); - if (context.isFailed()) - writer.write(" [failed]"); - if (context.isStopped()) - writer.write(" [stopped]"); - writer.write("</li>\n"); - } - } - } - - for (int i=0;i<10;i++) - writer.write("\n<!-- Padding for IE -->"); - - writer.write("\n</BODY>\n</HTML>\n"); - writer.flush(); - response.setContentLength(writer.size()); - OutputStream out=response.getOutputStream(); - writer.writeTo(out); - out.close(); - } - - public boolean getShowContexts() - { - return _showContexts; - } - - public void setShowContexts(boolean show) - { - _showContexts = show; - } - -}
--- a/src/org/eclipse/jetty/server/handler/GzipHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,328 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; -import org.eclipse.jetty.http.gzip.AbstractCompressedStream; -import org.eclipse.jetty.server.Request; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * GZIP Handler This handler will gzip the content of a response if: - * <ul> - * <li>The filter is mapped to a matching path</li> - * <li>The response status code is >=200 and <300 - * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li> - * <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or if no mimeTypes are defined the - * content-type is not "application/gzip"</li> - * <li>No content-encoding is specified by the resource</li> - * </ul> - * - * <p> - * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and CPU cycles. If this handler is used for static content, - * then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the <code>org.eclipse.jetty.servlet.DefaultServlet</code> is advised instead. - * </p> - */ -public class GzipHandler extends HandlerWrapper -{ - private static final Logger LOG = LoggerFactory.getLogger(GzipHandler.class); - - protected Set<String> _mimeTypes; - protected Set<String> _excluded; - protected int _bufferSize = 8192; - protected int _minGzipSize = 256; - protected String _vary = "Accept-Encoding, User-Agent"; - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new gzip handler. - */ - public GzipHandler() - { - } - - /* ------------------------------------------------------------ */ - /** - * Get the mime types. - * - * @return mime types to set - */ - public Set<String> getMimeTypes() - { - return _mimeTypes; - } - - /* ------------------------------------------------------------ */ - /** - * Set the mime types. - * - * @param mimeTypes - * the mime types to set - */ - public void setMimeTypes(Set<String> mimeTypes) - { - _mimeTypes = mimeTypes; - } - - /* ------------------------------------------------------------ */ - /** - * Set the mime types. - * - * @param mimeTypes - * the mime types to set - */ - public void setMimeTypes(String mimeTypes) - { - if (mimeTypes != null) - { - _mimeTypes = new HashSet<String>(); - StringTokenizer tok = new StringTokenizer(mimeTypes,",",false); - while (tok.hasMoreTokens()) - { - _mimeTypes.add(tok.nextToken()); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Get the excluded user agents. - * - * @return excluded user agents - */ - public Set<String> getExcluded() - { - return _excluded; - } - - /* ------------------------------------------------------------ */ - /** - * Set the excluded user agents. - * - * @param excluded - * excluded user agents to set - */ - public void setExcluded(Set<String> excluded) - { - _excluded = excluded; - } - - /* ------------------------------------------------------------ */ - /** - * Set the excluded user agents. - * - * @param excluded - * excluded user agents to set - */ - public void setExcluded(String excluded) - { - if (excluded != null) - { - _excluded = new HashSet<String>(); - StringTokenizer tok = new StringTokenizer(excluded,",",false); - while (tok.hasMoreTokens()) - _excluded.add(tok.nextToken()); - } - } - - /* ------------------------------------------------------------ */ - /** - * @return The value of the Vary header set if a response can be compressed. - */ - public String getVary() - { - return _vary; - } - - /* ------------------------------------------------------------ */ - /** - * Set the value of the Vary header sent with responses that could be compressed. - * <p> - * By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by - * default from the excludedAgents. If user-agents are not to be excluded, then - * this can be set to 'Accept-Encoding'. Note also that shared caches may cache - * many copies of a resource that is varied by User-Agent - one per variation of the - * User-Agent, unless the cache does some normalization of the UA string. - * @param vary The value of the Vary header set if a response can be compressed. - */ - public void setVary(String vary) - { - _vary = vary; - } - - /* ------------------------------------------------------------ */ - /** - * Get the buffer size. - * - * @return the buffer size - */ - public int getBufferSize() - { - return _bufferSize; - } - - /* ------------------------------------------------------------ */ - /** - * Set the buffer size. - * - * @param bufferSize - * buffer size to set - */ - public void setBufferSize(int bufferSize) - { - _bufferSize = bufferSize; - } - - /* ------------------------------------------------------------ */ - /** - * Get the minimum reponse size. - * - * @return minimum reponse size - */ - public int getMinGzipSize() - { - return _minGzipSize; - } - - /* ------------------------------------------------------------ */ - /** - * Set the minimum reponse size. - * - * @param minGzipSize - * minimum reponse size - */ - public void setMinGzipSize(int minGzipSize) - { - _minGzipSize = minGzipSize; - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - if (_handler!=null && isStarted()) - { - String ae = request.getHeader("accept-encoding"); - if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding") - && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) - { - if (_excluded!=null) - { - String ua = request.getHeader("User-Agent"); - if (_excluded.contains(ua)) - { - _handler.handle(target, request, response); - return; - } - } - - final CompressedResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response); - - boolean exceptional=true; - try - { - _handler.handle(target, request, wrappedResponse); - exceptional=false; - } - finally - { - if (exceptional && !response.isCommitted()) - { - wrappedResponse.resetBuffer(); - wrappedResponse.noCompression(); - } - else - wrappedResponse.finish(); - } - } - else - { - _handler.handle(target, request, response); - } - } - } - - /** - * Allows derived implementations to replace ResponseWrapper implementation. - * - * @param request the request - * @param response the response - * @return the gzip response wrapper - */ - protected CompressedResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response) - { - return new CompressedResponseWrapper(request,response) - { - { - super.setMimeTypes(GzipHandler.this._mimeTypes); - super.setBufferSize(GzipHandler.this._bufferSize); - super.setMinCompressSize(GzipHandler.this._minGzipSize); - } - - @Override - protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException - { - return new AbstractCompressedStream("gzip",request,this,_vary) - { - @Override - protected DeflaterOutputStream createStream() throws IOException - { - return new GZIPOutputStream(_response.getOutputStream(),_bufferSize); - } - }; - } - - @Override - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return GzipHandler.this.newWriter(out,encoding); - } - }; - } - - /** - * Allows derived implementations to replace PrintWriter implementation. - * - * @param out the out - * @param encoding the encoding - * @return the prints the writer - * @throws UnsupportedEncodingException - */ - protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException - { - return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding)); - } -}
--- a/src/org/eclipse/jetty/server/handler/HandlerCollection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,305 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; -import java.util.concurrent.CountDownLatch; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.LazyList; -import org.eclipse.jetty.util.MultiException; - -/* ------------------------------------------------------------ */ -/** A collection of handlers. - * <p> - * The default implementations calls all handlers in list order, - * regardless of the response status or exceptions. Derived implementation - * may alter the order or the conditions of calling the contained - * handlers. - * <p> - * - * @org.apache.xbean.XBean - */ -public class HandlerCollection extends AbstractHandlerContainer -{ - private final boolean _mutableWhenRunning; - private volatile Handler[] _handlers; - private boolean _parallelStart=false; - - /* ------------------------------------------------------------ */ - public HandlerCollection() - { - _mutableWhenRunning=false; - } - - /* ------------------------------------------------------------ */ - public HandlerCollection(boolean mutableWhenRunning) - { - _mutableWhenRunning=mutableWhenRunning; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the handlers. - */ - public Handler[] getHandlers() - { - return _handlers; - } - - /* ------------------------------------------------------------ */ - /** - * - * @param handlers The handlers to set. - */ - public void setHandlers(Handler[] handlers) - { - if (!_mutableWhenRunning && isStarted()) - throw new IllegalStateException(STARTED); - - Handler [] old_handlers = _handlers==null?null:_handlers.clone(); - _handlers = handlers; - - Server server = getServer(); - MultiException mex = new MultiException(); - for (int i=0;handlers!=null && i<handlers.length;i++) - { - if (handlers[i].getServer()!=server) - handlers[i].setServer(server); - } - - // stop old handlers - for (int i=0;old_handlers!=null && i<old_handlers.length;i++) - { - if (old_handlers[i]!=null) - { - try - { - if (old_handlers[i].isStarted()) - old_handlers[i].stop(); - } - catch (Throwable e) - { - mex.add(e); - } - } - } - - mex.ifExceptionThrowRuntime(); - } - - - - /* ------------------------------------------------------------ */ - /** Get the parrallelStart. - * @return true if the contained handlers are started in parallel. - */ - public boolean isParallelStart() - { - return _parallelStart; - } - - - - /* ------------------------------------------------------------ */ - /** Set the parallelStart. - * @param parallelStart If true, contained handlers are started in parallel. - */ - public void setParallelStart(boolean parallelStart) - { - this._parallelStart = parallelStart; - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) - throws IOException, ServletException - { - if (_handlers!=null && isStarted()) - { - MultiException mex=null; - - for (int i=0;i<_handlers.length;i++) - { - try - { - _handlers[i].handle(target, request, response); - } - catch(IOException e) - { - throw e; - } - catch(RuntimeException e) - { - throw e; - } - catch(Exception e) - { - if (mex==null) - mex=new MultiException(); - mex.add(e); - } - } - if (mex!=null) - { - if (mex.size()==1) - throw new ServletException(mex.getThrowable(0)); - else - throw new ServletException(mex); - } - - } - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.server.handler.AbstractHandler#doStart() - */ - @Override - protected void doStart() throws Exception - { - final MultiException mex=new MultiException(); - if (_handlers!=null) - { - if (_parallelStart) - { - final CountDownLatch latch = new CountDownLatch(_handlers.length); - final ClassLoader loader = Thread.currentThread().getContextClassLoader(); - for (int i=0;i<_handlers.length;i++) - { - final int h=i; - getServer().threadPool.execute( - new Runnable() - { - public void run() - { - ClassLoader orig = Thread.currentThread().getContextClassLoader(); - try - { - Thread.currentThread().setContextClassLoader(loader); - _handlers[h].start(); - } - catch(Throwable e) - { - mex.add(e); - } - finally - { - Thread.currentThread().setContextClassLoader(orig); - latch.countDown(); - } - } - } - ); - } - latch.await(); - } - else - { - for (int i=0;i<_handlers.length;i++) - { - try{_handlers[i].start();} - catch(Throwable e){mex.add(e);} - } - } - } - super.doStart(); - mex.ifExceptionThrow(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.server.handler.AbstractHandler#doStop() - */ - @Override - protected void doStop() throws Exception - { - MultiException mex=new MultiException(); - try { super.doStop(); } catch(Throwable e){mex.add(e);} - if (_handlers!=null) - { - for (int i=_handlers.length;i-->0;) - try{_handlers[i].stop();}catch(Throwable e){mex.add(e);} - } - mex.ifExceptionThrow(); - } - - /* ------------------------------------------------------------ */ - @Override - public void setServer(Server server) - { - if (isStarted()) - throw new IllegalStateException(STARTED); - - Server old_server=getServer(); - - super.setServer(server); - - Handler[] h=getHandlers(); - for (int i=0;h!=null && i<h.length;i++) - h[i].setServer(server); - - } - - /* ------------------------------------------------------------ */ - /* Add a handler. - * This implementation adds the passed handler to the end of the existing collection of handlers. - * @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler) - */ - public void addHandler(Handler handler) - { - setHandlers((Handler[])LazyList.addToArray(getHandlers(), handler, Handler.class)); - } - - /* ------------------------------------------------------------ */ - public void removeHandler(Handler handler) - { - Handler[] handlers = getHandlers(); - - if (handlers!=null && handlers.length>0 ) - setHandlers((Handler[])LazyList.removeFromArray(handlers, handler)); - } - - /* ------------------------------------------------------------ */ - @Override - protected Object expandChildren(Object list, Class byClass) - { - Handler[] handlers = getHandlers(); - for (int i=0;handlers!=null && i<handlers.length;i++) - list=expandHandler(handlers[i], list, byClass); - return list; - } - - /* ------------------------------------------------------------ */ - @Override - public void destroy() - { - if (!isStopped()) - throw new IllegalStateException("!STOPPED"); - Handler[] children=getChildHandlers(); - setHandlers(null); - for (Handler child: children) - child.destroy(); - super.destroy(); - } -}
--- a/src/org/eclipse/jetty/server/handler/HandlerList.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; - -/* ------------------------------------------------------------ */ -/** HandlerList. - * This extension of {@link HandlerCollection} will call - * each contained handler in turn until either an exception is thrown, the response - * is committed or a positive response status is set. - */ -public class HandlerList extends HandlerCollection -{ - @Override - public void handle(String target, Request request, HttpServletResponse response) - throws IOException, ServletException - { - Handler[] handlers = getHandlers(); - - if (handlers!=null && isStarted()) - { - for (int i=0;i<handlers.length;i++) - { - handlers[i].handle(target, request, response); - if ( request.isHandled()) - return; - } - } - } -}
--- a/src/org/eclipse/jetty/server/handler/HandlerWrapper.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.component.LifeCycle; - -/* ------------------------------------------------------------ */ -/** A <code>HandlerWrapper</code> acts as a {@link Handler} but delegates the {@link Handler#handle handle} method and - * {@link LifeCycle life cycle} events to a delegate. This is primarily used to implement the <i>Decorator</i> pattern. - * - */ -public class HandlerWrapper extends AbstractHandlerContainer -{ - protected Handler _handler; - - /* ------------------------------------------------------------ */ - /** - * - */ - public HandlerWrapper() - { - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the handlers. - */ - public Handler getHandler() - { - return _handler; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the handlers. - */ - public Handler[] getHandlers() - { - if (_handler==null) - return new Handler[0]; - return new Handler[] {_handler}; - } - - /* ------------------------------------------------------------ */ - /** - * @param handler Set the {@link Handler} which should be wrapped. - */ - public void setHandler(Handler handler) - { - if (isStarted()) - throw new IllegalStateException(STARTED); - - Handler old_handler = _handler; - _handler = handler; - if (handler!=null) - handler.setServer(getServer()); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - if (_handler!=null) - _handler.start(); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ - @Override - protected void doStop() throws Exception - { - if (_handler!=null) - _handler.stop(); - super.doStop(); - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - if (_handler!=null && isStarted()) - { - _handler.handle(target, request, response); - } - } - - - /* ------------------------------------------------------------ */ - @Override - public void setServer(Server server) - { - Server old_server=getServer(); - if (server==old_server) - return; - - if (isStarted()) - throw new IllegalStateException(STARTED); - - super.setServer(server); - - Handler h=getHandler(); - if (h!=null) - h.setServer(server); - } - - - /* ------------------------------------------------------------ */ - @Override - protected Object expandChildren(Object list, Class byClass) - { - return expandHandler(_handler,list,byClass); - } - - /* ------------------------------------------------------------ */ - public <H extends Handler> H getNestedHandlerByClass(Class<H> byclass) - { - HandlerWrapper h=this; - while (h!=null) - { - if (byclass.isInstance(h)) - return (H)h; - Handler w = h.getHandler(); - if (w instanceof HandlerWrapper) - h=(HandlerWrapper)w; - else break; - } - return null; - - } - - /* ------------------------------------------------------------ */ - @Override - public void destroy() - { - if (!isStopped()) - throw new IllegalStateException("!STOPPED"); - Handler child=getHandler(); - if (child!=null) - { - setHandler(null); - child.destroy(); - } - super.destroy(); - } - -}
--- a/src/org/eclipse/jetty/server/handler/RequestLogHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.io.IOException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Locale; -import java.util.TimeZone; - -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * RequestLogHandler. - * This handler can be used to wrap an individual context for context logging. - * - * @org.apache.xbean.XBean - */ -public class RequestLogHandler extends HandlerWrapper -{ - private static final Logger LOG = LoggerFactory.getLogger(RequestLogHandler.class); - - @Override - public void handle(String target, final Request request, final HttpServletResponse response) - throws IOException, ServletException - { - try - { - super.handle(target, request, response); - } - finally - { - log(request, (Response)response); - } - } - - /* ------------------------------------------------------------ */ - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStart() - */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - startLog(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - stopLog(); - } - - - - // from NCSARequestLog - - public String filename = null; - private boolean extended = false; - public long retainTime = 1000L*60*60*24*31; // 31 days - private boolean _closeOut; - public boolean preferProxiedForAddress = false; - public String logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z"; - public Locale logLocale = Locale.getDefault(); - public TimeZone timeZone = TimeZone.getTimeZone("GMT"); - public boolean logLatency = false; - public boolean logCookies = false; - public boolean logServer = false; - - private transient OutputStream _out; - private transient DateFormat dateFormat; - private transient Writer _writer; - - /* ------------------------------------------------------------ */ - /** - * Writes the request and response information to the output stream. - * - * @see org.eclipse.jetty.server.RequestLog#log(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response) - */ - public void log(Request request, Response response) - { - try - { - if (_out == null) - return; - - StringBuilder buf = new StringBuilder(256); - - if (logServer) - { - buf.append(request.getServerName()); - buf.append(' '); - } - - String addr = null; - if (preferProxiedForAddress) - { - addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR); - } - - if (addr == null) - addr = request.getRemoteAddr(); - - buf.append(addr); - buf.append(" - ["); - - synchronized(dateFormat) { - buf.append(dateFormat.format(request.getTimeStamp())); - } - - buf.append("] \""); - buf.append(request.getMethod()); - buf.append(' '); - buf.append(request.getUri().toString()); - buf.append(' '); - buf.append(request.getProtocol()); - buf.append("\" "); - - int status = response.getStatus(); - if (status <= 0) - status = 404; - buf.append((char)('0' + ((status / 100) % 10))); - buf.append((char)('0' + ((status / 10) % 10))); - buf.append((char)('0' + (status % 10))); - - long responseLength = response.getContentCount(); - if (responseLength >= 0) - { - buf.append(' '); - if (responseLength > 99999) - buf.append(responseLength); - else - { - if (responseLength > 9999) - buf.append((char)('0' + ((responseLength / 10000) % 10))); - if (responseLength > 999) - buf.append((char)('0' + ((responseLength / 1000) % 10))); - if (responseLength > 99) - buf.append((char)('0' + ((responseLength / 100) % 10))); - if (responseLength > 9) - buf.append((char)('0' + ((responseLength / 10) % 10))); - buf.append((char)('0' + (responseLength) % 10)); - } - buf.append(' '); - } - else - buf.append(" - "); - - - if (extended) - logExtended(request, response, buf); - - if (logCookies) - { - Cookie[] cookies = request.getCookies(); - if (cookies == null || cookies.length == 0) - buf.append(" -"); - else - { - buf.append(" \""); - for (int i = 0; i < cookies.length; i++) - { - if (i != 0) - buf.append(';'); - buf.append(cookies[i].getName()); - buf.append('='); - buf.append(cookies[i].getValue()); - } - buf.append('\"'); - } - } - - if (logLatency) - { - long now = System.currentTimeMillis(); - - if (logLatency) - { - buf.append(' '); - buf.append(now - request.getTimeStamp()); - } - } - - buf.append('\n'); - - String log = buf.toString(); - write(log); - } - catch (IOException e) - { - LOG.warn("",e); - } - } - - /* ------------------------------------------------------------ */ - protected synchronized void write(String log) throws IOException - { - if (_writer==null) - return; - _writer.write(log); - _writer.flush(); - } - - - /* ------------------------------------------------------------ */ - /** - * Writes extended request and response information to the output stream. - * - * @param request request object - * @param response response object - * @param b StringBuilder to write to - * @throws IOException - */ - protected void logExtended(Request request, - Response response, - StringBuilder b) throws IOException - { - String referer = request.getHeader(HttpHeaders.REFERER); - if (referer == null) - b.append("\"-\" "); - else - { - b.append('"'); - b.append(referer); - b.append("\" "); - } - - String agent = request.getHeader(HttpHeaders.USER_AGENT); - if (agent == null) - b.append("\"-\" "); - else - { - b.append('"'); - b.append(agent); - b.append('"'); - } - } - - private synchronized void startLog() throws Exception { - dateFormat = new SimpleDateFormat(logDateFormat,logLocale); - dateFormat.setTimeZone(timeZone); - - if (filename != null) { - File file = new File(filename); - if( file.exists() ) { - File old = new File(filename+".old"); - if( old.exists() && file.lastModified() - old.lastModified() > retainTime ) - old.delete(); - if( !old.exists() ) - file.renameTo(old); - } - _out = new FileOutputStream(file,true); - _closeOut = true; - LOG.info("Opened " + filename); - } - else - _out = System.err; - - _writer = new OutputStreamWriter(_out); - } - - private synchronized void stopLog() throws Exception { - try { - if (_writer != null) - _writer.flush(); - } catch (IOException e) { - LOG.trace("",e); - } - if (_closeOut) { - try { - _out.close(); - } catch (IOException e) { - LOG.trace("",e); - } - } - _out = null; - _closeOut = false; - dateFormat = null; - _writer = null; - } - -}
--- a/src/org/eclipse/jetty/server/handler/ResourceHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,438 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.MalformedURLException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpMethods; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.io.WriterOutputStream; -import org.eclipse.jetty.server.AbstractHttpConnection; -import javax.servlet.RequestDispatcher; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.eclipse.jetty.util.resource.FileResource; -import org.eclipse.jetty.util.resource.Resource; - - -/* ------------------------------------------------------------ */ -/** Resource Handler. - * - * This handle will serve static content and handle If-Modified-Since headers. - * No caching is done. - * Requests for resources that do not exist are let pass (Eg no 404's). - * - * - * @org.apache.xbean.XBean - */ -public final class ResourceHandler extends HandlerWrapper -{ - private static final Logger LOG = LoggerFactory.getLogger(ResourceHandler.class); - - Resource _baseResource; - Resource _defaultStylesheet; - Resource _stylesheet; - String[] _welcomeFiles={"index.html"}; - MimeTypes _mimeTypes = new MimeTypes(); - boolean _aliases; - boolean _directory; - - /* ------------------------------------------------------------ */ - public ResourceHandler() - { - - } - - /* ------------------------------------------------------------ */ - public MimeTypes getMimeTypes() - { - return _mimeTypes; - } - - /* ------------------------------------------------------------ */ - public void setMimeTypes(MimeTypes mimeTypes) - { - _mimeTypes = mimeTypes; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if resource aliases are allowed. - */ - public boolean isAliases() - { - return _aliases; - } - - /* ------------------------------------------------------------ */ - /** - * Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed. - * Allowing aliases can significantly increase security vulnerabilities. - * If this handler is deployed inside a ContextHandler, then the - * {@link ContextHandler#isAliases()} takes precedent. - * @param aliases True if aliases are supported. - */ - public void setAliases(boolean aliases) - { - _aliases = aliases; - } - - /* ------------------------------------------------------------ */ - /** Get the directory option. - * @return true if directories are listed. - */ - public boolean isDirectoriesListed() - { - return _directory; - } - - /* ------------------------------------------------------------ */ - /** Set the directory. - * @param directory true if directories are listed. - */ - public void setDirectoriesListed(boolean directory) - { - _directory = directory; - } - - /* ------------------------------------------------------------ */ - @Override - public void doStart() - throws Exception - { - if (!_aliases && !FileResource.getCheckAliases()) - throw new IllegalStateException("Alias checking disabled"); - - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the resourceBase. - */ - public Resource getBaseResource() - { - if (_baseResource==null) - return null; - return _baseResource; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the base resource as a string. - */ - public String getResourceBase() - { - if (_baseResource==null) - return null; - return _baseResource.toString(); - } - - - /* ------------------------------------------------------------ */ - /** - * @param base The resourceBase to set. - */ - public void setBaseResource(Resource base) - { - _baseResource=base; - } - - /* ------------------------------------------------------------ */ - /** - * @param resourceBase The base resource as a string. - */ - public void setResourceBase(String resourceBase) - { - try - { - setBaseResource(Resource.newResource(resourceBase)); - } - catch (Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - throw new IllegalArgumentException(resourceBase); - } - } - - private Resource getStylesheet() - { - if(_stylesheet != null) - { - return _stylesheet; - } - else - { - if(_defaultStylesheet == null) - { - try - { - _defaultStylesheet = Resource.newResource(this.getClass().getResource("/org/eclipse/jetty/jetty-dir.css")); - } - catch(IOException e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - } - } - return _defaultStylesheet; - } - } - - /* ------------------------------------------------------------ */ - /** - * @param stylesheet The location of the stylesheet to be used as a String. - */ - public void setStylesheet(String stylesheet) - { - try - { - _stylesheet = Resource.newResource(stylesheet); - if(!_stylesheet.exists()) - { - LOG.warn("unable to find custom stylesheet: " + stylesheet); - _stylesheet = null; - } - } - catch(Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - throw new IllegalArgumentException(stylesheet.toString()); - } - } - - private Resource getResource(Request request) throws MalformedURLException - { - String path = request.getPathInfo(); - if (path==null || !path.startsWith("/")) - throw new MalformedURLException(path); - - Resource base = _baseResource; - if (base==null) - { - ContextHandler ch = request._contextHandler; - if (ch==null) - return null; - base = ch.getBaseResource(); - if (base==null) - return null; - } - - try - { - path = URIUtil.canonicalPath(path); - return base.addPath(path); - } - catch(Exception e) - { - LOG.trace("",e); - } - - return null; - } - - - /* ------------------------------------------------------------ */ - public String[] getWelcomeFiles() - { - return _welcomeFiles; - } - - /* ------------------------------------------------------------ */ - public void setWelcomeFiles(String[] welcomeFiles) - { - _welcomeFiles=welcomeFiles; - } - - /* ------------------------------------------------------------ */ - protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException - { - for (int i=0;i<_welcomeFiles.length;i++) - { - Resource welcome=directory.addPath(_welcomeFiles[i]); - if (welcome.exists() && !welcome.isDirectory()) - return welcome; - } - - return null; - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - if (request.isHandled()) - return; - - boolean skipContentBody = false; - - if(!HttpMethods.GET.equals(request.getMethod())) - { - if(!HttpMethods.HEAD.equals(request.getMethod())) - { - //try another handler - super.handle(target, request, response); - return; - } - skipContentBody = true; - } - - Resource resource = getResource(request); - - if (resource==null || !resource.exists()) - { - if (target.endsWith("/jetty-dir.css")) - { - resource = getStylesheet(); - if (resource==null) - return; - response.setContentType("text/css"); - } - else - { - //no resource - try other handlers - super.handle(target, request, response); - return; - } - } - - if (!_aliases && resource.getAlias()!=null) - { - LOG.info(resource+" aliased to "+resource.getAlias()); - return; - } - - // We are going to serve something - request.setHandled(true); - - if (resource.isDirectory()) - { - if (!request.getPathInfo().endsWith("/")) - { - response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),"/"))); - return; - } - - Resource welcome=getWelcome(resource); - if (welcome!=null && welcome.exists()) - resource=welcome; - else - { - doDirectory(request,response,resource); - request.setHandled(true); - return; - } - } - - // set some headers - long last_modified=resource.lastModified(); - if (last_modified>0) - { - long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); - if (if_modified>0 && last_modified/1000<=if_modified/1000) - { - response.setStatus(HttpStatus.NOT_MODIFIED_304); - return; - } - } - - String mime = _mimeTypes.getMimeByExtension(resource.toString()); - if (mime==null) - mime=_mimeTypes.getMimeByExtension(request.getPathInfo()); - - // set the headers - doResponseHeaders(response,resource,mime); - response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified); - - if(skipContentBody) - return; - // Send the content - OutputStream out =null; - try {out = response.getOutputStream();} - catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());} - - // See if a short direct method can be used? - if (out instanceof AbstractHttpConnection.Output) - { - // TODO file mapped buffers - ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream()); - } - else - { - // Write content normally - resource.writeTo(out,0,resource.length()); - } - } - - /* ------------------------------------------------------------ */ - protected void doDirectory(Request request,HttpServletResponse response, Resource resource) - throws IOException - { - if (_directory) - { - String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0); - response.setContentType("text/html; charset=UTF-8"); - response.getWriter().println(listing); - } - else - response.sendError(HttpStatus.FORBIDDEN_403); - } - - /* ------------------------------------------------------------ */ - /** Set the response headers. - * This method is called to set the response headers such as content type and content length. - * May be extended to add additional headers. - * @param response - * @param resource - * @param mimeType - */ - protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) - { - if (mimeType!=null) - response.setContentType(mimeType); - - long length=resource.length(); - - if (response instanceof Response) - { - HttpFields fields = ((Response)response).getHttpFields(); - - if (length>0) - fields.putLongField(HttpHeaders.CONTENT_LENGTH,length); - } - else - { - if (length>0) - response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length)); - } - - } -}
--- a/src/org/eclipse/jetty/server/handler/ShutdownHandler.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * A handler that shuts the server down on a valid request. Used to do "soft" restarts from Java. If _exitJvm ist set to true a hard System.exit() call is being - * made. - * - * This handler is a contribution from Johannes Brodwall: https://bugs.eclipse.org/bugs/show_bug.cgi?id=357687 - * - * Usage: - * - * <pre> - Server server = new Server(8080); - HandlerList handlers = new HandlerList(); - handlers.setHandlers(new Handler[] - { someOtherHandler, new ShutdownHandler(server,"secret password") }); - server.setHandler(handlers); - server.start(); - </pre> - * - <pre> - public static void attemptShutdown(int port, String shutdownCookie) { - try { - URL url = new URL("http://localhost:" + port + "/shutdown?token=" + shutdownCookie); - HttpURLConnection connection = (HttpURLConnection)url.openConnection(); - connection.setRequestMethod("POST"); - connection.getResponseCode(); - logger.info("Shutting down " + url + ": " + connection.getResponseMessage()); - } catch (SocketException e) { - logger.debug("Not running"); - // Okay - the server is not running - } catch (IOException e) { - throw new RuntimeException(e); - } - } - </pre> - */ -public class ShutdownHandler extends AbstractHandler -{ - private static final Logger LOG = LoggerFactory.getLogger(ShutdownHandler.class); - - private final String _shutdownToken; - - private final Server _server; - - private boolean _exitJvm = false; - - - - /** - * Creates a listener that lets the server be shut down remotely (but only from localhost). - * - * @param server - * the Jetty instance that should be shut down - * @param shutdownToken - * a secret password to avoid unauthorized shutdown attempts - */ - public ShutdownHandler(Server server, String shutdownToken) - { - this._server = server; - this._shutdownToken = shutdownToken; - } - - @Override - public void handle(String target, Request request, HttpServletResponse response) throws IOException, ServletException - { - if (!target.equals("/shutdown")) - { - return; - } - - if (!request.getMethod().equals("POST")) - { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return; - } - if (!hasCorrectSecurityToken(request)) - { - LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request)); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - if (!requestFromLocalhost(request)) - { - LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request)); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - - LOG.info("Shutting down by request from " + getRemoteAddr(request)); - - new Thread() - { - public void run () - { - try - { - shutdownServer(); - } - catch (InterruptedException e) - { - LOG.trace("",e); - } - catch (Exception e) - { - throw new RuntimeException("Shutting down server",e); - } - } - }.start(); - } - - private boolean requestFromLocalhost(Request request) - { - return "127.0.0.1".equals(getRemoteAddr(request)); - } - - protected String getRemoteAddr(Request request) - { - return request.getRemoteAddr(); - } - - private boolean hasCorrectSecurityToken(Request request) - { - return _shutdownToken.equals(request.getParameter("token")); - } - - private void shutdownServer() throws Exception - { - _server.stop(); - - if (_exitJvm) - { - System.exit(0); - } - } - - public void setExitJvm(boolean exitJvm) - { - this._exitJvm = exitJvm; - } - -}
--- a/src/org/eclipse/jetty/server/nio/BlockingChannelConnector.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.nio; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.nio.channels.ByteChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.jetty.http.HttpException; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.io.nio.ChannelEndPoint; -import org.eclipse.jetty.server.BlockingHttpConnection; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.AbstractHttpConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------------------------- */ -/** Blocking NIO connector. - * This connector uses efficient NIO buffers with a traditional blocking thread model. - * Direct NIO buffers are used and a thread is allocated per connections. - * - * This connector is best used when there are a few very active connections. - * - * @org.apache.xbean.XBean element="blockingNioConnector" description="Creates a blocking NIO based socket connector" - * - * - * - */ -public final class BlockingChannelConnector extends Connector -{ - private static final Logger LOG = LoggerFactory.getLogger(BlockingChannelConnector.class); - - private final Set<BlockingChannelEndPoint> _endpoints = new ConcurrentHashMap<BlockingChannelEndPoint,Boolean>().newKeySet(); - - - /* ------------------------------------------------------------ */ - /** Constructor. - * - */ - public BlockingChannelConnector(Server server,int port) - { - super(server,port); - } - - - @Override - protected void doStart() throws Exception - { - // Create a new server socket and set to non blocking mode - _acceptChannel = ServerSocketChannel.open(); - _acceptChannel.configureBlocking(true); - - // Bind the server socket to the local host and port - InetSocketAddress addr = getHost()==null?new InetSocketAddress(port):new InetSocketAddress(getHost(),port); - _acceptChannel.bind(addr); - - super.doStart(); - server.threadPool.execute(new Runnable() - { - - public void run() - { - while (isRunning()) - { - try - { - Thread.sleep(400); - long now = System.currentTimeMillis(); - for (BlockingChannelEndPoint endp : _endpoints) - { - endp.checkIdleTimestamp(now); - } - } - catch(InterruptedException e) - { - LOG.trace("",e); - } - catch(Exception e) - { - LOG.warn("",e); - } - } - } - - }); - - } - - @Override - public void accept() - throws IOException, InterruptedException - { - SocketChannel channel = _acceptChannel.accept(); - channel.configureBlocking(true); - Socket socket = channel.socket(); - configure(socket); - - BlockingChannelEndPoint endp = new BlockingChannelEndPoint(channel); - try { - server.threadPool.execute(endp); - } catch(RejectedExecutionException e) { - LOG.warn("dispatch failed for {}",endp._connection); - endp.close(); - } - } - - @Override - public void customize(AbstractHttpConnection con) - throws IOException - { - con._endp.setMaxIdleTime(_maxIdleTime); - configure(con._endp.getChannel().socket()); - } - - - private class BlockingChannelEndPoint extends ChannelEndPoint implements Runnable - { - private final BlockingHttpConnection _connection; - private int _timeout; - private volatile long _idleTimestamp; - - BlockingChannelEndPoint(SocketChannel channel) - throws IOException - { - super(channel,BlockingChannelConnector.this._maxIdleTime); - _connection = new BlockingHttpConnection(BlockingChannelConnector.this,this); - } - - private void checkIdleTimestamp(long now) - { - if (_idleTimestamp!=0 && _timeout>0 && now>(_idleTimestamp+_timeout)) - { - try - { - close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - } - } - - @Override - public int fill(ByteBuffer buffer) throws IOException - { - _idleTimestamp = System.currentTimeMillis(); - return super.fill(buffer); - } - - @Override - public int flush(ByteBuffer buffer) throws IOException - { - _idleTimestamp = System.currentTimeMillis(); - return super.flush(buffer); - } - - @Override - public int flush(ByteBuffer header, ByteBuffer buffer, ByteBuffer trailer) throws IOException - { - _idleTimestamp = System.currentTimeMillis(); - return super.flush(header,buffer,trailer); - } - - @Override - public void run() - { - try - { - _timeout = getMaxIdleTime(); - _endpoints.add(this); -/* - while (isOpen()) - { - _idleTimestamp = System.currentTimeMillis(); - _connection.handle(); - } -*/ - _idleTimestamp = System.currentTimeMillis(); - _connection.handle(); - if( isOpen() ) throw new RuntimeException(); - } - catch (EofException e) - { - LOG.warn("EOF", e); -// LOG.debug("EOF", e); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - catch (HttpException e) - { - LOG.warn("BAD", e); -// LOG.debug("BAD", e); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - catch(Throwable e) - { - LOG.warn("handle failed",e); - try{close();} - catch(IOException e2){LOG.trace("",e2);} - } - finally - { - _endpoints.remove(this); - - // wait for client to close, but if not, close ourselves. - try - { - if (!_socket.isClosed()) - { - long timestamp = System.currentTimeMillis(); - int max_idle = getMaxIdleTime(); - - _socket.setSoTimeout(getMaxIdleTime()); - int c=0; - do - { - c = _socket.getInputStream().read(); - } - while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle); - if (!_socket.isClosed()) - _socket.close(); - } - } - catch(IOException e) - { - LOG.trace("",e); - } - } - } - - @Override - public String toString() - { - return String.format("BCEP@%x{l(%s)<->r(%s),open=%b,ishut=%b,oshut=%b}-{%s}", - hashCode(), - _socket.getRemoteSocketAddress(), - _socket.getLocalSocketAddress(), - isOpen(), - isInputShutdown(), - isOutputShutdown(), - _connection); - } - - } -}
--- a/src/org/eclipse/jetty/server/nio/SelectChannelConnector.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.nio; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.channels.SelectionKey; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; - -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.nio.AsyncConnection; -import org.eclipse.jetty.io.nio.SelectChannelEndPoint; -import org.eclipse.jetty.io.nio.SelectorManager; -import org.eclipse.jetty.server.AsyncHttpConnection; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.AbstractHttpConnection; - -/* ------------------------------------------------------------------------------- */ -/** - * Selecting NIO connector. - * <p> - * This connector uses efficient NIO buffers with a non blocking threading model. Direct NIO buffers - * are used and threads are only allocated to connections with requests. Synchronization is used to - * simulate blocking for the servlet API, and any unflushed content at the end of request handling - * is written asynchronously. - * </p> - * <p> - * This connector is best used when there are a many connections that have idle periods. - * </p> - * - * @org.apache.xbean.XBean element="nioConnector" description="Creates an NIO based socket connector" - */ -public class SelectChannelConnector extends Connector -{ - private final SelectorManager _manager = new SelectorManager(this); - - public SelectChannelConnector(Server server,int port) - { - super(server,port); - addBean(_manager,true); - } - - @Override - public final void accept() throws IOException - { - ServerSocketChannel server = _acceptChannel; - - if (server!=null && server.isOpen() && _manager.isStarted()) - { - final SocketChannel channel = server.accept(); - channel.configureBlocking(false); - Socket socket = channel.socket(); - configure(socket); - this.server.threadPool.execute(new Runnable(){public void run(){ - _manager.register(channel); - }}); - } - } - - @Override - public void customize(AbstractHttpConnection con) throws IOException - { - con._endp.setMaxIdleTime(_maxIdleTime); - } - - @Override - protected synchronized void doStart() throws Exception - { - if (_acceptChannel == null) - { - // Create a new server socket - _acceptChannel = ServerSocketChannel.open(); - // Set to blocking mode - _acceptChannel.configureBlocking(true); - - // Bind the server socket to the local host and port - _acceptChannel.socket().setReuseAddress(true); - InetSocketAddress addr = getHost()==null?new InetSocketAddress(port):new InetSocketAddress(getHost(),port); - _acceptChannel.bind(addr); - if( _acceptChannel.socket().getLocalPort() != port ) - throw new IOException("Server channel not bound"); - } - - super.doStart(); - } - - public AsyncConnection newConnection(SocketChannel channel,AsyncEndPoint endpoint) - { - return new AsyncHttpConnection(this,endpoint); - } -}
--- a/src/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -SelectChannelConnector: HTTP connector using NIO ByteChannels and Selectors -lowResourcesConnections: The number of connections, which if exceeded represents low resources
--- a/src/org/eclipse/jetty/server/ssl/ServletSSL.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.ssl; - -/* --------------------------------------------------------------------- */ -/** - * Jetty Servlet SSL support utilities. - * <p> - * A collection of utilities required to support the SSL requirements of the Servlet 2.2 and 2.3 - * specs. - * - * <p> - * Used by the SSL listener classes. - * - * - */ -public class ServletSSL -{ - /* ------------------------------------------------------------ */ - /** - * Given the name of a TLS/SSL cipher suite, return an int representing it effective stream - * cipher key strength. i.e. How much entropy material is in the key material being fed into the - * encryption routines. - * - * <p> - * This is based on the information on effective key lengths in RFC 2246 - The TLS Protocol - * Version 1.0, Appendix C. CipherSuite definitions: - * - * <pre> - * Effective - * Cipher Type Key Bits - * - * NULL * Stream 0 - * IDEA_CBC Block 128 - * RC2_CBC_40 * Block 40 - * RC4_40 * Stream 40 - * RC4_128 Stream 128 - * DES40_CBC * Block 40 - * DES_CBC Block 56 - * 3DES_EDE_CBC Block 168 - * </pre> - * - * @param cipherSuite String name of the TLS cipher suite. - * @return int indicating the effective key entropy bit-length. - */ - public static int deduceKeyLength(String cipherSuite) - { - // Roughly ordered from most common to least common. - if (cipherSuite == null) - return 0; - else if (cipherSuite.indexOf("WITH_AES_256_") >= 0) - return 256; - else if (cipherSuite.indexOf("WITH_RC4_128_") >= 0) - return 128; - else if (cipherSuite.indexOf("WITH_AES_128_") >= 0) - return 128; - else if (cipherSuite.indexOf("WITH_RC4_40_") >= 0) - return 40; - else if (cipherSuite.indexOf("WITH_3DES_EDE_CBC_") >= 0) - return 168; - else if (cipherSuite.indexOf("WITH_IDEA_CBC_") >= 0) - return 128; - else if (cipherSuite.indexOf("WITH_RC2_CBC_40_") >= 0) - return 40; - else if (cipherSuite.indexOf("WITH_DES40_CBC_") >= 0) - return 40; - else if (cipherSuite.indexOf("WITH_DES_CBC_") >= 0) - return 56; - else - return 0; - } -}
--- a/src/org/eclipse/jetty/server/ssl/SslCertificates.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.ssl; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; - -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.TypeUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SslCertificates -{ - private static final Logger LOG = LoggerFactory.getLogger(SslCertificates.class); - - /** - * The name of the SSLSession attribute that will contain any cached information. - */ - static final String CACHED_INFO_ATTR = CachedInfo.class.getName(); - - public static X509Certificate[] getCertChain(SSLSession sslSession) - { - try - { - javax.security.cert.X509Certificate javaxCerts[]=sslSession.getPeerCertificateChain(); - if (javaxCerts==null||javaxCerts.length==0) - return null; - - int length=javaxCerts.length; - X509Certificate[] javaCerts=new X509Certificate[length]; - - java.security.cert.CertificateFactory cf=java.security.cert.CertificateFactory.getInstance("X.509"); - for (int i=0; i<length; i++) - { - byte bytes[]=javaxCerts[i].getEncoded(); - ByteArrayInputStream stream=new ByteArrayInputStream(bytes); - javaCerts[i]=(X509Certificate)cf.generateCertificate(stream); - } - - return javaCerts; - } - catch (SSLPeerUnverifiedException pue) - { - return null; - } - catch (Exception e) - { - LOG.warn("EXCEPTION",e); - return null; - } - } - - - /* ------------------------------------------------------------ */ - /** - * Allow the Listener a chance to customise the request. before the server - * does its stuff. <br> - * This allows the required attributes to be set for SSL requests. <br> - * The requirements of the Servlet specs are: - * <ul> - * <li> an attribute named "javax.servlet.request.ssl_session_id" of type - * String (since Servlet Spec 3.0).</li> - * <li> an attribute named "javax.servlet.request.cipher_suite" of type - * String.</li> - * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li> - * <li> an attribute named "javax.servlet.request.X509Certificate" of type - * java.security.cert.X509Certificate[]. This is an array of objects of type - * X509Certificate, the order of this array is defined as being in ascending - * order of trust. The first certificate in the chain is the one set by the - * client, the next is the one used to authenticate the first, and so on. - * </li> - * </ul> - * - * @param endpoint - * The Socket the request arrived on. - * @param request - * HttpRequest to be customised. - */ - public static void customize(SSLSession sslSession, EndPoint endpoint, Request request) throws IOException - { - request.setScheme("https"); - - try - { - String cipherSuite=sslSession.getCipherSuite(); - Integer keySize; - X509Certificate[] certs; - String idStr; - - CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR); - if (cachedInfo!=null) - { - keySize=cachedInfo.getKeySize(); - certs=cachedInfo.getCerts(); - idStr=cachedInfo.getIdStr(); - } - else - { - keySize=new Integer(ServletSSL.deduceKeyLength(cipherSuite)); - certs=SslCertificates.getCertChain(sslSession); - byte[] bytes = sslSession.getId(); - idStr = TypeUtil.toHexString(bytes); - cachedInfo=new CachedInfo(keySize,certs,idStr); - sslSession.putValue(CACHED_INFO_ATTR,cachedInfo); - } - - if (certs!=null) - request.setAttribute("javax.servlet.request.X509Certificate",certs); - - request.setAttribute("javax.servlet.request.cipher_suite",cipherSuite); - request.setAttribute("javax.servlet.request.key_size",keySize); - request.setAttribute("javax.servlet.request.ssl_session_id", idStr); - } - catch (Exception e) - { - LOG.warn("EXCEPTION",e); - } - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /** - * Simple bundle of information that is cached in the SSLSession. Stores the - * effective keySize and the client certificate chain. - */ - private static class CachedInfo - { - private final X509Certificate[] _certs; - private final Integer _keySize; - private final String _idStr; - - CachedInfo(Integer keySize, X509Certificate[] certs,String idStr) - { - this._keySize=keySize; - this._certs=certs; - this._idStr=idStr; - } - - X509Certificate[] getCerts() - { - return _certs; - } - - Integer getKeySize() - { - return _keySize; - } - - String getIdStr() - { - return _idStr; - } - } - -}
--- a/src/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.ssl; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; - -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.io.nio.AsyncConnection; -import org.eclipse.jetty.io.nio.SslConnection; -import org.eclipse.jetty.io.nio.SelectChannelEndPoint; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.AbstractHttpConnection; -import org.eclipse.jetty.server.AsyncHttpConnection; -import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.ssl.SslContextFactory; - -/* ------------------------------------------------------------ */ -/** - * SslSelectChannelConnector. - * - * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector" - */ -public final class SslSelectChannelConnector extends SelectChannelConnector -{ - private final SslContextFactory _sslContextFactory; - - /* ------------------------------------------------------------ */ - public SslSelectChannelConnector(Server server,int port) - { - this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH),server,port); - setSoLingerTime(30000); - } - - /* ------------------------------------------------------------ */ - /** Construct with explicit SslContextFactory. - * The SslContextFactory passed is added via {@link #addBean(Object)} so that - * it's lifecycle may be managed with {@link AggregateLifeCycle}. - * @param sslContextFactory - */ - public SslSelectChannelConnector(SslContextFactory sslContextFactory,Server server,int port) - { - super(server,port); - _sslContextFactory = sslContextFactory; - addBean(_sslContextFactory); - setSoLingerTime(30000); - } - - @Override - protected ByteBuffer newBuffer(int size) { - return ByteBuffer.allocate(size); - } - - - /* ------------------------------------------------------------ */ - /** - * Allow the Listener a chance to customise the request. before the server - * does its stuff. <br> - * This allows the required attributes to be set for SSL requests. <br> - * The requirements of the Servlet specs are: - * <ul> - * <li> an attribute named "javax.servlet.request.ssl_session_id" of type - * String (since Servlet Spec 3.0).</li> - * <li> an attribute named "javax.servlet.request.cipher_suite" of type - * String.</li> - * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li> - * <li> an attribute named "javax.servlet.request.X509Certificate" of type - * java.security.cert.X509Certificate[]. This is an array of objects of type - * X509Certificate, the order of this array is defined as being in ascending - * order of trust. The first certificate in the chain is the one set by the - * client, the next is the one used to authenticate the first, and so on. - * </li> - * </ul> - * - * @param endpoint - * The Socket the request arrived on. - * @param request - * HttpRequest to be customised. - */ - @Override - public void customize(AbstractHttpConnection con) throws IOException - { - con._request.setScheme("https"); - super.customize(con); - - SslConnection.SslEndPoint sslEndpoint=(SslConnection.SslEndPoint)con._endp; - SSLEngine sslEngine = sslEndpoint.getSslEngine(); - SSLSession sslSession = sslEngine.getSession(); - - SslCertificates.customize(sslSession,con._endp,con._request); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory() - */ - public SslContextFactory getSslContextFactory() - { - return _sslContextFactory; - } - - /* ------------------------------------------------------------ */ - /** - * By default, we're confidential, given we speak SSL. But, if we've been - * told about an confidential port, and said port is not our port, then - * we're not. This allows separation of listeners providing INTEGRAL versus - * CONFIDENTIAL constraints, such as one SSL listener configured to require - * client certs providing CONFIDENTIAL, whereas another SSL listener not - * requiring client certs providing mere INTEGRAL constraints. - */ - @Override - public boolean isConfidential() - { - return true; - } - - @Override - public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint) - { - try - { - SSLEngine engine = createSSLEngine(channel); - SslConnection connection = new SslConnection(engine, endpoint); - AsyncHttpConnection delegate = (AsyncHttpConnection)super.newConnection(channel, connection.getSslEndPoint()); - connection.getSslEndPoint().setConnection(delegate); - connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate()); - return connection; - } - catch (IOException e) - { - throw new RuntimeIOException(e); - } - } - - /* ------------------------------------------------------------ */ - /** - * @param channel A channel which if passed is used as to extract remote - * host and port for the purposes of SSL session caching - * @return A SSLEngine for a new or cached SSL Session - * @throws IOException if the SSLEngine cannot be created - */ - private SSLEngine createSSLEngine(SocketChannel channel) throws IOException - { - String peerHost = channel.socket().getInetAddress().getHostAddress(); - int peerPort = channel.socket().getPort(); - SSLEngine engine = _sslContextFactory.newSslEngine(peerHost, peerPort); - engine.setUseClientMode(false); - return engine; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart() - */ - @Override - protected void doStart() throws Exception - { - _sslContextFactory.checkKeyStore(); - _sslContextFactory.start(); - - SSLEngine sslEngine = _sslContextFactory.newSslEngine(); - - sslEngine.setUseClientMode(false); - - SSLSession sslSession = sslEngine.getSession(); - - if (_requestHeaderSize < sslSession.getApplicationBufferSize()) - _requestHeaderSize = sslSession.getApplicationBufferSize(); - if (_requestBufferSize < sslSession.getApplicationBufferSize()) - _requestBufferSize = sslSession.getApplicationBufferSize(); - - super.doStart(); - } - -}
--- a/src/org/eclipse/jetty/util/ArrayQueue.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,379 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.AbstractList; -import java.util.NoSuchElementException; -import java.util.Queue; - -/* ------------------------------------------------------------ */ -/** - * Queue backed by circular array. - * <p/> - * This partial Queue implementation (also with {@link #remove()} for stack operation) - * is backed by a growable circular array. - * - * @param <E> - */ -public class ArrayQueue<E> extends AbstractList<E> implements Queue<E> -{ - public static final int DEFAULT_CAPACITY = 64; - public static final int DEFAULT_GROWTH = 32; - - protected final Object _lock; - protected final int _growCapacity; - protected Object[] _elements; - protected int _nextE; - protected int _nextSlot; - protected int _size; - - /* ------------------------------------------------------------ */ - public ArrayQueue() - { - this(DEFAULT_CAPACITY, -1); - } - - /* ------------------------------------------------------------ */ - public ArrayQueue(int capacity) - { - this(capacity, -1); - } - - /* ------------------------------------------------------------ */ - public ArrayQueue(int initCapacity, int growBy) - { - this(initCapacity, growBy, null); - } - - /* ------------------------------------------------------------ */ - public ArrayQueue(int initCapacity, int growBy, Object lock) - { - _lock = lock == null ? this : lock; - _growCapacity = growBy; - _elements = new Object[initCapacity]; - } - - /* ------------------------------------------------------------ */ - public int getCapacity() - { - synchronized (_lock) - { - return _elements.length; - } - } - - /* ------------------------------------------------------------ */ - @Override - public boolean add(E e) - { - if (!offer(e)) - throw new IllegalStateException("Full"); - return true; - } - - /* ------------------------------------------------------------ */ - public boolean offer(E e) - { - synchronized (_lock) - { - return enqueue(e); - } - } - - /* ------------------------------------------------------------ */ - private boolean enqueue(E e) - { - if (_size == _elements.length && !grow()) - return false; - - _size++; - _elements[_nextSlot++] = e; - if (_nextSlot == _elements.length) - _nextSlot = 0; - - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Add without synchronization or bounds checking - * - * @param e the element to add - * @see #add(Object) - */ - public void addUnsafe(E e) - { - if (!enqueue(e)) - throw new IllegalStateException("Full"); - } - - /* ------------------------------------------------------------ */ - public E element() - { - synchronized (_lock) - { - if (isEmpty()) - throw new NoSuchElementException(); - return at(_nextE); - } - } - - @SuppressWarnings("unchecked") - private E at(int index) - { - return (E)_elements[index]; - } - - /* ------------------------------------------------------------ */ - public E peek() - { - synchronized (_lock) - { - if (isEmpty()) - return null; - return at(_nextE); - } - } - - /* ------------------------------------------------------------ */ - public E poll() - { - synchronized (_lock) - { - if (_size == 0) - return null; - return dequeue(); - } - } - - /* ------------------------------------------------------------ */ - private E dequeue() - { - E e = at(_nextE); - _elements[_nextE] = null; - _size--; - if (++_nextE == _elements.length) - _nextE = 0; - return e; - } - - /* ------------------------------------------------------------ */ - public E remove() - { - synchronized (_lock) - { - if (_size == 0) - throw new NoSuchElementException(); - return dequeue(); - } - } - - /* ------------------------------------------------------------ */ - @Override - public void clear() - { - synchronized (_lock) - { - _size = 0; - _nextE = 0; - _nextSlot = 0; - } - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isEmpty() - { - synchronized (_lock) - { - return _size == 0; - } - } - - /* ------------------------------------------------------------ */ - @Override - public int size() - { - synchronized (_lock) - { - return _size; - } - } - - /* ------------------------------------------------------------ */ - @Override - public E get(int index) - { - synchronized (_lock) - { - if (index < 0 || index >= _size) - throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")"); - return getUnsafe(index); - } - } - - /* ------------------------------------------------------------ */ - /** - * Get without synchronization or bounds checking. - * - * @param index index of the element to return - * @return the element at the specified index - * @see #get(int) - */ - public E getUnsafe(int index) - { - int i = (_nextE + index) % _elements.length; - return at(i); - } - - /* ------------------------------------------------------------ */ - @Override - public E remove(int index) - { - synchronized (_lock) - { - if (index < 0 || index >= _size) - throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")"); - - int i = (_nextE + index) % _elements.length; - E old = at(i); - - if (i < _nextSlot) - { - // 0 _elements.length - // _nextE........._nextSlot - System.arraycopy(_elements, i + 1, _elements, i, _nextSlot - i); - _nextSlot--; - _size--; - } - else - { - // 0 _elements.length - // ......_nextSlot _nextE.......... - System.arraycopy(_elements, i + 1, _elements, i, _elements.length - i - 1); - if (_nextSlot > 0) - { - _elements[_elements.length - 1] = _elements[0]; - System.arraycopy(_elements, 1, _elements, 0, _nextSlot - 1); - _nextSlot--; - } - else - _nextSlot = _elements.length - 1; - - _size--; - } - - return old; - } - } - - /* ------------------------------------------------------------ */ - @Override - public E set(int index, E element) - { - synchronized (_lock) - { - if (index < 0 || index >= _size) - throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")"); - - int i = _nextE + index; - if (i >= _elements.length) - i -= _elements.length; - E old = at(i); - _elements[i] = element; - return old; - } - } - - /* ------------------------------------------------------------ */ - @Override - public void add(int index, E element) - { - synchronized (_lock) - { - if (index < 0 || index > _size) - throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")"); - - if (_size == _elements.length && !grow()) - throw new IllegalStateException("Full"); - - if (index == _size) - { - add(element); - } - else - { - int i = _nextE + index; - if (i >= _elements.length) - i -= _elements.length; - - _size++; - _nextSlot++; - if (_nextSlot == _elements.length) - _nextSlot = 0; - - if (i < _nextSlot) - { - // 0 _elements.length - // _nextE.....i..._nextSlot - // 0 _elements.length - // ..i..._nextSlot _nextE.......... - System.arraycopy(_elements, i, _elements, i + 1, _nextSlot - i); - _elements[i] = element; - } - else - { - // 0 _elements.length - // ......_nextSlot _nextE.....i.... - if (_nextSlot > 0) - { - System.arraycopy(_elements, 0, _elements, 1, _nextSlot); - _elements[0] = _elements[_elements.length - 1]; - } - - System.arraycopy(_elements, i, _elements, i + 1, _elements.length - i - 1); - _elements[i] = element; - } - } - } - } - - /* ------------------------------------------------------------ */ - protected boolean grow() - { - synchronized (_lock) - { - if (_growCapacity <= 0) - return false; - - Object[] elements = new Object[_elements.length + _growCapacity]; - - int split = _elements.length - _nextE; - if (split > 0) - System.arraycopy(_elements, _nextE, elements, 0, split); - if (_nextE != 0) - System.arraycopy(_elements, 0, elements, split, _nextSlot); - - _elements = elements; - _nextE = 0; - _nextSlot = _size; - return true; - } - } -}
--- a/src/org/eclipse/jetty/util/Attributes.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.Enumeration; - -/* ------------------------------------------------------------ */ -/** Attributes. - * Interface commonly used for storing attributes. - * - * - */ -public interface Attributes -{ - public void removeAttribute(String name); - public void setAttribute(String name, Object attribute); - public Object getAttribute(String name); - public Enumeration<String> getAttributeNames(); - public void clearAttributes(); -}
--- a/src/org/eclipse/jetty/util/AttributesMap.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/* ------------------------------------------------------------ */ -/** AttributesMap. - * - * - */ -public class AttributesMap implements Attributes -{ - protected final Map<String,Object> _map; - - /* ------------------------------------------------------------ */ - public AttributesMap() - { - _map=new HashMap<String,Object>(); - } - - /* ------------------------------------------------------------ */ - public AttributesMap(Map<String,Object> map) - { - _map=map; - } - - /* ------------------------------------------------------------ */ - public AttributesMap(AttributesMap map) - { - _map=new HashMap<String,Object>(map._map); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#removeAttribute(java.lang.String) - */ - public void removeAttribute(String name) - { - _map.remove(name); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#setAttribute(java.lang.String, java.lang.Object) - */ - public void setAttribute(String name, Object attribute) - { - if (attribute==null) - _map.remove(name); - else - _map.put(name, attribute); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#getAttribute(java.lang.String) - */ - public Object getAttribute(String name) - { - return _map.get(name); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#getAttributeNames() - */ - public Enumeration<String> getAttributeNames() - { - return Collections.enumeration(_map.keySet()); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#getAttributeNames() - */ - public Set<String> getAttributeNameSet() - { - return _map.keySet(); - } - - /* ------------------------------------------------------------ */ - public Set<Map.Entry<String, Object>> getAttributeEntrySet() - { - return _map.entrySet(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#getAttributeNames() - */ - public static Enumeration<String> getAttributeNamesCopy(Attributes attrs) - { - if (attrs instanceof AttributesMap) - return Collections.enumeration(((AttributesMap)attrs)._map.keySet()); - - List<String> names = new ArrayList<String>(); - names.addAll(Collections.list(attrs.getAttributeNames())); - return Collections.enumeration(names); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.util.Attributes#clear() - */ - public void clearAttributes() - { - _map.clear(); - } - - /* ------------------------------------------------------------ */ - public int size() - { - return _map.size(); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _map.toString(); - } - - /* ------------------------------------------------------------ */ - public Set<String> keySet() - { - return _map.keySet(); - } - - /* ------------------------------------------------------------ */ - public void addAll(Attributes attributes) - { - Enumeration<String> e = attributes.getAttributeNames(); - while (e.hasMoreElements()) - { - String name=e.nextElement(); - setAttribute(name,attributes.getAttribute(name)); - } - } - -}
--- a/src/org/eclipse/jetty/util/ByteArrayISO8859Writer.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; - - -/* ------------------------------------------------------------ */ -/** Byte Array ISO 8859 writer. - * This class combines the features of a OutputStreamWriter for - * ISO8859 encoding with that of a ByteArrayOutputStream. It avoids - * many inefficiencies associated with these standard library classes. - * It has been optimized for standard ASCII characters. - * - * - */ -public class ByteArrayISO8859Writer extends Writer -{ - private byte[] _buf; - private int _size; - private ByteArrayOutputStream2 _bout=null; - private OutputStreamWriter _writer=null; - private boolean _fixed=false; - - /* ------------------------------------------------------------ */ - /** Constructor. - */ - public ByteArrayISO8859Writer() - { - _buf=new byte[2048]; - } - - /* ------------------------------------------------------------ */ - /** Constructor. - * @param capacity Buffer capacity - */ - public ByteArrayISO8859Writer(int capacity) - { - _buf=new byte[capacity]; - } - - /* ------------------------------------------------------------ */ - public ByteArrayISO8859Writer(byte[] buf) - { - _buf=buf; - _fixed=true; - } - - /* ------------------------------------------------------------ */ - public Object getLock() - { - return lock; - } - - /* ------------------------------------------------------------ */ - public int size() - { - return _size; - } - - /* ------------------------------------------------------------ */ - public int capacity() - { - return _buf.length; - } - - /* ------------------------------------------------------------ */ - public int spareCapacity() - { - return _buf.length-_size; - } - - /* ------------------------------------------------------------ */ - public void setLength(int l) - { - _size=l; - } - - /* ------------------------------------------------------------ */ - public byte[] getBuf() - { - return _buf; - } - - /* ------------------------------------------------------------ */ - public void writeTo(OutputStream out) - throws IOException - { - out.write(_buf,0,_size); - } - - /* ------------------------------------------------------------ */ - public void write(char c) - throws IOException - { - ensureSpareCapacity(1); - if (c>=0&&c<=0x7f) - _buf[_size++]=(byte)c; - else - { - char[] ca ={c}; - writeEncoded(ca,0,1); - } - } - - /* ------------------------------------------------------------ */ - @Override - public void write(char[] ca) - throws IOException - { - ensureSpareCapacity(ca.length); - for (int i=0;i<ca.length;i++) - { - char c=ca[i]; - if (c>=0&&c<=0x7f) - _buf[_size++]=(byte)c; - else - { - writeEncoded(ca,i,ca.length-i); - break; - } - } - } - - /* ------------------------------------------------------------ */ - @Override - public void write(char[] ca,int offset, int length) - throws IOException - { - ensureSpareCapacity(length); - for (int i=0;i<length;i++) - { - char c=ca[offset+i]; - if (c>=0&&c<=0x7f) - _buf[_size++]=(byte)c; - else - { - writeEncoded(ca,offset+i,length-i); - break; - } - } - } - - /* ------------------------------------------------------------ */ - @Override - public void write(String s) - throws IOException - { - if (s==null) - { - write("null",0,4); - return; - } - - int length=s.length(); - ensureSpareCapacity(length); - for (int i=0;i<length;i++) - { - char c=s.charAt(i); - if (c>=0x0&&c<=0x7f) - _buf[_size++]=(byte)c; - else - { - writeEncoded(s.toCharArray(),i,length-i); - break; - } - } - } - - /* ------------------------------------------------------------ */ - @Override - public void write(String s,int offset, int length) - throws IOException - { - ensureSpareCapacity(length); - for (int i=0;i<length;i++) - { - char c=s.charAt(offset+i); - if (c>=0&&c<=0x7f) - _buf[_size++]=(byte)c; - else - { - writeEncoded(s.toCharArray(),offset+i,length-i); - break; - } - } - } - - /* ------------------------------------------------------------ */ - private void writeEncoded(char[] ca,int offset, int length) - throws IOException - { - if (_bout==null) - { - _bout = new ByteArrayOutputStream2(2*length); - _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1); - } - else - _bout.reset(); - _writer.write(ca,offset,length); - _writer.flush(); - ensureSpareCapacity(_bout.getCount()); - System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount()); - _size+=_bout.getCount(); - } - - /* ------------------------------------------------------------ */ - @Override - public void flush() - {} - - /* ------------------------------------------------------------ */ - public void resetWriter() - { - _size=0; - } - - /* ------------------------------------------------------------ */ - @Override - public void close() - {} - - /* ------------------------------------------------------------ */ - public void destroy() - { - _buf=null; - } - - /* ------------------------------------------------------------ */ - public void ensureSpareCapacity(int n) - throws IOException - { - if (_size+n>_buf.length) - { - if (_fixed) - throw new IOException("Buffer overflow: "+_buf.length); - byte[] buf = new byte[(_buf.length+n)*4/3]; - System.arraycopy(_buf,0,buf,0,_size); - _buf=buf; - } - } - - - /* ------------------------------------------------------------ */ - public byte[] getByteArray() - { - byte[] data=new byte[_size]; - System.arraycopy(_buf,0,data,0,_size); - return data; - } - -} - -
--- a/src/org/eclipse/jetty/util/ByteArrayOutputStream2.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; -import java.io.ByteArrayOutputStream; - -/* ------------------------------------------------------------ */ -/** ByteArrayOutputStream with public internals - - * - */ -public class ByteArrayOutputStream2 extends ByteArrayOutputStream -{ - public ByteArrayOutputStream2(){super();} - public ByteArrayOutputStream2(int size){super(size);} - public byte[] getBuf(){return buf;} - public int getCount(){return count;} - public void setCount(int count){this.count = count;} - - public void reset(int minSize) - { - reset(); - if (buf.length<minSize) - { - buf=new byte[minSize]; - } - } - - public void writeUnchecked(int b) - { - buf[count++]=(byte)b; - } - -}
--- a/src/org/eclipse/jetty/util/IO.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,313 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ======================================================================== */ -/** IO Utilities. - * Provides stream handling utilities in - * singleton Threadpool implementation accessed by static members. - */ -public class IO -{ - private static final Logger LOG = LoggerFactory.getLogger(IO.class); - - /* ------------------------------------------------------------------- */ - private static int bufferSize = 64*1024; - - /* ------------------------------------------------------------------- */ - /** Copy Stream in to Stream out until EOF or exception. - */ - public static void copy(InputStream in, OutputStream out) - throws IOException - { - copy(in,out,-1); - } - - /* ------------------------------------------------------------------- */ - /** Copy Reader to Writer out until EOF or exception. - */ - public static void copy(Reader in, Writer out) - throws IOException - { - copy(in,out,-1); - } - - /* ------------------------------------------------------------------- */ - /** Copy Stream in to Stream for byteCount bytes or until EOF or exception. - */ - public static void copy(InputStream in, - OutputStream out, - long byteCount) - throws IOException - { - byte buffer[] = new byte[bufferSize]; - int len=bufferSize; - - if (byteCount>=0) - { - while (byteCount>0) - { - int max = byteCount<bufferSize?(int)byteCount:bufferSize; - len=in.read(buffer,0,max); - - if (len==-1) - break; - - byteCount -= len; - out.write(buffer,0,len); - } - } - else - { - while (true) - { - len=in.read(buffer,0,bufferSize); - if (len<0 ) - break; - out.write(buffer,0,len); - } - } - } - - /* ------------------------------------------------------------------- */ - /** Copy Reader to Writer for byteCount bytes or until EOF or exception. - */ - public static void copy(Reader in, - Writer out, - long byteCount) - throws IOException - { - char buffer[] = new char[bufferSize]; - int len=bufferSize; - - if (byteCount>=0) - { - while (byteCount>0) - { - if (byteCount<bufferSize) - len=in.read(buffer,0,(int)byteCount); - else - len=in.read(buffer,0,bufferSize); - - if (len==-1) - break; - - byteCount -= len; - out.write(buffer,0,len); - } - } - else if (out instanceof PrintWriter) - { - PrintWriter pout=(PrintWriter)out; - while (!pout.checkError()) - { - len=in.read(buffer,0,bufferSize); - if (len==-1) - break; - out.write(buffer,0,len); - } - } - else - { - while (true) - { - len=in.read(buffer,0,bufferSize); - if (len==-1) - break; - out.write(buffer,0,len); - } - } - } - - /* ------------------------------------------------------------ */ - /** Copy files or directories - * @param from - * @param to - * @throws IOException - */ - public static void copy(File from,File to) throws IOException - { - if (from.isDirectory()) - copyDir(from,to); - else - copyFile(from,to); - } - - /* ------------------------------------------------------------ */ - public static void copyDir(File from,File to) throws IOException - { - if (to.exists()) - { - if (!to.isDirectory()) - throw new IllegalArgumentException(to.toString()); - } - else - to.mkdirs(); - - File[] files = from.listFiles(); - if (files!=null) - { - for (int i=0;i<files.length;i++) - { - String name = files[i].getName(); - if (".".equals(name) || "..".equals(name)) - continue; - copy(files[i],new File(to,name)); - } - } - } - - /* ------------------------------------------------------------ */ - public static void copyFile(File from,File to) throws IOException - { - FileInputStream in=new FileInputStream(from); - FileOutputStream out=new FileOutputStream(to); - copy(in,out); - in.close(); - out.close(); - } - - - /* ------------------------------------------------------------ */ - /** - * closes any {@link Closeable} - * - * @param c the closeable to close - */ - public static void close(Closeable c) - { - try - { - if (c != null) - c.close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - } - - /** - * closes an input stream, and logs exceptions - * - * @param is the input stream to close - */ - public static void close(InputStream is) - { - try - { - if (is != null) - is.close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - } - - /** - * closes a reader, and logs exceptions - * - * @param reader the reader to close - */ - public static void close(Reader reader) - { - try - { - if (reader != null) - reader.close(); - } catch (IOException e) - { - LOG.trace("",e); - } - } - - /** - * closes a writer, and logs exceptions - * - * @param writer the writer to close - */ - public static void close(Writer writer) - { - try - { - if (writer != null) - writer.close(); - } catch (IOException e) - { - LOG.trace("",e); - } - } - - /* ------------------------------------------------------------ */ - /** - * closes an output stream, and logs exceptions - * - * @param os the output stream to close - */ - public static void close(OutputStream os) - { - try - { - if (os != null) - os.close(); - } - catch (IOException e) - { - LOG.trace("",e); - } - } - - /* ------------------------------------------------------------ */ - /** - * @return An outputstream to nowhere - */ - public static InputStream getClosedStream() - { - return __closedStream; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - private static class ClosedIS extends InputStream - { - @Override - public int read() throws IOException - { - return -1; - } - } - private static ClosedIS __closedStream = new ClosedIS(); -}
--- a/src/org/eclipse/jetty/util/LazyList.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,483 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -/* ------------------------------------------------------------ */ -/** Lazy List creation. - * A List helper class that attempts to avoid unnecessary List - * creation. If a method needs to create a List to return, but it is - * expected that this will either be empty or frequently contain a - * single item, then using LazyList will avoid additional object - * creations by using {@link Collections#EMPTY_LIST} or - * {@link Collections#singletonList(Object)} where possible. - * <p> - * LazyList works by passing an opaque representation of the list in - * and out of all the LazyList methods. This opaque object is either - * null for an empty list, an Object for a list with a single entry - * or an {@link ArrayList} for a list of items. - * - * <p><h4>Usage</h4> - * <pre> - * Object lazylist =null; - * while(loopCondition) - * { - * Object item = getItem(); - * if (item.isToBeAdded()) - * lazylist = LazyList.add(lazylist,item); - * } - * return LazyList.getList(lazylist); - * </pre> - * - * An ArrayList of default size is used as the initial LazyList. - * - * @see java.util.List - */ -public class LazyList - implements Cloneable, Serializable -{ - private static final String[] __EMTPY_STRING_ARRAY = new String[0]; - - /* ------------------------------------------------------------ */ - private LazyList() - {} - - /* ------------------------------------------------------------ */ - /** Add an item to a LazyList - * @param list The list to add to or null if none yet created. - * @param item The item to add. - * @return The lazylist created or added to. - */ - @SuppressWarnings("unchecked") - public static Object add(Object list, Object item) - { - if (list==null) - { - if (item instanceof List || item==null) - { - List<Object> l = new ArrayList<Object>(); - l.add(item); - return l; - } - - return item; - } - - if (list instanceof List) - { - ((List<Object>)list).add(item); - return list; - } - - List<Object> l=new ArrayList<Object>(); - l.add(list); - l.add(item); - return l; - } - - /* ------------------------------------------------------------ */ - /** Add an item to a LazyList - * @param list The list to add to or null if none yet created. - * @param index The index to add the item at. - * @param item The item to add. - * @return The lazylist created or added to. - */ - @SuppressWarnings("unchecked") - public static Object add(Object list, int index, Object item) - { - if (list==null) - { - if (index>0 || item instanceof List || item==null) - { - List<Object> l = new ArrayList<Object>(); - l.add(index,item); - return l; - } - return item; - } - - if (list instanceof List) - { - ((List<Object>)list).add(index,item); - return list; - } - - List<Object> l=new ArrayList<Object>(); - l.add(list); - l.add(index,item); - return l; - } - - /* ------------------------------------------------------------ */ - /** Add the contents of a Collection to a LazyList - * @param list The list to add to or null if none yet created. - * @param collection The Collection whose contents should be added. - * @return The lazylist created or added to. - */ - public static Object addCollection(Object list, Collection<?> collection) - { - Iterator<?> i=collection.iterator(); - while(i.hasNext()) - list=LazyList.add(list,i.next()); - return list; - } - - /* ------------------------------------------------------------ */ - /** Add the contents of an array to a LazyList - * @param list The list to add to or null if none yet created. - * @param array The array whose contents should be added. - * @return The lazylist created or added to. - */ - public static Object addArray(Object list, Object[] array) - { - for(int i=0;array!=null && i<array.length;i++) - list=LazyList.add(list,array[i]); - return list; - } - - /* ------------------------------------------------------------ */ - /** Ensure the capacity of the underlying list. - * - */ - public static Object ensureSize(Object list, int initialSize) - { - if (list==null) - return new ArrayList<Object>(initialSize); - if (list instanceof ArrayList) - { - ArrayList<?> ol=(ArrayList<?>)list; - if (ol.size()>initialSize) - return ol; - ArrayList<Object> nl = new ArrayList<Object>(initialSize); - nl.addAll(ol); - return nl; - } - List<Object> l= new ArrayList<Object>(initialSize); - l.add(list); - return l; - } - - /* ------------------------------------------------------------ */ - public static Object remove(Object list, Object o) - { - if (list==null) - return null; - - if (list instanceof List) - { - List<?> l = (List<?>)list; - l.remove(o); - if (l.size()==0) - return null; - return list; - } - - if (list.equals(o)) - return null; - return list; - } - - /* ------------------------------------------------------------ */ - public static Object remove(Object list, int i) - { - if (list==null) - return null; - - if (list instanceof List) - { - List<?> l = (List<?>)list; - l.remove(i); - if (l.size()==0) - return null; - return list; - } - - if (i==0) - return null; - return list; - } - - - - /* ------------------------------------------------------------ */ - /** Get the real List from a LazyList. - * - * @param list A LazyList returned from LazyList.add(Object) - * @return The List of added items, which may be an EMPTY_LIST - * or a SingletonList. - */ - public static<E> List<E> getList(Object list) - { - return getList(list,false); - } - - - /* ------------------------------------------------------------ */ - /** Get the real List from a LazyList. - * - * @param list A LazyList returned from LazyList.add(Object) or null - * @param nullForEmpty If true, null is returned instead of an - * empty list. - * @return The List of added items, which may be null, an EMPTY_LIST - * or a SingletonList. - */ - @SuppressWarnings("unchecked") - public static<E> List<E> getList(Object list, boolean nullForEmpty) - { - if (list==null) - { - if (nullForEmpty) - return null; - return Collections.emptyList(); - } - if (list instanceof List) - return (List<E>)list; - - return (List<E>)Collections.singletonList(list); - } - - - /* ------------------------------------------------------------ */ - public static String[] toStringArray(Object list) - { - if (list==null) - return __EMTPY_STRING_ARRAY; - - if (list instanceof List) - { - List<?> l = (List<?>)list; - String[] a = new String[l.size()]; - for (int i=l.size();i-->0;) - { - Object o=l.get(i); - if (o!=null) - a[i]=o.toString(); - } - return a; - } - - return new String[] {list.toString()}; - } - - /* ------------------------------------------------------------ */ - /** Convert a lazylist to an array - * @param list The list to convert - * @param clazz The class of the array, which may be a primitive type - * @return array of the lazylist entries passed in - */ - public static Object toArray(Object list,Class<?> clazz) - { - if (list==null) - return Array.newInstance(clazz,0); - - if (list instanceof List) - { - List<?> l = (List<?>)list; - if (clazz.isPrimitive()) - { - Object a = Array.newInstance(clazz,l.size()); - for (int i=0;i<l.size();i++) - Array.set(a,i,l.get(i)); - return a; - } - return l.toArray((Object[])Array.newInstance(clazz,l.size())); - - } - - Object a = Array.newInstance(clazz,1); - Array.set(a,0,list); - return a; - } - - /* ------------------------------------------------------------ */ - /** The size of a lazy List - * @param list A LazyList returned from LazyList.add(Object) or null - * @return the size of the list. - */ - public static int size(Object list) - { - if (list==null) - return 0; - if (list instanceof List) - return ((List<?>)list).size(); - return 1; - } - - /* ------------------------------------------------------------ */ - /** Get item from the list - * @param list A LazyList returned from LazyList.add(Object) or null - * @param i int index - * @return the item from the list. - */ - @SuppressWarnings("unchecked") - public static <E> E get(Object list, int i) - { - if (list==null) - throw new IndexOutOfBoundsException(); - - if (list instanceof List) - return (E)((List<?>)list).get(i); - - if (i==0) - return (E)list; - - throw new IndexOutOfBoundsException(); - } - - /* ------------------------------------------------------------ */ - public static boolean contains(Object list,Object item) - { - if (list==null) - return false; - - if (list instanceof List) - return ((List<?>)list).contains(item); - - return list.equals(item); - } - - - /* ------------------------------------------------------------ */ - public static Object clone(Object list) - { - if (list==null) - return null; - if (list instanceof List) - return new ArrayList<Object>((List<?>)list); - return list; - } - - /* ------------------------------------------------------------ */ - public static String toString(Object list) - { - if (list==null) - return "[]"; - if (list instanceof List) - return list.toString(); - return "["+list+"]"; - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings("unchecked") - public static<E> Iterator<E> iterator(Object list) - { - if (list==null) - { - List<E> empty=Collections.emptyList(); - return empty.iterator(); - } - if (list instanceof List) - { - return ((List<E>)list).iterator(); - } - List<E> l=getList(list); - return l.iterator(); - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings("unchecked") - public static<E> ListIterator<E> listIterator(Object list) - { - if (list==null) - { - List<E> empty=Collections.emptyList(); - return empty.listIterator(); - } - if (list instanceof List) - return ((List<E>)list).listIterator(); - - List<E> l=getList(list); - return l.listIterator(); - } - - /* ------------------------------------------------------------ */ - /** - * @param array Any array of object - * @return A new <i>modifiable</i> list initialised with the elements from <code>array</code>. - */ - public static<E> List<E> array2List(E[] array) - { - if (array==null || array.length==0) - return new ArrayList<E>(); - return new ArrayList<E>(Arrays.asList(array)); - } - - /* ------------------------------------------------------------ */ - /** Add element to an array - * @param array The array to add to (or null) - * @param item The item to add - * @param type The type of the array (in case of null array) - * @return new array with contents of array plus item - */ - public static<T> T[] addToArray(T[] array, T item, Class<?> type) - { - if (array==null) - { - if (type==null && item!=null) - type= item.getClass(); - @SuppressWarnings("unchecked") - T[] na = (T[])Array.newInstance(type, 1); - na[0]=item; - return na; - } - else - { - // TODO: Replace with Arrays.copyOf(T[] original, int newLength) from Java 1.6+ - Class<?> c = array.getClass().getComponentType(); - @SuppressWarnings("unchecked") - T[] na = (T[])Array.newInstance(c, Array.getLength(array)+1); - System.arraycopy(array, 0, na, 0, array.length); - na[array.length]=item; - return na; - } - } - - /* ------------------------------------------------------------ */ - public static<T> T[] removeFromArray(T[] array, Object item) - { - if (item==null || array==null) - return array; - for (int i=array.length;i-->0;) - { - if (item.equals(array[i])) - { - Class<?> c = array==null?item.getClass():array.getClass().getComponentType(); - @SuppressWarnings("unchecked") - T[] na = (T[])Array.newInstance(c, Array.getLength(array)-1); - if (i>0) - System.arraycopy(array, 0, na, 0, i); - if (i+1<array.length) - System.arraycopy(array, i+1, na, i, array.length-(i+1)); - return na; - } - } - return array; - } - -} -
--- a/src/org/eclipse/jetty/util/MultiException.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.List; - - -/* ------------------------------------------------------------ */ -/** Wraps multiple exceptions. - * - * Allows multiple exceptions to be thrown as a single exception. - * - * - */ -@SuppressWarnings("serial") -public class MultiException extends Exception -{ - private Object nested; - - /* ------------------------------------------------------------ */ - public MultiException() - { - super("Multiple exceptions"); - } - - /* ------------------------------------------------------------ */ - public void add(Throwable e) - { - if (e instanceof MultiException) - { - MultiException me = (MultiException)e; - for (int i=0;i<LazyList.size(me.nested);i++) - nested=LazyList.add(nested,LazyList.get(me.nested,i)); - } - else - nested=LazyList.add(nested,e); - } - - /* ------------------------------------------------------------ */ - public int size() - { - return LazyList.size(nested); - } - - /* ------------------------------------------------------------ */ - public List<Throwable> getThrowables() - { - return LazyList.getList(nested); - } - - /* ------------------------------------------------------------ */ - public Throwable getThrowable(int i) - { - return (Throwable) LazyList.get(nested,i); - } - - /* ------------------------------------------------------------ */ - /** Throw a multiexception. - * If this multi exception is empty then no action is taken. If it - * contains a single exception that is thrown, otherwise the this - * multi exception is thrown. - * @exception Exception - */ - public void ifExceptionThrow() - throws Exception - { - switch (LazyList.size(nested)) - { - case 0: - break; - case 1: - Throwable th=(Throwable)LazyList.get(nested,0); - if (th instanceof Error) - throw (Error)th; - if (th instanceof Exception) - throw (Exception)th; - default: - throw this; - } - } - - /* ------------------------------------------------------------ */ - /** Throw a Runtime exception. - * If this multi exception is empty then no action is taken. If it - * contains a single error or runtime exception that is thrown, otherwise the this - * multi exception is thrown, wrapped in a runtime exception. - * @exception Error If this exception contains exactly 1 {@link Error} - * @exception RuntimeException If this exception contains 1 {@link Throwable} but it is not an error, - * or it contains more than 1 {@link Throwable} of any type. - */ - public void ifExceptionThrowRuntime() - throws Error - { - switch (LazyList.size(nested)) - { - case 0: - break; - case 1: - Throwable th=(Throwable)LazyList.get(nested,0); - if (th instanceof Error) - throw (Error)th; - else if (th instanceof RuntimeException) - throw (RuntimeException)th; - else - throw new RuntimeException(th); - default: - throw new RuntimeException(this); - } - } - - /* ------------------------------------------------------------ */ - /** Throw a multiexception. - * If this multi exception is empty then no action is taken. If it - * contains a any exceptions then this - * multi exception is thrown. - */ - public void ifExceptionThrowMulti() - throws MultiException - { - if (LazyList.size(nested)>0) - throw this; - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - if (LazyList.size(nested)>0) - return MultiException.class.getSimpleName()+ - LazyList.getList(nested); - return MultiException.class.getSimpleName()+"[]"; - } - - /* ------------------------------------------------------------ */ - @Override - public void printStackTrace() - { - super.printStackTrace(); - for (int i=0;i<LazyList.size(nested);i++) - ((Throwable)LazyList.get(nested,i)).printStackTrace(); - } - - - /* ------------------------------------------------------------------------------- */ - /** - * @see java.lang.Throwable#printStackTrace(java.io.PrintStream) - */ - @Override - public void printStackTrace(PrintStream out) - { - super.printStackTrace(out); - for (int i=0;i<LazyList.size(nested);i++) - ((Throwable)LazyList.get(nested,i)).printStackTrace(out); - } - - /* ------------------------------------------------------------------------------- */ - /** - * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter) - */ - @Override - public void printStackTrace(PrintWriter out) - { - super.printStackTrace(out); - for (int i=0;i<LazyList.size(nested);i++) - ((Throwable)LazyList.get(nested,i)).printStackTrace(out); - } - -}
--- a/src/org/eclipse/jetty/util/MultiMap.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,415 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/* ------------------------------------------------------------ */ -/** A multi valued Map. - * This Map specializes HashMap and provides methods - * that operate on multi valued items. - * <P> - * Implemented as a map of LazyList values - * @param <K> The key type of the map. - * - * @see LazyList - * - */ -public class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable -{ - private static final long serialVersionUID = -6878723138353851005L; - Map<K,Object> _map; - ConcurrentMap<K, Object> _cmap; - - public MultiMap() - { - _map=new HashMap<K, Object>(); - } - - public MultiMap(Map<K,Object> map) - { - if (map instanceof ConcurrentMap) - _map=_cmap=new ConcurrentHashMap<K, Object>(map); - else - _map=new HashMap<K, Object>(map); - } - - public MultiMap(MultiMap<K> map) - { - if (map._cmap!=null) - _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap); - else - _map=new HashMap<K,Object>(map._map); - } - - public MultiMap(int capacity) - { - _map=new HashMap<K, Object>(capacity); - } - - public MultiMap(boolean concurrent) - { - if (concurrent) - _map=_cmap=new ConcurrentHashMap<K, Object>(); - else - _map=new HashMap<K, Object>(); - } - - - /* ------------------------------------------------------------ */ - /** Get multiple values. - * Single valued entries are converted to singleton lists. - * @param name The entry key. - * @return Unmodifieable List of values. - */ - public List getValues(Object name) - { - return LazyList.getList(_map.get(name),true); - } - - /* ------------------------------------------------------------ */ - /** Get a value from a multiple value. - * If the value is not a multivalue, then index 0 retrieves the - * value or null. - * @param name The entry key. - * @param i Index of element to get. - * @return Unmodifieable List of values. - */ - public Object getValue(Object name,int i) - { - Object l=_map.get(name); - if (i==0 && LazyList.size(l)==0) - return null; - return LazyList.get(l,i); - } - - - /* ------------------------------------------------------------ */ - /** Get value as String. - * Single valued items are converted to a String with the toString() - * Object method. Multi valued entries are converted to a comma separated - * List. No quoting of commas within values is performed. - * @param name The entry key. - * @return String value. - */ - public String getString(Object name) - { - Object l=_map.get(name); - switch(LazyList.size(l)) - { - case 0: - return null; - case 1: - Object o=LazyList.get(l,0); - return o==null?null:o.toString(); - default: - { - StringBuilder values=new StringBuilder(128); - for (int i=0; i<LazyList.size(l); i++) - { - Object e=LazyList.get(l,i); - if (e!=null) - { - if (values.length()>0) - values.append(','); - values.append(e.toString()); - } - } - return values.toString(); - } - } - } - - /* ------------------------------------------------------------ */ - public Object get(Object name) - { - Object l=_map.get(name); - switch(LazyList.size(l)) - { - case 0: - return null; - case 1: - Object o=LazyList.get(l,0); - return o; - default: - return LazyList.getList(l,true); - } - } - - /* ------------------------------------------------------------ */ - /** Put and entry into the map. - * @param name The entry key. - * @param value The entry value. - * @return The previous value or null. - */ - public Object put(K name, Object value) - { - return _map.put(name,LazyList.add(null,value)); - } - - /* ------------------------------------------------------------ */ - /** Put multi valued entry. - * @param name The entry key. - * @param values The List of multiple values. - * @return The previous value or null. - */ - public Object putValues(K name, List<? extends Object> values) - { - return _map.put(name,values); - } - - /* ------------------------------------------------------------ */ - /** Put multi valued entry. - * @param name The entry key. - * @param values The String array of multiple values. - * @return The previous value or null. - */ - public Object putValues(K name, String... values) - { - Object list=null; - for (int i=0;i<values.length;i++) - list=LazyList.add(list,values[i]); - return _map.put(name,list); - } - - - /* ------------------------------------------------------------ */ - /** Add value to multi valued entry. - * If the entry is single valued, it is converted to the first - * value of a multi valued entry. - * @param name The entry key. - * @param value The entry value. - */ - public void add(K name, Object value) - { - Object lo = _map.get(name); - Object ln = LazyList.add(lo,value); - if (lo!=ln) - _map.put(name,ln); - } - - /* ------------------------------------------------------------ */ - /** Add values to multi valued entry. - * If the entry is single valued, it is converted to the first - * value of a multi valued entry. - * @param name The entry key. - * @param values The List of multiple values. - */ - public void addValues(K name, List<? extends Object> values) - { - Object lo = _map.get(name); - Object ln = LazyList.addCollection(lo,values); - if (lo!=ln) - _map.put(name,ln); - } - - /* ------------------------------------------------------------ */ - /** Add values to multi valued entry. - * If the entry is single valued, it is converted to the first - * value of a multi valued entry. - * @param name The entry key. - * @param values The String array of multiple values. - */ - public void addValues(K name, String[] values) - { - Object lo = _map.get(name); - Object ln = LazyList.addCollection(lo,Arrays.asList(values)); - if (lo!=ln) - _map.put(name,ln); - } - - /* ------------------------------------------------------------ */ - /** Remove value. - * @param name The entry key. - * @param value The entry value. - * @return true if it was removed. - */ - public boolean removeValue(K name,Object value) - { - Object lo = _map.get(name); - Object ln=lo; - int s=LazyList.size(lo); - if (s>0) - { - ln=LazyList.remove(lo,value); - if (ln==null) - _map.remove(name); - else - _map.put(name, ln); - } - return LazyList.size(ln)!=s; - } - - - /* ------------------------------------------------------------ */ - /** Put all contents of map. - * @param m Map - */ - public void putAll(Map<? extends K, ? extends Object> m) - { - boolean multi = (m instanceof MultiMap); - - if (multi) - { - for (Map.Entry<? extends K, ? extends Object> entry : m.entrySet()) - { - _map.put(entry.getKey(),LazyList.clone(entry.getValue())); - } - } - else - { - _map.putAll(m); - } - } - - /* ------------------------------------------------------------ */ - /** - * @return Map of String arrays - */ - public Map<K,String[]> toStringArrayMap() - { - HashMap<K,String[]> map = new HashMap<K,String[]>(_map.size()*3/2) - { - public String toString() - { - StringBuilder b=new StringBuilder(); - b.append('{'); - for (K k:keySet()) - { - if(b.length()>1) - b.append(','); - b.append(k); - b.append('='); - b.append(Arrays.asList(get(k))); - } - - b.append('}'); - return b.toString(); - } - }; - - for(Map.Entry<K,Object> entry: _map.entrySet()) - { - String[] a = LazyList.toStringArray(entry.getValue()); - map.put(entry.getKey(),a); - } - return map; - } - - @Override - public String toString() - { - return _cmap==null?_map.toString():_cmap.toString(); - } - - public void clear() - { - _map.clear(); - } - - public boolean containsKey(Object key) - { - return _map.containsKey(key); - } - - public boolean containsValue(Object value) - { - return _map.containsValue(value); - } - - public Set<Entry<K, Object>> entrySet() - { - return _map.entrySet(); - } - - @Override - public boolean equals(Object o) - { - return _map.equals(o); - } - - @Override - public int hashCode() - { - return _map.hashCode(); - } - - public boolean isEmpty() - { - return _map.isEmpty(); - } - - public Set<K> keySet() - { - return _map.keySet(); - } - - public Object remove(Object key) - { - return _map.remove(key); - } - - public int size() - { - return _map.size(); - } - - public Collection<Object> values() - { - return _map.values(); - } - - - - public Object putIfAbsent(K key, Object value) - { - if (_cmap==null) - throw new UnsupportedOperationException(); - return _cmap.putIfAbsent(key,value); - } - - public boolean remove(Object key, Object value) - { - if (_cmap==null) - throw new UnsupportedOperationException(); - return _cmap.remove(key,value); - } - - public boolean replace(K key, Object oldValue, Object newValue) - { - if (_cmap==null) - throw new UnsupportedOperationException(); - return _cmap.replace(key,oldValue,newValue); - } - - public Object replace(K key, Object value) - { - if (_cmap==null) - throw new UnsupportedOperationException(); - return _cmap.replace(key,value); - } -}
--- a/src/org/eclipse/jetty/util/MultiPartInputStream.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,719 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.Base64; - -import javax.servlet.ServletException; -import javax.servlet.http.Part; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - - -/** - * MultiPartInputStream - * - * Handle a MultiPart Mime input stream, breaking it up on the boundary into files and strings. - */ -public class MultiPartInputStream -{ - private static final Logger LOG = LoggerFactory.getLogger(MultiPartInputStream.class); - - protected InputStream _in; - protected String _contentType; - protected MultiMap<String> _parts; - - - - public final class MultiPart implements Part - { - protected String _name; - protected String _filename; - protected File _file; - protected OutputStream _out; - protected ByteArrayOutputStream2 _bout; - protected String _contentType; - protected MultiMap<String> _headers; - protected long _size = 0; - - public MultiPart (String name, String filename) - throws IOException - { - _name = name; - _filename = filename; - } - - protected void setContentType (String contentType) - { - _contentType = contentType; - } - - - protected void open() - throws IOException - { - //We will either be writing to a file, if it has a filename on the content-disposition - //and otherwise a byte-array-input-stream, OR if we exceed the getFileSizeThreshold, we - //will need to change to write to a file. - if (_filename != null && _filename.trim().length() > 0) - { - createFile(); - } - else - { - //Write to a buffer in memory until we discover we've exceed the - //MultipartConfig fileSizeThreshold - _out = _bout= new ByteArrayOutputStream2(); - } - } - - protected void close() - throws IOException - { - _out.close(); - } - - - protected void write (int b) - throws IOException - { - _out.write(b); - _size ++; - } - - protected void write (byte[] bytes, int offset, int length) - throws IOException - { - _out.write(bytes, offset, length); - _size += length; - } - - protected void createFile () - throws IOException - { - _file = File.createTempFile("MultiPart", null); - _file.deleteOnExit(); - FileOutputStream fos = new FileOutputStream(_file); - BufferedOutputStream bos = new BufferedOutputStream(fos); - - if (_size > 0 && _out != null) - { - //already written some bytes, so need to copy them into the file - _out.flush(); - _bout.writeTo(bos); - _out.close(); - _bout = null; - } - _out = bos; - } - - - - protected void setHeaders(MultiMap<String> headers) - { - _headers = headers; - } - - /** - * @see javax.servlet.http.Part#getContentType() - */ - public String getContentType() - { - return _contentType; - } - - /** - * @see javax.servlet.http.Part#getHeader(java.lang.String) - */ - public String getHeader(String name) - { - if (name == null) - return null; - return (String)_headers.getValue(name.toLowerCase(Locale.ENGLISH), 0); - } - - /** - * @see javax.servlet.http.Part#getHeaderNames() - */ - public Collection<String> getHeaderNames() - { - return _headers.keySet(); - } - - /** - * @see javax.servlet.http.Part#getHeaders(java.lang.String) - */ - public Collection<String> getHeaders(String name) - { - return _headers.getValues(name); - } - - /** - * @see javax.servlet.http.Part#getInputStream() - */ - public InputStream getInputStream() throws IOException - { - if (_file != null) - { - //written to a file, whether temporary or not - return new BufferedInputStream (new FileInputStream(_file)); - } - else - { - //part content is in memory - return new ByteArrayInputStream(_bout.getBuf(),0,_bout.size()); - } - } - - public byte[] getBytes() - { - if (_bout!=null) - return _bout.toByteArray(); - return null; - } - - /** - * @see javax.servlet.http.Part#getName() - */ - public String getName() - { - return _name; - } - - /** - * @see javax.servlet.http.Part#getSize() - */ - public long getSize() - { - return _size; - } - - /** - * @see javax.servlet.http.Part#write(java.lang.String) - */ - public void write(String fileName) throws IOException - { - throw new UnsupportedOperationException(); - } - - /** - * Remove the file, whether or not Part.write() was called on it - * (ie no longer temporary) - * @see javax.servlet.http.Part#delete() - */ - public void delete() throws IOException - { - if (_file != null && _file.exists()) - _file.delete(); - } - - /** - * Only remove tmp files. - * - * @throws IOException - */ - public void cleanUp() throws IOException - { - if (_file != null && _file.exists()) - _file.delete(); - } - - - /** - * Get the file, if any, the data has been written to. - * @return - */ - public File getFile () - { - return _file; - } - - - /** - * Get the filename from the content-disposition. - * @return null or the filename - */ - public String getContentDispositionFilename () - { - return _filename; - } - } - - - - - /** - * @param in Request input stream - * @param contentType Content-Type header - * @param config MultipartConfigElement - * @param contextTmpDir javax.servlet.context.tempdir - */ - public MultiPartInputStream (InputStream in, String contentType) - { - _in = new ReadLineInputStream(in); - _contentType = contentType; - } - - /** - * Get the already parsed parts. - * - * @return - */ - public Collection<Part> getParsedParts() - { - if (_parts == null) - return Collections.emptyList(); - - Collection<Object> values = _parts.values(); - List<Part> parts = new ArrayList<Part>(); - for (Object o: values) - { - List<Part> asList = LazyList.getList(o, false); - parts.addAll(asList); - } - return parts; - } - - /** - * Delete any tmp storage for parts, and clear out the parts list. - * - * @throws MultiException - */ - public void deleteParts () - throws MultiException - { - Collection<Part> parts = getParsedParts(); - MultiException err = new MultiException(); - for (Part p:parts) - { - try - { - ((MultiPartInputStream.MultiPart)p).cleanUp(); - } - catch(Exception e) - { - err.add(e); - } - } - _parts.clear(); - - err.ifExceptionThrowMulti(); - } - - - /** - * Parse, if necessary, the multipart data and return the list of Parts. - * - * @return - * @throws IOException - * @throws ServletException - */ - public Collection<Part> getParts() - throws IOException, ServletException - { - parse(); - Collection<Object> values = _parts.values(); - List<Part> parts = new ArrayList<Part>(); - for (Object o: values) - { - List<Part> asList = LazyList.getList(o, false); - parts.addAll(asList); - } - return parts; - } - - - /** - * Get the named Part. - * - * @param name - * @return - * @throws IOException - * @throws ServletException - */ - public Part getPart(String name) - throws IOException, ServletException - { - parse(); - return (Part)_parts.getValue(name, 0); - } - - - /** - * Parse, if necessary, the multipart stream. - * - * @throws IOException - * @throws ServletException - */ - protected void parse () - throws IOException, ServletException - { - //have we already parsed the input? - if (_parts != null) - return; - - //initialize - long total = 0; //keep running total of size of bytes read from input and throw an exception if exceeds MultipartConfigElement._maxRequestSize - _parts = new MultiMap<String>(); - - //if its not a multipart request, don't parse it - if (_contentType == null || !_contentType.startsWith("multipart/form-data")) - return; - - String contentTypeBoundary = ""; - int bstart = _contentType.indexOf("boundary="); - if (bstart >= 0) - { - int bend = _contentType.indexOf(";", bstart); - bend = (bend < 0? _contentType.length(): bend); - contentTypeBoundary = QuotedStringTokenizer.unquote(value(_contentType.substring(bstart,bend), true).trim()); - } - - String boundary="--"+contentTypeBoundary; - byte[] byteBoundary=(boundary+"--").getBytes(StringUtil.__ISO_8859_1); - - // Get first boundary - String line = null; - try - { - line=((ReadLineInputStream)_in).readLine(); - } - catch (IOException e) - { - LOG.warn("Badly formatted multipart request"); - throw e; - } - - if (line == null) - throw new IOException("Missing content for multipart request"); - - boolean badFormatLogged = false; - line=line.trim(); - while (line != null && !line.equals(boundary)) - { - if (!badFormatLogged) - { - LOG.warn("Badly formatted multipart request"); - badFormatLogged = true; - } - line=((ReadLineInputStream)_in).readLine(); - line=(line==null?line:line.trim()); - } - - if (line == null) - throw new IOException("Missing initial multi part boundary"); - - // Read each part - boolean lastPart=false; - - outer:while(!lastPart) - { - String contentDisposition=null; - String contentType=null; - String contentTransferEncoding=null; - - MultiMap<String> headers = new MultiMap<String>(); - while(true) - { - line=((ReadLineInputStream)_in).readLine(); - - //No more input - if(line==null) - break outer; - - // If blank line, end of part headers - if("".equals(line)) - break; - - total += line.length(); - - //get content-disposition and content-type - int c=line.indexOf(':',0); - if(c>0) - { - String key=line.substring(0,c).trim().toLowerCase(Locale.ENGLISH); - String value=line.substring(c+1,line.length()).trim(); - headers.put(key, value); - if (key.equalsIgnoreCase("content-disposition")) - contentDisposition=value; - if (key.equalsIgnoreCase("content-type")) - contentType = value; - if(key.equals("content-transfer-encoding")) - contentTransferEncoding=value; - - } - } - - // Extract content-disposition - boolean form_data=false; - if(contentDisposition==null) - { - throw new IOException("Missing content-disposition"); - } - - QuotedStringTokenizer tok=new QuotedStringTokenizer(contentDisposition,";", false, true); - String name=null; - String filename=null; - while(tok.hasMoreTokens()) - { - String t=tok.nextToken().trim(); - String tl=t.toLowerCase(Locale.ENGLISH); - if(t.startsWith("form-data")) - form_data=true; - else if(tl.startsWith("name=")) - name=value(t, true); - else if(tl.startsWith("filename=")) - filename=filenameValue(t); - } - - // Check disposition - if(!form_data) - { - continue; - } - //It is valid for reset and submit buttons to have an empty name. - //If no name is supplied, the browser skips sending the info for that field. - //However, if you supply the empty string as the name, the browser sends the - //field, with name as the empty string. So, only continue this loop if we - //have not yet seen a name field. - if(name==null) - { - continue; - } - - //Have a new Part - MultiPart part = new MultiPart(name, filename); - part.setHeaders(headers); - part.setContentType(contentType); - _parts.add(name, part); - part.open(); - - InputStream partInput = null; - if ("base64".equalsIgnoreCase(contentTransferEncoding)) - { - partInput = Base64.getDecoder().wrap(_in); - } - else if ("quoted-printable".equalsIgnoreCase(contentTransferEncoding)) - { - partInput = new FilterInputStream(_in) - { - @Override - public int read() throws IOException - { - int c = in.read(); - if (c >= 0 && c == '=') - { - int hi = in.read(); - int lo = in.read(); - if (hi < 0 || lo < 0) - { - throw new IOException("Unexpected end to quoted-printable byte"); - } - char[] chars = new char[] { (char)hi, (char)lo }; - c = Integer.parseInt(new String(chars),16); - } - return c; - } - }; - } - else - partInput = _in; - - try - { - int state=-2; - int c; - boolean cr=false; - boolean lf=false; - - // loop for all lines - while(true) - { - int b=0; - while((c=(state!=-2)?state:partInput.read())!=-1) - { - total ++; - - state=-2; - - // look for CR and/or LF - if(c==13||c==10) - { - if(c==13) - { - partInput.mark(1); - int tmp=partInput.read(); - if (tmp!=10) - partInput.reset(); - else - state=tmp; - } - break; - } - - // Look for boundary - if(b>=0&&b<byteBoundary.length&&c==byteBoundary[b]) - { - b++; - } - else - { - // Got a character not part of the boundary, so we don't have the boundary marker. - // Write out as many chars as we matched, then the char we're looking at. - if(cr) - part.write(13); - - if(lf) - part.write(10); - - cr=lf=false; - if(b>0) - part.write(byteBoundary,0,b); - - b=-1; - part.write(c); - } - } - - // Check for incomplete boundary match, writing out the chars we matched along the way - if((b>0&&b<byteBoundary.length-2)||(b==byteBoundary.length-1)) - { - if(cr) - part.write(13); - - if(lf) - part.write(10); - - cr=lf=false; - part.write(byteBoundary,0,b); - b=-1; - } - - // Boundary match. If we've run out of input or we matched the entire final boundary marker, then this is the last part. - if(b>0||c==-1) - { - - if(b==byteBoundary.length) - lastPart=true; - if(state==10) - state=-2; - break; - } - - // handle CR LF - if(cr) - part.write(13); - - if(lf) - part.write(10); - - cr=(c==13); - lf=(c==10||state==10); - if(state==10) - state=-2; - } - } - finally - { - part.close(); - } - } - if (!lastPart) - throw new IOException("Incomplete parts"); - } - - - /* ------------------------------------------------------------ */ - private String value(String nameEqualsValue, boolean splitAfterSpace) - { - /* - String value=nameEqualsValue.substring(nameEqualsValue.indexOf('=')+1).trim(); - int i=value.indexOf(';'); - if(i>0) - value=value.substring(0,i); - if(value.startsWith("\"")) - { - value=value.substring(1,value.indexOf('"',1)); - } - else if (splitAfterSpace) - { - i=value.indexOf(' '); - if(i>0) - value=value.substring(0,i); - } - return value; - */ - int idx = nameEqualsValue.indexOf('='); - String value = nameEqualsValue.substring(idx+1).trim(); - return QuotedStringTokenizer.unquoteOnly(value); - } - - - /* ------------------------------------------------------------ */ - private String filenameValue(String nameEqualsValue) - { - int idx = nameEqualsValue.indexOf('='); - String value = nameEqualsValue.substring(idx+1).trim(); - - if (value.matches(".??[a-z,A-Z]\\:\\\\[^\\\\].*")) - { - //incorrectly escaped IE filenames that have the whole path - //we just strip any leading & trailing quotes and leave it as is - char first=value.charAt(0); - if (first=='"' || first=='\'') - value=value.substring(1); - char last=value.charAt(value.length()-1); - if (last=='"' || last=='\'') - value = value.substring(0,value.length()-1); - - return value; - } - else - //unquote the string, but allow any backslashes that don't - //form a valid escape sequence to remain as many browsers - //even on *nix systems will not escape a filename containing - //backslashes - return QuotedStringTokenizer.unquoteOnly(value, true); - } -}
--- a/src/org/eclipse/jetty/util/MultiPartOutputStream.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - - -/* ================================================================ */ -/** Handle a multipart MIME response. - * - * - * -*/ -public class MultiPartOutputStream extends FilterOutputStream -{ - /* ------------------------------------------------------------ */ - private static final byte[] __CRLF={'\r','\n'}; - private static final byte[] __DASHDASH={'-','-'}; - - public static String MULTIPART_MIXED="multipart/mixed"; - public static String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace"; - - /* ------------------------------------------------------------ */ - private String boundary; - private byte[] boundaryBytes; - - /* ------------------------------------------------------------ */ - private boolean inPart=false; - - /* ------------------------------------------------------------ */ - public MultiPartOutputStream(OutputStream out) - throws IOException - { - super(out); - - boundary = "jetty"+System.identityHashCode(this)+ - Long.toString(System.currentTimeMillis(),36); - boundaryBytes=boundary.getBytes(StringUtil.__ISO_8859_1); - - inPart=false; - } - - - - /* ------------------------------------------------------------ */ - /** End the current part. - * @exception IOException IOException - */ - @Override - public void close() - throws IOException - { - if (inPart) - out.write(__CRLF); - out.write(__DASHDASH); - out.write(boundaryBytes); - out.write(__DASHDASH); - out.write(__CRLF); - inPart=false; - super.close(); - } - - /* ------------------------------------------------------------ */ - public String getBoundary() - { - return boundary; - } - - public OutputStream getOut() {return out;} - - /* ------------------------------------------------------------ */ - /** Start creation of the next Content. - */ - public void startPart(String contentType) - throws IOException - { - if (inPart) - out.write(__CRLF); - inPart=true; - out.write(__DASHDASH); - out.write(boundaryBytes); - out.write(__CRLF); - if (contentType != null) - out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1)); - out.write(__CRLF); - out.write(__CRLF); - } - - /* ------------------------------------------------------------ */ - /** Start creation of the next Content. - */ - public void startPart(String contentType, String[] headers) - throws IOException - { - if (inPart) - out.write(__CRLF); - inPart=true; - out.write(__DASHDASH); - out.write(boundaryBytes); - out.write(__CRLF); - if (contentType != null) - out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1)); - out.write(__CRLF); - for (int i=0;headers!=null && i<headers.length;i++) - { - out.write(headers[i].getBytes(StringUtil.__ISO_8859_1)); - out.write(__CRLF); - } - out.write(__CRLF); - } - - /* ------------------------------------------------------------ */ - @Override - public void write(byte[] b, int off, int len) throws IOException - { - out.write(b,off,len); - } -} - - - -
--- a/src/org/eclipse/jetty/util/MultiPartWriter.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.FilterWriter; -import java.io.IOException; -import java.io.Writer; - - -/* ================================================================ */ -/** Handle a multipart MIME response. - * - * - * -*/ -public class MultiPartWriter extends FilterWriter -{ - /* ------------------------------------------------------------ */ - private final static String __CRLF="\015\012"; - private final static String __DASHDASH="--"; - - public static String MULTIPART_MIXED=MultiPartOutputStream.MULTIPART_MIXED; - public static String MULTIPART_X_MIXED_REPLACE=MultiPartOutputStream.MULTIPART_X_MIXED_REPLACE; - - /* ------------------------------------------------------------ */ - private String boundary; - - /* ------------------------------------------------------------ */ - private boolean inPart=false; - - /* ------------------------------------------------------------ */ - public MultiPartWriter(Writer out) - throws IOException - { - super(out); - boundary = "jetty"+System.identityHashCode(this)+ - Long.toString(System.currentTimeMillis(),36); - - inPart=false; - } - - /* ------------------------------------------------------------ */ - /** End the current part. - * @exception IOException IOException - */ - @Override - public void close() - throws IOException - { - if (inPart) - out.write(__CRLF); - out.write(__DASHDASH); - out.write(boundary); - out.write(__DASHDASH); - out.write(__CRLF); - inPart=false; - super.close(); - } - - /* ------------------------------------------------------------ */ - public String getBoundary() - { - return boundary; - } - - /* ------------------------------------------------------------ */ - /** Start creation of the next Content. - */ - public void startPart(String contentType) - throws IOException - { - if (inPart) - out.write(__CRLF); - out.write(__DASHDASH); - out.write(boundary); - out.write(__CRLF); - out.write("Content-Type: "); - out.write(contentType); - out.write(__CRLF); - out.write(__CRLF); - inPart=true; - } - - /* ------------------------------------------------------------ */ - /** end creation of the next Content. - */ - public void endPart() - throws IOException - { - if (inPart) - out.write(__CRLF); - inPart=false; - } - - /* ------------------------------------------------------------ */ - /** Start creation of the next Content. - */ - public void startPart(String contentType, String[] headers) - throws IOException - { - if (inPart) - out.write(__CRLF); - out.write(__DASHDASH); - out.write(boundary); - out.write(__CRLF); - out.write("Content-Type: "); - out.write(contentType); - out.write(__CRLF); - for (int i=0;headers!=null && i<headers.length;i++) - { - out.write(headers[i]); - out.write(__CRLF); - } - out.write(__CRLF); - inPart=true; - } - -} - - - -
--- a/src/org/eclipse/jetty/util/QuotedStringTokenizer.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,603 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.IOException; -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; - -/* ------------------------------------------------------------ */ -/** StringTokenizer with Quoting support. - * - * This class is a copy of the java.util.StringTokenizer API and - * the behaviour is the same, except that single and double quoted - * string values are recognised. - * Delimiters within quotes are not considered delimiters. - * Quotes can be escaped with '\'. - * - * @see java.util.StringTokenizer - * - */ -public class QuotedStringTokenizer - extends StringTokenizer -{ - private final static String __delim="\t\n\r"; - private String _string; - private String _delim = __delim; - private boolean _returnQuotes=false; - private boolean _returnDelimiters=false; - private StringBuffer _token; - private boolean _hasToken=false; - private int _i=0; - private int _lastStart=0; - private boolean _double=true; - private boolean _single=true; - - /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str, - String delim, - boolean returnDelimiters, - boolean returnQuotes) - { - super(""); - _string=str; - if (delim!=null) - _delim=delim; - _returnDelimiters=returnDelimiters; - _returnQuotes=returnQuotes; - - if (_delim.indexOf('\'')>=0 || - _delim.indexOf('"')>=0) - throw new Error("Can't use quotes as delimiters: "+_delim); - - _token=new StringBuffer(_string.length()>1024?512:_string.length()/2); - } - - /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str, - String delim, - boolean returnDelimiters) - { - this(str,delim,returnDelimiters,false); - } - - /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str, - String delim) - { - this(str,delim,false,false); - } - - /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str) - { - this(str,null,false,false); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean hasMoreTokens() - { - // Already found a token - if (_hasToken) - return true; - - _lastStart=_i; - - int state=0; - boolean escape=false; - while (_i<_string.length()) - { - char c=_string.charAt(_i++); - - switch (state) - { - case 0: // Start - if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - { - _token.append(c); - return _hasToken=true; - } - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else - { - _token.append(c); - _hasToken=true; - state=1; - } - break; - - case 1: // Token - _hasToken=true; - if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - _i--; - return _hasToken; - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else - { - _token.append(c); - } - break; - - case 2: // Single Quote - _hasToken=true; - if (escape) - { - escape=false; - _token.append(c); - } - else if (c=='\'') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - { - _token.append(c); - } - break; - - case 3: // Double Quote - _hasToken=true; - if (escape) - { - escape=false; - _token.append(c); - } - else if (c=='\"') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - { - _token.append(c); - } - break; - } - } - - return _hasToken; - } - - /* ------------------------------------------------------------ */ - @Override - public String nextToken() - throws NoSuchElementException - { - if (!hasMoreTokens() || _token==null) - throw new NoSuchElementException(); - String t=_token.toString(); - _token.setLength(0); - _hasToken=false; - return t; - } - - /* ------------------------------------------------------------ */ - @Override - public String nextToken(String delim) - throws NoSuchElementException - { - _delim=delim; - _i=_lastStart; - _token.setLength(0); - _hasToken=false; - return nextToken(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean hasMoreElements() - { - return hasMoreTokens(); - } - - /* ------------------------------------------------------------ */ - @Override - public Object nextElement() - throws NoSuchElementException - { - return nextToken(); - } - - /* ------------------------------------------------------------ */ - /** Not implemented. - */ - @Override - public int countTokens() - { - return -1; - } - - - /* ------------------------------------------------------------ */ - /** Quote a string. - * The string is quoted only if quoting is required due to - * embedded delimiters, quote characters or the - * empty string. - * @param s The string to quote. - * @param delim the delimiter to use to quote the string - * @return quoted string - */ - public static String quoteIfNeeded(String s, String delim) - { - if (s==null) - return null; - if (s.length()==0) - return "\"\""; - - - for (int i=0;i<s.length();i++) - { - char c = s.charAt(i); - if (c=='\\' || c=='"' || c=='\'' || Character.isWhitespace(c) || delim.indexOf(c)>=0) - { - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); - return b.toString(); - } - } - - return s; - } - - /* ------------------------------------------------------------ */ - /** Quote a string. - * The string is quoted only if quoting is required due to - * embeded delimiters, quote characters or the - * empty string. - * @param s The string to quote. - * @return quoted string - */ - public static String quote(String s) - { - if (s==null) - return null; - if (s.length()==0) - return "\"\""; - - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); - return b.toString(); - - } - - private static final char[] escapes = new char[32]; - static - { - Arrays.fill(escapes, (char)0xFFFF); - escapes['\b'] = 'b'; - escapes['\t'] = 't'; - escapes['\n'] = 'n'; - escapes['\f'] = 'f'; - escapes['\r'] = 'r'; - } - - /* ------------------------------------------------------------ */ - /** Quote a string into an Appendable. - * The characters ", \, \n, \r, \t, \f and \b are escaped - * @param buffer The Appendable - * @param input The String to quote. - */ - public static void quote(Appendable buffer, String input) - { - try - { - buffer.append('"'); - for (int i = 0; i < input.length(); ++i) - { - char c = input.charAt(i); - if (c >= 32) - { - if (c == '"' || c == '\\') - buffer.append('\\'); - buffer.append(c); - } - else - { - char escape = escapes[c]; - if (escape == 0xFFFF) - { - // Unicode escape - buffer.append('\\').append('u').append('0').append('0'); - if (c < 0x10) - buffer.append('0'); - buffer.append(Integer.toString(c, 16)); - } - else - { - buffer.append('\\').append(escape); - } - } - } - buffer.append('"'); - } - catch (IOException x) - { - throw new RuntimeException(x); - } - } - - /* ------------------------------------------------------------ */ - /** Quote a string into a StringBuffer only if needed. - * Quotes are forced if any delim characters are present. - * - * @param buf The StringBuffer - * @param s The String to quote. - * @param delim String of characters that must be quoted. - * @return true if quoted; - */ - public static boolean quoteIfNeeded(Appendable buf, String s,String delim) - { - for (int i=0;i<s.length();i++) - { - char c = s.charAt(i); - if (delim.indexOf(c)>=0) - { - quote(buf,s); - return true; - } - } - - try - { - buf.append(s); - return false; - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } - - - /* ------------------------------------------------------------ */ - public static String unquoteOnly(String s) - { - return unquoteOnly(s, false); - } - - - /* ------------------------------------------------------------ */ - /** Unquote a string, NOT converting unicode sequences - * @param s The string to unquote. - * @param lenient if true, will leave in backslashes that aren't valid escapes - * @return quoted string - */ - public static String unquoteOnly(String s, boolean lenient) - { - if (s==null) - return null; - if (s.length()<2) - return s; - - char first=s.charAt(0); - char last=s.charAt(s.length()-1); - if (first!=last || (first!='"' && first!='\'')) - return s; - - StringBuilder b = new StringBuilder(s.length() - 2); - boolean escape=false; - for (int i=1;i<s.length()-1;i++) - { - char c = s.charAt(i); - - if (escape) - { - escape=false; - if (lenient && !isValidEscaping(c)) - { - b.append('\\'); - } - b.append(c); - } - else if (c=='\\') - { - escape=true; - } - else - { - b.append(c); - } - } - - return b.toString(); - } - - /* ------------------------------------------------------------ */ - public static String unquote(String s) - { - return unquote(s,false); - } - - /* ------------------------------------------------------------ */ - /** Unquote a string. - * @param s The string to unquote. - * @return quoted string - */ - public static String unquote(String s, boolean lenient) - { - if (s==null) - return null; - if (s.length()<2) - return s; - - char first=s.charAt(0); - char last=s.charAt(s.length()-1); - if (first!=last || (first!='"' && first!='\'')) - return s; - - StringBuilder b = new StringBuilder(s.length() - 2); - boolean escape=false; - for (int i=1;i<s.length()-1;i++) - { - char c = s.charAt(i); - - if (escape) - { - escape=false; - switch (c) - { - case 'n': - b.append('\n'); - break; - case 'r': - b.append('\r'); - break; - case 't': - b.append('\t'); - break; - case 'f': - b.append('\f'); - break; - case 'b': - b.append('\b'); - break; - case '\\': - b.append('\\'); - break; - case '/': - b.append('/'); - break; - case '"': - b.append('"'); - break; - case 'u': - b.append((char)( - (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<24)+ - (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<16)+ - (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<8)+ - (TypeUtil.convertHexDigit((byte)s.charAt(i++))) - ) - ); - break; - default: - if (lenient && !isValidEscaping(c)) - { - b.append('\\'); - } - b.append(c); - } - } - else if (c=='\\') - { - escape=true; - } - else - { - b.append(c); - } - } - - return b.toString(); - } - - - /* ------------------------------------------------------------ */ - /** Check that char c (which is preceded by a backslash) is a valid - * escape sequence. - * @param c - * @return - */ - private static boolean isValidEscaping(char c) - { - return ((c == 'n') || (c == 'r') || (c == 't') || - (c == 'f') || (c == 'b') || (c == '\\') || - (c == '/') || (c == '"') || (c == 'u')); - } - - /* ------------------------------------------------------------ */ - /** - * @return handle double quotes if true - */ - public boolean getDouble() - { - return _double; - } - - /* ------------------------------------------------------------ */ - /** - * @param d handle double quotes if true - */ - public void setDouble(boolean d) - { - _double=d; - } - - /* ------------------------------------------------------------ */ - /** - * @return handle single quotes if true - */ - public boolean getSingle() - { - return _single; - } - - /* ------------------------------------------------------------ */ - /** - * @param single handle single quotes if true - */ - public void setSingle(boolean single) - { - _single=single; - } -}
--- a/src/org/eclipse/jetty/util/ReadLineInputStream.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * ReadLineInputStream - * - * Read from an input stream, accepting CR/LF, LF or just CR. - */ -public class ReadLineInputStream extends BufferedInputStream -{ - boolean _seenCRLF; - boolean _skipLF; - - public ReadLineInputStream(InputStream in) - { - super(in); - } - - public ReadLineInputStream(InputStream in, int size) - { - super(in,size); - } - - public String readLine() throws IOException - { - mark(buf.length); - - while (true) - { - int b=super.read(); - - if (markpos < 0) - throw new IOException("Buffer size exceeded: no line terminator"); - - if (b==-1) - { - int m=markpos; - markpos=-1; - if (pos>m) - return new String(buf,m,pos-m,StringUtil.__UTF8_CHARSET); - - return null; - } - - if (b=='\r') - { - int p=pos; - - // if we have seen CRLF before, hungrily consume LF - if (_seenCRLF && pos<count) - { - if (buf[pos]=='\n') - pos+=1; - } - else - _skipLF=true; - int m=markpos; - markpos=-1; - return new String(buf,m,p-m-1,StringUtil.__UTF8_CHARSET); - } - - if (b=='\n') - { - if (_skipLF) - { - _skipLF=false; - _seenCRLF=true; - markpos++; - continue; - } - int m=markpos; - markpos=-1; - return new String(buf,m,pos-m-1,StringUtil.__UTF8_CHARSET); - } - } - } - - @Override - public synchronized int read() throws IOException - { - int b = super.read(); - if (_skipLF) - { - _skipLF=false; - if (_seenCRLF && b=='\n') - b=super.read(); - } - return b; - } - - @Override - public synchronized int read(byte[] buf, int off, int len) throws IOException - { - if (_skipLF && len>0) - { - _skipLF=false; - if (_seenCRLF) - { - int b = super.read(); - if (b==-1) - return -1; - - if (b!='\n') - { - buf[off]=(byte)(0xff&b); - return 1+super.read(buf,off+1,len-1); - } - } - } - - return super.read(buf,off,len); - } - - -}
--- a/src/org/eclipse/jetty/util/StringUtil.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** Fast String Utilities. - * - * These string utilities provide both conveniance methods and - * performance improvements over most standard library versions. The - * main aim of the optimizations is to avoid object creation unless - * absolutely required. - * - * - */ -public final class StringUtil -{ - private static final Logger LOG = LoggerFactory.getLogger(StringUtil.class); - - public static final String ALL_INTERFACES="0.0.0.0"; - - public static final String __ISO_8859_1="ISO-8859-1"; - public final static String __UTF8="UTF-8"; - public final static String __UTF16="UTF-16"; - - public final static Charset __UTF8_CHARSET; - public final static Charset __ISO_8859_1_CHARSET; - - static - { - __UTF8_CHARSET=Charset.forName(__UTF8); - __ISO_8859_1_CHARSET=Charset.forName(__ISO_8859_1); - } - - private static char[] lowercases = { - '\000','\001','\002','\003','\004','\005','\006','\007', - '\010','\011','\012','\013','\014','\015','\016','\017', - '\020','\021','\022','\023','\024','\025','\026','\027', - '\030','\031','\032','\033','\034','\035','\036','\037', - '\040','\041','\042','\043','\044','\045','\046','\047', - '\050','\051','\052','\053','\054','\055','\056','\057', - '\060','\061','\062','\063','\064','\065','\066','\067', - '\070','\071','\072','\073','\074','\075','\076','\077', - '\100','\141','\142','\143','\144','\145','\146','\147', - '\150','\151','\152','\153','\154','\155','\156','\157', - '\160','\161','\162','\163','\164','\165','\166','\167', - '\170','\171','\172','\133','\134','\135','\136','\137', - '\140','\141','\142','\143','\144','\145','\146','\147', - '\150','\151','\152','\153','\154','\155','\156','\157', - '\160','\161','\162','\163','\164','\165','\166','\167', - '\170','\171','\172','\173','\174','\175','\176','\177' }; - - /* ------------------------------------------------------------ */ - /** - * fast lower case conversion. Only works on ascii (not unicode) - * @param s the string to convert - * @return a lower case version of s - */ - public static String asciiToLowerCase(String s) - { - char[] c = null; - int i=s.length(); - - // look for first conversion - while (i-->0) - { - char c1=s.charAt(i); - if (c1<=127) - { - char c2=lowercases[c1]; - if (c1!=c2) - { - c=s.toCharArray(); - c[i]=c2; - break; - } - } - } - - while (i-->0) - { - if(c[i]<=127) - c[i] = lowercases[c[i]]; - } - - return c==null?s:new String(c); - } - - /* ------------------------------------------------------------ */ - /** - * replace substrings within string. - */ - public static String replace(String s, String sub, String with) - { - int c=0; - int i=s.indexOf(sub,c); - if (i == -1) - return s; - - StringBuilder buf = new StringBuilder(s.length()+with.length()); - - do - { - buf.append(s.substring(c,i)); - buf.append(with); - c=i+sub.length(); - } while ((i=s.indexOf(sub,c))!=-1); - - if (c<s.length()) - buf.append(s.substring(c,s.length())); - - return buf.toString(); - - } - - - /* ------------------------------------------------------------ */ - /** - * append hex digit - * - */ - public static void append(StringBuilder buf,byte b,int base) - { - int bi=0xff&b; - int c='0'+(bi/base)%base; - if (c>'9') - c= 'a'+(c-'0'-10); - buf.append((char)c); - c='0'+bi%base; - if (c>'9') - c= 'a'+(c-'0'-10); - buf.append((char)c); - } - - public static void append2digits(StringBuilder buf,int i) - { - if (i<100) - { - buf.append((char)(i/10+'0')); - buf.append((char)(i%10+'0')); - } - } - - public static String toString(byte[] b,int offset,int length,String charset) - { - try - { - return new String(b,offset,length,charset); - } - catch (UnsupportedEncodingException e) - { - throw new IllegalArgumentException(e); - } - } - - public static boolean isUTF8(String charset) - { - return __UTF8.equalsIgnoreCase(charset)||"UTF8".equalsIgnoreCase(charset); - } - - - public static byte[] getBytes(String s) - { - try - { - return s.getBytes(__ISO_8859_1); - } - catch(Exception e) - { - LOG.warn("",e); - return s.getBytes(); - } - } - -}
--- a/src/org/eclipse/jetty/util/TypeUtil.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,575 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** - * TYPE Utilities. - * Provides various static utiltiy methods for manipulating types and their - * string representations. - * - * @since Jetty 4.1 - */ -public class TypeUtil -{ - private static final Logger LOG = LoggerFactory.getLogger(TypeUtil.class); - public static int CR = '\015'; - public static int LF = '\012'; - - /* ------------------------------------------------------------ */ - private static final HashMap<String, Class<?>> name2Class=new HashMap<String, Class<?>>(); - static - { - name2Class.put("boolean",java.lang.Boolean.TYPE); - name2Class.put("byte",java.lang.Byte.TYPE); - name2Class.put("char",java.lang.Character.TYPE); - name2Class.put("double",java.lang.Double.TYPE); - name2Class.put("float",java.lang.Float.TYPE); - name2Class.put("int",java.lang.Integer.TYPE); - name2Class.put("long",java.lang.Long.TYPE); - name2Class.put("short",java.lang.Short.TYPE); - name2Class.put("void",java.lang.Void.TYPE); - - name2Class.put("java.lang.Boolean.TYPE",java.lang.Boolean.TYPE); - name2Class.put("java.lang.Byte.TYPE",java.lang.Byte.TYPE); - name2Class.put("java.lang.Character.TYPE",java.lang.Character.TYPE); - name2Class.put("java.lang.Double.TYPE",java.lang.Double.TYPE); - name2Class.put("java.lang.Float.TYPE",java.lang.Float.TYPE); - name2Class.put("java.lang.Integer.TYPE",java.lang.Integer.TYPE); - name2Class.put("java.lang.Long.TYPE",java.lang.Long.TYPE); - name2Class.put("java.lang.Short.TYPE",java.lang.Short.TYPE); - name2Class.put("java.lang.Void.TYPE",java.lang.Void.TYPE); - - name2Class.put("java.lang.Boolean",java.lang.Boolean.class); - name2Class.put("java.lang.Byte",java.lang.Byte.class); - name2Class.put("java.lang.Character",java.lang.Character.class); - name2Class.put("java.lang.Double",java.lang.Double.class); - name2Class.put("java.lang.Float",java.lang.Float.class); - name2Class.put("java.lang.Integer",java.lang.Integer.class); - name2Class.put("java.lang.Long",java.lang.Long.class); - name2Class.put("java.lang.Short",java.lang.Short.class); - - name2Class.put("Boolean",java.lang.Boolean.class); - name2Class.put("Byte",java.lang.Byte.class); - name2Class.put("Character",java.lang.Character.class); - name2Class.put("Double",java.lang.Double.class); - name2Class.put("Float",java.lang.Float.class); - name2Class.put("Integer",java.lang.Integer.class); - name2Class.put("Long",java.lang.Long.class); - name2Class.put("Short",java.lang.Short.class); - - name2Class.put(null,java.lang.Void.TYPE); - name2Class.put("string",java.lang.String.class); - name2Class.put("String",java.lang.String.class); - name2Class.put("java.lang.String",java.lang.String.class); - } - - /* ------------------------------------------------------------ */ - private static final HashMap<Class<?>, String> class2Name=new HashMap<Class<?>, String>(); - static - { - class2Name.put(java.lang.Boolean.TYPE,"boolean"); - class2Name.put(java.lang.Byte.TYPE,"byte"); - class2Name.put(java.lang.Character.TYPE,"char"); - class2Name.put(java.lang.Double.TYPE,"double"); - class2Name.put(java.lang.Float.TYPE,"float"); - class2Name.put(java.lang.Integer.TYPE,"int"); - class2Name.put(java.lang.Long.TYPE,"long"); - class2Name.put(java.lang.Short.TYPE,"short"); - class2Name.put(java.lang.Void.TYPE,"void"); - - class2Name.put(java.lang.Boolean.class,"java.lang.Boolean"); - class2Name.put(java.lang.Byte.class,"java.lang.Byte"); - class2Name.put(java.lang.Character.class,"java.lang.Character"); - class2Name.put(java.lang.Double.class,"java.lang.Double"); - class2Name.put(java.lang.Float.class,"java.lang.Float"); - class2Name.put(java.lang.Integer.class,"java.lang.Integer"); - class2Name.put(java.lang.Long.class,"java.lang.Long"); - class2Name.put(java.lang.Short.class,"java.lang.Short"); - - class2Name.put(null,"void"); - class2Name.put(java.lang.String.class,"java.lang.String"); - } - - /* ------------------------------------------------------------ */ - private static final HashMap<Class<?>, Method> class2Value=new HashMap<Class<?>, Method>(); - static - { - try - { - Class<?>[] s ={java.lang.String.class}; - - class2Value.put(java.lang.Boolean.TYPE, - java.lang.Boolean.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Byte.TYPE, - java.lang.Byte.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Double.TYPE, - java.lang.Double.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Float.TYPE, - java.lang.Float.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Integer.TYPE, - java.lang.Integer.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Long.TYPE, - java.lang.Long.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Short.TYPE, - java.lang.Short.class.getMethod("valueOf",s)); - - class2Value.put(java.lang.Boolean.class, - java.lang.Boolean.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Byte.class, - java.lang.Byte.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Double.class, - java.lang.Double.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Float.class, - java.lang.Float.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Integer.class, - java.lang.Integer.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Long.class, - java.lang.Long.class.getMethod("valueOf",s)); - class2Value.put(java.lang.Short.class, - java.lang.Short.class.getMethod("valueOf",s)); - } - catch(Exception e) - { - throw new Error(e); - } - } - - /* ------------------------------------------------------------ */ - /** Array to List. - * <p> - * Works like {@link Arrays#asList(Object...)}, but handles null arrays. - * @return a list backed by the array. - */ - public static <T> List<T> asList(T[] a) - { - if (a==null) - return Collections.emptyList(); - return Arrays.asList(a); - } - - /* ------------------------------------------------------------ */ - /** Class from a canonical name for a type. - * @param name A class or type name. - * @return A class , which may be a primitive TYPE field.. - */ - public static Class<?> fromName(String name) - { - return name2Class.get(name); - } - - /* ------------------------------------------------------------ */ - /** Canonical name for a type. - * @param type A class , which may be a primitive TYPE field. - * @return Canonical name. - */ - public static String toName(Class<?> type) - { - return class2Name.get(type); - } - - /* ------------------------------------------------------------ */ - /** Convert String value to instance. - * @param type The class of the instance, which may be a primitive TYPE field. - * @param value The value as a string. - * @return The value as an Object. - */ - public static Object valueOf(Class<?> type, String value) - { - try - { - if (type.equals(java.lang.String.class)) - return value; - - Method m = class2Value.get(type); - if (m!=null) - return m.invoke(null, value); - - if (type.equals(java.lang.Character.TYPE) || - type.equals(java.lang.Character.class)) - return new Character(value.charAt(0)); - - Constructor<?> c = type.getConstructor(java.lang.String.class); - return c.newInstance(value); - } - catch(NoSuchMethodException e) - { - // LogSupport.ignore(log,e); - } - catch(IllegalAccessException e) - { - // LogSupport.ignore(log,e); - } - catch(InstantiationException e) - { - // LogSupport.ignore(log,e); - } - catch(InvocationTargetException e) - { - if (e.getTargetException() instanceof Error) - throw (Error)(e.getTargetException()); - // LogSupport.ignore(log,e); - } - return null; - } - - /* ------------------------------------------------------------ */ - /** Convert String value to instance. - * @param type classname or type (eg int) - * @param value The value as a string. - * @return The value as an Object. - */ - public static Object valueOf(String type, String value) - { - return valueOf(fromName(type),value); - } - - /* ------------------------------------------------------------ */ - /** Parse an int from a substring. - * Negative numbers are not handled. - * @param s String - * @param offset Offset within string - * @param length Length of integer or -1 for remainder of string - * @param base base of the integer - * @return the parsed integer - * @throws NumberFormatException if the string cannot be parsed - */ - public static int parseInt(String s, int offset, int length, int base) - throws NumberFormatException - { - int value=0; - - if (length<0) - length=s.length()-offset; - - for (int i=0;i<length;i++) - { - char c=s.charAt(offset+i); - - int digit=convertHexDigit((int)c); - if (digit<0 || digit>=base) - throw new NumberFormatException(s.substring(offset,offset+length)); - value=value*base+digit; - } - return value; - } - - /* ------------------------------------------------------------ */ - /** Parse an int from a byte array of ascii characters. - * Negative numbers are not handled. - * @param b byte array - * @param offset Offset within string - * @param length Length of integer or -1 for remainder of string - * @param base base of the integer - * @return the parsed integer - * @throws NumberFormatException if the array cannot be parsed into an integer - */ - public static int parseInt(byte[] b, int offset, int length, int base) - throws NumberFormatException - { - int value=0; - - if (length<0) - length=b.length-offset; - - for (int i=0;i<length;i++) - { - char c=(char)(0xff&b[offset+i]); - - int digit=c-'0'; - if (digit<0 || digit>=base || digit>=10) - { - digit=10+c-'A'; - if (digit<10 || digit>=base) - digit=10+c-'a'; - } - if (digit<0 || digit>=base) - throw new NumberFormatException(new String(b,offset,length)); - value=value*base+digit; - } - return value; - } - - /* ------------------------------------------------------------ */ - public static byte[] parseBytes(String s, int base) - { - byte[] bytes=new byte[s.length()/2]; - for (int i=0;i<s.length();i+=2) - bytes[i/2]=(byte)TypeUtil.parseInt(s,i,2,base); - return bytes; - } - - /* ------------------------------------------------------------ */ - public static String toString(byte[] bytes, int base) - { - StringBuilder buf = new StringBuilder(); - for (byte b : bytes) - { - int bi=0xff&b; - int c='0'+(bi/base)%base; - if (c>'9') - c= 'a'+(c-'0'-10); - buf.append((char)c); - c='0'+bi%base; - if (c>'9') - c= 'a'+(c-'0'-10); - buf.append((char)c); - } - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - /** - * @param c An ASCII encoded character 0-9 a-f A-F - * @return The byte value of the character 0-16. - */ - public static byte convertHexDigit( byte c ) - { - byte b = (byte)((c & 0x1f) + ((c >> 6) * 0x19) - 0x10); - if (b<0 || b>15) - throw new IllegalArgumentException("!hex "+c); - return b; - } - - /* ------------------------------------------------------------ */ - /** - * @param c An ASCII encoded character 0-9 a-f A-F - * @return The byte value of the character 0-16. - */ - public static int convertHexDigit( int c ) - { - int d= ((c & 0x1f) + ((c >> 6) * 0x19) - 0x10); - if (d<0 || d>15) - throw new NumberFormatException("!hex "+c); - return d; - } - - /* ------------------------------------------------------------ */ - public static void toHex(byte b,Appendable buf) - { - try - { - int d=0xf&((0xF0&b)>>4); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&b; - buf.append((char)((d>9?('A'-10):'0')+d)); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - public static void toHex(int value,Appendable buf) throws IOException - { - int d=0xf&((0xF0000000&value)>>28); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x0F000000&value)>>24); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x00F00000&value)>>20); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x000F0000&value)>>16); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x0000F000&value)>>12); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x00000F00&value)>>8); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&((0x000000F0&value)>>4); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&value; - buf.append((char)((d>9?('A'-10):'0')+d)); - - Integer.toString(0,36); - } - - - /* ------------------------------------------------------------ */ - public static void toHex(long value,Appendable buf) throws IOException - { - toHex((int)(value>>32),buf); - toHex((int)value,buf); - } - - /* ------------------------------------------------------------ */ - public static String toHexString(byte b) - { - return toHexString(new byte[]{b}, 0, 1); - } - - /* ------------------------------------------------------------ */ - public static String toHexString(byte[] b) - { - return toHexString(b, 0, b.length); - } - - /* ------------------------------------------------------------ */ - public static String toHexString(byte[] b,int offset,int length) - { - StringBuilder buf = new StringBuilder(); - for (int i=offset;i<offset+length;i++) - { - int bi=0xff&b[i]; - int c='0'+(bi/16)%16; - if (c>'9') - c= 'A'+(c-'0'-10); - buf.append((char)c); - c='0'+bi%16; - if (c>'9') - c= 'a'+(c-'0'-10); - buf.append((char)c); - } - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - public static byte[] fromHexString(String s) - { - if (s.length()%2!=0) - throw new IllegalArgumentException(s); - byte[] array = new byte[s.length()/2]; - for (int i=0;i<array.length;i++) - { - int b = Integer.parseInt(s.substring(i*2,i*2+2),16); - array[i]=(byte)(0xff&b); - } - return array; - } - - - public static void dump(Class<?> c) - { - System.err.println("Dump: "+c); - dump(c.getClassLoader()); - } - - public static void dump(ClassLoader cl) - { - System.err.println("Dump Loaders:"); - while(cl!=null) - { - System.err.println(" loader "+cl); - cl = cl.getParent(); - } - } - - - /* ------------------------------------------------------------ */ - /** - * @deprecated - */ - public static byte[] readLine(InputStream in) throws IOException - { - byte[] buf = new byte[256]; - - int i=0; - int loops=0; - int ch=0; - - while (true) - { - ch=in.read(); - if (ch<0) - break; - loops++; - - // skip a leading LF's - if (loops==1 && ch==LF) - continue; - - if (ch==CR || ch==LF) - break; - - if (i>=buf.length) - { - byte[] old_buf=buf; - buf=new byte[old_buf.length+256]; - System.arraycopy(old_buf, 0, buf, 0, old_buf.length); - } - buf[i++]=(byte)ch; - } - - if (ch==-1 && i==0) - return null; - - // skip a trailing LF if it exists - if (ch==CR && in.available()>=1 && in.markSupported()) - { - in.mark(1); - ch=in.read(); - if (ch!=LF) - in.reset(); - } - - byte[] old_buf=buf; - buf=new byte[i]; - System.arraycopy(old_buf, 0, buf, 0, i); - - return buf; - } - - public static Object call(Class<?> oClass, String method, Object obj, Object[] arg) - throws InvocationTargetException, NoSuchMethodException - { - // Lets just try all methods for now - Method[] methods = oClass.getMethods(); - for (int c = 0; methods != null && c < methods.length; c++) - { - if (!methods[c].getName().equals(method)) - continue; - if (methods[c].getParameterTypes().length != arg.length) - continue; - if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null)) - continue; - if ((obj == null) && methods[c].getDeclaringClass() != oClass) - continue; - - try - { - return methods[c].invoke(obj,arg); - } - catch (IllegalAccessException e) - { - LOG.trace("",e); - } - catch (IllegalArgumentException e) - { - LOG.trace("",e); - } - } - - throw new NoSuchMethodException(method); - } -}
--- a/src/org/eclipse/jetty/util/URIUtil.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,574 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URLEncoder; - - - -/* ------------------------------------------------------------ */ -/** URI Holder. - * This class assists with the decoding and encoding or HTTP URI's. - * It differs from the java.net.URL class as it does not provide - * communications ability, but it does assist with query string - * formatting. - * <P>UTF-8 encoding is used by default for % encoded characters. This - * may be overridden with the org.eclipse.jetty.util.URI.charset system property. - * @see UrlEncoded - * - */ -public final class URIUtil { - // Use UTF-8 as per http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars - public static final String __CHARSET = StringUtil.__UTF8; - - private URIUtil() - {} - - /* ------------------------------------------------------------ */ - /** Encode a URI path. - * This is the same encoding offered by URLEncoder, except that - * the '/' character is not encoded. - * @param path The path the encode - * @return The encoded path - */ - public static String encodePath(String path) - { - if (path==null || path.length()==0) - return path; - - StringBuilder buf = encodePath(null,path); - return buf==null?path:buf.toString(); - } - - /* ------------------------------------------------------------ */ - /** Encode a URI path. - * @param path The path the encode - * @param buf StringBuilder to encode path into (or null) - * @return The StringBuilder or null if no substitutions required. - */ - public static StringBuilder encodePath(StringBuilder buf, String path) - { - byte[] bytes=null; - if (buf==null) - { - loop: - for (int i=0;i<path.length();i++) - { - char c=path.charAt(i); - switch(c) - { - case '%': - case '?': - case ';': - case '#': - case '\'': - case '"': - case '<': - case '>': - case ' ': - buf=new StringBuilder(path.length()*2); - break loop; - default: - if (c>127) - { - try - { - bytes=path.getBytes(URIUtil.__CHARSET); - } - catch (UnsupportedEncodingException e) - { - throw new IllegalStateException(e); - } - buf=new StringBuilder(path.length()*2); - break loop; - } - - } - } - if (buf==null) - return null; - } - - synchronized(buf) - { - if (bytes!=null) - { - for (int i=0;i<bytes.length;i++) - { - byte c=bytes[i]; - switch(c) - { - case '%': - buf.append("%25"); - continue; - case '?': - buf.append("%3F"); - continue; - case ';': - buf.append("%3B"); - continue; - case '#': - buf.append("%23"); - continue; - case '"': - buf.append("%22"); - continue; - case '\'': - buf.append("%27"); - continue; - case '<': - buf.append("%3C"); - continue; - case '>': - buf.append("%3E"); - continue; - case ' ': - buf.append("%20"); - continue; - default: - if (c<0) - { - buf.append('%'); - TypeUtil.toHex(c,buf); - } - else - buf.append((char)c); - continue; - } - } - - } - else - { - for (int i=0;i<path.length();i++) - { - char c=path.charAt(i); - switch(c) - { - case '%': - buf.append("%25"); - continue; - case '?': - buf.append("%3F"); - continue; - case ';': - buf.append("%3B"); - continue; - case '#': - buf.append("%23"); - continue; - case '"': - buf.append("%22"); - continue; - case '\'': - buf.append("%27"); - continue; - case '<': - buf.append("%3C"); - continue; - case '>': - buf.append("%3E"); - continue; - case ' ': - buf.append("%20"); - continue; - default: - buf.append(c); - continue; - } - } - } - } - - return buf; - } - - /* ------------------------------------------------------------ */ - /* Decode a URI path and strip parameters - * @param path The path the encode - * @param buf StringBuilder to encode path into - */ - public static String decodePath(String path) - { - if (path==null) - return null; - // Array to hold all converted characters - char[] chars=null; - int n=0; - // Array to hold a sequence of %encodings - byte[] bytes=null; - int b=0; - - int len=path.length(); - - for (int i=0;i<len;i++) - { - char c = path.charAt(i); - - if (c=='%' && (i+2)<len) - { - if (chars==null) - { - chars=new char[len]; - bytes=new byte[len]; - path.getChars(0,i,chars,0); - } - bytes[b++]=(byte)(0xff&TypeUtil.parseInt(path,i+1,2,16)); - i+=2; - continue; - } - else if (c==';') - { - if (chars==null) - { - chars=new char[len]; - path.getChars(0,i,chars,0); - n=i; - } - break; - } - else if (bytes==null) - { - n++; - continue; - } - - // Do we have some bytes to convert? - if (b>0) - { - // convert series of bytes and add to chars - String s; - try - { - s=new String(bytes,0,b,__CHARSET); - } - catch (UnsupportedEncodingException e) - { - s=new String(bytes,0,b); - } - s.getChars(0,s.length(),chars,n); - n+=s.length(); - b=0; - } - - chars[n++]=c; - } - - if (chars==null) - return path; - - // if we have a remaining sequence of bytes - if (b>0) - { - // convert series of bytes and add to chars - String s; - try - { - s=new String(bytes,0,b,__CHARSET); - } - catch (UnsupportedEncodingException e) - { - s=new String(bytes,0,b); - } - s.getChars(0,s.length(),chars,n); - n+=s.length(); - } - - return new String(chars,0,n); - } - - /* ------------------------------------------------------------ */ - /* Decode a URI path and strip parameters. - * @param path The path the encode - * @param buf StringBuilder to encode path into - */ - public static String decodePath(byte[] buf, int offset, int length) - { - byte[] bytes=null; - int n=0; - - for (int i=0;i<length;i++) - { - byte b = buf[i + offset]; - - if (b=='%' && (i+2)<length) - { - b=(byte)(0xff&TypeUtil.parseInt(buf,i+offset+1,2,16)); - i+=2; - } - else if (b==';') - { - length=i; - break; - } - else if (bytes==null) - { - n++; - continue; - } - - if (bytes==null) - { - bytes=new byte[length]; - for (int j=0;j<n;j++) - bytes[j]=buf[j + offset]; - } - - bytes[n++]=b; - } - - if (bytes==null) - return StringUtil.toString(buf,offset,length,__CHARSET); - return StringUtil.toString(bytes,0,n,__CHARSET); - } - - - /* ------------------------------------------------------------ */ - /** Add two URI path segments. - * Handles null and empty paths, path and query params (eg ?a=b or - * ;JSESSIONID=xxx) and avoids duplicate '/' - * @param p1 URI path segment (should be encoded) - * @param p2 URI path segment (should be encoded) - * @return Legally combined path segments. - */ - public static String addPaths(String p1, String p2) - { - if (p1==null || p1.length()==0) - { - if (p1!=null && p2==null) - return p1; - return p2; - } - if (p2==null || p2.length()==0) - return p1; - - int split=p1.indexOf(';'); - if (split<0) - split=p1.indexOf('?'); - if (split==0) - return p2+p1; - if (split<0) - split=p1.length(); - - StringBuilder buf = new StringBuilder(p1.length()+p2.length()+2); - buf.append(p1); - - if (buf.charAt(split-1)=='/') - { - if (p2.startsWith("/")) - { - buf.deleteCharAt(split-1); - buf.insert(split-1,p2); - } - else - buf.insert(split,p2); - } - else - { - if (p2.startsWith("/")) - buf.insert(split,p2); - else - { - buf.insert(split,'/'); - buf.insert(split+1,p2); - } - } - - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - /** Return the parent Path. - * Treat a URI like a directory path and return the parent directory. - */ - public static String parentPath(String p) - { - if (p==null || "/".equals(p)) - return null; - int slash=p.lastIndexOf('/',p.length()-2); - if (slash>=0) - return p.substring(0,slash+1); - return null; - } - - /* ------------------------------------------------------------ */ - /** Convert a path to a cananonical form. - * All instances of "." and ".." are factored out. Null is returned - * if the path tries to .. above its root. - * @param path - * @return path or null. - */ - public static String canonicalPath(String path) - { - if (path==null || path.length()==0) - return path; - - int end=path.length(); - int start = path.lastIndexOf('/', end); - - search: - while (end>0) - { - switch(end-start) - { - case 2: // possible single dot - if (path.charAt(start+1)!='.') - break; - break search; - case 3: // possible double dot - if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.') - break; - break search; - } - - end=start; - start=path.lastIndexOf('/',end-1); - } - - // If we have checked the entire string - if (start>=end) - return path; - - StringBuilder buf = new StringBuilder(path); - int delStart=-1; - int delEnd=-1; - int skip=0; - - while (end>0) - { - switch(end-start) - { - case 2: // possible single dot - if (buf.charAt(start+1)!='.') - { - if (skip>0 && --skip==0) - { - delStart=start>=0?start:0; - if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.') - delStart++; - } - break; - } - - if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/') - break; - - if(delEnd<0) - delEnd=end; - delStart=start; - if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/') - { - delStart++; - if (delEnd<buf.length() && buf.charAt(delEnd)=='/') - delEnd++; - break; - } - if (end==buf.length()) - delStart++; - - end=start--; - while (start>=0 && buf.charAt(start)!='/') - start--; - continue; - - case 3: // possible double dot - if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.') - { - if (skip>0 && --skip==0) - { delStart=start>=0?start:0; - if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.') - delStart++; - } - break; - } - - delStart=start; - if (delEnd<0) - delEnd=end; - - skip++; - end=start--; - while (start>=0 && buf.charAt(start)!='/') - start--; - continue; - - default: - if (skip>0 && --skip==0) - { - delStart=start>=0?start:0; - if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.') - delStart++; - } - } - - // Do the delete - if (skip<=0 && delStart>=0 && delEnd>=delStart) - { - buf.delete(delStart,delEnd); - delStart=delEnd=-1; - if (skip>0) - delEnd=end; - } - - end=start--; - while (start>=0 && buf.charAt(start)!='/') - start--; - } - - // Too many .. - if (skip>0) - return null; - - // Do the delete - if (delEnd>=0) - buf.delete(delStart,delEnd); - - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - /** - * @param uri URI - * @return True if the uri has a scheme - */ - public static boolean hasScheme(String uri) - { - for (int i=0;i<uri.length();i++) - { - char c=uri.charAt(i); - if (c==':') - return true; - if (!(c>='a'&&c<='z' || - c>='A'&&c<='Z' || - (i>0 &&(c>='0'&&c<='9' || - c=='.' || - c=='+' || - c=='-')) - )) - break; - } - return false; - } - -} - - -
--- a/src/org/eclipse/jetty/util/UrlEncoded.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1034 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import static org.eclipse.jetty.util.TypeUtil.convertHexDigit; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** Handles coding of MIME "x-www-form-urlencoded". - * <p> - * This class handles the encoding and decoding for either - * the query string of a URL or the _content of a POST HTTP request. - * - * <h4>Notes</h4> - * The UTF-8 charset is assumed, unless otherwise defined by either - * passing a parameter or setting the "org.eclipse.jetty.util.UrlEncoding.charset" - * System property. - * <p> - * The hashtable either contains String single values, vectors - * of String or arrays of Strings. - * <p> - * This class is only partially synchronised. In particular, simple - * get operations are not protected from concurrent updates. - * - * @see java.net.URLEncoder - */ -public class UrlEncoded extends MultiMap implements Cloneable -{ - private static final Logger LOG = LoggerFactory.getLogger(UrlEncoded.class); - - public static final String ENCODING = System.getProperty("org.eclipse.jetty.util.UrlEncoding.charset",StringUtil.__UTF8); - - /* ----------------------------------------------------------------- */ - public UrlEncoded(UrlEncoded url) - { - super(url); - } - - /* ----------------------------------------------------------------- */ - public UrlEncoded() - { - super(6); - } - - /* ----------------------------------------------------------------- */ - public UrlEncoded(String s) - { - super(6); - decode(s,ENCODING); - } - - /* ----------------------------------------------------------------- */ - public UrlEncoded(String s, String charset) - { - super(6); - decode(s,charset); - } - - /* ----------------------------------------------------------------- */ - public void decode(String query) - { - decodeTo(query,this,ENCODING,-1); - } - - /* ----------------------------------------------------------------- */ - public void decode(String query,String charset) - { - decodeTo(query,this,charset,-1); - } - - /* -------------------------------------------------------------- */ - /** Encode Hashtable with % encoding. - */ - public String encode() - { - return encode(ENCODING,false); - } - - /* -------------------------------------------------------------- */ - /** Encode Hashtable with % encoding. - */ - public String encode(String charset) - { - return encode(charset,false); - } - - /* -------------------------------------------------------------- */ - /** Encode Hashtable with % encoding. - * @param equalsForNullValue if True, then an '=' is always used, even - * for parameters without a value. e.g. "blah?a=&b=&c=". - */ - public synchronized String encode(String charset, boolean equalsForNullValue) - { - return encode(this,charset,equalsForNullValue); - } - - /* -------------------------------------------------------------- */ - /** Encode Hashtable with % encoding. - * @param equalsForNullValue if True, then an '=' is always used, even - * for parameters without a value. e.g. "blah?a=&b=&c=". - */ - public static String encode(MultiMap map, String charset, boolean equalsForNullValue) - { - if (charset==null) - charset=ENCODING; - - StringBuilder result = new StringBuilder(128); - - Iterator iter = map.entrySet().iterator(); - while(iter.hasNext()) - { - Map.Entry entry = (Map.Entry)iter.next(); - - String key = entry.getKey().toString(); - Object list = entry.getValue(); - int s=LazyList.size(list); - - if (s==0) - { - result.append(encodeString(key,charset)); - if(equalsForNullValue) - result.append('='); - } - else - { - for (int i=0;i<s;i++) - { - if (i>0) - result.append('&'); - Object val=LazyList.get(list,i); - result.append(encodeString(key,charset)); - - if (val!=null) - { - String str=val.toString(); - if (str.length()>0) - { - result.append('='); - result.append(encodeString(str,charset)); - } - else if (equalsForNullValue) - result.append('='); - } - else if (equalsForNullValue) - result.append('='); - } - } - if (iter.hasNext()) - result.append('&'); - } - return result.toString(); - } - - - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param content the string containing the encoded parameters - */ - public static void decodeTo(String content, MultiMap map, String charset) - { - decodeTo(content,map,charset,-1); - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param content the string containing the encoded parameters - */ - public static void decodeTo(String content, MultiMap map, String charset, int maxKeys) - { - if (charset==null) - charset=ENCODING; - - synchronized(map) - { - String key = null; - String value = null; - int mark=-1; - boolean encoded=false; - for (int i=0;i<content.length();i++) - { - char c = content.charAt(i); - switch (c) - { - case '&': - int l=i-mark-1; - value = l==0?"": - (encoded?decodeString(content,mark+1,l,charset):content.substring(mark+1,i)); - mark=i; - encoded=false; - if (key != null) - { - map.add(key,value); - } - else if (value!=null&&value.length()>0) - { - map.add(value,""); - } - key = null; - value=null; - if (maxKeys>0 && map.size()>maxKeys) - throw new IllegalStateException("Form too many keys"); - break; - case '=': - if (key!=null) - break; - key = encoded?decodeString(content,mark+1,i-mark-1,charset):content.substring(mark+1,i); - mark=i; - encoded=false; - break; - case '+': - encoded=true; - break; - case '%': - encoded=true; - break; - } - } - - if (key != null) - { - int l=content.length()-mark-1; - value = l==0?"":(encoded?decodeString(content,mark+1,l,charset):content.substring(mark+1)); - map.add(key,value); - } - else if (mark<content.length()) - { - key = encoded - ?decodeString(content,mark+1,content.length()-mark-1,charset) - :content.substring(mark+1); - if (key != null && key.length() > 0) - { - map.add(key,""); - } - } - } - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param raw the byte[] containing the encoded parameters - * @param offset the offset within raw to decode from - * @param length the length of the section to decode - * @param map the {@link MultiMap} to populate - */ - public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map) - { - decodeUtf8To(raw,offset,length,map,new Utf8StringBuilder()); - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param raw the byte[] containing the encoded parameters - * @param offset the offset within raw to decode from - * @param length the length of the section to decode - * @param map the {@link MultiMap} to populate - * @param buffer the buffer to decode into - */ - public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map,Utf8StringBuilder buffer) - { - synchronized(map) - { - String key = null; - String value = null; - - // TODO cache of parameter names ??? - int end=offset+length; - for (int i=offset;i<end;i++) - { - byte b=raw[i]; - try - { - switch ((char)(0xff&b)) - { - case '&': - value = buffer.length()==0?"":buffer.toString(); - buffer.reset(); - if (key != null) - { - map.add(key,value); - } - else if (value!=null&&value.length()>0) - { - map.add(value,""); - } - key = null; - value=null; - break; - - case '=': - if (key!=null) - { - buffer.append(b); - break; - } - key = buffer.toString(); - buffer.reset(); - break; - - case '+': - buffer.append((byte)' '); - break; - - case '%': - if (i+2<end) - { - if ('u'==raw[i+1]) - { - i++; - if (i+4<end) - buffer.getStringBuilder().append(Character.toChars((convertHexDigit(raw[++i])<<12) +(convertHexDigit(raw[++i])<<8) + (convertHexDigit(raw[++i])<<4) +convertHexDigit(raw[++i]))); - else - { - buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT); - i=end; - } - } - else - buffer.append((byte)((convertHexDigit(raw[++i])<<4) + convertHexDigit(raw[++i]))); - } - else - { - buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT); - i=end; - } - break; - - default: - buffer.append(b); - break; - } - } - catch(NotUtf8Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - } - } - - if (key != null) - { - value = buffer.length()==0?"":buffer.toReplacedString(); - buffer.reset(); - map.add(key,value); - } - else if (buffer.length()>0) - { - map.add(buffer.toReplacedString(),""); - } - } - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param in InputSteam to read - * @param map MultiMap to add parameters to - * @param maxLength maximum number of keys to read or -1 for no limit - */ - public static void decode88591To(InputStream in, MultiMap map, int maxLength, int maxKeys) - throws IOException - { - synchronized(map) - { - StringBuffer buffer = new StringBuffer(); - String key = null; - String value = null; - - int b; - - // TODO cache of parameter names ??? - int totalLength=0; - while ((b=in.read())>=0) - { - switch ((char) b) - { - case '&': - value = buffer.length()==0?"":buffer.toString(); - buffer.setLength(0); - if (key != null) - { - map.add(key,value); - } - else if (value!=null&&value.length()>0) - { - map.add(value,""); - } - key = null; - value=null; - if (maxKeys>0 && map.size()>maxKeys) - throw new IllegalStateException("Form too many keys"); - break; - - case '=': - if (key!=null) - { - buffer.append((char)b); - break; - } - key = buffer.toString(); - buffer.setLength(0); - break; - - case '+': - buffer.append(' '); - break; - - case '%': - int code0=in.read(); - if ('u'==code0) - { - int code1=in.read(); - if (code1>=0) - { - int code2=in.read(); - if (code2>=0) - { - int code3=in.read(); - if (code3>=0) - buffer.append(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3))); - } - } - } - else if (code0>=0) - { - int code1=in.read(); - if (code1>=0) - buffer.append((char)((convertHexDigit(code0)<<4)+convertHexDigit(code1))); - } - break; - - default: - buffer.append((char)b); - break; - } - if (maxLength>=0 && (++totalLength > maxLength)) - throw new IllegalStateException("Form too large"); - } - - if (key != null) - { - value = buffer.length()==0?"":buffer.toString(); - buffer.setLength(0); - map.add(key,value); - } - else if (buffer.length()>0) - { - map.add(buffer.toString(), ""); - } - } - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param in InputSteam to read - * @param map MultiMap to add parameters to - * @param maxLength maximum number of keys to read or -1 for no limit - */ - public static void decodeUtf8To(InputStream in, MultiMap map, int maxLength, int maxKeys) - throws IOException - { - synchronized(map) - { - Utf8StringBuilder buffer = new Utf8StringBuilder(); - String key = null; - String value = null; - - int b; - - // TODO cache of parameter names ??? - int totalLength=0; - while ((b=in.read())>=0) - { - try - { - switch ((char) b) - { - case '&': - value = buffer.length()==0?"":buffer.toString(); - buffer.reset(); - if (key != null) - { - map.add(key,value); - } - else if (value!=null&&value.length()>0) - { - map.add(value,""); - } - key = null; - value=null; - if (maxKeys>0 && map.size()>maxKeys) - throw new IllegalStateException("Form too many keys"); - break; - - case '=': - if (key!=null) - { - buffer.append((byte)b); - break; - } - key = buffer.toString(); - buffer.reset(); - break; - - case '+': - buffer.append((byte)' '); - break; - - case '%': - int code0=in.read(); - if ('u'==code0) - { - int code1=in.read(); - if (code1>=0) - { - int code2=in.read(); - if (code2>=0) - { - int code3=in.read(); - if (code3>=0) - buffer.getStringBuilder().append(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3))); - } - } - } - else if (code0>=0) - { - int code1=in.read(); - if (code1>=0) - buffer.append((byte)((convertHexDigit(code0)<<4)+convertHexDigit(code1))); - } - break; - - default: - buffer.append((byte)b); - break; - } - } - catch(NotUtf8Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - } - if (maxLength>=0 && (++totalLength > maxLength)) - throw new IllegalStateException("Form too large"); - } - - if (key != null) - { - value = buffer.length()==0?"":buffer.toString(); - buffer.reset(); - map.add(key,value); - } - else if (buffer.length()>0) - { - map.add(buffer.toString(), ""); - } - } - } - - /* -------------------------------------------------------------- */ - public static void decodeUtf16To(InputStream in, MultiMap map, int maxLength, int maxKeys) throws IOException - { - InputStreamReader input = new InputStreamReader(in,StringUtil.__UTF16); - StringWriter buf = new StringWriter(8192); - IO.copy(input,buf,maxLength); - - decodeTo(buf.getBuffer().toString(),map,StringUtil.__UTF16,maxKeys); - } - - /* -------------------------------------------------------------- */ - /** Decoded parameters to Map. - * @param in the stream containing the encoded parameters - */ - public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength, int maxKeys) - throws IOException - { - //no charset present, use the configured default - if (charset==null) - { - charset=ENCODING; - } - - if (StringUtil.__UTF8.equalsIgnoreCase(charset)) - { - decodeUtf8To(in,map,maxLength,maxKeys); - return; - } - - if (StringUtil.__ISO_8859_1.equals(charset)) - { - decode88591To(in,map,maxLength,maxKeys); - return; - } - - if (StringUtil.__UTF16.equalsIgnoreCase(charset)) // Should be all 2 byte encodings - { - decodeUtf16To(in,map,maxLength,maxKeys); - return; - } - - - synchronized(map) - { - String key = null; - String value = null; - - int c; - - int totalLength = 0; - ByteArrayOutputStream2 output = new ByteArrayOutputStream2(); - - int size=0; - - while ((c=in.read())>0) - { - switch ((char) c) - { - case '&': - size=output.size(); - value = size==0?"":output.toString(charset); - output.setCount(0); - if (key != null) - { - map.add(key,value); - } - else if (value!=null&&value.length()>0) - { - map.add(value,""); - } - key = null; - value=null; - if (maxKeys>0 && map.size()>maxKeys) - throw new IllegalStateException("Form too many keys"); - break; - case '=': - if (key!=null) - { - output.write(c); - break; - } - size=output.size(); - key = size==0?"":output.toString(charset); - output.setCount(0); - break; - case '+': - output.write(' '); - break; - case '%': - int code0=in.read(); - if ('u'==code0) - { - int code1=in.read(); - if (code1>=0) - { - int code2=in.read(); - if (code2>=0) - { - int code3=in.read(); - if (code3>=0) - output.write(new String(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3))).getBytes(charset)); - } - } - - } - else if (code0>=0) - { - int code1=in.read(); - if (code1>=0) - output.write((convertHexDigit(code0)<<4)+convertHexDigit(code1)); - } - break; - default: - output.write(c); - break; - } - - totalLength++; - if (maxLength>=0 && totalLength > maxLength) - throw new IllegalStateException("Form too large"); - } - - size=output.size(); - if (key != null) - { - value = size==0?"":output.toString(charset); - output.setCount(0); - map.add(key,value); - } - else if (size>0) - map.add(output.toString(charset),""); - } - } - - /* -------------------------------------------------------------- */ - /** Decode String with % encoding. - * This method makes the assumption that the majority of calls - * will need no decoding. - */ - public static String decodeString(String encoded,int offset,int length,String charset) - { - if (charset==null || StringUtil.isUTF8(charset)) - { - Utf8StringBuffer buffer=null; - - for (int i=0;i<length;i++) - { - char c = encoded.charAt(offset+i); - if (c<0||c>0xff) - { - if (buffer==null) - { - buffer=new Utf8StringBuffer(length); - buffer.getStringBuffer().append(encoded,offset,offset+i+1); - } - else - buffer.getStringBuffer().append(c); - } - else if (c=='+') - { - if (buffer==null) - { - buffer=new Utf8StringBuffer(length); - buffer.getStringBuffer().append(encoded,offset,offset+i); - } - - buffer.getStringBuffer().append(' '); - } - else if (c=='%') - { - if (buffer==null) - { - buffer=new Utf8StringBuffer(length); - buffer.getStringBuffer().append(encoded,offset,offset+i); - } - - if ((i+2)<length) - { - try - { - if ('u'==encoded.charAt(offset+i+1)) - { - if((i+5)<length) - { - int o=offset+i+2; - i+=5; - String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16))); - buffer.getStringBuffer().append(unicode); - } - else - { - i=length; - buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT); - } - } - else - { - int o=offset+i+1; - i+=2; - byte b=(byte)TypeUtil.parseInt(encoded,o,2,16); - buffer.append(b); - } - } - catch(NotUtf8Exception e) - { - LOG.warn(e.toString()); - LOG.debug("",e); - } - catch(NumberFormatException nfe) - { - LOG.debug("",nfe); - buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT); - } - } - else - { - buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT); - i=length; - } - } - else if (buffer!=null) - buffer.getStringBuffer().append(c); - } - - if (buffer==null) - { - if (offset==0 && encoded.length()==length) - return encoded; - return encoded.substring(offset,offset+length); - } - - return buffer.toReplacedString(); - } - else - { - StringBuffer buffer=null; - - try - { - for (int i=0;i<length;i++) - { - char c = encoded.charAt(offset+i); - if (c<0||c>0xff) - { - if (buffer==null) - { - buffer=new StringBuffer(length); - buffer.append(encoded,offset,offset+i+1); - } - else - buffer.append(c); - } - else if (c=='+') - { - if (buffer==null) - { - buffer=new StringBuffer(length); - buffer.append(encoded,offset,offset+i); - } - - buffer.append(' '); - } - else if (c=='%') - { - if (buffer==null) - { - buffer=new StringBuffer(length); - buffer.append(encoded,offset,offset+i); - } - - byte[] ba=new byte[length]; - int n=0; - while(c>=0 && c<=0xff) - { - if (c=='%') - { - if(i+2<length) - { - try - { - if ('u'==encoded.charAt(offset+i+1)) - { - if (i+6<length) - { - int o=offset+i+2; - i+=6; - String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16))); - byte[] reencoded = unicode.getBytes(charset); - System.arraycopy(reencoded,0,ba,n,reencoded.length); - n+=reencoded.length; - } - else - { - ba[n++] = (byte)'?'; - i=length; - } - } - else - { - int o=offset+i+1; - i+=3; - ba[n]=(byte)TypeUtil.parseInt(encoded,o,2,16); - n++; - } - } - catch(NumberFormatException nfe) - { - LOG.trace("",nfe); - ba[n++] = (byte)'?'; - } - } - else - { - ba[n++] = (byte)'?'; - i=length; - } - } - else if (c=='+') - { - ba[n++]=(byte)' '; - i++; - } - else - { - ba[n++]=(byte)c; - i++; - } - - if (i>=length) - break; - c = encoded.charAt(offset+i); - } - - i--; - buffer.append(new String(ba,0,n,charset)); - - } - else if (buffer!=null) - buffer.append(c); - } - - if (buffer==null) - { - if (offset==0 && encoded.length()==length) - return encoded; - return encoded.substring(offset,offset+length); - } - - return buffer.toString(); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException(e); - } - } - - } - - /* ------------------------------------------------------------ */ - /** Perform URL encoding. - * @param string - * @return encoded string. - */ - public static String encodeString(String string) - { - return encodeString(string,ENCODING); - } - - /* ------------------------------------------------------------ */ - /** Perform URL encoding. - * @param string - * @return encoded string. - */ - public static String encodeString(String string,String charset) - { - if (charset==null) - charset=ENCODING; - byte[] bytes=null; - try - { - bytes=string.getBytes(charset); - } - catch(UnsupportedEncodingException e) - { - // LOG.warn(LogSupport.EXCEPTION,e); - bytes=string.getBytes(); - } - - int len=bytes.length; - byte[] encoded= new byte[bytes.length*3]; - int n=0; - boolean noEncode=true; - - for (int i=0;i<len;i++) - { - byte b = bytes[i]; - - if (b==' ') - { - noEncode=false; - encoded[n++]=(byte)'+'; - } - else if (b>='a' && b<='z' || - b>='A' && b<='Z' || - b>='0' && b<='9') - { - encoded[n++]=b; - } - else - { - noEncode=false; - encoded[n++]=(byte)'%'; - byte nibble= (byte) ((b&0xf0)>>4); - if (nibble>=10) - encoded[n++]=(byte)('A'+nibble-10); - else - encoded[n++]=(byte)('0'+nibble); - nibble= (byte) (b&0xf); - if (nibble>=10) - encoded[n++]=(byte)('A'+nibble-10); - else - encoded[n++]=(byte)('0'+nibble); - } - } - - if (noEncode) - return string; - - try - { - return new String(encoded,0,n,charset); - } - catch(UnsupportedEncodingException e) - { - // LOG.warn(LogSupport.EXCEPTION,e); - return new String(encoded,0,n); - } - } - - - /* ------------------------------------------------------------ */ - /** - */ - @Override - public Object clone() - { - return new UrlEncoded(this); - } -}
--- a/src/org/eclipse/jetty/util/Utf8Appendable.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.IOException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * Utf8 Appendable abstract base class - * - * This abstract class wraps a standard {@link java.lang.Appendable} and provides methods to append UTF-8 encoded bytes, that are converted into characters. - * - * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before state a character is appended to the string buffer. - * - * The UTF-8 decoding is done by this class and no additional buffers or Readers are used. The UTF-8 code was inspired by - * http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - * - * License information for Bjoern Hoehrmann's code: - * - * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - **/ -public abstract class Utf8Appendable -{ - protected static final Logger LOG = LoggerFactory.getLogger(Utf8Appendable.class); - public static final char REPLACEMENT = '\ufffd'; - private static final int UTF8_ACCEPT = 0; - private static final int UTF8_REJECT = 12; - - protected final Appendable _appendable; - protected int _state = UTF8_ACCEPT; - - private static final byte[] BYTE_TABLE = - { - // The first part of the table maps bytes to character classes that - // to reduce the size of the transition table and create bitmasks. - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8 - }; - - private static final byte[] TRANS_TABLE = - { - // The second part is a transition table that maps a combination - // of a state of the automaton and a character class to a state. - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12 - }; - - private int _codep; - - public Utf8Appendable(Appendable appendable) - { - _appendable = appendable; - } - - public abstract int length(); - - protected void reset() - { - _state = UTF8_ACCEPT; - } - - public void append(byte b) - { - try - { - appendByte(b); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - public void append(byte[] b, int offset, int length) - { - try - { - int end = offset + length; - for (int i = offset; i < end; i++) - appendByte(b[i]); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - public boolean append(byte[] b, int offset, int length, int maxChars) - { - try - { - int end = offset + length; - for (int i = offset; i < end; i++) - { - if (length() > maxChars) - return false; - appendByte(b[i]); - } - return true; - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - protected void appendByte(byte b) throws IOException - { - - if (b > 0 && _state == UTF8_ACCEPT) - { - _appendable.append((char)(b & 0xFF)); - } - else - { - int i = b & 0xFF; - int type = BYTE_TABLE[i]; - _codep = _state == UTF8_ACCEPT ? (0xFF >> type) & i : (i & 0x3F) | (_codep << 6); - int next = TRANS_TABLE[_state + type]; - - switch(next) - { - case UTF8_ACCEPT: - _state=next; - if (_codep < Character.MIN_HIGH_SURROGATE) - { - _appendable.append((char)_codep); - } - else - { - for (char c : Character.toChars(_codep)) - _appendable.append(c); - } - break; - - case UTF8_REJECT: - String reason = "byte "+TypeUtil.toHexString(b)+" in state "+(_state/12); - _codep=0; - _state = UTF8_ACCEPT; - _appendable.append(REPLACEMENT); - throw new NotUtf8Exception(reason); - - default: - _state=next; - - } - } - } - - public boolean isUtf8SequenceComplete() - { - return _state == UTF8_ACCEPT; - } - - public static class NotUtf8Exception extends IllegalArgumentException - { - public NotUtf8Exception(String reason) - { - super("Not valid UTF8! "+reason); - } - } - - protected void checkState() - { - if (!isUtf8SequenceComplete()) - { - _codep=0; - _state = UTF8_ACCEPT; - try - { - _appendable.append(REPLACEMENT); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - throw new NotUtf8Exception("incomplete UTF8 sequence"); - } - } - - public String toReplacedString() - { - if (!isUtf8SequenceComplete()) - { - _codep=0; - _state = UTF8_ACCEPT; - try - { - _appendable.append(REPLACEMENT); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - Throwable th= new NotUtf8Exception("incomplete UTF8 sequence"); - LOG.warn(th.toString()); - LOG.debug("",th); - } - return _appendable.toString(); - } -}
--- a/src/org/eclipse/jetty/util/Utf8StringBuffer.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -/* ------------------------------------------------------------ */ -/** - * UTF-8 StringBuffer. - * - * This class wraps a standard {@link java.lang.StringBuffer} and provides methods to append - * UTF-8 encoded bytes, that are converted into characters. - * - * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before - * state a character is appended to the string buffer. - * - * The UTF-8 decoding is done by this class and no additional buffers or Readers are used. - * The UTF-8 code was inspired by http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - */ -public class Utf8StringBuffer extends Utf8Appendable -{ - final StringBuffer _buffer; - - public Utf8StringBuffer() - { - super(new StringBuffer()); - _buffer = (StringBuffer)_appendable; - } - - public Utf8StringBuffer(int capacity) - { - super(new StringBuffer(capacity)); - _buffer = (StringBuffer)_appendable; - } - - @Override - public int length() - { - return _buffer.length(); - } - - @Override - public void reset() - { - super.reset(); - _buffer.setLength(0); - } - - public StringBuffer getStringBuffer() - { - checkState(); - return _buffer; - } - - @Override - public String toString() - { - checkState(); - return _buffer.toString(); - } -}
--- a/src/org/eclipse/jetty/util/Utf8StringBuilder.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - - -/* ------------------------------------------------------------ */ -/** UTF-8 StringBuilder. - * - * This class wraps a standard {@link java.lang.StringBuilder} and provides methods to append - * UTF-8 encoded bytes, that are converted into characters. - * - * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before - * state a character is appended to the string buffer. - * - * The UTF-8 decoding is done by this class and no additional buffers or Readers are used. - * The UTF-8 code was inspired by http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - * - */ -public class Utf8StringBuilder extends Utf8Appendable -{ - final StringBuilder _buffer; - - public Utf8StringBuilder() - { - super(new StringBuilder()); - _buffer=(StringBuilder)_appendable; - } - - public Utf8StringBuilder(int capacity) - { - super(new StringBuilder(capacity)); - _buffer=(StringBuilder)_appendable; - } - - @Override - public int length() - { - return _buffer.length(); - } - - @Override - public void reset() - { - super.reset(); - _buffer.setLength(0); - } - - public StringBuilder getStringBuilder() - { - checkState(); - return _buffer; - } - - @Override - public String toString() - { - checkState(); - return _buffer.toString(); - } - - -}
--- a/src/org/eclipse/jetty/util/component/AbstractLifeCycle.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.util.concurrent.CopyOnWriteArrayList; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Basic implementation of the life cycle interface for components. - * - * - */ -public abstract class AbstractLifeCycle implements LifeCycle -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractLifeCycle.class); - public static final String STOPPED="STOPPED"; - public static final String FAILED="FAILED"; - public static final String STARTING="STARTING"; - public static final String STARTED="STARTED"; - public static final String STOPPING="STOPPING"; - public static final String RUNNING="RUNNING"; - - private final Object _lock = new Object(); - private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3; - private volatile int _state = __STOPPED; - - protected void doStart() throws Exception - { - } - - protected void doStop() throws Exception - { - } - - public final void start() throws Exception - { - synchronized (_lock) - { - try - { - if (_state == __STARTED || _state == __STARTING) - return; - setStarting(); - doStart(); - setStarted(); - } - catch (Exception e) - { - setFailed(e); - throw e; - } - catch (Error e) - { - setFailed(e); - throw e; - } - } - } - - public final void stop() throws Exception - { - synchronized (_lock) - { - try - { - if (_state == __STOPPING || _state == __STOPPED) - return; - setStopping(); - doStop(); - setStopped(); - } - catch (Exception e) - { - setFailed(e); - throw e; - } - catch (Error e) - { - setFailed(e); - throw e; - } - } - } - - public boolean isRunning() - { - final int state = _state; - - return state == __STARTED || state == __STARTING; - } - - public boolean isStarted() - { - return _state == __STARTED; - } - - public boolean isStarting() - { - return _state == __STARTING; - } - - public boolean isStopping() - { - return _state == __STOPPING; - } - - public boolean isStopped() - { - return _state == __STOPPED; - } - - public boolean isFailed() - { - return _state == __FAILED; - } - - public String getState() - { - switch(_state) - { - case __FAILED: return FAILED; - case __STARTING: return STARTING; - case __STARTED: return STARTED; - case __STOPPING: return STOPPING; - case __STOPPED: return STOPPED; - } - return null; - } - - public static String getState(LifeCycle lc) - { - if (lc.isStarting()) return STARTING; - if (lc.isStarted()) return STARTED; - if (lc.isStopping()) return STOPPING; - if (lc.isStopped()) return STOPPED; - return FAILED; - } - - private void setStarted() - { - _state = __STARTED; - LOG.debug(STARTED+" {}",this); - } - - private void setStarting() - { - LOG.debug("starting {}",this); - _state = __STARTING; - } - - private void setStopping() - { - LOG.debug("stopping {}",this); - _state = __STOPPING; - } - - private void setStopped() - { - _state = __STOPPED; - LOG.debug("{} {}",STOPPED,this); - } - - private void setFailed(Throwable th) - { - _state = __FAILED; - LOG.warn(FAILED+" " + this+": "+th); - } - -}
--- a/src/org/eclipse/jetty/util/component/AggregateLifeCycle.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans. - * <p> - * Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate. - * An unmanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. - * <p> - * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean. - * Otherwise the methods {@link #addBean(Object, boolean)}, {@link #manage(Object)} and {@link #unmanage(Object)} can be used to - * explicitly control the life cycle relationship. - * <p> - * If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanaged, or - * the API must be used to explicitly set it as unmanaged. - * <p> - */ -public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable -{ - private static final Logger LOG = LoggerFactory.getLogger(AggregateLifeCycle.class); - private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>(); - private boolean _started=false; - - private class Bean - { - Bean(LifeCycle b,boolean managed) - { - _bean = b; - _managed = managed; - } - final LifeCycle _bean; - final boolean _managed; - - public String toString() - { - return "{"+_bean+","+_managed+"}"; - } - } - - /* ------------------------------------------------------------ */ - /** - * Start the managed lifecycle beans in the order they were added. - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - for (Bean b:_beans) - { - if (b._managed) - { - LifeCycle l = b._bean; - if (!l.isRunning()) - l.start(); - } - } - // indicate that we are started, so that addBean will start other beans added. - _started = true; - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /** - * Stop the joined lifecycle beans in the reverse order they were added. - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStop() throws Exception - { - _started = false; - super.doStop(); - List<Bean> reverse = new ArrayList<Bean>(_beans); - Collections.reverse(reverse); - for (Bean b:reverse) - { - if (b._managed) - { - LifeCycle l = b._bean; - if (l.isRunning()) - l.stop(); - } - } - } - - - /* ------------------------------------------------------------ */ - /** - * Destroy the joined Destroyable beans in the reverse order they were added. - * @see org.eclipse.jetty.util.component.Destroyable#destroy() - */ - public void destroy() - { - List<Bean> reverse = new ArrayList<Bean>(_beans); - Collections.reverse(reverse); - for (Bean b:reverse) - { - if (b._bean instanceof Destroyable && b._managed) - { - Destroyable d = (Destroyable)b._bean; - d.destroy(); - } - } - _beans.clear(); - } - - - /* ------------------------------------------------------------ */ - /** Is the bean contained in the aggregate. - * @param bean - * @return True if the aggregate contains the bean - */ - private boolean contains(LifeCycle bean) - { - for (Bean b:_beans) - if (b._bean==bean) - return true; - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Add an associated bean. - * If the bean is a {@link LifeCycle}, then it will be managed if it is not - * already started and umanaged if it is already started. The {@link #addBean(Object, boolean)} - * method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)} - * methods may be used after an add to change the status. - * @param o the bean object to add - * @return true if the bean was added or false if it has already been added. - */ - public boolean addBean(LifeCycle o) - { - // beans are joined unless they are started lifecycles - return addBean(o,!o.isStarted()); - } - - /* ------------------------------------------------------------ */ - /** Add an associated lifecycle. - * @param o The lifecycle to add - * @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint. - * @return true if bean was added, false if already present. - */ - public boolean addBean(LifeCycle o, boolean managed) - { - if (contains(o)) - return false; - - Bean b = new Bean(o,managed); - _beans.add(b); - - // Start the bean if we are started - if (managed && _started) - { - try - { - o.start(); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - return true; - } - - /* ------------------------------------------------------------ */ - /** Get dependent beans - * @return List of beans. - */ - public Collection<Object> getBeans() - { -// return new ArrayList<Object>(_beans); - ArrayList<Object> beans = new ArrayList<Object>(); - for (Bean b:_beans) { - beans.add(b._bean); - } - return beans; - } - - - /* ------------------------------------------------------------ */ - /** - * Remove an associated bean. - */ - public boolean removeBean (LifeCycle o) - { - Iterator<Bean> i = _beans.iterator(); - while(i.hasNext()) - { - Bean b=i.next(); - if (b._bean==o) - { - _beans.remove(b); - return true; - } - } - return false; - } - - public String dump() - { - return dump(this); - } - - public static String dump(Dumpable dumpable) - { - StringBuilder b = new StringBuilder(); - try - { - dumpable.dump(b,""); - } - catch (IOException e) - { - LOG.warn("",e); - } - return b.toString(); - } - - private void dump(Appendable out) throws IOException - { - dump(out,""); - } - - private void dumpThis(Appendable out) throws IOException - { - out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n"); - } - - public static void dumpObject(Appendable out,Object o) throws IOException - { - try - { - if (o instanceof LifeCycle) - out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n"); - else - out.append(String.valueOf(o)).append("\n"); - } - catch(Throwable th) - { - out.append(" => ").append(th.toString()).append('\n'); - } - } - - public void dump(Appendable out,String indent) throws IOException - { - dumpThis(out); - int size=_beans.size(); - if (size==0) - return; - int i=0; - for (Bean b : _beans) - { - i++; - - out.append(indent).append(" +- "); - if (b._managed) - { - if (b._bean instanceof Dumpable) - ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | ")); - else - dumpObject(out,b._bean); - } - else - dumpObject(out,b._bean); - } - - if (i!=size) - out.append(indent).append(" |\n"); - } - - public static void dump(Appendable out,String indent,Collection<?>... collections) throws IOException - { - if (collections.length==0) - return; - int size=0; - for (Collection<?> c : collections) - size+=c.size(); - if (size==0) - return; - - int i=0; - for (Collection<?> c : collections) - { - for (Object o : c) - { - i++; - out.append(indent).append(" +- "); - - if (o instanceof Dumpable) - ((Dumpable)o).dump(out,indent+(i==size?" ":" | ")); - else - dumpObject(out,o); - } - - if (i!=size) - out.append(indent).append(" |\n"); - } - } -}
--- a/src/org/eclipse/jetty/util/component/Destroyable.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - - -/** - * <p>A Destroyable is an object which can be destroyed.</p> - * <p>Typically a Destroyable is a {@link LifeCycle} component that can hold onto - * resources over multiple start/stop cycles. A call to destroy will release all - * resources and will prevent any further start/stop cycles from being successful.</p> - */ -public interface Destroyable -{ - void destroy(); -}
--- a/src/org/eclipse/jetty/util/component/Dumpable.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.io.IOException; - -public interface Dumpable -{ - String dump(); - void dump(Appendable out,String indent) throws IOException; -}
--- a/src/org/eclipse/jetty/util/component/LifeCycle.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.util.EventListener; - -/* ------------------------------------------------------------ */ -/** - * The lifecycle interface for generic components. - * <br /> - * Classes implementing this interface have a defined life cycle - * defined by the methods of this interface. - * - * - */ -public interface LifeCycle -{ - /* ------------------------------------------------------------ */ - /** - * Starts the component. - * @throws Exception If the component fails to start - * @see #isStarted() - * @see #stop() - * @see #isFailed() - */ - public void start() - throws Exception; - - /* ------------------------------------------------------------ */ - /** - * Stops the component. - * The component may wait for current activities to complete - * normally, but it can be interrupted. - * @exception Exception If the component fails to stop - * @see #isStopped() - * @see #start() - * @see #isFailed() - */ - public void stop() - throws Exception; - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is starting or has been started. - */ - public boolean isRunning(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component has been started. - * @see #start() - * @see #isStarting() - */ - public boolean isStarted(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is starting. - * @see #isStarted() - */ - public boolean isStarting(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is stopping. - * @see #isStopped() - */ - public boolean isStopping(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component has been stopped. - * @see #stop() - * @see #isStopping() - */ - public boolean isStopped(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component has failed to start or has failed to stop. - */ - public boolean isFailed(); - -}
--- a/src/org/eclipse/jetty/util/component/jmx/AggregateLifeCycle-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -AggregateLifeCycle: A LifeCycle holding other LifeCycles -dumpStdErr():Object:INFO:Dump the nested Object state to StdErr \ No newline at end of file
--- a/src/org/eclipse/jetty/util/component/jmx/Dumpable-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -Dumpable: Dumpable Object -dump():Object:INFO:Dump the nested Object state as a String \ No newline at end of file
--- a/src/org/eclipse/jetty/util/component/jmx/LifeCycle-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -LifeCycle: Startable object -start(): Starts the instance -stop(): Stops the instance -running: Instance is started or starting -started: Instance is started -starting: Instance is starting -stopping: Instance is stopping -stopped: Instance is stopped -failed: Instance is failed \ No newline at end of file
--- a/src/org/eclipse/jetty/util/resource/BadResource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; - - -/* ------------------------------------------------------------ */ -/** Bad Resource. - * - * A Resource that is returned for a bade URL. Acts as a resource - * that does not exist and throws appropriate exceptions. - * - * - */ -class BadResource extends URLResource -{ - /* ------------------------------------------------------------ */ - private String _message=null; - - /* -------------------------------------------------------- */ - BadResource(URL url, String message) - { - super(url,null); - _message=message; - } - - - /* -------------------------------------------------------- */ - @Override - public boolean exists() - { - return false; - } - - /* -------------------------------------------------------- */ - @Override - public long lastModified() - { - return -1; - } - - /* -------------------------------------------------------- */ - @Override - public boolean isDirectory() - { - return false; - } - - /* --------------------------------------------------------- */ - @Override - public long length() - { - return -1; - } - - - /* ------------------------------------------------------------ */ - @Override - public File getFile() - { - return null; - } - - /* --------------------------------------------------------- */ - @Override - public InputStream getInputStream() throws IOException - { - throw new FileNotFoundException(_message); - } - - /* --------------------------------------------------------- */ - @Override - public OutputStream getOutputStream() - throws java.io.IOException, SecurityException - { - throw new FileNotFoundException(_message); - } - - /* --------------------------------------------------------- */ - @Override - public boolean delete() - throws SecurityException - { - throw new SecurityException(_message); - } - - /* --------------------------------------------------------- */ - @Override - public boolean renameTo( Resource dest) - throws SecurityException - { - throw new SecurityException(_message); - } - - /* --------------------------------------------------------- */ - @Override - public String[] list() - { - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public void copyTo(File destination) - throws IOException - { - throw new SecurityException(_message); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return super.toString()+"; BadResource="+_message; - } - -}
--- a/src/org/eclipse/jetty/util/resource/FileResource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,400 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.security.Permission; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** File Resource. - * - * Handle resources of implied or explicit file type. - * This class can check for aliasing in the filesystem (eg case - * insensitivity). By default this is turned on, or it can be controlled - * by calling the static method @see FileResource#setCheckAliases(boolean) - * - */ -public class FileResource extends URLResource -{ - private static final Logger LOG = LoggerFactory.getLogger(FileResource.class); - private static boolean __checkAliases = true; - - /* ------------------------------------------------------------ */ - private File _file; - private transient URL _alias=null; - private transient boolean _aliasChecked=false; - - /* ------------------------------------------------------------------------------- */ - /** setCheckAliases. - * @param checkAliases True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found. - */ - public static void setCheckAliases(boolean checkAliases) - { - __checkAliases=checkAliases; - } - - /* ------------------------------------------------------------------------------- */ - /** getCheckAliases. - * @return True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found. - */ - public static boolean getCheckAliases() - { - return __checkAliases; - } - - /* -------------------------------------------------------- */ - public FileResource(URL url) - throws IOException, URISyntaxException - { - super(url,null); - - try - { - // Try standard API to convert URL to file. - _file =new File(new URI(url.toString())); - } - catch (URISyntaxException e) - { - throw e; - } - catch (Exception e) - { - LOG.trace("",e); - try - { - // Assume that File.toURL produced unencoded chars. So try - // encoding them. - String file_url="file:"+URIUtil.encodePath(url.toString().substring(5)); - URI uri = new URI(file_url); - if (uri.getAuthority()==null) - _file = new File(uri); - else - _file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile())); - } - catch (Exception e2) - { - LOG.trace("",e2); - - // Still can't get the file. Doh! try good old hack! - checkConnection(); - Permission perm = _connection.getPermission(); - _file = new File(perm==null?url.getFile():perm.getName()); - } - } - if (_file.isDirectory()) - { - if (!_urlString.endsWith("/")) - _urlString=_urlString+"/"; - } - else - { - if (_urlString.endsWith("/")) - _urlString=_urlString.substring(0,_urlString.length()-1); - } - - } - - /* -------------------------------------------------------- */ - FileResource(URL url, URLConnection connection, File file) - { - super(url,connection); - _file=file; - if (_file.isDirectory() && !_urlString.endsWith("/")) - _urlString=_urlString+"/"; - } - - /* -------------------------------------------------------- */ - @Override - public Resource addPath(String path) - throws IOException,MalformedURLException - { - URLResource r=null; - String url=null; - - path = org.eclipse.jetty.util.URIUtil.canonicalPath(path); - - if ("/".equals(path)) - return this; - else if (!isDirectory()) - { - r=(FileResource)super.addPath(path); - url=r._urlString; - } - else - { - if (path==null) - throw new MalformedURLException(); - - // treat all paths being added as relative - String rel=path; - if (path.startsWith("/")) - rel = path.substring(1); - - url=URIUtil.addPaths(_urlString,URIUtil.encodePath(rel)); - r=(URLResource)Resource.newResource(url); - } - - // Check for encoding aliases - // The encoded path should be a suffix of the resource (give or take a directory / ) - String encoded=URIUtil.encodePath(path); - int expected=r.toString().length()-encoded.length(); - int index = r._urlString.lastIndexOf(encoded, expected); - if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory())) - { - if (r instanceof FileResource) - { - ((FileResource)r)._alias=((FileResource)r)._file.getCanonicalFile().toURI().toURL(); - ((FileResource)r)._aliasChecked=true; - } - } - return r; - } - - - /* ------------------------------------------------------------ */ - @Override - public URL getAlias() - { - if (__checkAliases && !_aliasChecked) - { - try - { - String abs=_file.getAbsolutePath(); - String can=_file.getCanonicalPath(); - - if (abs.length()!=can.length() || !abs.equals(can)) - _alias=Resource.toURL(new File(can)); - - _aliasChecked=true; - - if (_alias!=null && LOG.isDebugEnabled()) - { - LOG.debug("ALIAS abs="+abs); - LOG.debug("ALIAS can="+can); - } - } - catch(Exception e) - { - LOG.warn("EXCEPTION",e); - return getURL(); - } - } - return _alias; - } - - /* -------------------------------------------------------- */ - /** - * Returns true if the resource exists. - */ - @Override - public boolean exists() - { - return _file.exists(); - } - - /* -------------------------------------------------------- */ - /** - * Returns the last modified time - */ - @Override - public long lastModified() - { - return _file.lastModified(); - } - - /* -------------------------------------------------------- */ - /** - * Returns true if the respresenetd resource is a container/directory. - */ - @Override - public boolean isDirectory() - { - return _file.isDirectory(); - } - - /* --------------------------------------------------------- */ - /** - * Return the length of the resource - */ - @Override - public long length() - { - return _file.length(); - } - - - /* --------------------------------------------------------- */ - /** - * Returns the name of the resource - */ - @Override - public String getName() - { - return _file.getAbsolutePath(); - } - - /* ------------------------------------------------------------ */ - /** - * Returns an File representing the given resource or NULL if this - * is not possible. - */ - @Override - public File getFile() - { - return _file; - } - - /* --------------------------------------------------------- */ - /** - * Returns an input stream to the resource - */ - @Override - public InputStream getInputStream() throws IOException - { - return new FileInputStream(_file); - } - - /* --------------------------------------------------------- */ - /** - * Returns an output stream to the resource - */ - @Override - public OutputStream getOutputStream() - throws java.io.IOException, SecurityException - { - return new FileOutputStream(_file); - } - - /* --------------------------------------------------------- */ - /** - * Deletes the given resource - */ - @Override - public boolean delete() - throws SecurityException - { - return _file.delete(); - } - - /* --------------------------------------------------------- */ - /** - * Rename the given resource - */ - @Override - public boolean renameTo( Resource dest) - throws SecurityException - { - if( dest instanceof FileResource) - return _file.renameTo( ((FileResource)dest)._file); - else - return false; - } - - /* --------------------------------------------------------- */ - /** - * Returns a list of resources contained in the given resource - */ - @Override - public String[] list() - { - String[] list =_file.list(); - if (list==null) - return null; - for (int i=list.length;i-->0;) - { - if (new File(_file,list[i]).isDirectory() && - !list[i].endsWith("/")) - list[i]+="/"; - } - return list; - } - - /* ------------------------------------------------------------ */ - /** Encode according to this resource type. - * File URIs are encoded. - * @param uri URI to encode. - * @return The uri unchanged. - */ - @Override - public String encode(String uri) - { - return uri; - } - - /* ------------------------------------------------------------ */ - /** - * @param o - * @return <code>true</code> of the object <code>o</code> is a {@link FileResource} pointing to the same file as this resource. - */ - @Override - public boolean equals( Object o) - { - if (this == o) - return true; - - if (null == o || ! (o instanceof FileResource)) - return false; - - FileResource f=(FileResource)o; - return f._file == _file || (null != _file && _file.equals(f._file)); - } - - /* ------------------------------------------------------------ */ - /** - * @return the hashcode. - */ - @Override - public int hashCode() - { - return null == _file ? super.hashCode() : _file.hashCode(); - } - - /* ------------------------------------------------------------ */ - @Override - public void copyTo(File destination) - throws IOException - { - if (isDirectory()) - { - IO.copyDir(getFile(),destination); - } - else - { - if (destination.exists()) - throw new IllegalArgumentException(destination+" exists"); - IO.copy(getFile(),destination); - } - } -}
--- a/src/org/eclipse/jetty/util/resource/JarFileResource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,435 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.IOException; -import java.net.JarURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -class JarFileResource extends JarResource -{ - private static final Logger LOG = LoggerFactory.getLogger(JarFileResource.class); - private JarFile _jarFile; - private File _file; - private String[] _list; - private JarEntry _entry; - private boolean _directory; - private String _jarUrl; - private String _path; - private boolean _exists; - - /* -------------------------------------------------------- */ - JarFileResource(URL url) - { - super(url); - } - - /* ------------------------------------------------------------ */ - JarFileResource(URL url, boolean useCaches) - { - super(url, useCaches); - } - - - /* ------------------------------------------------------------ */ - @Override - public synchronized void release() - { - _list=null; - _entry=null; - _file=null; - //if the jvm is not doing url caching, then the JarFiles will not be cached either, - //and so they are safe to close - if (!getUseCaches()) - { - if ( _jarFile != null ) - { - try - { - LOG.debug("Closing JarFile "+_jarFile.getName()); - _jarFile.close(); - } - catch ( IOException ioe ) - { - LOG.trace("",ioe); - } - } - } - _jarFile=null; - super.release(); - } - - /* ------------------------------------------------------------ */ - @Override - protected boolean checkConnection() - { - try - { - super.checkConnection(); - } - finally - { - if (_jarConnection==null) - { - _entry=null; - _file=null; - _jarFile=null; - _list=null; - } - } - return _jarFile!=null; - } - - - /* ------------------------------------------------------------ */ - @Override - protected synchronized void newConnection() - throws IOException - { - super.newConnection(); - - _entry=null; - _file=null; - _jarFile=null; - _list=null; - - int sep = _urlString.indexOf("!/"); - _jarUrl=_urlString.substring(0,sep+2); - _path=_urlString.substring(sep+2); - if (_path.length()==0) - _path=null; - _jarFile=_jarConnection.getJarFile(); - _file=new File(_jarFile.getName()); - } - - - /* ------------------------------------------------------------ */ - /** - * Returns true if the represented resource exists. - */ - @Override - public boolean exists() - { - if (_exists) - return true; - - if (_urlString.endsWith("!/")) - { - - String file_url=_urlString.substring(4,_urlString.length()-2); - try{return newResource(file_url).exists();} - catch(Exception e) {LOG.trace("",e); return false;} - } - - boolean check=checkConnection(); - - // Is this a root URL? - if (_jarUrl!=null && _path==null) - { - // Then if it exists it is a directory - _directory=check; - return true; - } - else - { - // Can we find a file for it? - JarFile jarFile=null; - if (check) - // Yes - jarFile=_jarFile; - else - { - // No - so lets look if the root entry exists. - try - { - JarURLConnection c=(JarURLConnection)((new URL(_jarUrl)).openConnection()); - c.setUseCaches(getUseCaches()); - jarFile=c.getJarFile(); - } - catch(Exception e) - { - LOG.trace("",e); - } - } - - // Do we need to look more closely? - if (jarFile!=null && _entry==null && !_directory) - { - // OK - we have a JarFile, lets look at the entries for our path - Enumeration<JarEntry> e=jarFile.entries(); - while(e.hasMoreElements()) - { - JarEntry entry = (JarEntry) e.nextElement(); - String name=entry.getName().replace('\\','/'); - - // Do we have a match - if (name.equals(_path)) - { - _entry=entry; - // Is the match a directory - _directory=_path.endsWith("/"); - break; - } - else if (_path.endsWith("/")) - { - if (name.startsWith(_path)) - { - _directory=true; - break; - } - } - else if (name.startsWith(_path) && name.length()>_path.length() && name.charAt(_path.length())=='/') - { - _directory=true; - break; - } - } - - if (_directory && !_urlString.endsWith("/")) - { - _urlString+="/"; - try - { - _url=new URL(_urlString); - } - catch(MalformedURLException ex) - { - LOG.warn("",ex); - } - } - } - } - - _exists= ( _directory || _entry!=null); - return _exists; - } - - - /* ------------------------------------------------------------ */ - /** - * Returns true if the represented resource is a container/directory. - * If the resource is not a file, resources ending with "/" are - * considered directories. - */ - @Override - public boolean isDirectory() - { - return _urlString.endsWith("/") || exists() && _directory; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the last modified time - */ - @Override - public long lastModified() - { - if (checkConnection() && _file!=null) - { - if (exists() && _entry!=null) - return _entry.getTime(); - return _file.lastModified(); - } - return -1; - } - - /* ------------------------------------------------------------ */ - @Override - public synchronized String[] list() - { - if (isDirectory() && _list==null) - { - List<String> list = null; - try - { - list = listEntries(); - } - catch (Exception e) - { - //Sun's JarURLConnection impl for jar: protocol will close a JarFile in its connect() method if - //useCaches == false (eg someone called URLConnection with defaultUseCaches==true). - //As their sun.net.www.protocol.jar package caches JarFiles and/or connections, we can wind up in - //the situation where the JarFile we have remembered in our _jarFile member has actually been closed - //by other code. - //So, do one retry to drop a connection and get a fresh JarFile - LOG.warn("Retrying list:"+e); - LOG.debug("",e); - release(); - list = listEntries(); - } - - if (list != null) - { - _list=new String[list.size()]; - list.toArray(_list); - } - } - return _list; - } - - - /* ------------------------------------------------------------ */ - private List<String> listEntries () - { - checkConnection(); - - ArrayList<String> list = new ArrayList<String>(32); - JarFile jarFile=_jarFile; - if(jarFile==null) - { - try - { - JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection()); - jc.setUseCaches(getUseCaches()); - jarFile=jc.getJarFile(); - } - catch(Exception e) - { - - e.printStackTrace(); - LOG.trace("",e); - } - } - - Enumeration<JarEntry> e=jarFile.entries(); - String dir=_urlString.substring(_urlString.indexOf("!/")+2); - while(e.hasMoreElements()) - { - JarEntry entry = e.nextElement(); - String name=entry.getName().replace('\\','/'); - if(!name.startsWith(dir) || name.length()==dir.length()) - { - continue; - } - String listName=name.substring(dir.length()); - int dash=listName.indexOf('/'); - if (dash>=0) - { - //when listing jar:file urls, you get back one - //entry for the dir itself, which we ignore - if (dash==0 && listName.length()==1) - continue; - //when listing jar:file urls, all files and - //subdirs have a leading /, which we remove - if (dash==0) - listName=listName.substring(dash+1, listName.length()); - else - listName=listName.substring(0,dash+1); - - if (list.contains(listName)) - continue; - } - - list.add(listName); - } - - return list; - } - - - - - - /* ------------------------------------------------------------ */ - /** - * Return the length of the resource - */ - @Override - public long length() - { - if (isDirectory()) - return -1; - - if (_entry!=null) - return _entry.getSize(); - - return -1; - } - - /* ------------------------------------------------------------ */ - /** Encode according to this resource type. - * File URIs are not encoded. - * @param uri URI to encode. - * @return The uri unchanged. - */ - @Override - public String encode(String uri) - { - return uri; - } - - - /** - * Take a Resource that possibly might use URLConnection caching - * and turn it into one that doesn't. - * @param resource - * @return the non-caching resource - */ - public static Resource getNonCachingResource (Resource resource) - { - if (!(resource instanceof JarFileResource)) - return resource; - - JarFileResource oldResource = (JarFileResource)resource; - - JarFileResource newResource = new JarFileResource(oldResource.getURL(), false); - return newResource; - - } - - /** - * Check if this jar:file: resource is contained in the - * named resource. Eg <code>jar:file:///a/b/c/foo.jar!/x.html</code> isContainedIn <code>file:///a/b/c/foo.jar</code> - * @param resource - * @return true if resource is contained in the named resource - * @throws MalformedURLException - */ - @Override - public boolean isContainedIn (Resource resource) - throws MalformedURLException - { - String string = _urlString; - int index = string.indexOf("!/"); - if (index > 0) - string = string.substring(0,index); - if (string.startsWith("jar:")) - string = string.substring(4); - URL url = new URL(string); - return url.sameFile(resource.getURL()); - } -} - - - - - - - -
--- a/src/org/eclipse/jetty/util/resource/JarResource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,273 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.JarURLConnection; -import java.net.URL; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.Manifest; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -public class JarResource extends URLResource -{ - private static final Logger LOG = LoggerFactory.getLogger(JarResource.class); - protected JarURLConnection _jarConnection; - - /* -------------------------------------------------------- */ - JarResource(URL url) - { - super(url,null); - } - - /* ------------------------------------------------------------ */ - JarResource(URL url, boolean useCaches) - { - super(url, null, useCaches); - } - - /* ------------------------------------------------------------ */ - @Override - public synchronized void release() - { - _jarConnection=null; - super.release(); - } - - /* ------------------------------------------------------------ */ - @Override - protected synchronized boolean checkConnection() - { - super.checkConnection(); - try - { - if (_jarConnection!=_connection) - newConnection(); - } - catch(IOException e) - { - LOG.trace("",e); - _jarConnection=null; - } - - return _jarConnection!=null; - } - - /* ------------------------------------------------------------ */ - /** - * @throws IOException Sub-classes of <code>JarResource</code> may throw an IOException (or subclass) - */ - protected void newConnection() throws IOException - { - _jarConnection=(JarURLConnection)_connection; - } - - /* ------------------------------------------------------------ */ - /** - * Returns true if the respresenetd resource exists. - */ - @Override - public boolean exists() - { - if (_urlString.endsWith("!/")) - return checkConnection(); - else - return super.exists(); - } - - /* ------------------------------------------------------------ */ - @Override - public File getFile() - throws IOException - { - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public InputStream getInputStream() - throws java.io.IOException - { - checkConnection(); - if (!_urlString.endsWith("!/")) - return new FilterInputStream(super.getInputStream()) - { - @Override - public void close() throws IOException {this.in=IO.getClosedStream();} - }; - - URL url = new URL(_urlString.substring(4,_urlString.length()-2)); - InputStream is = url.openStream(); - return is; - } - - /* ------------------------------------------------------------ */ - @Override - public void copyTo(File directory) - throws IOException - { - if (!exists()) - return; - - if(LOG.isDebugEnabled()) - LOG.debug("Extract "+this+" to "+directory); - - String urlString = this.getURL().toExternalForm().trim(); - int endOfJarUrl = urlString.indexOf("!/"); - int startOfJarUrl = (endOfJarUrl >= 0?4:0); - - if (endOfJarUrl < 0) - throw new IOException("Not a valid jar url: "+urlString); - - URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl)); - String subEntryName = (endOfJarUrl+2 < urlString.length() ? urlString.substring(endOfJarUrl + 2) : null); - boolean subEntryIsDir = (subEntryName != null && subEntryName.endsWith("/")?true:false); - - if (LOG.isDebugEnabled()) - LOG.debug("Extracting entry = "+subEntryName+" from jar "+jarFileURL); - - InputStream is = jarFileURL.openConnection().getInputStream(); - JarInputStream jin = new JarInputStream(is); - JarEntry entry; - boolean shouldExtract; - while((entry=jin.getNextJarEntry())!=null) - { - String entryName = entry.getName(); - if ((subEntryName != null) && (entryName.startsWith(subEntryName))) - { - // is the subentry really a dir? - if (!subEntryIsDir && subEntryName.length()+1==entryName.length() && entryName.endsWith("/")) - subEntryIsDir=true; - - //if there is a particular subEntry that we are looking for, only - //extract it. - if (subEntryIsDir) - { - //if it is a subdirectory we are looking for, then we - //are looking to extract its contents into the target - //directory. Remove the name of the subdirectory so - //that we don't wind up creating it too. - entryName = entryName.substring(subEntryName.length()); - if (!entryName.equals("")) - { - //the entry is - shouldExtract = true; - } - else - shouldExtract = false; - } - else - shouldExtract = true; - } - else if ((subEntryName != null) && (!entryName.startsWith(subEntryName))) - { - //there is a particular entry we are looking for, and this one - //isn't it - shouldExtract = false; - } - else - { - //we are extracting everything - shouldExtract = true; - } - - - if (!shouldExtract) - { - if (LOG.isDebugEnabled()) - LOG.debug("Skipping entry: "+entryName); - continue; - } - - String dotCheck = entryName.replace('\\', '/'); - dotCheck = URIUtil.canonicalPath(dotCheck); - if (dotCheck == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Invalid entry: "+entryName); - continue; - } - - File file=new File(directory,entryName); - - if (entry.isDirectory()) - { - // Make directory - if (!file.exists()) - file.mkdirs(); - } - else - { - // make directory (some jars don't list dirs) - File dir = new File(file.getParent()); - if (!dir.exists()) - dir.mkdirs(); - - // Make file - FileOutputStream fout = null; - try - { - fout = new FileOutputStream(file); - IO.copy(jin,fout); - } - finally - { - IO.close(fout); - } - - // touch the file. - if (entry.getTime()>=0) - file.setLastModified(entry.getTime()); - } - } - - if ((subEntryName == null) || (subEntryName != null && subEntryName.equalsIgnoreCase("META-INF/MANIFEST.MF"))) - { - Manifest manifest = jin.getManifest(); - if (manifest != null) - { - File metaInf = new File (directory, "META-INF"); - metaInf.mkdir(); - File f = new File(metaInf, "MANIFEST.MF"); - FileOutputStream fout = new FileOutputStream(f); - manifest.write(fout); - fout.close(); - } - } - IO.close(jin); - } - - public static Resource newJarResource(Resource resource) throws IOException - { - if (resource instanceof JarResource) - return resource; - return Resource.newResource("jar:" + resource + "!/"); - } -}
--- a/src/org/eclipse/jetty/util/resource/Resource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,620 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.text.DateFormat; -import java.util.Arrays; -import java.util.Date; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/* ------------------------------------------------------------ */ -/** - * Abstract resource class. - */ -public abstract class Resource implements ResourceFactory -{ - private static final Logger LOG = LoggerFactory.getLogger(Resource.class); - public static boolean __defaultUseCaches = true; - volatile Object _associate; - - /* ------------------------------------------------------------ */ - /** - * Change the default setting for url connection caches. - * Subsequent URLConnections will use this default. - * @param useCaches - */ - public static void setDefaultUseCaches (boolean useCaches) - { - __defaultUseCaches=useCaches; - } - - /* ------------------------------------------------------------ */ - public static boolean getDefaultUseCaches () - { - return __defaultUseCaches; - } - - /* ------------------------------------------------------------ */ - /** Construct a resource from a uri. - * @param uri A URI. - * @return A Resource object. - * @throws IOException Problem accessing URI - */ - public static Resource newResource(URI uri) - throws IOException - { - return newResource(uri.toURL()); - } - - /* ------------------------------------------------------------ */ - /** Construct a resource from a url. - * @param url A URL. - * @return A Resource object. - * @throws IOException Problem accessing URL - */ - public static Resource newResource(URL url) - throws IOException - { - return newResource(url, __defaultUseCaches); - } - - /* ------------------------------------------------------------ */ - /** - * Construct a resource from a url. - * @param url the url for which to make the resource - * @param useCaches true enables URLConnection caching if applicable to the type of resource - * @return - */ - static Resource newResource(URL url, boolean useCaches) - { - if (url==null) - return null; - - String url_string=url.toExternalForm(); - if( url_string.startsWith( "file:")) - { - try - { - FileResource fileResource= new FileResource(url); - return fileResource; - } - catch(Exception e) - { - LOG.debug("EXCEPTION",e); - return new BadResource(url,e.toString()); - } - } - else if( url_string.startsWith( "jar:file:")) - { - return new JarFileResource(url, useCaches); - } - else if( url_string.startsWith( "jar:")) - { - return new JarResource(url, useCaches); - } - - return new URLResource(url,null,useCaches); - } - - - - /* ------------------------------------------------------------ */ - /** Construct a resource from a string. - * @param resource A URL or filename. - * @return A Resource object. - */ - public static Resource newResource(String resource) - throws MalformedURLException, IOException - { - return newResource(resource, __defaultUseCaches); - } - - /* ------------------------------------------------------------ */ - /** Construct a resource from a string. - * @param resource A URL or filename. - * @param useCaches controls URLConnection caching - * @return A Resource object. - */ - public static Resource newResource (String resource, boolean useCaches) - throws MalformedURLException, IOException - { - URL url=null; - try - { - // Try to format as a URL? - url = new URL(resource); - } - catch(MalformedURLException e) - { - if(!resource.startsWith("ftp:") && - !resource.startsWith("file:") && - !resource.startsWith("jar:")) - { - try - { - // It's a file. - if (resource.startsWith("./")) - resource=resource.substring(2); - - File file=new File(resource).getCanonicalFile(); - url=Resource.toURL(file); - - URLConnection connection=url.openConnection(); - connection.setUseCaches(useCaches); - return new FileResource(url,connection,file); - } - catch(Exception e2) - { - LOG.debug("EXCEPTION",e2); - throw e; - } - } - else - { - LOG.warn("Bad Resource: "+resource); - throw e; - } - } - - return newResource(url); - } - - /* ------------------------------------------------------------ */ - public static Resource newResource (File file) - throws MalformedURLException, IOException - { - file = file.getCanonicalFile(); - URL url = Resource.toURL(file); - - URLConnection connection = url.openConnection(); - FileResource fileResource = new FileResource(url, connection, file); - return fileResource; - } - - /* ------------------------------------------------------------ */ - /** Construct a system resource from a string. - * The resource is tried as classloader resource before being - * treated as a normal resource. - * @param resource Resource as string representation - * @return The new Resource - * @throws IOException Problem accessing resource. - */ - public static Resource newSystemResource(String resource) - throws IOException - { - URL url=null; - // Try to format as a URL? - ClassLoader loader=Thread.currentThread().getContextClassLoader(); - if (loader!=null) - { - try - { - url = loader.getResource(resource); - if (url == null && resource.startsWith("/")) - url = loader.getResource(resource.substring(1)); - } - catch (IllegalArgumentException e) - { - // Catches scenario where a bad Windows path like "C:\dev" is - // improperly escaped, which various downstream classloaders - // tend to have a problem with - url = null; - } - } - if (url==null) - { - loader=Resource.class.getClassLoader(); - if (loader!=null) - { - url=loader.getResource(resource); - if (url==null && resource.startsWith("/")) - url=loader.getResource(resource.substring(1)); - } - } - - if (url==null) - { - url=ClassLoader.getSystemResource(resource); - if (url==null && resource.startsWith("/")) - url=ClassLoader.getSystemResource(resource.substring(1)); - } - - if (url==null) - return null; - - return newResource(url); - } - - /* ------------------------------------------------------------ */ - public static boolean isContainedIn (Resource r, Resource containingResource) throws MalformedURLException - { - return r.isContainedIn(containingResource); - } - - /* ------------------------------------------------------------ */ - @Override - protected void finalize() - { - release(); - } - - /* ------------------------------------------------------------ */ - public abstract boolean isContainedIn (Resource r) throws MalformedURLException; - - - /* ------------------------------------------------------------ */ - /** Release any temporary resources held by the resource. - */ - public abstract void release(); - - - /* ------------------------------------------------------------ */ - /** - * Returns true if the respresened resource exists. - */ - public abstract boolean exists(); - - - /* ------------------------------------------------------------ */ - /** - * Returns true if the respresenetd resource is a container/directory. - * If the resource is not a file, resources ending with "/" are - * considered directories. - */ - public abstract boolean isDirectory(); - - /* ------------------------------------------------------------ */ - /** - * Returns the last modified time - */ - public abstract long lastModified(); - - - /* ------------------------------------------------------------ */ - /** - * Return the length of the resource - */ - public abstract long length(); - - - /* ------------------------------------------------------------ */ - /** - * Returns an URL representing the given resource - */ - public abstract URL getURL(); - - /* ------------------------------------------------------------ */ - /** - * Returns an URI representing the given resource - */ - public URI getURI() - { - try - { - return getURL().toURI(); - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - - - /* ------------------------------------------------------------ */ - /** - * Returns an File representing the given resource or NULL if this - * is not possible. - */ - public abstract File getFile() - throws IOException; - - - /* ------------------------------------------------------------ */ - /** - * Returns the name of the resource - */ - public abstract String getName(); - - - /* ------------------------------------------------------------ */ - /** - * Returns an input stream to the resource - */ - public abstract InputStream getInputStream() - throws java.io.IOException; - - /* ------------------------------------------------------------ */ - /** - * Returns an output stream to the resource - */ - public abstract OutputStream getOutputStream() - throws java.io.IOException, SecurityException; - - /* ------------------------------------------------------------ */ - /** - * Deletes the given resource - */ - public abstract boolean delete() - throws SecurityException; - - /* ------------------------------------------------------------ */ - /** - * Rename the given resource - */ - public abstract boolean renameTo( Resource dest) - throws SecurityException; - - /* ------------------------------------------------------------ */ - /** - * Returns a list of resource names contained in the given resource - * The resource names are not URL encoded. - */ - public abstract String[] list(); - - /* ------------------------------------------------------------ */ - /** - * Returns the resource contained inside the current resource with the - * given name. - * @param path The path segment to add, which should be encoded by the - * encode method. - */ - public abstract Resource addPath(String path) - throws IOException,MalformedURLException; - - /* ------------------------------------------------------------ */ - /** Get a resource from withing this resource. - * <p> - * This method is essentially an alias for {@link #addPath(String)}, but without checked exceptions. - * This method satisfied the {@link ResourceFactory} interface. - * @see org.eclipse.jetty.util.resource.ResourceFactory#getResource(java.lang.String) - */ - public Resource getResource(String path) - { - try - { - return addPath(path); - } - catch(Exception e) - { - LOG.debug("",e); - return null; - } - } - - /* ------------------------------------------------------------ */ - /** Encode according to this resource type. - * The default implementation calls URI.encodePath(uri) - * @param uri - * @return String encoded for this resource type. - */ - public String encode(String uri) - { - return URIUtil.encodePath(uri); - } - - /* ------------------------------------------------------------ */ - public Object getAssociate() - { - return _associate; - } - - /* ------------------------------------------------------------ */ - public void setAssociate(Object o) - { - _associate=o; - } - - /* ------------------------------------------------------------ */ - /** - * @return The canonical Alias of this resource or null if none. - */ - public URL getAlias() - { - return null; - } - - /* ------------------------------------------------------------ */ - /** Get the resource list as a HTML directory listing. - * @param base The base URL - * @param parent True if the parent directory should be included - * @return String of HTML - */ - public String getListHTML(String base,boolean parent) - throws IOException - { - base=URIUtil.canonicalPath(base); - if (base==null || !isDirectory()) - return null; - - String[] ls = list(); - if (ls==null) - return null; - Arrays.sort(ls); - - String decodedBase = URIUtil.decodePath(base); - String title = "Directory: "+deTag(decodedBase); - - StringBuilder buf=new StringBuilder(4096); - buf.append("<HTML><HEAD>"); - buf.append("<LINK HREF=\"").append("jetty-dir.css").append("\" REL=\"stylesheet\" TYPE=\"text/css\"/><TITLE>"); - buf.append(title); - buf.append("</TITLE></HEAD><BODY>\n<H1>"); - buf.append(title); - buf.append("</H1>\n<TABLE BORDER=0>\n"); - - if (parent) - { - buf.append("<TR><TD><A HREF=\""); - buf.append(URIUtil.addPaths(base,"../")); - buf.append("\">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n"); - } - - String encodedBase = hrefEncodeURI(base); - - DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM, - DateFormat.MEDIUM); - for (int i=0 ; i< ls.length ; i++) - { - Resource item = addPath(ls[i]); - - buf.append("\n<TR><TD><A HREF=\""); - String path=URIUtil.addPaths(encodedBase,URIUtil.encodePath(ls[i])); - - buf.append(path); - - if (item.isDirectory() && !path.endsWith("/")) - buf.append("/"); - - // URIUtil.encodePath(buf,path); - buf.append("\">"); - buf.append(deTag(ls[i])); - buf.append(" "); - buf.append("</A></TD><TD ALIGN=right>"); - buf.append(item.length()); - buf.append(" bytes </TD><TD>"); - buf.append(dfmt.format(new Date(item.lastModified()))); - buf.append("</TD></TR>"); - } - buf.append("</TABLE>\n"); - buf.append("</BODY></HTML>\n"); - - return buf.toString(); - } - - /** - * Encode any characters that could break the URI string in an HREF. - * Such as <a href="/path/to;<script>Window.alert("XSS"+'%20'+"here");</script>">Link</a> - * - * The above example would parse incorrectly on various browsers as the "<" or '"' characters - * would end the href attribute value string prematurely. - * - * @param raw the raw text to encode. - * @return the defanged text. - */ - private static String hrefEncodeURI(String raw) - { - StringBuffer buf = null; - - loop: - for (int i=0;i<raw.length();i++) - { - char c=raw.charAt(i); - switch(c) - { - case '\'': - case '"': - case '<': - case '>': - buf=new StringBuffer(raw.length()<<1); - break loop; - } - } - if (buf==null) - return raw; - - for (int i=0;i<raw.length();i++) - { - char c=raw.charAt(i); - switch(c) - { - case '"': - buf.append("%22"); - continue; - case '\'': - buf.append("%27"); - continue; - case '<': - buf.append("%3C"); - continue; - case '>': - buf.append("%3E"); - continue; - default: - buf.append(c); - continue; - } - } - - return buf.toString(); - } - - private static String deTag(String raw) - { - return StringUtil.replace( StringUtil.replace(raw,"<","<"), ">", ">"); - } - - /* ------------------------------------------------------------ */ - /** - * @param out - * @param start First byte to write - * @param count Bytes to write or -1 for all of them. - */ - public void writeTo(OutputStream out,long start,long count) - throws IOException - { - InputStream in = getInputStream(); - try - { - in.skip(start); - if (count<0) - IO.copy(in,out); - else - IO.copy(in,out,count); - } - finally - { - in.close(); - } - } - - /* ------------------------------------------------------------ */ - public void copyTo(File destination) - throws IOException - { - if (destination.exists()) - throw new IllegalArgumentException(destination+" exists"); - writeTo(new FileOutputStream(destination),0,-1); - } - - /* ------------------------------------------------------------ */ - /** Generate a properly encoded URL from a {@link File} instance. - * @param file Target file. - * @return URL of the target file. - * @throws MalformedURLException - */ - public static URL toURL(File file) throws MalformedURLException - { - return file.toURI().toURL(); - } -}
--- a/src/org/eclipse/jetty/util/resource/ResourceCollection.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,482 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.StringTokenizer; - -import org.eclipse.jetty.util.URIUtil; - -/** - * A collection of resources (dirs). - * Allows webapps to have multiple (static) sources. - * The first resource in the collection is the main resource. - * If a resource is not found in the main resource, it looks it up in - * the order the resources were constructed. - * - * - * - */ -public class ResourceCollection extends Resource -{ - private Resource[] _resources; - - /* ------------------------------------------------------------ */ - /** - * Instantiates an empty resource collection. - * - * This constructor is used when configuring jetty-maven-plugin. - */ - public ResourceCollection() - { - _resources = new Resource[0]; - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new resource collection. - * - * @param resources the resources to be added to collection - */ - public ResourceCollection(Resource... resources) - { - List<Resource> list = new ArrayList<Resource>(); - for (Resource r : resources) - { - if (r==null) - continue; - if (r instanceof ResourceCollection) - { - for (Resource r2 : ((ResourceCollection)r).getResources()) - list.add(r2); - } - else - list.add(r); - } - _resources = list.toArray(new Resource[list.size()]); - for(Resource r : _resources) - { - if(!r.exists() || !r.isDirectory()) - throw new IllegalArgumentException(r + " is not an existing directory."); - } - } - - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new resource collection. - * - * @param resources the resource strings to be added to collection - */ - public ResourceCollection(String[] resources) - { - _resources = new Resource[resources.length]; - try - { - for(int i=0; i<resources.length; i++) - { - _resources[i] = Resource.newResource(resources[i]); - if(!_resources[i].exists() || !_resources[i].isDirectory()) - throw new IllegalArgumentException(_resources[i] + " is not an existing directory."); - } - } - catch(IllegalArgumentException e) - { - throw e; - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new resource collection. - * - * @param csvResources the string containing comma-separated resource strings - */ - public ResourceCollection(String csvResources) - { - setResourcesAsCSV(csvResources); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves the resource collection's resources. - * - * @return the resource array - */ - public Resource[] getResources() - { - return _resources; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the resource collection's resources. - * - * @param resources the new resource array - */ - public void setResources(Resource[] resources) - { - _resources = resources != null ? resources : new Resource[0]; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the resources as string of comma-separated values. - * This method should be used when configuring jetty-maven-plugin. - * - * @param csvResources the comma-separated string containing - * one or more resource strings. - */ - public void setResourcesAsCSV(String csvResources) - { - StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;"); - int len = tokenizer.countTokens(); - if(len==0) - { - throw new IllegalArgumentException("ResourceCollection@setResourcesAsCSV(String) " + - " argument must be a string containing one or more comma-separated resource strings."); - } - - _resources = new Resource[len]; - try - { - for(int i=0; tokenizer.hasMoreTokens(); i++) - { - _resources[i] = Resource.newResource(tokenizer.nextToken().trim()); - if(!_resources[i].exists() || !_resources[i].isDirectory()) - throw new IllegalArgumentException(_resources[i] + " is not an existing directory."); - } - } - catch(Exception e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - /** - * @param path The path segment to add - * @return The contained resource (found first) in the collection of resources - */ - @Override - public Resource addPath(String path) throws IOException, MalformedURLException - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - if(path==null) - throw new MalformedURLException(); - - if(path.length()==0 || "/".equals(path)) - return this; - - Resource resource=null; - ArrayList<Resource> resources = null; - int i=0; - for(; i<_resources.length; i++) - { - resource = _resources[i].addPath(path); - if (resource.exists()) - { - if (resource.isDirectory()) - break; - return resource; - } - } - - for(i++; i<_resources.length; i++) - { - Resource r = _resources[i].addPath(path); - if (r.exists() && r.isDirectory()) - { - if (resource!=null) - { - resources = new ArrayList<Resource>(); - resources.add(resource); - resource=null; - } - resources.add(r); - } - } - - if (resource!=null) - return resource; - if (resources!=null) - return new ResourceCollection(resources.toArray(new Resource[resources.size()])); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @param path - * @return the resource(file) if found, returns a list of resource dirs if its a dir, else null. - * @throws IOException - * @throws MalformedURLException - */ - protected Object findResource(String path) throws IOException, MalformedURLException - { - Resource resource=null; - ArrayList<Resource> resources = null; - int i=0; - for(; i<_resources.length; i++) - { - resource = _resources[i].addPath(path); - if (resource.exists()) - { - if (resource.isDirectory()) - break; - - return resource; - } - } - - for(i++; i<_resources.length; i++) - { - Resource r = _resources[i].addPath(path); - if (r.exists() && r.isDirectory()) - { - if (resource!=null) - { - resources = new ArrayList<Resource>(); - resources.add(resource); - } - resources.add(r); - } - } - - if (resource!=null) - return resource; - if (resources!=null) - return resources; - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean delete() throws SecurityException - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean exists() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - return true; - } - - /* ------------------------------------------------------------ */ - @Override - public File getFile() throws IOException - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - File f = r.getFile(); - if(f!=null) - return f; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public InputStream getInputStream() throws IOException - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - InputStream is = r.getInputStream(); - if(is!=null) - return is; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public String getName() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - String name = r.getName(); - if(name!=null) - return name; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public OutputStream getOutputStream() throws IOException, SecurityException - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - OutputStream os = r.getOutputStream(); - if(os!=null) - return os; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public URL getURL() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - URL url = r.getURL(); - if(url!=null) - return url; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isDirectory() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - return true; - } - - /* ------------------------------------------------------------ */ - @Override - public long lastModified() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - { - long lm = r.lastModified(); - if (lm!=-1) - return lm; - } - return -1; - } - - /* ------------------------------------------------------------ */ - @Override - public long length() - { - return -1; - } - - /* ------------------------------------------------------------ */ - /** - * @return The list of resource names(merged) contained in the collection of resources. - */ - @Override - public String[] list() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - HashSet<String> set = new HashSet<String>(); - for(Resource r : _resources) - { - for(String s : r.list()) - set.add(s); - } - String[] result=set.toArray(new String[set.size()]); - Arrays.sort(result); - return result; - } - - /* ------------------------------------------------------------ */ - @Override - public void release() - { - if(_resources==null) - throw new IllegalStateException("*resources* not set."); - - for(Resource r : _resources) - r.release(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean renameTo(Resource dest) throws SecurityException - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - @Override - public void copyTo(File destination) - throws IOException - { - for (int r=_resources.length;r-->0;) - _resources[r].copyTo(destination); - } - - /* ------------------------------------------------------------ */ - /** - * @return the list of resources separated by a path separator - */ - @Override - public String toString() - { - if(_resources==null) - return "[]"; - - return String.valueOf(Arrays.asList(_resources)); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isContainedIn(Resource r) throws MalformedURLException - { - // TODO could look at implementing the semantic of is this collection a subset of the Resource r? - return false; - } - -}
--- a/src/org/eclipse/jetty/util/resource/ResourceFactory.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - - -/* ------------------------------------------------------------ */ -/** ResourceFactory. - */ -public interface ResourceFactory -{ - - /* ------------------------------------------------------------ */ - /** Get a resource for a path. - * @param path The path to the resource - * @return The resource or null - */ - Resource getResource(String path); -}
--- a/src/org/eclipse/jetty/util/resource/URLResource.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.security.Permission; - -import org.eclipse.jetty.util.URIUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** Abstract resource class. - */ -public class URLResource extends Resource -{ - private static final Logger LOG = LoggerFactory.getLogger(URLResource.class); - protected URL _url; - protected String _urlString; - - protected URLConnection _connection; - protected InputStream _in=null; - transient boolean _useCaches = Resource.__defaultUseCaches; - - /* ------------------------------------------------------------ */ - protected URLResource(URL url, URLConnection connection) - { - _url = url; - _urlString=_url.toString(); - _connection=connection; - } - - /* ------------------------------------------------------------ */ - protected URLResource (URL url, URLConnection connection, boolean useCaches) - { - this (url, connection); - _useCaches = useCaches; - } - - /* ------------------------------------------------------------ */ - protected synchronized boolean checkConnection() - { - if (_connection==null) - { - try{ - _connection=_url.openConnection(); - _connection.setUseCaches(_useCaches); - } - catch(IOException e) - { - LOG.trace("",e); - } - } - return _connection!=null; - } - - /* ------------------------------------------------------------ */ - /** Release any resources held by the resource. - */ - @Override - public synchronized void release() - { - if (_in!=null) - { - try{_in.close();}catch(IOException e){LOG.trace("",e);} - _in=null; - } - - if (_connection!=null) - _connection=null; - } - - /* ------------------------------------------------------------ */ - /** - * Returns true if the represented resource exists. - */ - @Override - public boolean exists() - { - try - { - synchronized(this) - { - if (checkConnection() && _in==null ) - _in = _connection.getInputStream(); - } - } - catch (IOException e) - { - LOG.trace("",e); - } - return _in!=null; - } - - /* ------------------------------------------------------------ */ - /** - * Returns true if the respresenetd resource is a container/directory. - * If the resource is not a file, resources ending with "/" are - * considered directories. - */ - @Override - public boolean isDirectory() - { - return exists() && _url.toString().endsWith("/"); - } - - - /* ------------------------------------------------------------ */ - /** - * Returns the last modified time - */ - @Override - public long lastModified() - { - if (checkConnection()) - return _connection.getLastModified(); - return -1; - } - - - /* ------------------------------------------------------------ */ - /** - * Return the length of the resource - */ - @Override - public long length() - { - if (checkConnection()) - return _connection.getContentLength(); - return -1; - } - - /* ------------------------------------------------------------ */ - /** - * Returns an URL representing the given resource - */ - @Override - public URL getURL() - { - return _url; - } - - /* ------------------------------------------------------------ */ - /** - * Returns an File representing the given resource or NULL if this - * is not possible. - */ - @Override - public File getFile() - throws IOException - { - // Try the permission hack - if (checkConnection()) - { - Permission perm = _connection.getPermission(); - if (perm instanceof java.io.FilePermission) - return new File(perm.getName()); - } - - // Try the URL file arg - try {return new File(_url.getFile());} - catch(Exception e) {LOG.trace("",e);} - - // Don't know the file - return null; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the name of the resource - */ - @Override - public String getName() - { - return _url.toExternalForm(); - } - - /* ------------------------------------------------------------ */ - /** - * Returns an input stream to the resource - */ - @Override - public synchronized InputStream getInputStream() - throws java.io.IOException - { - if (!checkConnection()) - throw new IOException( "Invalid resource"); - - try - { - if( _in != null) - { - InputStream in = _in; - _in=null; - return in; - } - return _connection.getInputStream(); - } - finally - { - _connection=null; - } - } - - - /* ------------------------------------------------------------ */ - /** - * Returns an output stream to the resource - */ - @Override - public OutputStream getOutputStream() - throws java.io.IOException, SecurityException - { - throw new IOException( "Output not supported"); - } - - /* ------------------------------------------------------------ */ - /** - * Deletes the given resource - */ - @Override - public boolean delete() - throws SecurityException - { - throw new SecurityException( "Delete not supported"); - } - - /* ------------------------------------------------------------ */ - /** - * Rename the given resource - */ - @Override - public boolean renameTo( Resource dest) - throws SecurityException - { - throw new SecurityException( "RenameTo not supported"); - } - - /* ------------------------------------------------------------ */ - /** - * Returns a list of resource names contained in the given resource - */ - @Override - public String[] list() - { - return null; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the resource contained inside the current resource with the - * given name - */ - @Override - public Resource addPath(String path) - throws IOException,MalformedURLException - { - if (path==null) - return null; - - path = URIUtil.canonicalPath(path); - - return newResource(URIUtil.addPaths(_url.toExternalForm(),path)); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _urlString; - } - - /* ------------------------------------------------------------ */ - @Override - public int hashCode() - { - return _urlString.hashCode(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean equals( Object o) - { - return o instanceof URLResource && _urlString.equals(((URLResource)o)._urlString); - } - - /* ------------------------------------------------------------ */ - public boolean getUseCaches () - { - return _useCaches; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isContainedIn (Resource containingResource) throws MalformedURLException - { - return false; //TODO check this! - } -}
--- a/src/org/eclipse/jetty/util/security/CertificateUtils.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.io.InputStream; -import java.security.KeyStore; -import java.security.cert.CRL; -import java.security.cert.CertificateFactory; -import java.util.Collection; - -import org.eclipse.jetty.util.resource.Resource; - -public class CertificateUtils -{ - /* ------------------------------------------------------------ */ - public static KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception - { - KeyStore keystore = null; - - if (storeStream != null || storePath != null) - { - InputStream inStream = storeStream; - try - { - if (inStream == null) - { - inStream = Resource.newResource(storePath).getInputStream(); - } - - if (storeProvider != null) - { - keystore = KeyStore.getInstance(storeType, storeProvider); - } - else - { - keystore = KeyStore.getInstance(storeType); - } - - keystore.load(inStream, storePassword == null ? null : storePassword.toCharArray()); - } - finally - { - if (inStream != null) - { - inStream.close(); - } - } - } - - return keystore; - } - - /* ------------------------------------------------------------ */ - public static Collection<? extends CRL> loadCRL(String crlPath) throws Exception - { - Collection<? extends CRL> crlList = null; - - if (crlPath != null) - { - InputStream in = null; - try - { - in = Resource.newResource(crlPath).getInputStream(); - crlList = CertificateFactory.getInstance("X.509").generateCRLs(in); - } - finally - { - if (in != null) - { - in.close(); - } - } - } - - return crlList; - } - -}
--- a/src/org/eclipse/jetty/util/security/CertificateValidator.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,343 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.security.GeneralSecurityException; -import java.security.InvalidParameterException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.Security; -import java.security.cert.CRL; -import java.security.cert.CertPathBuilder; -import java.security.cert.CertPathBuilderResult; -import java.security.cert.CertPathValidator; -import java.security.cert.CertStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.concurrent.atomic.AtomicLong; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Convenience class to handle validation of certificates, aliases and keystores - * - * Allows specifying Certificate Revocation List (CRL), as well as enabling - * CRL Distribution Points Protocol (CRLDP) certificate extension support, - * and also enabling On-Line Certificate Status Protocol (OCSP) support. - * - * IMPORTANT: at least one of the above mechanisms *MUST* be configured and - * operational, otherwise certificate validation *WILL FAIL* unconditionally. - */ -public class CertificateValidator -{ - private static final Logger LOG = LoggerFactory.getLogger(CertificateValidator.class); - private static AtomicLong __aliasCount = new AtomicLong(); - - private KeyStore _trustStore; - private Collection<? extends CRL> _crls; - - /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */ - private int _maxCertPathLength = -1; - /** CRL Distribution Points (CRLDP) support */ - private boolean _enableCRLDP = false; - /** On-Line Certificate Status Protocol (OCSP) support */ - private boolean _enableOCSP = false; - /** Location of OCSP Responder */ - private String _ocspResponderURL; - - /** - * creates an instance of the certificate validator - * - * @param trustStore - * @param crls - */ - public CertificateValidator(KeyStore trustStore, Collection<? extends CRL> crls) - { - if (trustStore == null) - { - throw new InvalidParameterException("TrustStore must be specified for CertificateValidator."); - } - - _trustStore = trustStore; - _crls = crls; - } - - /** - * validates all aliases inside of a given keystore - * - * @param keyStore - * @throws CertificateException - */ - public void validate( KeyStore keyStore ) throws CertificateException - { - try - { - Enumeration<String> aliases = keyStore.aliases(); - - for ( ; aliases.hasMoreElements(); ) - { - String alias = aliases.nextElement(); - - validate(keyStore,alias); - } - - } - catch ( KeyStoreException kse ) - { - throw new CertificateException("Unable to retrieve aliases from keystore", kse); - } - } - - - /** - * validates a specific alias inside of the keystore being passed in - * - * @param keyStore - * @param keyAlias - * @return the keyAlias if valid - * @throws CertificateException - */ - public String validate(KeyStore keyStore, String keyAlias) throws CertificateException - { - String result = null; - - if (keyAlias != null) - { - try - { - validate(keyStore, keyStore.getCertificate(keyAlias)); - } - catch (KeyStoreException kse) - { - LOG.debug("",kse); - throw new CertificateException("Unable to validate certificate" + - " for alias [" + keyAlias + "]: " + kse.getMessage(), kse); - } - result = keyAlias; - } - - return result; - } - - /** - * validates a specific certificate inside of the keystore being passed in - * - * @param keyStore - * @param cert - * @throws CertificateException - */ - public void validate(KeyStore keyStore, Certificate cert) throws CertificateException - { - Certificate[] certChain = null; - - if (cert != null && cert instanceof X509Certificate) - { - ((X509Certificate)cert).checkValidity(); - - String certAlias = null; - try - { - if (keyStore == null) - { - throw new InvalidParameterException("Keystore cannot be null"); - } - - certAlias = keyStore.getCertificateAlias((X509Certificate)cert); - if (certAlias == null) - { - certAlias = "JETTY" + String.format("%016X",__aliasCount.incrementAndGet()); - keyStore.setCertificateEntry(certAlias, cert); - } - - certChain = keyStore.getCertificateChain(certAlias); - if (certChain == null || certChain.length == 0) - { - throw new IllegalStateException("Unable to retrieve certificate chain"); - } - } - catch (KeyStoreException kse) - { - LOG.debug("",kse); - throw new CertificateException("Unable to validate certificate" + - (certAlias == null ? "":" for alias [" +certAlias + "]") + ": " + kse.getMessage(), kse); - } - - validate(certChain); - } - } - - public void validate(Certificate[] certChain) throws CertificateException - { - try - { - ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(); - for (Certificate item : certChain) - { - if (item == null) - continue; - - if (!(item instanceof X509Certificate)) - { - throw new IllegalStateException("Invalid certificate type in chain"); - } - - certList.add((X509Certificate)item); - } - - if (certList.isEmpty()) - { - throw new IllegalStateException("Invalid certificate chain"); - - } - - X509CertSelector certSelect = new X509CertSelector(); - certSelect.setCertificate(certList.get(0)); - - // Configure certification path builder parameters - PKIXBuilderParameters pbParams = new PKIXBuilderParameters(_trustStore, certSelect); - pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList))); - - // Set maximum certification path length - pbParams.setMaxPathLength(_maxCertPathLength); - - // Enable revocation checking - pbParams.setRevocationEnabled(true); - - // Set static Certificate Revocation List - if (_crls != null && !_crls.isEmpty()) - { - pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls))); - } - - // Enable On-Line Certificate Status Protocol (OCSP) support - if (_enableOCSP) - { - Security.setProperty("ocsp.enable","true"); - } - // Enable Certificate Revocation List Distribution Points (CRLDP) support - if (_enableCRLDP) - { - System.setProperty("com.sun.security.enableCRLDP","true"); - } - - // Build certification path - CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); - - // Validate certification path - CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams); - } - catch (GeneralSecurityException gse) - { - LOG.debug("",gse); - throw new CertificateException("Unable to validate certificate: " + gse.getMessage(), gse); - } - } - - public KeyStore getTrustStore() - { - return _trustStore; - } - - public Collection<? extends CRL> getCrls() - { - return _crls; - } - - /** - * @return Maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public int getMaxCertPathLength() - { - return _maxCertPathLength; - } - - /* ------------------------------------------------------------ */ - /** - * @param maxCertPathLength - * maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public void setMaxCertPathLength(int maxCertPathLength) - { - _maxCertPathLength = maxCertPathLength; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if CRL Distribution Points support is enabled - */ - public boolean isEnableCRLDP() - { - return _enableCRLDP; - } - - /* ------------------------------------------------------------ */ - /** Enables CRL Distribution Points Support - * @param enableCRLDP true - turn on, false - turns off - */ - public void setEnableCRLDP(boolean enableCRLDP) - { - _enableCRLDP = enableCRLDP; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if On-Line Certificate Status Protocol support is enabled - */ - public boolean isEnableOCSP() - { - return _enableOCSP; - } - - /* ------------------------------------------------------------ */ - /** Enables On-Line Certificate Status Protocol support - * @param enableOCSP true - turn on, false - turn off - */ - public void setEnableOCSP(boolean enableOCSP) - { - _enableOCSP = enableOCSP; - } - - /* ------------------------------------------------------------ */ - /** - * @return Location of the OCSP Responder - */ - public String getOcspResponderURL() - { - return _ocspResponderURL; - } - - /* ------------------------------------------------------------ */ - /** Set the location of the OCSP Responder. - * @param ocspResponderURL location of the OCSP Responder - */ - public void setOcspResponderURL(String ocspResponderURL) - { - _ocspResponderURL = ocspResponderURL; - } -}
--- a/src/org/eclipse/jetty/util/security/Constraint.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,226 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.io.Serializable; -import java.util.Arrays; - -/* ------------------------------------------------------------ */ -/** - * Describe an auth and/or data constraint. - * - * - */ -public class Constraint implements Cloneable, Serializable -{ - /* ------------------------------------------------------------ */ - public final static String __BASIC_AUTH = "BASIC"; - - public final static String __FORM_AUTH = "FORM"; - - public final static String __DIGEST_AUTH = "DIGEST"; - - public final static String __CERT_AUTH = "CLIENT_CERT"; - - public final static String __CERT_AUTH2 = "CLIENT-CERT"; - - public final static String __SPNEGO_AUTH = "SPNEGO"; - - public final static String __NEGOTIATE_AUTH = "NEGOTIATE"; - - public static boolean validateMethod (String method) - { - if (method == null) - return false; - method = method.trim(); - return (method.equals(__FORM_AUTH) - || method.equals(__BASIC_AUTH) - || method.equals (__DIGEST_AUTH) - || method.equals (__CERT_AUTH) - || method.equals(__CERT_AUTH2) - || method.equals(__SPNEGO_AUTH) - || method.equals(__NEGOTIATE_AUTH)); - } - - /* ------------------------------------------------------------ */ - public final static int DC_UNSET = -1, DC_NONE = 0, DC_INTEGRAL = 1, DC_CONFIDENTIAL = 2, DC_FORBIDDEN = 3; - - /* ------------------------------------------------------------ */ - public final static String NONE = "NONE"; - - public final static String ANY_ROLE = "*"; - - /* ------------------------------------------------------------ */ - private String _name; - - private String[] _roles; - - private int _dataConstraint = DC_UNSET; - - private boolean _anyRole = false; - - private boolean _authenticate = false; - - /* ------------------------------------------------------------ */ - /** - * Constructor. - */ - public Constraint() - { - } - - /* ------------------------------------------------------------ */ - /** - * Conveniance Constructor. - * - * @param name - * @param role - */ - public Constraint(String name, String role) - { - setName(name); - setRoles(new String[] { role }); - } - - /* ------------------------------------------------------------ */ - @Override - public Object clone() throws CloneNotSupportedException - { - return super.clone(); - } - - /* ------------------------------------------------------------ */ - /** - * @param name - */ - public void setName(String name) - { - _name = name; - } - - /* ------------------------------------------------------------ */ - public void setRoles(String[] roles) - { - _roles = roles; - _anyRole = false; - if (roles != null) - for (int i = roles.length; !_anyRole && i-- > 0;) - _anyRole |= ANY_ROLE.equals(roles[i]); - } - - /* ------------------------------------------------------------ */ - /** - * @return True if any user role is permitted. - */ - public boolean isAnyRole() - { - return _anyRole; - } - - /* ------------------------------------------------------------ */ - /** - * @return List of roles for this constraint. - */ - public String[] getRoles() - { - return _roles; - } - - /* ------------------------------------------------------------ */ - /** - * @param role - * @return True if the constraint contains the role. - */ - public boolean hasRole(String role) - { - if (_anyRole) return true; - if (_roles != null) for (int i = _roles.length; i-- > 0;) - if (role.equals(_roles[i])) return true; - return false; - } - - /* ------------------------------------------------------------ */ - /** - * @param authenticate True if users must be authenticated - */ - public void setAuthenticate(boolean authenticate) - { - _authenticate = authenticate; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if the constraint requires request authentication - */ - public boolean getAuthenticate() - { - return _authenticate; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if authentication required but no roles set - */ - public boolean isForbidden() - { - return _authenticate && !_anyRole && (_roles == null || _roles.length == 0); - } - - /* ------------------------------------------------------------ */ - /** - * @param c Data constrain indicator: 0=DC+NONE, 1=DC_INTEGRAL & - * 2=DC_CONFIDENTIAL - */ - public void setDataConstraint(int c) - { - if (c < 0 || c > DC_CONFIDENTIAL) throw new IllegalArgumentException("Constraint out of range"); - _dataConstraint = c; - } - - /* ------------------------------------------------------------ */ - /** - * @return Data constrain indicator: 0=DC+NONE, 1=DC_INTEGRAL & - * 2=DC_CONFIDENTIAL - */ - public int getDataConstraint() - { - return _dataConstraint; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if a data constraint has been set. - */ - public boolean hasDataConstraint() - { - return _dataConstraint >= DC_NONE; - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return "SC{" + _name - + "," - + (_anyRole ? "*" : (_roles == null ? "-" : Arrays.asList(_roles).toString())) - + "," - + (_dataConstraint == DC_UNSET ? "DC_UNSET}" : (_dataConstraint == DC_NONE ? "NONE}" : (_dataConstraint == DC_INTEGRAL ? "INTEGRAL}" : "CONFIDENTIAL}"))); - } - -}
--- a/src/org/eclipse/jetty/util/security/Credential.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.io.Serializable; -import java.security.MessageDigest; - -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.TypeUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * Credentials. The Credential class represents an abstract mechanism for - * checking authentication credentials. A credential instance either represents - * a secret, or some data that could only be derived from knowing the secret. - * <p> - * Often a Credential is related to a Password via a one way algorithm, so while - * a Password itself is a Credential, a UnixCrypt or MD5 digest of a a password - * is only a credential that can be checked against the password. - * <p> - * This class includes an implementation for unix Crypt an MD5 digest. - * - * @see Password - * - */ -public abstract class Credential implements Serializable -{ - private static final Logger LOG = LoggerFactory.getLogger(Credential.class); - - private static final long serialVersionUID = -7760551052768181572L; - - /* ------------------------------------------------------------ */ - /** - * Check a credential - * - * @param credentials The credential to check against. This may either be - * another Credential object, a Password object or a String - * which is interpreted by this credential. - * @return True if the credentials indicated that the shared secret is known - * to both this Credential and the passed credential. - */ - public abstract boolean check(Object credentials); - - /* ------------------------------------------------------------ */ - /** - * Get a credential from a String. If the credential String starts with a - * known Credential type (eg "CRYPT:" or "MD5:" ) then a Credential of that - * type is returned. Else the credential is assumed to be a Password. - * - * @param credential String representation of the credential - * @return A Credential or Password instance. - */ - public static Credential getCredential(String credential) - { - if (credential.startsWith(Crypt.__TYPE)) return new Crypt(credential); - if (credential.startsWith(MD5.__TYPE)) return new MD5(credential); - - return new Password(credential); - } - - /* ------------------------------------------------------------ */ - /** - * Unix Crypt Credentials - */ - public static class Crypt extends Credential - { - private static final long serialVersionUID = -2027792997664744210L; - - public static final String __TYPE = "CRYPT:"; - - private final String _cooked; - - Crypt(String cooked) - { - _cooked = cooked.startsWith(Crypt.__TYPE) ? cooked.substring(__TYPE.length()) : cooked; - } - - @Override - public boolean check(Object credentials) - { - if (credentials instanceof char[]) - credentials=new String((char[])credentials); - if (!(credentials instanceof String) && !(credentials instanceof Password)) - LOG.warn("Can't check " + credentials.getClass() + " against CRYPT"); - - String passwd = credentials.toString(); - return _cooked.equals(UnixCrypt.crypt(passwd, _cooked)); - } - - public static String crypt(String user, String pw) - { - return "CRYPT:" + UnixCrypt.crypt(pw, user); - } - } - - /* ------------------------------------------------------------ */ - /** - * MD5 Credentials - */ - public static class MD5 extends Credential - { - private static final long serialVersionUID = 5533846540822684240L; - - public static final String __TYPE = "MD5:"; - - public static final Object __md5Lock = new Object(); - - private static MessageDigest __md; - - private final byte[] _digest; - - /* ------------------------------------------------------------ */ - MD5(String digest) - { - digest = digest.startsWith(__TYPE) ? digest.substring(__TYPE.length()) : digest; - _digest = TypeUtil.parseBytes(digest, 16); - } - - /* ------------------------------------------------------------ */ - public byte[] getDigest() - { - return _digest; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean check(Object credentials) - { - try - { - byte[] digest = null; - - if (credentials instanceof char[]) - credentials=new String((char[])credentials); - if (credentials instanceof Password || credentials instanceof String) - { - synchronized (__md5Lock) - { - if (__md == null) __md = MessageDigest.getInstance("MD5"); - __md.reset(); - __md.update(credentials.toString().getBytes(StringUtil.__ISO_8859_1)); - digest = __md.digest(); - } - if (digest == null || digest.length != _digest.length) return false; - for (int i = 0; i < digest.length; i++) - if (digest[i] != _digest[i]) return false; - return true; - } - else if (credentials instanceof MD5) - { - MD5 md5 = (MD5) credentials; - if (_digest.length != md5._digest.length) return false; - for (int i = 0; i < _digest.length; i++) - if (_digest[i] != md5._digest[i]) return false; - return true; - } - else if (credentials instanceof Credential) - { - // Allow credential to attempt check - i.e. this'll work - // for DigestAuthModule$Digest credentials - return ((Credential) credentials).check(this); - } - else - { - LOG.warn("Can't check " + credentials.getClass() + " against MD5"); - return false; - } - } - catch (Exception e) - { - LOG.warn("",e); - return false; - } - } - - /* ------------------------------------------------------------ */ - public static String digest(String password) - { - try - { - byte[] digest; - synchronized (__md5Lock) - { - if (__md == null) - { - try - { - __md = MessageDigest.getInstance("MD5"); - } - catch (Exception e) - { - LOG.warn("",e); - return null; - } - } - - __md.reset(); - __md.update(password.getBytes(StringUtil.__ISO_8859_1)); - digest = __md.digest(); - } - - return __TYPE + TypeUtil.toString(digest, 16); - } - catch (Exception e) - { - LOG.warn("",e); - return null; - } - } - } -}
--- a/src/org/eclipse/jetty/util/security/Password.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.io.IOException; -import java.util.Arrays; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/* ------------------------------------------------------------ */ -/** - * 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 - * be passed to another system). They are not secure, but prevent casual - * observation. - * <p> - * Passwords that begin with CRYPT: are oneway encrypted with UnixCrypt. The - * real password cannot be retrieved, but comparisons can be made to other - * passwords. A Crypt can be generated by running org.eclipse.util.UnixCrypt as - * a main class, passing password and then the username. Checksum passwords are - * 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 -{ - private static final Logger LOG = LoggerFactory.getLogger(Password.class); - - private static final long serialVersionUID = 5062906681431569445L; - - public static final String __OBFUSCATE = "OBF:"; - - private String _pw; - - /* ------------------------------------------------------------ */ - /** - * Constructor. - * - * @param password The String password. - */ - public Password(String password) - { - _pw = password; - - // expand password - while (_pw != null && _pw.startsWith(__OBFUSCATE)) - _pw = deobfuscate(_pw); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _pw; - } - - /* ------------------------------------------------------------ */ - public String toStarString() - { - return "*****************************************************".substring(0, _pw.length()); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean check(Object credentials) - { - if (this == credentials) return true; - - if (credentials instanceof Password) return credentials.equals(_pw); - - if (credentials instanceof String) return credentials.equals(_pw); - - if (credentials instanceof char[]) return Arrays.equals(_pw.toCharArray(), (char[]) credentials); - - if (credentials instanceof Credential) return ((Credential) credentials).check(_pw); - - return false; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - - if (null == o) - return false; - - if (o instanceof Password) - { - Password p = (Password) o; - //noinspection StringEquality - return p._pw == _pw || (null != _pw && _pw.equals(p._pw)); - } - - if (o instanceof String) - return o.equals(_pw); - - return false; - } - - /* ------------------------------------------------------------ */ - @Override - public int hashCode() - { - return null == _pw ? super.hashCode() : _pw.hashCode(); - } - - /* ------------------------------------------------------------ */ - public static String obfuscate(String s) - { - StringBuilder buf = new StringBuilder(); - byte[] b = s.getBytes(); - - buf.append(__OBFUSCATE); - for (int i = 0; i < b.length; i++) - { - byte b1 = b[i]; - byte b2 = b[s.length() - (i + 1)]; - int i1 = 127 + b1 + b2; - int i2 = 127 + b1 - b2; - int i0 = i1 * 256 + i2; - String x = Integer.toString(i0, 36); - - switch (x.length()) - { - case 1: - buf.append('0'); - buf.append('0'); - buf.append('0'); - buf.append(x); - break; - case 2: - buf.append('0'); - buf.append('0'); - buf.append(x); - break; - case 3: - buf.append('0'); - buf.append(x); - break; - default: - buf.append(x); - break; - } - } - return buf.toString(); - - } - - /* ------------------------------------------------------------ */ - public static String deobfuscate(String s) - { - if (s.startsWith(__OBFUSCATE)) s = s.substring(4); - - byte[] b = new byte[s.length() / 2]; - int l = 0; - for (int i = 0; i < s.length(); i += 4) - { - String x = s.substring(i, i + 4); - int i0 = Integer.parseInt(x, 36); - int i1 = (i0 / 256); - int i2 = (i0 % 256); - b[l++] = (byte) ((i1 + i2 - 254) / 2); - } - - return new String(b, 0, l); - } - - /* ------------------------------------------------------------ */ - /** - * Get a password. A password is obtained by trying - * <UL> - * <LI>Calling <Code>System.getProperty(realm,dft)</Code> - * <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. - * @param promptDft The default to use if prompting for the password. - * @return Password - */ - public static Password getPassword(String realm, String dft, String promptDft) - { - String passwd = System.getProperty(realm, dft); - if (passwd == null || passwd.length() == 0) - { - try - { - System.out.print(realm + ((promptDft != null && promptDft.length() > 0) ? " [dft]" : "") + " : "); - System.out.flush(); - byte[] buf = new byte[512]; - int len = System.in.read(buf); - if (len > 0) passwd = new String(buf, 0, len).trim(); - } - catch (IOException e) - { - LOG.warn("EXCEPTION", e); - } - if (passwd == null || passwd.length() == 0) passwd = promptDft; - } - return new Password(passwd); - } - - /* ------------------------------------------------------------ */ - /** - * @param arg - */ - public static void main(String[] arg) - { - if (arg.length != 1 && arg.length != 2) - { - System.err.println("Usage - java org.eclipse.jetty.security.Password [<user>] <password>"); - System.err.println("If the password is ?, the user will be prompted for the password"); - System.exit(1); - } - String p = arg[arg.length == 1 ? 0 : 1]; - Password pw = new Password(p); - System.err.println(pw.toString()); - System.err.println(obfuscate(pw.toString())); - System.err.println(Credential.MD5.digest(p)); - if (arg.length == 2) System.err.println(Credential.Crypt.crypt(arg[0], pw.toString())); - } -}
--- a/src/org/eclipse/jetty/util/security/UnixCrypt.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,461 +0,0 @@ -/* - * @(#)UnixCrypt.java 0.9 96/11/25 - * - * Copyright (c) 1996 Aki Yoshida. All rights reserved. - * - * Permission to use, copy, modify and distribute this software - * for non-commercial or commercial purposes and without fee is - * hereby granted provided that this copyright notice appears in - * all copies. - */ - -/** - * Unix crypt(3C) utility - * - * @version 0.9, 11/25/96 - * @author Aki Yoshida - */ - -/** - * modified April 2001 - * by Iris Van den Broeke, Daniel Deville - */ - -package org.eclipse.jetty.util.security; - - -/* ------------------------------------------------------------ */ -/** - * Unix Crypt. Implements the one way cryptography used by Unix systems for - * simple password protection. - * - * @version $Id: UnixCrypt.java,v 1.1 2005/10/05 14:09:14 janb Exp $ - * @author Greg Wilkins (gregw) - */ -public class UnixCrypt -{ - - /* (mostly) Standard DES Tables from Tom Truscott */ - private static final byte[] IP = { /* initial permutation */ - 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 }; - - /* The final permutation is the inverse of IP - no table is necessary */ - private static final byte[] ExpandTr = { /* expansion operation */ - 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 }; - - private static final byte[] PC1 = { /* permuted choice table 1 */ - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; - - private static final byte[] Rotates = { /* PC1 rotation schedule */ - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; - - private static final byte[] PC2 = { /* permuted choice table 2 */ - 9, 18, 14, 17, 11, 24, 1, 5, 22, 25, 3, 28, 15, 6, 21, 10, 35, 38, 23, 19, 12, 4, 26, 8, 43, 54, 16, 7, 27, 20, 13, 2, - - 0, 0, 41, 52, 31, 37, 47, 55, 0, 0, 30, 40, 51, 45, 33, 48, 0, 0, 44, 49, 39, 56, 34, 53, 0, 0, 46, 42, 50, 36, 29, 32 }; - - private static final byte[][] S = { /* 48->32 bit substitution tables */ - /* S[1] */ - { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, - 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, - /* S[2] */ - { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, - 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, - /* S[3] */ - { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, - 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, - /* S[4] */ - { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, - 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, - /* S[5] */ - { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, - 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, - /* S[6] */ - { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, - 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, - /* S[7] */ - { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, - 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, - /* S[8] */ - { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, - 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }; - - private static final byte[] P32Tr = { /* 32-bit permutation function */ - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; - - private static final byte[] CIFP = { /* - * compressed/interleaved - * permutation - */ - 1, 2, 3, 4, 17, 18, 19, 20, 5, 6, 7, 8, 21, 22, 23, 24, 9, 10, 11, 12, 25, 26, 27, 28, 13, 14, 15, 16, 29, 30, 31, 32, - - 33, 34, 35, 36, 49, 50, 51, 52, 37, 38, 39, 40, 53, 54, 55, 56, 41, 42, 43, 44, 57, 58, 59, 60, 45, 46, 47, 48, 61, 62, 63, 64 }; - - private static final byte[] ITOA64 = { /* 0..63 => ascii-64 */ - (byte) '.', (byte) '/', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'A', - (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', - (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', - (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', - (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', - (byte) 'x', (byte) 'y', (byte) 'z' }; - - /* ===== Tables that are initialized at run time ==================== */ - - private static final byte[] A64TOI = new byte[128]; /* ascii-64 => 0..63 */ - - /* Initial key schedule permutation */ - private static final long[][] PC1ROT = new long[16][16]; - - /* Subsequent key schedule rotation permutations */ - private static final long[][][] PC2ROT = new long[2][16][16]; - - /* Initial permutation/expansion table */ - private static final long[][] IE3264 = new long[8][16]; - - /* Table that combines the S, P, and E operations. */ - private static final long[][] SPE = new long[8][64]; - - /* compressed/interleaved => final permutation table */ - private static final long[][] CF6464 = new long[16][16]; - - /* ==================================== */ - - static - { - byte[] perm = new byte[64]; - byte[] temp = new byte[64]; - - // inverse table. - for (int i = 0; i < 64; i++) - A64TOI[ITOA64[i]] = (byte) i; - - // PC1ROT - bit reverse, then PC1, then Rotate, then PC2 - for (int i = 0; i < 64; i++) - perm[i] = (byte) 0; - - for (int i = 0; i < 64; i++) - { - int k; - if ((k = PC2[i]) == 0) continue; - k += Rotates[0] - 1; - if ((k % 28) < Rotates[0]) k -= 28; - k = PC1[k]; - if (k > 0) - { - k--; - k = (k | 0x07) - (k & 0x07); - k++; - } - perm[i] = (byte) k; - } - init_perm(PC1ROT, perm, 8); - - // PC2ROT - PC2 inverse, then Rotate, then PC2 - for (int j = 0; j < 2; j++) - { - int k; - for (int i = 0; i < 64; i++) - perm[i] = temp[i] = 0; - for (int i = 0; i < 64; i++) - { - if ((k = PC2[i]) == 0) continue; - temp[k - 1] = (byte) (i + 1); - } - for (int i = 0; i < 64; i++) - { - if ((k = PC2[i]) == 0) continue; - k += j; - if ((k % 28) <= j) k -= 28; - perm[i] = temp[k]; - } - - init_perm(PC2ROT[j], perm, 8); - } - - // Bit reverse, intial permupation, expantion - for (int i = 0; i < 8; i++) - { - for (int j = 0; j < 8; j++) - { - int k = (j < 2) ? 0 : IP[ExpandTr[i * 6 + j - 2] - 1]; - if (k > 32) - k -= 32; - else if (k > 0) k--; - if (k > 0) - { - k--; - k = (k | 0x07) - (k & 0x07); - k++; - } - perm[i * 8 + j] = (byte) k; - } - } - - init_perm(IE3264, perm, 8); - - // Compression, final permutation, bit reverse - for (int i = 0; i < 64; i++) - { - int k = IP[CIFP[i] - 1]; - if (k > 0) - { - k--; - k = (k | 0x07) - (k & 0x07); - k++; - } - perm[k - 1] = (byte) (i + 1); - } - - init_perm(CF6464, perm, 8); - - // SPE table - for (int i = 0; i < 48; i++) - perm[i] = P32Tr[ExpandTr[i] - 1]; - for (int t = 0; t < 8; t++) - { - for (int j = 0; j < 64; j++) - { - int k = (((j >> 0) & 0x01) << 5) | (((j >> 1) & 0x01) << 3) - | (((j >> 2) & 0x01) << 2) - | (((j >> 3) & 0x01) << 1) - | (((j >> 4) & 0x01) << 0) - | (((j >> 5) & 0x01) << 4); - k = S[t][k]; - k = (((k >> 3) & 0x01) << 0) | (((k >> 2) & 0x01) << 1) | (((k >> 1) & 0x01) << 2) | (((k >> 0) & 0x01) << 3); - for (int i = 0; i < 32; i++) - temp[i] = 0; - for (int i = 0; i < 4; i++) - temp[4 * t + i] = (byte) ((k >> i) & 0x01); - long kk = 0; - for (int i = 24; --i >= 0;) - kk = ((kk << 1) | ((long) temp[perm[i] - 1]) << 32 | (temp[perm[i + 24] - 1])); - - SPE[t][j] = to_six_bit(kk); - } - } - } - - /** - * You can't call the constructer. - */ - private UnixCrypt() - { - } - - /** - * Returns the transposed and split code of a 24-bit code into a 4-byte - * code, each having 6 bits. - */ - private static int to_six_bit(int num) - { - return (((num << 26) & 0xfc000000) | ((num << 12) & 0xfc0000) | ((num >> 2) & 0xfc00) | ((num >> 16) & 0xfc)); - } - - /** - * Returns the transposed and split code of two 24-bit code into two 4-byte - * code, each having 6 bits. - */ - private static long to_six_bit(long num) - { - return (((num << 26) & 0xfc000000fc000000L) | ((num << 12) & 0xfc000000fc0000L) | ((num >> 2) & 0xfc000000fc00L) | ((num >> 16) & 0xfc000000fcL)); - } - - /** - * Returns the permutation of the given 64-bit code with the specified - * permutataion table. - */ - private static long perm6464(long c, long[][] p) - { - long out = 0L; - for (int i = 8; --i >= 0;) - { - int t = (int) (0x00ff & c); - c >>= 8; - long tp = p[i << 1][t & 0x0f]; - out |= tp; - tp = p[(i << 1) + 1][t >> 4]; - out |= tp; - } - return out; - } - - /** - * Returns the permutation of the given 32-bit code with the specified - * permutataion table. - */ - private static long perm3264(int c, long[][] p) - { - long out = 0L; - for (int i = 4; --i >= 0;) - { - int t = (0x00ff & c); - c >>= 8; - long tp = p[i << 1][t & 0x0f]; - out |= tp; - tp = p[(i << 1) + 1][t >> 4]; - out |= tp; - } - return out; - } - - /** - * Returns the key schedule for the given key. - */ - private static long[] des_setkey(long keyword) - { - long K = perm6464(keyword, PC1ROT); - long[] KS = new long[16]; - KS[0] = K & ~0x0303030300000000L; - - for (int i = 1; i < 16; i++) - { - KS[i] = K; - K = perm6464(K, PC2ROT[Rotates[i] - 1]); - - KS[i] = K & ~0x0303030300000000L; - } - return KS; - } - - /** - * Returns the DES encrypted code of the given word with the specified - * environment. - */ - private static long des_cipher(long in, int salt, int num_iter, long[] KS) - { - salt = to_six_bit(salt); - long L = in; - long R = L; - L &= 0x5555555555555555L; - R = (R & 0xaaaaaaaa00000000L) | ((R >> 1) & 0x0000000055555555L); - L = ((((L << 1) | (L << 32)) & 0xffffffff00000000L) | ((R | (R >> 32)) & 0x00000000ffffffffL)); - - L = perm3264((int) (L >> 32), IE3264); - R = perm3264((int) (L & 0xffffffff), IE3264); - - while (--num_iter >= 0) - { - for (int loop_count = 0; loop_count < 8; loop_count++) - { - long kp; - long B; - long k; - - kp = KS[(loop_count << 1)]; - k = ((R >> 32) ^ R) & salt & 0xffffffffL; - k |= (k << 32); - B = (k ^ R ^ kp); - - L ^= (SPE[0][(int) ((B >> 58) & 0x3f)] ^ SPE[1][(int) ((B >> 50) & 0x3f)] - ^ SPE[2][(int) ((B >> 42) & 0x3f)] - ^ SPE[3][(int) ((B >> 34) & 0x3f)] - ^ SPE[4][(int) ((B >> 26) & 0x3f)] - ^ SPE[5][(int) ((B >> 18) & 0x3f)] - ^ SPE[6][(int) ((B >> 10) & 0x3f)] ^ SPE[7][(int) ((B >> 2) & 0x3f)]); - - kp = KS[(loop_count << 1) + 1]; - k = ((L >> 32) ^ L) & salt & 0xffffffffL; - k |= (k << 32); - B = (k ^ L ^ kp); - - R ^= (SPE[0][(int) ((B >> 58) & 0x3f)] ^ SPE[1][(int) ((B >> 50) & 0x3f)] - ^ SPE[2][(int) ((B >> 42) & 0x3f)] - ^ SPE[3][(int) ((B >> 34) & 0x3f)] - ^ SPE[4][(int) ((B >> 26) & 0x3f)] - ^ SPE[5][(int) ((B >> 18) & 0x3f)] - ^ SPE[6][(int) ((B >> 10) & 0x3f)] ^ SPE[7][(int) ((B >> 2) & 0x3f)]); - } - // swap L and R - L ^= R; - R ^= L; - L ^= R; - } - L = ((((L >> 35) & 0x0f0f0f0fL) | (((L & 0xffffffff) << 1) & 0xf0f0f0f0L)) << 32 | (((R >> 35) & 0x0f0f0f0fL) | (((R & 0xffffffff) << 1) & 0xf0f0f0f0L))); - - L = perm6464(L, CF6464); - - return L; - } - - /** - * Initializes the given permutation table with the mapping table. - */ - private static void init_perm(long[][] perm, byte[] p, int chars_out) - { - for (int k = 0; k < chars_out * 8; k++) - { - - int l = p[k] - 1; - if (l < 0) continue; - int i = l >> 2; - l = 1 << (l & 0x03); - for (int j = 0; j < 16; j++) - { - int s = ((k & 0x07) + ((7 - (k >> 3)) << 3)); - if ((j & l) != 0x00) perm[i][j] |= (1L << s); - } - } - } - - /** - * Encrypts String into crypt (Unix) code. - * - * @param key the key to be encrypted - * @param setting the salt to be used - * @return the encrypted String - */ - public static String crypt(String key, String setting) - { - long constdatablock = 0L; /* encryption constant */ - byte[] cryptresult = new byte[13]; /* encrypted result */ - long keyword = 0L; - /* invalid parameters! */ - if (key == null || setting == null) return "*"; // will NOT match under - // ANY circumstances! - - int keylen = key.length(); - - for (int i = 0; i < 8; i++) - { - keyword = (keyword << 8) | ((i < keylen) ? 2 * key.charAt(i) : 0); - } - - long[] KS = des_setkey(keyword); - - int salt = 0; - for (int i = 2; --i >= 0;) - { - char c = (i < setting.length()) ? setting.charAt(i) : '.'; - cryptresult[i] = (byte) c; - salt = (salt << 6) | (0x00ff & A64TOI[c]); - } - - long rsltblock = des_cipher(constdatablock, salt, 25, KS); - - cryptresult[12] = ITOA64[(((int) rsltblock) << 2) & 0x3f]; - rsltblock >>= 4; - for (int i = 12; --i >= 2;) - { - cryptresult[i] = ITOA64[((int) rsltblock) & 0x3f]; - rsltblock >>= 6; - } - - return new String(cryptresult, 0, 13); - } - - public static void main(String[] arg) - { - if (arg.length != 2) - { - System.err.println("Usage - java org.eclipse.util.UnixCrypt <key> <salt>"); - System.exit(1); - } - - System.err.println("Crypt=" + crypt(arg[0], arg[1])); - } - -}
--- a/src/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.ssl; - -import java.net.Socket; -import java.security.Principal; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509KeyManager; - - -/* ------------------------------------------------------------ */ -/** - * KeyManager to select a key with desired alias - * while delegating processing to specified KeyManager - * Can be used both with server and client sockets - */ -public class AliasedX509ExtendedKeyManager extends X509ExtendedKeyManager -{ - private String _keyAlias; - private X509KeyManager _keyManager; - - /* ------------------------------------------------------------ */ - /** - * Construct KeyManager instance - * @param keyAlias Alias of the key to be selected - * @param keyManager Instance of KeyManager to be wrapped - * @throws Exception - */ - public AliasedX509ExtendedKeyManager(String keyAlias, X509KeyManager keyManager) throws Exception - { - _keyAlias = keyAlias; - _keyManager = keyManager; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket) - */ - public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket) - */ - public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ? _keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getClientAliases(String keyType, Principal[] issuers) - { - return _keyManager.getClientAliases(keyType, issuers); - } - - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getServerAliases(String keyType, Principal[] issuers) - { - return _keyManager.getServerAliases(keyType, issuers); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String) - */ - public X509Certificate[] getCertificateChain(String alias) - { - return _keyManager.getCertificateChain(alias); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String) - */ - public PrivateKey getPrivateKey(String alias) - { - return _keyManager.getPrivateKey(alias); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineServerAlias(java.lang.String, java.security.Principal[], javax.net.ssl.SSLEngine) - */ - @Override - public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) - { - return _keyAlias == null ? super.chooseEngineServerAlias(keyType,issuers,engine) : _keyAlias; - } - - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineClientAlias(String[], Principal[], SSLEngine) - */ - @Override - public String chooseEngineClientAlias(String keyType[], Principal[] issuers, SSLEngine engine) - { - return _keyAlias == null ? super.chooseEngineClientAlias(keyType,issuers,engine) : _keyAlias; - } -}
--- a/src/org/eclipse/jetty/util/ssl/AliasedX509KeyManager.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.ssl; - -import java.net.Socket; -import java.security.Principal; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; - -import javax.net.ssl.X509KeyManager; - - -/* ------------------------------------------------------------ */ -/** - * KeyManager to select a key with desired alias - * while delegating processing to specified KeyManager - * Can be used both with server and client sockets - */ -public class AliasedX509KeyManager implements X509KeyManager -{ - private String _keyAlias; - private X509KeyManager _keyManager; - - /* ------------------------------------------------------------ */ - /** - * Construct KeyManager instance - * @param keyAlias Alias of the key to be selected - * @param keyManager Instance of KeyManager to be wrapped - * @throws Exception - */ - public AliasedX509KeyManager(String keyAlias, X509KeyManager keyManager) throws Exception - { - _keyAlias = keyAlias; - _keyManager = keyManager; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket) - */ - public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket) - */ - public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ?_keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getClientAliases(String keyType, Principal[] issuers) - { - return _keyManager.getClientAliases(keyType, issuers); - } - - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getServerAliases(String keyType, Principal[] issuers) - { - return _keyManager.getServerAliases(keyType, issuers); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String) - */ - public X509Certificate[] getCertificateChain(String alias) - { - return _keyManager.getCertificateChain(alias); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String) - */ - public PrivateKey getPrivateKey(String alias) - { - return _keyManager.getPrivateKey(alias); - } -}
--- a/src/org/eclipse/jetty/util/ssl/SslContextFactory.java Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1537 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.ssl; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.security.InvalidParameterException; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.security.Security; -import java.security.cert.CRL; -import java.security.cert.CertStore; -import java.security.cert.Certificate; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.X509CertSelector; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import javax.net.ssl.CertPathTrustManagerParameters; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509KeyManager; -import javax.net.ssl.X509TrustManager; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.security.CertificateUtils; -import org.eclipse.jetty.util.security.CertificateValidator; -import org.eclipse.jetty.util.security.Password; - - -/* ------------------------------------------------------------ */ -/** - * SslContextFactory is used to configure SSL connectors - * as well as HttpClient. It holds all SSL parameters and - * creates SSL context based on these parameters to be - * used by the SSL connectors. - */ -public class SslContextFactory extends AbstractLifeCycle -{ - public final static TrustManager[] TRUST_ALL_CERTS = new X509TrustManager[]{new X509TrustManager() - { - public java.security.cert.X509Certificate[] getAcceptedIssuers() - { - return new java.security.cert.X509Certificate[]{}; - } - - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) - { - } - - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) - { - } - }}; - - private static final Logger LOG = LoggerFactory.getLogger(SslContextFactory.class); - - public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM = - (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ? - "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm")); - public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM = - (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ? - "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm")); - - /** Default value for the keystore location path. */ - public static final String DEFAULT_KEYSTORE_PATH = - System.getProperty("user.home") + File.separator + ".keystore"; - - /** String name of key password property. */ - public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword"; - - /** String name of keystore password property. */ - public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password"; - - /** Excluded protocols. */ - private final Set<String> _excludeProtocols = new LinkedHashSet<String>(); - /** Included protocols. */ - private Set<String> _includeProtocols = null; - - /** Excluded cipher suites. */ - private final Set<String> _excludeCipherSuites = new LinkedHashSet<String>(); - /** Included cipher suites. */ - private Set<String> _includeCipherSuites = null; - - /** Keystore path. */ - private String _keyStorePath; - /** Keystore provider name */ - private String _keyStoreProvider; - /** Keystore type */ - private String _keyStoreType = "JKS"; - /** Keystore input stream */ - private InputStream _keyStoreInputStream; - - /** SSL certificate alias */ - private String _certAlias; - - /** Truststore path */ - private String _trustStorePath; - /** Truststore provider name */ - private String _trustStoreProvider; - /** Truststore type */ - private String _trustStoreType = "JKS"; - /** Truststore input stream */ - private InputStream _trustStoreInputStream; - - /** Set to true if client certificate authentication is required */ - private boolean _needClientAuth = false; - /** Set to true if client certificate authentication is desired */ - private boolean _wantClientAuth = false; - - /** Set to true if renegotiation is allowed */ - private boolean _allowRenegotiate = true; - - /** Keystore password */ - private transient Password _keyStorePassword; - /** Key manager password */ - private transient Password _keyManagerPassword; - /** Truststore password */ - private transient Password _trustStorePassword; - - /** SSL provider name */ - private String _sslProvider; - /** SSL protocol name */ - private String _sslProtocol = "TLS"; - - /** SecureRandom algorithm */ - private String _secureRandomAlgorithm; - /** KeyManager factory algorithm */ - private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM; - /** TrustManager factory algorithm */ - private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM; - - /** Set to true if SSL certificate validation is required */ - private boolean _validateCerts; - /** Set to true if SSL certificate of the peer validation is required */ - private boolean _validatePeerCerts; - /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */ - private int _maxCertPathLength = -1; - /** Path to file that contains Certificate Revocation List */ - private String _crlPath; - /** Set to true to enable CRL Distribution Points (CRLDP) support */ - private boolean _enableCRLDP = false; - /** Set to true to enable On-Line Certificate Status Protocol (OCSP) support */ - private boolean _enableOCSP = false; - /** Location of OCSP Responder */ - private String _ocspResponderURL; - - /** SSL keystore */ - private KeyStore _keyStore; - /** SSL truststore */ - private KeyStore _trustStore; - /** Set to true to enable SSL Session caching */ - private boolean _sessionCachingEnabled = true; - /** SSL session cache size */ - private int _sslSessionCacheSize; - /** SSL session timeout */ - private int _sslSessionTimeout; - - /** SSL context */ - private SSLContext _context; - - private boolean _trustAll; - - /* ------------------------------------------------------------ */ - /** - * Construct an instance of SslContextFactory - * Default constructor for use in XmlConfiguration files - */ - public SslContextFactory() - { - _trustAll=true; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an instance of SslContextFactory - * Default constructor for use in XmlConfiguration files - * @param trustAll whether to blindly trust all certificates - * @see #setTrustAll(boolean) - */ - public SslContextFactory(boolean trustAll) - { - _trustAll=trustAll; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an instance of SslContextFactory - * @param keyStorePath default keystore location - */ - public SslContextFactory(String keyStorePath) - { - _keyStorePath = keyStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * Create the SSLContext object and start the lifecycle - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - if (_context == null) - { - if (_keyStore==null && _keyStoreInputStream == null && _keyStorePath == null && - _trustStore==null && _trustStoreInputStream == null && _trustStorePath == null ) - { - TrustManager[] trust_managers=null; - - if (_trustAll) - { - LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!"); - // Create a trust manager that does not validate certificate chains - trust_managers = TRUST_ALL_CERTS; - } - - SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm); - _context = SSLContext.getInstance(_sslProtocol); - _context.init(null, trust_managers, secureRandom); - } - else - { - // verify that keystore and truststore - // parameters are set up correctly - checkKeyStore(); - - KeyStore keyStore = loadKeyStore(); - KeyStore trustStore = loadTrustStore(); - - Collection<? extends CRL> crls = loadCRL(_crlPath); - - if (_validateCerts && keyStore != null) - { - if (_certAlias == null) - { - List<String> aliases = Collections.list(keyStore.aliases()); - _certAlias = aliases.size() == 1 ? aliases.get(0) : null; - } - - Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias); - if (cert == null) - { - throw new Exception("No certificate found in the keystore" + (_certAlias==null ? "":" for alias " + _certAlias)); - } - - CertificateValidator validator = new CertificateValidator(trustStore, crls); - validator.setMaxCertPathLength(_maxCertPathLength); - validator.setEnableCRLDP(_enableCRLDP); - validator.setEnableOCSP(_enableOCSP); - validator.setOcspResponderURL(_ocspResponderURL); - validator.validate(keyStore, cert); - } - - KeyManager[] keyManagers = getKeyManagers(keyStore); - TrustManager[] trustManagers = getTrustManagers(trustStore,crls); - - SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm); - _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider); - _context.init(keyManagers,trustManagers,secureRandom); - - SSLEngine engine=newSslEngine(); - - LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols())); - if (LOG.isDebugEnabled()) - LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites())); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @return The array of protocol names to exclude from - * {@link SSLEngine#setEnabledProtocols(String[])} - */ - public String[] getExcludeProtocols() - { - return _excludeProtocols.toArray(new String[_excludeProtocols.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * @param protocols - * The array of protocol names to exclude from - * {@link SSLEngine#setEnabledProtocols(String[])} - */ - public void setExcludeProtocols(String... protocols) - { - checkNotStarted(); - - _excludeProtocols.clear(); - _excludeProtocols.addAll(Arrays.asList(protocols)); - } - - /* ------------------------------------------------------------ */ - /** - * @param protocol Protocol names to add to {@link SSLEngine#setEnabledProtocols(String[])} - */ - public void addExcludeProtocols(String... protocol) - { - checkNotStarted(); - _excludeProtocols.addAll(Arrays.asList(protocol)); - } - - /* ------------------------------------------------------------ */ - /** - * @return The array of protocol names to include in - * {@link SSLEngine#setEnabledProtocols(String[])} - */ - public String[] getIncludeProtocols() - { - return _includeProtocols.toArray(new String[_includeProtocols.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * @param protocols - * The array of protocol names to include in - * {@link SSLEngine#setEnabledProtocols(String[])} - */ - public void setIncludeProtocols(String... protocols) - { - checkNotStarted(); - - _includeProtocols = new LinkedHashSet<String>(Arrays.asList(protocols)); - } - - /* ------------------------------------------------------------ */ - /** - * @return The array of cipher suite names to exclude from - * {@link SSLEngine#setEnabledCipherSuites(String[])} - */ - public String[] getExcludeCipherSuites() - { - return _excludeCipherSuites.toArray(new String[_excludeCipherSuites.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * @param cipherSuites - * The array of cipher suite names to exclude from - * {@link SSLEngine#setEnabledCipherSuites(String[])} - */ - public void setExcludeCipherSuites(String... cipherSuites) - { - checkNotStarted(); - _excludeCipherSuites.clear(); - _excludeCipherSuites.addAll(Arrays.asList(cipherSuites)); - } - - /* ------------------------------------------------------------ */ - /** - * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])} - */ - public void addExcludeCipherSuites(String... cipher) - { - checkNotStarted(); - _excludeCipherSuites.addAll(Arrays.asList(cipher)); - } - - /* ------------------------------------------------------------ */ - /** - * @return The array of cipher suite names to include in - * {@link SSLEngine#setEnabledCipherSuites(String[])} - */ - public String[] getIncludeCipherSuites() - { - return _includeCipherSuites.toArray(new String[_includeCipherSuites.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * @param cipherSuites - * The array of cipher suite names to include in - * {@link SSLEngine#setEnabledCipherSuites(String[])} - */ - public void setIncludeCipherSuites(String... cipherSuites) - { - checkNotStarted(); - - _includeCipherSuites = new LinkedHashSet<String>(Arrays.asList(cipherSuites)); - } - - /* ------------------------------------------------------------ */ - /** - * @return The file or URL of the SSL Key store. - */ - public String getKeyStorePath() - { - return _keyStorePath; - } - - /* ------------------------------------------------------------ */ - @Deprecated - public String getKeyStore() - { - return _keyStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * @param keyStorePath - * The file or URL of the SSL Key store. - */ - public void setKeyStorePath(String keyStorePath) - { - checkNotStarted(); - - _keyStorePath = keyStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * @param keyStorePath the file system path or URL of the keystore - * @deprecated Use {@link #setKeyStorePath(String)} - */ - @Deprecated - public void setKeyStore(String keyStorePath) - { - checkNotStarted(); - - _keyStorePath = keyStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * @return The provider of the key store - */ - public String getKeyStoreProvider() - { - return _keyStoreProvider; - } - - /* ------------------------------------------------------------ */ - /** - * @param keyStoreProvider - * The provider of the key store - */ - public void setKeyStoreProvider(String keyStoreProvider) - { - checkNotStarted(); - - _keyStoreProvider = keyStoreProvider; - } - - /* ------------------------------------------------------------ */ - /** - * @return The type of the key store (default "JKS") - */ - public String getKeyStoreType() - { - return (_keyStoreType); - } - - /* ------------------------------------------------------------ */ - /** - * @param keyStoreType - * The type of the key store (default "JKS") - */ - public void setKeyStoreType(String keyStoreType) - { - checkNotStarted(); - - _keyStoreType = keyStoreType; - } - - /* ------------------------------------------------------------ */ - /** Get the _keyStoreInputStream. - * @return the _keyStoreInputStream - * - * @deprecated - */ - @Deprecated - public InputStream getKeyStoreInputStream() - { - checkKeyStore(); - - return _keyStoreInputStream; - } - - /* ------------------------------------------------------------ */ - /** Set the keyStoreInputStream. - * @param keyStoreInputStream the InputStream to the KeyStore - * - * @deprecated Use {@link #setKeyStore(KeyStore)} - */ - @Deprecated - public void setKeyStoreInputStream(InputStream keyStoreInputStream) - { - checkNotStarted(); - - _keyStoreInputStream = keyStoreInputStream; - } - - /* ------------------------------------------------------------ */ - /** - * @return Alias of SSL certificate for the connector - */ - public String getCertAlias() - { - return _certAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @param certAlias - * Alias of SSL certificate for the connector - */ - public void setCertAlias(String certAlias) - { - checkNotStarted(); - - _certAlias = certAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @return The file name or URL of the trust store location - */ - public String getTrustStore() - { - return _trustStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * @param trustStorePath - * The file name or URL of the trust store location - */ - public void setTrustStore(String trustStorePath) - { - checkNotStarted(); - - _trustStorePath = trustStorePath; - } - - /* ------------------------------------------------------------ */ - /** - * @return The provider of the trust store - */ - public String getTrustStoreProvider() - { - return _trustStoreProvider; - } - - /* ------------------------------------------------------------ */ - /** - * @param trustStoreProvider - * The provider of the trust store - */ - public void setTrustStoreProvider(String trustStoreProvider) - { - checkNotStarted(); - - _trustStoreProvider = trustStoreProvider; - } - - /* ------------------------------------------------------------ */ - /** - * @return The type of the trust store (default "JKS") - */ - public String getTrustStoreType() - { - return _trustStoreType; - } - - /* ------------------------------------------------------------ */ - /** - * @param trustStoreType - * The type of the trust store (default "JKS") - */ - public void setTrustStoreType(String trustStoreType) - { - checkNotStarted(); - - _trustStoreType = trustStoreType; - } - - /* ------------------------------------------------------------ */ - /** Get the _trustStoreInputStream. - * @return the _trustStoreInputStream - * - * @deprecated - */ - @Deprecated - public InputStream getTrustStoreInputStream() - { - checkKeyStore(); - - return _trustStoreInputStream; - } - - /* ------------------------------------------------------------ */ - /** Set the _trustStoreInputStream. - * @param trustStoreInputStream the InputStream to the TrustStore - * - * @deprecated - */ - @Deprecated - public void setTrustStoreInputStream(InputStream trustStoreInputStream) - { - checkNotStarted(); - - _trustStoreInputStream = trustStoreInputStream; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if SSL needs client authentication. - * @see SSLEngine#getNeedClientAuth() - */ - public boolean getNeedClientAuth() - { - return _needClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * @param needClientAuth - * True if SSL needs client authentication. - * @see SSLEngine#getNeedClientAuth() - */ - public void setNeedClientAuth(boolean needClientAuth) - { - checkNotStarted(); - - _needClientAuth = needClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if SSL wants client authentication. - * @see SSLEngine#getWantClientAuth() - */ - public boolean getWantClientAuth() - { - return _wantClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * @param wantClientAuth - * True if SSL wants client authentication. - * @see SSLEngine#getWantClientAuth() - */ - public void setWantClientAuth(boolean wantClientAuth) - { - checkNotStarted(); - - _wantClientAuth = wantClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if SSL certificate has to be validated - * @deprecated - */ - @Deprecated - public boolean getValidateCerts() - { - return _validateCerts; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if SSL certificate has to be validated - */ - public boolean isValidateCerts() - { - return _validateCerts; - } - - /* ------------------------------------------------------------ */ - /** - * @param validateCerts - * true if SSL certificates have to be validated - */ - public void setValidateCerts(boolean validateCerts) - { - checkNotStarted(); - - _validateCerts = validateCerts; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if SSL certificates of the peer have to be validated - */ - public boolean isValidatePeerCerts() - { - return _validatePeerCerts; - } - - /* ------------------------------------------------------------ */ - /** - * @param validatePeerCerts - * true if SSL certificates of the peer have to be validated - */ - public void setValidatePeerCerts(boolean validatePeerCerts) - { - checkNotStarted(); - - _validatePeerCerts = validatePeerCerts; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if SSL re-negotiation is allowed (default false) - */ - public boolean isAllowRenegotiate() - { - return _allowRenegotiate; - } - - /* ------------------------------------------------------------ */ - /** - * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered - * a vulnerability in SSL/TLS with re-negotiation. If your JVM - * does not have CVE-2009-3555 fixed, then re-negotiation should - * not be allowed. CVE-2009-3555 was fixed in Sun java 1.6 with a ban - * of renegotiates in u19 and with RFC5746 in u22. - * - * @param allowRenegotiate - * true if re-negotiation is allowed (default false) - */ - public void setAllowRenegotiate(boolean allowRenegotiate) - { - checkNotStarted(); - - _allowRenegotiate = allowRenegotiate; - } - - /* ------------------------------------------------------------ */ - /** - * @param password - * The password for the key store - */ - public void setKeyStorePassword(String password) - { - checkNotStarted(); - - _keyStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null); - } - - /* ------------------------------------------------------------ */ - /** - * @param password - * The password (if any) for the specific key within the key store - */ - public void setKeyManagerPassword(String password) - { - checkNotStarted(); - - _keyManagerPassword = Password.getPassword(KEYPASSWORD_PROPERTY,password,null); - } - - /* ------------------------------------------------------------ */ - /** - * @param password - * The password for the trust store - */ - public void setTrustStorePassword(String password) - { - checkNotStarted(); - - _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null); - } - - /* ------------------------------------------------------------ */ - /** - * @return The SSL provider name, which if set is passed to - * {@link SSLContext#getInstance(String, String)} - */ - public String getProvider() - { - return _sslProvider; - } - - /* ------------------------------------------------------------ */ - /** - * @param provider - * The SSL provider name, which if set is passed to - * {@link SSLContext#getInstance(String, String)} - */ - public void setProvider(String provider) - { - checkNotStarted(); - - _sslProvider = provider; - } - - /* ------------------------------------------------------------ */ - /** - * @return The SSL protocol (default "TLS") passed to - * {@link SSLContext#getInstance(String, String)} - */ - public String getProtocol() - { - return _sslProtocol; - } - - /* ------------------------------------------------------------ */ - /** - * @param protocol - * The SSL protocol (default "TLS") passed to - * {@link SSLContext#getInstance(String, String)} - */ - public void setProtocol(String protocol) - { - checkNotStarted(); - - _sslProtocol = protocol; - } - - /* ------------------------------------------------------------ */ - /** - * @return The algorithm name, which if set is passed to - * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to - * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)} - */ - public String getSecureRandomAlgorithm() - { - return _secureRandomAlgorithm; - } - - /* ------------------------------------------------------------ */ - /** - * @param algorithm - * The algorithm name, which if set is passed to - * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to - * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)} - */ - public void setSecureRandomAlgorithm(String algorithm) - { - checkNotStarted(); - - _secureRandomAlgorithm = algorithm; - } - - /* ------------------------------------------------------------ */ - /** - * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory} - */ - public String getSslKeyManagerFactoryAlgorithm() - { - return (_keyManagerFactoryAlgorithm); - } - - /* ------------------------------------------------------------ */ - /** - * @param algorithm - * The algorithm name (default "SunX509") used by the {@link KeyManagerFactory} - */ - public void setSslKeyManagerFactoryAlgorithm(String algorithm) - { - checkNotStarted(); - - _keyManagerFactoryAlgorithm = algorithm; - } - - /* ------------------------------------------------------------ */ - /** - * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory} - */ - public String getTrustManagerFactoryAlgorithm() - { - return (_trustManagerFactoryAlgorithm); - } - - /* ------------------------------------------------------------ */ - /** - * @return True if all certificates should be trusted if there is no KeyStore or TrustStore - */ - public boolean isTrustAll() - { - return _trustAll; - } - - /* ------------------------------------------------------------ */ - /** - * @param trustAll True if all certificates should be trusted if there is no KeyStore or TrustStore - */ - public void setTrustAll(boolean trustAll) - { - _trustAll = trustAll; - } - - /* ------------------------------------------------------------ */ - /** - * @param algorithm - * The algorithm name (default "SunX509") used by the {@link TrustManagerFactory} - * Use the string "TrustAll" to install a trust manager that trusts all. - */ - public void setTrustManagerFactoryAlgorithm(String algorithm) - { - checkNotStarted(); - - _trustManagerFactoryAlgorithm = algorithm; - } - - /* ------------------------------------------------------------ */ - /** - * @return Path to file that contains Certificate Revocation List - */ - public String getCrlPath() - { - return _crlPath; - } - - /* ------------------------------------------------------------ */ - /** - * @param crlPath - * Path to file that contains Certificate Revocation List - */ - public void setCrlPath(String crlPath) - { - checkNotStarted(); - - _crlPath = crlPath; - } - - /* ------------------------------------------------------------ */ - /** - * @return Maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public int getMaxCertPathLength() - { - return _maxCertPathLength; - } - - /* ------------------------------------------------------------ */ - /** - * @param maxCertPathLength - * maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public void setMaxCertPathLength(int maxCertPathLength) - { - checkNotStarted(); - - _maxCertPathLength = maxCertPathLength; - } - - /* ------------------------------------------------------------ */ - /** - * @return The SSLContext - */ - public SSLContext getSslContext() - { - if (!isStarted()) - throw new IllegalStateException(getState()); - return _context; - } - - /* ------------------------------------------------------------ */ - /** - * @param sslContext - * Set a preconfigured SSLContext - */ - public void setSslContext(SSLContext sslContext) - { - checkNotStarted(); - - _context = sslContext; - } - - /* ------------------------------------------------------------ */ - /** - * Override this method to provide alternate way to load a keystore. - * - * @return the key store instance - * @throws Exception if the keystore cannot be loaded - */ - protected KeyStore loadKeyStore() throws Exception - { - return _keyStore != null ? _keyStore : getKeyStore(_keyStoreInputStream, - _keyStorePath, _keyStoreType, _keyStoreProvider, - _keyStorePassword==null? null: _keyStorePassword.toString()); - } - - /* ------------------------------------------------------------ */ - /** - * Override this method to provide alternate way to load a truststore. - * - * @return the key store instance - * @throws Exception if the truststore cannot be loaded - */ - protected KeyStore loadTrustStore() throws Exception - { - return _trustStore != null ? _trustStore : getKeyStore(_trustStoreInputStream, - _trustStorePath, _trustStoreType, _trustStoreProvider, - _trustStorePassword==null? null: _trustStorePassword.toString()); - } - - /* ------------------------------------------------------------ */ - /** - * Loads keystore using an input stream or a file path in the same - * order of precedence. - * - * Required for integrations to be able to override the mechanism - * used to load a keystore in order to provide their own implementation. - * - * @param storeStream keystore input stream - * @param storePath path of keystore file - * @param storeType keystore type - * @param storeProvider keystore provider - * @param storePassword keystore password - * @return created keystore - * @throws Exception if the keystore cannot be obtained - * - * @deprecated - */ - @Deprecated - protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception - { - return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword); - } - - /* ------------------------------------------------------------ */ - /** - * Loads certificate revocation list (CRL) from a file. - * - * Required for integrations to be able to override the mechanism used to - * load CRL in order to provide their own implementation. - * - * @param crlPath path of certificate revocation list file - * @return Collection of CRL's - * @throws Exception if the certificate revocation list cannot be loaded - */ - protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception - { - return CertificateUtils.loadCRL(crlPath); - } - - /* ------------------------------------------------------------ */ - protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception - { - KeyManager[] managers = null; - - if (keyStore != null) - { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm); - keyManagerFactory.init(keyStore,_keyManagerPassword == null?(_keyStorePassword == null?null:_keyStorePassword.toString().toCharArray()):_keyManagerPassword.toString().toCharArray()); - managers = keyManagerFactory.getKeyManagers(); - - if (_certAlias != null) - { - for (int idx = 0; idx < managers.length; idx++) - { - if (managers[idx] instanceof X509KeyManager) - { - managers[idx] = new AliasedX509ExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]); - } - } - } - } - - return managers; - } - - /* ------------------------------------------------------------ */ - protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception - { - TrustManager[] managers = null; - if (trustStore != null) - { - // Revocation checking is only supported for PKIX algorithm - if (_validatePeerCerts && _trustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX")) - { - PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector()); - - // Set maximum certification path length - pbParams.setMaxPathLength(_maxCertPathLength); - - // Make sure revocation checking is enabled - pbParams.setRevocationEnabled(true); - - if (crls != null && !crls.isEmpty()) - { - pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls))); - } - - if (_enableCRLDP) - { - // Enable Certificate Revocation List Distribution Points (CRLDP) support - System.setProperty("com.sun.security.enableCRLDP","true"); - } - - if (_enableOCSP) - { - // Enable On-Line Certificate Status Protocol (OCSP) support - Security.setProperty("ocsp.enable","true"); - - if (_ocspResponderURL != null) - { - // Override location of OCSP Responder - Security.setProperty("ocsp.responderURL", _ocspResponderURL); - } - } - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm); - trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams)); - - managers = trustManagerFactory.getTrustManagers(); - } - else - { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm); - trustManagerFactory.init(trustStore); - - managers = trustManagerFactory.getTrustManagers(); - } - } - - return managers; - } - - /* ------------------------------------------------------------ */ - /** - * Check KeyStore Configuration. Ensures that if keystore has been - * configured but there's no truststore, that keystore is - * used as truststore. - * @throws IllegalStateException if SslContextFactory configuration can't be used. - */ - public void checkKeyStore() - { - if (_context != null) - return; //nothing to check if using preconfigured context - - - if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null) - throw new IllegalStateException("SSL doesn't have a valid keystore"); - - // if the keystore has been configured but there is no - // truststore configured, use the keystore as the truststore - if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null) - { - _trustStore = _keyStore; - _trustStorePath = _keyStorePath; - _trustStoreInputStream = _keyStoreInputStream; - _trustStoreType = _keyStoreType; - _trustStoreProvider = _keyStoreProvider; - _trustStorePassword = _keyStorePassword; - _trustManagerFactoryAlgorithm = _keyManagerFactoryAlgorithm; - } - - // It's the same stream we cannot read it twice, so read it once in memory - if (_keyStoreInputStream != null && _keyStoreInputStream == _trustStoreInputStream) - { - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - IO.copy(_keyStoreInputStream, baos); - _keyStoreInputStream.close(); - - _keyStoreInputStream = new ByteArrayInputStream(baos.toByteArray()); - _trustStoreInputStream = new ByteArrayInputStream(baos.toByteArray()); - } - catch (Exception ex) - { - throw new IllegalStateException(ex); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Select protocols to be used by the connector - * based on configured inclusion and exclusion lists - * as well as enabled and supported protocols. - * @param enabledProtocols Array of enabled protocols - * @param supportedProtocols Array of supported protocols - * @return Array of protocols to enable - */ - public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols) - { - Set<String> selected_protocols = new LinkedHashSet<String>(); - - // Set the starting protocols - either from the included or enabled list - if (_includeProtocols!=null) - { - // Use only the supported included protocols - for (String protocol : _includeProtocols) - if(Arrays.asList(supportedProtocols).contains(protocol)) - selected_protocols.add(protocol); - } - else - selected_protocols.addAll(Arrays.asList(enabledProtocols)); - - - // Remove any excluded protocols - if (_excludeProtocols != null) - selected_protocols.removeAll(_excludeProtocols); - - return selected_protocols.toArray(new String[selected_protocols.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * Select cipher suites to be used by the connector - * based on configured inclusion and exclusion lists - * as well as enabled and supported cipher suite lists. - * @param enabledCipherSuites Array of enabled cipher suites - * @param supportedCipherSuites Array of supported cipher suites - * @return Array of cipher suites to enable - */ - public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) - { - Set<String> selected_ciphers = new LinkedHashSet<String>(); - - // Set the starting ciphers - either from the included or enabled list - if (_includeCipherSuites!=null) - { - // Use only the supported included ciphers - for (String cipherSuite : _includeCipherSuites) - if(Arrays.asList(supportedCipherSuites).contains(cipherSuite)) - selected_ciphers.add(cipherSuite); - } - else - selected_ciphers.addAll(Arrays.asList(enabledCipherSuites)); - - - // Remove any excluded ciphers - if (_excludeCipherSuites != null) - selected_ciphers.removeAll(_excludeCipherSuites); - return selected_ciphers.toArray(new String[selected_ciphers.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * Check if the lifecycle has been started and throw runtime exception - */ - protected void checkNotStarted() - { - if (isStarted()) - throw new IllegalStateException("Cannot modify configuration when "+getState()); - } - - /* ------------------------------------------------------------ */ - /** - * @return true if CRL Distribution Points support is enabled - */ - public boolean isEnableCRLDP() - { - return _enableCRLDP; - } - - /* ------------------------------------------------------------ */ - /** Enables CRL Distribution Points Support - * @param enableCRLDP true - turn on, false - turns off - */ - public void setEnableCRLDP(boolean enableCRLDP) - { - checkNotStarted(); - - _enableCRLDP = enableCRLDP; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if On-Line Certificate Status Protocol support is enabled - */ - public boolean isEnableOCSP() - { - return _enableOCSP; - } - - /* ------------------------------------------------------------ */ - /** Enables On-Line Certificate Status Protocol support - * @param enableOCSP true - turn on, false - turn off - */ - public void setEnableOCSP(boolean enableOCSP) - { - checkNotStarted(); - - _enableOCSP = enableOCSP; - } - - /* ------------------------------------------------------------ */ - /** - * @return Location of the OCSP Responder - */ - public String getOcspResponderURL() - { - return _ocspResponderURL; - } - - /* ------------------------------------------------------------ */ - /** Set the location of the OCSP Responder. - * @param ocspResponderURL location of the OCSP Responder - */ - public void setOcspResponderURL(String ocspResponderURL) - { - checkNotStarted(); - - _ocspResponderURL = ocspResponderURL; - } - - /* ------------------------------------------------------------ */ - /** Set the key store. - * @param keyStore the key store to set - */ - public void setKeyStore(KeyStore keyStore) - { - checkNotStarted(); - - _keyStore = keyStore; - } - - /* ------------------------------------------------------------ */ - /** Set the trust store. - * @param trustStore the trust store to set - */ - public void setTrustStore(KeyStore trustStore) - { - checkNotStarted(); - - _trustStore = trustStore; - } - - /* ------------------------------------------------------------ */ - /** Set the key store resource. - * @param resource the key store resource to set - */ - public void setKeyStoreResource(Resource resource) - { - checkNotStarted(); - - try - { - _keyStoreInputStream = resource.getInputStream(); - } - catch (IOException e) - { - throw new InvalidParameterException("Unable to get resource "+ - "input stream for resource "+resource.toString()); - } - } - - /* ------------------------------------------------------------ */ - /** Set the trust store resource. - * @param resource the trust store resource to set - */ - public void setTrustStoreResource(Resource resource) - { - checkNotStarted(); - - try - { - _trustStoreInputStream = resource.getInputStream(); - } - catch (IOException e) - { - throw new InvalidParameterException("Unable to get resource "+ - "input stream for resource "+resource.toString()); - } - } - - /* ------------------------------------------------------------ */ - /** - * @return true if SSL Session caching is enabled - */ - public boolean isSessionCachingEnabled() - { - return _sessionCachingEnabled; - } - - /* ------------------------------------------------------------ */ - /** Set the flag to enable SSL Session caching. - * @param enableSessionCaching the value of the flag - */ - public void setSessionCachingEnabled(boolean enableSessionCaching) - { - _sessionCachingEnabled = enableSessionCaching; - } - - /* ------------------------------------------------------------ */ - /** Get SSL session cache size. - * @return SSL session cache size - */ - public int getSslSessionCacheSize() - { - return _sslSessionCacheSize; - } - - /* ------------------------------------------------------------ */ - /** SEt SSL session cache size. - * @param sslSessionCacheSize SSL session cache size to set - */ - public void setSslSessionCacheSize(int sslSessionCacheSize) - { - _sslSessionCacheSize = sslSessionCacheSize; - } - - /* ------------------------------------------------------------ */ - /** Get SSL session timeout. - * @return SSL session timeout - */ - public int getSslSessionTimeout() - { - return _sslSessionTimeout; - } - - /* ------------------------------------------------------------ */ - /** Set SSL session timeout. - * @param sslSessionTimeout SSL session timeout to set - */ - public void setSslSessionTimeout(int sslSessionTimeout) - { - _sslSessionTimeout = sslSessionTimeout; - } - - - /* ------------------------------------------------------------ */ - public SSLServerSocket newSslServerSocket(String host,int port,int backlog) throws IOException - { - SSLServerSocketFactory factory = _context.getServerSocketFactory(); - - SSLServerSocket socket = - (SSLServerSocket) (host==null ? - factory.createServerSocket(port,backlog): - factory.createServerSocket(port,backlog,InetAddress.getByName(host))); - - if (getWantClientAuth()) - socket.setWantClientAuth(getWantClientAuth()); - if (getNeedClientAuth()) - socket.setNeedClientAuth(getNeedClientAuth()); - - socket.setEnabledCipherSuites(selectCipherSuites( - socket.getEnabledCipherSuites(), - socket.getSupportedCipherSuites())); - socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols())); - - return socket; - } - - /* ------------------------------------------------------------ */ - public SSLSocket newSslSocket() throws IOException - { - SSLSocketFactory factory = _context.getSocketFactory(); - - SSLSocket socket = (SSLSocket)factory.createSocket(); - - if (getWantClientAuth()) - socket.setWantClientAuth(getWantClientAuth()); - if (getNeedClientAuth()) - socket.setNeedClientAuth(getNeedClientAuth()); - - socket.setEnabledCipherSuites(selectCipherSuites( - socket.getEnabledCipherSuites(), - socket.getSupportedCipherSuites())); - socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols())); - - return socket; - } - - /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine(String host,int port) - { - SSLEngine sslEngine=isSessionCachingEnabled() - ?_context.createSSLEngine(host, port) - :_context.createSSLEngine(); - - customize(sslEngine); - return sslEngine; - } - - /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine() - { - SSLEngine sslEngine=_context.createSSLEngine(); - customize(sslEngine); - return sslEngine; - } - - /* ------------------------------------------------------------ */ - public void customize(SSLEngine sslEngine) - { - if (getWantClientAuth()) - sslEngine.setWantClientAuth(getWantClientAuth()); - if (getNeedClientAuth()) - sslEngine.setNeedClientAuth(getNeedClientAuth()); - - sslEngine.setEnabledCipherSuites(selectCipherSuites( - sslEngine.getEnabledCipherSuites(), - sslEngine.getSupportedCipherSuites())); - - sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols())); - } - - /* ------------------------------------------------------------ */ - public String toString() - { - return String.format("%s@%x(%s,%s)", - getClass().getSimpleName(), - hashCode(), - _keyStorePath, - _trustStorePath); - } -}
--- a/src/org/eclipse/jetty/util/thread/jmx/QueuedThreadPool-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -QueuedThreadPool: A thread pool with no max bound by default -minThreads: Minimum number of threads in the pool -maxThreads: Maximum number threads in the pool -maxQueued: The maximum size of the job queue or -1 for unbounded. -name: Name of the thread pool -daemon: Is pool thread using daemon thread -threadsPriority: The priority of threads in the pool -maxIdleTimeMs: Maximum time a thread may be idle in ms -detailedDump: Full stack detail in dump output -dump(): Dump thread state -stopThread(long): Stop a pool thread -stopThread(long)[0]: id:Thread ID -interruptThread(long): Interrupt a pool thread -interruptThread(long)[0]: id:Thread ID -dumpThread(long): Dump a pool thread stack -dumpThread(long)[0]: id:Thread ID
--- a/src/org/eclipse/jetty/util/thread/jmx/ThreadPool-mbean.properties Thu Nov 10 03:08:20 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -ThreadPool: Pool of threads -threads: RO:Number of Threads in pool -idleThreads: RO:Number of idle Threads in pool -lowOnThreads: RO:Indicates the pool is low on available threads.