org.eclipse.jetty.client.UpgradeProtocolHandler Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.client;
import java.util.List;
import org.eclipse.jetty.client.transport.HttpConversation;
import org.eclipse.jetty.client.transport.HttpRequest;
import org.eclipse.jetty.client.transport.HttpResponse;
import org.eclipse.jetty.client.transport.ResponseListeners;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.Callback;
/**
* A protocol handler that handles HTTP 101 responses.
*/
public class UpgradeProtocolHandler implements ProtocolHandler
{
private final List protocols = List.of("websocket", "h2c");
@Override
public String getName()
{
return "upgrade";
}
@Override
public boolean accept(Request request, Response response)
{
boolean upgraded = HttpStatus.SWITCHING_PROTOCOLS_101 == response.getStatus();
boolean accepted = false;
if (upgraded)
accepted = acceptHeaders(request, response);
return upgraded && accepted;
}
protected boolean acceptHeaders(Request request, Response response)
{
HttpField responseUpgrade = response.getHeaders().getField(HttpHeader.UPGRADE);
if (responseUpgrade != null && protocols.stream().anyMatch(responseUpgrade::contains))
return true;
// The response may not contain the Upgrade header, so check the request.
HttpField requestUpgrade = request.getHeaders().getField(HttpHeader.UPGRADE);
return requestUpgrade != null && protocols.stream().anyMatch(requestUpgrade::contains);
}
@Override
public Response.Listener getResponseListener()
{
return new Response.Listener()
{
@Override
public void onComplete(Result result)
{
Response response = result.getResponse();
HttpRequest request = (HttpRequest)response.getRequest();
if (result.isSucceeded())
{
try
{
HttpConversation conversation = request.getConversation();
HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName());
if (upgrader == null)
throw new HttpResponseException("101 response without " + HttpUpgrader.class.getSimpleName(), response);
EndPoint endPoint = (EndPoint)conversation.getAttribute(EndPoint.class.getName());
if (endPoint == null)
throw new HttpResponseException("Upgrade without " + EndPoint.class.getSimpleName(), response);
upgrader.upgrade(response, endPoint, Callback.from(Callback.NOOP::succeeded, x -> forwardFailureComplete(request, null, response, x)));
}
catch (Throwable x)
{
forwardFailureComplete(request, null, response, x);
}
}
else
{
forwardFailureComplete(request, result.getRequestFailure(), response, result.getResponseFailure());
}
}
};
}
private void forwardFailureComplete(HttpRequest request, Throwable requestFailure, Response response, Throwable responseFailure)
{
HttpConversation conversation = request.getConversation();
conversation.updateResponseListeners(null);
ResponseListeners responseListeners = conversation.getResponseListeners();
responseListeners.emitFailureComplete(new Result(request, requestFailure, response, responseFailure));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy