[tor-commits] [metrics-web/master] Enable downloading all descriptors referenced by a consensus.

karsten at torproject.org karsten at torproject.org
Thu Jul 21 14:02:11 UTC 2011


commit cfa54b8f076eced634d484e2cdaa4af84ab477fc
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Thu Jul 21 15:17:03 2011 +0200

    Enable downloading all descriptors referenced by a consensus.
---
 .../ernie/web/ServerDescriptorServlet.java         |  138 +++++++++++++++-----
 1 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/src/org/torproject/ernie/web/ServerDescriptorServlet.java b/src/org/torproject/ernie/web/ServerDescriptorServlet.java
index 960bd75..1db68c4 100644
--- a/src/org/torproject/ernie/web/ServerDescriptorServlet.java
+++ b/src/org/torproject/ernie/web/ServerDescriptorServlet.java
@@ -2,6 +2,8 @@ package org.torproject.ernie.web;
 
 import java.io.*;
 import java.sql.*;
+import java.text.*;
+import java.util.*;
 import java.util.logging.*;
 import java.util.regex.*;
 
@@ -36,56 +38,124 @@ public class ServerDescriptorServlet extends HttpServlet {
       HttpServletResponse response) throws IOException,
       ServletException {
 
-    /* Check desc-id parameter. */
+    /* Read desc-id and/or valid-after parameters. */
+    String validAfterParameter = request.getParameter("valid-after");
     String descIdParameter = request.getParameter("desc-id");
-    if (descIdParameter == null || descIdParameter.length() < 8 ||
-        descIdParameter.length() > 40) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
-      return;
-    }
-    String descId = descIdParameter.toLowerCase();
-    Pattern descIdPattern = Pattern.compile("^[0-9a-f]+$");
-    Matcher descIdMatcher = descIdPattern.matcher(descId);
-    if (!descIdMatcher.matches()) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
-      return;
-    }
 
-    /* Look up descriptor in the database. */
-    String descriptor = null;
-    byte[] rawDescriptor = null;
-    try {
-      Connection conn = ds.getConnection();
-      Statement statement = conn.createStatement();
-      String query = "SELECT descriptor, rawdesc FROM descriptor "
-          + "WHERE descriptor LIKE '" + descId + "%'";
-      ResultSet rs = statement.executeQuery(query);
-      if (rs.next()) {
-        descriptor = rs.getString(1);
-        rawDescriptor = rs.getBytes(2);
+    /* See if we were given a desc-id parameter.  If so, look up this
+     * descriptor and return it. */
+    List<byte[]> rawDescriptors = new ArrayList<byte[]>();
+    String filename = null;
+    if (descIdParameter != null && validAfterParameter == null) {
+      if (descIdParameter.length() < 8 ||
+          descIdParameter.length() > 40) {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        return;
+      }
+      String descId = descIdParameter.toLowerCase();
+      Pattern descIdPattern = Pattern.compile("^[0-9a-f]+$");
+      Matcher descIdMatcher = descIdPattern.matcher(descId);
+      if (!descIdMatcher.matches()) {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        return;
+      }
+
+      /* Look up descriptor in the database. */
+      try {
+        Connection conn = ds.getConnection();
+        Statement statement = conn.createStatement();
+        String query = "SELECT descriptor, rawdesc FROM descriptor "
+            + "WHERE descriptor LIKE '" + descId + "%'";
+        ResultSet rs = statement.executeQuery(query);
+        if (rs.next()) {
+          filename = rs.getString(1);
+          rawDescriptors.add(rs.getBytes(2));
+        }
+        rs.close();
+        statement.close();
+        conn.close();
+      } catch (SQLException e) {
+        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        return;
       }
-      rs.close();
-      statement.close();
-      conn.close();
-    } catch (SQLException e) {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+
+    /* See if we were given a valid-after parameter.  If so, return all
+     * descriptors referenced from the consensus published at that
+     * time. */
+    } else if (descIdParameter == null && validAfterParameter != null) {
+      if (validAfterParameter.length() !=
+          "yyyy-MM-dd-HH-mm-ss".length()) {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        return;
+      }
+      SimpleDateFormat parameterFormat = new SimpleDateFormat(
+          "yyyy-MM-dd-HH-mm-ss");
+      parameterFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+      long parsedTimestamp = -1L;
+      try {
+        parsedTimestamp = parameterFormat.parse(validAfterParameter).
+            getTime();
+      } catch (ParseException e) {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        return;
+      }
+      if (parsedTimestamp < 0L) {
+        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        return;
+      }
+      filename = validAfterParameter + "-descriptors";
+
+      /* Look up descriptors in the database. */
+      SimpleDateFormat databaseFormat = new SimpleDateFormat(
+          "yyyy-MM-dd HH:mm:ss");
+      databaseFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+      String databaseParameter = databaseFormat.format(parsedTimestamp);
+      try {
+        Connection conn = this.ds.getConnection();
+        Statement statement = conn.createStatement();
+        String query = "SELECT descriptor.rawdesc FROM statusentry "
+            + "JOIN descriptor ON statusentry.descriptor = "
+            + "descriptor.descriptor WHERE validafter = '"
+            + databaseParameter + "'";
+        ResultSet rs = statement.executeQuery(query);
+        while (rs.next()) {
+          rawDescriptors.add(rs.getBytes(1));
+        }
+        rs.close();
+        statement.close();
+        conn.close();
+      } catch (SQLException e) {
+        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        return;
+      }
+
+    /* Return an error if neither desc-id nor valid-after parameter was
+     * given (or both of them). */
+    } else {
+      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
       return;
     }
 
     /* Write response. */
-    if (rawDescriptor == null) {
+    if (rawDescriptors.size() == 0) {
       response.sendError(HttpServletResponse.SC_NOT_FOUND);
       return;
     }
     try {
       response.setContentType("text/plain");
+      int responseLength = 0;
+      for (byte[] rawDescriptor : rawDescriptors) {
+        responseLength += rawDescriptor.length;
+      }
       response.setHeader("Content-Length", String.valueOf(
-          rawDescriptor.length));
+          responseLength));
       response.setHeader("Content-Disposition", "inline; filename=\""
-          + descriptor + "\"");
+          + filename + "\"");
       BufferedOutputStream output = new BufferedOutputStream(
           response.getOutputStream());
-      output.write(rawDescriptor);
+      for (byte[] rawDescriptor : rawDescriptors) {
+        output.write(rawDescriptor);
+      }
       output.flush();
       output.close();
     } finally {



More information about the tor-commits mailing list