Fixing CRLF files
This commit is contained in:
parent
0638ad1bd9
commit
edaefdbb3b
|
@ -1,96 +1,96 @@
|
|||
<copyright>
|
||||
<year>1995-2017</year>
|
||||
<holder>Mort Bay Consulting Pty. Ltd.</holder>
|
||||
</copyright>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>{revnumber}</revnumber>
|
||||
<date>
|
||||
<?dbtimestamp format="Y-m-d H:M:S"?>
|
||||
</date>
|
||||
<revdescription>
|
||||
</copyright>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>{revnumber}</revnumber>
|
||||
<date>
|
||||
<?dbtimestamp format="Y-m-d H:M:S"?>
|
||||
</date>
|
||||
<revdescription>
|
||||
<para>This documentation is produced and contributed to under the Eclipse Public License v1.0.</para>
|
||||
</revdescription>
|
||||
</revision>
|
||||
</revhistory>
|
||||
<keywordset>
|
||||
<keyword>jetty</keyword>
|
||||
<keyword>servlet</keyword>
|
||||
<keyword>servlet-api</keyword>
|
||||
<keyword>cometd</keyword>
|
||||
<keyword>http</keyword>
|
||||
<keyword>websocket</keyword>
|
||||
<keyword>eclipse</keyword>
|
||||
<keyword>maven</keyword>
|
||||
<keyword>java</keyword>
|
||||
<keyword>server</keyword>
|
||||
<keyword>software</keyword>
|
||||
</keywordset>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Jan</firstname>
|
||||
<surname>Bartel</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Project Lead</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Becker</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Simone</firstname>
|
||||
<surname>Bordet</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Joakim</firstname>
|
||||
<surname>Erdfelt</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Jesse</firstname>
|
||||
<surname>McConnell</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Greg</firstname>
|
||||
<surname>Wilkins</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Project Lead</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<editor>
|
||||
<personname>
|
||||
<firstname>Shirley</firstname>
|
||||
<surname>Boulay</surname>
|
||||
</personname>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
</revdescription>
|
||||
</revision>
|
||||
</revhistory>
|
||||
<keywordset>
|
||||
<keyword>jetty</keyword>
|
||||
<keyword>servlet</keyword>
|
||||
<keyword>servlet-api</keyword>
|
||||
<keyword>cometd</keyword>
|
||||
<keyword>http</keyword>
|
||||
<keyword>websocket</keyword>
|
||||
<keyword>eclipse</keyword>
|
||||
<keyword>maven</keyword>
|
||||
<keyword>java</keyword>
|
||||
<keyword>server</keyword>
|
||||
<keyword>software</keyword>
|
||||
</keywordset>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Jan</firstname>
|
||||
<surname>Bartel</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Project Lead</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Becker</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Simone</firstname>
|
||||
<surname>Bordet</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Joakim</firstname>
|
||||
<surname>Erdfelt</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Jesse</firstname>
|
||||
<surname>McConnell</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Committer</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Greg</firstname>
|
||||
<surname>Wilkins</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<shortaffil>Jetty</shortaffil>
|
||||
<jobtitle>Project Lead</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
<editor>
|
||||
<personname>
|
||||
<firstname>Shirley</firstname>
|
||||
<surname>Boulay</surname>
|
||||
</personname>
|
||||
</editor>
|
||||
</authorgroup>
|
||||
|
|
|
@ -1,162 +1,162 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Authenticator.Result;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
|
||||
/**
|
||||
* Jetty handler that bridges requests to {@link HttpHandler}.
|
||||
*/
|
||||
public class HttpSpiContextHandler extends ContextHandler
|
||||
{
|
||||
public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class);
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpHandler _httpHandler;
|
||||
|
||||
public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler)
|
||||
{
|
||||
this._httpContext = httpContext;
|
||||
this._httpHandler = httpHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
|
||||
{
|
||||
if (!target.startsWith(getContextPath()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HttpExchange jettyHttpExchange;
|
||||
if (baseRequest.isSecure())
|
||||
{
|
||||
jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp);
|
||||
}
|
||||
else
|
||||
{
|
||||
jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp);
|
||||
}
|
||||
|
||||
// TODO: add filters processing
|
||||
|
||||
try
|
||||
{
|
||||
Authenticator auth = _httpContext.getAuthenticator();
|
||||
if (auth != null)
|
||||
{
|
||||
handleAuthentication(resp,jettyHttpExchange,auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpHandler.handle(jettyHttpExchange);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.debug(ex);
|
||||
PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody());
|
||||
|
||||
resp.setStatus(500);
|
||||
writer.println("<h2>HTTP ERROR: 500</h2>");
|
||||
writer.println("<pre>INTERNAL_SERVER_ERROR</pre>");
|
||||
writer.println("<p>RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "</p>");
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
writer.println("<pre>");
|
||||
ex.printStackTrace(writer);
|
||||
writer.println("</pre>");
|
||||
}
|
||||
|
||||
baseRequest.getHttpChannel().getHttpConfiguration().writePoweredBy(writer,"<p>","</p>");
|
||||
|
||||
writer.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException
|
||||
{
|
||||
Result result = auth.authenticate(httpExchange);
|
||||
if (result instanceof Authenticator.Failure)
|
||||
{
|
||||
int rc = ((Authenticator.Failure)result).getResponseCode();
|
||||
for (Map.Entry<String,List<String>> header : httpExchange.getResponseHeaders().entrySet())
|
||||
{
|
||||
for (String value : header.getValue())
|
||||
resp.addHeader(header.getKey(),value);
|
||||
}
|
||||
resp.sendError(rc);
|
||||
}
|
||||
else if (result instanceof Authenticator.Retry)
|
||||
{
|
||||
int rc = ((Authenticator.Retry)result).getResponseCode();
|
||||
for (Map.Entry<String,List<String>> header : httpExchange.getResponseHeaders().entrySet())
|
||||
{
|
||||
for (String value : header.getValue())
|
||||
resp.addHeader(header.getKey(),value);
|
||||
}
|
||||
resp.setStatus(rc);
|
||||
resp.flushBuffer();
|
||||
}
|
||||
else if (result instanceof Authenticator.Success)
|
||||
{
|
||||
HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal();
|
||||
((JettyExchange)httpExchange).setPrincipal(principal);
|
||||
_httpHandler.handle(httpExchange);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHandler getHttpHandler()
|
||||
{
|
||||
return _httpHandler;
|
||||
}
|
||||
|
||||
public void setHttpHandler(HttpHandler handler)
|
||||
{
|
||||
this._httpHandler = handler;
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Authenticator.Result;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
|
||||
/**
|
||||
* Jetty handler that bridges requests to {@link HttpHandler}.
|
||||
*/
|
||||
public class HttpSpiContextHandler extends ContextHandler
|
||||
{
|
||||
public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class);
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpHandler _httpHandler;
|
||||
|
||||
public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler)
|
||||
{
|
||||
this._httpContext = httpContext;
|
||||
this._httpHandler = httpHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
|
||||
{
|
||||
if (!target.startsWith(getContextPath()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HttpExchange jettyHttpExchange;
|
||||
if (baseRequest.isSecure())
|
||||
{
|
||||
jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp);
|
||||
}
|
||||
else
|
||||
{
|
||||
jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp);
|
||||
}
|
||||
|
||||
// TODO: add filters processing
|
||||
|
||||
try
|
||||
{
|
||||
Authenticator auth = _httpContext.getAuthenticator();
|
||||
if (auth != null)
|
||||
{
|
||||
handleAuthentication(resp,jettyHttpExchange,auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpHandler.handle(jettyHttpExchange);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOG.debug(ex);
|
||||
PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody());
|
||||
|
||||
resp.setStatus(500);
|
||||
writer.println("<h2>HTTP ERROR: 500</h2>");
|
||||
writer.println("<pre>INTERNAL_SERVER_ERROR</pre>");
|
||||
writer.println("<p>RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "</p>");
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
writer.println("<pre>");
|
||||
ex.printStackTrace(writer);
|
||||
writer.println("</pre>");
|
||||
}
|
||||
|
||||
baseRequest.getHttpChannel().getHttpConfiguration().writePoweredBy(writer,"<p>","</p>");
|
||||
|
||||
writer.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException
|
||||
{
|
||||
Result result = auth.authenticate(httpExchange);
|
||||
if (result instanceof Authenticator.Failure)
|
||||
{
|
||||
int rc = ((Authenticator.Failure)result).getResponseCode();
|
||||
for (Map.Entry<String,List<String>> header : httpExchange.getResponseHeaders().entrySet())
|
||||
{
|
||||
for (String value : header.getValue())
|
||||
resp.addHeader(header.getKey(),value);
|
||||
}
|
||||
resp.sendError(rc);
|
||||
}
|
||||
else if (result instanceof Authenticator.Retry)
|
||||
{
|
||||
int rc = ((Authenticator.Retry)result).getResponseCode();
|
||||
for (Map.Entry<String,List<String>> header : httpExchange.getResponseHeaders().entrySet())
|
||||
{
|
||||
for (String value : header.getValue())
|
||||
resp.addHeader(header.getKey(),value);
|
||||
}
|
||||
resp.setStatus(rc);
|
||||
resp.flushBuffer();
|
||||
}
|
||||
else if (result instanceof Authenticator.Success)
|
||||
{
|
||||
HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal();
|
||||
((JettyExchange)httpExchange).setPrincipal(principal);
|
||||
_httpHandler.handle(httpExchange);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHandler getHttpHandler()
|
||||
{
|
||||
return _httpHandler;
|
||||
}
|
||||
|
||||
public void setHttpHandler(HttpHandler handler)
|
||||
{
|
||||
this._httpHandler = handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,111 +1,111 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Filter;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpContext}
|
||||
*/
|
||||
public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
|
||||
{
|
||||
|
||||
private HttpSpiContextHandler _jettyContextHandler;
|
||||
|
||||
private HttpServer _server;
|
||||
|
||||
private Map<String,Object> _attributes = new HashMap<String,Object>();
|
||||
|
||||
private List<Filter> _filters = new ArrayList<Filter>();
|
||||
|
||||
private Authenticator _authenticator;
|
||||
|
||||
|
||||
protected JettyHttpContext(HttpServer server, String path,
|
||||
HttpHandler handler)
|
||||
{
|
||||
this._server = server;
|
||||
_jettyContextHandler = new HttpSpiContextHandler(this, handler);
|
||||
_jettyContextHandler.setContextPath(path);
|
||||
}
|
||||
|
||||
protected HttpSpiContextHandler getJettyContextHandler()
|
||||
{
|
||||
return _jettyContextHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler()
|
||||
{
|
||||
return _jettyContextHandler.getHttpHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandler(HttpHandler h)
|
||||
{
|
||||
_jettyContextHandler.setHttpHandler(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath()
|
||||
{
|
||||
return _jettyContextHandler.getContextPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes()
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Filter> getFilters()
|
||||
{
|
||||
return _filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator setAuthenticator(Authenticator auth)
|
||||
{
|
||||
Authenticator previous = _authenticator;
|
||||
_authenticator = auth;
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator getAuthenticator()
|
||||
{
|
||||
return _authenticator;
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.net.httpserver.Authenticator;
|
||||
import com.sun.net.httpserver.Filter;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpContext}
|
||||
*/
|
||||
public class JettyHttpContext extends com.sun.net.httpserver.HttpContext
|
||||
{
|
||||
|
||||
private HttpSpiContextHandler _jettyContextHandler;
|
||||
|
||||
private HttpServer _server;
|
||||
|
||||
private Map<String,Object> _attributes = new HashMap<String,Object>();
|
||||
|
||||
private List<Filter> _filters = new ArrayList<Filter>();
|
||||
|
||||
private Authenticator _authenticator;
|
||||
|
||||
|
||||
protected JettyHttpContext(HttpServer server, String path,
|
||||
HttpHandler handler)
|
||||
{
|
||||
this._server = server;
|
||||
_jettyContextHandler = new HttpSpiContextHandler(this, handler);
|
||||
_jettyContextHandler.setContextPath(path);
|
||||
}
|
||||
|
||||
protected HttpSpiContextHandler getJettyContextHandler()
|
||||
{
|
||||
return _jettyContextHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler()
|
||||
{
|
||||
return _jettyContextHandler.getHttpHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandler(HttpHandler h)
|
||||
{
|
||||
_jettyContextHandler.setHttpHandler(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath()
|
||||
{
|
||||
return _jettyContextHandler.getContextPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes()
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Filter> getFilters()
|
||||
{
|
||||
return _filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator setAuthenticator(Authenticator auth)
|
||||
{
|
||||
Authenticator previous = _authenticator;
|
||||
_authenticator = auth;
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator getAuthenticator()
|
||||
{
|
||||
return _authenticator;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,233 +1,233 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpExchange}
|
||||
*/
|
||||
public class JettyHttpExchangeDelegate extends HttpExchange
|
||||
{
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpServletRequest _req;
|
||||
|
||||
private HttpServletResponse _resp;
|
||||
|
||||
private Headers _responseHeaders = new Headers();
|
||||
|
||||
private int _responseCode = 0;
|
||||
|
||||
private InputStream _is;
|
||||
|
||||
private OutputStream _os;
|
||||
|
||||
private HttpPrincipal _httpPrincipal;
|
||||
|
||||
JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp)
|
||||
{
|
||||
this._httpContext = jaxWsContext;
|
||||
this._req = req;
|
||||
this._resp = resp;
|
||||
try
|
||||
{
|
||||
this._is = req.getInputStream();
|
||||
this._os = resp.getOutputStream();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getRequestHeaders()
|
||||
{
|
||||
Headers headers = new Headers();
|
||||
Enumeration<?> en = _req.getHeaderNames();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
String name = (String)en.nextElement();
|
||||
Enumeration<?> en2 = _req.getHeaders(name);
|
||||
while (en2.hasMoreElements())
|
||||
{
|
||||
String value = (String)en2.nextElement();
|
||||
headers.add(name,value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getResponseHeaders()
|
||||
{
|
||||
return _responseHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestURI()
|
||||
{
|
||||
try
|
||||
{
|
||||
String uriAsString = _req.getRequestURI();
|
||||
if (_req.getQueryString() != null)
|
||||
{
|
||||
uriAsString += "?" + _req.getQueryString();
|
||||
}
|
||||
|
||||
return new URI(uriAsString);
|
||||
}
|
||||
catch (URISyntaxException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestMethod()
|
||||
{
|
||||
return _req.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContext getHttpContext()
|
||||
{
|
||||
return _httpContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
_resp.getOutputStream().close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getRequestBody()
|
||||
{
|
||||
return _is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getResponseBody()
|
||||
{
|
||||
return _os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendResponseHeaders(int rCode, long responseLength) throws IOException
|
||||
{
|
||||
this._responseCode = rCode;
|
||||
|
||||
for (Map.Entry<String, List<String>> stringListEntry : _responseHeaders.entrySet())
|
||||
{
|
||||
String name = stringListEntry.getKey();
|
||||
List<String> values = stringListEntry.getValue();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
_resp.setHeader(name,value);
|
||||
}
|
||||
}
|
||||
if (responseLength > 0)
|
||||
{
|
||||
_resp.setHeader("content-length","" + responseLength);
|
||||
}
|
||||
_resp.setStatus(rCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResponseCode()
|
||||
{
|
||||
return _responseCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol()
|
||||
{
|
||||
return _req.getProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return _req.getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value)
|
||||
{
|
||||
_req.setAttribute(name,value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStreams(InputStream i, OutputStream o)
|
||||
{
|
||||
_is = i;
|
||||
_os = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPrincipal getPrincipal()
|
||||
{
|
||||
return _httpPrincipal;
|
||||
}
|
||||
|
||||
public void setPrincipal(HttpPrincipal principal)
|
||||
{
|
||||
this._httpPrincipal = principal;
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpContext;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpPrincipal;
|
||||
|
||||
/**
|
||||
* Jetty implementation of {@link com.sun.net.httpserver.HttpExchange}
|
||||
*/
|
||||
public class JettyHttpExchangeDelegate extends HttpExchange
|
||||
{
|
||||
|
||||
private HttpContext _httpContext;
|
||||
|
||||
private HttpServletRequest _req;
|
||||
|
||||
private HttpServletResponse _resp;
|
||||
|
||||
private Headers _responseHeaders = new Headers();
|
||||
|
||||
private int _responseCode = 0;
|
||||
|
||||
private InputStream _is;
|
||||
|
||||
private OutputStream _os;
|
||||
|
||||
private HttpPrincipal _httpPrincipal;
|
||||
|
||||
JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp)
|
||||
{
|
||||
this._httpContext = jaxWsContext;
|
||||
this._req = req;
|
||||
this._resp = resp;
|
||||
try
|
||||
{
|
||||
this._is = req.getInputStream();
|
||||
this._os = resp.getOutputStream();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getRequestHeaders()
|
||||
{
|
||||
Headers headers = new Headers();
|
||||
Enumeration<?> en = _req.getHeaderNames();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
String name = (String)en.nextElement();
|
||||
Enumeration<?> en2 = _req.getHeaders(name);
|
||||
while (en2.hasMoreElements())
|
||||
{
|
||||
String value = (String)en2.nextElement();
|
||||
headers.add(name,value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Headers getResponseHeaders()
|
||||
{
|
||||
return _responseHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestURI()
|
||||
{
|
||||
try
|
||||
{
|
||||
String uriAsString = _req.getRequestURI();
|
||||
if (_req.getQueryString() != null)
|
||||
{
|
||||
uriAsString += "?" + _req.getQueryString();
|
||||
}
|
||||
|
||||
return new URI(uriAsString);
|
||||
}
|
||||
catch (URISyntaxException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestMethod()
|
||||
{
|
||||
return _req.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContext getHttpContext()
|
||||
{
|
||||
return _httpContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
_resp.getOutputStream().close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getRequestBody()
|
||||
{
|
||||
return _is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getResponseBody()
|
||||
{
|
||||
return _os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendResponseHeaders(int rCode, long responseLength) throws IOException
|
||||
{
|
||||
this._responseCode = rCode;
|
||||
|
||||
for (Map.Entry<String, List<String>> stringListEntry : _responseHeaders.entrySet())
|
||||
{
|
||||
String name = stringListEntry.getKey();
|
||||
List<String> values = stringListEntry.getValue();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
_resp.setHeader(name,value);
|
||||
}
|
||||
}
|
||||
if (responseLength > 0)
|
||||
{
|
||||
_resp.setHeader("content-length","" + responseLength);
|
||||
}
|
||||
_resp.setStatus(rCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResponseCode()
|
||||
{
|
||||
return _responseCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol()
|
||||
{
|
||||
return _req.getProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name)
|
||||
{
|
||||
return _req.getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object value)
|
||||
{
|
||||
_req.setAttribute(name,value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStreams(InputStream i, OutputStream o)
|
||||
{
|
||||
_is = i;
|
||||
_os = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPrincipal getPrincipal()
|
||||
{
|
||||
return _httpPrincipal;
|
||||
}
|
||||
|
||||
public void setPrincipal(HttpPrincipal principal)
|
||||
{
|
||||
this._httpPrincipal = principal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,80 +1,80 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import com.sun.net.httpserver.spi.HttpServerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
/**
|
||||
* Jetty implementation of <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/index.html">Java HTTP Server SPI</a>
|
||||
*/
|
||||
public class JettyHttpServerProvider extends HttpServerProvider
|
||||
{
|
||||
|
||||
private static Server _server;
|
||||
|
||||
public static void setServer(Server server)
|
||||
{
|
||||
_server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer createHttpServer(InetSocketAddress addr, int backlog)
|
||||
throws IOException
|
||||
{
|
||||
Server server = _server;
|
||||
boolean shared = true;
|
||||
|
||||
if (server == null)
|
||||
{
|
||||
ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool());
|
||||
server = new Server(threadPool);
|
||||
|
||||
HandlerCollection handlerCollection = new HandlerCollection();
|
||||
handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()});
|
||||
server.setHandler(handlerCollection);
|
||||
|
||||
shared = false;
|
||||
}
|
||||
|
||||
JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared);
|
||||
if (addr != null)
|
||||
jettyHttpServer.bind(addr, backlog);
|
||||
return jettyHttpServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.spi;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import com.sun.net.httpserver.spi.HttpServerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
/**
|
||||
* Jetty implementation of <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/index.html">Java HTTP Server SPI</a>
|
||||
*/
|
||||
public class JettyHttpServerProvider extends HttpServerProvider
|
||||
{
|
||||
|
||||
private static Server _server;
|
||||
|
||||
public static void setServer(Server server)
|
||||
{
|
||||
_server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServer createHttpServer(InetSocketAddress addr, int backlog)
|
||||
throws IOException
|
||||
{
|
||||
Server server = _server;
|
||||
boolean shared = true;
|
||||
|
||||
if (server == null)
|
||||
{
|
||||
ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool());
|
||||
server = new Server(threadPool);
|
||||
|
||||
HandlerCollection handlerCollection = new HandlerCollection();
|
||||
handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()});
|
||||
server.setHandler(handlerCollection);
|
||||
|
||||
shared = false;
|
||||
}
|
||||
|
||||
JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared);
|
||||
if (addr != null)
|
||||
jettyHttpServer.bind(addr, backlog);
|
||||
return jettyHttpServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,78 +1,78 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.maven.plugin;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This goal is used to run Jetty with a pre-assembled war.
|
||||
* </p>
|
||||
* <p>
|
||||
* It accepts exactly the same options as the <a href="run-war-mojo.html">run-war</a> goal.
|
||||
* However, it doesn't assume that the current artifact is a
|
||||
* webapp and doesn't try to assemble it into a war before its execution.
|
||||
* So using it makes sense only when used in conjunction with the
|
||||
* <a href="run-war-mojo.html#webApp">war</a> configuration parameter pointing to a pre-built WAR.
|
||||
* </p>
|
||||
* <p>
|
||||
* This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested
|
||||
* HTTP client components.
|
||||
* </p>
|
||||
*
|
||||
* @goal deploy-war
|
||||
* @requiresDependencyResolution runtime
|
||||
* @execute phase="validate"
|
||||
* @description Deploy a pre-assembled war
|
||||
*
|
||||
*/
|
||||
public class JettyDeployWar extends JettyRunWarMojo
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* If true, the plugin should continue and not block. Otherwise the
|
||||
* plugin will block further execution and you will need to use
|
||||
* cntrl-c to stop it.
|
||||
*
|
||||
*
|
||||
* @parameter default-value="true"
|
||||
*/
|
||||
protected boolean daemon = true;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException
|
||||
{
|
||||
nonblocking = daemon;
|
||||
super.execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finishConfigurationBeforeStart() throws Exception
|
||||
{
|
||||
super.finishConfigurationBeforeStart();
|
||||
//only stop the server at shutdown if we are blocking
|
||||
server.setStopAtShutdown(!nonblocking);
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.maven.plugin;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This goal is used to run Jetty with a pre-assembled war.
|
||||
* </p>
|
||||
* <p>
|
||||
* It accepts exactly the same options as the <a href="run-war-mojo.html">run-war</a> goal.
|
||||
* However, it doesn't assume that the current artifact is a
|
||||
* webapp and doesn't try to assemble it into a war before its execution.
|
||||
* So using it makes sense only when used in conjunction with the
|
||||
* <a href="run-war-mojo.html#webApp">war</a> configuration parameter pointing to a pre-built WAR.
|
||||
* </p>
|
||||
* <p>
|
||||
* This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested
|
||||
* HTTP client components.
|
||||
* </p>
|
||||
*
|
||||
* @goal deploy-war
|
||||
* @requiresDependencyResolution runtime
|
||||
* @execute phase="validate"
|
||||
* @description Deploy a pre-assembled war
|
||||
*
|
||||
*/
|
||||
public class JettyDeployWar extends JettyRunWarMojo
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* If true, the plugin should continue and not block. Otherwise the
|
||||
* plugin will block further execution and you will need to use
|
||||
* cntrl-c to stop it.
|
||||
*
|
||||
*
|
||||
* @parameter default-value="true"
|
||||
*/
|
||||
protected boolean daemon = true;
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException
|
||||
{
|
||||
nonblocking = daemon;
|
||||
super.execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finishConfigurationBeforeStart() throws Exception
|
||||
{
|
||||
super.finishConfigurationBeforeStart();
|
||||
//only stop the server at shutdown if we are blocking
|
||||
server.setStopAtShutdown(!nonblocking);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,182 +1,182 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.security;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.util.security.Password;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Some requests for static data that is served by ResourceHandler, but some is secured.
|
||||
* <p>
|
||||
* This is mainly here to test security bypass techniques using aliased names that should be caught.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class AliasedConstraintTest
|
||||
{
|
||||
private static final String TEST_REALM = "TestRealm";
|
||||
private static Server server;
|
||||
private static LocalConnector connector;
|
||||
private static ConstraintSecurityHandler security;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
connector = new LocalConnector(server);
|
||||
server.setConnectors(new Connector[] { connector });
|
||||
|
||||
ContextHandler context = new ContextHandler();
|
||||
SessionHandler session = new SessionHandler();
|
||||
|
||||
HashLoginService loginService = new HashLoginService(TEST_REALM);
|
||||
loginService.putUser("user0",new Password("password"),new String[] {});
|
||||
loginService.putUser("user",new Password("password"),new String[] { "user" });
|
||||
loginService.putUser("user2",new Password("password"),new String[] { "user" });
|
||||
loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" });
|
||||
loginService.putUser("user3",new Password("password"),new String[] { "foo" });
|
||||
|
||||
context.setContextPath("/ctx");
|
||||
context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath());
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[]{context,new DefaultHandler()});
|
||||
server.setHandler(handlers);
|
||||
context.setHandler(session);
|
||||
// context.addAliasCheck(new AllowSymLinkAliasChecker());
|
||||
|
||||
server.addBean(loginService);
|
||||
|
||||
security = new ConstraintSecurityHandler();
|
||||
session.setHandler(security);
|
||||
ResourceHandler handler = new ResourceHandler();
|
||||
security.setHandler(handler);
|
||||
|
||||
List<ConstraintMapping> constraints = new ArrayList<>();
|
||||
|
||||
Constraint constraint0 = new Constraint();
|
||||
constraint0.setAuthenticate(true);
|
||||
constraint0.setName("forbid");
|
||||
ConstraintMapping mapping0 = new ConstraintMapping();
|
||||
mapping0.setPathSpec("/forbid/*");
|
||||
mapping0.setConstraint(constraint0);
|
||||
constraints.add(mapping0);
|
||||
|
||||
Set<String> knownRoles = new HashSet<>();
|
||||
knownRoles.add("user");
|
||||
knownRoles.add("administrator");
|
||||
|
||||
security.setConstraintMappings(constraints,knownRoles);
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}: {1}")
|
||||
public static Collection<Object[]> data()
|
||||
{
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
final String OPENCONTENT = "this is open content";
|
||||
|
||||
data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT });
|
||||
data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT });
|
||||
data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null });
|
||||
data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null });
|
||||
data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Parameter(value = 0)
|
||||
public String uri;
|
||||
|
||||
@Parameter(value = 1)
|
||||
public int expectedStatusCode;
|
||||
|
||||
@Parameter(value = 2)
|
||||
public String expectedContent;
|
||||
|
||||
@Test
|
||||
public void testAccess() throws Exception
|
||||
{
|
||||
StringBuilder request = new StringBuilder();
|
||||
request.append("GET ").append(uri).append(" HTTP/1.1\r\n");
|
||||
request.append("Host: localhost\r\n");
|
||||
request.append("Connection: close\r\n");
|
||||
request.append("\r\n");
|
||||
|
||||
String response = connector.getResponses(request.toString());
|
||||
|
||||
switch (expectedStatusCode)
|
||||
{
|
||||
case 200:
|
||||
assertThat(response,startsWith("HTTP/1.1 200 OK"));
|
||||
break;
|
||||
case 403:
|
||||
assertThat(response,startsWith("HTTP/1.1 403 Forbidden"));
|
||||
break;
|
||||
case 404:
|
||||
assertThat(response,startsWith("HTTP/1.1 404 Not Found"));
|
||||
break;
|
||||
default:
|
||||
fail("Write a handler for response status code: " + expectedStatusCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (expectedContent != null)
|
||||
{
|
||||
assertThat(response,containsString("this is open content"));
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.security;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.util.security.Password;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Some requests for static data that is served by ResourceHandler, but some is secured.
|
||||
* <p>
|
||||
* This is mainly here to test security bypass techniques using aliased names that should be caught.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class AliasedConstraintTest
|
||||
{
|
||||
private static final String TEST_REALM = "TestRealm";
|
||||
private static Server server;
|
||||
private static LocalConnector connector;
|
||||
private static ConstraintSecurityHandler security;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
connector = new LocalConnector(server);
|
||||
server.setConnectors(new Connector[] { connector });
|
||||
|
||||
ContextHandler context = new ContextHandler();
|
||||
SessionHandler session = new SessionHandler();
|
||||
|
||||
HashLoginService loginService = new HashLoginService(TEST_REALM);
|
||||
loginService.putUser("user0",new Password("password"),new String[] {});
|
||||
loginService.putUser("user",new Password("password"),new String[] { "user" });
|
||||
loginService.putUser("user2",new Password("password"),new String[] { "user" });
|
||||
loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" });
|
||||
loginService.putUser("user3",new Password("password"),new String[] { "foo" });
|
||||
|
||||
context.setContextPath("/ctx");
|
||||
context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath());
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[]{context,new DefaultHandler()});
|
||||
server.setHandler(handlers);
|
||||
context.setHandler(session);
|
||||
// context.addAliasCheck(new AllowSymLinkAliasChecker());
|
||||
|
||||
server.addBean(loginService);
|
||||
|
||||
security = new ConstraintSecurityHandler();
|
||||
session.setHandler(security);
|
||||
ResourceHandler handler = new ResourceHandler();
|
||||
security.setHandler(handler);
|
||||
|
||||
List<ConstraintMapping> constraints = new ArrayList<>();
|
||||
|
||||
Constraint constraint0 = new Constraint();
|
||||
constraint0.setAuthenticate(true);
|
||||
constraint0.setName("forbid");
|
||||
ConstraintMapping mapping0 = new ConstraintMapping();
|
||||
mapping0.setPathSpec("/forbid/*");
|
||||
mapping0.setConstraint(constraint0);
|
||||
constraints.add(mapping0);
|
||||
|
||||
Set<String> knownRoles = new HashSet<>();
|
||||
knownRoles.add("user");
|
||||
knownRoles.add("administrator");
|
||||
|
||||
security.setConstraintMappings(constraints,knownRoles);
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}: {1}")
|
||||
public static Collection<Object[]> data()
|
||||
{
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
final String OPENCONTENT = "this is open content";
|
||||
|
||||
data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT });
|
||||
data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT });
|
||||
data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null });
|
||||
data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null });
|
||||
data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Parameter(value = 0)
|
||||
public String uri;
|
||||
|
||||
@Parameter(value = 1)
|
||||
public int expectedStatusCode;
|
||||
|
||||
@Parameter(value = 2)
|
||||
public String expectedContent;
|
||||
|
||||
@Test
|
||||
public void testAccess() throws Exception
|
||||
{
|
||||
StringBuilder request = new StringBuilder();
|
||||
request.append("GET ").append(uri).append(" HTTP/1.1\r\n");
|
||||
request.append("Host: localhost\r\n");
|
||||
request.append("Connection: close\r\n");
|
||||
request.append("\r\n");
|
||||
|
||||
String response = connector.getResponses(request.toString());
|
||||
|
||||
switch (expectedStatusCode)
|
||||
{
|
||||
case 200:
|
||||
assertThat(response,startsWith("HTTP/1.1 200 OK"));
|
||||
break;
|
||||
case 403:
|
||||
assertThat(response,startsWith("HTTP/1.1 403 Forbidden"));
|
||||
break;
|
||||
case 404:
|
||||
assertThat(response,startsWith("HTTP/1.1 404 Not Found"));
|
||||
break;
|
||||
default:
|
||||
fail("Write a handler for response status code: " + expectedStatusCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (expectedContent != null)
|
||||
{
|
||||
assertThat(response,containsString("this is open content"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,409 +1,409 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.servlets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.io.ManagedSelector;
|
||||
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThreadStarvationTest
|
||||
{
|
||||
@Rule
|
||||
public TestTracker tracker = new TestTracker();
|
||||
private Server _server;
|
||||
|
||||
@After
|
||||
public void dispose() throws Exception
|
||||
{
|
||||
if (_server != null)
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Slow
|
||||
public void testDefaultServletSuccess() throws Exception
|
||||
{
|
||||
int maxThreads = 10;
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads);
|
||||
threadPool.setDetailedDump(true);
|
||||
_server = new Server(threadPool);
|
||||
|
||||
// Prepare a big file to download.
|
||||
File directory = MavenTestingUtils.getTargetTestingDir();
|
||||
Files.createDirectories(directory.toPath());
|
||||
String resourceName = "resource.bin";
|
||||
Path resourcePath = Paths.get(directory.getPath(), resourceName);
|
||||
try (OutputStream output = Files.newOutputStream(resourcePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE))
|
||||
{
|
||||
byte[] chunk = new byte[1024];
|
||||
Arrays.fill(chunk,(byte)'X');
|
||||
chunk[chunk.length-2]='\r';
|
||||
chunk[chunk.length-1]='\n';
|
||||
for (int i = 0; i < 256 * 1024; ++i)
|
||||
output.write(chunk);
|
||||
}
|
||||
|
||||
final CountDownLatch writePending = new CountDownLatch(1);
|
||||
ServerConnector connector = new ServerConnector(_server, 0, 1)
|
||||
{
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
|
||||
{
|
||||
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout())
|
||||
{
|
||||
@Override
|
||||
protected void onIncompleteFlush()
|
||||
{
|
||||
super.onIncompleteFlush();
|
||||
writePending.countDown();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
connector.setIdleTimeout(Long.MAX_VALUE);
|
||||
_server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler(_server, "/");
|
||||
context.setResourceBase(directory.toURI().toString());
|
||||
context.addServlet(DefaultServlet.class, "/*").setAsyncSupported(false);
|
||||
_server.setHandler(context);
|
||||
|
||||
_server.start();
|
||||
|
||||
List<Socket> sockets = new ArrayList<>();
|
||||
for (int i = 0; i < maxThreads*2; ++i)
|
||||
{
|
||||
Socket socket = new Socket("localhost", connector.getLocalPort());
|
||||
sockets.add(socket);
|
||||
OutputStream output = socket.getOutputStream();
|
||||
String request = "" +
|
||||
"GET /" + resourceName + " HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
output.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
output.flush();
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
// Wait for a the servlet to block.
|
||||
Assert.assertTrue(writePending.await(5, TimeUnit.SECONDS));
|
||||
|
||||
long expected = Files.size(resourcePath);
|
||||
byte[] buffer = new byte[48 * 1024];
|
||||
List<Exchanger<Long>> totals = new ArrayList<>();
|
||||
for (Socket socket : sockets)
|
||||
{
|
||||
final Exchanger<Long> x = new Exchanger<>();
|
||||
totals.add(x);
|
||||
final InputStream input = socket.getInputStream();
|
||||
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
long total=0;
|
||||
try
|
||||
{
|
||||
// look for CRLFCRLF
|
||||
StringBuilder header = new StringBuilder();
|
||||
int state=0;
|
||||
while (state<4 && header.length()<2048)
|
||||
{
|
||||
int ch=input.read();
|
||||
if (ch<0)
|
||||
break;
|
||||
header.append((char)ch);
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
if (ch=='\r')
|
||||
state=1;
|
||||
break;
|
||||
case 1:
|
||||
if (ch=='\n')
|
||||
state=2;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 2:
|
||||
if (ch=='\r')
|
||||
state=3;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 3:
|
||||
if (ch=='\n')
|
||||
state=4;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (total<expected)
|
||||
{
|
||||
int read=input.read(buffer);
|
||||
if (read<0)
|
||||
break;
|
||||
total+=read;
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
x.exchange(total);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
for (Exchanger<Long> x : totals)
|
||||
{
|
||||
Long total = x.exchange(-1L,10000,TimeUnit.SECONDS);
|
||||
Assert.assertEquals(expected,total.longValue());
|
||||
}
|
||||
|
||||
// We could read everything, good.
|
||||
for (Socket socket : sockets)
|
||||
socket.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureStarvation() throws Exception
|
||||
{
|
||||
try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
|
||||
{
|
||||
int acceptors = 0;
|
||||
int selectors = 1;
|
||||
int maxThreads = 10;
|
||||
final int barried=maxThreads-acceptors-selectors;
|
||||
final CyclicBarrier barrier = new CyclicBarrier(barried);
|
||||
|
||||
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads);
|
||||
threadPool.setDetailedDump(true);
|
||||
_server = new Server(threadPool);
|
||||
|
||||
|
||||
ServerConnector connector = new ServerConnector(_server, acceptors, selectors)
|
||||
{
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
|
||||
{
|
||||
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout())
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean flush(ByteBuffer... buffers) throws IOException
|
||||
{
|
||||
super.flush(buffers[0]);
|
||||
throw new IOException("TEST FAILURE");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
connector.setIdleTimeout(Long.MAX_VALUE);
|
||||
_server.addConnector(connector);
|
||||
|
||||
final AtomicInteger count = new AtomicInteger(0);
|
||||
_server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
int c=count.getAndIncrement();
|
||||
try
|
||||
{
|
||||
if (c<barried)
|
||||
{
|
||||
barrier.await(10,TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException | BrokenBarrierException | TimeoutException e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
}
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(200);
|
||||
response.setContentLength(13);
|
||||
response.getWriter().print("Hello World!\n");
|
||||
response.getWriter().flush();
|
||||
}
|
||||
});
|
||||
|
||||
_server.start();
|
||||
|
||||
List<Socket> sockets = new ArrayList<>();
|
||||
for (int i = 0; i < maxThreads*2; ++i)
|
||||
{
|
||||
Socket socket = new Socket("localhost", connector.getLocalPort());
|
||||
sockets.add(socket);
|
||||
OutputStream output = socket.getOutputStream();
|
||||
String request = "" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
// "Connection: close\r\n" +
|
||||
"\r\n";
|
||||
output.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
output.flush();
|
||||
}
|
||||
|
||||
|
||||
byte[] buffer = new byte[48 * 1024];
|
||||
List<Exchanger<Integer>> totals = new ArrayList<>();
|
||||
for (Socket socket : sockets)
|
||||
{
|
||||
final Exchanger<Integer> x = new Exchanger<>();
|
||||
totals.add(x);
|
||||
final InputStream input = socket.getInputStream();
|
||||
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int read=0;
|
||||
try
|
||||
{
|
||||
// look for CRLFCRLF
|
||||
StringBuilder header = new StringBuilder();
|
||||
int state=0;
|
||||
while (state<4 && header.length()<2048)
|
||||
{
|
||||
int ch=input.read();
|
||||
if (ch<0)
|
||||
break;
|
||||
header.append((char)ch);
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
if (ch=='\r')
|
||||
state=1;
|
||||
break;
|
||||
case 1:
|
||||
if (ch=='\n')
|
||||
state=2;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 2:
|
||||
if (ch=='\r')
|
||||
state=3;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 3:
|
||||
if (ch=='\n')
|
||||
state=4;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
read=input.read(buffer);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
x.exchange(read);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
for (Exchanger<Integer> x : totals)
|
||||
{
|
||||
Integer read = x.exchange(-1,10,TimeUnit.SECONDS);
|
||||
Assert.assertEquals(-1,read.intValue());
|
||||
}
|
||||
|
||||
// We could read everything, good.
|
||||
for (Socket socket : sockets)
|
||||
socket.close();
|
||||
|
||||
_server.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.servlets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.io.ManagedSelector;
|
||||
import org.eclipse.jetty.io.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThreadStarvationTest
|
||||
{
|
||||
@Rule
|
||||
public TestTracker tracker = new TestTracker();
|
||||
private Server _server;
|
||||
|
||||
@After
|
||||
public void dispose() throws Exception
|
||||
{
|
||||
if (_server != null)
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Slow
|
||||
public void testDefaultServletSuccess() throws Exception
|
||||
{
|
||||
int maxThreads = 10;
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads);
|
||||
threadPool.setDetailedDump(true);
|
||||
_server = new Server(threadPool);
|
||||
|
||||
// Prepare a big file to download.
|
||||
File directory = MavenTestingUtils.getTargetTestingDir();
|
||||
Files.createDirectories(directory.toPath());
|
||||
String resourceName = "resource.bin";
|
||||
Path resourcePath = Paths.get(directory.getPath(), resourceName);
|
||||
try (OutputStream output = Files.newOutputStream(resourcePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE))
|
||||
{
|
||||
byte[] chunk = new byte[1024];
|
||||
Arrays.fill(chunk,(byte)'X');
|
||||
chunk[chunk.length-2]='\r';
|
||||
chunk[chunk.length-1]='\n';
|
||||
for (int i = 0; i < 256 * 1024; ++i)
|
||||
output.write(chunk);
|
||||
}
|
||||
|
||||
final CountDownLatch writePending = new CountDownLatch(1);
|
||||
ServerConnector connector = new ServerConnector(_server, 0, 1)
|
||||
{
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
|
||||
{
|
||||
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout())
|
||||
{
|
||||
@Override
|
||||
protected void onIncompleteFlush()
|
||||
{
|
||||
super.onIncompleteFlush();
|
||||
writePending.countDown();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
connector.setIdleTimeout(Long.MAX_VALUE);
|
||||
_server.addConnector(connector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler(_server, "/");
|
||||
context.setResourceBase(directory.toURI().toString());
|
||||
context.addServlet(DefaultServlet.class, "/*").setAsyncSupported(false);
|
||||
_server.setHandler(context);
|
||||
|
||||
_server.start();
|
||||
|
||||
List<Socket> sockets = new ArrayList<>();
|
||||
for (int i = 0; i < maxThreads*2; ++i)
|
||||
{
|
||||
Socket socket = new Socket("localhost", connector.getLocalPort());
|
||||
sockets.add(socket);
|
||||
OutputStream output = socket.getOutputStream();
|
||||
String request = "" +
|
||||
"GET /" + resourceName + " HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"\r\n";
|
||||
output.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
output.flush();
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
// Wait for a the servlet to block.
|
||||
Assert.assertTrue(writePending.await(5, TimeUnit.SECONDS));
|
||||
|
||||
long expected = Files.size(resourcePath);
|
||||
byte[] buffer = new byte[48 * 1024];
|
||||
List<Exchanger<Long>> totals = new ArrayList<>();
|
||||
for (Socket socket : sockets)
|
||||
{
|
||||
final Exchanger<Long> x = new Exchanger<>();
|
||||
totals.add(x);
|
||||
final InputStream input = socket.getInputStream();
|
||||
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
long total=0;
|
||||
try
|
||||
{
|
||||
// look for CRLFCRLF
|
||||
StringBuilder header = new StringBuilder();
|
||||
int state=0;
|
||||
while (state<4 && header.length()<2048)
|
||||
{
|
||||
int ch=input.read();
|
||||
if (ch<0)
|
||||
break;
|
||||
header.append((char)ch);
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
if (ch=='\r')
|
||||
state=1;
|
||||
break;
|
||||
case 1:
|
||||
if (ch=='\n')
|
||||
state=2;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 2:
|
||||
if (ch=='\r')
|
||||
state=3;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 3:
|
||||
if (ch=='\n')
|
||||
state=4;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (total<expected)
|
||||
{
|
||||
int read=input.read(buffer);
|
||||
if (read<0)
|
||||
break;
|
||||
total+=read;
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
x.exchange(total);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
for (Exchanger<Long> x : totals)
|
||||
{
|
||||
Long total = x.exchange(-1L,10000,TimeUnit.SECONDS);
|
||||
Assert.assertEquals(expected,total.longValue());
|
||||
}
|
||||
|
||||
// We could read everything, good.
|
||||
for (Socket socket : sockets)
|
||||
socket.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureStarvation() throws Exception
|
||||
{
|
||||
try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
|
||||
{
|
||||
int acceptors = 0;
|
||||
int selectors = 1;
|
||||
int maxThreads = 10;
|
||||
final int barried=maxThreads-acceptors-selectors;
|
||||
final CyclicBarrier barrier = new CyclicBarrier(barried);
|
||||
|
||||
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads);
|
||||
threadPool.setDetailedDump(true);
|
||||
_server = new Server(threadPool);
|
||||
|
||||
|
||||
ServerConnector connector = new ServerConnector(_server, acceptors, selectors)
|
||||
{
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
|
||||
{
|
||||
return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout())
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean flush(ByteBuffer... buffers) throws IOException
|
||||
{
|
||||
super.flush(buffers[0]);
|
||||
throw new IOException("TEST FAILURE");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
connector.setIdleTimeout(Long.MAX_VALUE);
|
||||
_server.addConnector(connector);
|
||||
|
||||
final AtomicInteger count = new AtomicInteger(0);
|
||||
_server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
int c=count.getAndIncrement();
|
||||
try
|
||||
{
|
||||
if (c<barried)
|
||||
{
|
||||
barrier.await(10,TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException | BrokenBarrierException | TimeoutException e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
}
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(200);
|
||||
response.setContentLength(13);
|
||||
response.getWriter().print("Hello World!\n");
|
||||
response.getWriter().flush();
|
||||
}
|
||||
});
|
||||
|
||||
_server.start();
|
||||
|
||||
List<Socket> sockets = new ArrayList<>();
|
||||
for (int i = 0; i < maxThreads*2; ++i)
|
||||
{
|
||||
Socket socket = new Socket("localhost", connector.getLocalPort());
|
||||
sockets.add(socket);
|
||||
OutputStream output = socket.getOutputStream();
|
||||
String request = "" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
// "Connection: close\r\n" +
|
||||
"\r\n";
|
||||
output.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
output.flush();
|
||||
}
|
||||
|
||||
|
||||
byte[] buffer = new byte[48 * 1024];
|
||||
List<Exchanger<Integer>> totals = new ArrayList<>();
|
||||
for (Socket socket : sockets)
|
||||
{
|
||||
final Exchanger<Integer> x = new Exchanger<>();
|
||||
totals.add(x);
|
||||
final InputStream input = socket.getInputStream();
|
||||
|
||||
new Thread()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int read=0;
|
||||
try
|
||||
{
|
||||
// look for CRLFCRLF
|
||||
StringBuilder header = new StringBuilder();
|
||||
int state=0;
|
||||
while (state<4 && header.length()<2048)
|
||||
{
|
||||
int ch=input.read();
|
||||
if (ch<0)
|
||||
break;
|
||||
header.append((char)ch);
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
if (ch=='\r')
|
||||
state=1;
|
||||
break;
|
||||
case 1:
|
||||
if (ch=='\n')
|
||||
state=2;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 2:
|
||||
if (ch=='\r')
|
||||
state=3;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
case 3:
|
||||
if (ch=='\n')
|
||||
state=4;
|
||||
else
|
||||
state=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
read=input.read(buffer);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
x.exchange(read);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
for (Exchanger<Integer> x : totals)
|
||||
{
|
||||
Integer read = x.exchange(-1,10,TimeUnit.SECONDS);
|
||||
Assert.assertEquals(-1,read.intValue());
|
||||
}
|
||||
|
||||
// We could read everything, good.
|
||||
for (Socket socket : sockets)
|
||||
socket.close();
|
||||
|
||||
_server.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,214 +1,214 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.start;
|
||||
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.start.config.ConfigSources;
|
||||
import org.eclipse.jetty.start.config.JettyBaseConfigSource;
|
||||
import org.eclipse.jetty.start.config.JettyHomeConfigSource;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BaseHomeTest
|
||||
{
|
||||
public static void assertPathList(BaseHome hb, String message, List<String> expected, PathFinder finder)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (Path path : finder.getHits())
|
||||
{
|
||||
actual.add(hb.toShortForm(path.toFile()));
|
||||
}
|
||||
|
||||
if (actual.size() != expected.size())
|
||||
{
|
||||
System.out.printf("Actual Path(s): %,d hits%n",actual.size());
|
||||
for (String path : actual)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
System.out.printf("Expected Path(s): %,d entries%n",expected.size());
|
||||
for (String path : expected)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
public static void assertPathList(BaseHome hb, String message, List<String> expected, List<Path> paths)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (Path path : paths)
|
||||
{
|
||||
actual.add(hb.toShortForm(path.toFile()));
|
||||
}
|
||||
|
||||
if (actual.size() != expected.size())
|
||||
{
|
||||
System.out.printf("Actual Path(s): %,d hits%n",actual.size());
|
||||
for (String path : actual)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
System.out.printf("Expected Path(s): %,d entries%n",expected.size());
|
||||
for (String path : expected)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
public static void assertFileList(BaseHome hb, String message, List<String> expected, List<File> files)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (File file : files)
|
||||
{
|
||||
actual.add(hb.toShortForm(file));
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPath_OnlyHome() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
Path startIni = hb.getPath("start.ini");
|
||||
|
||||
String ref = hb.toShortForm(startIni);
|
||||
Assert.assertThat("Reference",ref,startsWith("${jetty.home}"));
|
||||
|
||||
String contents = IO.readToString(startIni.toFile());
|
||||
Assert.assertThat("Contents",contents,containsString("Home Ini"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_OnlyHome() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.home}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.home}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_OnlyHome_InisOnly() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*.ini");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.home}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.home}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_Both() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*.ini");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.base}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.base}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
expected.add("${jetty.base}/start.d/myapp.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefault() throws IOException
|
||||
{
|
||||
BaseHome bh = new BaseHome();
|
||||
Assert.assertThat("Home",bh.getHome(),notNullValue());
|
||||
Assert.assertThat("Base",bh.getBase(),notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPath_Both() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
Path startIni = hb.getPath("start.ini");
|
||||
|
||||
String ref = hb.toShortForm(startIni);
|
||||
Assert.assertThat("Reference",ref,startsWith("${jetty.base}"));
|
||||
|
||||
String contents = IO.readToString(startIni.toFile());
|
||||
Assert.assertThat("Contents",contents,containsString("Base Ini"));
|
||||
}
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.start;
|
||||
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.start.config.ConfigSources;
|
||||
import org.eclipse.jetty.start.config.JettyBaseConfigSource;
|
||||
import org.eclipse.jetty.start.config.JettyHomeConfigSource;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BaseHomeTest
|
||||
{
|
||||
public static void assertPathList(BaseHome hb, String message, List<String> expected, PathFinder finder)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (Path path : finder.getHits())
|
||||
{
|
||||
actual.add(hb.toShortForm(path.toFile()));
|
||||
}
|
||||
|
||||
if (actual.size() != expected.size())
|
||||
{
|
||||
System.out.printf("Actual Path(s): %,d hits%n",actual.size());
|
||||
for (String path : actual)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
System.out.printf("Expected Path(s): %,d entries%n",expected.size());
|
||||
for (String path : expected)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
public static void assertPathList(BaseHome hb, String message, List<String> expected, List<Path> paths)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (Path path : paths)
|
||||
{
|
||||
actual.add(hb.toShortForm(path.toFile()));
|
||||
}
|
||||
|
||||
if (actual.size() != expected.size())
|
||||
{
|
||||
System.out.printf("Actual Path(s): %,d hits%n",actual.size());
|
||||
for (String path : actual)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
System.out.printf("Expected Path(s): %,d entries%n",expected.size());
|
||||
for (String path : expected)
|
||||
{
|
||||
System.out.printf(" %s%n",path);
|
||||
}
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
public static void assertFileList(BaseHome hb, String message, List<String> expected, List<File> files)
|
||||
{
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (File file : files)
|
||||
{
|
||||
actual.add(hb.toShortForm(file));
|
||||
}
|
||||
Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPath_OnlyHome() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
Path startIni = hb.getPath("start.ini");
|
||||
|
||||
String ref = hb.toShortForm(startIni);
|
||||
Assert.assertThat("Reference",ref,startsWith("${jetty.home}"));
|
||||
|
||||
String contents = IO.readToString(startIni.toFile());
|
||||
Assert.assertThat("Contents",contents,containsString("Home Ini"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_OnlyHome() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.home}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.home}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_OnlyHome_InisOnly() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*.ini");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.home}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.home}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPaths_Both() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
List<Path> paths = hb.getPaths("start.d/*.ini");
|
||||
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("${jetty.base}/start.d/jmx.ini");
|
||||
expected.add("${jetty.home}/start.d/jndi.ini");
|
||||
expected.add("${jetty.home}/start.d/jsp.ini");
|
||||
expected.add("${jetty.base}/start.d/logging.ini");
|
||||
expected.add("${jetty.home}/start.d/ssl.ini");
|
||||
expected.add("${jetty.base}/start.d/myapp.ini");
|
||||
FSTest.toOsSeparators(expected);
|
||||
|
||||
assertPathList(hb,"Paths found",expected,paths);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefault() throws IOException
|
||||
{
|
||||
BaseHome bh = new BaseHome();
|
||||
Assert.assertThat("Home",bh.getHome(),notNullValue());
|
||||
Assert.assertThat("Base",bh.getBase(),notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPath_Both() throws IOException
|
||||
{
|
||||
File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home");
|
||||
File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base");
|
||||
|
||||
ConfigSources config = new ConfigSources();
|
||||
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||
|
||||
BaseHome hb = new BaseHome(config);
|
||||
Path startIni = hb.getPath("start.ini");
|
||||
|
||||
String ref = hb.toShortForm(startIni);
|
||||
Assert.assertThat("Reference",ref,startsWith("${jetty.base}"));
|
||||
|
||||
String contents = IO.readToString(startIni.toFile());
|
||||
Assert.assertThat("Contents",contents,containsString("Base Ini"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,284 +1,284 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.start;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.start.Props.Prop;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class ConfigurationAssert
|
||||
{
|
||||
/**
|
||||
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
||||
*
|
||||
* @param baseHome
|
||||
* the BaseHome used. Access it via {@link Main#getBaseHome()}
|
||||
* @param args
|
||||
* the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
||||
* @param filename
|
||||
* the filename of the assertion values
|
||||
* @throws FileNotFoundException if unable to find the configuration
|
||||
* @throws IOException if unable to process the configuration
|
||||
*/
|
||||
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException
|
||||
{
|
||||
Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath();
|
||||
File file = MavenTestingUtils.getTestResourceFile(filename);
|
||||
TextFile textFile = new TextFile(file.toPath());
|
||||
|
||||
// Validate XMLs (order is important)
|
||||
List<String> expectedXmls = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("XML|"))
|
||||
{
|
||||
expectedXmls.add(FS.separators(getValue(line)));
|
||||
}
|
||||
}
|
||||
List<String> actualXmls = new ArrayList<>();
|
||||
for (Path xml : args.getXmlFiles())
|
||||
{
|
||||
actualXmls.add(shorten(baseHome,xml,testResourcesDir));
|
||||
}
|
||||
assertOrdered("XML Resolution Order",expectedXmls,actualXmls);
|
||||
|
||||
// Validate LIBs (order is not important)
|
||||
List<String> expectedLibs = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("LIB|"))
|
||||
{
|
||||
expectedLibs.add(FS.separators(getValue(line)));
|
||||
}
|
||||
}
|
||||
List<String> actualLibs = new ArrayList<>();
|
||||
for (File path : args.getClasspath())
|
||||
{
|
||||
actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir));
|
||||
}
|
||||
assertContainsUnordered("Libs",expectedLibs,actualLibs);
|
||||
|
||||
// Validate PROPERTIES (order is not important)
|
||||
Set<String> expectedProperties = new HashSet<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("PROP|"))
|
||||
{
|
||||
expectedProperties.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualProperties = new ArrayList<>();
|
||||
for (Prop prop : args.getProperties())
|
||||
{
|
||||
String name = prop.key;
|
||||
if ("jetty.home".equals(name) || "jetty.base".equals(name) ||
|
||||
"user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) ||
|
||||
name.startsWith("java."))
|
||||
{
|
||||
// strip these out from assertion, to make assertions easier.
|
||||
continue;
|
||||
}
|
||||
actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value));
|
||||
}
|
||||
assertContainsUnordered("Properties",expectedProperties,actualProperties);
|
||||
|
||||
// Validate Downloads
|
||||
List<String> expectedDownloads = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("DOWNLOAD|"))
|
||||
{
|
||||
expectedDownloads.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualDownloads = new ArrayList<>();
|
||||
for (FileArg darg : args.getFiles())
|
||||
{
|
||||
if (darg.uri != null)
|
||||
{
|
||||
actualDownloads.add(String.format("%s|%s",darg.uri,darg.location));
|
||||
}
|
||||
}
|
||||
assertContainsUnordered("Downloads",expectedDownloads,actualDownloads);
|
||||
|
||||
// Validate Files/Dirs creation
|
||||
List<String> expectedFiles = new ArrayList<>();
|
||||
for(String line: textFile)
|
||||
{
|
||||
if(line.startsWith("FILE|"))
|
||||
{
|
||||
expectedFiles.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualFiles = new ArrayList<>();
|
||||
for(FileArg farg: args.getFiles())
|
||||
{
|
||||
if(farg.uri == null)
|
||||
{
|
||||
actualFiles.add(farg.location);
|
||||
}
|
||||
}
|
||||
assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles);
|
||||
}
|
||||
|
||||
private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir)
|
||||
{
|
||||
String value = baseHome.toShortForm(path);
|
||||
if (value.startsWith("${"))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (path.startsWith(testResourcesDir))
|
||||
{
|
||||
int len = testResourcesDir.toString().length();
|
||||
value = "${maven-test-resources}" + value.substring(len);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
|
||||
{
|
||||
// same size?
|
||||
boolean mismatch = expectedSet.size() != actualSet.size();
|
||||
|
||||
// test content
|
||||
Set<String> missing = new HashSet<>();
|
||||
for (String expected : expectedSet)
|
||||
{
|
||||
if (!actualSet.contains(expected))
|
||||
{
|
||||
missing.add(expected);
|
||||
}
|
||||
}
|
||||
|
||||
if (mismatch || missing.size() > 0)
|
||||
{
|
||||
// build up detailed error message
|
||||
StringWriter message = new StringWriter();
|
||||
PrintWriter err = new PrintWriter(message);
|
||||
|
||||
err.printf("%s: Assert Contains (Unordered)",msg);
|
||||
if (mismatch)
|
||||
{
|
||||
err.print(" [size mismatch]");
|
||||
}
|
||||
if (missing.size() >= 0)
|
||||
{
|
||||
err.printf(" [%d entries missing]",missing.size());
|
||||
}
|
||||
err.println();
|
||||
err.printf("Actual Entries (size: %d)%n",actualSet.size());
|
||||
for (String actual : actualSet)
|
||||
{
|
||||
char indicator = expectedSet.contains(actual)?' ':'>';
|
||||
err.printf("%s| %s%n",indicator,actual);
|
||||
}
|
||||
err.printf("Expected Entries (size: %d)%n",expectedSet.size());
|
||||
for (String expected : expectedSet)
|
||||
{
|
||||
char indicator = actualSet.contains(expected)?' ':'>';
|
||||
err.printf("%s| %s%n",indicator,expected);
|
||||
}
|
||||
err.flush();
|
||||
Assert.fail(message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
|
||||
{
|
||||
// same size?
|
||||
boolean mismatch = expectedList.size() != actualList.size();
|
||||
|
||||
// test content
|
||||
List<Integer> badEntries = new ArrayList<>();
|
||||
int min = Math.min(expectedList.size(),actualList.size());
|
||||
int max = Math.max(expectedList.size(),actualList.size());
|
||||
for (int i = 0; i < min; i++)
|
||||
{
|
||||
if (!expectedList.get(i).equals(actualList.get(i)))
|
||||
{
|
||||
badEntries.add(i);
|
||||
}
|
||||
}
|
||||
for (int i = min; i < max; i++)
|
||||
{
|
||||
badEntries.add(i);
|
||||
}
|
||||
|
||||
if (mismatch || badEntries.size() > 0)
|
||||
{
|
||||
// build up detailed error message
|
||||
StringWriter message = new StringWriter();
|
||||
PrintWriter err = new PrintWriter(message);
|
||||
|
||||
err.printf("%s: Assert Contains (Unordered)",msg);
|
||||
if (mismatch)
|
||||
{
|
||||
err.print(" [size mismatch]");
|
||||
}
|
||||
if (badEntries.size() >= 0)
|
||||
{
|
||||
err.printf(" [%d entries not matched]",badEntries.size());
|
||||
}
|
||||
err.println();
|
||||
err.printf("Actual Entries (size: %d)%n",actualList.size());
|
||||
for (int i = 0; i < actualList.size(); i++)
|
||||
{
|
||||
String actual = actualList.get(i);
|
||||
char indicator = badEntries.contains(i)?'>':' ';
|
||||
err.printf("%s[%d] %s%n",indicator,i,actual);
|
||||
}
|
||||
|
||||
err.printf("Expected Entries (size: %d)%n",expectedList.size());
|
||||
for (int i = 0; i < expectedList.size(); i++)
|
||||
{
|
||||
String expected = expectedList.get(i);
|
||||
char indicator = badEntries.contains(i)?'>':' ';
|
||||
err.printf("%s[%d] %s%n",indicator,i,expected);
|
||||
}
|
||||
err.flush();
|
||||
Assert.fail(message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getValue(String arg)
|
||||
{
|
||||
int idx = arg.indexOf('|');
|
||||
Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0));
|
||||
String value = arg.substring(idx + 1).trim();
|
||||
Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.start;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.start.Props.Prop;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class ConfigurationAssert
|
||||
{
|
||||
/**
|
||||
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
|
||||
*
|
||||
* @param baseHome
|
||||
* the BaseHome used. Access it via {@link Main#getBaseHome()}
|
||||
* @param args
|
||||
* the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
|
||||
* @param filename
|
||||
* the filename of the assertion values
|
||||
* @throws FileNotFoundException if unable to find the configuration
|
||||
* @throws IOException if unable to process the configuration
|
||||
*/
|
||||
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException
|
||||
{
|
||||
Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath();
|
||||
File file = MavenTestingUtils.getTestResourceFile(filename);
|
||||
TextFile textFile = new TextFile(file.toPath());
|
||||
|
||||
// Validate XMLs (order is important)
|
||||
List<String> expectedXmls = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("XML|"))
|
||||
{
|
||||
expectedXmls.add(FS.separators(getValue(line)));
|
||||
}
|
||||
}
|
||||
List<String> actualXmls = new ArrayList<>();
|
||||
for (Path xml : args.getXmlFiles())
|
||||
{
|
||||
actualXmls.add(shorten(baseHome,xml,testResourcesDir));
|
||||
}
|
||||
assertOrdered("XML Resolution Order",expectedXmls,actualXmls);
|
||||
|
||||
// Validate LIBs (order is not important)
|
||||
List<String> expectedLibs = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("LIB|"))
|
||||
{
|
||||
expectedLibs.add(FS.separators(getValue(line)));
|
||||
}
|
||||
}
|
||||
List<String> actualLibs = new ArrayList<>();
|
||||
for (File path : args.getClasspath())
|
||||
{
|
||||
actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir));
|
||||
}
|
||||
assertContainsUnordered("Libs",expectedLibs,actualLibs);
|
||||
|
||||
// Validate PROPERTIES (order is not important)
|
||||
Set<String> expectedProperties = new HashSet<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("PROP|"))
|
||||
{
|
||||
expectedProperties.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualProperties = new ArrayList<>();
|
||||
for (Prop prop : args.getProperties())
|
||||
{
|
||||
String name = prop.key;
|
||||
if ("jetty.home".equals(name) || "jetty.base".equals(name) ||
|
||||
"user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) ||
|
||||
name.startsWith("java."))
|
||||
{
|
||||
// strip these out from assertion, to make assertions easier.
|
||||
continue;
|
||||
}
|
||||
actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value));
|
||||
}
|
||||
assertContainsUnordered("Properties",expectedProperties,actualProperties);
|
||||
|
||||
// Validate Downloads
|
||||
List<String> expectedDownloads = new ArrayList<>();
|
||||
for (String line : textFile)
|
||||
{
|
||||
if (line.startsWith("DOWNLOAD|"))
|
||||
{
|
||||
expectedDownloads.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualDownloads = new ArrayList<>();
|
||||
for (FileArg darg : args.getFiles())
|
||||
{
|
||||
if (darg.uri != null)
|
||||
{
|
||||
actualDownloads.add(String.format("%s|%s",darg.uri,darg.location));
|
||||
}
|
||||
}
|
||||
assertContainsUnordered("Downloads",expectedDownloads,actualDownloads);
|
||||
|
||||
// Validate Files/Dirs creation
|
||||
List<String> expectedFiles = new ArrayList<>();
|
||||
for(String line: textFile)
|
||||
{
|
||||
if(line.startsWith("FILE|"))
|
||||
{
|
||||
expectedFiles.add(getValue(line));
|
||||
}
|
||||
}
|
||||
List<String> actualFiles = new ArrayList<>();
|
||||
for(FileArg farg: args.getFiles())
|
||||
{
|
||||
if(farg.uri == null)
|
||||
{
|
||||
actualFiles.add(farg.location);
|
||||
}
|
||||
}
|
||||
assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles);
|
||||
}
|
||||
|
||||
private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir)
|
||||
{
|
||||
String value = baseHome.toShortForm(path);
|
||||
if (value.startsWith("${"))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (path.startsWith(testResourcesDir))
|
||||
{
|
||||
int len = testResourcesDir.toString().length();
|
||||
value = "${maven-test-resources}" + value.substring(len);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
|
||||
{
|
||||
// same size?
|
||||
boolean mismatch = expectedSet.size() != actualSet.size();
|
||||
|
||||
// test content
|
||||
Set<String> missing = new HashSet<>();
|
||||
for (String expected : expectedSet)
|
||||
{
|
||||
if (!actualSet.contains(expected))
|
||||
{
|
||||
missing.add(expected);
|
||||
}
|
||||
}
|
||||
|
||||
if (mismatch || missing.size() > 0)
|
||||
{
|
||||
// build up detailed error message
|
||||
StringWriter message = new StringWriter();
|
||||
PrintWriter err = new PrintWriter(message);
|
||||
|
||||
err.printf("%s: Assert Contains (Unordered)",msg);
|
||||
if (mismatch)
|
||||
{
|
||||
err.print(" [size mismatch]");
|
||||
}
|
||||
if (missing.size() >= 0)
|
||||
{
|
||||
err.printf(" [%d entries missing]",missing.size());
|
||||
}
|
||||
err.println();
|
||||
err.printf("Actual Entries (size: %d)%n",actualSet.size());
|
||||
for (String actual : actualSet)
|
||||
{
|
||||
char indicator = expectedSet.contains(actual)?' ':'>';
|
||||
err.printf("%s| %s%n",indicator,actual);
|
||||
}
|
||||
err.printf("Expected Entries (size: %d)%n",expectedSet.size());
|
||||
for (String expected : expectedSet)
|
||||
{
|
||||
char indicator = actualSet.contains(expected)?' ':'>';
|
||||
err.printf("%s| %s%n",indicator,expected);
|
||||
}
|
||||
err.flush();
|
||||
Assert.fail(message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
|
||||
{
|
||||
// same size?
|
||||
boolean mismatch = expectedList.size() != actualList.size();
|
||||
|
||||
// test content
|
||||
List<Integer> badEntries = new ArrayList<>();
|
||||
int min = Math.min(expectedList.size(),actualList.size());
|
||||
int max = Math.max(expectedList.size(),actualList.size());
|
||||
for (int i = 0; i < min; i++)
|
||||
{
|
||||
if (!expectedList.get(i).equals(actualList.get(i)))
|
||||
{
|
||||
badEntries.add(i);
|
||||
}
|
||||
}
|
||||
for (int i = min; i < max; i++)
|
||||
{
|
||||
badEntries.add(i);
|
||||
}
|
||||
|
||||
if (mismatch || badEntries.size() > 0)
|
||||
{
|
||||
// build up detailed error message
|
||||
StringWriter message = new StringWriter();
|
||||
PrintWriter err = new PrintWriter(message);
|
||||
|
||||
err.printf("%s: Assert Contains (Unordered)",msg);
|
||||
if (mismatch)
|
||||
{
|
||||
err.print(" [size mismatch]");
|
||||
}
|
||||
if (badEntries.size() >= 0)
|
||||
{
|
||||
err.printf(" [%d entries not matched]",badEntries.size());
|
||||
}
|
||||
err.println();
|
||||
err.printf("Actual Entries (size: %d)%n",actualList.size());
|
||||
for (int i = 0; i < actualList.size(); i++)
|
||||
{
|
||||
String actual = actualList.get(i);
|
||||
char indicator = badEntries.contains(i)?'>':' ';
|
||||
err.printf("%s[%d] %s%n",indicator,i,actual);
|
||||
}
|
||||
|
||||
err.printf("Expected Entries (size: %d)%n",expectedList.size());
|
||||
for (int i = 0; i < expectedList.size(); i++)
|
||||
{
|
||||
String expected = expectedList.get(i);
|
||||
char indicator = badEntries.contains(i)?'>':' ';
|
||||
err.printf("%s[%d] %s%n",indicator,i,expected);
|
||||
}
|
||||
err.flush();
|
||||
Assert.fail(message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getValue(String arg)
|
||||
{
|
||||
int idx = arg.indexOf('|');
|
||||
Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0));
|
||||
String value = arg.substring(idx + 1).trim();
|
||||
Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue