| 
			| 
					
						| 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 | 
								|  | « Ответ #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. |  |  | 
	|  |