View difference between Paste ID: 91Z6zUQj and G2YkPFNy
SHOW: | | - or go back to the newest paste.
1
// libwebsocketsserver.cpp : Defines the entry point for the console application.
2
//
3
4
#include "stdafx.h"
5
 #include <stdio.h>
6
#include <stdlib.h>
7
#include <string.h>
8
#ifdef _WIN32
9
#include <io.h>
10
#else
11
#include <unistd.h>
12
#endif
13
#include <signal.h>
14
#include <libwebsockets.h>
15
16
#define KGRN "\033[0;32;32m"
17
#define KCYN "\033[0;36m"
18
#define KRED "\033[0;32;31m"
19
#define KYEL "\033[1;33m"
20
#define KMAG "\033[0;35m"
21
#define KBLU "\033[0;32;34m"
22
#define KCYN_L "\033[1;36m"
23
#define RESET "\033[0m"
24
25
static int destroy_flag = 0;
26
27
static void INT_HANDLER(int signo) {
28
	destroy_flag = 1;
29
}
30
31
32
static int callback_http(
33
struct lws *wsi,
34
enum lws_callback_reasons reason, void *user,
35
	void *in, size_t len)
36
{
37
38
	switch (reason) {
39
		// http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n260
40
	case LWS_CALLBACK_CLIENT_WRITEABLE:
41
		printf("connection established\n");
42
43
		// http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n281
44
	case LWS_CALLBACK_HTTP: {
45
		char *requested_uri = (char *)in;
46
		printf("requested URI: %s\n", requested_uri);
47
48
		/*if (strcmp(requested_uri, "/") == 0) {
49
			lws_return_http_status(wsi, 200, "Hello, World!\0");
50
			// http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n597
51
			//lws_write(wsi, universal_response,
52
			//	strlen((const char*)universal_response), LWS_WRITE_HTTP);
53
			lws_http_transaction_completed(wsi);
54
			break;
55
56
		}
57
		else {*/
58
			if (strcmp(requested_uri, "index.html\0") != 0 && strcmp(requested_uri, "/\0") != 0) {
59
				printf("returning 404\n");
60
				lws_return_http_status(wsi, 404, "Only index.html is returned");
61
				lws_http_transaction_completed(wsi);
62
				break;
63
			}
64
65
66
			char *resource_path = "./index_cpp.html";
67
				printf("Returned resource path: %s\n", resource_path);
68
				char *mime = "text/html";
69
				// by default non existing resources return code 400
70
				// for more information how this function handles headers
71
				// see it's source code
72
				// http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/parsers.c#n1896
73
				lws_serve_http_file(wsi, resource_path, mime,"",0);
74
		//}
75
76
		// close connection
77
		lws_http_transaction_completed(wsi);
78
		break;
79
	}
80
    //The following callbacks are ignored due to not being used
81
	case LWS_CALLBACK_LOCK_POLL:
82
		/*
83
		* lock mutex to protect pollfd state
84
		* called before any other POLL related callback
85
		* if protecting wsi lifecycle change, len == 1
86
		*/
87
		break;
88
89
	case LWS_CALLBACK_UNLOCK_POLL:
90
		/*
91
		* unlock mutex to protect pollfd state when
92
		* called after any other POLL related callback
93
		* if protecting wsi lifecycle change, len == 1
94
		*/
95
		break;
96
	case LWS_CALLBACK_GET_THREAD_ID:
97
		break;
98
	case LWS_CALLBACK_PROTOCOL_INIT:
99
		break;
100
	//If something unexpected pops up
101
	default:
102
		printf("unhandled callback %d\n ", reason);
103
		break;
104
	}
105
106
	
107
108
	return 0;
109
}
110
111
112
char *randstring(int length) {
113
	static int mySeed = 25011984;
114
	char *string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
115
	size_t stringLen = strlen(string);
116
	char *randomString = NULL;
117
118
	srand((unsigned int)time(NULL) * length + ++mySeed);
119
120
	if (length < 1) {
121
		length = 1;
122
	}
123
124
	randomString = (char *)malloc(sizeof(char) * (length + 1));
125
126
	if (randomString) {
127
		short key = 0;
128
129
		for (int n = 0; n < length; n++) {
130
			key = rand() % stringLen;
131
			randomString[n] = string[key];
132
		}
133
134
		randomString[length] = '\0';
135
136
		return randomString;
137
	}
138
	else {
139
		printf("No memory");
140
		exit(1);
141
	}
142
}
143
144
const int replySize = 30000;
145
146
char *reply_string = randstring(replySize);
147
148
149
150
/* *
151
* websocket_write_back: write the string data to the destination wsi.
152
*/
153
int websocket_write_back(struct lws *wsi_in, char *str, int str_size_in)
154
{
155-
	//if (str == NULL || wsi_in == NULL)
155+
156-
	//	return -1;
156+
157
	unsigned char *out = NULL;
158
159
	char *write_what = reply_string;
160
161
	out = (unsigned char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
162
	//* setup the buffer*/
163
	memcpy(out + LWS_SEND_BUFFER_PRE_PADDING, write_what, len);
164-
	//if (str_size_in < 1)
164+
165-
		len = strlen(write_what);
165+
166-
	//else
166+
167-
		//len = str_size_in;
167+
168
	free(out);
169
170
	return n;
171
}
172
173
static int ws_service_callback(
174
	struct lws *wsi,
175-
	//printf(KBLU"[websocket_write_back] %s\n"RESET, write_what);
175+
176
	void *user,
177
	void *in, size_t len)
178
{
179
180
	printf("Got a ws request %d\n", reason);
181
182
	switch (reason) {
183
184
	case LWS_CALLBACK_ESTABLISHED:
185
		printf(KYEL"[Main Service] Connection established\n"RESET);
186
		break;
187
188
		//* If receive a data from client*/
189
	case LWS_CALLBACK_RECEIVE:
190
		printf(KCYN_L"[Main Service] Server recvived:\n"RESET/*, (char *)in*/);
191
192
		//* echo back to client*/
193
		websocket_write_back(wsi, (char *)in, -1);
194
195
		break;
196
	case LWS_CALLBACK_CLOSED:
197
		printf(KYEL"[Main Service] Client close.\n"RESET);
198
		break;
199
200
	default:
201
		break;
202
	}
203
204
	return 0;
205
}
206
207
struct per_session_data {
208
	int fd;
209
};
210
211
bool got_sighup = false;
212
bool got_sigint = false;
213
214
void handle_signal(int signal) {
215
	switch (signal) {
216
#ifdef _WIN32
217
	case SIGTERM:
218
	case SIGABRT:
219
	case SIGBREAK:
220
#else
221
	case SIGHUP:
222
#endif
223
		got_sighup = true;
224
		break;
225
	case SIGINT:
226
		got_sigint = true;
227
		break;
228
	}
229
}
230
#ifdef _WIN32
231
232
void usleep(__int64 usec)
233
{
234
	HANDLE timer;
235
	LARGE_INTEGER ft;
236
237
	ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time
238
239
	timer = CreateWaitableTimer(NULL, TRUE, NULL);
240
	SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
241
	WaitForSingleObject(timer, INFINITE);
242
	CloseHandle(timer);
243
}
244
#endif
245
246
struct per_session_data__http {
247
	lws_filefd_type fd;
248
	char post_string[256];
249
#ifdef LWS_WITH_CGI
250
	struct lws_cgi_args args;
251
#endif
252
#if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT)
253
	int reason_bf;
254
#endif
255
	unsigned int client_finished : 1;
256
};
257
258
259
static struct lws_protocols protocols[] = {
260
	/* first protocol must always be HTTP handler */
261
262
	{
263
		"http-only",		/* name */
264
		callback_http,		/* callback */
265
		sizeof(struct per_session_data__http),	/* per_session_data_size */
266
		0,			/* max frame size / rx buffer */
267
	},
268
	{
269
		"tspp",
270
		ws_service_callback,
271
		sizeof(struct per_session_data),
272
		0, /* rx buf size must be >= permessage-deflate rx size */
273
	},
274
	{ NULL, NULL, 0, 0 } /* terminator */
275
};
276
277
278
int _tmain(int argc, _TCHAR* argv[])
279
{
280
	// server url will usd port 5000
281
	int port = 5000;
282
	const char *interface = NULL;
283
	struct lws_context_creation_info info;
284
	struct lws_context *context;
285
	// Not using ssl
286
	const char *cert_path = NULL;
287
	const char *key_path = NULL;
288
	// no special options
289
	int opts = 0;
290
291
#ifdef _WIN32
292
	signal(SIGINT, handle_signal);
293
	signal(SIGTERM, handle_signal);
294
	signal(SIGABRT, handle_signal);
295
#else
296
297
	//* register the signal SIGINT handler */
298
	struct sigaction  act;
299
	act.sa_handler = INT_HANDLER;
300
	act.sa_flags = 0;
301
	sigemptyset(&act.sa_mask);
302
	sigaction(SIGINT, &act, 0);
303
#endif
304
305
	//* setup websocket protocol */
306
307
	//* setup websocket context info*/
308
	memset(&info, 0, sizeof info);
309
	info.port = port;
310
	info.iface = interface;
311
	info.protocols = protocols;
312
313
	info.extensions = lws_get_internal_extensions();
314
	info.ssl_cert_filepath = cert_path;
315
	info.ssl_private_key_filepath = key_path;
316
	info.gid = -1;
317
	info.uid = -1;
318
	info.options = opts;
319
320
	//* create libwebsocket context. */
321
	context = lws_create_context(&info);
322
	if (context == NULL) {
323
		printf(KRED"[Main] Websocket context create error.\n"RESET);
324
		return -1;
325
	}
326
327
	printf(KGRN"[Main] Websocket context create success.\n"RESET);
328
329
	//* websocket service */
330
	while (!destroy_flag) {
331
		lws_service(context, 0);
332
	}
333
	usleep(10);
334
	lws_context_destroy(context);
335
336
	return 0;
337
	return 0;
338
}