Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x

This commit is contained in:
Lachlan Roberts 2020-05-14 13:29:52 +10:00
commit ccaca1892e
6 changed files with 294 additions and 44 deletions

View File

@ -0,0 +1,147 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.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.server;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletMapping;
import org.eclipse.jetty.util.Attributes;
class AsyncAttributes extends Attributes.Wrapper
{
private String _requestURI;
private String _contextPath;
private String _servletPath;
private String _pathInfo;
private String _queryString;
private HttpServletMapping _httpServletMapping;
public AsyncAttributes(Attributes attributes, String requestUri, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
{
super(attributes);
// TODO: make fields final in jetty-10 and NOOP when one of these attributes is set.
_requestURI = requestUri;
_contextPath = contextPath;
_servletPath = servletPath;
_pathInfo = pathInfo;
_queryString = queryString;
_httpServletMapping = httpServletMapping;
}
@Override
public Object getAttribute(String key)
{
switch (key)
{
case AsyncContext.ASYNC_REQUEST_URI:
return _requestURI;
case AsyncContext.ASYNC_CONTEXT_PATH:
return _contextPath;
case AsyncContext.ASYNC_SERVLET_PATH:
return _servletPath;
case AsyncContext.ASYNC_PATH_INFO:
return _pathInfo;
case AsyncContext.ASYNC_QUERY_STRING:
return _queryString;
case AsyncContext.ASYNC_MAPPING:
return _httpServletMapping;
default:
return super.getAttribute(key);
}
}
@Override
public Set<String> getAttributeNameSet()
{
Set<String> set = new HashSet<>(super.getAttributeNameSet());
if (_requestURI != null)
set.add(AsyncContext.ASYNC_REQUEST_URI);
if (_contextPath != null)
set.add(AsyncContext.ASYNC_CONTEXT_PATH);
if (_servletPath != null)
set.add(AsyncContext.ASYNC_SERVLET_PATH);
if (_pathInfo != null)
set.add(AsyncContext.ASYNC_PATH_INFO);
if (_queryString != null)
set.add(AsyncContext.ASYNC_QUERY_STRING);
if (_httpServletMapping != null)
set.add(AsyncContext.ASYNC_MAPPING);
return set;
}
@Override
public void setAttribute(String key, Object value)
{
switch (key)
{
case AsyncContext.ASYNC_REQUEST_URI:
_requestURI = (String)value;
break;
case AsyncContext.ASYNC_CONTEXT_PATH:
_contextPath = (String)value;
break;
case AsyncContext.ASYNC_SERVLET_PATH:
_servletPath = (String)value;
break;
case AsyncContext.ASYNC_PATH_INFO:
_pathInfo = (String)value;
break;
case AsyncContext.ASYNC_QUERY_STRING:
_queryString = (String)value;
break;
case AsyncContext.ASYNC_MAPPING:
_httpServletMapping = (HttpServletMapping)value;
break;
default:
super.setAttribute(key, value);
break;
}
}
@Override
public void clearAttributes()
{
_requestURI = null;
_contextPath = null;
_servletPath = null;
_pathInfo = null;
_queryString = null;
_httpServletMapping = null;
super.clearAttributes();
}
public static void applyAsyncAttributes(Attributes attributes, String requestURI, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
{
if (requestURI != null)
attributes.setAttribute(AsyncContext.ASYNC_REQUEST_URI, requestURI);
if (contextPath != null)
attributes.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, contextPath);
if (servletPath != null)
attributes.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, servletPath);
if (pathInfo != null)
attributes.setAttribute(AsyncContext.ASYNC_PATH_INFO, pathInfo);
if (queryString != null)
attributes.setAttribute(AsyncContext.ASYNC_QUERY_STRING, queryString);
if (httpServletMapping != null)
attributes.setAttribute(AsyncContext.ASYNC_MAPPING, httpServletMapping);
}
}

View File

@ -34,7 +34,7 @@ public class AsyncContextEvent extends AsyncEvent implements Runnable
private final Context _context;
private final AsyncContextState _asyncContext;
private final HttpURI _baseURI;
private volatile HttpChannelState _state;
private final HttpChannelState _state;
private ServletContext _dispatchContext;
private String _dispatchPath;
private volatile Scheduler.Task _timeoutTask;
@ -53,33 +53,9 @@ public class AsyncContextEvent extends AsyncEvent implements Runnable
_state = state;
_baseURI = baseURI;
// If we haven't been async dispatched before
if (baseRequest.getAttribute(AsyncContext.ASYNC_REQUEST_URI) == null)
{
// We are setting these attributes during startAsync, when the spec implies that
// they are only available after a call to AsyncContext.dispatch(...);
// have we been forwarded before?
String uri = (String)baseRequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
if (uri != null)
{
baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI, uri);
baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, baseRequest.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, baseRequest.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO, baseRequest.getAttribute(RequestDispatcher.FORWARD_PATH_INFO));
baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING, baseRequest.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, baseRequest.getAttribute(RequestDispatcher.FORWARD_MAPPING));
}
else
{
baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI, baseRequest.getRequestURI());
baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH, baseRequest.getContextPath());
baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH, baseRequest.getServletPath());
baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO, baseRequest.getPathInfo());
baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING, baseRequest.getQueryString());
baseRequest.setAttribute(AsyncContext.ASYNC_MAPPING, baseRequest.getHttpServletMapping());
}
}
baseRequest.setAsyncAttributes();
}
public HttpURI getBaseURI()

View File

@ -338,19 +338,19 @@ public class Dispatcher implements RequestDispatcher
{
case FORWARD_PATH_INFO:
_pathInfo = (String)value;
return;
break;
case FORWARD_REQUEST_URI:
_requestURI = (String)value;
return;
break;
case FORWARD_SERVLET_PATH:
_servletPath = (String)value;
return;
break;
case FORWARD_CONTEXT_PATH:
_contextPath = (String)value;
return;
break;
case FORWARD_QUERY_STRING:
_query = (String)value;
return;
break;
case FORWARD_MAPPING:
_mapping = (HttpServletMapping)value;
return;
@ -359,6 +359,7 @@ public class Dispatcher implements RequestDispatcher
_attributes.removeAttribute(key);
else
_attributes.setAttribute(key, value);
break;
}
}
else if (value == null)
@ -467,27 +468,28 @@ public class Dispatcher implements RequestDispatcher
{
case INCLUDE_PATH_INFO:
_pathInfo = (String)value;
return;
break;
case INCLUDE_REQUEST_URI:
_requestURI = (String)value;
return;
break;
case INCLUDE_SERVLET_PATH:
_servletPath = (String)value;
return;
break;
case INCLUDE_CONTEXT_PATH:
_contextPath = (String)value;
return;
break;
case INCLUDE_QUERY_STRING:
_query = (String)value;
return;
break;
case INCLUDE_MAPPING:
_mapping = (HttpServletMapping)value;
return;
break;
default:
if (value == null)
_attributes.removeAttribute(key);
else
_attributes.setAttribute(key, value);
break;
}
}
else if (value == null)

View File

@ -739,7 +739,7 @@ public class Request implements HttpServletRequest
public Attributes getAttributes()
{
if (_attributes == null)
_attributes = new AttributesMap();
_attributes = new ServletAttributes();
return _attributes;
}
@ -1815,7 +1815,7 @@ public class Request implements HttpServletRequest
_attributes = Attributes.unwrap(_attributes);
if (_attributes != null)
{
if (AttributesMap.class.equals(_attributes.getClass()))
if (ServletAttributes.class.equals(_attributes.getClass()))
_attributes.clearAttributes();
else
_attributes = null;
@ -1896,7 +1896,7 @@ public class Request implements HttpServletRequest
LOG.warn("Deprecated: org.eclipse.jetty.server.sendContent");
if (_attributes == null)
_attributes = new AttributesMap();
_attributes = new ServletAttributes();
_attributes.setAttribute(name, value);
if (!_requestAttributeListeners.isEmpty())
@ -1919,6 +1919,59 @@ public class Request implements HttpServletRequest
_attributes = attributes;
}
public void setAsyncAttributes()
{
// Return if we have been async dispatched before.
if (getAttribute(AsyncContext.ASYNC_REQUEST_URI) != null)
return;
String requestURI;
String contextPath;
String servletPath;
String pathInfo;
String queryString;
HttpServletMapping httpServletMapping;
// Have we been forwarded before?
requestURI = (String)getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
if (requestURI != null)
{
contextPath = (String)getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH);
servletPath = (String)getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
pathInfo = (String)getAttribute(RequestDispatcher.FORWARD_PATH_INFO);
queryString = (String)getAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
httpServletMapping = (HttpServletMapping)getAttribute(RequestDispatcher.FORWARD_MAPPING);
}
else
{
requestURI = getRequestURI();
contextPath = getContextPath();
servletPath = getServletPath();
pathInfo = getPathInfo();
queryString = getQueryString();
httpServletMapping = getHttpServletMapping();
}
// Unwrap the _attributes to get the base attributes instance.
Attributes baseAttributes;
if (_attributes == null)
_attributes = baseAttributes = new ServletAttributes();
else
baseAttributes = Attributes.unwrap(_attributes);
if (baseAttributes instanceof ServletAttributes)
{
// Set the AsyncAttributes on the ServletAttributes.
ServletAttributes servletAttributes = (ServletAttributes)baseAttributes;
servletAttributes.setAsyncAttributes(requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
}
else
{
// If ServletAttributes has been replaced just set them on the top level Attributes.
AsyncAttributes.applyAsyncAttributes(_attributes, requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
}
}
/**
* Set the authentication.
*

View File

@ -0,0 +1,73 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.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.server;
import java.util.Set;
import javax.servlet.http.HttpServletMapping;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap;
public class ServletAttributes implements Attributes
{
private final Attributes _attributes = new AttributesMap();
private AsyncAttributes _asyncAttributes;
public void setAsyncAttributes(String requestURI, String contextPath, String servletPath, String pathInfo, String queryString, HttpServletMapping httpServletMapping)
{
_asyncAttributes = new AsyncAttributes(_attributes, requestURI, contextPath, servletPath, pathInfo, queryString, httpServletMapping);
}
private Attributes getAttributes()
{
return (_asyncAttributes == null) ? _attributes : _asyncAttributes;
}
@Override
public void removeAttribute(String name)
{
getAttributes().removeAttribute(name);
}
@Override
public void setAttribute(String name, Object attribute)
{
getAttributes().setAttribute(name, attribute);
}
@Override
public Object getAttribute(String name)
{
return getAttributes().getAttribute(name);
}
@Override
public Set<String> getAttributeNameSet()
{
return getAttributes().getAttributeNameSet();
}
@Override
public void clearAttributes()
{
getAttributes().clearAttributes();
_asyncAttributes = null;
}
}

View File

@ -111,8 +111,7 @@ public class AttributesMap implements Attributes, Dumpable
if (attrs instanceof AttributesMap)
return Collections.enumeration(((AttributesMap)attrs).keySet());
List<String> names = new ArrayList<>();
names.addAll(Collections.list(attrs.getAttributeNames()));
List<String> names = new ArrayList<>(Collections.list(attrs.getAttributeNames()));
return Collections.enumeration(names);
}