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

This commit is contained in:
Simone Bordet 2016-06-22 11:28:50 +02:00
commit b9b3300e1d
5 changed files with 46 additions and 17 deletions

View File

@ -27,7 +27,6 @@ import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.Destination; import org.eclipse.jetty.client.api.Destination;
import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
@ -172,24 +171,24 @@ public class HttpProxy extends ProxyConfiguration.Proxy
connection.send(connect, result -> connection.send(connect, result ->
{ {
// The EndPoint may have changed during the conversation, get the latest. // The EndPoint may have changed during the conversation, get the latest.
EndPoint endPoint1 = (EndPoint)conversation.getAttribute(EndPoint.class.getName()); EndPoint endPoint = (EndPoint)conversation.getAttribute(EndPoint.class.getName());
if (result.isSucceeded()) if (result.isSucceeded())
{ {
Response response = result.getResponse(); Response response = result.getResponse();
if (response.getStatus() == HttpStatus.OK_200) if (response.getStatus() == HttpStatus.OK_200)
{ {
tunnelSucceeded(endPoint1); tunnelSucceeded(endPoint);
} }
else else
{ {
HttpResponseException failure = new HttpResponseException("Unexpected " + response + HttpResponseException failure = new HttpResponseException("Unexpected " + response +
" for " + result.getRequest(), response); " for " + result.getRequest(), response);
tunnelFailed(endPoint1, failure); tunnelFailed(endPoint, failure);
} }
} }
else else
{ {
tunnelFailed(endPoint1, result.getFailure()); tunnelFailed(endPoint, result.getFailure());
} }
}); });
} }
@ -206,6 +205,9 @@ public class HttpProxy extends ProxyConfiguration.Proxy
new SslClientConnectionFactory(client.getSslContextFactory(), client.getByteBufferPool(), client.getExecutor(), connectionFactory); new SslClientConnectionFactory(client.getSslContextFactory(), client.getByteBufferPool(), client.getExecutor(), connectionFactory);
HttpConnectionOverHTTP oldConnection = (HttpConnectionOverHTTP)endPoint.getConnection(); HttpConnectionOverHTTP oldConnection = (HttpConnectionOverHTTP)endPoint.getConnection();
org.eclipse.jetty.io.Connection newConnection = sslConnectionFactory.newConnection(endPoint, context); org.eclipse.jetty.io.Connection newConnection = sslConnectionFactory.newConnection(endPoint, context);
// Creating the connection will link the new Connection the EndPoint,
// but we need the old Connection linked for the upgrade to do its job.
endPoint.setConnection(oldConnection);
endPoint.upgrade(newConnection); endPoint.upgrade(newConnection);
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("HTTP tunnel established: {} over {}", oldConnection, newConnection); LOG.debug("HTTP tunnel established: {} over {}", oldConnection, newConnection);

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.client.HttpResponseException;
import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
@ -176,7 +177,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
protected void fillInterested() protected void fillInterested()
{ {
getHttpChannel().getHttpConnection().fillInterested(); getHttpConnection().fillInterested();
} }
private void shutdown() private void shutdown()
@ -276,7 +277,19 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
if (exchange == null) if (exchange == null)
return false; return false;
return !responseSuccess(exchange); boolean proceed = responseSuccess(exchange);
if (!proceed)
return true;
int status = exchange.getResponse().getStatus();
if (status == HttpStatus.SWITCHING_PROTOCOLS_101)
return true;
if (HttpMethod.CONNECT.is(exchange.getRequest().getMethod()) &&
status == HttpStatus.OK_200)
return true;
return false;
} }
@Override @Override

View File

@ -77,6 +77,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.toolchain.test.TestingDir;
@ -1510,6 +1511,11 @@ public class HttpClientTest extends AbstractHttpClientServerTest
ContentResponse response = listener.get(5, TimeUnit.SECONDS); ContentResponse response = listener.get(5, TimeUnit.SECONDS);
Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(200, response.getStatus());
// Because the tunnel was successful, this connection will be
// upgraded to an SslConnection, so it will not be fill interested.
// This test doesn't upgrade, so it needs to restore the fill interest.
((AbstractConnection)connection).fillInterested();
// Test that I can send another request on the same connection. // Test that I can send another request on the same connection.
request = client.newRequest(host, port); request = client.newRequest(host, port);
listener = new FutureResponseListener(request); listener = new FutureResponseListener(request);

View File

@ -181,6 +181,7 @@ public class ForwardProxyTLSServerTest
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
@ -210,6 +211,7 @@ public class ForwardProxyTLSServerTest
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response1.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response1.getStatus());
@ -224,6 +226,7 @@ public class ForwardProxyTLSServerTest
.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString()) .header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString())
.header(HttpHeader.CONTENT_LENGTH, String.valueOf(content.length())) .header(HttpHeader.CONTENT_LENGTH, String.valueOf(content.length()))
.content(new StringContentProvider(content)) .content(new StringContentProvider(content))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response2.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response2.getStatus());
@ -250,11 +253,11 @@ public class ForwardProxyTLSServerTest
{ {
final AtomicReference<Connection> connection = new AtomicReference<>(); final AtomicReference<Connection> connection = new AtomicReference<>();
final CountDownLatch connectionLatch = new CountDownLatch(1); final CountDownLatch connectionLatch = new CountDownLatch(1);
String body1 = "BODY"; String content1 = "BODY";
ContentResponse response1 = httpClient.newRequest("localhost", serverConnector.getLocalPort()) ContentResponse response1 = httpClient.newRequest("localhost", serverConnector.getLocalPort())
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body1, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(content1, "UTF-8"))
.onRequestCommit(request -> .onRequestCommit(request ->
{ {
Destination destination = httpClient.getDestination(HttpScheme.HTTPS.asString(), "localhost", serverConnector.getLocalPort()); Destination destination = httpClient.getDestination(HttpScheme.HTTPS.asString(), "localhost", serverConnector.getLocalPort());
@ -268,15 +271,16 @@ public class ForwardProxyTLSServerTest
} }
}); });
}) })
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response1.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response1.getStatus());
String content = response1.getContentAsString(); String content = response1.getContentAsString();
Assert.assertEquals(body1, content); Assert.assertEquals(content1, content);
Assert.assertTrue(connectionLatch.await(5, TimeUnit.SECONDS)); Assert.assertTrue(connectionLatch.await(5, TimeUnit.SECONDS));
String body2 = "body=" + body1; String body2 = "body=" + content1;
org.eclipse.jetty.client.api.Request request2 = httpClient.newRequest("localhost", serverConnector.getLocalPort()) org.eclipse.jetty.client.api.Request request2 = httpClient.newRequest("localhost", serverConnector.getLocalPort())
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.POST) .method(HttpMethod.POST)
@ -291,8 +295,8 @@ public class ForwardProxyTLSServerTest
ContentResponse response2 = listener2.get(5, TimeUnit.SECONDS); ContentResponse response2 = listener2.get(5, TimeUnit.SECONDS);
Assert.assertEquals(HttpStatus.OK_200, response2.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response2.getStatus());
String content2 = response1.getContentAsString(); String content2 = response2.getContentAsString();
Assert.assertEquals(body1, content2); Assert.assertEquals(content1, content2);
} }
finally finally
{ {
@ -341,6 +345,7 @@ public class ForwardProxyTLSServerTest
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
// Long idle timeout for the request. // Long idle timeout for the request.
.idleTimeout(10 * idleTimeout, TimeUnit.MILLISECONDS) .idleTimeout(10 * idleTimeout, TimeUnit.MILLISECONDS)
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
@ -372,6 +377,7 @@ public class ForwardProxyTLSServerTest
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.fail(); Assert.fail();
} }
@ -404,6 +410,7 @@ public class ForwardProxyTLSServerTest
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.fail(); Assert.fail();
} }
@ -438,6 +445,7 @@ public class ForwardProxyTLSServerTest
{ {
httpClient.newRequest("localhost", serverConnector.getLocalPort()) httpClient.newRequest("localhost", serverConnector.getLocalPort())
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.fail(); Assert.fail();
} }
@ -516,6 +524,7 @@ public class ForwardProxyTLSServerTest
.scheme(HttpScheme.HTTPS.asString()) .scheme(HttpScheme.HTTPS.asString())
.method(HttpMethod.GET) .method(HttpMethod.GET)
.path("/echo?body=" + URLEncoder.encode(body, "UTF-8")) .path("/echo?body=" + URLEncoder.encode(body, "UTF-8"))
.timeout(5, TimeUnit.SECONDS)
.send(); .send();
Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); Assert.assertEquals(HttpStatus.OK_200, response.getStatus());

View File

@ -378,9 +378,10 @@ public class HttpChannelState
} }
else else
{ {
read_interested=_asyncReadUnready;
_state=State.ASYNC_WAIT; _state=State.ASYNC_WAIT;
action=Action.WAIT; action=Action.WAIT;
if (_asyncReadUnready)
_channel.asyncReadFillInterested();
Scheduler scheduler = _channel.getScheduler(); Scheduler scheduler = _channel.getScheduler();
if (scheduler!=null && _timeoutMs>0) if (scheduler!=null && _timeoutMs>0)
_event.setTimeoutTask(scheduler.schedule(_event,_timeoutMs,TimeUnit.MILLISECONDS)); _event.setTimeoutTask(scheduler.schedule(_event,_timeoutMs,TimeUnit.MILLISECONDS));
@ -419,8 +420,6 @@ public class HttpChannelState
} }
} }
if (read_interested)
_channel.asyncReadFillInterested();
return action; return action;
} }