kisilevski
|
|
« : 19-11-2008 08:38 » |
|
Ситуация такая: С помощью WinINet функций загружаю с сервера файлы. Ну, типа HttpOpenRequest, HttpSendRequest, InternetReadFile итд. Всё работает.
Проблема в следующем: Если есть ссылка типа h**p://www.codeproject.com/KB/dialog/CGlassDialog/cglassdialog_source.zip, то у меня в явном аиде имеется имя файла, с которым я могу сохранить полученное. Если есть ссылка, для которой в теге <А href="чегототам">Filename.ext</А> явным образом прописано имя файла - тоже всё понятно.
Если же есть такая ссылка: h**p://www.gz-volga.ru/pls/kea/utl.download_attach?p_id=365926 или такая: <А href="h**p://spl.gz-kuban.ru/spl.gz-kuban.ru/blob;jsessionid=8282F7DD226BBBC1F7CBB6B4EB7640FB?id=152710">Скачать</А>,
то тогда у меня вообще нет имени файла. Однако, если делать через IE -> SaveTargetAs - он каким-то образом получает имя файла при закачке, то есть это как-то возможно. Просмотрел список фозможных флагов для HttpQueryInfo - ничего подходящего не нашлось.
Подскажите, пожалуйста, каким образом можно всё-таки получить в процессе закачки файла его имя. Вообще не представляю себе с какого конца к этой проблеме подступиться.
|
|
« Последнее редактирование: 19-11-2008 10:17 от Вад »
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
zubr
Гость
|
|
« Ответ #1 : 19-11-2008 09:19 » |
|
<А href="h**p://spl.gz-kuban.ru/spl.gz-kuban.ru/blob;jsessionid=8282F7DD226BBBC1F7CBB6B4EB7640FB?id=152710">Скачать</А> Это ссылка не на сам файл, а на страницу, с ссылкой на файл. Загрузка файла уже осуществляется или пользователем или скриптом автоматически. Как выход - имитировать действия пользователя, кликом на ссылке.
|
|
« Последнее редактирование: 19-11-2008 10:18 от Вад »
|
Записан
|
|
|
|
kisilevski
|
|
« Ответ #2 : 19-11-2008 09:35 » |
|
<А href="h**p://spl.gz-kuban.ru/spl.gz-kuban.ru/blob;jsessionid=8282F7DD226BBBC1F7CBB6B4EB7640FB?id=152710">Скачать</А> Это ссылка не на сам файл, а на страницу, с ссылкой на файл. Насколько я понимаю, это не совсем так. Через IE - Save Target AS получается файл с дивным именем "КД+по+Лоту+6030.rar". Через InternetReadFile, ручками, приходит тот же массив размером 168 кБайт. То есть сервер отдаёт файл именно по той ссылке, безо всякой промежуточной страницы со скриптом. И как-то IE умудряется получить его имя.. К тому же кликнуть-то по ней можно, но после этого нужно ручками указывать куда сохранять итд. А должно всё само работать, без участия персонала.
|
|
« Последнее редактирование: 19-11-2008 10:25 от kisilevski »
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
kisilevski
|
|
« Ответ #3 : 19-11-2008 16:20 » |
|
Всё, решение основного вопроса найдено. Выглядит более, чем просто: TCHAR szContentDSP[512]; DWORD dwDSPSize = 512; BOOL b=::HttpQueryInfo(m_hHttpFile, HTTP_QUERY_CONTENT_DISPOSITION , szContentDSP, &dwDSPSize, NULL);
В строчке szContentDSP получаем заголовок ответа сервера, типа такого: " attachment; filename=%D0%9A%D0%94+%D0%BF%D0%BE+%D0%9B%D0%BE%D1%82%D1%83+6030.rar". Осталось только понять, как превратить чудо-строку в читабельный текст Есть ли готовое решение, или это нужно перекодировать вручную?
|
|
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
Вад
|
|
« Ответ #4 : 20-11-2008 09:03 » |
|
Не знаю насчёт готовых решений, но если вручную - считываешь %NN, записываешь в строку символ с кодом 0xNN, плюсы игнорируются, остальное (чему не предшествует'%') - добавляется в строку как есть. Похоже, так.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 20-11-2008 10:15 » |
|
kisilevski, это чудо-строка имеет url-encoded формат (см. RFC): %XX - шестнадцатеричный код + - пробел
По кодам вижу, что это UTF-8.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
kisilevski
|
|
« Ответ #6 : 20-11-2008 16:35 » |
|
Спасибо, я поступил самым на тот момент простым для меня способом: CString StrFNDSP(szContentDSP); if(StrFNDSP!=""){ StrFNDSP.Replace("%D0%90", "А"); StrFNDSP.Replace("%D0%91", "Б"); StrFNDSP.Replace("%D0%92", "В"); StrFNDSP.Replace("%D0%93", "Г"); StrFNDSP.Replace("%D0%94", "Д"); .....
всё работает
|
|
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 20-11-2008 16:40 » |
|
kisilevski, я бы тоже так сделал, кстати
|
|
|
Записан
|
|
|
|
kisilevski
|
|
« Ответ #8 : 20-11-2008 16:46 » |
|
|
|
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
zubr
Гость
|
|
« Ответ #9 : 20-11-2008 17:46 » |
|
kisilevski, и что весь алфавит русский с латинским переписывал? Это круто. А если бы кодировка была другая? Я когда бот делал, то URL перекодировал так: bool CIEHelper::CharToHex(const TCHAR str[], const int& size, int& sum) { sum=0x0; int k=size-1, hx; for (int i=0; i<size; i++) { switch (toupper(str[i])) { case '0': hx=0x0; break; case '1': hx=0x01; break; case '2': hx=0x02; break; case '3': hx=0x03; break; case '4': hx=0x04; break; case '5': hx=0x05; break; case '6': hx=0x06; break; case '7': hx=0x07; break; case '8': hx=0x08; break; case '9': hx=0x09; break; case 'A': hx=0x0A; break; case 'B': hx=0x0B; break; case 'C': hx=0x0C; break; case 'D': hx=0x0D; break; case 'E': hx=0x0E; break; case 'F': hx=0x0F; break; default: return(0); } hx=hx<<(4*k); sum+=hx; k--; } return (1); };
void CIEHelper::DecodeURL (CString& sUrl) { int k = 0; int sum; char c; CString s (_T("xx")); if (sUrl.GetLength() == 0) return;
k = sUrl.Find (_T('+')); while (k != -1) { sUrl.Delete (k); sUrl.Insert (k, _T(' ')); k = sUrl.Find (_T('+')); }
k = sUrl.Find (_T('%')); while (k != -1) { s.CopyChars (s.GetBuffer(), sUrl.GetBuffer()+k+1, 2); sUrl.ReleaseBuffer(); sUrl.Delete (k, 3); CharToHex (s.GetBuffer(), 2, sum); s.ReleaseBuffer(); c = char(sum); sUrl.Insert (k, c); k = sUrl.Find (_T('%')); } };
Ну а чтоб определить кодировку, надо по всей видимости вызывать HttpQueryInfo с флагом HTTP_QUERY_ACCEPT_ENCODING.
|
|
|
Записан
|
|
|
|
kisilevski
|
|
« Ответ #10 : 20-11-2008 19:05 » |
|
Только русский. Мб наивным было с моей стороны предположить, что английские буквы прийдут как есть. Мало пока статистики, тк дома у меня CDMA, вот поработает программа ночь на сервере, тогда буду знать, что с нерусскими буквами, ежели встретятся. Кодировки действительно имеет смысл проверять, хорошая мысль, доберусь и до этого. Спасибо за пример про перекодировку. Полтора года не программировал, теперь вот вспоминаю, что и как.
|
|
|
Записан
|
Ложки нет. See MSDN for details.
|
|
|
|