use of io.undertow.server.HttpHandler in project undertow by undertow-io.
the class BypassServletTestCase method setup.
@BeforeClass
public static void setup() throws ServletException {
final PathHandler root = new PathHandler();
final ServletContainer container = ServletContainer.Factory.newInstance();
DeploymentInfo builder = new DeploymentInfo().setClassLoader(SimpleServletTestCase.class.getClassLoader()).setContextPath("/servletContext").setClassIntrospecter(TestClassIntrospector.INSTANCE).setDeploymentName("servletContext.war").addServlet(new ServletInfo("servlet", MessageServlet.class).addMapping("/").addInitParam(MessageServlet.MESSAGE, "This is a servlet")).addListener(new ListenerInfo(TestListener.class)).addInitialHandlerChainWrapper(new HandlerWrapper() {
@Override
public HttpHandler wrap(final HttpHandler handler) {
return new HttpHandler() {
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
if (exchange.getRelativePath().equals("/async")) {
exchange.getResponseSender().send("This is not a servlet", IoCallback.END_EXCHANGE);
} else {
handler.handleRequest(exchange);
}
}
};
}
});
DeploymentManager manager = container.addDeployment(builder);
manager.deploy();
root.addPrefixPath(builder.getContextPath(), manager.start());
DefaultServer.setRootHandler(root);
}
use of io.undertow.server.HttpHandler in project undertow by undertow-io.
the class Undertow method start.
public synchronized void start() {
UndertowLogger.ROOT_LOGGER.debugf("starting undertow server %s", this);
xnio = Xnio.getInstance(Undertow.class.getClassLoader());
channels = new ArrayList<>();
try {
if (internalWorker) {
worker = xnio.createWorker(OptionMap.builder().set(Options.WORKER_IO_THREADS, ioThreads).set(Options.CONNECTION_HIGH_WATER, 1000000).set(Options.CONNECTION_LOW_WATER, 1000000).set(Options.WORKER_TASK_CORE_THREADS, workerThreads).set(Options.WORKER_TASK_MAX_THREADS, workerThreads).set(Options.TCP_NODELAY, true).set(Options.CORK, true).addAll(workerOptions).getMap());
}
OptionMap socketOptions = OptionMap.builder().set(Options.WORKER_IO_THREADS, worker.getIoThreadCount()).set(Options.TCP_NODELAY, true).set(Options.REUSE_ADDRESSES, true).set(Options.BALANCING_TOKENS, 1).set(Options.BALANCING_CONNECTIONS, 2).set(Options.BACKLOG, 1000).addAll(this.socketOptions).getMap();
OptionMap serverOptions = OptionMap.builder().set(UndertowOptions.NO_REQUEST_TIMEOUT, 60 * 1000).addAll(this.serverOptions).getMap();
ByteBufferPool buffers = new DefaultByteBufferPool(directBuffers, bufferSize, -1, 4);
listenerInfo = new ArrayList<>();
for (ListenerConfig listener : listeners) {
UndertowLogger.ROOT_LOGGER.debugf("Configuring listener with protocol %s for interface %s and port %s", listener.type, listener.host, listener.port);
final HttpHandler rootHandler = listener.rootHandler != null ? listener.rootHandler : this.rootHandler;
if (listener.type == ListenerType.AJP) {
AjpOpenListener openListener = new AjpOpenListener(buffers, serverOptions);
openListener.setRootHandler(rootHandler);
ChannelListener<AcceptingChannel<StreamConnection>> acceptListener = ChannelListeners.openListenerAdapter(openListener);
OptionMap socketOptionsWithOverrides = OptionMap.builder().addAll(socketOptions).addAll(listener.overrideSocketOptions).getMap();
AcceptingChannel<? extends StreamConnection> server = worker.createStreamConnectionServer(new InetSocketAddress(Inet4Address.getByName(listener.host), listener.port), acceptListener, socketOptionsWithOverrides);
server.resumeAccepts();
channels.add(server);
listenerInfo.add(new ListenerInfo("ajp", server.getLocalAddress(), null, openListener));
} else {
OptionMap undertowOptions = OptionMap.builder().set(UndertowOptions.BUFFER_PIPELINED_DATA, true).addAll(serverOptions).getMap();
if (listener.type == ListenerType.HTTP) {
HttpOpenListener openListener = new HttpOpenListener(buffers, undertowOptions);
openListener.setRootHandler(rootHandler);
ChannelListener<AcceptingChannel<StreamConnection>> acceptListener = ChannelListeners.openListenerAdapter(openListener);
OptionMap socketOptionsWithOverrides = OptionMap.builder().addAll(socketOptions).addAll(listener.overrideSocketOptions).getMap();
AcceptingChannel<? extends StreamConnection> server = worker.createStreamConnectionServer(new InetSocketAddress(Inet4Address.getByName(listener.host), listener.port), acceptListener, socketOptionsWithOverrides);
server.resumeAccepts();
channels.add(server);
listenerInfo.add(new ListenerInfo("http", server.getLocalAddress(), null, openListener));
} else if (listener.type == ListenerType.HTTPS) {
OpenListener openListener;
HttpOpenListener httpOpenListener = new HttpOpenListener(buffers, undertowOptions);
httpOpenListener.setRootHandler(rootHandler);
boolean http2 = serverOptions.get(UndertowOptions.ENABLE_HTTP2, false);
if (http2) {
AlpnOpenListener alpn = new AlpnOpenListener(buffers, undertowOptions, httpOpenListener);
if (http2) {
Http2OpenListener http2Listener = new Http2OpenListener(buffers, undertowOptions);
http2Listener.setRootHandler(rootHandler);
alpn.addProtocol(Http2OpenListener.HTTP2, http2Listener, 10);
alpn.addProtocol(Http2OpenListener.HTTP2_14, http2Listener, 7);
}
openListener = alpn;
} else {
openListener = httpOpenListener;
}
ChannelListener<AcceptingChannel<StreamConnection>> acceptListener = ChannelListeners.openListenerAdapter(openListener);
XnioSsl xnioSsl;
if (listener.sslContext != null) {
xnioSsl = new UndertowXnioSsl(xnio, OptionMap.create(Options.USE_DIRECT_BUFFERS, true), listener.sslContext);
} else {
xnioSsl = new UndertowXnioSsl(xnio, OptionMap.create(Options.USE_DIRECT_BUFFERS, true), JsseSslUtils.createSSLContext(listener.keyManagers, listener.trustManagers, new SecureRandom(), OptionMap.create(Options.USE_DIRECT_BUFFERS, true)));
}
OptionMap socketOptionsWithOverrides = OptionMap.builder().addAll(socketOptions).addAll(listener.overrideSocketOptions).getMap();
AcceptingChannel<SslConnection> sslServer = xnioSsl.createSslConnectionServer(worker, new InetSocketAddress(Inet4Address.getByName(listener.host), listener.port), (ChannelListener) acceptListener, socketOptionsWithOverrides);
sslServer.resumeAccepts();
channels.add(sslServer);
listenerInfo.add(new ListenerInfo("https", sslServer.getLocalAddress(), listener.sslContext, openListener));
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of io.undertow.server.HttpHandler in project undertow by undertow-io.
the class PredicatesHandler method addPredicatedHandler.
/**
* Adds a new predicated handler.
* <p>
*
* @param predicate
* @param handlerWrapper
*/
public PredicatesHandler addPredicatedHandler(final Predicate predicate, final HandlerWrapper handlerWrapper, final HandlerWrapper elseBranch) {
Holder[] old = handlers;
Holder[] handlers = new Holder[old.length + 1];
System.arraycopy(old, 0, handlers, 0, old.length);
HttpHandler elseHandler = elseBranch != null ? elseBranch.wrap(this) : null;
handlers[old.length] = new Holder(predicate, handlerWrapper.wrap(this), elseHandler);
this.handlers = handlers;
return this;
}
use of io.undertow.server.HttpHandler in project undertow by undertow-io.
the class PredicateHandler method handleRequest.
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
HttpHandler next = predicate.resolve(exchange) ? trueHandler : falseHandler;
next.handleRequest(exchange);
}
use of io.undertow.server.HttpHandler in project undertow by undertow-io.
the class ResourceHandler method serveResource.
private void serveResource(final HttpServerExchange exchange, final boolean sendContent) throws Exception {
if (DirectoryUtils.sendRequestedBlobs(exchange)) {
return;
}
if (!allowed.resolve(exchange)) {
exchange.setStatusCode(StatusCodes.FORBIDDEN);
exchange.endExchange();
return;
}
ResponseCache cache = exchange.getAttachment(ResponseCache.ATTACHMENT_KEY);
final boolean cachable = this.cachable.resolve(exchange);
//we set caching headers before we try and serve from the cache
if (cachable && cacheTime != null) {
exchange.getResponseHeaders().put(Headers.CACHE_CONTROL, "public, max-age=" + cacheTime);
long date = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(cacheTime);
String dateHeader = DateUtils.toDateString(new Date(date));
exchange.getResponseHeaders().put(Headers.EXPIRES, dateHeader);
}
if (cache != null && cachable) {
if (cache.tryServeResponse()) {
return;
}
}
//we now dispatch to a worker thread
//as resource manager methods are potentially blocking
HttpHandler dispatchTask = new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
Resource resource = null;
try {
if (File.separatorChar == '/' || !exchange.getRelativePath().contains(File.separator)) {
//we don't process resources that contain the sperator character if this is not /
//this prevents attacks where people use windows path seperators in file URLS's
resource = resourceManager.getResource(canonicalize(exchange.getRelativePath()));
}
} catch (IOException e) {
clearCacheHeaders(exchange);
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.endExchange();
return;
}
if (resource == null) {
clearCacheHeaders(exchange);
//usually a 404 handler
next.handleRequest(exchange);
return;
}
if (resource.isDirectory()) {
Resource indexResource;
try {
indexResource = getIndexFiles(resourceManager, resource.getPath(), welcomeFiles);
} catch (IOException e) {
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.endExchange();
return;
}
if (indexResource == null) {
if (directoryListingEnabled) {
DirectoryUtils.renderDirectoryListing(exchange, resource);
return;
} else {
exchange.setStatusCode(StatusCodes.FORBIDDEN);
exchange.endExchange();
return;
}
} else if (!exchange.getRequestPath().endsWith("/")) {
exchange.setStatusCode(StatusCodes.FOUND);
exchange.getResponseHeaders().put(Headers.LOCATION, RedirectBuilder.redirect(exchange, exchange.getRelativePath() + "/", true));
exchange.endExchange();
return;
}
resource = indexResource;
} else if (exchange.getRelativePath().endsWith("/")) {
//UNDERTOW-432
exchange.setStatusCode(StatusCodes.NOT_FOUND);
exchange.endExchange();
return;
}
final ETag etag = resource.getETag();
final Date lastModified = resource.getLastModified();
if (!ETagUtils.handleIfMatch(exchange, etag, false) || !DateUtils.handleIfUnmodifiedSince(exchange, lastModified)) {
exchange.setStatusCode(StatusCodes.PRECONDITION_FAILED);
exchange.endExchange();
return;
}
if (!ETagUtils.handleIfNoneMatch(exchange, etag, true) || !DateUtils.handleIfModifiedSince(exchange, lastModified)) {
exchange.setStatusCode(StatusCodes.NOT_MODIFIED);
exchange.endExchange();
return;
}
final ContentEncodedResourceManager contentEncodedResourceManager = ResourceHandler.this.contentEncodedResourceManager;
Long contentLength = resource.getContentLength();
if (contentLength != null && !exchange.getResponseHeaders().contains(Headers.TRANSFER_ENCODING)) {
exchange.setResponseContentLength(contentLength);
}
ByteRange.RangeResponseResult rangeResponse = null;
long start = -1, end = -1;
if (resource instanceof RangeAwareResource && ((RangeAwareResource) resource).isRangeSupported() && contentLength != null && contentEncodedResourceManager == null) {
exchange.getResponseHeaders().put(Headers.ACCEPT_RANGES, "bytes");
//TODO: figure out what to do with the content encoded resource manager
ByteRange range = ByteRange.parse(exchange.getRequestHeaders().getFirst(Headers.RANGE));
if (range != null && range.getRanges() == 1 && resource.getContentLength() != null) {
rangeResponse = range.getResponseResult(resource.getContentLength(), exchange.getRequestHeaders().getFirst(Headers.IF_RANGE), resource.getLastModified(), resource.getETag() == null ? null : resource.getETag().getTag());
if (rangeResponse != null) {
start = rangeResponse.getStart();
end = rangeResponse.getEnd();
exchange.setStatusCode(rangeResponse.getStatusCode());
exchange.getResponseHeaders().put(Headers.CONTENT_RANGE, rangeResponse.getContentRange());
long length = rangeResponse.getContentLength();
exchange.setResponseContentLength(length);
if (rangeResponse.getStatusCode() == StatusCodes.REQUEST_RANGE_NOT_SATISFIABLE) {
return;
}
}
}
}
if (!exchange.getResponseHeaders().contains(Headers.CONTENT_TYPE)) {
final String contentType = resource.getContentType(mimeMappings);
if (contentType != null) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, contentType);
} else {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");
}
}
if (lastModified != null) {
exchange.getResponseHeaders().put(Headers.LAST_MODIFIED, resource.getLastModifiedString());
}
if (etag != null) {
exchange.getResponseHeaders().put(Headers.ETAG, etag.toString());
}
if (contentEncodedResourceManager != null) {
try {
ContentEncodedResource encoded = contentEncodedResourceManager.getResource(resource, exchange);
if (encoded != null) {
exchange.getResponseHeaders().put(Headers.CONTENT_ENCODING, encoded.getContentEncoding());
exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, encoded.getResource().getContentLength());
encoded.getResource().serve(exchange.getResponseSender(), exchange, IoCallback.END_EXCHANGE);
return;
}
} catch (IOException e) {
//TODO: should this be fatal
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
exchange.endExchange();
return;
}
}
if (!sendContent) {
exchange.endExchange();
} else if (rangeResponse != null) {
((RangeAwareResource) resource).serveRange(exchange.getResponseSender(), exchange, start, end, IoCallback.END_EXCHANGE);
} else {
resource.serve(exchange.getResponseSender(), exchange, IoCallback.END_EXCHANGE);
}
}
};
if (exchange.isInIoThread()) {
exchange.dispatch(dispatchTask);
} else {
dispatchTask.handleRequest(exchange);
}
}
Aggregations