Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Upload файла (WinInet)


Автор: Микаэль 10.2.2009, 17:48
Положение дел: есть файлы, которые ужно залить на сервер через HTTP средствами WinInet по соответствующему логину и паролю.
Проблема: при установке флага INTERNET_FLAG_KEEP_CONNECTION запрос не проходит на сервер (не отображается в логах), а при его отсутствии сервер возвращает ошибку 401 (отсутствует авторизация). Если не использовать систему логина (отключать права доступа на сервере), все работает без проблем. Однако логин необходим.
Если у кого-то есть соображения на этот счет, буду благодарен.

Код


var
  s, readed,w: DWord;
  f : file;
  Buf : PBuf;
  param : Cardinal;
  proxy : PChar;
  internet_buf : INTERNET_BUFFERS;

.......

http_internet:=InternetOpen(PChar(ExtractFileName(application.exename)),param,proxy,nil,0);
if http_internet <> nil then begin
   http_connection:=InternetConnect(http_internet,PChar(HTTPHost]),80,PChar(UserName),Pchar(Password]),INTERNET_SERVICE_HTTP,0,0);
   if http_connection <> nil then begin

    AssignFile(f,FFileList[0]);
    Reset(f,1);
    s:=FileSize(f);
    new(buf);

    http_request:=HttpOpenRequest(http_connection,'PUT',PChar(filePath),nil,nil,nil,INTERNET_FLAG_KEEP_CONNECTION or INTERNET_FLAG_NO_CACHE_WRITE,0);
    FillChar(internet_buf,sizeOf(internet_buf),0);
    internet_buf.dwStructSize:=sizeOf(internet_buf);
    internet_buf.dwBufferTotal:=filesize(f);

   if HTTPsendRequestEX(http_request, @internet_buf, nil, HSR_INITIATE, 0) then begin

    {$I-}
    BlockRead(f,buf^,1024,readed);               
    if IOResult = 0 then
      repeat
        InternetWriteFile(http_request,@buf,readed,w);                     
        BlockRead(f,buf^,1024,readed); // ñíîâà ÷èòàåì
      until readed = 0                         

    HttpEndRequest(http_request, nil, 0, 0);

    {$I+}

    dispose(buf);
    closeFile(f); 
    end 

   InternetCloseHandle(http_request);
   InternetCloseHandle(http_connection);
   InternetCloseHandle(http_internet);

Автор: Snowy 10.2.2009, 19:03
InternetCreateUrl
Заполни структуру, включая логин и пароль.
И скармливай этот урл, который соберёт функция.

Автор: Микаэль 11.2.2009, 17:58
Спасибо за совет!

Функция собирает незамысловатую строку типа:
Код

http://логин:пароль@хост/путь/файл


Передаем ее как урл запроса, и в логах сервер пишет дословно следующее:
Код

80 PUT /http:/логин:пароль@хост/путь/файл - 404

(с расстановкой слэшей я не ошибся)
и в чем-то он (сервер) прав, ибо такого адреса быть не может  smile 

Так что проблема, к сожалению, еще актуальна  smile 

Автор: Snowy 11.2.2009, 18:46
Это я тупость в прошлый раз написал.
Зубудь её.
В приведённом куске кода всё верно.
Вероятно что-то не так в параметрах. Тут непонятно.
Может прокси виноват...
Попробуй флаг INTERNET_FLAG_RELOAD.
Также можно попробовать, в случае 401, принудительно повторить установку пароля через InternetSetOption с флагом INTERNET_OPTION_USERNAME  и INTERNET_OPTION_PASSWORD.
А в коде ошибок не вижу. Всё верно.

Автор: Микаэль 18.2.2009, 14:19
Спасибо, но к сожалению не помогло...
Этот вопрос пока замяли... Аплоад решили не запароливать, но выяснилось, что download с авторизацией работает ни на всех компьютерах.
На систмах Win XP SP2 rus, (wininet v.6.0.2900.2180), Win 2K SP4 rus (wininet v.5.0.3700.6713) - авторизация проходит нормально
На английской Win 2k c такой же версией wininet и еще какой-то Win 2k (с кожалению, не имею доступа, чтобы уточнить) - ошибка 401.
В чем могут быть потенциальные грабли?

UPD: Код dowload'a могу привести, но он мало чем принципиально отличается от upload'а.

Автор: MetalFan 18.2.2009, 14:56
может filePath кривой какой-нибудь...
а вообще еще можно посмотреть, что шлет клиентское приложение через какой-нить http tracer...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)