add request and response to JettyWSFrameHandler on server side

wrap exceptions delivered to jetty connect CompletableFuture

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-06-20 16:47:11 +10:00
parent ec4179cf42
commit e305736b02
7 changed files with 375 additions and 6 deletions

View File

@ -44,10 +44,15 @@ public class UpgradeException extends WebSocketException
}
public UpgradeException(URI requestURI, Throwable cause)
{
this(requestURI, -1, cause);
}
public UpgradeException(URI requestURI, int responseStatusCode, Throwable cause)
{
super(cause);
this.requestURI = requestURI;
this.responseStatusCode = -1;
this.responseStatusCode = responseStatusCode;
}
public URI getRequestURI()

View File

@ -152,7 +152,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketPoli
{
if (error != null)
{
futureSession.completeExceptionally(error);
futureSession.completeExceptionally(JettyWebSocketFrameHandler.convertCause(error));
return;
}

View File

@ -473,7 +473,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler
session.getCoreSession().demand(1);
}
static Throwable convertCause(Throwable cause)
public static Throwable convertCause(Throwable cause)
{
if (cause instanceof MessageTooLargeException)
return new org.eclipse.jetty.websocket.api.MessageTooLargeException(cause.getMessage(), cause);
@ -494,7 +494,10 @@ public class JettyWebSocketFrameHandler implements FrameHandler
return new org.eclipse.jetty.websocket.api.InvalidWebSocketException(cause.getMessage(), cause);
if (cause instanceof UpgradeException)
return new org.eclipse.jetty.websocket.api.UpgradeException(((UpgradeException)cause).getRequestURI(), cause);
{
UpgradeException ue = (UpgradeException)cause;
return new org.eclipse.jetty.websocket.api.UpgradeException(ue.getRequestURI(), ue.getResponseStatusCode(), cause);
}
return cause;
}

View File

@ -23,6 +23,7 @@ import javax.servlet.ServletContext;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler;
import org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory;
import org.eclipse.jetty.websocket.common.WebSocketContainer;
import org.eclipse.jetty.websocket.core.FrameHandler;
@ -48,7 +49,10 @@ public class JettyServerFrameHandlerFactory
@Override
public FrameHandler newFrameHandler(Object websocketPojo, ServletUpgradeRequest upgradeRequest, ServletUpgradeResponse upgradeResponse)
{
return super.newJettyFrameHandler(websocketPojo);
JettyWebSocketFrameHandler frameHandler = super.newJettyFrameHandler(websocketPojo);
frameHandler.setUpgradeRequest(new UpgradeRequestAdapter(upgradeRequest));
frameHandler.setUpgradeResponse(new UpgradeResponseAdapter(upgradeResponse));
return frameHandler;
}
@Override

View File

@ -0,0 +1,235 @@
//
// ========================================================================
// Copyright (c) 1995-2019 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.websocket.server.internal;
import java.net.HttpCookie;
import java.net.URI;
import java.security.Principal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
public class UpgradeRequestAdapter implements UpgradeRequest
{
private final ServletUpgradeRequest servletRequest;
public UpgradeRequestAdapter(ServletUpgradeRequest servletRequest)
{
this.servletRequest = servletRequest;
}
@Override
public void addExtensions(ExtensionConfig... configs)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void addExtensions(String... configs)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public List<HttpCookie> getCookies()
{
return this.servletRequest.getCookies();
}
@Override
public List<ExtensionConfig> getExtensions()
{
return this.servletRequest.getExtensions().stream()
.map((ext) -> new JettyExtensionConfig(ext.getName(), ext.getParameters()))
.collect(Collectors.toList());
}
@Override
public String getHeader(String name)
{
return this.servletRequest.getHeader(name);
}
@Override
public int getHeaderInt(String name)
{
return this.servletRequest.getHeaderInt(name);
}
@Override
public Map<String, List<String>> getHeaders()
{
return this.servletRequest.getHeadersMap();
}
@Override
public List<String> getHeaders(String name)
{
return this.servletRequest.getHeaders(name);
}
@Override
public String getHost()
{
return this.servletRequest.getHost();
}
@Override
public String getHttpVersion()
{
return this.servletRequest.getHttpVersion();
}
@Override
public String getMethod()
{
return this.servletRequest.getMethod();
}
@Override
public String getOrigin()
{
return this.servletRequest.getOrigin();
}
@Override
public Map<String, List<String>> getParameterMap()
{
return this.servletRequest.getParameterMap();
}
@Override
public String getProtocolVersion()
{
return this.servletRequest.getProtocolVersion();
}
@Override
public String getQueryString()
{
return this.servletRequest.getQueryString();
}
@Override
public URI getRequestURI()
{
return this.servletRequest.getRequestURI();
}
@Override
public Object getSession()
{
return this.servletRequest.getSession();
}
@Override
public List<String> getSubProtocols()
{
return this.servletRequest.getSubProtocols();
}
@Override
public Principal getUserPrincipal()
{
return this.servletRequest.getUserPrincipal();
}
@Override
public boolean hasSubProtocol(String test)
{
return this.servletRequest.hasSubProtocol(test);
}
@Override
public boolean isSecure()
{
return this.servletRequest.isSecure();
}
@Override
public void setCookies(List<HttpCookie> cookies)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setExtensions(List<ExtensionConfig> configs)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setHeader(String name, List<String> values)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setHeader(String name, String value)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setHeaders(Map<String, List<String>> headers)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setHttpVersion(String httpVersion)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setMethod(String method)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setRequestURI(URI uri)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setSession(Object session)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setSubProtocols(List<String> protocols)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
@Override
public void setSubProtocols(String... protocols)
{
throw new UnsupportedOperationException("Not supported from Servlet API");
}
}

View File

@ -0,0 +1,123 @@
//
// ========================================================================
// Copyright (c) 1995-2019 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.websocket.server.internal;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
public class UpgradeResponseAdapter implements UpgradeResponse
{
private final ServletUpgradeResponse servletResponse;
public UpgradeResponseAdapter(ServletUpgradeResponse servletResponse)
{
this.servletResponse = servletResponse;
}
@Override
public void addHeader(String name, String value)
{
this.servletResponse.addHeader(name, value);
}
@Override
public String getAcceptedSubProtocol()
{
return this.servletResponse.getAcceptedSubProtocol();
}
@Override
public List<ExtensionConfig> getExtensions()
{
return this.servletResponse.getExtensions().stream()
.map((ext) -> new JettyExtensionConfig(ext.getName(), ext.getParameters()))
.collect(Collectors.toList());
}
@Override
public String getHeader(String name)
{
return this.servletResponse.getHeader(name);
}
@Override
public Set<String> getHeaderNames()
{
return this.servletResponse.getHeaderNames();
}
@Override
public Map<String, List<String>> getHeaders()
{
return this.servletResponse.getHeadersMap();
}
@Override
public List<String> getHeaders(String name)
{
return this.servletResponse.getHeaders(name);
}
@Override
public int getStatusCode()
{
return this.servletResponse.getStatusCode();
}
@Override
public void sendForbidden(String message) throws IOException
{
this.servletResponse.sendForbidden(message);
}
@Override
public void setAcceptedSubProtocol(String protocol)
{
this.servletResponse.setAcceptedSubProtocol(protocol);
}
@Override
public void setExtensions(List<ExtensionConfig> extensions)
{
List<org.eclipse.jetty.websocket.core.ExtensionConfig> coreExtensionConfigs = extensions.stream()
.map((ext) -> new org.eclipse.jetty.websocket.core.ExtensionConfig(ext.getName(), ext.getParameters()))
.collect(Collectors.toList());
this.servletResponse.setExtensions(coreExtensionConfigs);
}
@Override
public void setHeader(String name, String value)
{
this.servletResponse.setHeader(name, value);
}
@Override
public void setStatusCode(int statusCode)
{
this.servletResponse.setStatusCode(statusCode);
}
}

View File

@ -239,7 +239,6 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon
Throwable failure = result.getFailure();
boolean wrapFailure = !((failure instanceof java.net.SocketException) ||
(failure instanceof java.io.InterruptedIOException) ||
(failure instanceof HttpResponseException) ||
(failure instanceof UpgradeException));
if (wrapFailure)
failure = new UpgradeException(requestURI, responseStatusCode, responseLine, failure);