Annotation of embedaddon/curl/tests/libtest/lib1533.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@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: 
                     23: /*
                     24:  * This test sends data with CURLOPT_KEEP_SENDING_ON_ERROR.
                     25:  * The server responds with an early error response.
                     26:  * The test is successful if the connection can be reused for the next request,
                     27:  * because this implies that the data has been sent completely to the server.
                     28:  */
                     29: 
                     30: #include "test.h"
                     31: 
                     32: #include "memdebug.h"
                     33: 
                     34: struct cb_data {
                     35:   CURL *easy_handle;
                     36:   int response_received;
                     37:   int paused;
                     38:   size_t remaining_bytes;
                     39: };
                     40: 
                     41: 
                     42: static void reset_data(struct cb_data *data, CURL *curl)
                     43: {
                     44:   data->easy_handle = curl;
                     45:   data->response_received = 0;
                     46:   data->paused = 0;
                     47:   data->remaining_bytes = 3;
                     48: }
                     49: 
                     50: 
                     51: static size_t read_callback(void *ptr, size_t size, size_t nitems,
                     52:                             void *userdata)
                     53: {
                     54:   struct cb_data *data = (struct cb_data *)userdata;
                     55: 
                     56:   /* wait until the server has sent all response headers */
                     57:   if(data->response_received) {
                     58:     size_t totalsize = nitems * size;
                     59: 
                     60:     size_t bytes_to_send = data->remaining_bytes;
                     61:     if(bytes_to_send > totalsize) {
                     62:       bytes_to_send = totalsize;
                     63:     }
                     64: 
                     65:     memset(ptr, 'a', bytes_to_send);
                     66:     data->remaining_bytes -= bytes_to_send;
                     67: 
                     68:     return bytes_to_send;
                     69:   }
                     70:   else {
                     71:     data->paused = 1;
                     72:     return CURL_READFUNC_PAUSE;
                     73:   }
                     74: }
                     75: 
                     76: 
                     77: static size_t write_callback(char *ptr, size_t size, size_t nmemb,
                     78:                              void *userdata)
                     79: {
                     80:   struct cb_data *data = (struct cb_data *)userdata;
                     81:   size_t totalsize = nmemb * size;
                     82: 
                     83:   /* unused parameter */
                     84:   (void)ptr;
                     85: 
                     86:   /* all response headers have been received */
                     87:   data->response_received = 1;
                     88: 
                     89:   if(data->paused) {
                     90:     /* continue to send request body data */
                     91:     data->paused = 0;
                     92:     curl_easy_pause(data->easy_handle, CURLPAUSE_CONT);
                     93:   }
                     94: 
                     95:   return totalsize;
                     96: }
                     97: 
                     98: 
                     99: static int perform_and_check_connections(CURL *curl, const char *description,
                    100:                                          long expected_connections)
                    101: {
                    102:   CURLcode res;
                    103:   long connections = 0;
                    104: 
                    105:   res = curl_easy_perform(curl);
                    106:   if(res != CURLE_OK) {
                    107:     fprintf(stderr, "curl_easy_perform() failed\n");
                    108:     return TEST_ERR_MAJOR_BAD;
                    109:   }
                    110: 
                    111:   res = curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &connections);
                    112:   if(res != CURLE_OK) {
                    113:     fprintf(stderr, "curl_easy_getinfo() failed\n");
                    114:     return TEST_ERR_MAJOR_BAD;
                    115:   }
                    116: 
                    117:   fprintf(stderr, "%s: expected: %ld connections; actual: %ld connections\n",
                    118:           description, expected_connections, connections);
                    119: 
                    120:   if(connections != expected_connections) {
                    121:     return TEST_ERR_FAILURE;
                    122:   }
                    123: 
                    124:   return TEST_ERR_SUCCESS;
                    125: }
                    126: 
                    127: 
                    128: int test(char *URL)
                    129: {
                    130:   struct cb_data data;
                    131:   CURL *curl = NULL;
                    132:   CURLcode res = CURLE_FAILED_INIT;
                    133: 
                    134:   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
                    135:     fprintf(stderr, "curl_global_init() failed\n");
                    136:     return TEST_ERR_MAJOR_BAD;
                    137:   }
                    138: 
                    139:   curl = curl_easy_init();
                    140:   if(curl == NULL) {
                    141:     fprintf(stderr, "curl_easy_init() failed\n");
                    142:     curl_global_cleanup();
                    143:     return TEST_ERR_MAJOR_BAD;
                    144:   }
                    145: 
                    146:   reset_data(&data, curl);
                    147: 
                    148:   test_setopt(curl, CURLOPT_URL, URL);
                    149:   test_setopt(curl, CURLOPT_POST, 1L);
                    150:   test_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
                    151:               (curl_off_t)data.remaining_bytes);
                    152:   test_setopt(curl, CURLOPT_VERBOSE, 1L);
                    153:   test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
                    154:   test_setopt(curl, CURLOPT_READDATA, &data);
                    155:   test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
                    156:   test_setopt(curl, CURLOPT_WRITEDATA, &data);
                    157: 
                    158:   res = perform_and_check_connections(curl,
                    159:     "First request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
                    160:   if(res != TEST_ERR_SUCCESS) {
                    161:     goto test_cleanup;
                    162:   }
                    163: 
                    164:   reset_data(&data, curl);
                    165: 
                    166:   res = perform_and_check_connections(curl,
                    167:     "Second request without CURLOPT_KEEP_SENDING_ON_ERROR", 1);
                    168:   if(res != TEST_ERR_SUCCESS) {
                    169:     goto test_cleanup;
                    170:   }
                    171: 
                    172:   test_setopt(curl, CURLOPT_KEEP_SENDING_ON_ERROR, 1L);
                    173: 
                    174:   reset_data(&data, curl);
                    175: 
                    176:   res = perform_and_check_connections(curl,
                    177:     "First request with CURLOPT_KEEP_SENDING_ON_ERROR", 1);
                    178:   if(res != TEST_ERR_SUCCESS) {
                    179:     goto test_cleanup;
                    180:   }
                    181: 
                    182:   reset_data(&data, curl);
                    183: 
                    184:   res = perform_and_check_connections(curl,
                    185:     "Second request with CURLOPT_KEEP_SENDING_ON_ERROR", 0);
                    186:   if(res != TEST_ERR_SUCCESS) {
                    187:     goto test_cleanup;
                    188:   }
                    189: 
                    190:   res = TEST_ERR_SUCCESS;
                    191: 
                    192: test_cleanup:
                    193: 
                    194:   curl_easy_cleanup(curl);
                    195: 
                    196:   curl_global_cleanup();
                    197: 
                    198:   return (int)res;
                    199: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>