Как использовать CURL formadd загрузить файл с полями отправки в C ++? - PullRequest
0 голосов
/ 13 апреля 2020

я хочу загрузить файл с некоторыми полями, такими как идентификатор идентификатора файла, на сервер с библиотекой CURL.

после некоторых экспериментов мне не удалось отправить даже идентификатор файла на сервер. ниже приведен код.

приветствуется любая помощь или подсказка :)

следующий код основан на библиотеке CURL, например, модуль Testlib554, вы можете загрузить исходный код с здесь.

и подробные вопросы.

сначала находятся ли файлы, которые я хочу загрузить, в правильном формате formadd? на самом деле Я хорошо понимаю, как добавить имя файла и пути к файлам

секунда, как заполнить поля или атрибуты этого перевода, ie. строка формата JSON "{" caseDesignId ": 37}" , при загрузке файла.

static int once(char *URL, bool oldstyle)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  CURLFORMcode formrc;

  struct curl_httppost *formpost = NULL;
  struct curl_httppost *lastptr = NULL;
  struct WriteThis pooh;
  struct WriteThis pooh2;

  pooh.readptr = data;
  pooh.sizeleft = strlen(data);

  /* Fill in the file upload field */
  if(oldstyle) {
    formrc = curl_formadd(&formpost,
                          &lastptr,
                          CURLFORM_COPYNAME, "sendfile",
                          CURLFORM_STREAM, &pooh,
                          CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
                          CURLFORM_FILENAME, **pathfile[0],// file i want to upload to server
                          CURLFORM_END);
  }
  else {
    /* new style */
    formrc = curl_formadd(&formpost,
                          &lastptr,
                          CURLFORM_COPYNAME, "sendfile alternative",
                          CURLFORM_STREAM, &pooh,
                          CURLFORM_CONTENTLEN, (curl_off_t)pooh.sizeleft,
                          CURLFORM_FILENAME, pathfile[0],// file i want to upload to server
                          CURLFORM_END);
  }

  if(formrc)
    printf("curl_formadd(1) = %d\n", (int)formrc);

  /* Now add the same data with another name and make it not look like
     a file upload but still using the callback */

  pooh2.readptr = data;
  pooh2.sizeleft = strlen(data);

  /* Fill in the file upload field */
  formrc = curl_formadd(&formpost,
                        &lastptr,
                        CURLFORM_COPYNAME, "callbackdata",
                        CURLFORM_STREAM, &pooh2,
                        CURLFORM_CONTENTSLENGTH, (long)pooh2.sizeleft,
                        CURLFORM_END);

  if(formrc)
    fprintf(stderr,"curl_formadd(2) = %d\n", (int)formrc);

  /* Fill in the filename field */
  formrc = curl_formadd(&formpost,
                        &lastptr,
                        CURLFORM_COPYNAME, "filename",
                        CURLFORM_COPYCONTENTS, pathfile[1],// file i want to upload to server
                        CURLFORM_END);

  if(formrc)
    printf("curl_formadd(3) = %d\n", (int)formrc);


  /* Fill in a submit field too */
  // here i want to upload "{\"caseDesignId\":88}" with the files to server ....but fails
  formrc = curl_formadd(&formpost,
                        &lastptr,
                        CURLFORM_COPYNAME, "caseDesignId",// the submit fields "key"
                        CURLFORM_COPYCONTENTS, "37",      // the submit fields "value"
                        CURLFORM_CONTENTTYPE, "text/plain",
                        CURLFORM_END);

  if(formrc)
    printf("curl_formadd(4) = %d\n", (int)formrc);

  formrc = curl_formadd(&formpost, &lastptr,
                        CURLFORM_COPYNAME, "caseDesignId",
                        CURLFORM_BUFFER, "{\"caseDesignId\":37}",
                        CURLFORM_BUFFERPTR, "{\"caseDesignId\":37}",
                        CURLFORM_BUFFERLENGTH, (long)strlen("{\"caseDesignId\":37}"),//anthoer try
                        CURLFORM_END);

  if(formrc)
    printf("curl_formadd(5) = %d\n", (int)formrc);

  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_formfree(formpost);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* First set the URL that is about to receive our POST. */
  test_setopt(curl, CURLOPT_URL, URL);

  /* Now specify we want to POST data */
  test_setopt(curl, CURLOPT_POST, 1L);

  /* Set the expected POST size */
  test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);

  /* we want to use our own read function */
  test_setopt(curl, CURLOPT_READFUNCTION, read_callback);

  /* send a multi-part formpost */
  test_setopt(curl, CURLOPT_HTTPPOST, formpost);

  /* get verbose debug output please */
  test_setopt(curl, CURLOPT_VERBOSE, 1L);

  /* include headers in the output */
  test_setopt(curl, CURLOPT_HEADER, 1L);

  /* Perform the request, res will get the return code */
  res = curl_easy_perform(curl);

test_cleanup:

  /* always cleanup */
  curl_easy_cleanup(curl);

  /* now cleanup the formpost chain */
  curl_formfree(formpost);

  return res;
}   

информация об ошибке: " ошибка статуса 400: неправильный запрос, сообщение: не удалось преобразовать значение **** в требуемый тип 'int'"

1 Ответ

0 голосов
/ 13 апреля 2020
finally, problem is solved.

first, as for the process of finding the way. tools of wireshark and postman is much helpful. with those tools, i compare the two way of uploading files with attributes. when uploading with postman i grab the package with wireshark which used as a standard format of uploading.  this maybe more helpful than the answer.

second, the main code which upload file with some attribute of one transfer goes as followed.

static int once(char *URL, bool oldstyle)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  CURLFORMcode formrc;

  int nFileSize = (0);
  struct curl_httppost *formpost = NULL;
  struct curl_httppost *lastptr = NULL;
  struct WriteThis pooh;
  struct WriteThis pooh2;
  struct WriteThis pw;
  FILE* hFile = fopen(pathfile[0], "rb+");
  if (NULL != hFile) {
      fseek(hFile, 0, SEEK_END);
      pw.sizeleft = ftell(hFile);
      fseek(hFile, 0, SEEK_SET);

      pw.readptr = (char*)malloc(pw.sizeleft + 1);
      memset(pw.readptr, 0, pw.sizeleft+1);
      nFileSize = fread(pw.readptr, 1, pw.sizeleft + 1, hFile);
      fclose(hFile);
      hFile = NULL;
  }
  pooh.readptr = data;
  pooh.sizeleft = strlen(data);

  /* Fill in the file upload field */
  if(oldstyle) {
    formrc = curl_formadd(&formpost,
                          &lastptr,
                          CURLFORM_COPYNAME, "file",
                          CURLFORM_STREAM, &pooh,
                          CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
                          CURLFORM_FILENAME, "face0.png",//"postit2.c",
                          CURLFORM_END);
  }
  else {
    /* new style */
    formrc = curl_formadd(&formpost,
                          &lastptr,
                          CURLFORM_COPYNAME, "file",
                          CURLFORM_STREAM, &pw,
                          CURLFORM_CONTENTLEN, (curl_off_t)pw.sizeleft,
                          CURLFORM_FILENAME, "face0.png",//"file name 2",
                          CURLFORM_CONTENTTYPE, "image/png",
                          CURLFORM_END);
  }

  if(formrc)
    printf("curl_formadd(1) = %d\n", (int)formrc);

  /* Now add the same data with another name and make it not look like
     a file upload but still using the callback */

  /* Fill in a submit field too */
  formrc = curl_formadd(&formpost,
                        &lastptr,
                        CURLFORM_COPYNAME, "caseDesignId",
                        CURLFORM_COPYCONTENTS, "37",
                        ///CURLFORM_CONTENTTYPE, "text/plain",
                        CURLFORM_END);

  if(formrc)
    printf("curl_formadd(4) = %d\n", (int)formrc);

  curl = curl_easy_init();
  if(!curl) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_formfree(formpost);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* First set the URL that is about to receive our POST. */
  test_setopt(curl, CURLOPT_URL, URL);

  /* Now specify we want to POST data */
  test_setopt(curl, CURLOPT_POST, 1L);

  /* Set the expected POST size */
  test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);

  /* we want to use our own read function */
  test_setopt(curl, CURLOPT_READFUNCTION, read_callback);

  /* send a multi-part formpost */
  test_setopt(curl, CURLOPT_HTTPPOST, formpost);

  /* get verbose debug output please */
  test_setopt(curl, CURLOPT_VERBOSE, 1L);

  /* include headers in the output */
  test_setopt(curl, CURLOPT_HEADER, 1L);

  /* Perform the request, res will get the return code */
  res = curl_easy_perform(curl);

test_cleanup:

  /* always cleanup */
  curl_easy_cleanup(curl);

  /* now cleanup the formpost chain */
  curl_formfree(formpost);

  return res;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...