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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Имя файла для закачки  (Прочитано 1699 раз)
0 Пользователей и 1 Гость смотрят эту тему.
..::SCRIBE::..
Помогающий

ua
Offline Offline
Пол: Мужской
не путайте банальность с ленью=)


« : 11-08-2016 12:41 » 

Всем привет.

Пробую качать файлы через api, модуль WinInet.
Функции:
InternetOpen
InternetOpenURL
InternetQueryDataAvailable
InternetSetFilePointer
InternetReadFile
Так вот, как узнать реальное имя файла что закачивается?
Допустим я скармливаю ему ссыль:
http://www.ex.ua/load/262344568
в итоге прилетает файл:
http://fs36.www.ex.ua/load/81447245caa8335f38c1c7355b93aecb/262344568/lubuntu-pack-16.04.1-desktop-amd64.iso
(увидел я его из браузера)
Сама функция без впоросов его качает(первую ссылку), но как его сохранить, не зная изначального имени?
Вот как узнать что это "lubuntu-pack-16.04.1-desktop-amd64.iso"? Оно его просто в буфер качает и все.

Спасибо.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 11-08-2016 21:02 » 

В данном примере был редирект — средствами HTTP или HTML/JS.
В качестве имени конечного файла используются данные последнего запроса с ответом 200 или 206. Может быть использована часть пути запроса от последнего "/" или имя передается в ответ через заголовок HTTP Content-Disposition.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
..::SCRIBE::..
Помогающий

ua
Offline Offline
Пол: Мужской
не путайте банальность с ленью=)


« Ответ #2 : 17-08-2016 13:26 » 

Спасибо за подсказку.
Намучился я с этим апи.
Хочу в нем собственно и выловить этот редирект, нашел в инете как, поставить обработчик т.е вызвать InternetSetStatusCallback.
Вроде работает, сообщения сыплются, только в виде абракадабры, не пойму что за кодировка такая.
Вот че пришло, и как его привести к человеческому виду?
Код: (Text)
HTTP request is about to automatically redirect the request 瑨灴⼺是㍳⸶睷⹷硥甮⽡潬摡㠯㐱㜴㐲挵慡㌸㔳㍦挸挱㌷㔵㥢愳捥⽢㘲㌲㐴㘵⼸畬畢瑮⵵慰正ㄭ⸶㐰ㄮ搭獥瑫灯愭摭㐶椮潳㸀眙팱眘
Покажу процедуру, чтобы не было вопросов откуда нормальные буквы=)
Код: (Delphi)
procedure StatusCallback(
  hInet:        HINTERNET;
  Context:      DWORD_PTR;
  Status:       DWORD;
  pInformation: Pointer;
  InfoLength:   DWORD ); export; stdcall;
var
  s: String; //UTF8String
  //info: array of char;
begin
  //SetLength(info, INfoLength);
  //info:= pInformation;
  case Status of
    INTERNET_STATUS_CLOSING_CONNECTION: s := 'Closing the connection to the server';
    INTERNET_STATUS_CONNECTED_TO_SERVER: s := 'Successfully connected to the socket address: ';
    INTERNET_STATUS_CONNECTING_TO_SERVER: s := 'Connecting to the socket address';
    INTERNET_STATUS_CONNECTION_CLOSED: s := 'Successfully closed the connection to the server';
    INTERNET_STATUS_CTL_RESPONSE_RECEIVED: s := 'Not implemented';
    INTERNET_STATUS_HANDLE_CLOSING: s := 'This handle value has been terminated';
    INTERNET_STATUS_HANDLE_CREATED: s := 'InternetConnect has created the new handle';
    INTERNET_STATUS_INTERMEDIATE_RESPONSE: s :=
      'Received an intermediate (100 level) status code message from the server';
    INTERNET_STATUS_NAME_RESOLVED: s := 'Successfully found the IP address: ' + PWideChar(pInformation);
    INTERNET_STATUS_PREFETCH: s := 'Not implemented';
    INTERNET_STATUS_RECEIVING_RESPONSE: s := 'Waiting for the server to respond to a request ';
    INTERNET_STATUS_REDIRECT: s := 'HTTP request is about to automatically redirect the request ' +
      PChar(pInformation);
    INTERNET_STATUS_REQUEST_COMPLETE: s := 'An asynchronous operation has been completed';
    INTERNET_STATUS_REQUEST_SENT: s := 'Successfully sent the information request to the server: ' +
      IntToStr(Integer(pInformation)) + ' Byte';
    INTERNET_STATUS_RESOLVING_NAME: s := 'Looking up the IP address: ' + PWideChar(pInformation);
    INTERNET_STATUS_RESPONSE_RECEIVED: s := 'Successfully received a response from the server: ' +
      IntToStr(Integer(pInformation)) + ' Byte';
    INTERNET_STATUS_SENDING_REQUEST: s := 'Sending the information request to the server.';
    INTERNET_STATUS_STATE_CHANGE:
      begin
        s := 'Moved between a secure (HTTPS) and a nonsecure (HTTP) site.';
        case DWORD(pInformation) of
          INTERNET_STATE_CONNECTED: s := s + #13#10 + 'Connected state. Mutually exclusive with disconnected state.';
          INTERNET_STATE_DISCONNECTED: s := s + #13#10 +
            'Disconnected state. No network connection could be established.';
          INTERNET_STATE_DISCONNECTED_BY_USER: s := s + #13#10 + 'Disconnected by user request.';
          INTERNET_STATE_IDLE: s := s + #13#10 + 'No network requests are being made by Windows Internet.';
          INTERNET_STATE_BUSY: s := s + #13#10 + 'Network requests are being made by Windows Internet.';
        end;
      end;
  end;
  //ShowMessage(s);
  fmMain.Memo1.Lines.Add(s);
end;

Подвязывается обработчик так:
Код: (Delphi)
hInet := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
InternetSetStatusCallback(hInet, @StatusCallback);
hURL := InternetOpenURL(hInet, PChar(SrcName), nil, 0, INTERNET_FLAG_NEED_FILE, Integer(@StatusCallback));

Записан
..::SCRIBE::..
Помогающий

ua
Offline Offline
Пол: Мужской
не путайте банальность с ленью=)


« Ответ #3 : 18-08-2016 10:21 » 

Нашел, дурная моя голова, надо использовать PAnsiChar.
Записан
..::SCRIBE::..
Помогающий

ua
Offline Offline
Пол: Мужской
не путайте банальность с ленью=)


« Ответ #4 : 19-08-2016 06:59 » 

И еще, может кому пригодится, как бонус, пример передачи данных в процедуру CallBack через Context.

Описание структуры данных для передачи, вообще пример есть тут https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa383976(v=vs.85).aspx, но на C++.
Так вот, структура контекста (может быть какой угодно):
 
Код: (Delphi)
TCallbackContext = record
    ccTaskId : integer;
  end;
  PCallbackContext = ^TCallbackContext;

Передача ее в процедуру:

Код: (Delphi)
var
  hInet, hURL: HINTERNET;
  myContext: TCallbackContext;
begin
  myContext.ccTaskId:= SomeObject.Id;
  hInet := InternetOpen(PChar('Some Name'), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  InternetSetStatusCallback(hInet, @IDCallback); //устанавливаем обработчик
  hURL := InternetOpenURL(hInet, PChar('имя ссылки'), nil, 0, INTERNET_FLAG_NEED_FILE, DWORD_PTR(@myContext)); //тут передаем наши данные.

В обработчике ловим:

Код: (Delphi)
procedure IDCallback(
  hInet:        HINTERNET;
  Context:      DWORD_PTR;
  Status:       DWORD;
  pInformation: Pointer;
  InfoLength:   DWORD);
var
  cxInfo: PCallbackContext;
begin
  cxInfo:= Pointer(Context);
  ShowMessage(inttostr(cxInfo^.ccTaskId)); //показываем, что не дурю=)
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines