From 7690f9e34b36124948abe07d2ef4895ab685f403 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka <valenok@gmail.com> Date: Fri, 17 Jan 2014 10:17:15 +0000 Subject: [PATCH] Fixed websocket example, and websocket callback calling logic. --- examples/Makefile | 9 ++- examples/mkdata.pl | 53 ++++++++++++++ examples/qcomm.c | 48 ------------- examples/websocket.c | 92 ++++++++++--------------- examples/websocket_html_root/index.html | 44 ------------ examples/websocket_html_root/ws.html | 43 ------------ mongoose.c | 2 +- 7 files changed, 96 insertions(+), 195 deletions(-) create mode 100644 examples/mkdata.pl delete mode 100644 examples/qcomm.c delete mode 100644 examples/websocket_html_root/index.html delete mode 100644 examples/websocket_html_root/ws.html diff --git a/examples/Makefile b/examples/Makefile index 8dbb6512f..51537035a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -18,9 +18,9 @@ else endif endif -all: +all: websocket_html.c $(CC) hello.c ../mongoose.c -o hello $(CFLAGS) - $(CC) qcomm.c ../mongoose.c -o qcomm $(CFLAGS) + $(CC) websocket.c websocket_html.c ../mongoose.c -o websocket $(CFLAGS) $(CC) post.c ../mongoose.c -o post $(CFLAGS) $(CC) multi_threaded.c ../mongoose.c -o multi_threaded $(CFLAGS) $(CC) upload.c ../mongoose.c -o upload $(CFLAGS) @@ -31,6 +31,8 @@ all: # $(CC) chat.c ../mongoose.c -o chat $(CFLAGS) # $(CC) lua_dll.c ../build/lua_5.2.1.c -o $@.so $(CFLAGS) $(DLL_FLAGS) +websocket_html.c: websocket.html + perl mkdata.pl $< > $@ MSVC = ../../vc6 CL = $(MSVC)/bin/cl @@ -38,8 +40,9 @@ CLFLAGS = /MD /TC /nologo $(DBG) /W3 /DNO_SSL \ /I$(MSVC)/include /I.. /Dsnprintf=_snprintf LFLAGS = /link /incremental:no /libpath:$(MSVC)/lib /machine:IX86 -windows: +windows: websocket_html.c $(CL) hello.c ../mongoose.c $(CLFLAGS) $(LFLAGS) + $(CL) websocket.c websocket_html.c ../mongoose.c $(CLFLAGS) $(LFLAGS) $(CL) post.c ../mongoose.c $(CLFLAGS) $(LFLAGS) $(CL) multi_threaded.c ../mongoose.c $(CLFLAGS) $(LFLAGS) $(CL) upload.c ../mongoose.c $(CLFLAGS) $(LFLAGS) diff --git a/examples/mkdata.pl b/examples/mkdata.pl new file mode 100644 index 000000000..cf75a0d25 --- /dev/null +++ b/examples/mkdata.pl @@ -0,0 +1,53 @@ +# This program is used to embed arbitrary data into a C binary. It takes +# a list of files as an input, and produces a .c data file that contains +# contents of all these files as collection of char arrays. +# +# Usage: perl <this_file> <file1> [file2, ...] > embedded_data.c + +foreach my $i (0 .. $#ARGV) { + open FD, '<:raw', $ARGV[$i] or die "Cannot open $ARGV[$i]: $!\n"; + printf("static const unsigned char v%d[] = {", $i); + my $byte; + my $j = 0; + while (read(FD, $byte, 1)) { + if (($j % 12) == 0) { + print "\n"; + } + printf ' %#04x,', ord($byte); + $j++; + } + print " 0x00\n};\n"; + close FD; +} + +print <<EOS; + +#include <stddef.h> +#include <string.h> + +static const struct embedded_file { + const char *name; + const unsigned char *data; + size_t size; +} embedded_files[] = { +EOS + +foreach my $i (0 .. $#ARGV) { + print " {\"$ARGV[$i]\", v$i, sizeof(v$i) - 1},\n"; +} + +print <<EOS; + {NULL, NULL, 0} +}; + +const char *find_embedded_file(const char *name, size_t *size) { + const struct embedded_file *p; + for (p = embedded_files; p->name != NULL; p++) { + if (!strcmp(p->name, name)) { + if (size != NULL) { *size = p->size; } + return (const char *) p->data; + } + } + return NULL; +} +EOS diff --git a/examples/qcomm.c b/examples/qcomm.c deleted file mode 100644 index 5212a3615..000000000 --- a/examples/qcomm.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <unistd.h> -#include <string.h> - -#include "mongoose.h" - -static void iterate_callback(struct mg_connection *c, void *param) { - if (c->is_websocket) { - char buf[20]; - int len = snprintf(buf, sizeof(buf), "%d", * (int *) param); - mg_websocket_write(c, 1, buf, len); - } -} - -// This handler is called for each incoming websocket frame, one or more -// times for connection lifetime. -static int handler(struct mg_connection *conn) { - static const char oops[] = "HTTP/1.0 200 OK\r\n\r\nwebsocket data expected\n"; - - if (!conn->is_websocket) { - mg_write(conn, oops, sizeof(oops) - 1); - return 1; - } - - mg_websocket_write(conn, 1, conn->content, conn->content_len); - - return conn->content_len == 4 && !memcmp(conn->content, "exit", 4); -} - -int main(int argc, char *argv[]) { - struct mg_server *server = mg_create_server(NULL); - unsigned int current_timer = 0, last_timer = 0; - - mg_set_option(server, "listening_port", "8080"); - mg_set_option(server, "document_root", argc > 1 ? argv[1] : "."); - mg_add_uri_handler(server, "/ws", handler); - - printf("Started on port %s\n", mg_get_option(server, "listening_port")); - for (;;) { - current_timer = mg_poll_server(server, 1); - if (current_timer - last_timer > 4) { - last_timer = current_timer; - mg_iterate_over_connections(server, iterate_callback, ¤t_timer); - } - } - - mg_destroy_server(&server); - return 0; -} diff --git a/examples/websocket.c b/examples/websocket.c index 5fbf5005f..67306d9d4 100644 --- a/examples/websocket.c +++ b/examples/websocket.c @@ -1,67 +1,47 @@ -// Copyright (c) 2004-2012 Sergey Lyubka -// This file is a part of mongoose project, http://github.com/valenok/mongoose - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> #include "mongoose.h" -static int event_handler(struct mg_event *event) { - - if (event->type == MG_REQUEST_BEGIN) { - const char *version_header = mg_get_header(event->conn, - "Sec-WebSocket-Version"); - - if (version_header != NULL) { - // Websocket request, process it - if (strcmp(version_header, "13") != 0) { - mg_printf(event->conn, "%s", "HTTP/1.1 426 Upgrade Required\r\n\r\n"); - } else { - static const char *server_ready_message = "server ready"; - char *data; - int bits, len, must_exit = 0; - - // Handshake, and send initial server message - mg_websocket_handshake(event->conn); - mg_websocket_write(event->conn, WEBSOCKET_OPCODE_TEXT, - server_ready_message, strlen(server_ready_message)); - - // Read messages sent by client. Echo them back. - while (must_exit == 0 && - (len = mg_websocket_read(event->conn, &bits, &data)) > 0) { - - printf("got message: [%.*s]\n", len, data); - mg_websocket_write(event->conn, WEBSOCKET_OPCODE_TEXT, data, len); - - // If the message is "exit", close the connection, exit the loop - if (memcmp(data, "exit", 4) == 0) { - mg_websocket_write(event->conn, - WEBSOCKET_OPCODE_CONNECTION_CLOSE, "", 0); - must_exit = 1; - } +extern const char *find_embedded_file(const char *, size_t *); - // It's our responsibility to free allocated message - free(data); - } - } - return 1; - } +static void iterate_callback(struct mg_connection *c, void *param) { + if (c->is_websocket) { + char buf[20]; + int len = snprintf(buf, sizeof(buf), "%d", * (int *) param); + mg_websocket_write(c, 1, buf, len); } +} - return 0; +// This handler is called for each incoming websocket frame, one or more +// times for connection lifetime. +static int index_html(struct mg_connection *conn) { + size_t index_size; + const char *index_html = find_embedded_file("websocket.html", &index_size); + + if (conn->is_websocket) { + mg_websocket_write(conn, 1, conn->content, conn->content_len); + return conn->content_len == 4 && !memcmp(conn->content, "exit", 4); + } else { + mg_send_header(conn, "Content-Type", "text/html"); + mg_send_data(conn, index_html, index_size); + return 1; + } } int main(void) { - struct mg_context *ctx; - const char *options[] = { - "listening_ports", "8080", - "document_root", "websocket_html_root", - NULL - }; - - ctx = mg_start(options, &event_handler, NULL); - getchar(); // Wait until user hits "enter" - mg_stop(ctx); + struct mg_server *server = mg_create_server(NULL); + unsigned int current_timer = 0, last_timer = 0; + + mg_set_option(server, "listening_port", "8080"); + mg_add_uri_handler(server, "/", index_html); + + printf("Started on port %s\n", mg_get_option(server, "listening_port")); + for (;;) { + current_timer = mg_poll_server(server, 100); + if (current_timer - last_timer > 4) { + last_timer = current_timer; + mg_iterate_over_connections(server, iterate_callback, ¤t_timer); + } + } + mg_destroy_server(&server); return 0; } diff --git a/examples/websocket_html_root/index.html b/examples/websocket_html_root/index.html deleted file mode 100644 index 8c5f765fc..000000000 --- a/examples/websocket_html_root/index.html +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8" /> -<title>WebSocket Test</title> -<script language="javascript" type="text/javascript"> - - var writeToScreen = function(message) { - var div = document.createElement('div'); - div.innerHTML = message; - document.getElementById('output').appendChild(div); - }; - window.onload = function() { - var url = 'ws://' + window.location.host + '/foo'; - websocket = new WebSocket(url); - websocket.onopen = function(ev) { - writeToScreen('CONNECTED'); - var message = 'Ðе вÑÑ‘ подчинÑетÑÑ Ñ€Ð°Ð·ÑƒÐ¼Ñƒ. Ðо вÑÑ‘ подчинÑетÑÑ ÑƒÐ¿Ð¾Ñ€Ñтву. '; - writeToScreen('SENT: ' + message); - websocket.send(message); - }; - websocket.onclose = function(ev) { - writeToScreen('DISCONNECTED'); - }; - websocket.onmessage = function(ev) { - writeToScreen('<span style="color: blue;">RESPONSE: ' + ev.data + - ' </span>'); - websocket.send('exit'); - }; - websocket.onerror = function(ev) { - writeToScreen('<span style="color: red; ">ERROR: </span> ' + ev.data); - }; - }; -</script> -<style> div {font: small Verdana; } </style> -<h2>Mongoose WebSocket Test</h2> - - <div style="width: 400px; color: #aaa; padding: 1em; "> - This page code creates websocket to the URI "/foo", - sends a message to it, waits for the reply, then sends an "exit" message. - Server must echo all messages back, and terminate the conversation after - receiving the "exit" message. - </div> - -<div id="output"></div> -</html> diff --git a/examples/websocket_html_root/ws.html b/examples/websocket_html_root/ws.html deleted file mode 100644 index 8f83a0bb7..000000000 --- a/examples/websocket_html_root/ws.html +++ /dev/null @@ -1,43 +0,0 @@ -<!DOCTYPE html> -<meta charset="utf-8" /> -<title>WebSocket Test</title> -<script language="javascript" type="text/javascript"> - - var out = function(message) { - var div = document.createElement('div'); - div.innerHTML = message; - document.getElementById('output').appendChild(div); - }; - - window.onload = function() { - var url = 'ws://' + location.host + '/ws'; - var num_messages = 0; - - websocket = new WebSocket(url); - websocket.onopen = function(ev) { - out('CONNECTED'); - var msg = 'Ðе вÑÑ‘ подчинÑетÑÑ Ñ€Ð°Ð·ÑƒÐ¼Ñƒ. Ðо вÑÑ‘ подчинÑетÑÑ ÑƒÐ¿Ð¾Ñ€Ñтву. '; - out('SENT: ' + msg); - websocket.send(msg); - }; - websocket.onclose = function(ev) { - out('DISCONNECTED'); - }; - websocket.onmessage = function(ev) { - if (!ev.data) return; // No data, this is a PING message, ignore it - out('<span style="color: blue;">RESPONSE: ' + ev.data + ' </span>'); - num_messages++; - if (num_messages > 100) { - websocket.send('exit'); - } - }; - websocket.onerror = function(ev) { - out('<span style="color: red; ">ERROR: </span> ' + ev.data); - }; - }; -</script> -<style> div {font: small Verdana; } </style> -<h2>Qualcomm WebSocket Test</h2> - -<div id="output"></div> -</html> diff --git a/mongoose.c b/mongoose.c index ad9afc5cb..d9bdaebf0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1940,7 +1940,7 @@ static void write_to_client(struct connection *conn) { conn->num_bytes_sent += n; } - if (conn->endpoint_type == EP_USER) { + if (conn->endpoint_type == EP_USER && !conn->mg_conn.is_websocket) { conn->mg_conn.wsbits = conn->flags & CONN_CLOSE ? 1 : 0; call_uri_handler(conn); } -- GitLab