[tor-commits] [onionoo/master] Add country parameter to search by country code.
karsten at torproject.org
karsten at torproject.org
Thu Jun 14 15:43:01 UTC 2012
commit cedd372a13a49c11da9b4327e8b7e373c750eab6
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Thu Jun 14 17:36:33 2012 +0200
Add country parameter to search by country code.
Implements #5960.
---
src/org/torproject/onionoo/CurrentNodes.java | 22 ++++++---
src/org/torproject/onionoo/Node.java | 4 +-
src/org/torproject/onionoo/ResourceServlet.java | 56 ++++++++++++++++++++++-
web/index.html | 5 ++
4 files changed, 78 insertions(+), 9 deletions(-)
diff --git a/src/org/torproject/onionoo/CurrentNodes.java b/src/org/torproject/onionoo/CurrentNodes.java
index 74879af..63fb8c6 100644
--- a/src/org/torproject/onionoo/CurrentNodes.java
+++ b/src/org/torproject/onionoo/CurrentNodes.java
@@ -71,9 +71,13 @@ public class CurrentNodes {
if (parts.length > 9) {
consensusWeight = Long.parseLong(parts[9]);
}
+ String countryCode = "??";
+ if (parts.length > 10) {
+ countryCode = parts[10];
+ }
this.addRelay(nickname, fingerprint, address,
validAfterMillis, orPort, dirPort, relayFlags,
- consensusWeight);
+ consensusWeight, countryCode);
} else if (line.startsWith("b ")) {
String[] parts = line.split(" ");
if (parts.length < 9) {
@@ -136,9 +140,11 @@ public class CurrentNodes {
String relayFlags = sb.toString().substring(1);
String consensusWeight = String.valueOf(
entry.getConsensusWeight());
+ String countryCode = entry.getCountryCode() != null
+ ? entry.getCountryCode() : "??";
bw.write("r " + nickname + " " + fingerprint + " " + address + " "
+ validAfter + " " + orPort + " " + dirPort + " " + relayFlags
- + " " + consensusWeight + "\n");
+ + " " + consensusWeight + " " + countryCode + "\n");
}
for (Node entry : this.currentBridges.values()) {
String nickname = entry.getNickname();
@@ -155,7 +161,7 @@ public class CurrentNodes {
String relayFlags = sb.toString().substring(1);
bw.write("b " + nickname + " " + fingerprint + " " + address + " "
+ published + " " + orPort + " " + dirPort + " " + relayFlags
- + " -1\n");
+ + " -1 ??\n");
}
bw.close();
} catch (IOException e) {
@@ -214,19 +220,21 @@ public class CurrentNodes {
SortedSet<String> relayFlags = entry.getFlags();
long consensusWeight = entry.getBandwidth();
this.addRelay(nickname, fingerprint, address, validAfterMillis,
- orPort, dirPort, relayFlags, consensusWeight);
+ orPort, dirPort, relayFlags, consensusWeight, null);
}
}
public void addRelay(String nickname, String fingerprint,
String address, long validAfterMillis, int orPort, int dirPort,
- SortedSet<String> relayFlags, long consensusWeight) {
+ SortedSet<String> relayFlags, long consensusWeight,
+ String countryCode) {
if (validAfterMillis >= cutoff &&
(!this.currentRelays.containsKey(fingerprint) ||
this.currentRelays.get(fingerprint).getLastSeenMillis() <
validAfterMillis)) {
Node entry = new Node(nickname, fingerprint, address,
- validAfterMillis, orPort, dirPort, relayFlags, consensusWeight);
+ validAfterMillis, orPort, dirPort, relayFlags, consensusWeight,
+ countryCode);
this.currentRelays.put(fingerprint, entry);
if (validAfterMillis > this.lastValidAfterMillis) {
this.lastValidAfterMillis = validAfterMillis;
@@ -333,7 +341,7 @@ public class CurrentNodes {
this.currentBridges.get(fingerprint).getLastSeenMillis() <
publishedMillis)) {
Node entry = new Node(nickname, fingerprint, address,
- publishedMillis, orPort, dirPort, relayFlags, -1L);
+ publishedMillis, orPort, dirPort, relayFlags, -1L, null);
this.currentBridges.put(fingerprint, entry);
if (publishedMillis > this.lastPublishedMillis) {
this.lastPublishedMillis = publishedMillis;
diff --git a/src/org/torproject/onionoo/Node.java b/src/org/torproject/onionoo/Node.java
index b7bc126..887a600 100644
--- a/src/org/torproject/onionoo/Node.java
+++ b/src/org/torproject/onionoo/Node.java
@@ -31,7 +31,8 @@ public class Node {
private boolean running;
public Node(String nickname, String fingerprint, String address,
long lastSeenMillis, int orPort, int dirPort,
- SortedSet<String> relayFlags, long consensusWeight) {
+ SortedSet<String> relayFlags, long consensusWeight,
+ String countryCode) {
this.nickname = nickname;
this.fingerprint = fingerprint;
try {
@@ -47,6 +48,7 @@ public class Node {
this.dirPort = dirPort;
this.relayFlags = relayFlags;
this.consensusWeight = consensusWeight;
+ this.countryCode = countryCode;
}
public String getFingerprint() {
return this.fingerprint;
diff --git a/src/org/torproject/onionoo/ResourceServlet.java b/src/org/torproject/onionoo/ResourceServlet.java
index e821500..8744150 100644
--- a/src/org/torproject/onionoo/ResourceServlet.java
+++ b/src/org/torproject/onionoo/ResourceServlet.java
@@ -47,6 +47,8 @@ public class ResourceServlet extends HttpServlet {
private Map<String, String>
relayFingerprintSummaryLines = new HashMap<String, String>(),
bridgeFingerprintSummaryLines = new HashMap<String, String>();
+ private Map<String, Set<String>> relaysByCountryCode =
+ new HashMap<String, Set<String>>();
private void readSummaryFile() {
if (!summaryFile.exists()) {
readSummaryFile = false;
@@ -75,6 +77,16 @@ public class ResourceServlet extends HttpServlet {
consensusWeight, fingerprint));
orderRelaysByConsensusWeight.add(String.format("%020d %s",
consensusWeight, hashedFingerprint));
+ String countryCode = entry.getCountryCode();
+ if (countryCode == null) {
+ countryCode = "??";
+ }
+ if (!this.relaysByCountryCode.containsKey(countryCode)) {
+ this.relaysByCountryCode.put(countryCode,
+ new HashSet<String>());
+ }
+ this.relaysByCountryCode.get(countryCode).add(fingerprint);
+ this.relaysByCountryCode.get(countryCode).add(hashedFingerprint);
}
Collections.sort(orderRelaysByConsensusWeight);
this.relaysByConsensusWeight = new ArrayList<String>();
@@ -178,7 +190,8 @@ public class ResourceServlet extends HttpServlet {
/* Make sure that the request doesn't contain any unknown
* parameters. */
Set<String> knownParameters = new HashSet<String>(Arrays.asList(
- "type,running,search,lookup,order,limit,offset".split(",")));
+ "type,running,search,lookup,country,order,limit,offset".
+ split(",")));
for (String parameterKey : parameterMap.keySet()) {
if (!knownParameters.contains(parameterKey)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
@@ -235,6 +248,16 @@ public class ResourceServlet extends HttpServlet {
this.filterByFingerprint(filteredRelays, filteredBridges,
fingerprint);
}
+ if (parameterMap.containsKey("country")) {
+ String countryCodeParameter = this.parseCountryCodeParameter(
+ parameterMap.get("country"));
+ if (countryCodeParameter == null) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ this.filterByCountryCode(filteredRelays, filteredBridges,
+ countryCodeParameter);
+ }
/* Re-order and limit results. */
List<String> orderedRelays = new ArrayList<String>();
@@ -389,6 +412,15 @@ public class ResourceServlet extends HttpServlet {
return parameter;
}
+ private static Pattern countryCodeParameterPattern =
+ Pattern.compile("^[0-9a-zA-Z]{2}$");
+ private String parseCountryCodeParameter(String parameter) {
+ if (!countryCodeParameterPattern.matcher(parameter).matches()) {
+ return null;
+ }
+ return parameter;
+ }
+
private void filterByType(Map<String, String> filteredRelays,
Map<String, String> filteredBridges, boolean relaysRequested) {
if (relaysRequested) {
@@ -502,6 +534,28 @@ public class ResourceServlet extends HttpServlet {
}
}
+ private void filterByCountryCode(Map<String, String> filteredRelays,
+ Map<String, String> filteredBridges, String countryCodeParameter) {
+ String countryCode = countryCodeParameter.toLowerCase();
+ if (!this.relaysByCountryCode.containsKey(countryCode)) {
+ filteredRelays.clear();
+ } else {
+ Set<String> relaysWithCountryCode =
+ this.relaysByCountryCode.get(countryCode);
+ Set<String> removeRelays = new HashSet<String>();
+ for (Map.Entry<String, String> e : filteredRelays.entrySet()) {
+ String fingerprint = e.getKey();
+ if (!relaysWithCountryCode.contains(fingerprint)) {
+ removeRelays.add(fingerprint);
+ }
+ }
+ for (String fingerprint : removeRelays) {
+ filteredRelays.remove(fingerprint);
+ }
+ }
+ filteredBridges.clear();
+ }
+
private void writeRelays(List<String> relays, PrintWriter pw,
String resourceType) {
pw.write("{\"relays_published\":\"" + this.relaysPublishedString
diff --git a/web/index.html b/web/index.html
index 5ea7743..589d347 100755
--- a/web/index.html
+++ b/web/index.html
@@ -623,6 +623,11 @@ Fingerprints should always be hashed using SHA-1, regardless of looking up
a relay or a bridge, in order to not accidentally leak non-hashed bridge
fingerprints in the URL.
</td></tr>
+<tr><td><b><font color="blue">country</font></b></td><td>Return only
+relays which are located in the given country as identified by a
+two-letter lower-case country code.
+<font color="blue">Added parameter on June 14, 2012.</font>
+</td></tr>
</table>
<p>Relay and/or bridge documents in the response can be ordered and
limited by providing further parameters.</p>
More information about the tor-commits
mailing list