package io.lumify.web;
import io.lumify.miniweb.Handler;
import io.lumify.miniweb.HandlerChain;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import net.sf.uadetector.ReadableUserAgent;
import net.sf.uadetector.UserAgentStringParser;
import net.sf.uadetector.VersionNumber;
import net.sf.uadetector.service.UADetectorServiceFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class UserAgentFilter implements Handler {
private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(UserAgentFilter.class);
private static final Map<String, VersionNumber> MINIMUM_VERSION_BROWSERS = new HashMap<String, VersionNumber>();
static {
MINIMUM_VERSION_BROWSERS.put("IE", new VersionNumber("10"));
MINIMUM_VERSION_BROWSERS.put("Firefox", new VersionNumber("17"));
}
private final UserAgentStringParser parser = UADetectorServiceFactory.getResourceModuleParser();
private final Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(2, TimeUnit.HOURS)
.build();
@Override
public void handle(HttpServletRequest request, HttpServletResponse httpServletResponse, HandlerChain handlerChain) throws Exception {
String message = isUnsupported(request.getHeader("User-Agent"));
if (!message.equals("")) {
httpServletResponse.setContentType("text/plain");
PrintWriter writer = httpServletResponse.getWriter();
writer.println(message);
writer.close();
writer.flush();
return;
}
handlerChain.next(request, httpServletResponse);
}
private String isUnsupported(String userAgentString) {
String message = cache.getIfPresent(userAgentString);
if (message == null) {
ReadableUserAgent userAgent = parser.parse(userAgentString);
message = isUnsupported(userAgent);
cache.put(userAgentString, message);
}
return message;
}
private String isUnsupported(ReadableUserAgent userAgent) {
if (MINIMUM_VERSION_BROWSERS.containsKey(userAgent.getName())) {
VersionNumber minimumVersion = MINIMUM_VERSION_BROWSERS.get(userAgent.getName());
if (userAgent.getVersionNumber().compareTo(minimumVersion) < 0) {
String message = getUnsupportedMessage(userAgent);
LOGGER.warn(message);
return message;
}
}
return "";
}
private String getUnsupportedMessage(ReadableUserAgent userAgent) {
VersionNumber minimumVersion = MINIMUM_VERSION_BROWSERS.get(userAgent.getName());
if (minimumVersion != null) {
return userAgent.getName() + " " + userAgent.getVersionNumber().toVersionString() + " is not supported. Please upgrade to at least version " + minimumVersion.toVersionString() + ".";
}
return userAgent.getName() + " " + userAgent.getVersionNumber().toVersionString() + " is not supported.";
}
}