Commit a8bb4bab authored by iwakeh's avatar iwakeh
Browse files

Add minimal-invasive catch-all clauses for all servlets.

This should be a temporary measure to investigate task-24534.
parent cb5700d5
......@@ -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;
}
......
......@@ -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.");
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment