Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/jetty-9.2.x'
Browse files Browse the repository at this point in the history
Conflicts:
	tests/test-integration/src/test/java/org/eclipse/jetty/test/support/TestableJettyServer.java
	tests/test-integration/src/test/resources/BIOHttp.xml
	tests/test-integration/src/test/resources/BIOHttps.xml
	tests/test-integration/src/test/resources/NIOHttp.xml
	tests/test-integration/src/test/resources/NIOHttps.xml
  • Loading branch information
janbartel committed Apr 30, 2015
2 parents 15eb108 + 25474ff commit e30c05c
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 124 deletions.
Expand Up @@ -76,7 +76,7 @@ public static HttpMethod lookAheadGet(byte[] bytes, final int position, int limi
return HEAD;
break;
case 'O':
if (bytes[position+1]=='O' && bytes[position+2]=='T' && bytes[position+3]=='I' && length>=8 &&
if (bytes[position+1]=='P' && bytes[position+2]=='T' && bytes[position+3]=='I' && length>=8 &&
bytes[position+4]=='O' && bytes[position+5]=='N' && bytes[position+6]=='S' && bytes[position+7]==' ' )
return OPTIONS;
break;
Expand Down
Expand Up @@ -71,8 +71,7 @@ public void execute() throws MojoExecutionException, MojoFailureException
@Override
public void startJetty() throws MojoExecutionException
{
//Only do enough setup to be able to produce a quickstart-web.xml file to
//pass onto the forked process to run
//Only do enough setup to be able to produce a quickstart-web.xml file

//if the user didn't nominate a file to generate into, pick the name and
//make sure that it is deleted on exit
Expand Down
Expand Up @@ -146,6 +146,7 @@ public class JettyRunForkedMojo extends JettyRunMojo


private Resource originalBaseResource;
private boolean originalPersistTemp;


/**
Expand Down Expand Up @@ -253,6 +254,9 @@ public void startJetty() throws MojoExecutionException
//copy the base resource as configured by the plugin
originalBaseResource = webApp.getBaseResource();

//get the original persistance setting
originalPersistTemp = webApp.isPersistTempDirectory();

//set the webapp up to do very little other than generate the quickstart-web.xml
webApp.setCopyWebDir(false);
webApp.setCopyWebInf(false);
Expand All @@ -275,8 +279,11 @@ public void startJetty() throws MojoExecutionException
tpool.start();
else
webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString());

//leave everything unpacked for the forked process to use
webApp.setPersistTempDirectory(true);

webApp.start(); //just enough to generate the quickstart
webApp.start(); //just enough to generate the quickstart

//save config of the webapp BEFORE we stop
File props = prepareConfiguration();
Expand Down Expand Up @@ -470,31 +477,23 @@ public File prepareConfiguration() throws MojoExecutionException

//tmp dir
props.put("tmp.dir", webApp.getTempDirectory().getAbsolutePath());
props.put("tmp.dir.persist", Boolean.toString(webApp.isPersistTempDirectory()));

//resource bases - these are what has been configured BEFORE the webapp started and
//potentially reordered them and included any resources from META-INF
if (originalBaseResource != null)
{
StringBuffer rb = new StringBuffer();
if (originalBaseResource instanceof ResourceCollection)
{
ResourceCollection resources = ((ResourceCollection)originalBaseResource);
for (Resource r:resources.getResources())
{
if (rb.length() > 0) rb.append(",");
rb.append(r.toString());
}
}
else
rb.append(originalBaseResource.toString());

props.put("base.dirs", rb.toString());
}
props.put("tmp.dir.persist", Boolean.toString(originalPersistTemp));

//sort out the resource base directories of the webapp
props.put("base.first", Boolean.toString(webApp.getBaseAppFirst()));
//send over the original base resources before any overlays were added
if (originalBaseResource instanceof ResourceCollection)
props.put("base.dirs.orig", toCSV(((ResourceCollection)originalBaseResource).getResources()));
else
props.put("base.dirs.orig", originalBaseResource.toString());

//send over the calculated resource bases that includes unpacked overlays, but none of the
//meta-inf resources
Resource postOverlayResources = (Resource)webApp.getAttribute(MavenWebInfConfiguration.RESOURCE_BASES_POST_OVERLAY);
if (postOverlayResources instanceof ResourceCollection)
props.put("base.dirs", toCSV(((ResourceCollection)postOverlayResources).getResources()));
else
props.put("base.dirs", postOverlayResources.toString());


//web-inf classes
if (webApp.getClasses() != null)
{
Expand Down Expand Up @@ -751,4 +750,17 @@ private String toCSV (List<String> strings)
}
return strbuff.toString();
}

private String toCSV (Resource[] resources)
{
StringBuffer rb = new StringBuffer();

for (Resource r:resources)
{
if (rb.length() > 0) rb.append(",");
rb.append(r.toString());
}

return rb.toString();
}
}
Expand Up @@ -23,9 +23,11 @@
import java.util.Iterator;

import org.eclipse.jetty.quickstart.QuickStartConfiguration;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;

Expand Down Expand Up @@ -54,6 +56,20 @@ public Resource getQuickStartWebXml(WebAppContext context) throws Exception
return _quickStartWebXml;
}

@Override
public void preConfigure(WebAppContext context) throws Exception
{
//check that webapp is suitable for quick start
if (context.getBaseResource() == null)
throw new IllegalStateException ("No location for webapp");


//look for quickstart-web.xml in WEB-INF of webapp
Resource quickStartWebXml = getQuickStartWebXml(context);
LOG.debug("quickStartWebXml={}",quickStartWebXml);

context.getMetaData().setWebXml(quickStartWebXml);
}


@Override
Expand Down Expand Up @@ -89,4 +105,28 @@ public void configure(WebAppContext context) throws Exception
context.setServerClasses( newServerClasses );
}

@Override
public void deconfigure(WebAppContext context) throws Exception
{
//if we're not persisting the temp dir, get rid of any overlays
if (!context.isPersistTempDirectory())
{
Resource originalBases = (Resource)context.getAttribute("org.eclipse.jetty.resources.originalBases");
String originalBaseStr = originalBases.toString();

//Iterate over all of the resource bases and ignore any that were original bases, just
//deleting the overlays
Resource res = context.getBaseResource();
if (res instanceof ResourceCollection)
{
for (Resource r:((ResourceCollection)res).getResources())
{
if (originalBaseStr.contains(r.toString()))
continue;
IO.delete(r.getFile());
}
}
}
}

}
Expand Up @@ -25,7 +25,7 @@
import java.util.List;
import java.util.Locale;

import org.eclipse.jetty.util.IO;

import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
Expand All @@ -46,7 +46,7 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
{
private static final Logger LOG = Log.getLogger(MavenWebInfConfiguration.class);


public static final String RESOURCE_BASES_POST_OVERLAY = "org.eclipse.jetty.resource.postOverlay";
protected static int COUNTER = 0;
protected Resource _originalResourceBase;
protected List<Resource> _unpackedOverlayResources;
Expand Down Expand Up @@ -115,24 +115,11 @@ public void postConfigure(WebAppContext context) throws Exception
*/
public void deconfigure(WebAppContext context) throws Exception
{
//remove the unpacked wars
if (_unpackedOverlayResources != null && !_unpackedOverlayResources.isEmpty())
{
try
{
for (Resource r:_unpackedOverlayResources)
{
IO.delete(r.getFile());
}
}
catch (IOException e)
{
LOG.ignore(e);
}
}
super.deconfigure(context);
//restore whatever the base resource was before we might have included overlaid wars
context.setBaseResource(_originalResourceBase);
//undo the setting of the overlayed resources
context.removeAttribute(RESOURCE_BASES_POST_OVERLAY);
}


Expand Down Expand Up @@ -190,9 +177,10 @@ public void unpack(WebAppContext context) throws IOException
resourceBaseCollection.add(_originalResourceBase);
}
}

jwac.setBaseResource(new ResourceCollection(resourceBaseCollection.toArray(new Resource[resourceBaseCollection.size()])));
}

jwac.setAttribute(RESOURCE_BASES_POST_OVERLAY, jwac.getBaseResource());
}


Expand Down
Expand Up @@ -192,21 +192,23 @@ public void configureWebApp ()
str = (String)props.getProperty("tmp.dir.persist");
if (str != null)
webApp.setPersistTempDirectory(Boolean.valueOf(str));

// - the base directories
//Get the calculated base dirs which includes the overlays
str = (String)props.getProperty("base.dirs");
if (str != null && !"".equals(str.trim()))
{
ResourceCollection bases = new ResourceCollection(str.split(","));
webApp.setWar(bases.getResources()[0].toString());
webApp.setWar(null);
webApp.setBaseResource(bases);
}
// - put virtual webapp base resource first on resource path or not
str = (String)props.getProperty("base.first");

//Get the original base dirs without the overlays
str = (String)props.get("base.dirs.orig");
if (str != null && !"".equals(str.trim()))
webApp.setBaseAppFirst(Boolean.valueOf(str));

{
ResourceCollection bases = new ResourceCollection(str.split(","));
webApp.setAttribute ("org.eclipse.jetty.resources.originalBases", bases);
}

//For overlays
str = (String)props.getProperty("maven.war.includes");
Expand Down
10 changes: 3 additions & 7 deletions jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
Expand Up @@ -500,8 +500,10 @@ public void handle(HttpChannel connection) throws IOException, ServletException
if (LOG.isDebugEnabled())
LOG.debug("{} on {}{}",request.getDispatcherType(),connection,"\n"+request.getMethod()+" "+request.getHttpURI()+"\n"+request.getHttpFields());

if ("*".equals(target))
if (HttpMethod.OPTIONS.is(request.getMethod()) || "*".equals(target))
{
if (!HttpMethod.OPTIONS.is(request.getMethod()))
response.sendError(HttpStatus.BAD_REQUEST_400);
handleOptions(request,response);
if (!request.isHandled())
handle(target, request, request, response);
Expand All @@ -518,12 +520,6 @@ public void handle(HttpChannel connection) throws IOException, ServletException
*/
protected void handleOptions(Request request,Response response) throws IOException
{
if (!HttpMethod.OPTIONS.is(request.getMethod()))
response.sendError(HttpStatus.BAD_REQUEST_400);
request.setHandled(true);
response.setStatus(200);
response.setContentLength(0);
response.closeOutput();
}

/* ------------------------------------------------------------ */
Expand Down
Expand Up @@ -446,7 +446,9 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques
// handle directories
if (resource.isDirectory())
{
if (!request.getPathInfo().endsWith(URIUtil.SLASH))
String pathInfo = request.getPathInfo();
boolean endsWithSlash=(pathInfo==null?request.getServletPath():pathInfo).endsWith(URIUtil.SLASH);
if (!endsWithSlash)
{
response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)));
return;
Expand Down
Expand Up @@ -135,6 +135,45 @@ public void testSimple() throws Exception
}
}

@Test
public void testOPTIONS() throws Exception
{
configureServer(new OptionsHandler());

try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
{
OutputStream os = client.getOutputStream();

os.write(("OPTIONS * HTTP/1.1\r\n"
+ "Host: "+_serverURI.getHost()+"\r\n"
+ "Connection: close\r\n"
+ "\r\n").getBytes(StandardCharsets.ISO_8859_1));
os.flush();

// Read the response.
String response = readResponse(client);

Assert.assertThat(response, Matchers.containsString("HTTP/1.1 200 OK"));
Assert.assertThat(response, Matchers.containsString("Allow: GET"));
}

try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
{
OutputStream os = client.getOutputStream();

os.write(("GET * HTTP/1.1\r\n"
+ "Host: "+_serverURI.getHost()+"\r\n"
+ "Connection: close\r\n"
+ "\r\n").getBytes(StandardCharsets.ISO_8859_1));
os.flush();

// Read the response.
String response = readResponse(client);

Assert.assertThat(response, Matchers.containsString("HTTP/1.1 400 "));
Assert.assertThat(response, Matchers.not(Matchers.containsString("Allow: ")));
}
}

/*
* Feed a full header method
Expand Down
Expand Up @@ -150,6 +150,21 @@ else if (request.getCharacterEncoding()!=null)
}
}

protected static class OptionsHandler extends AbstractHandler
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
if (request.getMethod().equals("OPTIONS"))
response.setStatus(200);
else
response.setStatus(500);

response.setHeader("Allow", "GET");
}
}

protected static class HelloWorldHandler extends AbstractHandler
{
@Override
Expand Down
Expand Up @@ -719,6 +719,10 @@ private byte[] prefixToBytes(int prefix, int length)
prefix -= 8;
++index;
}

if (index == result.length)
return result;

// Sets the _prefix_ most significant bits to 1
result[index] = (byte)~((1 << (8 - prefix)) - 1);
return result;
Expand Down Expand Up @@ -1045,6 +1049,18 @@ public void setWhitelist(String value)
_whitelist.addAll(result);
LOG.debug("Whitelisted IP addresses: {}", result);
}

/**
* Set a list of IP addresses that will not be rate limited.
*
* @param values whitelist
*/
public void setWhitelist(List<String> values)
{
clearWhitelist();
_whitelist.addAll(values);
LOG.debug("Whitelisted IP addresses: {}", values);
}

/**
* Clears the list of whitelisted IP addresses
Expand Down

0 comments on commit e30c05c

Please sign in to comment.