commit b7f0ba813e9468c1635457a513a77496d62aed23 Author: Karsten Loesing karsten.loesing@gmx.net Date: Wed Jul 13 13:12:41 2011 +0200
Let users download votes from a given valid-after time. --- ChangeLog | 1 + etc/web.xml | 11 +++ src/org/torproject/ernie/web/VotesServlet.java | 110 ++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 94884cf..387e813 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ Metrics database and website change log:
Changes in version 0.0.2 - 2011-??-?? + - Let users download votes from a given valid-after time.
Changes in version 0.0.1 - 2011-06-08 - Initial release diff --git a/etc/web.xml b/etc/web.xml index 688e6f3..dbaa0a2 100644 --- a/etc/web.xml +++ b/etc/web.xml @@ -299,6 +299,17 @@ </servlet-mapping>
<servlet> + <servlet-name>Votes</servlet-name> + <servlet-class> + org.torproject.ernie.web.VotesServlet + </servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>Votes</servlet-name> + <url-pattern>/votes</url-pattern> + </servlet-mapping> + + <servlet> <servlet-name>ErnieGeneratedFile</servlet-name> <servlet-class> org.torproject.ernie.web.ErnieGeneratedFileServlet diff --git a/src/org/torproject/ernie/web/VotesServlet.java b/src/org/torproject/ernie/web/VotesServlet.java new file mode 100644 index 0000000..3af9705 --- /dev/null +++ b/src/org/torproject/ernie/web/VotesServlet.java @@ -0,0 +1,110 @@ +package org.torproject.ernie.web; + +import java.io.*; +import java.sql.*; +import java.text.*; +import java.util.*; +import java.util.logging.*; + +import javax.naming.*; +import javax.servlet.*; +import javax.servlet.http.*; +import javax.sql.*; + +public class VotesServlet extends HttpServlet { + + private DataSource ds; + + private Logger logger; + + public void init() { + + /* Initialize logger. */ + this.logger = Logger.getLogger(VotesServlet.class.toString()); + + /* Look up data source. */ + try { + Context cxt = new InitialContext(); + this.ds = (DataSource) cxt.lookup("java:comp/env/jdbc/tordir"); + this.logger.info("Successfully looked up data source."); + } catch (NamingException e) { + this.logger.log(Level.WARNING, "Could not look up data source", e); + } + } + + public void doGet(HttpServletRequest request, + HttpServletResponse response) throws IOException, + ServletException { + + /* Check valid-after parameter. */ + String validAfterParameter = request.getParameter("valid-after"); + if (validAfterParameter == null || + 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; + } + + /* Look up consensus in the database. */ + SimpleDateFormat databaseFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + databaseFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String databaseParameter = databaseFormat.format(parsedTimestamp); + List<byte[]> rawDescriptors = new ArrayList<byte[]>(); + try { + Connection conn = this.ds.getConnection(); + Statement statement = conn.createStatement(); + String query = "SELECT rawdesc FROM vote " + + "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; + } + + /* Write response. */ + 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( + responseLength)); + response.setHeader("Content-Disposition", "inline; filename="" + + validAfterParameter + "-votes""); + BufferedOutputStream output = new BufferedOutputStream( + response.getOutputStream()); + for (byte[] rawDescriptor : rawDescriptors) { + output.write(rawDescriptor); + } + } finally { + /* Nothing to do here. */ + } + } +} +
tor-commits@lists.torproject.org