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
29 struct ws_data {
30 CURL *easy;
31 char buf[1024*1024];
32 size_t blen;
33 size_t nwrites;
34 int has_meta;
35 int meta_flags;
36 };
37
flush_data(struct ws_data * wd)38 static void flush_data(struct ws_data *wd)
39 {
40 size_t i;
41
42 if(!wd->nwrites)
43 return;
44
45 for(i = 0; i < wd->blen; ++i)
46 printf("%02x ", (unsigned char)wd->buf[i]);
47
48 printf("\n");
49 if(wd->has_meta)
50 printf("RECFLAGS: %x\n", wd->meta_flags);
51 else
52 fprintf(stderr, "RECFLAGS: NULL\n");
53 wd->blen = 0;
54 wd->nwrites = 0;
55 }
56
add_data(struct ws_data * wd,const char * buf,size_t blen,const struct curl_ws_frame * meta)57 static size_t add_data(struct ws_data *wd, const char *buf, size_t blen,
58 const struct curl_ws_frame *meta)
59 {
60 if((wd->nwrites == 0) ||
61 (!!meta != !!wd->has_meta) ||
62 (meta && meta->flags != wd->meta_flags)) {
63 if(wd->nwrites > 0)
64 flush_data(wd);
65 wd->has_meta = (meta != NULL);
66 wd->meta_flags = meta ? meta->flags : 0;
67 }
68
69 if(wd->blen + blen > sizeof(wd->buf)) {
70 return 0;
71 }
72 memcpy(wd->buf + wd->blen, buf, blen);
73 wd->blen += blen;
74 wd->nwrites++;
75 return blen;
76 }
77
78
writecb(char * buffer,size_t size,size_t nitems,void * p)79 static size_t writecb(char *buffer, size_t size, size_t nitems, void *p)
80 {
81 struct ws_data *ws_data = p;
82 size_t incoming = nitems;
83 const struct curl_ws_frame *meta;
84 (void)size;
85
86 meta = curl_ws_meta(ws_data->easy);
87 incoming = add_data(ws_data, buffer, incoming, meta);
88
89 if(nitems != incoming)
90 fprintf(stderr, "returns error from callback\n");
91 return nitems;
92 }
93
test(char * URL)94 CURLcode test(char *URL)
95 {
96 CURL *curl;
97 CURLcode res = CURLE_OK;
98 struct ws_data ws_data;
99
100
101 global_init(CURL_GLOBAL_ALL);
102
103 curl = curl_easy_init();
104 if(curl) {
105 memset(&ws_data, 0, sizeof(ws_data));
106 ws_data.easy = curl;
107
108 curl_easy_setopt(curl, CURLOPT_URL, URL);
109 /* use the callback style */
110 curl_easy_setopt(curl, CURLOPT_USERAGENT, "webbie-sox/3");
111 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
112 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
113 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ws_data);
114 res = curl_easy_perform(curl);
115 fprintf(stderr, "curl_easy_perform() returned %d\n", res);
116 /* always cleanup */
117 curl_easy_cleanup(curl);
118 flush_data(&ws_data);
119 }
120 curl_global_cleanup();
121 return res;
122 }
123
124 #else
125 NO_SUPPORT_BUILT_IN
126 #endif
127