Home | History | Annotate | Download | only in libtest
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 #include "test.h"
     23 
     24 #include "memdebug.h"
     25 
     26 static char data[] =
     27 #ifdef CURL_DOES_CONVERSIONS
     28   /* ASCII representation with escape sequences for non-ASCII platforms */
     29   "\x74\x68\x69\x73\x20\x69\x73\x20\x77\x68\x61\x74\x20\x77\x65\x20\x70"
     30   "\x6f\x73\x74\x20\x74\x6f\x20\x74\x68\x65\x20\x73\x69\x6c\x6c\x79\x20"
     31   "\x77\x65\x62\x20\x73\x65\x72\x76\x65\x72";
     32 #else
     33   "this is what we post to the silly web server";
     34 #endif
     35 
     36 static const char name[] = "fieldname";
     37 
     38 
     39 /* This test attempts to use all form API features that are not
     40  * used elsewhere.
     41  */
     42 
     43 /* curl_formget callback to count characters. */
     44 static size_t count_chars(void *userp, const char *buf, size_t len)
     45 {
     46   size_t *pcounter = (size_t *) userp;
     47 
     48   (void) buf;
     49   *pcounter += len;
     50   return len;
     51 }
     52 
     53 
     54 int test(char *URL)
     55 {
     56   CURL *curl = NULL;
     57   CURLcode res = TEST_ERR_MAJOR_BAD;
     58   CURLFORMcode formrc;
     59   struct curl_slist *headers, *headers2 = NULL;
     60   struct curl_httppost *formpost = NULL;
     61   struct curl_httppost *lastptr = NULL;
     62   struct curl_forms formarray[3];
     63   size_t formlength = 0;
     64   char flbuf[32];
     65 
     66   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
     67     fprintf(stderr, "curl_global_init() failed\n");
     68     return TEST_ERR_MAJOR_BAD;
     69   }
     70 
     71   /* Check proper name and data copying, as well as headers. */
     72   headers = curl_slist_append(NULL, "X-customheader-1: Header 1 data");
     73   if(!headers) {
     74     goto test_cleanup;
     75   }
     76   headers2 = curl_slist_append(headers, "X-customheader-2: Header 2 data");
     77   if(!headers2) {
     78     goto test_cleanup;
     79   }
     80   headers = headers2;
     81   headers2 = curl_slist_append(headers, "Content-Type: text/plain");
     82   if(!headers2) {
     83     goto test_cleanup;
     84   }
     85   headers = headers2;
     86   formrc = curl_formadd(&formpost, &lastptr,
     87                         CURLFORM_COPYNAME, &name,
     88                         CURLFORM_COPYCONTENTS, &data,
     89                         CURLFORM_CONTENTHEADER, headers,
     90                         CURLFORM_END);
     91 
     92   if(formrc) {
     93     printf("curl_formadd(1) = %d\n", (int) formrc);
     94     goto test_cleanup;
     95   }
     96 
     97   /* Use a form array for the non-copy test. */
     98   formarray[0].option = CURLFORM_PTRCONTENTS;
     99   formarray[0].value = data;
    100   formarray[1].option = CURLFORM_CONTENTSLENGTH;
    101   formarray[1].value = (char *) strlen(data) - 1;
    102   formarray[2].option = CURLFORM_END;
    103   formarray[2].value = NULL;
    104   formrc = curl_formadd(&formpost,
    105                         &lastptr,
    106                         CURLFORM_PTRNAME, name,
    107                         CURLFORM_NAMELENGTH, strlen(name) - 1,
    108                         CURLFORM_ARRAY, formarray,
    109                         CURLFORM_FILENAME, "remotefile.txt",
    110                         CURLFORM_END);
    111 
    112   if(formrc) {
    113     printf("curl_formadd(2) = %d\n", (int) formrc);
    114     goto test_cleanup;
    115   }
    116 
    117   /* Now change in-memory data to affect CURLOPT_PTRCONTENTS value.
    118      Copied values (first field) must not be affected.
    119      CURLOPT_PTRNAME actually copies the name thus we do not test this here. */
    120   data[0]++;
    121 
    122   /* Check multi-files and content type propagation. */
    123   formrc = curl_formadd(&formpost,
    124                         &lastptr,
    125                         CURLFORM_COPYNAME, "multifile",
    126                         CURLFORM_FILE, libtest_arg2,    /* Set in first.c. */
    127                         CURLFORM_FILE, libtest_arg2,
    128                         CURLFORM_CONTENTTYPE, "text/whatever",
    129                         CURLFORM_FILE, libtest_arg2,
    130                         CURLFORM_END);
    131 
    132   if(formrc) {
    133     printf("curl_formadd(3) = %d\n", (int) formrc);
    134     goto test_cleanup;
    135   }
    136 
    137   /* Check data from file content. */
    138   formrc = curl_formadd(&formpost,
    139                         &lastptr,
    140                         CURLFORM_COPYNAME, "filecontents",
    141                         CURLFORM_FILECONTENT, libtest_arg2,
    142                         CURLFORM_END);
    143 
    144   if(formrc) {
    145     printf("curl_formadd(4) = %d\n", (int) formrc);
    146     goto test_cleanup;
    147   }
    148 
    149   /* Measure the current form length.
    150    * This is done before including stdin data because we want to reuse it
    151    * and stdin cannot be rewound.
    152    */
    153   curl_formget(formpost, (void *) &formlength, count_chars);
    154 
    155   /* Include length in data for external check. */
    156   curl_msnprintf(flbuf, sizeof flbuf, "%lu", (unsigned long) formlength);
    157   formrc = curl_formadd(&formpost,
    158                         &lastptr,
    159                         CURLFORM_COPYNAME, "formlength",
    160                         CURLFORM_COPYCONTENTS, &flbuf,
    161                         CURLFORM_END);
    162   if(formrc) {
    163     printf("curl_formadd(5) = %d\n", (int) formrc);
    164     goto test_cleanup;
    165   }
    166 
    167   /* Check stdin (may be problematic on some platforms). */
    168   formrc = curl_formadd(&formpost,
    169                         &lastptr,
    170                         CURLFORM_COPYNAME, "standardinput",
    171                         CURLFORM_FILE, "-",
    172                         CURLFORM_END);
    173   if(formrc) {
    174     printf("curl_formadd(6) = %d\n", (int) formrc);
    175     goto test_cleanup;
    176   }
    177 
    178   curl = curl_easy_init();
    179   if(!curl) {
    180     fprintf(stderr, "curl_easy_init() failed\n");
    181     goto test_cleanup;
    182   }
    183 
    184   /* First set the URL that is about to receive our POST. */
    185   test_setopt(curl, CURLOPT_URL, URL);
    186 
    187   /* send a multi-part formpost */
    188   test_setopt(curl, CURLOPT_HTTPPOST, formpost);
    189 
    190   /* get verbose debug output please */
    191   test_setopt(curl, CURLOPT_VERBOSE, 1L);
    192 
    193   /* include headers in the output */
    194   test_setopt(curl, CURLOPT_HEADER, 1L);
    195 
    196   /* Perform the request, res will get the return code */
    197   res = curl_easy_perform(curl);
    198 
    199 test_cleanup:
    200 
    201   /* always cleanup */
    202   curl_easy_cleanup(curl);
    203 
    204   /* now cleanup the formpost chain */
    205   curl_formfree(formpost);
    206   curl_slist_free_all(headers);
    207 
    208   curl_global_cleanup();
    209 
    210   return res;
    211 }
    212