estoy trabajando en un comprobador de enlaces, en general puedo realizar HEAD
solicitudes, sin embargo, algunos sitios parecen desactivar este verbo, por lo que en caso de fallo que necesito para llevar a cabo también una solicitud GET
(que vuelva a comprobar el enlace está realmente muerto)¿Cómo puedo realizar una solicitud GET sin descargar el contenido?
uso el siguiente código como mi probador enlace:
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;
}
todo esto funciona bien y dandy. Excepto que cuando realizo una solicitud GET
, toda la carga útil se descarga (vi esto en wireshark).
¿Hay alguna manera de configurar el ServicePoint
subyacente o la HttpWebRequest
no para amortiguar o la carga ansiosa el cuerpo de la respuesta en absoluto?
(Si estuviera codificación manual esta fijaría ventana realmente bajo la recepción de TCP, y sólo agarrar suficientes paquetes para obtener los encabezados, dejar de acking paquetes TCP, tan pronto como tengo suficiente información.)
para aquellos que se preguntan qué se pretende lograr, no quiero descargar un 40k 404 cuando obtengo un 404, hacerlo unos cientos de miles es caro en la red
Nota: aunque la codificación manual de la versión HTTP es bastante simple, la HTTPS me asusta un poco. (tal vez hay una biblioteca de sistema operativo que hace esto ya?) –
Pruebe una descarga parcial. Es posible descargar solo un rango con el rango http de rango. – rekire
@rekire 'Content-Range' puede estar bien para los servidores HTTP 1.1 que tienen el contenido, pero si obtiene un 404, todavía se lo devolverá por completo –