package org.netmelody.cieye.server.response;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Set;
import org.netmelody.cieye.core.domain.Sponsor;
import org.netmelody.cieye.core.observation.KnownOffendersDirectory;
import org.simpleframework.http.Request;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import static com.google.common.cache.CacheLoader.from;
import static java.util.concurrent.TimeUnit.HOURS;
public final class CachedRequestOriginTracker implements RequestOriginTracker {
private static final Function<String, String> DNS_HOSTNAME_LOOKUP = new Function<String, String>() {
@Override
public String apply(String ipAddress) {
try {
final InetAddress addr = InetAddress.getByName(ipAddress);
return addr.getHostName();
} catch (UnknownHostException e) {
return ipAddress;
}
}
};
private final LoadingCache<String, String> reverseLookup = CacheBuilder.newBuilder()
.expireAfterWrite(1, HOURS)
.build(from(DNS_HOSTNAME_LOOKUP));
private final KnownOffendersDirectory detective;
public CachedRequestOriginTracker(KnownOffendersDirectory detective) {
this.detective = detective;
}
@Override
public String originOf(Request request) {
final String forwardedFor = request.getValue("X-Forwarded-For");
if (null != forwardedFor && !forwardedFor.isEmpty()) {
return reverseLookup.getUnchecked(forwardedFor);
}
return request.getClientAddress().getHostName();
}
@Override
public Set<Sponsor> sponsorsOf(Request request, String operation) {
return detective.search(originOf(request) + " " + operation);
}
@Override
public Sponsor sponsorWith(String fingerprint) {
return Iterables.find(detective.search(fingerprint), Predicates.alwaysTrue(), null);
}
}