xref: /curl/tests/libtest/lib677.c (revision 25cbc2f7)
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 cmd[] = "A1 IDLE\r\n";
31 static char buf[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, 500,
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, cmd + pos, sizeof(cmd) - 1 - pos, &len);
86         if(ec != CURLE_OK) {
87           fprintf(stderr, "curl_easy_send() failed, with code %d (%s)\n",
88                   (int)ec, curl_easy_strerror(ec));
89           res = ec;
90           goto test_cleanup;
91         }
92         if(len > 0)
93           pos += len;
94         else
95           pos = 0;
96         if(pos == sizeof(cmd) - 1) {
97           state++;
98           pos = 0;
99         }
100       }
101       else if(pos < (ssize_t)sizeof(buf)) {
102         CURLcode ec;
103         ec = curl_easy_recv(curl, buf + pos, sizeof(buf) - pos, &len);
104         if(ec != CURLE_OK) {
105           fprintf(stderr, "curl_easy_recv() failed, with code %d (%s)\n",
106                   (int)ec, curl_easy_strerror(ec));
107           res = ec;
108           goto test_cleanup;
109         }
110         if(len > 0)
111           pos += len;
112       }
113       if(len <= 0)
114         sock = CURL_SOCKET_BAD;
115     }
116   }
117 
118   if(state) {
119     fwrite(buf, pos, 1, stdout);
120     putchar('\n');
121   }
122 
123   curl_multi_remove_handle(mcurl, curl);
124 test_cleanup:
125   curl_easy_cleanup(curl);
126   curl_multi_cleanup(mcurl);
127 
128   curl_global_cleanup();
129   return res;
130 }
131