[tor-commits] [metrics-lib/master] Implement bridge network status parsing.
karsten at torproject.org
karsten at torproject.org
Thu Jan 12 09:23:03 UTC 2012
commit d5ffbee290e55423e143e6eb558f2647e28b5d6a
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Thu Jan 12 09:29:11 2012 +0100
Implement bridge network status parsing.
---
.../impl/BridgeDescriptorReaderImpl.java | 85 ++++++++++++++++++--
.../descriptor/impl/BridgeNetworkStatusImpl.java | 75 +++++++++++++++++
.../torproject/descriptor/impl/DescriptorImpl.java | 30 +++++++
3 files changed, 183 insertions(+), 7 deletions(-)
diff --git a/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java b/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java
index 09f422c..04e5d2a 100644
--- a/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java
+++ b/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java
@@ -2,34 +2,105 @@
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Stack;
+import org.torproject.descriptor.Descriptor;
import org.torproject.descriptor.DescriptorFile;
import org.torproject.descriptor.BridgeDescriptorReader;
-public class BridgeDescriptorReaderImpl implements BridgeDescriptorReader {
+public class BridgeDescriptorReaderImpl
+ implements BridgeDescriptorReader {
+ private List<File> directories = new ArrayList<File>();
public void addDirectory(File directory) {
- /* TODO Implement me. */
+ this.directories.add(directory);
}
public void setExcludeFile(File fileToExclude) {
+ throw new UnsupportedOperationException("Not implemented yet.");
/* TODO Implement me. */
}
public void setExcludeFiles(Set<File> filesToExclude) {
+ throw new UnsupportedOperationException("Not implemented yet.");
/* TODO Implement me. */
}
- public void setInitialCacheLimit(long cacheLimitBytes) {
- /* TODO Implement me. */
+ public Iterator<DescriptorFile> readDescriptors() {
+ BlockingIteratorImpl<DescriptorFile> descriptorQueue =
+ new BlockingIteratorImpl<DescriptorFile>();
+ DescriptorReader reader = new DescriptorReader(this.directories,
+ descriptorQueue);
+ new Thread(reader).start();
+ return descriptorQueue;
}
- public Iterator<DescriptorFile> readDescriptors() {
- /* TODO Implement me. */
- return new BlockingIteratorImpl<DescriptorFile>();
+ private static class DescriptorReader implements Runnable {
+ private List<File> directories;
+ private BlockingIteratorImpl<DescriptorFile> descriptorQueue;
+ private DescriptorReader(List<File> directories,
+ BlockingIteratorImpl<DescriptorFile> descriptorQueue) {
+ this.directories = directories;
+ this.descriptorQueue = descriptorQueue;
+ }
+ public void run() {
+ for (File directory : this.directories) {
+ try {
+ Stack<File> files = new Stack<File>();
+ files.add(directory);
+ while (!files.isEmpty()) {
+ File file = files.pop();
+ if (file.isDirectory()) {
+ files.addAll(Arrays.asList(file.listFiles()));
+ } else {
+ try {
+ List<Descriptor> parsedDescriptors = this.readFile(file);
+ DescriptorFileImpl descriptorFile =
+ new DescriptorFileImpl();
+ descriptorFile.setDirectory(directory);
+ descriptorFile.setFile(file);
+ descriptorFile.setLastModified(file.lastModified());
+ descriptorFile.setDescriptors(parsedDescriptors);
+ this.descriptorQueue.add(descriptorFile);
+ } catch (DescriptorParseException e) {
+ /* TODO Handle me. */
+ }
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("Error while reading descriptors in '"
+ + directory.getAbsolutePath() + "'.");
+ /* TODO Handle this exception somehow. */
+ } finally {
+ this.descriptorQueue.setOutOfDescriptors();
+ }
+ }
+ }
+ private List<Descriptor> readFile(File file) throws IOException,
+ DescriptorParseException {
+ FileInputStream fis = new FileInputStream(file);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int len;
+ byte[] data = new byte[1024];
+ while ((len = bis.read(data, 0, 1024)) >= 0) {
+ baos.write(data, 0, len);
+ }
+ bis.close();
+ byte[] rawDescriptorBytes = baos.toByteArray();
+ return DescriptorImpl.parseBridgeDescriptors(rawDescriptorBytes,
+ file.getName());
+ }
}
}
diff --git a/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java b/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
new file mode 100644
index 0000000..714f6ae
--- /dev/null
+++ b/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
@@ -0,0 +1,75 @@
+/* Copyright 2012 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor.impl;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+import org.torproject.descriptor.BridgeNetworkStatus;
+
+/* Contains a bridge network status. */
+public class BridgeNetworkStatusImpl extends NetworkStatusImpl
+ implements BridgeNetworkStatus {
+
+ protected BridgeNetworkStatusImpl(byte[] statusBytes,
+ String fileName) throws DescriptorParseException {
+ super(statusBytes);
+ this.setPublishedMillisFromFileName(fileName);
+ }
+
+ private static SimpleDateFormat fileNameFormat = new SimpleDateFormat(
+ "yyyyMMdd-HHmmss");
+ static {
+ fileNameFormat.setLenient(false);
+ fileNameFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ private void setPublishedMillisFromFileName(String fileName)
+ throws DescriptorParseException {
+ if (fileName.length() ==
+ "20000101-000000-4A0CCD2DDC7995083D73F5D667100C8A5831F16D".
+ length()) {
+ String publishedString = fileName.substring(0,
+ "yyyyMMdd-HHmmss".length());
+ try {
+ this.publishedMillis = fileNameFormat.parse(publishedString).
+ getTime();
+ } catch (ParseException e) {
+ }
+ }
+ if (this.publishedMillis == 0L) {
+ throw new DescriptorParseException("Unrecognized bridge network "
+ + "status file name '" + fileName + "'.");
+ }
+ }
+
+ protected void parseHeader(byte[] headerBytes)
+ throws DescriptorParseException {
+ throw new DescriptorParseException("No directory header expected in "
+ + "bridge network status.");
+ }
+
+ protected void parseDirSource(byte[] dirSourceBytes)
+ throws DescriptorParseException {
+ throw new DescriptorParseException("No directory source expected in "
+ + "bridge network status.");
+ }
+
+ protected void parseFooter(byte[] footerBytes)
+ throws DescriptorParseException {
+ throw new DescriptorParseException("No directory footer expected in "
+ + "bridge network status.");
+ }
+
+ protected void parseDirectorySignature(byte[] directorySignatureBytes)
+ throws DescriptorParseException {
+ throw new DescriptorParseException("No directory signature expected "
+ + "in bridge network status.");
+ }
+
+ private long publishedMillis;
+ public long getPublishedMillis() {
+ return this.publishedMillis;
+ }
+}
+
diff --git a/src/org/torproject/descriptor/impl/DescriptorImpl.java b/src/org/torproject/descriptor/impl/DescriptorImpl.java
index cade4cf..24c1fe9 100644
--- a/src/org/torproject/descriptor/impl/DescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/DescriptorImpl.java
@@ -51,6 +51,36 @@ public abstract class DescriptorImpl implements Descriptor {
return parsedDescriptors;
}
+ protected static List<Descriptor> parseBridgeDescriptors(
+ byte[] rawDescriptorBytes, String fileName)
+ throws DescriptorParseException {
+ List<Descriptor> parsedDescriptors = new ArrayList<Descriptor>();
+ byte[] first100Chars = new byte[Math.min(100,
+ rawDescriptorBytes.length)];
+ System.arraycopy(rawDescriptorBytes, 0, first100Chars, 0,
+ first100Chars.length);
+ String firstLines = new String(first100Chars);
+ if (firstLines.startsWith("r ")) {
+ parsedDescriptors.add(new BridgeNetworkStatusImpl(
+ rawDescriptorBytes, fileName));
+ } else if (firstLines.startsWith("router ") ||
+ firstLines.contains("\nrouter ")) {
+ /* TODO Implement me.
+ parsedDescriptors.addAll(BridgeServerDescriptorImpl.
+ parseDescriptors(rawDescriptorBytes)); */
+ } else if (firstLines.startsWith("extra-info ") ||
+ firstLines.contains("\nextra-info ")) {
+ /* TODO Implement me.
+ parsedDescriptors.addAll(BridgeExtraInfoDescriptorImpl.
+ parseDescriptors(rawDescriptorBytes)); */
+ } else {
+ throw new DescriptorParseException("Could not detect bridge "
+ + "descriptor type in descriptor starting with '" + firstLines
+ + "'.");
+ }
+ return parsedDescriptors;
+ }
+
protected static List<byte[]> splitRawDescriptorBytes(
byte[] rawDescriptorBytes, String startToken) {
List<byte[]> rawDescriptors = new ArrayList<byte[]>();
More information about the tor-commits
mailing list