Issue #2114 Fix NPE in JettyHttpServerProvider

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2018-01-11 17:54:21 +01:00
parent 298580625e
commit 8d11b02760
4 changed files with 192 additions and 41 deletions

View File

@ -17,6 +17,12 @@
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.net.httpserver</groupId>
<artifactId>http</artifactId>

View File

@ -106,10 +106,16 @@ public class JettyHttpServer extends com.sun.net.httpserver.HttpServer
ServerConnector connector = new ServerConnector(_server);
connector.setPort(addr.getPort());
connector.setHost(addr.getHostName());
_server.addConnector(connector);
_connectors.put(addr.getHostName() + addr.getPort(), connector);
}
protected Server getServer()
{
return _server;
}
protected ServerConnector newServerConnector(InetSocketAddress addr,int backlog)
{

View File

@ -66,7 +66,8 @@ public class JettyHttpServerProvider extends HttpServerProvider
}
JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared);
jettyHttpServer.bind(addr, backlog);
if (addr != null)
jettyHttpServer.bind(addr, backlog);
return jettyHttpServer;
}

View File

@ -18,13 +18,26 @@
package org.eclipse.jetty.http.spi;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.BasicAuthentication;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import com.sun.net.httpserver.BasicAuthenticator;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
@ -32,57 +45,182 @@ import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.junit.Test;
public class TestSPIServer
{
public static void main(String[] args) throws Exception
/**
* Create a server that has a null InetSocketAddress, then
* bind before using.
*
* @throws Exception
*/
@Test
public void testUnboundHttpServer() throws Exception
{
String host="localhost";
int port = 8080;
HttpServer server = new JettyHttpServerProvider().createHttpServer(new
InetSocketAddress(host, port), 10);
server.start();
final HttpContext httpContext = server.createContext("/",
new HttpHandler()
HttpServer server = null;
try
{
//ensure no InetSocketAddress is passed
server = new JettyHttpServerProvider().createHttpServer(null, 10);
public void handle(HttpExchange exchange) throws IOException
final HttpContext httpContext = server.createContext("/",
new HttpHandler()
{
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type","text/plain");
exchange.sendResponseHeaders(200,0);
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext())
public void handle(HttpExchange exchange) throws IOException
{
String key = iter.next();
List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
responseBody.close();
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type","text/plain");
exchange.sendResponseHeaders(200,0);
}
});
httpContext.setAuthenticator(new BasicAuthenticator("Test")
{
@Override
public boolean checkCredentials(String username, String password)
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext())
{
String key = iter.next();
List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
responseBody.close();
}
});
httpContext.setAuthenticator(new BasicAuthenticator("Test")
{
if ("username".equals(username) && password.equals("password"))
return true;
return false;
@Override
public boolean checkCredentials(String username, String password)
{
if ("username".equals(username) && password.equals("password"))
return true;
return false;
}
});
//now bind one. Use port '0' to let jetty pick the
//address to bind so this test isn't port-specific
//and thus is portable and can be run concurrently on CI
//environments
server.bind(new InetSocketAddress("localhost", 0), 10);
server.start();
//find out the port jetty picked
Server jetty = ((JettyHttpServer)server).getServer();
int port = ((NetworkConnector)jetty.getConnectors()[0]).getLocalPort();
HttpClient client = new HttpClient();
client.start();
try
{
Request request = client.newRequest("http://localhost:" + port + "/");
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(URI.create("http://localhost:"+port), "Test", "username", "password"));
ContentResponse response = request.send();
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
}
});
Thread.sleep(10000000);
finally
{
client.stop();
}
}
finally
{
if (server != null)
server.stop(5);
}
}
/**
* Test using a server that is created with a given InetSocketAddress
* @throws Exception
*/
@Test
public void testBoundHttpServer() throws Exception
{
HttpServer server = null;
try
{
//use an InetSocketAddress, but use port value of '0' to allow
//jetty to pick a free port. Ensures test is not tied to specific port number
//for test portability and concurrency.
server = new JettyHttpServerProvider().createHttpServer(new
InetSocketAddress("localhost", 0), 10);
final HttpContext httpContext = server.createContext("/",
new HttpHandler()
{
public void handle(HttpExchange exchange) throws IOException
{
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type","text/plain");
exchange.sendResponseHeaders(200,0);
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext())
{
String key = iter.next();
List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
responseBody.close();
}
});
httpContext.setAuthenticator(new BasicAuthenticator("Test")
{
@Override
public boolean checkCredentials(String username, String password)
{
if ("username".equals(username) && password.equals("password"))
return true;
return false;
}
});
server.start();
//find out the port jetty picked
Server jetty = ((JettyHttpServer)server).getServer();
int port = ((NetworkConnector)jetty.getConnectors()[0]).getLocalPort();
HttpClient client = new HttpClient();
client.start();
try
{
Request request = client.newRequest("http://localhost:" + port + "/");
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(URI.create("http://localhost:"+port), "Test", "username", "password"));
ContentResponse response = request.send();
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
}
finally
{
client.stop();
}
}
finally
{
if (server != null)
server.stop(5);
}
}
}