diff --git a/examples/Makefile b/examples/Makefile index 8dbb6512..51537035 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 00000000..cf75a0d2 --- /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 [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 < +#include + +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 <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 5212a361..00000000 --- a/examples/qcomm.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -#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 5fbf5005..67306d9d 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 -#include -#include #include "mongoose.h" -static int event_handler(struct mg_event *event) { +extern const char *find_embedded_file(const char *, size_t *); - 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; - } - - // 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 - }; + struct mg_server *server = mg_create_server(NULL); + unsigned int current_timer = 0, last_timer = 0; - ctx = mg_start(options, &event_handler, NULL); - getchar(); // Wait until user hits "enter" - mg_stop(ctx); + 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 8c5f765f..00000000 --- a/examples/websocket_html_root/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - -WebSocket Test - - -

Mongoose WebSocket Test

- -
- 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. -
- -
- diff --git a/examples/websocket_html_root/ws.html b/examples/websocket_html_root/ws.html deleted file mode 100644 index 8f83a0bb..00000000 --- a/examples/websocket_html_root/ws.html +++ /dev/null @@ -1,43 +0,0 @@ - - -WebSocket Test - - -

Qualcomm WebSocket Test

- -
- diff --git a/mongoose.c b/mongoose.c index ad9afc5c..d9bdaebf 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); }