Package com.subgraph.orchid.directory.downloader

Source Code of com.subgraph.orchid.directory.downloader.DirectoryDocumentRequestor

package com.subgraph.orchid.directory.downloader;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import com.subgraph.orchid.CircuitManager;
import com.subgraph.orchid.ConsensusDocument;
import com.subgraph.orchid.ConsensusDocument.RequiredCertificate;
import com.subgraph.orchid.DirectoryCircuit;
import com.subgraph.orchid.KeyCertificate;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.RouterDescriptor;
import com.subgraph.orchid.RouterMicrodescriptor;
import com.subgraph.orchid.Stream;
import com.subgraph.orchid.StreamConnectFailedException;
import com.subgraph.orchid.Tor;
import com.subgraph.orchid.circuits.TorInitializationTracker;
import com.subgraph.orchid.data.HexDigest;

/**
* Synchronously downloads directory documents.
*/
public class DirectoryDocumentRequestor {
  private final static int OPEN_DIRECTORY_STREAM_TIMEOUT = 10 * 1000;
 
  private final DirectoryCircuit circuit;
  private final TorInitializationTracker initializationTracker;
 
 
  public DirectoryDocumentRequestor(DirectoryCircuit circuit) {
    this(circuit, null);
  }

  public DirectoryDocumentRequestor(DirectoryCircuit circuit, TorInitializationTracker initializationTracker) {
    this.circuit = circuit;
    this.initializationTracker = initializationTracker;
  }

  public RouterDescriptor downloadBridgeDescriptor(Router bridge) throws DirectoryRequestFailedException {
    return fetchSingleDocument(new BridgeDescriptorFetcher());
  }

  public ConsensusDocument downloadCurrentConsensus(boolean useMicrodescriptors) throws DirectoryRequestFailedException {
    return fetchSingleDocument(new ConsensusFetcher(useMicrodescriptors), CircuitManager.DIRECTORY_PURPOSE_CONSENSUS);
  }

  public List<KeyCertificate> downloadKeyCertificates(Set<RequiredCertificate> required) throws DirectoryRequestFailedException {
    return fetchDocuments(new CertificateFetcher(required), CircuitManager.DIRECTORY_PURPOSE_CERTIFICATES);
  }

  public List<RouterDescriptor> downloadRouterDescriptors(Set<HexDigest> fingerprints) throws DirectoryRequestFailedException {
    return fetchDocuments(new RouterDescriptorFetcher(fingerprints), CircuitManager.DIRECTORY_PURPOSE_DESCRIPTORS);
  }

  public List<RouterMicrodescriptor> downloadRouterMicrodescriptors(Set<HexDigest> fingerprints) throws DirectoryRequestFailedException  {
    return fetchDocuments(new MicrodescriptorFetcher(fingerprints), CircuitManager.DIRECTORY_PURPOSE_DESCRIPTORS);
  }
 
  private <T> T fetchSingleDocument(DocumentFetcher<T> fetcher) throws DirectoryRequestFailedException {
    return fetchSingleDocument(fetcher, 0);
  }

  private <T> T fetchSingleDocument(DocumentFetcher<T> fetcher, int purpose) throws DirectoryRequestFailedException {
    final List<T> result = fetchDocuments(fetcher, purpose);
    if(result.size() == 1) {
      return result.get(0);
    }
    return null;
  }
 
  private <T> List<T> fetchDocuments(DocumentFetcher<T> fetcher, int purpose) throws DirectoryRequestFailedException {
    try {
      final HttpConnection http = createHttpConnection(purpose);
      try {
        return fetcher.requestDocuments(http);
      } finally {
        http.close();
      }
    } catch (TimeoutException e) {
      throw new DirectoryRequestFailedException("Directory request timed out");
    } catch (StreamConnectFailedException e) {
      throw new DirectoryRequestFailedException("Failed to open directory stream", e);
    } catch (IOException e) {
      throw new DirectoryRequestFailedException("I/O exception processing directory request", e);
    } catch (InterruptedException e) {
      throw new DirectoryRequestFailedException("Directory request interrupted");
    }
  }
 
  private HttpConnection createHttpConnection(int purpose) throws InterruptedException, TimeoutException, StreamConnectFailedException {
    return new HttpConnection(openDirectoryStream(purpose));
  }

  private Stream openDirectoryStream(int purpose) throws InterruptedException, TimeoutException, StreamConnectFailedException {
    final int requestEventCode = purposeToEventCode(purpose, false);
    final int loadingEventCode = purposeToEventCode(purpose, true);
   
    notifyInitialization(requestEventCode);

    final Stream stream = circuit.openDirectoryStream(OPEN_DIRECTORY_STREAM_TIMEOUT, true);
    notifyInitialization(loadingEventCode);
    return stream;
  }
 
  private int purposeToEventCode(int purpose, boolean getLoadingEvent) {
    switch(purpose) {
    case CircuitManager.DIRECTORY_PURPOSE_CONSENSUS:
      return getLoadingEvent ? Tor.BOOTSTRAP_STATUS_LOADING_STATUS : Tor.BOOTSTRAP_STATUS_REQUESTING_STATUS;
    case CircuitManager.DIRECTORY_PURPOSE_CERTIFICATES:
       return getLoadingEvent ? Tor.BOOTSTRAP_STATUS_LOADING_KEYS : Tor.BOOTSTRAP_STATUS_REQUESTING_KEYS;
    case CircuitManager.DIRECTORY_PURPOSE_DESCRIPTORS:
      return getLoadingEvent ? Tor.BOOTSTRAP_STATUS_LOADING_DESCRIPTORS : Tor.BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS;
    default:
      return 0;
    }
  }
 
  private void notifyInitialization(int code) {
    if(code > 0 && initializationTracker != null) {
      initializationTracker.notifyEvent(code);
    }
  }
}
TOP

Related Classes of com.subgraph.orchid.directory.downloader.DirectoryDocumentRequestor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.