use of org.apache.catalina.connector.RequestFacade in project tomcat70 by apache.
the class UpgradeUtil method doUpgrade.
public static void doUpgrade(WsServerContainer sc, HttpServletRequest req, HttpServletResponse resp, ServerEndpointConfig sec, Map<String, String> pathParams) throws ServletException, IOException {
// Validate the rest of the headers and reject the request if that
// validation fails
String key;
String subProtocol = null;
if (!headerContainsToken(req, Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE)) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
if (!headerContainsToken(req, Constants.WS_VERSION_HEADER_NAME, Constants.WS_VERSION_HEADER_VALUE)) {
resp.setStatus(426);
resp.setHeader(Constants.WS_VERSION_HEADER_NAME, Constants.WS_VERSION_HEADER_VALUE);
return;
}
key = req.getHeader(Constants.WS_KEY_HEADER_NAME);
if (key == null) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// Origin check
String origin = req.getHeader(Constants.ORIGIN_HEADER_NAME);
if (!sec.getConfigurator().checkOrigin(origin)) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
// Sub-protocols
List<String> subProtocols = getTokensFromHeader(req, Constants.WS_PROTOCOL_HEADER_NAME);
subProtocol = sec.getConfigurator().getNegotiatedSubprotocol(sec.getSubprotocols(), subProtocols);
// Extensions
// Should normally only be one header but handle the case of multiple
// headers
List<Extension> extensionsRequested = new ArrayList<Extension>();
Enumeration<String> extHeaders = req.getHeaders(Constants.WS_EXTENSIONS_HEADER_NAME);
while (extHeaders.hasMoreElements()) {
Util.parseExtensionHeader(extensionsRequested, extHeaders.nextElement());
}
// Negotiation phase 1. By default this simply filters out the
// extensions that the server does not support but applications could
// use a custom configurator to do more than this.
List<Extension> installedExtensions = null;
if (sec.getExtensions().size() == 0) {
installedExtensions = Constants.INSTALLED_EXTENSIONS;
} else {
installedExtensions = new ArrayList<Extension>();
installedExtensions.addAll(sec.getExtensions());
installedExtensions.addAll(Constants.INSTALLED_EXTENSIONS);
}
List<Extension> negotiatedExtensionsPhase1 = sec.getConfigurator().getNegotiatedExtensions(installedExtensions, extensionsRequested);
// Negotiation phase 2. Create the Transformations that will be applied
// to this connection. Note than an extension may be dropped at this
// point if the client has requested a configuration that the server is
// unable to support.
List<Transformation> transformations = createTransformations(negotiatedExtensionsPhase1);
List<Extension> negotiatedExtensionsPhase2;
if (transformations.isEmpty()) {
negotiatedExtensionsPhase2 = Collections.emptyList();
} else {
negotiatedExtensionsPhase2 = new ArrayList<Extension>(transformations.size());
for (Transformation t : transformations) {
negotiatedExtensionsPhase2.add(t.getExtensionResponse());
}
}
// Build the transformation pipeline
Transformation transformation = null;
StringBuilder responseHeaderExtensions = new StringBuilder();
boolean first = true;
for (Transformation t : transformations) {
if (first) {
first = false;
} else {
responseHeaderExtensions.append(',');
}
append(responseHeaderExtensions, t.getExtensionResponse());
if (transformation == null) {
transformation = t;
} else {
transformation.setNext(t);
}
}
// Now we have the full pipeline, validate the use of the RSV bits.
if (transformation != null && !transformation.validateRsvBits(0)) {
throw new ServletException(sm.getString("upgradeUtil.incompatibleRsv"));
}
// If we got this far, all is good. Accept the connection.
resp.setHeader(Constants.UPGRADE_HEADER_NAME, Constants.UPGRADE_HEADER_VALUE);
resp.setHeader(Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE);
resp.setHeader(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, getWebSocketAccept(key));
if (subProtocol != null && subProtocol.length() > 0) {
// RFC6455 4.2.2 explicitly states "" is not valid here
resp.setHeader(Constants.WS_PROTOCOL_HEADER_NAME, subProtocol);
}
if (!transformations.isEmpty()) {
resp.setHeader(Constants.WS_EXTENSIONS_HEADER_NAME, responseHeaderExtensions.toString());
}
WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams);
WsHandshakeResponse wsResponse = new WsHandshakeResponse();
WsPerSessionServerEndpointConfig perSessionServerEndpointConfig = new WsPerSessionServerEndpointConfig(sec);
sec.getConfigurator().modifyHandshake(perSessionServerEndpointConfig, wsRequest, wsResponse);
wsRequest.finished();
// Add any additional headers
for (Entry<String, List<String>> entry : wsResponse.getHeaders().entrySet()) {
for (String headerValue : entry.getValue()) {
resp.addHeader(entry.getKey(), headerValue);
}
}
Endpoint ep;
try {
Class<?> clazz = sec.getEndpointClass();
if (Endpoint.class.isAssignableFrom(clazz)) {
ep = (Endpoint) sec.getConfigurator().getEndpointInstance(clazz);
} else {
ep = new PojoEndpointServer();
// Need to make path params available to POJO
perSessionServerEndpointConfig.getUserProperties().put(PojoEndpointServer.POJO_PATH_PARAM_KEY, pathParams);
}
} catch (InstantiationException e) {
throw new ServletException(e);
}
// Small hack until the Servlet API provides a way to do this.
ServletRequest inner = req;
// Unwrap the request
while (inner instanceof ServletRequestWrapper) {
inner = ((ServletRequestWrapper) inner).getRequest();
}
if (inner instanceof RequestFacade) {
WsHttpUpgradeHandler wsHandler = ((RequestFacade) inner).upgrade(WsHttpUpgradeHandler.class);
wsHandler.preInit(ep, perSessionServerEndpointConfig, sc, wsRequest, negotiatedExtensionsPhase2, subProtocol, transformation, pathParams, req.isSecure());
} else {
throw new ServletException("Upgrade failed");
}
}
use of org.apache.catalina.connector.RequestFacade in project tomcat70 by apache.
the class ApplicationDispatcher method unwrapRequest.
/**
* Unwrap the request if we have wrapped it.
*/
private void unwrapRequest(State state) {
if (state.wrapRequest == null)
return;
if (state.outerRequest.isAsyncStarted()) {
if (!state.outerRequest.getAsyncContext().hasOriginalRequestAndResponse()) {
return;
}
}
ServletRequest previous = null;
ServletRequest current = state.outerRequest;
while (current != null) {
// If we run into the container request we are done
if ((current instanceof Request) || (current instanceof RequestFacade))
break;
// Remove the current request if it is our wrapper
if (current == state.wrapRequest) {
ServletRequest next = ((ServletRequestWrapper) current).getRequest();
if (previous == null)
state.outerRequest = next;
else
((ServletRequestWrapper) previous).setRequest(next);
break;
}
// Advance to the next request in the chain
previous = current;
current = ((ServletRequestWrapper) current).getRequest();
}
}
use of org.apache.catalina.connector.RequestFacade in project tomcat70 by apache.
the class WebSocketServlet method doGet.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Information required to send the server handshake message
String key;
String subProtocol = null;
List<String> extensions = Collections.emptyList();
if (!headerContainsToken(req, "upgrade", "websocket")) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
if (!headerContainsToken(req, "connection", "upgrade")) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
if (!headerContainsToken(req, "sec-websocket-version", "13")) {
resp.setStatus(426);
resp.setHeader("Sec-WebSocket-Version", "13");
return;
}
key = req.getHeader("Sec-WebSocket-Key");
if (key == null) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String origin = req.getHeader("Origin");
if (!verifyOrigin(origin)) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
List<String> subProtocols = getTokensFromHeader(req, "Sec-WebSocket-Protocol");
if (!subProtocols.isEmpty()) {
subProtocol = selectSubProtocol(subProtocols);
}
// TODO Read client handshake - Sec-WebSocket-Extensions
// TODO Extensions require the ability to specify something (API TBD)
// that can be passed to the Tomcat internals and process extension
// data present when the frame is fragmented.
// If we got this far, all is good. Accept the connection.
resp.setHeader("Upgrade", "websocket");
resp.setHeader("Connection", "upgrade");
resp.setHeader("Sec-WebSocket-Accept", getWebSocketAccept(key));
if (subProtocol != null) {
resp.setHeader("Sec-WebSocket-Protocol", subProtocol);
}
if (!extensions.isEmpty()) {
// TODO
}
WsHttpServletRequestWrapper wrapper = new WsHttpServletRequestWrapper(req);
StreamInbound inbound = createWebSocketInbound(subProtocol, wrapper);
wrapper.invalidate();
// Small hack until the Servlet API provides a way to do this.
ServletRequest inner = req;
// Unwrap the request
while (inner instanceof ServletRequestWrapper) {
inner = ((ServletRequestWrapper) inner).getRequest();
}
if (inner instanceof RequestFacade) {
((RequestFacade) inner).doUpgrade(inbound);
} else {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, sm.getString("servlet.reqUpgradeFail"));
}
}
use of org.apache.catalina.connector.RequestFacade in project Payara by payara.
the class ApplicationDispatcher method unwrapRequest.
/**
* Log a message on the Logger associated with our Context (if any)
*
* @param message Message to be logged
*
* private void log(String message) {
* org.apache.catalina.Logger logger = context.getLogger();
* if (logger != null) {
* logger.log("ApplicationDispatcher[" + context.getPath() +
* "]: " + message);
* } else {
* if (log.isLoggable(Level.INFO)) {
* String msg = MessageFormat.format(rb.getString(LogFacade.APPLICATION_DISPATCHER_INFO),
* context.getPath(), message);
* log.log(Level.INFO, msg);
* }
* }
* }
*
* /**
* Log a message on the Logger associated with our Container (if any)
*
* @param message Message to be logged
* @param t Associated exception
*
* private void log(String message, Throwable t) {
* org.apache.catalina.Logger logger = context.getLogger();
* if (logger != null) {
* logger.log("ApplicationDispatcher[" + context.getPath() +
* "] " + message, t, org.apache.catalina.Logger.WARNING);
* } else {
* String msg = MessageFormat.format(rb.getString(LogFacade.APPLICATION_DISPATCHER_WARNING),
* context.getPath(), message);
* log.log(Level.WARNING, msg, t);
* }
* }
*/
/**
* Unwrap the request if we have wrapped it.
*/
private void unwrapRequest(State state) {
if (state.wrapRequest == null)
return;
ServletRequest previous = null;
ServletRequest current = state.outerRequest;
while (current != null) {
// If we run into the container request we are done
if ((current instanceof org.apache.catalina.Request) || (current instanceof RequestFacade))
break;
// Remove the current request if it is our wrapper
if (current == state.wrapRequest) {
ServletRequest next = ((ServletRequestWrapper) current).getRequest();
if (previous == null)
state.outerRequest = next;
else
((ServletRequestWrapper) previous).setRequest(next);
break;
}
// Advance to the next request in the chain
previous = current;
current = ((ServletRequestWrapper) current).getRequest();
}
}
use of org.apache.catalina.connector.RequestFacade in project Payara by payara.
the class StandardWrapperValve method invoke.
// --------------------------------------------------------- Public Methods
/**
* Invoke the servlet we are managing, respecting the rules regarding
* servlet lifecycle and SingleThreadModel support.
*
* @param request Request to be processed
* @param response Response to be produced
*
* @exception IOException if an input/output error occurred
* @exception ServletException if a servlet error occurred
*/
@Override
public int invoke(Request request, Response response) throws IOException, ServletException {
boolean unavailable = false;
Throwable throwable = null;
Servlet servlet = null;
StandardWrapper wrapper = (StandardWrapper) getContainer();
Context context = (Context) wrapper.getParent();
HttpRequest hrequest = (HttpRequest) request;
/*
* Create a request facade such that if the request was received
* at the root context, and the root context is mapped to a
* default-web-module, the default-web-module mapping is masked from
* the application code to which the request facade is being passed.
* For example, the request.facade's getContextPath() method will
* return "/", rather than the context root of the default-web-module,
* in this case.
*/
RequestFacade hreq = (RequestFacade) request.getRequest(true);
HttpServletResponse hres = (HttpServletResponse) response.getResponse();
// Check for the application being marked unavailable
if (!context.getAvailable()) {
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
response.setDetailMessage(rb.getString(LogFacade.APP_UNAVAILABLE));
// END S1AS 4878272
unavailable = true;
}
// Check for the servlet being marked unavailable
if (!unavailable && wrapper.isUnavailable()) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_UNAVAILABLE), wrapper.getName());
log(msg);
if (hres == null) {
// NOTE - Not much we can do generically
;
} else {
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE)) {
hres.setDateHeader("Retry-After", available);
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
response.setDetailMessage(msg);
// END S1AS 4878272
} else if (available == Long.MAX_VALUE) {
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_NOT_FOUND);
msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_NOT_FOUND), wrapper.getName());
response.setDetailMessage(msg);
// END S1AS 4878272
}
}
unavailable = true;
}
// Allocate a servlet instance to process this request
try {
if (!unavailable) {
servlet = wrapper.allocate();
}
} catch (UnavailableException e) {
if (e.isPermanent()) {
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_NOT_FOUND);
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_NOT_FOUND), wrapper.getName());
response.setDetailMessage(msg);
// END S1AS 4878272
} else {
hres.setDateHeader("Retry-After", e.getUnavailableSeconds());
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_UNAVAILABLE), wrapper.getName());
response.setDetailMessage(msg);
// END S1AS 4878272
}
} catch (ServletException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_ALLOCATE_EXCEPTION), wrapper.getName());
log(msg, StandardWrapper.getRootCause(e));
throwable = e;
exception(request, response, e);
servlet = null;
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_ALLOCATE_EXCEPTION), wrapper.getName());
log(msg, e);
throwable = e;
exception(request, response, e);
servlet = null;
}
// Acknowlege the request
try {
response.sendAcknowledgement();
} catch (IOException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SEND_ACKNOWLEDGEMENT_EXCEPTION), wrapper.getName());
log(msg, e);
throwable = e;
exception(request, response, e);
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SEND_ACKNOWLEDGEMENT_EXCEPTION), wrapper.getName());
log(msg, e);
throwable = e;
exception(request, response, e);
servlet = null;
}
DataChunk requestPathMB = hrequest.getRequestPathMB();
hreq.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, requestPathMB);
// Create the filter chain for this request
ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
ApplicationFilterChain filterChain = factory.createFilterChain((ServletRequest) request, wrapper, servlet);
// NOTE: This also calls the servlet's service() method
try {
String jspFile = wrapper.getJspFile();
if (jspFile != null) {
hreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
}
// START IASRI 4665318
if (servlet != null) {
if (filterChain != null) {
filterChain.setWrapper(wrapper);
filterChain.doFilter(hreq, hres);
} else {
wrapper.service(hreq, hres, servlet);
}
}
// END IASRI 4665318
} catch (ClientAbortException e) {
throwable = e;
exception(request, response, e);
} catch (IOException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_SERVICE_EXCEPTION), wrapper.getName());
log(msg, e);
throwable = e;
exception(request, response, e);
} catch (UnavailableException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_SERVICE_EXCEPTION), wrapper.getName());
log(msg, e);
// throwable = e;
// exception(request, response, e);
wrapper.unavailable(e);
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE)) {
hres.setDateHeader("Retry-After", available);
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
String msgServletUnavailable = MessageFormat.format(rb.getString(LogFacade.SERVLET_UNAVAILABLE), wrapper.getName());
response.setDetailMessage(msgServletUnavailable);
// END S1AS 4878272
} else if (available == Long.MAX_VALUE) {
// BEGIN S1AS 4878272
hres.sendError(HttpServletResponse.SC_NOT_FOUND);
String msgServletNotFound = MessageFormat.format(rb.getString(LogFacade.SERVLET_NOT_FOUND), wrapper.getName());
response.setDetailMessage(msgServletNotFound);
// END S1AS 4878272
}
// Do not save exception in 'throwable', because we
// do not want to do exception(request, response, e) processing
} catch (ServletException e) {
Throwable rootCause = StandardWrapper.getRootCause(e);
if (!(rootCause instanceof ClientAbortException)) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_SERVICE_EXCEPTION), wrapper.getName());
log(msg, rootCause);
}
throwable = e;
exception(request, response, e);
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_SERVICE_EXCEPTION), wrapper.getName());
log(msg, e);
throwable = e;
exception(request, response, e);
}
// Release the filter chain (if any) for this request
try {
if (filterChain != null)
filterChain.release();
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.RELEASE_FILTERS_EXCEPTION), wrapper.getName());
log(msg, e);
if (throwable == null) {
throwable = e;
exception(request, response, e);
}
}
// Deallocate the allocated servlet instance
try {
if (servlet != null) {
wrapper.deallocate(servlet);
}
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.DEALLOCATE_EXCEPTION), wrapper.getName());
log(msg, e);
if (throwable == null) {
throwable = e;
exception(request, response, e);
}
}
// unload it and release this instance
try {
if ((servlet != null) && (wrapper.getAvailable() == Long.MAX_VALUE)) {
wrapper.unload();
}
} catch (Throwable e) {
String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_UNLOAD_EXCEPTION), wrapper.getName());
log(msg, e);
if (throwable == null) {
exception(request, response, e);
}
}
return END_PIPELINE;
}
Aggregations