xref: /third_party/curl/tests/libtest/lib2304.c (revision 13498266)
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#ifdef USE_WEBSOCKETS
28
29static int 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 %u, sent %u\n", (int)result, (int)sent);
37
38  return (int)result;
39}
40
41static int 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 %u bytes rflags %x\n", (int)rlen,
62              meta->flags);
63    }
64  }
65  fprintf(stderr, "ws: curl_ws_recv returned %u, received %u\n", (int)result,
66          (int)rlen);
67  return (int)result;
68}
69
70static int 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 0;
82}
83
84/* just close the connection */
85static 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 %u, sent %u\n", (int)result, (int)sent);
92}
93
94static 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(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
113int 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 %u\n", (int)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 (int)res;
138}
139
140#else
141NO_SUPPORT_BUILT_IN
142#endif
143