Fixing CRLF files

This commit is contained in:
Joakim Erdfelt 2019-04-03 11:56:07 -05:00
parent 0638ad1bd9
commit edaefdbb3b
10 changed files with 1845 additions and 1845 deletions

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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"));
}
}
}

View File

@ -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();
}
}
}

View File

@ -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"));
}
}

View File

@ -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;
}
}