Merged branch 'jetty-9.3.x' into 'master'.

This commit is contained in:
Simone Bordet 2016-04-01 19:50:26 +02:00
commit 68a465d7a3
5 changed files with 175 additions and 77 deletions

View File

@ -35,6 +35,7 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -103,7 +104,7 @@ public abstract class HttpConnection implements Connection
URI uri = request.getURI(); URI uri = request.getURI();
if (proxy != null && !HttpClient.isSchemeSecure(request.getScheme()) && uri != null) if (proxy instanceof HttpProxy && !HttpClient.isSchemeSecure(request.getScheme()) && uri != null)
{ {
path = uri.toString(); path = uri.toString();
request.path(path); request.path(path);

View File

@ -26,8 +26,6 @@ import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -69,17 +67,16 @@ public class Socks4ProxyTest
byte ip4 = 13; byte ip4 = 13;
String serverHost = ip1 + "." + ip2 + "." + ip3 + "." + ip4; String serverHost = ip1 + "." + ip2 + "." + ip3 + "." + ip4;
int serverPort = proxyPort + 1; // Any port will do int serverPort = proxyPort + 1; // Any port will do
String method = "GET";
String path = "/path";
client.newRequest(serverHost, serverPort) client.newRequest(serverHost, serverPort)
.path("/path") .method(method)
.path(path)
.timeout(5, TimeUnit.SECONDS) .timeout(5, TimeUnit.SECONDS)
.send(new Response.CompleteListener() .send(result ->
{
@Override
public void onComplete(Result result)
{ {
if (result.isSucceeded()) if (result.isSucceeded())
latch.countDown(); latch.countDown();
}
}); });
SocketChannel channel = server.accept(); SocketChannel channel = server.accept();
@ -100,11 +97,11 @@ public class Socks4ProxyTest
// Socks4 response. // Socks4 response.
channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0})); channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0}));
buffer = ByteBuffer.allocate(3); buffer = ByteBuffer.allocate(method.length() + 1 + path.length());
read = channel.read(buffer); read = channel.read(buffer);
Assert.assertEquals(3, read); Assert.assertEquals(buffer.capacity(), read);
buffer.flip(); buffer.flip();
Assert.assertEquals("GET", StandardCharsets.UTF_8.decode(buffer).toString()); Assert.assertEquals(method + " " + path, StandardCharsets.UTF_8.decode(buffer).toString());
// Response // Response
String response = "" + String response = "" +
@ -129,19 +126,17 @@ public class Socks4ProxyTest
String serverHost = "127.0.0.13"; // Test expects an IP address. String serverHost = "127.0.0.13"; // Test expects an IP address.
int serverPort = proxyPort + 1; // Any port will do int serverPort = proxyPort + 1; // Any port will do
String method = "GET";
client.newRequest(serverHost, serverPort) client.newRequest(serverHost, serverPort)
.method(method)
.path("/path") .path("/path")
.timeout(5, TimeUnit.SECONDS) .timeout(5, TimeUnit.SECONDS)
.send(new Response.CompleteListener() .send(result ->
{
@Override
public void onComplete(Result result)
{ {
if (result.isSucceeded()) if (result.isSucceeded())
latch.countDown(); latch.countDown();
else else
result.getFailure().printStackTrace(); result.getFailure().printStackTrace();
}
}); });
SocketChannel channel = server.accept(); SocketChannel channel = server.accept();
@ -161,11 +156,11 @@ public class Socks4ProxyTest
channel.write(ByteBuffer.wrap(chunk2)); channel.write(ByteBuffer.wrap(chunk2));
buffer = ByteBuffer.allocate(3); buffer = ByteBuffer.allocate(method.length());
read = channel.read(buffer); read = channel.read(buffer);
Assert.assertEquals(3, read); Assert.assertEquals(buffer.capacity(), read);
buffer.flip(); buffer.flip();
Assert.assertEquals("GET", StandardCharsets.UTF_8.decode(buffer).toString()); Assert.assertEquals(method, StandardCharsets.UTF_8.decode(buffer).toString());
// Response // Response
String response = "" + String response = "" +

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.http2.client.http; package org.eclipse.jetty.http2.client.http;
import java.net.URI;
import org.eclipse.jetty.client.HttpContent; import org.eclipse.jetty.client.HttpContent;
import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.client.HttpSender; import org.eclipse.jetty.client.HttpSender;
@ -47,8 +49,9 @@ public class HttpSenderOverHTTP2 extends HttpSender
@Override @Override
protected void sendHeaders(HttpExchange exchange, final HttpContent content, final Callback callback) protected void sendHeaders(HttpExchange exchange, final HttpContent content, final Callback callback)
{ {
final Request request = exchange.getRequest(); Request request = exchange.getRequest();
HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), request.getPath(), null, request.getQuery(), null); String path = relativize(request.getPath());
HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null);
MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders()); MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders());
HeadersFrame headersFrame = new HeadersFrame(metaData, null, !content.hasContent()); HeadersFrame headersFrame = new HeadersFrame(metaData, null, !content.hasContent());
HttpChannelOverHTTP2 channel = getHttpChannel(); HttpChannelOverHTTP2 channel = getHttpChannel();
@ -84,6 +87,24 @@ public class HttpSenderOverHTTP2 extends HttpSender
channel.getSession().newStream(headersFrame, promise, channel.getStreamListener()); channel.getSession().newStream(headersFrame, promise, channel.getStreamListener());
} }
private String relativize(String path)
{
try
{
String result = path;
URI uri = URI.create(result);
if (uri.isAbsolute())
result = uri.getPath();
return result.isEmpty() ? "/" : result;
}
catch (Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug("Could not relativize " + path);
return path;
}
}
@Override @Override
protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback) protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
{ {

View File

@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
@ -260,6 +261,58 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
Assert.assertEquals(lastStream.get(), stream.getId()); Assert.assertEquals(lastStream.get(), stream.getId());
} }
@Test
public void testAbsoluteFormTarget() throws Exception
{
String path = "/path";
String query = "a=b";
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
Assert.assertEquals(path, request.getRequestURI());
Assert.assertEquals(query, request.getQueryString());
}
});
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.path("http://localhost:" + connector.getLocalPort() + path + "?" + query)
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testRequestViaForwardHttpProxy() throws Exception
{
String path = "/path";
String query = "a=b";
start(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
Assert.assertEquals(path, request.getRequestURI());
Assert.assertEquals(query, request.getQueryString());
}
});
int proxyPort = connector.getLocalPort();
client.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyPort));
int serverPort = proxyPort + 1; // Any port will do, just not the same as the proxy.
ContentResponse response = client.newRequest("localhost", serverPort)
.path(path + "?" + query)
.timeout(5, TimeUnit.SECONDS)
.send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Ignore @Ignore
@Test @Test
public void testExternalServer() throws Exception public void testExternalServer() throws Exception

View File

@ -21,11 +21,13 @@ package org.eclipse.jetty.http2.server;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.PreEncodedHttpField; import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.http2.IStream; import org.eclipse.jetty.http2.IStream;
@ -69,6 +71,8 @@ public class HttpChannelOverHTTP2 extends HttpChannel
} }
public Runnable onRequest(HeadersFrame frame) public Runnable onRequest(HeadersFrame frame)
{
try
{ {
MetaData.Request request = (MetaData.Request)frame.getMetaData(); MetaData.Request request = (MetaData.Request)frame.getMetaData();
HttpFields fields = request.getFields(); HttpFields fields = request.getFields();
@ -114,8 +118,21 @@ public class HttpChannelOverHTTP2 extends HttpChannel
return _delayedUntilContent ? null : this; return _delayedUntilContent ? null : this;
} }
catch (BadMessageException x)
{
onBadMessage(x.getCode(), x.getReason());
return null;
}
catch (Throwable x)
{
onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null);
return null;
}
}
public Runnable onPushRequest(MetaData.Request request) public Runnable onPushRequest(MetaData.Request request)
{
try
{ {
onRequest(request); onRequest(request);
getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE); getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE);
@ -132,6 +149,17 @@ public class HttpChannelOverHTTP2 extends HttpChannel
return this; return this;
} }
catch (BadMessageException x)
{
onBadMessage(x.getCode(), x.getReason());
return null;
}
catch (Throwable x)
{
onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null);
return null;
}
}
@Override @Override
public HttpTransportOverHTTP2 getHttpTransport() public HttpTransportOverHTTP2 getHttpTransport()