Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ public void sendRequest(final ClientRequest request, final ClientCallback<Client
clientCallback.failed(UndertowClientMessages.MESSAGES.invalidConnectionState());
return;
}
if (anyAreSet(state, CLOSE_REQ | CLOSED)) {
clientCallback.failed(new ClosedChannelException());
return;
}
final AjpClientExchange AjpClientExchange = new AjpClientExchange(clientCallback, request, this);
if (currentRequest == null) {
initiateRequest(AjpClientExchange);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ public void sendRequest(final ClientRequest request, final ClientCallback<Client
clientCallback.failed(UndertowClientMessages.MESSAGES.invalidConnectionState());
return;
}
if (anyAreSet(state, CLOSE_REQ | CLOSED)) {
clientCallback.failed(new ClosedChannelException());
return;
}
final HttpClientExchange httpClientExchange = new HttpClientExchange(clientCallback, request, this);
boolean ssl = this.connection instanceof SslConnection;
if(!ssl && !http2Tried && options.get(UndertowOptions.ENABLE_HTTP2, false) && !request.getRequestHeaders().contains(Headers.UPGRADE)) {
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/io/undertow/server/HttpServerExchange.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import io.undertow.util.ConduitFactory;
import io.undertow.util.Cookies;
import io.undertow.util.HeaderMap;
import io.undertow.util.HeaderValues;
import io.undertow.util.Headers;
import io.undertow.util.HttpString;
import io.undertow.util.Methods;
Expand Down Expand Up @@ -1929,6 +1930,16 @@ public XnioIoThread getIoThread() {
return connection.getIoThread();
}

public boolean isMultiPartExchange() {
//NOTE: should this include Range response?
final HeaderValues contentTypeHeaders = getRequestHeaders().get("Content-Type");
if(contentTypeHeaders != null && contentTypeHeaders.size() >0) {
return contentTypeHeaders.getFirst().startsWith("multipart");
} else {
return false;
}
}

/**
* @return The maximum entity size for this exchange
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ protected Host selectHost(HttpServerExchange exchange) {
}
}

int host = hostSelector.selectHost(hosts);
int host = hostSelector.selectHost(hosts, exchange);

final int startHost = host; //if the all hosts have problems we come back to this one
Host full = null;
Expand Down Expand Up @@ -473,16 +473,27 @@ private static class ExclusiveConnectionHolder {

public interface HostSelector {

@Deprecated(forRemoval = true)
int selectHost(Host[] availableHosts);

int selectHost(Host[] availableHosts, HttpServerExchange exchange);

}

static class RoundRobinHostSelector implements HostSelector {

private final AtomicInteger currentHost = new AtomicInteger(0);

@Override
@Deprecated(forRemoval = true)
public int selectHost(Host[] availableHosts) {
return currentHost.incrementAndGet() % availableHosts.length;
}

@Override
public int selectHost(Host[] availableHosts, HttpServerExchange exchange) {
return selectHost(availableHosts);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -671,5 +671,10 @@ private synchronized void destroy() {
cancelTask = null;
}

@Override
public boolean isInvalid() {
return this.invalid;
}

}
}
6 changes: 6 additions & 0 deletions core/src/main/java/io/undertow/server/session/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,10 @@ public interface Session {
* @return The new session ID
*/
String changeSessionId(HttpServerExchange exchange, SessionConfig config);

/**
* Return state of session. NOTE: this method does not take into account if process of invalidation start.
* @return <ul><li><b>true</b> - if session is no longer valid</li><li><b>false</b> - otherwise</li></ul>
*/
boolean isInvalid();
}
6 changes: 5 additions & 1 deletion core/src/main/java/io/undertow/util/MimeMappings.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class MimeMappings {
Map<String, String> defaultMappings = new HashMap<>(101);
defaultMappings.put("txt", "text/plain");
defaultMappings.put("css", "text/css");
defaultMappings.put("csv", "text/csv");
defaultMappings.put("html", "text/html");
defaultMappings.put("htm", "text/html");
defaultMappings.put("gif", "image/gif");
Expand Down Expand Up @@ -119,6 +120,10 @@ public class MimeMappings {
defaultMappings.put("mpeg", "video/mpeg");
defaultMappings.put("mpg", "video/mpeg");
defaultMappings.put("mpe", "video/mpeg");
defaultMappings.put("mp4", "video/mp4");
defaultMappings.put("webm", "video/webm");
defaultMappings.put("flac", "audio/flac");
defaultMappings.put("weba", "audio/webm");
defaultMappings.put("qt", "video/quicktime");
defaultMappings.put("mov", "video/quicktime");
defaultMappings.put("avi", "video/x-msvideo");
Expand All @@ -127,7 +132,6 @@ public class MimeMappings {
defaultMappings.put("wrl", "x-world/x-vrml");
defaultMappings.put("mpv2", "video/mpeg2");
defaultMappings.put("jnlp", "application/x-java-jnlp-file");

defaultMappings.put("eot", "application/vnd.ms-fontobject");
defaultMappings.put("woff", "application/font-woff");
defaultMappings.put("woff2", "application/font-woff2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.undertow.Undertow;
import io.undertow.client.UndertowClient;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.InMemorySessionManager;
import io.undertow.server.session.SessionAttachmentHandler;
import io.undertow.server.session.SessionCookieConfig;
Expand Down Expand Up @@ -53,10 +54,17 @@ public static void setup() throws URISyntaxException {
server2.start();

LoadBalancingProxyClient.HostSelector hostSelector = new LoadBalancingProxyClient.HostSelector() {

@Override
public int selectHost(LoadBalancingProxyClient.Host[] availableHosts) {
return 0;
}

@Override
public int selectHost(LoadBalancingProxyClient.Host[] availableHosts, HttpServerExchange exchange) {
return 0;
}

};

DefaultServer.setRootHandler(ProxyHandler.builder().setProxyClient(new LoadBalancingProxyClient(UndertowClient.getInstance(), null, hostSelector)
Expand Down
14 changes: 14 additions & 0 deletions servlet/src/main/java/io/undertow/servlet/api/DeploymentInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class DeploymentInfo implements Cloneable {
private ConfidentialPortManager confidentialPortManager;
private boolean allowNonStandardWrappers = false;
private int defaultSessionTimeout = 60 * 30;
private long defaultAsyncContextTimeout = 30000;
private ConcurrentMap<String, Object> servletContextAttributeBackingMap;
private ServletSessionConfig servletSessionConfig;
private String hostName = "localhost";
Expand Down Expand Up @@ -319,6 +320,18 @@ public DeploymentInfo setDefaultSessionTimeout(final int defaultSessionTimeout)
return this;
}

public long getDefaultAsyncConextTimeout() {
return defaultAsyncContextTimeout;
}

/**
* @param defaultAsyncContextTimeout The default async context timeout, in milliseconds
*/
public DeploymentInfo setDefaultAsyncConextTimeout(final long defaultAsyncContextTimeout) {
this.defaultAsyncContextTimeout = defaultAsyncContextTimeout;
return this;
}

public String getDefaultEncoding() {
return defaultEncoding;
}
Expand Down Expand Up @@ -1468,6 +1481,7 @@ public DeploymentInfo clone() {
info.notificationReceivers.addAll(notificationReceivers);
info.allowNonStandardWrappers = allowNonStandardWrappers;
info.defaultSessionTimeout = defaultSessionTimeout;
info.defaultAsyncContextTimeout = defaultAsyncContextTimeout;
info.servletContextAttributeBackingMap = servletContextAttributeBackingMap;
info.servletSessionConfig = servletSessionConfig;
info.hostName = hostName;
Expand Down
10 changes: 10 additions & 0 deletions servlet/src/main/java/io/undertow/servlet/core/ManagedServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,22 @@ public ServletInfo getServletInfo() {

/**
* This value determines max multipart message size
* @deprecated
* @see #getMaxMultipartRequestSize()
* @return
*/
public long getMaxRequestSize() {
return maxMultipartRequestSize;
}

/**
* This value determines max multipart message size
* @return
*/
public long getMaxMultipartRequestSize() {
return maxMultipartRequestSize;
}

public FormParserFactory getFormParserFactory() {
return formParserFactory;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception {
final HttpServletRequestImpl request = new HttpServletRequestImpl(exchange, servletContext);
final ServletRequestContext servletRequestContext = new ServletRequestContext(servletContext.getDeployment(), request, response, info);
//set the max request size if applicable
if (info.getServletChain().getManagedServlet().getMaxRequestSize() > 0 && isMultiPartExchange(exchange)) {
exchange.setMaxEntitySize(info.getServletChain().getManagedServlet().getMaxRequestSize());
if (info.getServletChain().getManagedServlet().getMaxMultipartRequestSize() > 0 && exchange.isMultiPartExchange()) {
exchange.setMaxEntitySize(info.getServletChain().getManagedServlet().getMaxMultipartRequestSize());
}
exchange.putAttachment(ServletRequestContext.ATTACHMENT_KEY, servletRequestContext);

Expand Down Expand Up @@ -216,8 +216,8 @@ public void dispatchMockRequest(HttpServletRequest request, HttpServletResponse
servletRequestContext.setServletRequest(request);
servletRequestContext.setServletResponse(response);
//set the max request size if applicable
if (info.getServletChain().getManagedServlet().getMaxRequestSize() > 0 && isMultiPartExchange(exchange)) {
exchange.setMaxEntitySize(info.getServletChain().getManagedServlet().getMaxRequestSize());
if (info.getServletChain().getManagedServlet().getMaxMultipartRequestSize() > 0 && exchange.isMultiPartExchange()) {
exchange.setMaxEntitySize(info.getServletChain().getManagedServlet().getMaxMultipartRequestSize());
}
exchange.putAttachment(ServletRequestContext.ATTACHMENT_KEY, servletRequestContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ public class AsyncContextImpl implements AsyncContext {
private AsyncContextImpl previousAsyncContext; //the previous async context


//todo: make default configurable
private volatile long timeout = 30000;
private volatile long timeout = -1;

private volatile XnioExecutor.Key timeoutKey;

Expand Down Expand Up @@ -114,6 +113,12 @@ public void run() {
initialRequestDone();
}
});
//If its chain and non default value is set, use it
if(previousAsyncContext!=null && previousAsyncContext.getTimeout() != servletRequestContext.getDeployment().getDeploymentInfo().getDefaultAsyncConextTimeout()) {
this.timeout = previousAsyncContext.getTimeout();
} else {
this.timeout = servletRequestContext.getDeployment().getDeploymentInfo().getDefaultAsyncConextTimeout();
}
}

public void updateTimeout() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,7 @@ public boolean isInvalid() {
if(invalid) {
return true;
}
try {
//TODO: in 1.5 we need to add session.isValid()
session.getMaxInactiveInterval();
return false;
} catch (IllegalStateException e) {
return true;
}
return this.session.isInvalid();
}

public static class UnwrapSessionAction implements PrivilegedAction<Session> {
Expand Down
Loading