Skip to content

Commit

Permalink
Introduce caching of ResteasyUriInfo.InitData
Browse files Browse the repository at this point in the history
This is done because the computation of the data is expensive

Relates to: #4345
  • Loading branch information
geoand committed Oct 15, 2019
1 parent 235ed78 commit 6c832bd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;
Expand Down Expand Up @@ -39,6 +41,8 @@ public class VertxRequestHandler implements Handler<RoutingContext> {
protected final BeanContainer beanContainer;
protected final CurrentIdentityAssociation association;

private final Map<String, ResteasyUriInfo.InitData> resteasyUriInfoInitDataMap = new ConcurrentHashMap<>();

public VertxRequestHandler(Vertx vertx,
BeanContainer beanContainer,
ResteasyDeployment deployment,
Expand Down Expand Up @@ -90,7 +94,22 @@ private void dispatch(RoutingContext routingContext, InputStream is, VertxOutput
try {
Context ctx = vertx.getOrCreateContext();
HttpServerRequest request = routingContext.request();
ResteasyUriInfo uriInfo = VertxUtil.extractUriInfo(request, servletMappingPrefix);

String uriString = VertxUtil.getUriString(request);
ResteasyUriInfo.InitData resteasyUriInfoCachedInitData = null;
boolean setInitDataUponSuccess = false;
if (ResteasyUriInfo.InitData.canBeCached(uriString)) {
String cacheKey = ResteasyUriInfo.InitData.getCacheKey(uriString, servletMappingPrefix);
resteasyUriInfoCachedInitData = resteasyUriInfoInitDataMap.get(cacheKey);
if (resteasyUriInfoCachedInitData == null) {
setInitDataUponSuccess = true;
}
}
if (resteasyUriInfoCachedInitData == null) {
resteasyUriInfoCachedInitData = new ResteasyUriInfo.InitData(uriString, servletMappingPrefix);
}

ResteasyUriInfo uriInfo = new ResteasyUriInfo(uriString, servletMappingPrefix, resteasyUriInfoCachedInitData);
ResteasyHttpHeaders headers = VertxUtil.extractHttpHeaders(request);
HttpServerResponse response = request.response();
VertxHttpResponse vertxResponse = new VertxHttpResponse(request, dispatcher.getProviderFactory(),
Expand All @@ -114,6 +133,14 @@ private void dispatch(RoutingContext routingContext, InputStream is, VertxOutput
if (!vertxRequest.getAsyncContext().isSuspended()) {
try {
vertxResponse.finish();
// the reason we only cache successful responses is to ensure that a torrent of erroneous URLs
// doesn't fill up the cache and cause a DoS
if (setInitDataUponSuccess && vertxResponse.getStatus() >= 200 && vertxResponse.getStatus() <= 300) {
// this could potentially be written multiple times for initial requests but it doesn't matter
// since the data is always the same
resteasyUriInfoInitDataMap.put(ResteasyUriInfo.InitData.getCacheKey(uriString, servletMappingPrefix),
resteasyUriInfoCachedInitData);
}
} catch (IOException e) {
log.error("Unexpected failure", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class VertxUtil {

private static final Pattern COMMA_PATTERN = Pattern.compile(",");

public static ResteasyUriInfo extractUriInfo(HttpServerRequest req, String contextPath) {
public static String getUriString(HttpServerRequest req) {
String uri = req.absoluteURI();
String protocol = req.scheme();

Expand All @@ -44,7 +44,16 @@ public static ResteasyUriInfo extractUriInfo(HttpServerRequest req, String conte
uriString = protocol + "://" + host + uri;
}

return new ResteasyUriInfo(uriString, contextPath);
return uriString;
}

public static ResteasyUriInfo.InitData extractUriInfoInitData(String uriString, String contextPath,
Map<String, ResteasyUriInfo.InitData> resteasyUriInfoInitDataMap) {
if (ResteasyUriInfo.InitData.canBeCached(uriString)) {
String cacheKey = ResteasyUriInfo.InitData.getCacheKey(uriString, contextPath);
return resteasyUriInfoInitDataMap.get(cacheKey);
}
return null;
}

public static ResteasyHttpHeaders extractHttpHeaders(HttpServerRequest request) {
Expand Down

0 comments on commit 6c832bd

Please sign in to comment.