xref: /curl/tests/libtest/lib677.c (revision 71cf0d1f)
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 "testutil.h"
27 #include "warnless.h"
28 #include "memdebug.h"
29 
30 static const char testcmd[] = "A1 IDLE\r\n";
31 static char testbuf[1024];
32 
test(char * URL)33 CURLcode test(char *URL)
34 {
35   CURLM *mcurl;
36   CURL *curl = NULL;
37   int mrun;
38   curl_socket_t sock = CURL_SOCKET_BAD;
39   time_t start = time(NULL);
40   int state = 0;
41   ssize_t pos = 0;
42   CURLcode res = CURLE_OK;
43 
44   global_init(CURL_GLOBAL_DEFAULT);
45   multi_init(mcurl);
46   easy_init(curl);
47 
48   easy_setopt(curl, CURLOPT_VERBOSE, 1L);
49   easy_setopt(curl, CURLOPT_URL, URL);
50   easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
51   if(curl_multi_add_handle(mcurl, curl))
52     goto test_cleanup;
53 
54   while(time(NULL) - start < 5) {
55     struct curl_waitfd waitfd;
56 
57     multi_perform(mcurl, &mrun);
58     for(;;) {
59       int i;
60       struct CURLMsg *m = curl_multi_info_read(mcurl, &i);
61 
62       if(!m)
63         break;
64       if(m->msg == CURLMSG_DONE && m->easy_handle == curl) {
65         curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sock);
66         if(sock == CURL_SOCKET_BAD)
67           goto test_cleanup;
68         printf("Connected fine, extracted socket. Moving on\n");
69       }
70     }
71 
72     if(sock != CURL_SOCKET_BAD) {
73       waitfd.events = state ? CURL_WAIT_POLLIN : CURL_WAIT_POLLOUT;
74       waitfd.revents = 0;
75       curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sock);
76       waitfd.fd = sock;
77     }
78     curl_multi_wait(mcurl, &waitfd, sock == CURL_SOCKET_BAD ? 0 : 1, 50,
79                     &mrun);
80     if((sock != CURL_SOCKET_BAD) && (waitfd.revents & waitfd.events)) {
81       size_t len = 0;
82 
83       if(!state) {
84         CURLcode ec;
85         ec = curl_easy_send(curl, testcmd + pos,
86                             sizeof(testcmd) - 1 - pos, &len);
87         if(ec == CURLE_AGAIN) {
88           continue;
89         }
90         else if(ec) {
91           fprintf(stderr, "curl_easy_send() failed, with code %d (%s)\n",
92                   (int)ec, curl_easy_strerror(ec));
93           res = ec;
94           goto test_cleanup;
95         }
96         if(len > 0)
97           pos += len;
98         else
99           pos = 0;
100         if(pos == sizeof(testcmd) - 1) {
101           state++;
102           pos = 0;
103         }
104       }
105       else if(pos < (ssize_t)sizeof(testbuf)) {
106         CURLcode ec;
107         ec = curl_easy_recv(curl, testbuf + pos, sizeof(testbuf) - pos, &len);
108         if(ec == CURLE_AGAIN) {
109           continue;
110         }
111         else if(ec) {
112           fprintf(stderr, "curl_easy_recv() failed, with code %d (%s)\n",
113                   (int)ec, curl_easy_strerror(ec));
114           res = ec;
115           goto test_cleanup;
116         }
117         if(len > 0)
118           pos += len;
119       }
120       if(len <= 0)
121         sock = CURL_SOCKET_BAD;
122     }
123   }
124 
125   if(state) {
126     fwrite(testbuf, pos, 1, stdout);
127     putchar('\n');
128   }
129 
130   curl_multi_remove_handle(mcurl, curl);
131 test_cleanup:
132   curl_easy_cleanup(curl);
133   curl_multi_cleanup(mcurl);
134 
135   curl_global_cleanup();
136   return res;
137 }
138