mynologin
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору audi6b44 Цитата: так как большенство из серверов при первом же обращении к ним по конечной ссылке секут наш IP, и при обрыве и тут-же втором обращении к ним дают нам фигу | Да не нужно рвать соединение. В общем, попробую объяснить ещё подробнее. Начнём с того, что MS позаботилась обо всём, что нужно касательно HTTP и HTTPS (и почти всего остального, но не суть), всё добавила в стандартные WinAPI в модуле wininet и всё документировала в MSDN. И не нужно быть профи, чтобы в этом разобраться. Нужно просто один раз прочитать. Поэтому все эти проблемы с неожиданными данными, openssl и другими сторонними компонентами несколько надуманы. Теперь конкретно по поводу процесса получения данных по очередной ссылке (на самом деле я сейчас просто могу открыть USD в дизассемблере и прямо оттуда cписать сюда весь порядок вызова функций). 1) InternetOpen. Ну это просто инициализация wininet. Рекомендуется вызывать её только один раз, а не каждый раз при установке соединения, как это делает USD. 2) InternetConnect. По сути только инициализация данных для будущего соединения. Для HTTP/HTTPS эта функция даже не устанавливает соединение. 3) HttpOpenRequest. И опять инициализация. Только теперь данных для будущего запроса. Соединения всё ещё нет. 4) HttpSendRequest. Вот здесь происходит практически всё: установка TCP-соединения, установка SSL-соединения (выбор шифрования, генерация ключей на обеих сторонах), отправка HTTP-запроса, считывание первых данных HTTP-ответа, включающих HTTP-заголовки. Система соединение не прерывает! 5) Т.к. система уже приняла от сервера первые данные, включающие HTTP-заголовки, USD теперь спокойно может проверить все необходимые ему поля этих заголовков (помним, что соединение ещё установлено... никто его не рвал). И для этого Windows любезно предоставляет функцию HttpQueryInfo. И USD её вызывает. Но единственное поле, которое он проверяет (передавая в функцию флаги HTTP_QUERY_CONTENT_LENGTH и HTTP_QUERY_FLAG_NUMBER), — это длина файла. После чего начинает докачивать остальные данные HTTP-ответа. Чтобы узнать тип возвращаемых данных, нужно также вызвать HttpQueryInfo с параметром HTTP_QUERY_CONTENT_TYPE. И исходя из возвращённого значения принимать решение о том, конечная это ссылка или нет. 6) И да... TCP-соединение ещё открыто и можно продолжать запрашивать данные от сервера, отвечающего на GET-запрос. Делается это вызовом функции InternetReadFile (в цикле, как это делает USD) до тех пор, пока все данные не будут получены. 7) Чуть не забыл... Соединение ведь всё ещё открыто. По правилам, надо за собой прибирать (InternetCloseHandle). Поэтому имеет смысл a) закрыть хэндл, возвращённый HttpOpenRequest, т.к. больше не планируется вызывать HttpSendRequest. b) закрыть хэндл, возвращённый InternetConnect, т.к после скачивания файла вообще не планируется отправлять запросы по этому же соединению. И вот только сейчас соединение будет разорвано. c) не закрывать хэндл (а USD закрывает), возвращённый InternetOpen, т.к. в будущем ещё планируется вызывать функции wininet. Добавлено: Цитата: ну обидно, что ты Диму таким тупым выставляешь.. | Э... Я буду всё отрицать. Багрепорты даже в MS с удовольствием принимают. И не считают себя тупыми при этом. | Всего записей: 65 | Зарегистр. 07-05-2011 | Отправлено: 03:39 22-05-2011 | Исправлено: mynologin, 03:46 22-05-2011 |
|