Страница 1 из 2

Отправка массива файлов через Libcurl

Добавлено: 27 Январь 2022, 14:26
harry
Возникла необходимость отправить через Libcurl в одном запросе набор полей и список файлов (картинок). Какой правильный путь решения данной задачи ?
Возможно ли из Clarion использовать такую конструкцию с передачей массива ?

Код: Выделить всё

curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", CURLFORM_ARRAY, forms, CURLFORM_END)

Отправка массива файлов через Libcurl

Добавлено: 27 Январь 2022, 14:36
Дед Пахом
Посмотрите класс TCurlHttpClass и вот эти методы:

Код: Выделить всё

FormAdd                         PROCEDURE(STRING pFieldName, STRING pContents), CURLFORMcode, PROC
FormAddFile                     PROCEDURE(STRING pFieldName, STRING pFileName, <STRING pContentType>), CURLFORMcode, PROC !ContentType like 'image/jpeg'
FormPost                        PROCEDURE(STRING pUrl, <STRING pResponseFile>, <curl::ProgressDataProcType xferproc>), CURLcode, PROC
FormPost                        PROCEDURE(STRING pUrl, *IDynStr pDynStr, <curl::ProgressDataProcType xferproc>), CURLcode, PROC
FormPostStr                     PROCEDURE(STRING pUrl, <*STRING pResponseBuf>, <curl::ProgressDataProcType xferproc>), CURLcode, PROC
FormFree                        PROCEDURE()

Отправка массива файлов через Libcurl

Добавлено: 27 Январь 2022, 14:40
harry
Перечисленные вами методы смотрел. реализую через FormAddFile и FormPost.
В заголовке задаю Content-type: multipart/form-data
Сначала цикл по простым текстовым полям

Код: Выделить всё

    Loop Indx=1 to Records(pPostFields)
      Get(pPostFields,Indx)

      IF ~(pPostFields.Value and pPostFields.Id) Then Cycle.

      cfres = self.FormAdd(pPostFields.Id, pPostFields.Value)
      IF cfres <> CURL_FORMADD_OK
        res = -1
      END

    End
Затем цикл по очереди файлов

Код: Выделить всё

   Loop Indx = 1 to Records(pFiles)
      GET(pFiles,Indx)

      szfilename = CLIP(pFiles.item)
      
      cfres = self.FormAddFile(szarg, pFiles.item)
      IF cfres <> CURL_FORMADD_OK
        res = -1
      END
    end

    res = self.FormPost(pUrl,pResponseFile, xferproc)
Но не уверен, что это тоже самое, что

Код: Выделить всё

curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", CURLFORM_ARRAY, forms, CURLFORM_END);
, т.к. отправляемая структура определена, как
comment string
claimNumber string
files array файлы к комментариям
В моем случае, FormAddFile будет создавать новое поле формы, но имена полей д.б. одинаковые - files.
Допустимо такое решение ?

Отправка массива файлов через Libcurl

Добавлено: 27 Январь 2022, 14:42
Дед Пахом
Само собой, это не то же самое, что

Код: Выделить всё

curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", CURLFORM_ARRAY, forms, CURLFORM_END);
потому что я в libcurl не использую вызов с флагом CURLFORM_ARRAY, и не планирую добавлять его поддержку. И вообще curl_formadd давно объявлена устаревшей и предлагается пользоваться curl_mime_xxx функциями (TCurlMimeClass в терминах Clarion).

Отправка массива файлов через Libcurl

Добавлено: 14 Февраль 2023, 21:48
atashe3
Хоть тема про отправку файлов
Хотел спросить в классе планируется сделать штатный метод загрузки больших файлов 100мег-4гиг частями?
Я на основе вашего класса сделал такую реализацию
Когда запланируете могу поделиться

Отправка массива файлов через Libcurl

Добавлено: 14 Февраль 2023, 21:55
Дед Пахом
Вы про какой протокол сейчас, http, email, ftp?

Отправка массива файлов через Libcurl

Добавлено: 15 Февраль 2023, 21:48
atashe3
Я про http протокол

Отправка массива файлов через Libcurl

Добавлено: 15 Февраль 2023, 22:37
Дед Пахом
Ну я не думал об этом, потому что не знал, что есть такая проблема.
Хотелось бы для начала узнать, а что не так с отправкой больших файлов? Медленно или вообще не работает?

Рекомендованный способ:

Код: Выделить всё

  curl.Init()
  curl.AddHttpHeader('ContentType:application/x-www-form-urlencoded;  charset=utf-8')
  curl.SetHttpHeaders() 

  mime.Init(curl)
  part = mime.AddPart()
  mime.SetFileData(part, pInputFile)  ! Передаём в libcurl.dll только имя файла, остальное она сделает сама
  mime.SetName(part, 'InputFile')
  
  curl.SetMimePost(mime)
  rc = curl.SendRequest(url)
причём загрузка содержимого файла реализована в самой библиотеке:
Документация libcurl писал(а):The contents of the file is read during the file transfer in a streaming manner to allow huge files to get transferred without using much memory.

Отправка массива файлов через Libcurl

Добавлено: 16 Февраль 2023, 22:09
atashe3
Спасибо за пример и цитату
я не знал о таком применении функции

У меня была проблема с приемом т.е. загрузкой файла очень большого файла с постоянно рвущемся каналом связи по http.
Curl отрабатывает свой таймаут в методе ReadFile и разрывает соединение если хост пропал или еще что.
Поэтому пришлось сделать перегруженный метод ReadFile что бы подсчитывал сколько он загрузил до разрыва связи и снова пытался загрузить с места где остановился в предыдущий раз. И так до конца файла

Отправка массива файлов через Libcurl

Добавлено: 17 Февраль 2023, 0:36
Дед Пахом
Виноват, я неверно истолковал "загрузку больших файлов" как загрузку с клиента на сервер.
Давайте Ваш ReadFile.

Отправка массива файлов через Libcurl

Добавлено: 17 Февраль 2023, 1:57
Admin
А Сервер какой нибудь CRC или хеш файла умеет отдавать что бы сверить и понять что файл принят корректно?

Отправка массива файлов через Libcurl

Добавлено: 17 Февраль 2023, 12:37
Дед Пахом
Content-Length разве что.

Отправка массива файлов через Libcurl

Добавлено: 17 Февраль 2023, 14:38
Admin
Дед Пахом писал(а): 17 Февраль 2023, 12:37 Content-Length разве что.
Это естессно но совсем не то :)

Отправка массива файлов через Libcurl

Добавлено: 18 Февраль 2023, 0:04
atashe3
Коллеги приветствую
Вот пример загрузки
!скачиваем файл
cc# = DownloadFileHttpGet2Part(s_URL, |
'DownFile.png', |
, |
'', |
, |
'', |
i_FileSize, |
i_FileSizeUpload, |
0)

Исходники прилагаю https://disk.yandex.ru/d/3Rd8taHhL7xs5A
в исходнике указан url на маленький файл, для проверки надо скачивать avi

Отправка массива файлов через Libcurl

Добавлено: 18 Февраль 2023, 0:18
Дед Пахом
Спасибо, что весь Clarion не упаковали. Короче, троян там, кидайте только clw+inc. Лучше прямо сюда.