Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: ошибки http  (Прочитано 15533 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Chuda
Гость
« : 26-03-2009 09:23 » 

очередной глупый вопрос от незнайки.
Задача всё та же: забрать страничку с сервера, дабы выполнить над ней некоторые действия.

Код:
String ipd = IdHTTP1->Get("http://servername.foo");

работает просто замечательно, пока сервер отвечает 200, и пока доступ в Интернет хороший.
Как только нет соединения, или сервер отвечает что-то типа 301, программа напрочь отказывается компилироваться.
Обработка исключений не помогает. Или я что-то не так делаю?

Код:
try {
String ipd = IdHTTP1->Get("http://servername.foo");
} catch(...) {
Memo1->Lines->Add("Sorry");
}

Как вот обработать ошибку?
Записан
zubr
Гость
« Ответ #1 : 26-03-2009 09:32 » 

Шильгия, причем здесь компиляция? Компиляция программы от качества соединения никаким образом не может зависеть. Предполагаю, что у тебя выскакивает исключение IDE BCB. То есть исключение в блоке try..catch обрабатывается, но в настройках среды не отключена функция дебагера "Останавливать при исключениях", поэтому если ты программу запускаешь из отладки (из IDE) то и выскакивает exception.
Записан
Chuda
Гость
« Ответ #2 : 26-03-2009 09:41 » 

zubr, я может что-то в специфике не понимаю.
Обычно этим не занимаюсь.
Вот как это выглядит:

Если нажать «Continue», то сообщение уходит… и более ничего. Всё остальное остаётся в таком же виде, как на скриншоте.
Записан
zubr
Гость
« Ответ #3 : 26-03-2009 12:40 » 

А в Memo1 текст "Sorry" появляется?
В меню BCB Tools->Options->Debagger Options->Codegear Debaggers->Language Exceptions сними галочку в чекбоксе "Notify on language exception"
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 26-03-2009 12:49 » 

Если мне не отшибло память, то редирект надо чуть посложней программить - получать ответ, вытаскивать новый URL и тд. Простыми http-запросами не обойтись. В VC++ конечно, как это там у Борланда не могу знать.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Гость
« Ответ #5 : 26-03-2009 14:07 » 

Джон, здесь все в компонент TIdHTTP зашито.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 26-03-2009 16:04 » 

Я так и думал.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Chuda
Гость
« Ответ #7 : 06-04-2009 14:31 » 

zubr, а как зашито?
когда редирект, приходит ответ 302.
TIdHTTP выпадает в exception. И там уже можно получить  новый адрес из компонента:
Код:
try {
FormB->IdHTTP1->Post("http://" + ServerName + "/login.php", pp);
try {
ipd = FormB->IdHTTP1->Get("http://" + ServerName + "/" + FormB->IdHTTP1->Response->Location);
} catch (...) {
FormB->MemoDebug->Lines->Add(String(FormB->IdHTTP1->ResponseCode));
}
} catch (...) {
FormB->MemoDebug->Lines->Add("Sorry…");
}

или как-то можно проще?
Записан
zubr
Гость
« Ответ #8 : 06-04-2009 18:28 » 

1. Исходники на IdHTTP смотри в модуле IdHTTP.pas (вроде в билдере лежат паскальные исходники).
2. Самое интересное находится в методе TIdCustomHTTP.DoRequest, TIdHTTPProtocol.ProcessResponse. Собственно в твоем случае exception возникает именно в методе ProcessResponse.
3. Установи в True свойство HandleRedirects, ну и свойство RedirectMax должно быть не меньше редиректов. Вот что пишет Борландский хелп по поводу HandleRedirects:
Цитата
TIdHTTP.HandleRedirects

Indicates if the HTTP client can handle redirections to an alternate resource location.
property HandleRedirects: Boolean;

Description

HandleRedirects is a published Boolean property in TIdHTTP, and indicates if the HTTP client should handle redirects in a response from the HTTP server. Redirects are indicated by the HTTP Response having a ResponseCode in the range 300 to 307, and requires further action needs by the HTTP Client to fulfill the request.
Redirection ResponseCodes include the following:

300 - Multiple Choices. The request can be fulfilled with one of a set of resources, each with its own specific location. The HTTP client can select a preferred representation and redirect its request to that location.
   301 - Moved Permanently. The requested resource has been assigned a new permanent URI and any future references to this resource should use the new location specified in the Response.
   302 - Found. The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client should continue to use the URI in the Request for future requests.

304 - Not Modified. If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server should respond with this status code. The 304 response should not contain a message body, and is always terminated by the first empty line after the header fields, and must include a Date header.
   305 - Use Proxy. The requested resource must be accessed through the proxy given by the Location header in the HTTP Response containing the URI of the Proxy.

307 - Temporary Redirect. The requested resource resides temporarily under a different URI. Since the redirection may be altered on occasion, the HTTP client should continue to use the URI in the RequestI for future requests.

HandleRedirects is used with RedirectMaximum in DoRequest to detect and prevent infinite redirection loops, by limiting the number of active redirections for the client to the value specified in RedirectMaximum.

When HandleRedirects is True, the HTTP Client will trigger the OnRedirect event handler to determine if the client can accept the redirection location found in an HTTP response. When accepted, the redirect causes a new HTTP request with the new location to be issued to fulfill the original request.

When HandleRedirects is False, the OnRedirect event handler will be triggered, and an EIdProtocolReplyError exception will be raised when the redirect cannot be handled by the HTTP client.

The default value for HandleRedirects is Id_TIdHTTP_HandleRedirects, as assigned in the Create constuctor.
Записан
Chuda
Гость
« Ответ #9 : 06-04-2009 21:53 » 

О как!
zubr, спасибо!
Это должно по идее код сократить вдвое.
Но тогда вот что беспокоит:
вообще пишется бот для онлайн-игры. Сервер у этой игры глюковат, и очень часто (реально часто, может раз минут в двадцать) вместо нормальных 200 или 302 выдаются ответы типа 500, 503, 504.
В случае с редиректом фактически два запроса: первый по начальному адресу (программа получает ответ 302 или 5хх: try-catch, и в цикле, пока не получим нормальный 302 с полем location в заголовках), а второй — это уже по реальному адресу, который указан в переадресации. По второму адресу тоже может прибыть ответ 200, а может и 500-503-504 (глюк).
Я сейчас обрабатываю оба ответа, добиваю сервер, пока он мне не ответит 302 и 200. Делает ли то же самое IdHTTP сам?
Записан
zubr
Гость
« Ответ #10 : 07-04-2009 03:50 » 

Все основные действия по HTTP-протоколу происходят в методе TIdHTTPProtocol.ProcessResponse. Там обрабатываются коды ошибок: 304, 401, 407, 204.
Для решения твоей задачи, можно пойти 2-мя путями:
1. Создать наследуемые классы от TIdCustomHTTP, TIdHTTPProtocol и в них переопределить методы DoRequest, ProcessResponse. Вариант сложноватый, но имеет смысл, если подобные программы с той же логикой придется писать и в дальнейшем.
2. Обрабатывать ошибки как у тебя сейчас в блоке catch. Только я бы сделал это рекурсивно и в отдельном потоке. Количество рекурсий можно ограничить какой нибудь переменной. То есть, чтобы в блоке catch вызывалась бы сама функция, тогда и код не будет громоздкий и число ошибочных запросов можно будет сделать достаточно большим.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines