使用C#在Tor中下载文件

3
我想使用Tor下载文件。大多数解决方案需要安装和运行其他软件(例如privoxy),但是我不想在我不使用程序时一直运行其他软件。
因此,我尝试了Tor.NET库,但我无法使用Tor获取它。这个示例不应返回我的IP地址,但它确实返回了。
ClientCreateParams createParams = new ClientCreateParams(@"D:\tor.exe", 9051);
Client client = Client.Create(createParams);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.icanhazip.com/");
request.Proxy = client.Proxy.WebProxy;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    var reader = new StreamReader(response.GetResponseStream());
    Console.WriteLine(reader.ReadToEnd());
}

Console.WriteLine("Press enter to exit...");
Console.ReadLine();

已经有多个关于此的评论了,但不幸的是该库的作者已经不再活跃。

也许您知道我做错了什么(是否需要更多配置?)或者有一个使用tor下载文件的替代方法的想法。


1
你应该考虑使用除C#之外的其他工具。像Python这样的脚本语言有Tor友好库。如果你想尝试在C#中实现,可以使用一个简单的httpwebrequest库,但是要传递一个代理参数为127.0.0.1、socks5和端口9050(取决于你的本地torrc文件)。如果你查看这里,问题中有一些代码可以帮助你开始。 - james-see
2个回答

6

您可以按照Tor项目手册中的指导,使用命令行HTTPTunnelPort,该手册可以在这里找到:首先,您需要使用以下命令启动HTTP隧道:

Tor.exe --HTTPTunnelPort 4711

它为您提供了一个HTTP隧道,位于127.0.0.1:4711(也可以参考此处)。现在您可以连接到这个代理:
WebProxy oWebProxy = new WebProxy (IPAddress.Loopback.ToString (), 4711);
WebClient oWebClient = new WebClient ();
oWebClient.Proxy = oWebProxy;
oWebClient.DownloadFile ("https://myUri", "myFilename");

到现在为止,微软建议在新开发中使用HttpClient。以下是代码:

// we must configure the HttpClient
HttpClientHandler oHttpClientHandler = new HttpClientHandler ();
oHttpClientHandler.UseProxy = true;
oHttpClientHandler.Proxy = 
  new WebProxy (IPAddress.Loopback.ToString (), 4711);
// we start an HttpClient with the handler; Microsoft recommends to start
// one HttpClient per application
HttpClient oHttpClient = new HttpClient (oHttpClientHandler);
// we request the resource by the GET method
HttpRequestMessage oHttpRequestMessage = 
  new HttpRequestMessage (HttpMethod.Get, "https://myUri");
// we make the request and we do only wait for the headers and not for
// content
Task<HttpResponseMessage> 
  oTaskSendAsync = 
    oHttpClient.SendAsync 
      (oHttpRequestMessage, HttpCompletionOption.ResponseHeadersRead);
// we wait for the arrival of the headers
oTaskSendAsync.Wait ();
// the function throws an exception if something went wrong
oTaskSendAsync.Result.EnsureSuccessStatusCode ();
// we can act on the returned headers
HttpResponseHeaders oResponseHeaders = oTaskSendAsync.Result.Headers;
HttpContentHeaders  oContentHeaders  = oTaskSendAsync.Result.Content.Headers;
// we fetch the content stream
Task<Stream> oTaskResponseStream = 
    oTaskSendAsync.Result.Content.ReadAsStreamAsync ();
// we open a file for the download data
FileStream oFileStream = File.OpenWrite ("myFilename");
// we delegate the copying of the content to the file
Task oTaskCopyTo = oTaskResponseStream.Result.CopyToAsync (oFileStream);
// and wait for its completion
oTaskCopyTo.Wait ();
// now we can close the file
oFileStream.Close ();

请注意使用Tor.exe的以下事项:
  • 如果端口已经被占用,Tor.exe将无法提供代理。它甚至不一定会通知您此故障。
  • 确保没有人欺骗您的程序,让Tor为您提供此代理。因此,Tor.exe应该在您的文件系统中处于安全位置。
  • 了解有关使用Tor的其他预防措施。

至少,您可能希望检查您的代理是否具有与本地互联网连接不同的IP地址。


请注意,至少对我来说,这仅适用于 https-URI,而不是 http。HTTP请求会导致 405 Method Not Allowed 错误。 - user3817008

0
最后我使用了https://github.com/Ogglas/SocksWebProxy@Ogglas下载一个使用Tor的文件。
该项目有一个示例,不起作用(第一次启动时它会无限期地等待Tor退出,但当您再次启动程序时,它可以使用Tor进程开始您的第一次尝试),所以我进行了更改。
我制作了一个Start()方法来启动Tor:
public async void Start(IProgress<int> progress)
{
    torProcess = new Process();
    torProcess.StartInfo.FileName = @"D:\...\tor.exe";
    torProcess.StartInfo.Arguments = @"-f ""D:\...\torrc""";
    torProcess.StartInfo.UseShellExecute = false;
    torProcess.StartInfo.RedirectStandardOutput = true;
    torProcess.StartInfo.CreateNoWindow = true;
    torProcess.Start();
    var reader = torProcess.StandardOutput;
    while (true)
    {
        var line = await reader.ReadLineAsync();
        if (line == null)
        {
            // EOF
            Environment.Exit(0);
        }
        // Get loading status
        foreach (Match m in Regex.Matches(line, @"Bootstrapped (\d+)%"))
        {
            progress.Report(Convert.ToInt32(m.Groups[1].Value));
        }

        if (line.Contains("100%: Done"))
        {
            // Tor loaded
            break;
        }
        if (line.Contains("Is Tor already running?"))
        {
            // Tor already running
            break;
        }
    }

    proxy = new SocksWebProxy(new ProxyConfig(
        //This is an internal http->socks proxy that runs in process
        IPAddress.Parse("127.0.0.1"),
        //This is the port your in process http->socks proxy will run on
        12345,
        //This could be an address to a local socks proxy (ex: Tor / Tor Browser, If Tor is running it will be on 127.0.0.1)
        IPAddress.Parse("127.0.0.1"),
        //This is the port that the socks proxy lives on (ex: Tor / Tor Browser, Tor is 9150)
        9150,
        //This Can be Socks4 or Socks5
        ProxyConfig.SocksVersion.Five
    ));
    progress.Report(100);
}

之后,您可以使用类似以下的代码来下载某些内容:

public static string DownloadString(string url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Proxy = proxy;
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        return new StreamReader(response.GetResponseStream()).ReadToEnd();
    }
}

当你退出程序时,你也应该终止Tor进程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接