More drastic changes to prevent CLOSE_WAIT - defensive socket settings, ban a troublesome IP

git-svn-id: https://zxing.googlecode.com/svn/trunk@2238 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2012-03-29 18:18:19 +00:00
parent bd1d0c4bef
commit 65efebdc97
3 changed files with 28 additions and 8 deletions

View file

@ -46,6 +46,10 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import java.awt.color.CMMException;
@ -63,7 +67,6 @@ import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -102,14 +105,12 @@ public final class DecodeServlet extends HttpServlet {
}
private DiskFileItemFactory diskFileItemFactory;
private HttpClient client;
@Override
public void init(ServletConfig servletConfig) {
Logger logger = Logger.getLogger("com.google.zxing");
logger.addHandler(new ServletContextLogHandler(servletConfig.getServletContext()));
diskFileItemFactory = new DiskFileItemFactory();
client = new DefaultHttpClient();
log.info("DecodeServlet configured");
}
@ -143,6 +144,14 @@ public final class DecodeServlet extends HttpServlet {
HttpUriRequest getRequest = new HttpGet(imageURI);
getRequest.addHeader("Connection", "close"); // Avoids CLOSE_WAIT socket issue?
HttpParams params = new BasicHttpParams();
DefaultHttpClient.setDefaultHttpParams(params);
params.setIntParameter(CoreConnectionPNames.SO_LINGER, 5); // Avoids CLOSE_WAIT socket issue?
params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);
params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
ClientConnectionManager connectionManager = new BasicClientConnectionManager();
HttpClient client = new DefaultHttpClient(connectionManager, params);
try {
HttpResponse getResponse;
@ -194,9 +203,7 @@ public final class DecodeServlet extends HttpServlet {
}
} finally {
ClientConnectionManager connectionManager = client.getConnectionManager();
connectionManager.closeExpiredConnections();
connectionManager.closeIdleConnections(1, TimeUnit.SECONDS);
connectionManager.shutdown();
}
}
@ -390,7 +397,6 @@ public final class DecodeServlet extends HttpServlet {
@Override
public void destroy() {
log.config("DecodeServlet shutting down...");
client.getConnectionManager().shutdown();
}
}

View file

@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@ -44,9 +45,11 @@ public final class DoSFilter implements Filter {
private static final int MAX_ACCESSES_PER_IP_PER_TIME = 10;
private static final long MAX_ACCESS_INTERVAL_MSEC = 10L * 1000L;
private static final long UNBAN_INTERVAL_MSEC = 60L * 60L * 1000L;
public static final String BAD_IPS_INIT_PARAM = "bad.ips";
private final IPTrie numRecentAccesses;
private final Timer timer;
private final Set<String> badIPAddresses;
private final Set<String> bannedIPAddresses;
private ServletContext context;
@ -54,6 +57,7 @@ public final class DoSFilter implements Filter {
numRecentAccesses = new IPTrie();
timer = new Timer("DosFilter reset timer");
bannedIPAddresses = Collections.synchronizedSet(new HashSet<String>());
badIPAddresses = new HashSet<String>();
}
@Override
@ -61,6 +65,11 @@ public final class DoSFilter implements Filter {
context = filterConfig.getServletContext();
timer.scheduleAtFixedRate(new ResetTask(), 0L, MAX_ACCESS_INTERVAL_MSEC);
timer.scheduleAtFixedRate(new UnbanTask(), 0L, UNBAN_INTERVAL_MSEC);
badIPAddresses.clear();
String badIPsString = filterConfig.getInitParameter(BAD_IPS_INIT_PARAM);
if (badIPsString != null) {
badIPAddresses.addAll(Arrays.asList(badIPsString.split(",")));
}
}
@Override
@ -77,7 +86,7 @@ public final class DoSFilter implements Filter {
private boolean isBanned(ServletRequest request) {
String remoteIPAddressString = request.getRemoteAddr();
if (bannedIPAddresses.contains(remoteIPAddressString)) {
if (bannedIPAddresses.contains(remoteIPAddressString) || badIPAddresses.contains(remoteIPAddressString)) {
return true;
}
InetAddress remoteIPAddress;
@ -100,6 +109,7 @@ public final class DoSFilter implements Filter {
timer.cancel();
numRecentAccesses.clear();
bannedIPAddresses.clear();
badIPAddresses.clear();
}
private final class ResetTask extends TimerTask {

View file

@ -24,6 +24,10 @@
<filter>
<filter-name>DoSFilter</filter-name>
<filter-class>com.google.zxing.web.DoSFilter</filter-class>
<init-param>
<param-name>bad.ips</param-name>
<param-value>69.89.31.60,2.95.142.74</param-value> <!-- Causes weird CLOSE_WAIT thread hangs -->
</init-param>
</filter>
<filter-mapping>