commit a8bb4babdb0a55e5f78b9d226c59145c16f06bff Author: iwakeh iwakeh@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."); } }
tor-commits@lists.torproject.org