465747 - Jetty is failing to process all HTTP OPTIONS requests.

The Server handleOptions method was handling all OPTIONS * requests with a blank 200 response.
This has been fixed so that this method only checks that * URI is only applied to OPTIONS method.
This commit is contained in:
Greg Wilkins 2015-04-29 14:01:20 +10:00
parent 6ebfd88323
commit d5c95a1302
9 changed files with 61 additions and 62 deletions

View File

@ -76,7 +76,7 @@ public enum HttpMethod
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;

View File

@ -487,8 +487,10 @@ public class Server extends HandlerWrapper implements Attributes
if (LOG.isDebugEnabled())
LOG.debug(request.getDispatcherType()+" "+request.getMethod()+" "+target+" on "+connection);
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);
@ -505,12 +507,6 @@ public class Server extends HandlerWrapper implements Attributes
*/
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();
}
/* ------------------------------------------------------------ */

View File

@ -131,6 +131,45 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
}
}
@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

View File

@ -150,6 +150,21 @@ public class HttpServerTestFixture
}
}
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

View File

@ -177,7 +177,7 @@ public class TestableJettyServer
_server.start();
// Find the active server port.
this._serverPort = ((NetworkConnector)_server.getConnectors()[0]).getPort();
this._serverPort = ((NetworkConnector)_server.getConnectors()[0]).getLocalPort();
System.err.println("Server Port="+_serverPort);
Assert.assertTrue("Server Port is between 1 and 65535. Actually <" + _serverPort + ">",(1 <= this._serverPort) && (this._serverPort <= 65535));
}

View File

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Set connectors -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.bio.SocketConnector">
<Set name="host"><SystemProperty name="jetty.host" /></Set>
<Set name="port"><SystemProperty name="jetty.port" default="0"/></Set>
<Set name="idleTimeout">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -1,29 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Set connectors -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<Set name="host"><SystemProperty name="jetty.host" /></Set>
<Set name="port"><SystemProperty name="jetty.port" default="0"/></Set>
<Set name="idleTimeout">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="keystore"><Property name="test.resourcesdir" default="src/test/resources" />/keystore</Set>
<Set name="password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name="keyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
<!--
<Set name="truststore"><Property name="test.resourcesdir" default="src/test/resources" />/keystore</Set>
<Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
-->
</New>
</Arg>
</Call>
</Configure>

View File

@ -21,7 +21,7 @@
</Array>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.port" default="8080" /></Set>
<Set name="port">0</Set>
<Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
</New>
</Arg>

View File

@ -26,7 +26,7 @@
</Array>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.https.port" default="8443" /></Set>
<Set name="port">0</Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>