Я пишу инструмент, который позволяет пользователю вводить URL-адрес, на который реагирует программа, пытаясь показать значок этого веб-сайта. У меня это работает для многих сайтов, но один сайт, который вызывает у меня проблемы, - это мой собственный сайт Trac. Похоже, что нормальное поведение Trac до тех пор, пока конечный пользователь не будет настроен, должен показать пользовательскую страницу 403 (Forbidden), пригласив пользователя войти в систему. Доступ к Trac из веб-браузера означает, что значок отображается на вкладке браузера, хотя я 'm не вошел в систему (и Firebug, например, показывает 403 для содержимого страницы). Если я просматриваю исходный код в браузере, местоположение favicon находится прямо в источнике. Однако из моего приложения, запрашивающего веб-сайт Trac с request.GetResponse()
, выдает WebException
, содержащий 403, что не дает мне возможности прочитать поток ответов, содержащий жизненно важную информацию, необходимую для поиска значка.Как получить значок с страницы 403
У меня уже есть код для загрузки HTML-кода веб-сайта и извлечения его значка. То, что я застрял в загрузке HTML на сайт, даже если он отвечает 403.
я играл с различными UserAgent
, Accept
и AcceptLanguage
свойства HttpWebRequest
объекта, но это не помогло. Я также пробовал использовать любые переадресации, когда я читал где-то, что .NET не делает их хорошо. Еще не повезло.
Вот что у меня есть:
public static MemoryStream DownloadHtml(
string urlParam,
int timeoutMs = DefaultHttpRequestTimeoutMs,
string userAgent = "",
bool silent = false
)
{
MemoryStream result = null;
HttpWebRequest request = null;
HttpWebResponse response = null;
try
{
Func<string, HttpWebRequest> createRequest = (urlForFunc) =>
{
var requestForAction = (HttpWebRequest)HttpWebRequest.Create(urlForFunc);
// This step is now required by Wikipedia (and others?) to prevent periodic or
// even constant 403's (Forbidden).
requestForAction.UserAgent = userAgent;
requestForAction.Accept = "text/html";
requestForAction.AllowAutoRedirect = false;
requestForAction.Timeout = timeoutMs;
return requestForAction;
};
string urlFromResponse = "";
string urlForRequest = "";
do
{
if(response == null)
{
urlForRequest = urlParam;
}
else
{
urlForRequest = urlFromResponse;
response.Close();
}
request = createRequest(urlForRequest);
response = (HttpWebResponse)request.GetResponse();
urlFromResponse = response.Headers[HttpResponseHeader.Location];
}
while(urlFromResponse != null
&& urlFromResponse.Length > 0
&& urlFromResponse != urlForRequest);
using(var stream = response.GetResponseStream())
{
result = new MemoryStream();
stream.CopyTo(result);
}
}
catch(WebException ex)
{
// Things like 404 and, well, all other web-type exceptions.
Debug.WriteLine(ex.Message);
if(ex.InnerException != null) Debug.WriteLine(ex.InnerException.Message);
}
catch(System.Threading.ThreadAbortException)
{
// Let ac.Thread handle some cleanup.
throw;
}
catch(Exception)
{
if(!silent) throw;
}
finally
{
if(response != null) response.Close();
}
return result;
}
Право в порядке исключения, стрелять! Одно место я не смотрел, включая его документы. Спасибо! –