xref: /curl/tests/libtest/lib1540.c (revision b2dc9554)
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 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.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  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 #include "test.h"
25 
26 #include "testtrace.h"
27 #include "testutil.h"
28 #include "warnless.h"
29 #include "memdebug.h"
30 
31 struct transfer_status {
32   CURL *easy;
33   int halted;
34   int counter; /* count write callback invokes */
35   int please;  /* number of times xferinfo is called while halted */
36 };
37 
please_continue(void * userp,curl_off_t dltotal,curl_off_t dlnow,curl_off_t ultotal,curl_off_t ulnow)38 static int please_continue(void *userp,
39                            curl_off_t dltotal,
40                            curl_off_t dlnow,
41                            curl_off_t ultotal,
42                            curl_off_t ulnow)
43 {
44   struct transfer_status *st = (struct transfer_status *)userp;
45   (void)dltotal;
46   (void)dlnow;
47   (void)ultotal;
48   (void)ulnow;
49   if(st->halted) {
50     st->please++;
51     if(st->please == 2) {
52       /* waited enough, unpause! */
53       curl_easy_pause(st->easy, CURLPAUSE_CONT);
54     }
55   }
56   fprintf(stderr, "xferinfo: paused %d\n", st->halted);
57   return 0; /* go on */
58 }
59 
header_callback(void * ptr,size_t size,size_t nmemb,void * userp)60 static size_t header_callback(void *ptr, size_t size, size_t nmemb,
61                               void *userp)
62 {
63   size_t len = size * nmemb;
64   (void)userp;
65   (void)fwrite(ptr, size, nmemb, stdout);
66   return len;
67 }
68 
write_callback(void * ptr,size_t size,size_t nmemb,void * userp)69 static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userp)
70 {
71   struct transfer_status *st = (struct transfer_status *)userp;
72   size_t len = size * nmemb;
73   st->counter++;
74   if(st->counter > 1) {
75     /* the first call puts us on pause, so subsequent calls are after
76        unpause */
77     fwrite(ptr, size, nmemb, stdout);
78     return len;
79   }
80   if(len)
81     printf("Got bytes but pausing!\n");
82   st->halted = 1;
83   return CURL_WRITEFUNC_PAUSE;
84 }
85 
test(char * URL)86 CURLcode test(char *URL)
87 {
88   CURL *curls = NULL;
89   CURLcode res = CURLE_OK;
90   struct transfer_status st;
91 
92   start_test_timing();
93 
94   memset(&st, 0, sizeof(st));
95 
96   global_init(CURL_GLOBAL_ALL);
97 
98   easy_init(curls);
99   st.easy = curls; /* to allow callbacks access */
100 
101   easy_setopt(curls, CURLOPT_URL, URL);
102   easy_setopt(curls, CURLOPT_WRITEFUNCTION, write_callback);
103   easy_setopt(curls, CURLOPT_WRITEDATA, &st);
104   easy_setopt(curls, CURLOPT_HEADERFUNCTION, header_callback);
105   easy_setopt(curls, CURLOPT_HEADERDATA, &st);
106 
107   easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, please_continue);
108   easy_setopt(curls, CURLOPT_XFERINFODATA, &st);
109   easy_setopt(curls, CURLOPT_NOPROGRESS, 0L);
110 
111   libtest_debug_config.nohex = 1;
112   libtest_debug_config.tracetime = 1;
113   test_setopt(curls, CURLOPT_DEBUGDATA, &libtest_debug_config);
114   easy_setopt(curls, CURLOPT_DEBUGFUNCTION, libtest_debug_cb);
115   easy_setopt(curls, CURLOPT_VERBOSE, 1L);
116 
117   res = curl_easy_perform(curls);
118 
119 test_cleanup:
120 
121   curl_easy_cleanup(curls);
122   curl_global_cleanup();
123 
124   return res; /* return the final return code */
125 }
126