- Remove separate print stacktrace method - Log level into the log similar to console output
136 lines
4.5 KiB
Java
136 lines
4.5 KiB
Java
package fr.xephi.authme.util;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.maxmind.geoip.LookupService;
|
|
import fr.xephi.authme.ConsoleLogger;
|
|
import fr.xephi.authme.initialization.DataFolder;
|
|
|
|
import javax.inject.Inject;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.net.URL;
|
|
import java.net.URLConnection;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
public class GeoLiteAPI {
|
|
private static final String LICENSE =
|
|
"[LICENSE] This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com";
|
|
private static final String GEOIP_URL =
|
|
"http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz";
|
|
private LookupService lookupService;
|
|
private Thread downloadTask;
|
|
|
|
private final File dataFile;
|
|
|
|
@Inject
|
|
GeoLiteAPI(@DataFolder File dataFolder) {
|
|
this.dataFile = new File(dataFolder, "GeoIP.dat");
|
|
// Fires download of recent data or the initialization of the look up service
|
|
isDataAvailable();
|
|
}
|
|
|
|
@VisibleForTesting
|
|
GeoLiteAPI(@DataFolder File dataFolder, LookupService lookupService) {
|
|
this.dataFile = dataFolder;
|
|
this.lookupService = lookupService;
|
|
}
|
|
|
|
/**
|
|
* Download (if absent or old) the GeoIpLite data file and then try to load it.
|
|
*
|
|
* @return True if the data is available, false otherwise.
|
|
*/
|
|
private synchronized boolean isDataAvailable() {
|
|
if (downloadTask != null && downloadTask.isAlive()) {
|
|
return false;
|
|
}
|
|
if (lookupService != null) {
|
|
return true;
|
|
}
|
|
|
|
if (dataFile.exists()) {
|
|
boolean dataIsOld = (System.currentTimeMillis() - dataFile.lastModified()) > TimeUnit.DAYS.toMillis(30);
|
|
if (!dataIsOld) {
|
|
try {
|
|
lookupService = new LookupService(dataFile);
|
|
ConsoleLogger.info(LICENSE);
|
|
return true;
|
|
} catch (IOException e) {
|
|
ConsoleLogger.logException("Failed to load GeoLiteAPI database", e);
|
|
return false;
|
|
}
|
|
} else {
|
|
if (!dataFile.delete()) {
|
|
ConsoleLogger.warning("Failed to delete GeoLiteAPI database");
|
|
}
|
|
}
|
|
}
|
|
// Ok, let's try to download the data file!
|
|
downloadTask = createDownloadTask();
|
|
downloadTask.start();
|
|
return false;
|
|
}
|
|
|
|
private Thread createDownloadTask() {
|
|
return new Thread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
URL downloadUrl = new URL(GEOIP_URL);
|
|
URLConnection conn = downloadUrl.openConnection();
|
|
conn.setConnectTimeout(10000);
|
|
conn.connect();
|
|
InputStream input = conn.getInputStream();
|
|
if (conn.getURL().toString().endsWith(".gz")) {
|
|
input = new GZIPInputStream(input);
|
|
}
|
|
OutputStream output = new FileOutputStream(dataFile);
|
|
byte[] buffer = new byte[2048];
|
|
int length = input.read(buffer);
|
|
while (length >= 0) {
|
|
output.write(buffer, 0, length);
|
|
length = input.read(buffer);
|
|
}
|
|
output.close();
|
|
input.close();
|
|
} catch (IOException e) {
|
|
ConsoleLogger.logException("Could not download GeoLiteAPI database", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the country code of the given IP address.
|
|
*
|
|
* @param ip textual IP address to lookup.
|
|
*
|
|
* @return two-character ISO 3166-1 alpha code for the country.
|
|
*/
|
|
public String getCountryCode(String ip) {
|
|
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
|
return lookupService.getCountry(ip).getCode();
|
|
}
|
|
return "--";
|
|
}
|
|
|
|
/**
|
|
* Get the country name of the given IP address.
|
|
*
|
|
* @param ip textual IP address to lookup.
|
|
*
|
|
* @return The name of the country.
|
|
*/
|
|
public String getCountryName(String ip) {
|
|
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
|
return lookupService.getCountry(ip).getName();
|
|
}
|
|
return "N/A";
|
|
}
|
|
|
|
}
|