Searching by host name is currently not supported, but it might be useful to add that. I could imagine supporting it by returning all host names ending with a given search term. For example, sampo.ru would return that relay and all others in the same domain. It would be a new qualified search term though, that is, one would have to search for it in Atlas like this: "hostname:sampo.ru".
This enhancement request originates from #10128 (moved) and has low priority.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related.
Learn more.
Simplify summary. (Considering whether something is a good idea or not is always part of a ticket.)
Trac: Summary: Consider adding support for searching by host name to Add support for searching by host name Sponsor: N/AtoN/A Reviewer: N/AtoN/A Severity: N/Ato Normal
How about we add a new parameter "host_name" with the following specification: "Return only relays with a domain name ending in the given (partial) host name. Filtering by host name is case-insensitive."
Aha, right, we should avoid confusions there. However, wouldn't we also have to encode domain names that we look up to punycode ourselves in order to say that? Could we limit this parameter to ASCII characters? Or would that be too much of a hack?
That would be (with new parts in italics): "Return only relays with a domain name ending in the given (partial) host name. Only ASCII characters are supported as host names. Filtering by host name is case-insensitive."
"ASCII characters in the Unicode string are represented literally, and non-ASCII characters are represented by ASCII characters that are allowed in host name labels (letters, digits, and hyphens)."
Okay, we're not doing anything with lookup responses, so let's say: "Return only relays with a domain name ending in the given (partial) host name. Non-ASCII host name characters must be encoded as punycode. Filtering by host name is case-insensitive." Please tweak as necessary! Thanks!
That description looks good to me functionally. (:
It might be useful to also add a tip to users:
To search only for subdomains of a specific domain, prefix your search string with a period, for example: "host_name:.csail.mit.edu".
Looks good! Rephrasing a tiny bit for uniform style and to avoid the ":" notation that is only used for qualified search terms:
"Return only relays with a domain name ending in the given (partial) host name. Searches for subdomains of a specific domain should ideally be prefixed with a period, for example: ".csail.mit.edu". Non-ASCII host name characters must be encoded as punycode. Filtering by host name is case-insensitive."
Obviously, feel free to use your description for Atlas where instructions are more user-facing and where qualified search terms are the only way to even use this parameter.
There are checkstyle complaints for the tests (line length and method names).
For SummayDocument the variables should be named correctly and instead of suppressing warnings using @SuppressWarnings("checkstyle:membername") the exposed values should be annotated (@Expose) and the @SerializedName should be defined. Of course, here only variable h was added, but this is a good time to overhaul all fields.
Rather use if(null == this.hostName) than if(this.hostName == null) (cf. RequestHandler).
Consider using Java8 idiom, for example:
--- a/src/main/java/org/torproject/onionoo/server/RequestHandler.java+++ b/src/main/java/org/torproject/onionoo/server/RequestHandler.java@@ -551,15 +551,12 @@ public class RequestHandler { } String hostName = this.hostName.toLowerCase(); Set<String> removeRelays = new HashSet<>(this.filteredRelays.keySet());- for (Map.Entry<String, Set<String>> e :- this.nodeIndex.getRelaysByHostName().entrySet()) {- if (e.getKey().endsWith(hostName)) {- removeRelays.removeAll(e.getValue());- }- }- for (String fingerprint : removeRelays) {- this.filteredRelays.remove(fingerprint);- }+ this.nodeIndex.getRelaysByHostName().entrySet().stream()+ .filter((mapEntry) -> mapEntry.getKey().endsWith(hostName))+ .forEach((mapEntry) -> removeRelays.removeAll(mapEntry.getValue()));+ removeRelays.stream()+ .forEach((fingerprint) -> this.filteredRelays.remove(fingerprint)); this.filteredBridges.clear(); }
(Again timeout for testCountryDeDe needed to be increased; weird, the stack trace is usually in a native method when the timeout occurs. Maybe, simply increase this timeout to 200ms?)
I'll work on the checkstyle complaints (oops!) and on renaming variables.
Regarding that Java 8 idiom, do you know whether it's possible to rewrite that to something that doesn't require a temporary data structure like removeRelays? Would be cool to simplify that code and related code in the same class even more.
I'll work on the checkstyle complaints (oops!) and on renaming variables.
Regarding that Java 8 idiom, do you know whether it's possible to rewrite that to something that doesn't require a temporary data structure like removeRelays? Would be cool to simplify that code and related code in the same class even more.
A simplification rather due to using the hostname from the summary doc than to j8:
diff --git a/src/main/java/org/torproject/onionoo/server/RequestHandler.java b/src/main/java/org/torproject/onionoo/server/RequestHandler.javaindex 23af60b..dd923d4 100644--- a/src/main/java/org/torproject/onionoo/server/RequestHandler.java+++ b/src/main/java/org/torproject/onionoo/server/RequestHandler.java@@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap;+import java.util.stream.Collectors; public class RequestHandler {@@ -550,16 +551,12 @@ public class RequestHandler { return; } String hostName = this.hostName.toLowerCase();- Set<String> removeRelays = new HashSet<>(this.filteredRelays.keySet());- for (Map.Entry<String, Set<String>> e :- this.nodeIndex.getRelaysByHostName().entrySet()) {- if (e.getKey().endsWith(hostName)) {- removeRelays.removeAll(e.getValue());- }- }- for (String fingerprint : removeRelays) {- this.filteredRelays.remove(fingerprint);- }+ this.filteredRelays+ .entrySet().retainAll(this.filteredRelays.entrySet().stream()+ .filter(entry+ -> null != entry.getValue().getHostName()+ && entry.getValue().getHostName().endsWith(hostName))+ .collect(Collectors.toSet())); this.filteredBridges.clear(); }
Hmm, can you rewrite that Java 8 snippet to something that uses the node index rather than iterate over all remaining SummaryDocuments? One reason is that it's potentially faster (otherwise we could as well drop the index entirely), and another reason is that even if it doesn't make a huge performance difference in this case, we could adapt the Java 8 approach more easily to the other methods in RequestHandler that do rely on the index.