479678 - Support HTTP/1.1 Upgrade in HttpClient.

Initial support.
This commit is contained in:
Simone Bordet 2015-10-13 22:55:11 +02:00
parent f052fc30a3
commit b0eb18b451
9 changed files with 89 additions and 6 deletions

View File

@ -129,6 +129,11 @@ public abstract class HttpChannel
return getHttpReceiver().abort(exchange, failure);
}
public Result exchangeTerminating(HttpExchange exchange, Result result)
{
return result;
}
public void exchangeTerminated(HttpExchange exchange, Result result)
{
disassociate(exchange);

View File

@ -531,15 +531,12 @@ public class HttpClient extends ContainerLifeCycle
*/
public List<Destination> getDestinations()
{
return new ArrayList<Destination>(destinations.values());
return new ArrayList<>(destinations.values());
}
protected void send(final HttpRequest request, List<Response.ResponseListener> listeners)
{
String scheme = request.getScheme().toLowerCase(Locale.ENGLISH);
if (!HttpScheme.HTTP.is(scheme) && !HttpScheme.HTTPS.is(scheme))
throw new IllegalArgumentException("Invalid protocol " + scheme);
String host = request.getHost().toLowerCase(Locale.ENGLISH);
HttpDestination destination = destinationFor(scheme, host, request.getPort());
destination.send(request, listeners);

View File

@ -437,6 +437,7 @@ public abstract class HttpReceiver
if (result != null)
{
result = channel.exchangeTerminating(exchange, result);
boolean ordered = getHttpDestination().getHttpClient().isStrictEventOrdering();
if (!ordered)
channel.exchangeTerminated(exchange, result);

View File

@ -376,6 +376,7 @@ public abstract class HttpSender implements AsyncContentProvider.Listener
}
else
{
result = channel.exchangeTerminating(exchange, result);
HttpDestination destination = getHttpChannel().getHttpDestination();
boolean ordered = destination.getHttpClient().isStrictEventOrdering();
if (!ordered)

View File

@ -167,12 +167,17 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
}
}
public boolean remove(Connection connection)
{
return connectionPool.remove(connection);
}
@Override
public void close(Connection connection)
{
super.close(connection);
boolean removed = connectionPool.remove(connection);
boolean removed = remove(connection);
if (getHttpExchanges().isEmpty())
{

View File

@ -52,6 +52,14 @@ public class Result
this.responseFailure = responseFailure;
}
public Result(Result result, Throwable responseFailure)
{
this.request = result.request;
this.requestFailure = result.requestFailure;
this.response = result.response;
this.responseFailure = responseFailure;
}
/**
* @return the request object
*/

View File

@ -21,6 +21,8 @@ package org.eclipse.jetty.client.http;
import org.eclipse.jetty.client.HttpChannel;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.client.HttpReceiver;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.HttpResponse;
import org.eclipse.jetty.client.HttpSender;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.api.Result;
@ -28,6 +30,7 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpVersion;
public class HttpChannelOverHTTP extends HttpChannel
@ -85,6 +88,34 @@ public class HttpChannelOverHTTP extends HttpChannel
connection.release();
}
@Override
public Result exchangeTerminating(HttpExchange exchange, Result result)
{
if (result.isFailed())
return result;
HttpResponse response = exchange.getResponse();
if (response.getStatus() != HttpStatus.SWITCHING_PROTOCOLS_101)
return result;
// TODO: protocol version and connection: upgrade
HttpRequest request = exchange.getRequest();
if (request instanceof HttpConnectionUpgrader)
{
HttpConnectionUpgrader listener = (HttpConnectionUpgrader)request;
try
{
listener.upgrade(response, getHttpConnection());
}
catch (Throwable x)
{
return new Result(result, x);
}
}
return result;
}
public void receive()
{
receiver.receive();
@ -131,6 +162,9 @@ public class HttpChannelOverHTTP extends HttpChannel
}
else
{
if (response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101)
connection.remove();
else
release();
}
}
@ -143,4 +177,5 @@ public class HttpChannelOverHTTP extends HttpChannel
sender,
receiver);
}
}

View File

@ -171,6 +171,11 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
return true;
}
public void remove()
{
getHttpDestination().remove(this);
}
@Override
public String toString()
{

View File

@ -0,0 +1,26 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.client.http;
import org.eclipse.jetty.client.HttpResponse;
public interface HttpConnectionUpgrader
{
public void upgrade(HttpResponse response, HttpConnectionOverHTTP connection);
}