use attributes instead of attachable for wrapped request/response

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2022-08-09 15:46:14 +10:00
parent c5f5bb9bba
commit 6101384cf6
15 changed files with 78 additions and 158 deletions

View File

@ -75,7 +75,6 @@ import org.eclipse.jetty.server.handler.ContextRequest;
import org.eclipse.jetty.server.handler.ContextResponse; import org.eclipse.jetty.server.handler.ContextResponse;
import org.eclipse.jetty.session.Session; import org.eclipse.jetty.session.Session;
import org.eclipse.jetty.session.SessionManager; import org.eclipse.jetty.session.SessionManager;
import org.eclipse.jetty.util.Attachable;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.HostPort;
@ -84,10 +83,11 @@ import org.eclipse.jetty.util.URIUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class ServletContextRequest extends ContextRequest implements Runnable, Attachable public class ServletContextRequest extends ContextRequest implements Runnable
{ {
public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.jetty.multipartConfig"; public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.jetty.multipartConfig";
public static final String WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE = "org.eclipse.jetty.websocket.wrappedRequest";
public static final String WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE = "org.eclipse.jetty.websocket.wrappedResponse";
private static final Logger LOG = LoggerFactory.getLogger(ServletContextRequest.class); private static final Logger LOG = LoggerFactory.getLogger(ServletContextRequest.class);
private static final Collection<Locale> __defaultLocale = Collections.singleton(Locale.getDefault()); private static final Collection<Locale> __defaultLocale = Collections.singleton(Locale.getDefault());
private static final int INPUT_NONE = 0; private static final int INPUT_NONE = 0;
@ -143,18 +143,6 @@ public class ServletContextRequest extends ContextRequest implements Runnable, A
_pathInContext = pathInContext; _pathInContext = pathInContext;
} }
@Override
public Object getAttachment()
{
return _attachment.get();
}
@Override
public void setAttachment(Object attachment)
{
_attachment.set(attachment);
}
@Override @Override
public void process(Request request, Response response, Callback callback) throws Exception public void process(Request request, Response response, Callback callback) throws Exception
{ {

View File

@ -54,7 +54,6 @@ import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.ContextResponse; import org.eclipse.jetty.server.handler.ContextResponse;
import org.eclipse.jetty.session.Session; import org.eclipse.jetty.session.Session;
import org.eclipse.jetty.session.SessionManager; import org.eclipse.jetty.session.SessionManager;
import org.eclipse.jetty.util.Attachable;
import org.eclipse.jetty.util.Blocker; import org.eclipse.jetty.util.Blocker;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.FutureCallback;
@ -62,7 +61,7 @@ import org.eclipse.jetty.util.SharedBlockingCallback;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
public class ServletContextResponse extends ContextResponse implements Attachable public class ServletContextResponse extends ContextResponse
{ {
private static final int __MIN_BUFFER_SIZE = 1; private static final int __MIN_BUFFER_SIZE = 1;
private static final HttpField __EXPIRES_01JAN1970 = new PreEncodedHttpField(HttpHeader.EXPIRES, DateGenerator.__01Jan1970); private static final HttpField __EXPIRES_01JAN1970 = new PreEncodedHttpField(HttpHeader.EXPIRES, DateGenerator.__01Jan1970);
@ -115,18 +114,6 @@ public class ServletContextResponse extends ContextResponse implements Attachabl
_httpServletResponse = new ServletApiResponse(response); _httpServletResponse = new ServletApiResponse(response);
} }
@Override
public Object getAttachment()
{
return _attachment.get();
}
@Override
public void setAttachment(Object attachment)
{
_attachment.set(attachment);
}
public HttpOutput getHttpOutput() public HttpOutput getHttpOutput()
{ {
return _httpOutput; return _httpOutput;

View File

@ -306,10 +306,10 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, defaultCustomizer)) if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, defaultCustomizer))
{ {
@ -318,8 +318,8 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
} }
finally finally
{ {
baseRequest.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }

View File

@ -225,10 +225,10 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, customizer)) if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, customizer))
{ {
@ -238,8 +238,8 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
} }
finally finally
{ {
baseRequest.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
return false; return false;

View File

@ -191,10 +191,10 @@ public abstract class JettyWebSocketServlet extends HttpServlet
// provide a null default customizer the customizer will be on the negotiator in the mapping // provide a null default customizer the customizer will be on the negotiator in the mapping
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
request.setAttachment(req); request.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, req);
response.setAttachment(resp); request.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, resp);
if (mapping.upgrade(request, response, callback, null)) if (mapping.upgrade(request, response, callback, null))
{ {
@ -204,8 +204,8 @@ public abstract class JettyWebSocketServlet extends HttpServlet
} }
finally finally
{ {
request.setAttachment(null); request.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
response.setAttachment(null); request.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }

View File

@ -37,7 +37,6 @@ import org.eclipse.jetty.ee10.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeRequest; import org.eclipse.jetty.ee10.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest; import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest;
@ -52,13 +51,9 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
public DelegatedServerUpgradeRequest(ServerUpgradeRequest request) public DelegatedServerUpgradeRequest(ServerUpgradeRequest request)
{ {
ServletContextRequest servletContextRequest = Request.as(request, ServletContextRequest.class); this.httpServletRequest = (HttpServletRequest)request
Object attachment = servletContextRequest.getAttachment(); .getAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
if (!(attachment instanceof HttpServletRequest))
throw new IllegalArgumentException("correct attachment not set on ServletContextRequest");
this.upgradeRequest = request; this.upgradeRequest = request;
this.httpServletRequest = (HttpServletRequest)attachment;
this.queryString = httpServletRequest.getQueryString(); this.queryString = httpServletRequest.getQueryString();
try try

View File

@ -22,6 +22,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee10.servlet.ServletContextRequest;
import org.eclipse.jetty.ee10.servlet.ServletContextResponse; import org.eclipse.jetty.ee10.servlet.ServletContextResponse;
import org.eclipse.jetty.ee10.websocket.api.ExtensionConfig; import org.eclipse.jetty.ee10.websocket.api.ExtensionConfig;
import org.eclipse.jetty.ee10.websocket.common.JettyExtensionConfig; import org.eclipse.jetty.ee10.websocket.common.JettyExtensionConfig;
@ -39,10 +40,8 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
{ {
upgradeResponse = response; upgradeResponse = response;
ServletContextResponse servletContextResponse = Response.as(response, ServletContextResponse.class); ServletContextResponse servletContextResponse = Response.as(response, ServletContextResponse.class);
Object attachment = servletContextResponse.getAttachment(); this.httpServletResponse = (HttpServletResponse)servletContextResponse.getRequest()
if (!(attachment instanceof HttpServletResponse)) .getAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
throw new IllegalArgumentException("correct attachment not set on ServletContextResponse");
this.httpServletResponse = (HttpServletResponse)attachment;
} }
@Override @Override

View File

@ -167,10 +167,10 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
// provide a null default customizer the customizer will be on the negotiator in the mapping // provide a null default customizer the customizer will be on the negotiator in the mapping
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (mappings.upgrade(baseRequest, baseResponse, callback, defaultCustomizer)) if (mappings.upgrade(baseRequest, baseResponse, callback, defaultCustomizer))
{ {
@ -180,8 +180,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
} }
finally finally
{ {
baseRequest.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); baseRequest.removeAttribute(ServletContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }

View File

@ -35,7 +35,6 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier; import java.util.function.Supplier;
import jakarta.servlet.DispatcherType; import jakarta.servlet.DispatcherType;
@ -73,8 +72,6 @@ import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ContextRequest; import org.eclipse.jetty.server.handler.ContextRequest;
import org.eclipse.jetty.server.handler.ContextResponse;
import org.eclipse.jetty.util.Attachable;
import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.ExceptionUtil;
@ -2453,11 +2450,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
} }
} }
public static class CoreContextRequest extends ContextRequest implements Attachable public static class CoreContextRequest extends ContextRequest
{ {
public static final String WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE = "org.eclipse.jetty.websocket.wrappedRequest";
public static final String WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE = "org.eclipse.jetty.websocket.wrappedResponse";
private final HttpChannel _httpChannel; private final HttpChannel _httpChannel;
private final org.eclipse.jetty.server.handler.ContextHandler _contextHandler;
private final AtomicReference<Object> _attachment = new AtomicReference<>();
protected CoreContextRequest(org.eclipse.jetty.server.handler.ContextHandler contextHandler, protected CoreContextRequest(org.eclipse.jetty.server.handler.ContextHandler contextHandler,
org.eclipse.jetty.server.handler.ContextHandler.Context context, org.eclipse.jetty.server.handler.ContextHandler.Context context,
@ -2467,53 +2465,12 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
{ {
super(contextHandler, context, wrapped, pathInContext); super(contextHandler, context, wrapped, pathInContext);
_httpChannel = httpChannel; _httpChannel = httpChannel;
_contextHandler = contextHandler;
} }
public HttpChannel getHttpChannel() public HttpChannel getHttpChannel()
{ {
return _httpChannel; return _httpChannel;
} }
@Override
protected ContextResponse newContextResponse(org.eclipse.jetty.server.Request request, Response response)
{
return new CoreContextResponse(_contextHandler.getContext(), this, response);
}
@Override
public Object getAttachment()
{
return _attachment.get();
}
@Override
public void setAttachment(Object attachment)
{
_attachment.set(attachment);
}
}
public static class CoreContextResponse extends ContextResponse implements Attachable
{
private final AtomicReference<Object> _attachment = new AtomicReference<>();
public CoreContextResponse(org.eclipse.jetty.server.handler.ContextHandler.Context context, org.eclipse.jetty.server.Request request, Response response)
{
super(context, request, response);
}
@Override
public Object getAttachment()
{
return _attachment.get();
}
@Override
public void setAttachment(Object attachment)
{
_attachment.set(attachment);
}
} }
public class CoreContextHandler extends org.eclipse.jetty.server.handler.ContextHandler implements org.eclipse.jetty.server.Request.Processor public class CoreContextHandler extends org.eclipse.jetty.server.handler.ContextHandler implements org.eclipse.jetty.server.Request.Processor

View File

@ -301,14 +301,15 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
Handshaker handshaker = webSocketMappings.getHandshaker(); Handshaker handshaker = webSocketMappings.getHandshaker();
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName()); HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
ContextHandler.CoreContextRequest baseRequest = Request.as(httpChannel.getCoreRequest(), ContextHandler.CoreContextRequest.class); Request baseRequest = httpChannel.getCoreRequest();
ContextHandler.CoreContextResponse baseResponse = Response.as(httpChannel.getCoreResponse(), ContextHandler.CoreContextResponse.class); Response baseResponse = httpChannel.getCoreResponse();
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, defaultCustomizer)) if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, defaultCustomizer))
{ {
@ -317,8 +318,8 @@ public class JakartaWebSocketServerContainer extends JakartaWebSocketClientConta
} }
finally finally
{ {
baseRequest.setAttachment(null); request.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); request.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }

View File

@ -220,14 +220,15 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
Handshaker handshaker = webSocketMappings.getHandshaker(); Handshaker handshaker = webSocketMappings.getHandshaker();
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName()); HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
ContextHandler.CoreContextRequest baseRequest = Request.as(httpChannel.getCoreRequest(), ContextHandler.CoreContextRequest.class); Request baseRequest = httpChannel.getCoreRequest();
ContextHandler.CoreContextResponse baseResponse = Response.as(httpChannel.getCoreResponse(), ContextHandler.CoreContextResponse.class); Response baseResponse = httpChannel.getCoreResponse();
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, customizer)) if (handshaker.upgradeRequest(negotiator, baseRequest, baseResponse, callback, components, customizer))
{ {
@ -237,8 +238,8 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
} }
finally finally
{ {
baseRequest.setAttachment(null); baseRequest.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); baseRequest.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
return false; return false;
} }

View File

@ -185,8 +185,8 @@ public abstract class JettyWebSocketServlet extends HttpServlet
{ {
// provide a null default customizer the customizer will be on the negotiator in the mapping // provide a null default customizer the customizer will be on the negotiator in the mapping
HttpChannel httpChannel = (HttpChannel)req.getAttribute(HttpChannel.class.getName()); HttpChannel httpChannel = (HttpChannel)req.getAttribute(HttpChannel.class.getName());
ContextHandler.CoreContextRequest request = Request.as(httpChannel.getCoreRequest(), ContextHandler.CoreContextRequest.class); Request request = httpChannel.getCoreRequest();
ContextHandler.CoreContextResponse response = Response.as(httpChannel.getCoreResponse(), ContextHandler.CoreContextResponse.class); Response response = httpChannel.getCoreResponse();
// Do preliminary check before proceeding to attempt an upgrade. // Do preliminary check before proceeding to attempt an upgrade.
if (mapping.getHandshaker().isWebSocketUpgradeRequest(request)) if (mapping.getHandshaker().isWebSocketUpgradeRequest(request))
@ -194,10 +194,10 @@ public abstract class JettyWebSocketServlet extends HttpServlet
// provide a null default customizer the customizer will be on the negotiator in the mapping // provide a null default customizer the customizer will be on the negotiator in the mapping
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
request.setAttachment(req); request.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, req);
response.setAttachment(resp); request.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, resp);
if (mapping.upgrade(request, response, callback, null)) if (mapping.upgrade(request, response, callback, null))
{ {
@ -207,8 +207,8 @@ public abstract class JettyWebSocketServlet extends HttpServlet
} }
finally finally
{ {
request.setAttachment(null); request.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
response.setAttachment(null); request.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }

View File

@ -37,7 +37,6 @@ import org.eclipse.jetty.ee9.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeRequest; import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest; import org.eclipse.jetty.websocket.core.server.ServerUpgradeRequest;
@ -52,13 +51,9 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
public DelegatedServerUpgradeRequest(ServerUpgradeRequest request) public DelegatedServerUpgradeRequest(ServerUpgradeRequest request)
{ {
this(request, Request.as(request, ContextHandler.CoreContextRequest.class).getHttpChannel().getRequest()); this.httpServletRequest = (HttpServletRequest)request
} .getAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
public DelegatedServerUpgradeRequest(ServerUpgradeRequest request, HttpServletRequest servletRequest)
{
this.upgradeRequest = request; this.upgradeRequest = request;
this.httpServletRequest = servletRequest;
this.queryString = httpServletRequest.getQueryString(); this.queryString = httpServletRequest.getQueryString();
try try
@ -145,13 +140,13 @@ public class DelegatedServerUpgradeRequest implements JettyServerUpgradeRequest
@Override @Override
public String getMethod() public String getMethod()
{ {
return upgradeRequest.getMethod(); return httpServletRequest.getMethod();
} }
@Override @Override
public String getOrigin() public String getOrigin()
{ {
return upgradeRequest.getHeaders().get(HttpHeader.ORIGIN); return httpServletRequest.getHeader(HttpHeader.ORIGIN.asString());
} }
@Override @Override

View File

@ -21,26 +21,31 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee9.nested.ContextHandler;
import org.eclipse.jetty.ee9.websocket.api.ExtensionConfig; import org.eclipse.jetty.ee9.websocket.api.ExtensionConfig;
import org.eclipse.jetty.ee9.websocket.common.JettyExtensionConfig; import org.eclipse.jetty.ee9.websocket.common.JettyExtensionConfig;
import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeResponse; import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeResponse;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Blocker;
import org.eclipse.jetty.websocket.core.server.ServerUpgradeResponse; import org.eclipse.jetty.websocket.core.server.ServerUpgradeResponse;
public class DelegatedServerUpgradeResponse implements JettyServerUpgradeResponse public class DelegatedServerUpgradeResponse implements JettyServerUpgradeResponse
{ {
private final ServerUpgradeResponse upgradeResponse; private final ServerUpgradeResponse upgradeResponse;
private final HttpServletResponse httpServletResponse;
public DelegatedServerUpgradeResponse(ServerUpgradeResponse response) public DelegatedServerUpgradeResponse(ServerUpgradeResponse response)
{ {
upgradeResponse = response; this.upgradeResponse = response;
this.httpServletResponse = (HttpServletResponse)response.getRequest()
.getAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
@Override @Override
public void addHeader(String name, String value) public void addHeader(String name, String value)
{ {
// TODO: This should go to the httpServletResponse for headers but then it won't do interception of the websocket headers
// which are done through the jetty-core Response wrapping ServerUpgradeResponse done by websocket-core.
upgradeResponse.getHeaders().add(name, value); upgradeResponse.getHeaders().add(name, value);
} }
@ -97,17 +102,13 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override @Override
public int getStatusCode() public int getStatusCode()
{ {
return upgradeResponse.getStatus(); return httpServletResponse.getStatus();
} }
@Override @Override
public void sendForbidden(String message) throws IOException public void sendForbidden(String message) throws IOException
{ {
try (Blocker.Callback callback = Blocker.callback()) httpServletResponse.sendError(HttpStatus.FORBIDDEN_403, message);
{
Response.writeError(upgradeResponse.getRequest(), upgradeResponse, callback, HttpStatus.FORBIDDEN_403, message);
callback.block();
}
} }
@Override @Override
@ -127,22 +128,18 @@ public class DelegatedServerUpgradeResponse implements JettyServerUpgradeRespons
@Override @Override
public void setStatusCode(int statusCode) public void setStatusCode(int statusCode)
{ {
upgradeResponse.setStatus(statusCode); httpServletResponse.setStatus(statusCode);
} }
@Override @Override
public boolean isCommitted() public boolean isCommitted()
{ {
return upgradeResponse.isCommitted(); return httpServletResponse.isCommitted();
} }
@Override @Override
public void sendError(int statusCode, String message) throws IOException public void sendError(int statusCode, String message) throws IOException
{ {
try (Blocker.Callback callback = Blocker.callback()) httpServletResponse.sendError(statusCode, message);
{
Response.writeError(upgradeResponse.getRequest(), upgradeResponse, callback, statusCode, message);
callback.block();
}
} }
} }

View File

@ -157,8 +157,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{ {
HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName()); HttpChannel httpChannel = (HttpChannel)request.getAttribute(HttpChannel.class.getName());
ContextHandler.CoreContextRequest baseRequest = Request.as(httpChannel.getCoreRequest(), ContextHandler.CoreContextRequest.class); Request baseRequest = httpChannel.getCoreRequest();
ContextHandler.CoreContextResponse baseResponse = Response.as(httpChannel.getCoreResponse(), ContextHandler.CoreContextResponse.class); Response baseResponse = httpChannel.getCoreResponse();
// Do preliminary check before proceeding to attempt an upgrade. // Do preliminary check before proceeding to attempt an upgrade.
if (mappings.getHandshaker().isWebSocketUpgradeRequest(baseRequest)) if (mappings.getHandshaker().isWebSocketUpgradeRequest(baseRequest))
@ -166,10 +166,10 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
// provide a null default customizer the customizer will be on the negotiator in the mapping // provide a null default customizer the customizer will be on the negotiator in the mapping
try (Blocker.Callback callback = Blocker.callback()) try (Blocker.Callback callback = Blocker.callback())
{ {
// Set the wrapped req and resp as attachments on the ServletContext Request/Response, so they // Set the wrapped req and resp as attributes on the ServletContext Request/Response, so they
// are accessible when websocket-core calls back the Jetty WebSocket creator. // are accessible when websocket-core calls back the Jetty WebSocket creator.
baseRequest.setAttachment(request); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE, request);
baseResponse.setAttachment(response); baseRequest.setAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE, response);
if (mappings.upgrade(baseRequest, baseResponse, callback, defaultCustomizer)) if (mappings.upgrade(baseRequest, baseResponse, callback, defaultCustomizer))
{ {
@ -179,8 +179,8 @@ public class WebSocketUpgradeFilter implements Filter, Dumpable
} }
finally finally
{ {
baseRequest.setAttachment(null); baseRequest.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_REQUEST_ATTRIBUTE);
baseResponse.setAttachment(null); baseRequest.removeAttribute(ContextHandler.CoreContextRequest.WEBSOCKET_WRAPPED_RESPONSE_ATTRIBUTE);
} }
} }