xref: /curl/tests/libtest/lib2304.c (revision d78e129d)
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 
25 #include "test.h"
26 
27 #ifndef CURL_DISABLE_WEBSOCKETS
28 
send_ping(CURL * curl,const char * send_payload)29 static CURLcode send_ping(CURL *curl, const char *send_payload)
30 {
31   size_t sent;
32   CURLcode result =
33     curl_ws_send(curl, send_payload, strlen(send_payload), &sent, 0,
34                  CURLWS_PING);
35   fprintf(stderr,
36           "ws: curl_ws_send returned %d, sent %d\n", result, (int)sent);
37 
38   return result;
39 }
40 
recv_pong(CURL * curl,const char * expected_payload)41 static CURLcode recv_pong(CURL *curl, const char *expected_payload)
42 {
43   size_t rlen;
44   const struct curl_ws_frame *meta;
45   char buffer[256];
46   CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta);
47   if(!result) {
48     if(meta->flags & CURLWS_PONG) {
49       int same = 0;
50       fprintf(stderr, "ws: got PONG back\n");
51       if(rlen == strlen(expected_payload)) {
52         if(!memcmp(expected_payload, buffer, rlen)) {
53           fprintf(stderr, "ws: got the same payload back\n");
54           same = 1;
55         }
56       }
57       if(!same)
58         fprintf(stderr, "ws: did NOT get the same payload back\n");
59     }
60     else {
61       fprintf(stderr, "recv_pong: got %d bytes rflags %x\n", (int)rlen,
62               meta->flags);
63     }
64   }
65   fprintf(stderr, "ws: curl_ws_recv returned %d, received %d\n", result,
66           (int)rlen);
67   return result;
68 }
69 
recv_any(CURL * curl)70 static CURLcode recv_any(CURL *curl)
71 {
72   size_t rlen;
73   const struct curl_ws_frame *meta;
74   char buffer[256];
75   CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta);
76   if(result)
77     return result;
78 
79   fprintf(stderr, "recv_any: got %u bytes rflags %x\n", (int)rlen,
80           meta->flags);
81   return CURLE_OK;
82 }
83 
84 /* just close the connection */
websocket_close(CURL * curl)85 static void websocket_close(CURL *curl)
86 {
87   size_t sent;
88   CURLcode result =
89     curl_ws_send(curl, "", 0, &sent, 0, CURLWS_CLOSE);
90   fprintf(stderr,
91           "ws: curl_ws_send returned %d, sent %u\n", result, (int)sent);
92 }
93 
websocket(CURL * curl)94 static void websocket(CURL *curl)
95 {
96   int i = 0;
97   fprintf(stderr, "ws: websocket() starts\n");
98   do {
99     recv_any(curl);
100     fprintf(stderr, "Send ping\n");
101     if(send_ping(curl, "foobar"))
102       return;
103     fprintf(stderr, "Receive pong\n");
104     if(recv_pong(curl, "foobar")) {
105       printf("Connection closed\n");
106       return;
107     }
108     sleep(2);
109   } while(i++ < 10);
110   websocket_close(curl);
111 }
112 
test(char * URL)113 CURLcode test(char *URL)
114 {
115   CURL *curl;
116   CURLcode res = CURLE_OK;
117 
118   global_init(CURL_GLOBAL_ALL);
119 
120   curl = curl_easy_init();
121   if(curl) {
122     curl_easy_setopt(curl, CURLOPT_URL, URL);
123 
124     /* use the callback style */
125     curl_easy_setopt(curl, CURLOPT_USERAGENT, "websocket/2304");
126     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
127     curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */
128     res = curl_easy_perform(curl);
129     fprintf(stderr, "curl_easy_perform() returned %d\n", res);
130     if(res == CURLE_OK)
131       websocket(curl);
132 
133     /* always cleanup */
134     curl_easy_cleanup(curl);
135   }
136   curl_global_cleanup();
137   return res;
138 }
139 
140 #else
141 NO_SUPPORT_BUILT_IN
142 #endif
143