commit a8bb4babdb0a55e5f78b9d226c59145c16f06bff
Author: iwakeh <iwakeh(a)torproject.org>
Date: Wed Nov 22 08:22:58 2017 +0000
Add minimal-invasive catch-all clauses for all servlets.
This should be a temporary measure to investigate task-24534.
---
.../metrics/exonerator/ExoneraTorServlet.java | 292 +++++++++++----------
.../metrics/exonerator/QueryServlet.java | 77 +++---
2 files changed, 192 insertions(+), 177 deletions(-)
diff --git a/src/main/java/org/torproject/metrics/exonerator/ExoneraTorServlet.java b/src/main/java/org/torproject/metrics/exonerator/ExoneraTorServlet.java
index bc52564..eb3b367 100644
--- a/src/main/java/org/torproject/metrics/exonerator/ExoneraTorServlet.java
+++ b/src/main/java/org/torproject/metrics/exonerator/ExoneraTorServlet.java
@@ -66,156 +66,164 @@ public class ExoneraTorServlet extends HttpServlet {
/* Step 1: Parse the request. */
- /* Parse ip parameter. */
- String ipParameter = request.getParameter("ip");
- String relayIp = parseIpParameter(ipParameter);
- final boolean relayIpHasError = relayIp == null;
-
- /* Parse timestamp parameter. */
- String timestampParameter = request.getParameter("timestamp");
- String timestampStr = parseTimestampParameter(timestampParameter);
- final boolean timestampHasError = timestampStr == null;
-
- /* Parse lang parameter. */
- String langParameter = request.getParameter("lang");
- String langStr = "en";
- if (null != langParameter
- && this.availableLanguages.contains(langParameter)) {
- langStr = langParameter;
- }
+ try {
+ /* Parse ip parameter. */
+ String ipParameter = request.getParameter("ip");
+ String relayIp = parseIpParameter(ipParameter);
+ final boolean relayIpHasError = relayIp == null;
+
+ /* Parse timestamp parameter. */
+ String timestampParameter = request.getParameter("timestamp");
+ String timestampStr = parseTimestampParameter(timestampParameter);
+ final boolean timestampHasError = timestampStr == null;
+
+ /* Parse lang parameter. */
+ String langParameter = request.getParameter("lang");
+ String langStr = "en";
+ if (null != langParameter
+ && this.availableLanguages.contains(langParameter)) {
+ langStr = langParameter;
+ }
- /* Step 2: Query the backend server. */
-
- boolean successfullyConnectedToBackend = false;
- String firstDate = null;
- String lastDate = null;
- boolean noRelevantConsensuses = true;
- List<String[]> statusEntries = new ArrayList<>();
- List<String> addressesInSameNetwork = null;
-
- /* Only query, if we received valid user input. */
- if (null != relayIp && !relayIp.isEmpty() && null != timestampStr
- && !timestampStr.isEmpty()) {
- QueryResponse queryResponse = this.queryBackend(relayIp, timestampStr);
- if (null != queryResponse) {
- successfullyConnectedToBackend = true;
- firstDate = queryResponse.firstDateInDatabase;
- lastDate = queryResponse.lastDateInDatabase;
- if (null != queryResponse.relevantStatuses
- && queryResponse.relevantStatuses) {
- noRelevantConsensuses = false;
- }
- if (null != queryResponse.matches) {
- for (QueryResponse.Match match : queryResponse.matches) {
- StringBuilder sb = new StringBuilder();
- int writtenAddresses = 0;
- for (String address : match.addresses) {
- sb.append((writtenAddresses++ > 0 ? ", " : "") + address);
+ /* Step 2: Query the backend server. */
+
+ boolean successfullyConnectedToBackend = false;
+ String firstDate = null;
+ String lastDate = null;
+ boolean noRelevantConsensuses = true;
+ List<String[]> statusEntries = new ArrayList<>();
+ List<String> addressesInSameNetwork = null;
+
+ /* Only query, if we received valid user input. */
+ if (null != relayIp && !relayIp.isEmpty() && null != timestampStr
+ && !timestampStr.isEmpty()) {
+ QueryResponse queryResponse = this.queryBackend(relayIp, timestampStr);
+ if (null != queryResponse) {
+ successfullyConnectedToBackend = true;
+ firstDate = queryResponse.firstDateInDatabase;
+ lastDate = queryResponse.lastDateInDatabase;
+ if (null != queryResponse.relevantStatuses
+ && queryResponse.relevantStatuses) {
+ noRelevantConsensuses = false;
+ }
+ if (null != queryResponse.matches) {
+ for (QueryResponse.Match match : queryResponse.matches) {
+ StringBuilder sb = new StringBuilder();
+ int writtenAddresses = 0;
+ for (String address : match.addresses) {
+ sb.append((writtenAddresses++ > 0 ? ", " : "") + address);
+ }
+ String[] statusEntry = new String[]{match.timestamp,
+ sb.toString(), match.fingerprint, match.nickname,
+ null == match.exit ? "U" : (match.exit ? "Y" : "N")};
+ statusEntries.add(statusEntry);
}
- String[] statusEntry = new String[]{match.timestamp,
- sb.toString(), match.fingerprint, match.nickname,
- null == match.exit ? "U" : (match.exit ? "Y" : "N")};
- statusEntries.add(statusEntry);
}
- }
- if (null != queryResponse.nearbyAddresses) {
- addressesInSameNetwork = Arrays.asList(queryResponse.nearbyAddresses);
+ if (null != queryResponse.nearbyAddresses) {
+ addressesInSameNetwork
+ = Arrays.asList(queryResponse.nearbyAddresses);
+ }
}
}
- }
- /* Step 3: Write the response. */
-
- /* Set content type, or the page doesn't render in Chrome. */
- response.setContentType("text/html");
- response.setCharacterEncoding("utf-8");
-
- /* Find the right resource bundle for the user's requested language. */
- ResourceBundle rb = ResourceBundle.getBundle("ExoneraTor",
- Locale.forLanguageTag(langStr));
-
- /* Start writing response. */
- StringWriter so = new StringWriter();
- PrintWriter out = new PrintWriter(so);
- this.writeHeader(out, rb, langStr);
-
- /* Write form. */
- boolean timestampOutOfRange = null != timestampStr
- && (null != firstDate && timestampStr.compareTo(firstDate) < 0
- || (null != lastDate && timestampStr.compareTo(lastDate) > 0));
- this.writeForm(out, rb, relayIp, relayIpHasError
- || ("".equals(relayIp) && !"".equals(timestampStr)), timestampStr,
- !relayIpHasError
- && !("".equals(relayIp) && !"".equals(timestampStr))
- && (timestampHasError || timestampOutOfRange
- || (!"".equals(relayIp) && "".equals(timestampStr))), langStr);
-
- /* If both parameters are empty, don't print any summary and exit.
- * This is the start page. */
- if ("".equals(relayIp) && "".equals(timestampStr)) {
- this.writeFooter(out, rb, null, null);
-
- /* If only one parameter is empty and the other is not, print summary with
- * warning message and exit. */
- } else if ("".equals(relayIp)) {
- this.writeSummaryNoIp(out, rb);
- this.writeFooter(out, rb, null, null);
- } else if ("".equals(timestampStr)) {
- this.writeSummaryNoTimestamp(out, rb);
- this.writeFooter(out, rb, null, null);
-
- /* If there's an issue with parsing either of the parameters, print summary
- * with error message and exit. */
- } else if (relayIpHasError) {
- this.writeSummaryInvalidIp(out, rb, ipParameter);
- this.writeFooter(out, rb, null, null);
- } else if (timestampHasError) {
- this.writeSummaryInvalidTimestamp(out, rb, timestampParameter);
- this.writeFooter(out, rb, null, null);
-
- /* If we were unable to connect to the database, write an error message. */
- } else if (!successfullyConnectedToBackend) {
- this.writeSummaryUnableToConnectToBackend(out, rb);
- this.writeFooter(out, rb, null, null);
-
- /* Similarly, if we found the database to be empty, write an error message,
- * too. */
- } else if (null == firstDate || null == lastDate) {
- this.writeSummaryNoData(out, rb);
- this.writeFooter(out, rb, null, null);
-
- /* If the requested date is out of range, tell the user. */
- } else if (timestampOutOfRange) {
- this.writeSummaryTimestampOutsideRange(out, rb, timestampStr,
- firstDate, lastDate);
- this.writeFooter(out, rb, relayIp, timestampStr);
-
- } else if (noRelevantConsensuses) {
- this.writeSummaryNoDataForThisInterval(out, rb);
- this.writeFooter(out, rb, relayIp, timestampStr);
-
- /* Print out result. */
- } else {
- if (!statusEntries.isEmpty()) {
- this.writeSummaryPositive(out, rb, relayIp, timestampStr);
- this.writeTechnicalDetails(out, rb, relayIp, timestampStr,
- statusEntries);
- } else if (addressesInSameNetwork != null
- && !addressesInSameNetwork.isEmpty()) {
- this.writeSummaryAddressesInSameNetwork(out, rb, relayIp,
- timestampStr, langStr, addressesInSameNetwork);
+ /* Step 3: Write the response. */
+
+ /* Set content type, or the page doesn't render in Chrome. */
+ response.setContentType("text/html");
+ response.setCharacterEncoding("utf-8");
+
+ /* Find the right resource bundle for the user's requested language. */
+ ResourceBundle rb = ResourceBundle.getBundle("ExoneraTor",
+ Locale.forLanguageTag(langStr));
+
+ /* Start writing response. */
+ StringWriter so = new StringWriter();
+ PrintWriter out = new PrintWriter(so);
+ this.writeHeader(out, rb, langStr);
+
+ /* Write form. */
+ boolean timestampOutOfRange = null != timestampStr
+ && (null != firstDate && timestampStr.compareTo(firstDate) < 0
+ || (null != lastDate && timestampStr.compareTo(lastDate) > 0));
+ this.writeForm(out, rb, relayIp, relayIpHasError
+ || ("".equals(relayIp) && !"".equals(timestampStr)), timestampStr,
+ !relayIpHasError
+ && !("".equals(relayIp) && !"".equals(timestampStr))
+ && (timestampHasError || timestampOutOfRange
+ || (!"".equals(relayIp) && "".equals(timestampStr))), langStr);
+
+ /* If both parameters are empty, don't print any summary and exit.
+ * This is the start page. */
+ if ("".equals(relayIp) && "".equals(timestampStr)) {
+ this.writeFooter(out, rb, null, null);
+
+ /* If only one parameter is empty and the other is not, print summary
+ * with warning message and exit. */
+ } else if ("".equals(relayIp)) {
+ this.writeSummaryNoIp(out, rb);
+ this.writeFooter(out, rb, null, null);
+ } else if ("".equals(timestampStr)) {
+ this.writeSummaryNoTimestamp(out, rb);
+ this.writeFooter(out, rb, null, null);
+
+ /* If there's an issue with parsing either of the parameters, print
+ * summary with error message and exit. */
+ } else if (relayIpHasError) {
+ this.writeSummaryInvalidIp(out, rb, ipParameter);
+ this.writeFooter(out, rb, null, null);
+ } else if (timestampHasError) {
+ this.writeSummaryInvalidTimestamp(out, rb, timestampParameter);
+ this.writeFooter(out, rb, null, null);
+
+ /* If we were unable to connect to the database,
+ * write an error message. */
+ } else if (!successfullyConnectedToBackend) {
+ this.writeSummaryUnableToConnectToBackend(out, rb);
+ this.writeFooter(out, rb, null, null);
+
+ /* Similarly, if we found the database to be empty,
+ * write an error message, too. */
+ } else if (null == firstDate || null == lastDate) {
+ this.writeSummaryNoData(out, rb);
+ this.writeFooter(out, rb, null, null);
+
+ /* If the requested date is out of range, tell the user. */
+ } else if (timestampOutOfRange) {
+ this.writeSummaryTimestampOutsideRange(out, rb, timestampStr,
+ firstDate, lastDate);
+ this.writeFooter(out, rb, relayIp, timestampStr);
+
+ } else if (noRelevantConsensuses) {
+ this.writeSummaryNoDataForThisInterval(out, rb);
+ this.writeFooter(out, rb, relayIp, timestampStr);
+
+ /* Print out result. */
} else {
- this.writeSummaryNegative(out, rb, relayIp, timestampStr);
+ if (!statusEntries.isEmpty()) {
+ this.writeSummaryPositive(out, rb, relayIp, timestampStr);
+ this.writeTechnicalDetails(out, rb, relayIp, timestampStr,
+ statusEntries);
+ } else if (addressesInSameNetwork != null
+ && !addressesInSameNetwork.isEmpty()) {
+ this.writeSummaryAddressesInSameNetwork(out, rb, relayIp,
+ timestampStr, langStr, addressesInSameNetwork);
+ } else {
+ this.writeSummaryNegative(out, rb, relayIp, timestampStr);
+ }
+ this.writePermanentLink(out, rb, relayIp, timestampStr, langStr);
+ this.writeFooter(out, rb, relayIp, timestampStr);
}
- this.writePermanentLink(out, rb, relayIp, timestampStr, langStr);
- this.writeFooter(out, rb, relayIp, timestampStr);
- }
- /* Forward to the JSP that adds header and footer. */
- request.setAttribute("lang", langStr);
- request.setAttribute("body", so.toString());
- request.getRequestDispatcher("WEB-INF/index.jsp").forward(request,
- response);
+ /* Forward to the JSP that adds header and footer. */
+ request.setAttribute("lang", langStr);
+ request.setAttribute("body", so.toString());
+ request.getRequestDispatcher("WEB-INF/index.jsp").forward(request,
+ response);
+ } catch (Throwable th) {
+ logger.error("Some problem in doGet. Returning error.", th);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "General error.");
+ }
}
/* Helper methods for handling the request. */
@@ -310,6 +318,8 @@ public class ExoneraTorServlet extends HttpServlet {
/* No result from backend, so that we don't have a query response to
* process further. */
logger.error("Backend query failed.", e);
+ } catch (Throwable th) {
+ logger.error("Backend query failed with general error.", th);
}
return null;
}
diff --git a/src/main/java/org/torproject/metrics/exonerator/QueryServlet.java b/src/main/java/org/torproject/metrics/exonerator/QueryServlet.java
index 7406be5..50badd6 100644
--- a/src/main/java/org/torproject/metrics/exonerator/QueryServlet.java
+++ b/src/main/java/org/torproject/metrics/exonerator/QueryServlet.java
@@ -62,45 +62,50 @@ public class QueryServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
+ try {
+ /* Parse ip parameter. */
+ String ipParameter = request.getParameter("ip");
+ if (null == ipParameter) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Missing ip parameter.");
+ return;
+ }
+ String relayIp = this.parseIpParameter(ipParameter);
+ if (null == relayIp) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Invalid ip parameter.");
+ return;
+ }
- /* Parse ip parameter. */
- String ipParameter = request.getParameter("ip");
- if (null == ipParameter) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
- "Missing ip parameter.");
- return;
- }
- String relayIp = this.parseIpParameter(ipParameter);
- if (null == relayIp) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
- "Invalid ip parameter.");
- return;
- }
-
- /* Parse timestamp parameter. */
- String timestampParameter = request.getParameter("timestamp");
- if (null == timestampParameter) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
- "Missing timestamp parameter.");
- return;
- }
- Long timestamp = this.parseTimestampParameter(timestampParameter);
- if (null == timestamp) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST,
- "Invalid timestamp parameter.");
- return;
- }
+ /* Parse timestamp parameter. */
+ String timestampParameter = request.getParameter("timestamp");
+ if (null == timestampParameter) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Missing timestamp parameter.");
+ return;
+ }
+ Long timestamp = this.parseTimestampParameter(timestampParameter);
+ if (null == timestamp) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST,
+ "Invalid timestamp parameter.");
+ return;
+ }
- /* Query the database. */
- QueryResponse queryResponse = this.queryDatabase(relayIp, timestamp);
- if (null == queryResponse) {
+ /* Query the database. */
+ QueryResponse queryResponse = this.queryDatabase(relayIp, timestamp);
+ if (null == queryResponse) {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Database error.");
+ } else {
+ /* Write the response. */
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+ response.getWriter().write(QueryResponse.toJson(queryResponse));
+ }
+ } catch (Throwable th) {
+ logger.error("Some problem in doGet. Returning error.", th);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
- "Database error.");
- } else {
- /* Write the response. */
- response.setContentType("application/json");
- response.setCharacterEncoding("utf-8");
- response.getWriter().write(QueryResponse.toJson(queryResponse));
+ "General backend error.");
}
}