Всем здрасте. Пожалуйста помоготи разобраться с одной проблемой. Мне нужно написать простую программу загружающую малые удалённые файлы и HTML страницы, скажем не более 300 кб. Для загрузки я использую функцию URLDownloadToFile. Ей достаточно передать указатели на URL и файл, и она загружает файл. Вот только нужно ещё за ранее узнать размер файла или HTML страницы, чтобы точно знать, что он не большой. Да и имя файла далеко не всегда в явном виде присутствует в URL. Вот процедура получения размера файла которая почему-то не всегда страбатывает Код (Text): HTML struc URL dd ? ;URL - ОТКУДА СКАЧИВАТЬ PATH dd ? ;ПОЛНОЕ ИМЯ ФАЙЛА HTML ends SizeURL proc psHtm:DWORD LOCAL hUrl:DWORD LOCAL dwRWurl:DWORD LOCAL dwRWfile:DWORD LOCAL dwBuffer[20]:BYTE LOCAL lpdwBufferLength LOCAL dwIndex LOCAL hInt assume ebx:ptr HTML mov ebx,psHtm invoke InternetOpen,offset AppName,0,0,0,0 mov hInt,eax xor eax,eax invoke InternetOpenUrl,hInt,[ebx].URL,eax,eax,eax,eax mov hUrl,eax .if eax mov lpdwBufferLength,sizeof dwBuffer mov dwIndex,0 invoke HttpQueryInfo,hUrl,HTTP_QUERY_CONTENT_LENGTH,addr dwBuffer,addr lpdwBufferLength,addr dwIndex invoke InternetCloseHandle,hUrl invoke crt_atol,addr dwBuffer .endif push eax invoke InternetCloseHandle,hInt pop eax ret assume ebx:nothing SizeURL endp Например если URL 'http://www.wasm.ru/baixado.php?mode=tool&id=403', то размер узнать не получается, а ещё с таким URL надо-бы ещё и имя файла узнавать. А если имя файла задано явно, то обычно проходит всё без проблем, скажем URL db 'http://www.somesite.ru/somearchive.zip',0.
Просто не всякий линк - это файл. Есть еще всякие "премудрости". baixado.php - это скрипт написанный на специальном языке, хранящийся на сервере и там же выполняющийся. Тут, видимо, нужны другие методы.
К сожалению, ты не очень понимаешь суть HTTP-протокола. Дело в том, что тут нет понятия файл/не файл. Есть понятия запрос/ответ. Вот это запрос. Внутри он может выглядеть следующим образом (сформировано Google Chrome): Ответ на него выглядит так: Это страница-перенаправление (код 302). Поле Location в этом случае указывает броузеру, куда следует идти дальше. Он и идёт: И в ответе теперь то, что нужно: Учитесь снифером пользоваться, господа.
Конкретно: что есть "не получается"? В чём это проявляется? Функция ошибку возвращает? Какая функция? Какую именно ошибку? Подозреваю, что ты просто поле Accept: */* забыл указать в InternetOpenUrl(), не знаю, проверять лень сейчас. В случае выше у тебя только два варианта: 1. Оставить обработку перенаправления системе, при этом имя ты уже получить не сможешь никак, только размер. 2. Выполнять перенаправление самостоятельно, тогда получишь и имя и размер. Для обработки вручную надо указать флаг INTERNET_FLAG_NO_AUTO_REDIRECT в функции InternetOpenUrl() и проверить наличие поля Location: ..., оно указывает, где реально лежит запрашиваемый объект, при этом первый запрос следует повторять рекурсивно, пока будет возвращаться поле Location в ответе (скорее всего попадание будет уже со второго раза, но мало ли...). На каждой итерации запоминай последнее возвращённое значение поля Location. Имя файла ты сможешь получить из последнего возвращённого Location'а, а размер - из запроса на URL, указанный в последнем Location.
Протоколов я действительно не знаю, просто надеялся, что и без этого можно обойтись. Жаль что нет API URLGetSize и URLGetName. Придётся самому по сидеть разобраться.
Таких функций URLGetSize и URLGetName в принципе не может быть. URL - это действительно скорее указание к действию, чем ссылка на файл. Ты бы уточнил свою задачу, может что-то подсказали тогда.
Всё работает, нужно использовать два способа: Код (Text): (FASM синтаксис) 1. invoke HttpQueryInfo, [hUrl], HTTP_QUERY_CONTENT_LENGTH, addr dwBuffer, addr lpdwBufferLength, 0 2. invoke InternetQueryDataAvailable, [hUrl], addr lpdwBufferLength, 0, 0 Если "HttpQueryInfo" возвращает "ERROR_HTTP_HEADER_NOT_FOUND", значит нет запрашиваемого заголовка, неоткуда его просто взять, и в этом случае прибегаем ко второму способу. "InternetQueryDataAvailable" позволяет определить сколько данных мы можем считать за раз функой "InternetReadFile". Так-как "HttpQueryInfo" вернул нам ошибку об отсутствии заголовка, то вероятно ссылку который мы пытаемся прочесть является динамически генерируемым ответом, и в этом случае размер этого ответа можно узнать при помощи "InternetQueryDataAvailable". У меня "HttpQueryInfo" возвратил корректный размер файла по ссылке - http://www.wasm.ru/baixado.php?mode=tool&id=403, следовательно если у тебя не работает, то ошибка в коде.
хм.. в протоколе http есть несколько методов передачи данных. и понятие "файл" там всё-таки есть - при передаче multimedia данных. в Вашем случа запросить размер файла, думаю, можно. нужно покапаться в rfc. суть заключается в том, чтобы запросить нужный файл не методом GET, а ... (забыл, вроде HEADER или как-то так) - сервер выдаст только заголовок ответа. ещё нужно указать серверу поддерживаемый тип передачи данных, чтобы он выдавал ответ не через chunked, а через content-length.