package org.glassfish.grizzly.servlet;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.io.BufferedReader;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.EmptyCompletionHandler;
import org.glassfish.grizzly.Grizzly;
import org.glassfish.grizzly.ThreadCache;
import org.glassfish.grizzly.http.Cookie;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.server.Response;
import org.glassfish.grizzly.http.server.Session;
import org.glassfish.grizzly.http.server.TimeoutHandler;
import org.glassfish.grizzly.http.server.util.Enumerator;
import org.glassfish.grizzly.http.server.util.Globals;
import org.glassfish.grizzly.http.server.util.MappingData;
import org.glassfish.grizzly.localization.LogMessages;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletRequestAttributeEvent;
import jakarta.servlet.ServletRequestAttributeListener;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletMapping;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpUpgradeHandler;
import jakarta.servlet.http.MappingMatch;
import jakarta.servlet.http.Part;
import jakarta.servlet.http.PushBuilder;
import jakarta.servlet.http.WebConnection;
@SuppressWarnings("deprecation")
public class HttpServletRequestImpl implements HttpServletRequest, Holders.RequestHolder {
private static final Logger LOGGER = Grizzly.logger(HttpServletRequestImpl.class);
protected Request request = null;
protected HttpServletResponseImpl servletResponse;
private boolean isAsyncSupported = true;
private final AtomicBoolean asyncStarted = new AtomicBoolean();
private AsyncContextImpl asyncContext;
private boolean isAsyncComplete;
private Thread asyncStartedThread;
private final ServletInputStreamImpl inputStream;
private ServletReaderImpl reader;
private HttpSessionImpl httpSession = null;
private WebappContext contextImpl;
private String contextPath = "";
private String servletPath = "";
private String pathInfo;
protected boolean usingInputStream = false;
protected boolean usingReader = false;
private boolean upgrade = false;
private HttpUpgradeHandler httpUpgradeHandler;
private HttpServletMapping httpServletMapping;
private static final ThreadCache.CachedTypeIndex<HttpServletRequestImpl> CACHE_IDX = ThreadCache.obtainIndex(HttpServletRequestImpl.class, 2);
public static HttpServletRequestImpl create() {
final HttpServletRequestImpl request = ThreadCache.takeFromCache(CACHE_IDX);
if (request != null) {
return request;
}
return new HttpServletRequestImpl();
}
protected HttpServletRequestImpl() {
this.inputStream = new ServletInputStreamImpl(this);
}
public void initialize(final Request request, final HttpServletResponseImpl servletResponse, final WebappContext context) throws IOException {
this.request = request;
this.servletResponse = servletResponse;
inputStream.initialize();
contextImpl = context;
if (context.getRequestCharacterEncoding() != null) {
request.setCharacterEncoding(context.getResponseCharacterEncoding());
}
if (context.getResponseCharacterEncoding() != null) {
servletResponse.setCharacterEncoding(context.getResponseCharacterEncoding());
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
@Override
public Object getAttribute(String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getAttribute(name);
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getAttributeNames() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetAttributePrivilegedAction());
} else {
return new Enumerator(request.getAttributeNames());
}
}
@SuppressWarnings("unchecked")
@Override
public String getCharacterEncoding() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetCharacterEncodingPrivilegedAction());
} else {
return request.getCharacterEncoding();
}
}
@Override
public void setCharacterEncoding(String env) throws java.io.UnsupportedEncodingException {
if (request == null) {
throw new IllegalStateException("Null request object");
}
request.setCharacterEncoding(env);
}
@Override
public int getContentLength() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getContentLength();
}
@Override
public long getContentLengthLong() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getContentLengthLong();
}
@Override
public String getContentType() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getContentType();
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (usingReader) {
throw new IllegalStateException("Illegal attempt to call getInputStream() after getReader() has already been called.");
}
usingInputStream = true;
return inputStream;
}
void recycle() {
request = null;
servletResponse = null;
reader = null;
inputStream.recycle();
usingInputStream = false;
usingReader = false;
upgrade = false;
httpUpgradeHandler = null;
if (asyncContext != null) {
asyncContext.clear();
asyncContext = null;
}
isAsyncSupported = true;
asyncStarted.set(false);
isAsyncComplete = false;
asyncStartedThread = null;
}
@SuppressWarnings("unchecked")
@Override
public String getParameter(String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetParameterPrivilegedAction(name));
} else {
return request.getParameter(name);
}
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getParameterNames() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return new Enumerator(AccessController.doPrivileged(new GetParameterNamesPrivilegedAction()));
} else {
return new Enumerator(request.getParameterNames());
}
}
@SuppressWarnings("unchecked")
@Override
public String[] getParameterValues(String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
String[] ret;
if (System.getSecurityManager() != null) {
ret = AccessController.doPrivileged(new GetParameterValuePrivilegedAction(name));
if (ret != null) {
ret = ret.clone();
}
} else {
ret = request.getParameterValues(name);
}
return ret;
}
@Override
public Map<String, String[]> getParameterMap() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetParameterMapPrivilegedAction());
} else {
return request.getParameterMap();
}
}
@Override
public String getProtocol() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getProtocol().getProtocolString();
}
@Override
public String getScheme() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getScheme();
}
@Override
public String getServerName() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getServerName();
}
@Override
public int getServerPort() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getServerPort();
}
@Override
public BufferedReader getReader() throws IOException {
if (usingInputStream) {
throw new IllegalStateException("Illegal attempt to call getReader() after getInputStream() has already been called.");
}
usingReader = true;
if (reader == null) {
reader = new ServletReaderImpl(request.getReader());
}
return reader;
}
@Override
public String getRemoteAddr() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRemoteAddr();
}
@Override
public String getRemoteHost() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRemoteHost();
}
@Override
public void setAttribute(String name, Object value) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
Object oldValue = request.getAttribute(name);
request.setAttribute(name, value);
EventListener[] listeners = contextImpl.getEventListeners();
if (listeners.length == 0) {
return;
}
ServletRequestAttributeEvent event = null;
for (int i = 0, len = listeners.length; i < len; i++) {
if (!(listeners[i] instanceof ServletRequestAttributeListener)) {
continue;
}
ServletRequestAttributeListener listener = (ServletRequestAttributeListener) listeners[i];
try {
if (event == null) {
if (oldValue != null) {
event = new ServletRequestAttributeEvent(contextImpl, this, name, oldValue);
} else {
event = new ServletRequestAttributeEvent(contextImpl, this, name, value);
}
}
if (oldValue != null) {
listener.attributeReplaced(event);
} else {
listener.attributeAdded(event);
}
} catch (Throwable t) {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, LogMessages.WARNING_GRIZZLY_HTTP_SERVLET_ATTRIBUTE_LISTENER_ADD_ERROR("ServletRequestAttributeListener",
listener.getClass().getName()), t);
}
}
}
}
@Override
public void removeAttribute(String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
Object value = request.getAttribute(name);
request.removeAttribute(name);
EventListener[] listeners = contextImpl.getEventListeners();
if (listeners.length == 0) {
return;
}
ServletRequestAttributeEvent event = null;
for (int i = 0, len = listeners.length; i < len; i++) {
if (!(listeners[i] instanceof ServletRequestAttributeListener)) {
continue;
}
ServletRequestAttributeListener listener = (ServletRequestAttributeListener) listeners[i];
try {
if (event == null) {
event = new ServletRequestAttributeEvent(contextImpl, this, name, value);
}
listener.attributeRemoved(event);
} catch (Throwable t) {
LOGGER.log(Level.WARNING, LogMessages.WARNING_GRIZZLY_HTTP_SERVLET_ATTRIBUTE_LISTENER_REMOVE_ERROR("ServletRequestAttributeListener",
listener.getClass().getName()), t);
}
}
}
@SuppressWarnings("unchecked")
@Override
public Locale getLocale() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetLocalePrivilegedAction());
} else {
return request.getLocale();
}
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<Locale> getLocales() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetLocalesPrivilegedAction());
} else {
return new Enumerator(request.getLocales());
}
}
@Override
public boolean isSecure() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.isSecure();
}
@Override
@SuppressWarnings("unchecked")
public RequestDispatcher getRequestDispatcher(String path) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetRequestDispatcherPrivilegedAction(path));
} else {
return getRequestDispatcherInternal(path);
}
}
private RequestDispatcher getRequestDispatcherInternal(String path) {
if (contextImpl == null) {
return null;
}
if (path == null) {
return null;
} else if (path.startsWith("/")) {
return contextImpl.getRequestDispatcher(path);
}
String servletPath = (String) getAttribute(DispatcherConstants.INCLUDE_SERVLET_PATH);
if (servletPath == null) {
servletPath = getServletPath();
}
String pathInfo = getPathInfo();
String requestPath;
if (pathInfo == null) {
requestPath = servletPath;
} else {
requestPath = servletPath + pathInfo;
}
int pos = requestPath.lastIndexOf('/');
String relative;
if (pos >= 0) {
relative = requestPath.substring(0, pos + 1) + path;
} else {
relative = requestPath + path;
}
return contextImpl.getRequestDispatcher(relative);
}
@Override
@SuppressWarnings("deprecation")
public String getRealPath(String path) {
return contextImpl.getRealPath(path);
}
@Override
public String getAuthType() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getAuthType();
}
@SuppressWarnings("unchecked")
public Cookie[] getGrizzlyCookies() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
Cookie[] ret;
if (System.getSecurityManager() != null) {
ret = AccessController.doPrivileged(new GetCookiesPrivilegedAction());
if (ret != null) {
ret = ret.clone();
}
} else {
ret = request.getCookies();
}
return ret;
}
@Override
public long (String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getDateHeader(name);
}
@Override
public String (String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getHeader(name);
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> (String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetHeadersPrivilegedAction(name));
} else {
return new Enumerator(request.getHeaders(name).iterator());
}
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> () {
if (request == null) {
throw new IllegalStateException("Null request object");
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new GetHeaderNamesPrivilegedAction());
} else {
return new Enumerator(request.getHeaderNames().iterator());
}
}
@Override
public int (String name) {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getIntHeader(name);
}
@Override
public String getMethod() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getMethod().getMethodString();
}
@Override
public String getPathInfo() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return pathInfo;
}
@Override
public String getPathTranslated() {
if (getPathInfo() == null) {
return null;
} else {
return contextImpl.getRealPath(getPathInfo());
}
}
@Override
public String getContextPath() {
return contextPath;
}
protected void setContextPath(String contextPath) {
if (contextPath == null) {
this.contextPath = "";
} else {
this.contextPath = contextPath;
}
}
@Override
public String getQueryString() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getQueryString();
}
@Override
public String getRemoteUser() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRemoteUser();
}
@Override
public boolean isUserInRole(String role) {
throw new IllegalStateException("Not yet implemented");
}
@Override
public java.security.Principal getUserPrincipal() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getUserPrincipal();
}
@Override
public String getRequestedSessionId() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRequestedSessionId();
}
@Override
public String getRequestURI() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRequestURI();
}
@Override
public StringBuffer getRequestURL() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return Request.appendRequestURL(request, new StringBuffer());
}
@Override
public String getServletPath() {
return servletPath;
}
@Override
public HttpSession getSession(boolean create) {
if (httpSession != null && httpSession.isValid()) {
return httpSession;
}
httpSession = null;
final Session internalSession = request.getSession(create);
if (internalSession == null) {
return null;
}
internalSession.setSessionTimeout(MILLISECONDS.convert(contextImpl.sessionTimeoutInSeconds, SECONDS));
httpSession = new HttpSessionImpl(contextImpl, internalSession);
if (httpSession.isNew()) {
httpSession.notifyNew();
}
return httpSession;
}
@Override
public HttpSession getSession() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return getSession(true);
}
@Override
public String changeSessionId() {
final String oldSessionId = request.changeSessionId();
getSession(false);
httpSession.notifyIdChanged(oldSessionId);
return oldSessionId;
}
@Override
public boolean isRequestedSessionIdValid() {
return request.isRequestedSessionIdValid();
}
@Override
public boolean isRequestedSessionIdFromCookie() {
return request.isRequestedSessionIdFromCookie();
}
@Override
public boolean isRequestedSessionIdFromURL() {
return request.isRequestedSessionIdFromURL();
}
@Override
@SuppressWarnings({ "deprecation" })
public boolean isRequestedSessionIdFromUrl() {
return isRequestedSessionIdFromURL();
}
@Override
public jakarta.servlet.http.Cookie[] getCookies() {
final Cookie[] internalCookies = request.getCookies();
if (internalCookies == null) {
return null;
}
int cookieIdx = 0;
jakarta.servlet.http.Cookie[] cookies = new jakarta.servlet.http.Cookie[internalCookies.length];
for (Cookie cookie : internalCookies) {
if (cookie instanceof CookieWrapper) {
cookies[cookieIdx++] = ((CookieWrapper) cookie).getWrappedCookie();
} else {
try {
jakarta.servlet.http.Cookie currentCookie = new jakarta.servlet.http.Cookie(cookie.getName(), cookie.getValue());
currentCookie.setComment(cookie.getComment());
if (cookie.getDomain() != null) {
currentCookie.setDomain(cookie.getDomain());
}
currentCookie.setMaxAge(cookie.getMaxAge());
currentCookie.setPath(cookie.getPath());
currentCookie.setSecure(cookie.isSecure());
currentCookie.setVersion(cookie.getVersion());
cookies[cookieIdx++] = currentCookie;
} catch (IllegalArgumentException iae) {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, LogMessages.WARNING_GRIZZLY_HTTP_SERVLET_COOKIE_CREATE_ERROR(cookie.getName(), iae.getLocalizedMessage()));
}
}
}
}
return cookieIdx == cookies.length ? cookies : Arrays.copyOf(cookies, cookieIdx);
}
@Override
public int getRemotePort() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getRemotePort();
}
@Override
public String getLocalName() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getLocalName();
}
@Override
public String getLocalAddr() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getLocalAddr();
}
@Override
public int getLocalPort() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getLocalPort();
}
protected WebappContext getContextImpl() {
return contextImpl;
}
protected void setContextImpl(WebappContext contextImpl) {
this.contextImpl = contextImpl;
}
public void setServletPath(final String servletPath) {
if (servletPath != null) {
if (servletPath.length() == 0) {
this.servletPath = "";
} else {
this.servletPath = servletPath;
}
}
}
protected void setPathInfo(final String pathInfo) {
this.pathInfo = pathInfo;
}
public Request getRequest() {
return request;
}
@Override
public ServletContext getServletContext() {
return contextImpl;
}
@Override
public Request getInternalRequest() {
return request;
}
@Override
public DispatcherType getDispatcherType() {
DispatcherType dispatcher = (DispatcherType) getAttribute(Globals.DISPATCHER_TYPE_ATTR);
if (dispatcher == null) {
dispatcher = DispatcherType.REQUEST;
}
return dispatcher;
}
@Override
public AsyncContext startAsync() throws IllegalStateException {
return startAsync(this, servletResponse);
}
@Override
public AsyncContext startAsync(final ServletRequest servletRequest, final ServletResponse servletResponse) throws IllegalStateException {
return startAsync(servletRequest, servletResponse, false);
}
private AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse, boolean isStartAsyncWithZeroArg)
throws IllegalStateException {
if (servletRequest == null || servletResponse == null) {
throw new IllegalArgumentException("Null request or response");
}
if (!isAsyncSupported()) {
throw new IllegalStateException("Request is within the scope of a " + "filter or servlet that does not support asynchronous operations");
}
final AsyncContextImpl asyncContextLocal = asyncContext;
if (asyncContextLocal != null) {
if (isAsyncStarted()) {
throw new IllegalStateException("ServletRequest.startAsync called" + " again without any asynchronous dispatch, or called "
+ "outside the scope of any such dispatch, or called " + "again within the scope of the same dispatch");
}
if (isAsyncComplete) {
throw new IllegalStateException("Response already closed");
}
if (!asyncContextLocal.isStartAsyncInScope()) {
throw new IllegalStateException("ServletRequest.startAsync called " + "outside the scope of an async dispatch");
}
asyncContextLocal.reinitialize(servletRequest, servletResponse, isStartAsyncWithZeroArg);
} else {
final AsyncContextImpl asyncContextFinal = new AsyncContextImpl(this, servletRequest, servletResponse, isStartAsyncWithZeroArg);
asyncContext = asyncContextFinal;
final CompletionHandler<org.glassfish.grizzly.http.server.Response> requestCompletionHandler = new EmptyCompletionHandler<org.glassfish.grizzly.http.server.Response>() {
@Override
public void completed(org.glassfish.grizzly.http.server.Response response) {
asyncContextFinal.notifyAsyncListeners(AsyncContextImpl.AsyncEventType.COMPLETE, null);
}
};
final TimeoutHandler timeoutHandler = new TimeoutHandler() {
@Override
public boolean onTimeout(final org.glassfish.grizzly.http.server.Response response) {
return processTimeout();
}
};
request.getResponse().suspend(-1, MILLISECONDS, requestCompletionHandler, timeoutHandler);
asyncStartedThread = Thread.currentThread();
}
getInternalRequest().getContext().suspend();
asyncStarted.set(true);
return asyncContext;
}
@Override
public boolean isAsyncStarted() {
return asyncStarted.get();
}
void setAsyncStarted(boolean asyncStarted) {
this.asyncStarted.set(asyncStarted);
}
public void disableAsyncSupport() {
isAsyncSupported = false;
}
void setAsyncTimeout(long timeout) {
request.getResponse().getSuspendContext().setTimeout(timeout, MILLISECONDS);
}
@Override
public boolean isAsyncSupported() {
return isAsyncSupported;
}
@Override
public AsyncContext getAsyncContext() {
if (!isAsyncStarted()) {
throw new IllegalStateException("The request has not been put into asynchronous mode, must call ServletRequest.startAsync first");
}
return asyncContext;
}
void asyncComplete() {
if (isAsyncComplete) {
throw new IllegalStateException("Request already released from asynchronous mode");
}
isAsyncComplete = true;
asyncStarted.set(false);
if (asyncStartedThread != Thread.currentThread() || !asyncContext.isOkToConfigure()) {
request.getResponse().resume();
} else {
final Response.SuspendedContextImpl suspendContext = (Response.SuspendedContextImpl) request.getResponse().getSuspendContext();
suspendContext.markResumed();
suspendContext.getSuspendStatus().reset();
}
}
void asyncTimeout() {
if (asyncContext != null) {
asyncContext.notifyAsyncListeners(AsyncContextImpl.AsyncEventType.TIMEOUT, null);
}
errorDispatchAndComplete(null);
}
void onAfterService() throws IOException {
if (asyncContext != null) {
asyncContext.setOkToConfigure(false);
if (asyncStarted.get()) {
request.getResponse().getSuspendContext().setTimeout(asyncContext.getTimeout(), MILLISECONDS);
}
} else if (isUpgrade()) {
if (httpUpgradeHandler != null) {
final WebConnection wc = WebConnectionFactory.create(this, getInputStream(), servletResponse.getOutputStream());
httpUpgradeHandler.init(wc);
} else {
LOGGER.log(Level.SEVERE, "HttpUpgradeHandler handler cannot be null");
}
}
}
private boolean processTimeout() {
boolean result;
final AsyncContextImpl asyncContextLocal = this.asyncContext;
try {
asyncTimeout();
} finally {
result = asyncContextLocal != null && !asyncContextLocal.getAndResetDispatchInScope();
}
return result;
}
void errorDispatchAndComplete(Throwable t) {
if (asyncContext != null && !asyncContext.isDispatchInScope() && !isAsyncComplete && isAsyncStarted()) {
servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
if (t != null) {
setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
}
try {
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Unable to perform error dispatch", e);
} finally {
if (!isAsyncComplete && isAsyncStarted()) {
asyncComplete();
}
}
}
}
@Override
public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException {
upgrade = true;
T handler;
try {
handler = contextImpl.createHttpUpgradeHandlerInstance(handlerClass);
} catch (Exception ex) {
if (ex instanceof IOException) {
throw (IOException) ex;
} else {
throw new IOException(ex);
}
}
httpUpgradeHandler = handler;
request.getResponse().suspend();
return handler;
}
public boolean isUpgrade() {
return upgrade;
}
public HttpUpgradeHandler getHttpUpgradeHandler() {
return httpUpgradeHandler;
}
@Override
public boolean authenticate(HttpServletResponse hsr) throws IOException, ServletException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void login(String string, String string1) throws ServletException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void logout() throws ServletException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Collection<Part> getParts() throws IOException, ServletException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Part getPart(String string) throws IOException, ServletException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public HttpServletMapping getHttpServletMapping() {
if (httpServletMapping == null) {
httpServletMapping = new Mapping(request);
}
return httpServletMapping;
}
@Override
public PushBuilder newPushBuilder() {
if (request.isPushEnabled()) {
final org.glassfish.grizzly.http.server.http2.PushBuilder pushBuilder = request.newPushBuilder();
return new PushBuilder() {
@Override
public PushBuilder method(final String method) {
pushBuilder.method(method);
return this;
}
@Override
public PushBuilder queryString(final String queryString) {
pushBuilder.queryString(queryString);
return this;
}
@Override
public PushBuilder sessionId(final String sessionId) {
pushBuilder.sessionId(sessionId);
return this;
}
@Override
public PushBuilder (final String name, final String value) {
pushBuilder.setHeader(name, value);
return this;
}
@Override
public PushBuilder (final String name, final String value) {
pushBuilder.addHeader(name, value);
return this;
}
@Override
public PushBuilder (final String name) {
pushBuilder.removeHeader(name);
return this;
}
@Override
public PushBuilder path(final String path) {
pushBuilder.path(path);
return this;
}
@Override
public void push() {
pushBuilder.push();
}
@Override
public String getMethod() {
return pushBuilder.getMethod();
}
@Override
public String getQueryString() {
return pushBuilder.getQueryString();
}
@Override
public String getSessionId() {
return pushBuilder.getSessionId();
}
@Override
public Set<String> () {
final Iterable<String> i = pushBuilder.getHeaderNames();
final Set<String> names = new HashSet<>();
for (String s : i) {
names.add(s);
}
return names;
}
@Override
public String (final String name) {
return pushBuilder.getHeader(name);
}
@Override
public String getPath() {
return pushBuilder.getPath();
}
};
}
return null;
}
@Override
public Map<String, String> getTrailerFields() {
return request.getTrailers();
}
@Override
public boolean isTrailerFieldsReady() {
return request.areTrailersAvailable();
}
private final class GetAttributePrivilegedAction implements PrivilegedAction<Enumeration<String>> {
@Override
public Enumeration<String> run() {
return new Enumerator<>(request.getAttributeNames());
}
}
private final class GetParameterMapPrivilegedAction implements PrivilegedAction<Map<String, String[]>> {
@Override
public Map<String, String[]> run() {
return request.getParameterMap();
}
}
private final class GetRequestDispatcherPrivilegedAction implements PrivilegedAction<RequestDispatcher> {
private final String path;
public GetRequestDispatcherPrivilegedAction(String path) {
this.path = path;
}
@Override
public RequestDispatcher run() {
return getRequestDispatcherInternal(path);
}
}
private final class GetParameterPrivilegedAction implements PrivilegedAction<String> {
public final String name;
public GetParameterPrivilegedAction(String name) {
this.name = name;
}
@Override
public String run() {
return request.getParameter(name);
}
}
private final class GetParameterNamesPrivilegedAction implements PrivilegedAction<Set<String>> {
@Override
public Set<String> run() {
return request.getParameterNames();
}
}
private final class GetParameterValuePrivilegedAction implements PrivilegedAction<String[]> {
public final String name;
public GetParameterValuePrivilegedAction(String name) {
this.name = name;
}
@Override
public String[] run() {
return request.getParameterValues(name);
}
}
private final class GetCookiesPrivilegedAction implements PrivilegedAction<Cookie[]> {
@Override
public Cookie[] run() {
return request.getCookies();
}
}
private final class GetCharacterEncodingPrivilegedAction implements PrivilegedAction<String> {
@Override
public String run() {
return request.getCharacterEncoding();
}
}
private final class implements PrivilegedAction<Enumeration<String>> {
private final String ;
public (String name) {
this.name = name;
}
@Override
public Enumeration<String> () {
return new Enumerator<>(request.getHeaders(name));
}
}
private final class implements PrivilegedAction<Enumeration<String>> {
@Override
public Enumeration<String> () {
return new Enumerator<>(request.getHeaderNames());
}
}
private final class GetLocalePrivilegedAction implements PrivilegedAction<Locale> {
@Override
public Locale run() {
return request.getLocale();
}
}
private final class GetLocalesPrivilegedAction implements PrivilegedAction<Enumeration<Locale>> {
@Override
public Enumeration<Locale> run() {
return new Enumerator<>(request.getLocales());
}
}
static class WebConnectionFactory {
static WebConnection create(final HttpServletRequestImpl req, final ServletInputStream inputStream, final ServletOutputStream outputStream) {
return new WebConnectionImpl(req, inputStream, outputStream);
}
}
private static final class Mapping implements HttpServletMapping {
private String matchValue;
private String pattern;
private String servletName;
private MappingMatch mappingMatch;
private Mapping(final Request request) {
final MappingData data = request.obtainMappingData();
if (data == null) {
throw new NullPointerException("No MappingData available.");
}
matchValue = data.matchedPath != null && data.matchedPath.length() >= 2 ? data.matchedPath.substring(1) : "";
pattern = data.descriptorPath != null ? data.descriptorPath : "";
servletName = data.servletName != null ? data.servletName : "";
switch (data.mappingType) {
case MappingData.CONTEXT_ROOT:
mappingMatch = MappingMatch.CONTEXT_ROOT;
break;
case MappingData.DEFAULT:
mappingMatch = MappingMatch.DEFAULT;
break;
case MappingData.EXACT:
mappingMatch = MappingMatch.EXACT;
break;
case MappingData.EXTENSION:
mappingMatch = MappingMatch.EXTENSION;
if (pattern.charAt(0) == '*') {
int i = matchValue.indexOf(pattern.substring(1));
if (-1 != i) {
matchValue = matchValue.substring(0, i);
}
}
break;
case MappingData.PATH:
mappingMatch = MappingMatch.PATH;
int patternLen = pattern.length();
if (patternLen > 0 && pattern.charAt(patternLen - 1) == '*') {
int indexOfPatternStart = patternLen - 2;
int matchValueLen = matchValue.length();
if (0 <= indexOfPatternStart && indexOfPatternStart < matchValueLen) {
matchValue = matchValue.substring(indexOfPatternStart);
}
}
break;
}
}
@Override
public String getMatchValue() {
return matchValue;
}
@Override
public String getPattern() {
return pattern;
}
@Override
public String getServletName() {
return servletName;
}
@Override
public MappingMatch getMappingMatch() {
return mappingMatch;
}
@Override
public String toString() {
return "Mapping{" + "matchValue='" + matchValue + '\'' + ", pattern='" + pattern + '\'' + ", servletName='" + servletName + '\'' + ", mappingMatch="
+ mappingMatch + '}';
}
}
}