WebClient не загружает нужный файл с предоставленного URL
Я хочу загрузить файл.torrent из дистрибутива Linux, но по какой-то причине окончательный файл, загруженный из моего приложения, отличается от того, который был загружен вручную. Тот, который загружает мое приложение, имеет 31 КБ, и это недопустимый файл.torrent, в то время как правый (когда я загружаю вручную) имеет 41 КБ, и он действителен.
URL из файла, который я хочу загрузить: http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent
Почему это происходит и как я могу загрузить один и тот же файл (действительный, размером 41 КБ)?
Благодарю.
Код C# из метода, который загружает файл выше:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (System.Net.WebClient wc = new System.Net.WebClient())
{
var path = @"D:\Baixar automaticamente"; // HACK Pegar isso dos settings na versão final
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = null;
// Try to extract the filename from the Content-Disposition header
if (!string.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"]))
{
fileName = wc.ResponseHeaders["Content-Disposition"].Substring(wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 10).Replace("\"", "");
}
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro");
if (File.Exists(torrentPath))
{
File.Delete(torrentPath);
}
Helper.Retry(() => wc.DownloadFile(new Uri(sLinkTorCache), torrentPath), TimeSpan.FromSeconds(3), 5);
}
Helper.Retry (Попробуйте выполнить метод еще раз в случае исключений HTTP):
public static void Retry(Action action, TimeSpan retryInterval, int retryCount = 3)
{
Retry<object>(() =>
{
action();
return null;
}, retryInterval, retryCount);
}
public static T Retry<T>(Func<T> action, TimeSpan retryInterval, int retryCount = 3)
{
var exceptions = new List<Exception>();
for (int retry = 0; retry < retryCount; retry++)
{
try
{
if (retry > 0)
System.Threading.Thread.Sleep(retryInterval); // TODO adicionar o Using pro thread
return action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
1 ответ
Сначала я думал, что сайт отвечает нежелательной почтой, если считает, что это запрос от бота (то есть он проверяет некоторые заголовки). После просмотра с Fiddler - кажется, что возвращенные данные абсолютно одинаковы как для веб-браузера, так и для кода. Это означает, что мы должным образом не дефлируем (извлекаем) ответ. Веб-серверы очень часто сжимают данные (используя что-то вроде gzip). WebClient
не автоматически выкачивает данные.
Используя ответ из Автоматической распаковки ответа gzip через WebClient.DownloadData - мне удалось заставить его работать должным образом.
Также обратите внимание, что вы скачиваете файл дважды. Вам не нужно это делать.
Рабочий код:
//Taken from above linked question
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
И используя это:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (var wc = new MyWebClient())
{
var path = @"C:\Junk";
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = "";
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro.torrent");
if (File.Exists(torrentPath))
File.Delete(torrentPath);
File.WriteAllBytes(torrentPath, data);
}