2015-11-03 9 views
1

У меня есть приложение delphi wininet.Загрузка файла с помощью WININET на delphi

На прошлой неделе я попытался отправить информацию для выполнения метода JSON, на этой неделе я пытаюсь загрузить файл на веб-сервер. Я использую тот же код с несколькими модификациями, но в тот момент, когда процедура InternetWriteFile выполняется, программа вызывает у меня исключение: «Controlador no válido».

Код здесь:

function TFormMain.CargarArchivo(Archivo, Server: string; Username, Password: PChar; blnSSL, iftoken: Boolean): Boolean; 
    var 
     Url, Header : String; 
     pSession, pConnection, pRequest : HINTERNET; 
     flags, dwSize, dwFlags : DWORD; 
     dwError, Port : Integer; 
     Escritos : Cardinal; 
    begin 
     Result := false; 
     pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); 
     if not Assigned(pSession) then 
      raise Exception.Create('InternetOpen failed. ' + WinInetErrorMsg(GetLastError)); 
     try 
      Url := Copy(Server,pos('/Servidor',Server),length(Server)); 
      if blnSSL then 
      begin 
      Server := Copy(Server,9,pos('/Servidor',Server)-1); 
      Port := INTERNET_DEFAULT_HTTPS_PORT 
      end 
      else 
      begin 
      Server := Copy(Server,8,pos('/Servidor',Server)-1); 
      Server := Copy(Server,1,pos(':',Server)-1); 
      Port := 8080; 
      end; 
      pConnection := InternetConnect(pSession, PChar(Server), port, Username, Password, INTERNET_SERVICE_HTTP, 0, 0); 
      if not Assigned(pConnection) then 
      raise Exception.Create('InternetConnect failed. ' + WinInetErrorMsg(GetLastError)); 
      try 
      if blnSSL then 
       flags := INTERNET_FLAG_SECURE 
      else 
       flags := 0; 
      pRequest := HTTPOpenRequest(pConnection, 'POST', PChar(Url), nil, nil, nil, flags, 0); 
      if not Assigned(pRequest) then 
       raise Exception.Create('HttpOpenRequest failed. ' + WinInetErrorMsg(GetLastError)); 
      try 
       // Set buffer size 
       dwSize:=SizeOf(dwFlags); 
       // Get the current flags 
       if (InternetQueryOption(pRequest, INTERNET_OPTION_SECURITY_FLAGS, @dwFlags, dwSize)) then 
       begin 
        // Add desired flags 
        dwFlags:=dwFlags or SECURITY_FLAG_IGNORE_UNKNOWN_CA or SECURITY_FLAG_IGNORE_CERT_CN_INVALID or SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; 
        // Set new flags 
        if not(InternetSetOption(pRequest, INTERNET_OPTION_SECURITY_FLAGS, @dwFlags, dwSize)) then 
        begin 
         // Get error code 
         dwError:=GetLastError; 
         // Failure 
         MessageBox(Application.Handle, PChar(IntToStr(dwError)), PChar(Application.Title), MB_OK or MB_ICONINFORMATION); 
        end; 
       end 
       else 
       begin 
        // Get error code 
        dwError:=GetLastError; 
        // Failure 
        MessageBox(Application.Handle, PChar(IntToStr(dwError)), PChar(Application.Title), MB_OK or MB_ICONINFORMATION); 
       end; 
       Header := 'Host: ' + Server + ':' + IntToStr(Port) + #13#10 + 
          'Content-Type: multipart/form-data; charset=UTF-8'#13#10; 
       if iftoken then 
       begin 
        Header := Header + 'auth_token: '+token+#13#10; 
        Header := Header + 'Csrf-token: no-check'#13#10; 
       end; 

       if not HttpAddRequestHeaders(pRequest, PChar(Header), Length(Header), HTTP_ADDREQ_FLAG_ADD) then 
        raise Exception.Create('HttpAddRequestHeaders failed. ' + WinInetErrorMsg(GetLastError)); 

       Parameters := TIdMultiPartFormDataStream.Create; 
       Parameters.AddFile('archivo', Archivo, ''); 
       if not HTTPSendRequest(pRequest, nil, 0, Parameters, Parameters.Size) then 
        raise Exception.Create('HTTPSendRequest failed. ' + WinInetErrorMsg(GetLastError)); 

       try 
        if not InternetWriteFile(Parameters, Parameters, Parameters.Size, Escritos) then 
         raise Exception.Create('InternetWriteFile failed. ' + WinInetErrorMsg(GetLastError)); 
        Result := true; 
       finally 
        Parameters.Free; 
       end; 
      finally 
       InternetCloseHandle(pRequest); 
      end; 
      finally 
      InternetCloseHandle(pConnection); 
      end; 
     finally 
      InternetCloseHandle(pSession); 
     end; 
    end; 

Exception

Я попытался инициализировать указатель файла с процедурой FtpOpenFile, но он не работает, так как сервер HTTP, FTP не, я думаю, ,

ответ

2

Вы не можете смешивать Indy и WinInet так, как вы пытаетесь их смешивать.

Вы пытаетесь создать POST a Indy TIdMultipartFormDataStream объект непосредственно из памяти. Это никогда не сработает. Вы должны сообщить TIdMultipartFormDataStream для генерации своих MIME-данных из ваших входных параметров, а затем опубликовать эти данные. TIdHTTTP.Post() обрабатывает это для вас, но вы не используете TIdHTTP, поэтому вам нужно сделать это вручную. В этом случае вам нужно сохранить сгенерированные данные TIdMultipartFormDataStream в отдельный TMemoryStream (используя метод TStream.CopyFrom()), а затем вы можете публиковать эти данные с помощью WinInet.

Даже тогда, ваш POST будет по-прежнему ломаются, потому что:

  1. вы не включая необходимые boundary параметра в заголовке запроса Content-Type (TIdMultipartFormDataStream генерирует это значение динамически), чтобы сервер мог разобрать MIME части правильно.

  2. Вы не можете смешивать HTTPSendRequest() и InternetWriteFile() вместе, если они оба пытаются отправить данные тела для запроса. Выберите тот или другой.

Попробуйте что-то больше, как это:

PostData := TMemoryStream.Create; 
try 
    Parameters := TIdMultiPartFormDataStream.Create; 
    try 
    Parameters.AddFile('archivo', Archivo, ''); 
    PostData.CopyFrom(Parameters, 0); 
    Header := 'Host: ' + Server + ':' + IntToStr(Port) + #13#10 + 
       'Content-Type: ' + Parameters.RequestContentType + #13#10; 
    finally 
    Parameters.Free; 
    end;  
    if iftoken then 
    begin 
    Header := Header + 'auth_token: '+token+#13#10; 
    Header := Header + 'Csrf-token: no-check'#13#10; 
    end; 
    if not HttpAddRequestHeaders(pRequest, PChar(Header), Length(Header), HTTP_ADDREQ_FLAG_ADD) then 
    raise Exception.Create('HttpAddRequestHeaders failed. ' + WinInetErrorMsg(GetLastError)); 
    if not HTTPSendRequest(pRequest, nil, 0, PostData.Memory, PostData.Size) then 
    raise Exception.Create('HTTPSendRequest failed. ' + WinInetErrorMsg(GetLastError)); 
    Result := True; 
finally 
    PostData.Free; 
end; 
+0

Снова спасибо за помощь. Я действительно новичок в обработке этого компонента, я привык использовать INDY, поэтому мое сочетание компонентов. –

Смежные вопросы