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\x0a";
     32 #else
     33   "this is what we post to the silly web server\n";
     34 #endif
     35 
     36 struct WriteThis {
     37   char *readptr;
     38   curl_off_t sizeleft;
     39 };
     40 
     41 static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
     42 {
     43 #ifdef LIB644
     44   (void)ptr;
     45   (void)size;
     46   (void)nmemb;
     47   (void)userp;
     48   return CURL_READFUNC_ABORT;
     49 #else
     50 
     51   struct WriteThis *pooh = (struct WriteThis *)userp;
     52   int eof = !*pooh->readptr;
     53 
     54   if(size*nmemb < 1)
     55     return 0;
     56 
     57 #ifndef LIB645
     58   eof = pooh->sizeleft <= 0;
     59   if(!eof)
     60     pooh->sizeleft--;
     61 #endif
     62 
     63   if(!eof) {
     64     *ptr = *pooh->readptr;           /* copy one single byte */
     65     pooh->readptr++;                 /* advance pointer */
     66     return 1;                        /* we return 1 byte at a time! */
     67   }
     68 
     69   return 0;                         /* no more data left to deliver */
     70 #endif
     71 }
     72 
     73 static int once(char *URL, bool oldstyle)
     74 {
     75   CURL *curl;
     76   CURLcode res = CURLE_OK;
     77 
     78   curl_mime *mime = NULL;
     79   curl_mimepart *part = NULL;
     80   struct WriteThis pooh;
     81   struct WriteThis pooh2;
     82   curl_off_t datasize = -1;
     83 
     84   pooh.readptr = data;
     85 #ifndef LIB645
     86   datasize = (curl_off_t)strlen(data);
     87 #endif
     88   pooh.sizeleft = datasize;
     89 
     90   curl = curl_easy_init();
     91   if(!curl) {
     92     fprintf(stderr, "curl_easy_init() failed\n");
     93     curl_global_cleanup();
     94     return TEST_ERR_MAJOR_BAD;
     95   }
     96 
     97   mime = curl_mime_init(curl);
     98   if(!mime) {
     99     fprintf(stderr, "curl_mime_init() failed\n");
    100     curl_easy_cleanup(curl);
    101     curl_global_cleanup();
    102     return TEST_ERR_MAJOR_BAD;
    103   }
    104 
    105   part = curl_mime_addpart(mime);
    106   if(!part) {
    107     fprintf(stderr, "curl_mime_addpart(1) failed\n");
    108     curl_mime_free(mime);
    109     curl_easy_cleanup(curl);
    110     curl_global_cleanup();
    111     return TEST_ERR_MAJOR_BAD;
    112   }
    113 
    114   /* Fill in the file upload part */
    115   if(oldstyle) {
    116     res = curl_mime_name(part, "sendfile");
    117     if(!res)
    118       res = curl_mime_data_cb(part, datasize, read_callback,
    119                               NULL, NULL, &pooh);
    120     if(!res)
    121       res = curl_mime_filename(part, "postit2.c");
    122   }
    123   else {
    124     /* new style */
    125     res = curl_mime_name(part, "sendfile alternative");
    126     if(!res)
    127       res = curl_mime_data_cb(part, datasize, read_callback,
    128                               NULL, NULL, &pooh);
    129     if(!res)
    130       res = curl_mime_filename(part, "file name 2");
    131   }
    132 
    133   if(res)
    134     printf("curl_mime_xxx(1) = %s\n", curl_easy_strerror(res));
    135 
    136   /* Now add the same data with another name and make it not look like
    137      a file upload but still using the callback */
    138 
    139   pooh2.readptr = data;
    140 #ifndef LIB645
    141   datasize = (curl_off_t)strlen(data);
    142 #endif
    143   pooh2.sizeleft = datasize;
    144 
    145   part = curl_mime_addpart(mime);
    146   if(!part) {
    147     fprintf(stderr, "curl_mime_addpart(2) failed\n");
    148     curl_mime_free(mime);
    149     curl_easy_cleanup(curl);
    150     curl_global_cleanup();
    151     return TEST_ERR_MAJOR_BAD;
    152   }
    153   /* Fill in the file upload part */
    154   res = curl_mime_name(part, "callbackdata");
    155   if(!res)
    156     res = curl_mime_data_cb(part, datasize, read_callback,
    157                             NULL, NULL, &pooh2);
    158 
    159   if(res)
    160     printf("curl_mime_xxx(2) = %s\n", curl_easy_strerror(res));
    161 
    162   part = curl_mime_addpart(mime);
    163   if(!part) {
    164     fprintf(stderr, "curl_mime_addpart(3) failed\n");
    165     curl_mime_free(mime);
    166     curl_easy_cleanup(curl);
    167     curl_global_cleanup();
    168     return TEST_ERR_MAJOR_BAD;
    169   }
    170 
    171   /* Fill in the filename field */
    172   res = curl_mime_name(part, "filename");
    173   if(!res)
    174     res = curl_mime_data(part,
    175 #ifdef CURL_DOES_CONVERSIONS
    176                          /* ASCII representation with escape
    177                             sequences for non-ASCII platforms */
    178                          "\x70\x6f\x73\x74\x69\x74\x32\x2e\x63",
    179 #else
    180                           "postit2.c",
    181 #endif
    182                           CURL_ZERO_TERMINATED);
    183 
    184   if(res)
    185     printf("curl_mime_xxx(3) = %s\n", curl_easy_strerror(res));
    186 
    187   /* Fill in a submit field too */
    188   part = curl_mime_addpart(mime);
    189   if(!part) {
    190     fprintf(stderr, "curl_mime_addpart(4) failed\n");
    191     curl_mime_free(mime);
    192     curl_easy_cleanup(curl);
    193     curl_global_cleanup();
    194     return TEST_ERR_MAJOR_BAD;
    195   }
    196   res = curl_mime_name(part, "submit");
    197   if(!res)
    198     res = curl_mime_data(part,
    199 #ifdef CURL_DOES_CONVERSIONS
    200                          /* ASCII representation with escape
    201                             sequences for non-ASCII platforms */
    202                          "\x73\x65\x6e\x64",
    203 #else
    204                           "send",
    205 #endif
    206                           CURL_ZERO_TERMINATED);
    207 
    208   if(res)
    209     printf("curl_mime_xxx(4) = %s\n", curl_easy_strerror(res));
    210 
    211   part = curl_mime_addpart(mime);
    212   if(!part) {
    213     fprintf(stderr, "curl_mime_addpart(5) failed\n");
    214     curl_mime_free(mime);
    215     curl_easy_cleanup(curl);
    216     curl_global_cleanup();
    217     return TEST_ERR_MAJOR_BAD;
    218   }
    219   res = curl_mime_name(part, "somename");
    220   if(!res)
    221     res = curl_mime_filename(part, "somefile.txt");
    222   if(!res)
    223     res = curl_mime_data(part, "blah blah", 9);
    224 
    225   if(res)
    226     printf("curl_mime_xxx(5) = %s\n", curl_easy_strerror(res));
    227 
    228   /* First set the URL that is about to receive our POST. */
    229   test_setopt(curl, CURLOPT_URL, URL);
    230 
    231   /* send a multi-part mimepost */
    232   test_setopt(curl, CURLOPT_MIMEPOST, mime);
    233 
    234   /* get verbose debug output please */
    235   test_setopt(curl, CURLOPT_VERBOSE, 1L);
    236 
    237   /* include headers in the output */
    238   test_setopt(curl, CURLOPT_HEADER, 1L);
    239 
    240   /* Perform the request, res will get the return code */
    241   res = curl_easy_perform(curl);
    242 
    243 test_cleanup:
    244 
    245   /* always cleanup */
    246   curl_easy_cleanup(curl);
    247 
    248   /* now cleanup the mimepost structure */
    249   curl_mime_free(mime);
    250 
    251   return res;
    252 }
    253 
    254 static int cyclic_add(void)
    255 {
    256   CURL *easy = curl_easy_init();
    257   curl_mime *mime = curl_mime_init(easy);
    258   curl_mimepart *part = curl_mime_addpart(mime);
    259   CURLcode a1 = curl_mime_subparts(part, mime);
    260 
    261   if(a1 == CURLE_BAD_FUNCTION_ARGUMENT) {
    262     curl_mime *submime = curl_mime_init(easy);
    263     curl_mimepart *subpart = curl_mime_addpart(submime);
    264 
    265     curl_mime_subparts(part, submime);
    266     a1 = curl_mime_subparts(subpart, mime);
    267   }
    268 
    269   curl_mime_free(mime);
    270   curl_easy_cleanup(easy);
    271   if(a1 != CURLE_BAD_FUNCTION_ARGUMENT)
    272     /* that should have failed */
    273     return 1;
    274 
    275   return 0;
    276 }
    277 
    278 int test(char *URL)
    279 {
    280   int res;
    281 
    282   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    283     fprintf(stderr, "curl_global_init() failed\n");
    284     return TEST_ERR_MAJOR_BAD;
    285   }
    286 
    287   res = once(URL, TRUE); /* old */
    288   if(!res)
    289     res = once(URL, FALSE); /* new */
    290 
    291   if(!res)
    292     res = cyclic_add();
    293 
    294   curl_global_cleanup();
    295 
    296   return res;
    297 }
    298