Я работаю над проверкой ссылок, в целом я могу выполнять запросы HEAD
, однако некоторые сайты, похоже, отключают эту команду, поэтому в случае неудачи мне также нужно выполнить запрос GET
(чтобы убедиться, что ссылка действительно мертва)
Я использую следующий код в качестве тестера ссылок:
public class ValidateResult
{
public HttpStatusCode? StatusCode { get; set; }
public Uri RedirectResult { get; set; }
public WebExceptionStatus? WebExceptionStatus { get; set; }
}
public ValidateResult Validate(Uri uri, bool useHeadMethod = true,
bool enableKeepAlive = false, int timeoutSeconds = 30)
{
ValidateResult result = new ValidateResult();
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
if (useHeadMethod)
{
request.Method = "HEAD";
}
else
{
request.Method = "GET";
}
// always compress, if you get back a 404 from a HEAD it can be quite big.
request.AutomaticDecompression = DecompressionMethods.GZip;
request.AllowAutoRedirect = false;
request.UserAgent = UserAgentString;
request.Timeout = timeoutSeconds * 1000;
request.KeepAlive = enableKeepAlive;
HttpWebResponse response = null;
try
{
response = request.GetResponse() as HttpWebResponse;
result.StatusCode = response.StatusCode;
if (response.StatusCode == HttpStatusCode.Redirect ||
response.StatusCode == HttpStatusCode.MovedPermanently ||
response.StatusCode == HttpStatusCode.SeeOther)
{
try
{
Uri targetUri = new Uri(Uri, response.Headers["Location"]);
var scheme = targetUri.Scheme.ToLower();
if (scheme == "http" || scheme == "https")
{
result.RedirectResult = targetUri;
}
else
{
// this little gem was born out of http://tinyurl.com/18r
// redirecting to about:blank
result.StatusCode = HttpStatusCode.SwitchingProtocols;
result.WebExceptionStatus = null;
}
}
catch (UriFormatException)
{
// another gem... people sometimes redirect to http://nonsense:port/yay
result.StatusCode = HttpStatusCode.SwitchingProtocols;
result.WebExceptionStatus = WebExceptionStatus.NameResolutionFailure;
}
}
}
catch (WebException ex)
{
result.WebExceptionStatus = ex.Status;
response = ex.Response as HttpWebResponse;
if (response != null)
{
result.StatusCode = response.StatusCode;
}
}
finally
{
if (response != null)
{
response.Close();
}
}
return result;
}
Все работает отлично, за исключением того, что когда я выполняю запрос GET
, весь загружается полезная нагрузка (я наблюдал это в wireshark)
Есть ли способ настроить базовый ServicePoint
или HttpWebRequest
так, чтобы тело ответа вообще не буферизировалось и не загружало тело ответа?
(Если бы я кодировал это вручную, я бы установил очень маленькое окно приема TCP, а затем перехватывал бы только достаточное количество пакетов для получения заголовков, прекращал бы подтверждение пакетов TCP, как только у меня есть е достаточно информации.)
для тех, кто интересуется, для чего это предназначено, я не хочу загружать 40k 404, когда я получаю 404, делать это в несколько сотен тысяч раз дорого в сети