From: chengtao.liu Date: Fri, 14 Feb 2014 05:47:11 +0000 (+0800) Subject: sync tinyweb codes X-Git-Tag: submit/tizen_common/20140625.153855~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=574372b37c9a8add2eadabd68ddda565a65d697a;p=test%2Ftools%2Ftinyweb.git sync tinyweb codes --- diff --git a/Makefile b/Makefile index 7042328..6e35bd4 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,9 @@ -OBJ=tinyweb -CFLAGS= -W -Wall -I.. -pthread +CFLAGS= -W -Wall -I.. -pthread -g -all: $(OBJ) - -tinyweb: echo - $(CC) tinyweb.c -ldl -lmongoose -L./ -o tinyweb; - -echo: mongoose - $(CC) -shared -fPIC -lmongoose -L./ echo.c -o echo.so - -mongoose: - $(CC) -shared -fPIC $(CFLAGS) -DUSE_WEBSOCKET mongoose.c -ldl -o libmongoose.so; - -install: $(OBJ) - install -d $(DESTDIR)/usr/bin/ - install -m 755 $(OBJ) $(DESTDIR)/usr/bin/ - install -d $(DESTDIR)/usr/lib - install -m 755 libmongoose.so $(DESTDIR)/usr/lib/ - install -m 755 echo.so $(DESTDIR)/usr/lib/ - install -m 755 -d $(DESTDIR)/usr/share/$(OBJ) - install -m 755 server.pem $(DESTDIR)/usr/share/$(OBJ) - ln -s /usr/lib/libssl.so.1.0.0 /usr/lib/libssl.so - ln -s /usr/lib/libcrypto.so.1.0.0 /usr/lib/libcrypto.so +all: + $(CC) websocket.c tinyweb.c mongoose.c $(CFLAGS) -DUSE_WEBSOCKET -ldl -lutil -o tinyweb; + $(CC) cgi-getfield.c -o cgi-getfield; + $(CC) cgi-getcookie.c -o cgi-getcookie; clean: - rm -rf tinyweb *.so + rm -rf tinyweb cgi-getcookie cgi-getfield diff --git a/README.md b/README.md new file mode 100644 index 0000000..df3950d --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Tinyweb diff --git a/VERSION b/VERSION index e346294..7d385d4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22 +0.25 diff --git a/cgi-getcookie.c b/cgi-getcookie.c new file mode 100644 index 0000000..d036f33 --- /dev/null +++ b/cgi-getcookie.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + +Authors: + Wang, Jing J + +*/ + +#include +#include +#include +#include +#include +#include + +static char * +scanspaces(char *p) { + while (*p == ' ' || *p == '\t') { + p++; + } + return p; +} + +static char* scan_cookie(char *p, char **items) { + int quote = 0; + items[0] = p = scanspaces(p); + while (*p != '=' && *p != 0) { + p++; + } + if (*p != '=' || p == items[0]) { + return 0; + } + *p++ = 0; + if (*p == '"' || *p == '\'' || *p == '`') { + quote = *p++; + } + items[1] = p; + if (quote != 0) { + while(*p != quote && *p != 0) { + p++; + } + if (*p != quote) { + return 0; + } + *p++ = 0; + if (*p == ';') { + p++; + } + } + else { + while (*p != ';' && *p != ' ' && *p != '\t' && + *p != '\r' && *p != '\n' && *p != 0) + { + p++; + } + if (*p != 0) { + *p++ = 0; + } + } + return p; +} + +int main(int argc, char **argv) { + char *items[2]; + char buf[4096], *p; + int len = -1; + if (argc != 2) + return -1; + char *field = argv[1]; + if ((len = fread(buf, 1, 4096, stdin)) > 0) { + buf[len] = 0; + p = buf; + while ((p = scan_cookie(p, items)) != 0) { + if (strcmp(items[0], field) == 0) { + printf("%s", items[1]); + return 0; + } + } + } + return -1; +} diff --git a/cgi-getfield.c b/cgi-getfield.c new file mode 100644 index 0000000..a25309c --- /dev/null +++ b/cgi-getfield.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + +Authors: + Wang, Jing J + +*/ + +#include +#include +#include +#include +#include +#include + +#define MAX_QUERY_SIZE 1024 +static int +hex(int digit) { + switch(digit) { + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return digit - '0'; + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return 10 + digit - 'A'; + + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return 10 + digit - 'a'; + + default: + return -1; + } +} + + +int decode_query(const char *query, char *pkey, char *pval, int *psize) { + char buf[256], *name, *value; + int i, k, j, L, R, done; + + if (query == 0) { + return -1; + } + name = value = 0; + for (i = j = k = done = 0; done == 0; i++) { + switch (query[i]) { + case '=': + if (name != 0) { + break; /* treat extraneous '=' as data */ + } + if (name == 0 && k > 0) { + name = buf; + buf[k++] = 0; + j = k; + value = buf + k; + } + continue; + + case 0: + done = 1; /* fall through */ + + case '&': + buf[k] = 0; + if (name == 0 && k > 0) { + name = buf; + value = buf + k; + } + if (name != 0) { + if (strncmp(name, pkey, strlen(pkey)) == 0) { + *psize = k - j; + memcpy(pval, value, k - j); + return 0; + } + } + k = 0; + name = value = 0; + continue; + + case '+': + buf[k++] = ' '; + continue; + + case '%': + if ((L = hex(query[i + 1])) >= 0 && + (R = hex(query[i + 2])) >= 0) + { + buf[k++] = (L << 4) + R; + i += 2; + continue; + } + break; /* treat extraneous '%' as data */ + } + buf[k++] = query[i]; + } + return -1; +} + +int +main(int argc, char **argv) { + char qbuf[MAX_QUERY_SIZE], val[MAX_QUERY_SIZE]; + int len = MAX_QUERY_SIZE; + int size = 0; + if (argc < 2) + return -1; + char *key = argv[1]; + if (argc > 2) + len = atoi(argv[2]); + if ((len = fread(qbuf, 1, len, stdin)) > 0) { + qbuf[len] = 0; + if (decode_query(qbuf, key, val, &size) == 0) { + fwrite(val, 1, size, stdout); + return 0; + } + } + return -1; +} diff --git a/echo.c b/echo.c index 72e4625..6136ce8 100644 --- a/echo.c +++ b/echo.c @@ -1,32 +1,17 @@ /* -Copyright (c) 2013 Intel Corporation. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of works must retain the original copyright notice, this list - of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the original copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this work without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. Authors: Wang, Jing J - */ #include diff --git a/mongoose.c b/mongoose.c index f1c59d1..57f9071 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1,33 +1,19 @@ /* -Copyright (c) 2013 Intel Corporation. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of works must retain the original copyright notice, this list - of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the original copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this work without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. Authors: Wang, Jing J - */ + #if defined(_WIN32) #if !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005 @@ -450,7 +436,7 @@ enum { ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE, GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST, EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE, - NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT, + NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT, PID_FILE, NUM_OPTIONS }; @@ -480,6 +466,7 @@ static const char *config_options[] = { "url_rewrite_patterns", NULL, "hide_files_patterns", NULL, "request_timeout_ms", "30000", + "pidfile", NULL, NULL }; diff --git a/mongoose.h b/mongoose.h index 00c33f1..c51f341 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1,32 +1,17 @@ /* -Copyright (c) 2013 Intel Corporation. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of works must retain the original copyright notice, this list - of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the original copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this work without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. Authors: Wang, Jing J - */ #ifndef MONGOOSE_HEADER_INCLUDED diff --git a/packaging/tinyweb.spec b/packaging/tinyweb.spec deleted file mode 100644 index 3a40ac5..0000000 --- a/packaging/tinyweb.spec +++ /dev/null @@ -1,55 +0,0 @@ -Name: tinyweb -Summary: test -Version: 0.22 -Release: 1 -Group: Development/Debug -License: GPL v2 only -URL: http://www.tizen.org/ -Source0: %{name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-build - -%description -A lightweight web server. It support http directory, websocket, cgi etc. - - -%prep -%setup -q -n %{name}-%{version} -# >> setup -# << setup - -%build -# >> build pre -# << build pre - - -# Call make instruction with smp support -make %{?jobs:-j%jobs} - -# >> build post -# << build post -%install -rm -rf %{buildroot} -# >> install pre -# << install pre -%make_install - -# >> install post -# << install post - -%clean -rm -rf %{buildroot} - -%files -%defattr(-,root,root,-) -# >> files -%{_bindir}/tinyweb -%{_libdir}/echo.so -%{_libdir}/libmongoose.so -%{_datadir}/%{name}/server.pem - -%{_libdir}/ -# << files - -%changelog -* Tue Mar 21 2013 jing wang 0.22 -- create for tct2.1 build diff --git a/tinyweb.c b/tinyweb.c index 10909b4..2dc1364 100644 --- a/tinyweb.c +++ b/tinyweb.c @@ -1,32 +1,17 @@ /* -Copyright (c) 2013 Intel Corporation. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of works must retain the original copyright notice, this list - of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the original copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this work without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. Authors: Wang, Jing J - */ #define _XOPEN_SOURCE 600 // For PATH_MAX on linux @@ -53,73 +38,19 @@ Authors: #define MAX_OPTIONS 40 #define MAX_CONF_FILE_LINE_SIZE (8 * 1024) - +extern void websocket_ready_handler(struct mg_connection *); +extern int websocket_data_handler(struct mg_connection *, int, char *, size_t); static int exit_flag; static char server_name[40]; // Set by init_server_name() static char config_file[PATH_MAX]; // Set by process_command_line_arguments() static struct mg_context *ctx; // Set by start_server() - #if !defined(CONFIG_FILE) #define CONFIG_FILE "mongoose.conf" #endif /* !CONFIG_FILE */ - -static void *get_app(struct mg_connection *conn) { - char app_name[128]; - const char *uri = mg_get_request_info(conn)->uri; - if (strcmp(uri, "/") == 0){ - snprintf(app_name, sizeof(app_name), "/usr/lib%secho.so", uri); - }else{ - snprintf(app_name, sizeof(app_name), "/usr/lib%s.so", uri); - } -// printf("app_name=%s\n", app_name); - void *ws_handle = NULL; - if ((ws_handle = dlopen(app_name, RTLD_LAZY)) == NULL) { - fprintf(stderr, "%s: cannot load %s\n", __func__, app_name); - return NULL; - } - return ws_handle; -} - -static void websocket_ready_handler(struct mg_connection *conn){ - const char *prot = mg_get_header(conn, "Sec-WebSocket-Protocol"); - char buf[100]; - if (prot){ - char *p = NULL; - snprintf(buf, sizeof(buf), "%s", prot); - if ((p = strrchr(buf, ',')) != NULL) { - *p = '\0'; - } - mg_printf(conn, "Sec-WebSocket-Protocol: %s\r\n", buf); - } - mg_printf(conn, "\r\n"); -} - - -// Arguments: -// flags: first byte of websocket frame, see websocket RFC, -// http://tools.ietf.org/html/rfc6455, section 5.2 -// data, data_len: payload data. Mask, if any, is already applied. -static int websocket_data_handler(struct mg_connection *conn, int flags, - char *data, size_t data_len){ - void *ws_handle = get_app(conn); - if (ws_handle == NULL) { - return 0; - } - int (*func)(struct mg_connection *, int, char *, size_t) = dlsym(ws_handle, "websocket_data"); - if (func == NULL){ - dlclose(ws_handle); - return 0; - } - int ret = (*func)(conn, flags, data, data_len); - dlclose(ws_handle); - return ret; -} - static void WINCDECL signal_handler(int sig_num) { - exit_flag = sig_num; + exit_flag = sig_num; } - static void die(const char *fmt, ...) { va_list ap; char msg[200]; @@ -319,7 +250,8 @@ static void start_server(int argc, char *argv[]) { } int main(int argc, char *argv[]) { - init_server_name(); + signal(SIGCHLD, SIG_IGN); + signal(SIGHUP, SIG_IGN); pid_t pid = 0; pid = fork(); if (pid < 0) { @@ -327,23 +259,34 @@ int main(int argc, char *argv[]) { exit(1); } if (pid > 0) { - fprintf(stderr, "Daemonize\n"); + sleep(1); exit(0); } umask(0); setsid(); + chdir("/"); + + init_server_name(); start_server(argc, argv); - printf("%s started on port(s) %s with web root [%s]\n", + pid = getpid(); + printf("%s started on port(s) %s with document root [%s], pid [%d]\n", server_name, mg_get_option(ctx, "listening_ports"), - mg_get_option(ctx, "document_root")); + mg_get_option(ctx, "document_root"), pid); + + char *pidfile = (char *)mg_get_option(ctx, "pidfile"); + if (*pidfile) { + FILE *fp = fopen(pidfile, "w+"); + fprintf(fp, "%d", pid); + fclose(fp); + } + while (exit_flag == 0) { sleep(1); } printf("Exiting on signal %d, waiting for all threads to finish...", exit_flag); + printf("%s", " done.\n"); fflush(stdout); mg_stop(ctx); - printf("%s", " done.\n"); - return EXIT_SUCCESS; } diff --git a/webservice.c b/webservice.c new file mode 100644 index 0000000..8327f4c --- /dev/null +++ b/webservice.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "mongoose.h" + +extern struct mg_context *ctx; // Set by start_server() +int webservice_handler(struct mg_connection *conn) { + const struct mg_request_info *ri = mg_get_request_info(conn); + char *post_data, fname[256], *data; + int post_data_len; + #define POST_SIZE 4*1024*1024 + if (!strcmp(ri->uri, "/save_file")) { + char fpath[256], *ptr; + //Apply space to contain post data + post_data = (char *)malloc(POST_SIZE); + // User has submitted a form, show submitted data and a variable value + post_data_len = mg_read(conn, post_data, POST_SIZE); + + data = (char *)malloc(POST_SIZE); + // Parse post data. + mg_get_var(post_data, post_data_len, "filename", fname, sizeof(fname)); + mg_get_var(post_data, post_data_len, "data", data, POST_SIZE); + free(post_data); + ptr = (char *)mg_get_option(ctx, "outdir"); + if (*ptr) { + sprintf(fpath, "%s/%s", ptr, fname); + FILE *fp = fopen(fpath, "w+"); + fputs(data, fp); + fclose(fp); + } else + printf("data=%s\n", data); + // Send Ok reply to the client. + mg_printf(conn, "HTTP/1.0 200 OK\r\n"); + free(data); + return 1; // Mark event as processed + } + + return 0; // Mark request as processed +} diff --git a/websocket.c b/websocket.c new file mode 100644 index 0000000..8274982 --- /dev/null +++ b/websocket.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2014 Intel Corporation, All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + +Authors: + Wang, Jing J +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mongoose.h" + +#include +#include +#include + +// Arguments: +// flags: first byte of websocket frame, see websocket RFC, +// http://tools.ietf.org/html/rfc6455, section 5.2 +// data, data_len: payload data. Mask, if any, is already applied. +static int websocket_data(struct mg_connection *conn, int flags, + char *data, size_t data_len) { + unsigned char reply[4]; + int offset = 2; + int ret = 1; + +// (void) flags; + + // Truncate echoed message, to simplify output code. + if (data_len > 65536) { + data_len = 65536; + } + printf("data_len=%d\n",data_len); + int opcode = flags & 0x0f; + if ((opcode == 0x08) || memcmp(data, ".close", 6)==0){ +// printf("close frame"); + reply[0] = 0x88; // close, FIN set + reply[1] = data_len; + // Status code + if (data_len == 0){ + reply[2] = 3; + reply[3] = 232; + }else{ + reply[2] = data[0]; + reply[3] = data[1]; + } + ret = 0; + } else { + reply[0] = 0x80|opcode; // FIN set + if (data_len <= 125){ + reply[1] = data_len; + } + else{ + reply[1] = 126; + reply[2] = data_len / 256; + reply[3] = data_len % 256; + offset = 4; + } + } + // Echo the message back to the client + mg_write(conn, reply, offset); + if (data_len > 0) + mg_write(conn, data, data_len); + // Returning zero means stoping websocket conversation. + // Close the conversation if client has sent us "exit" string. + return ret; +} + +void websocket_ready_handler(struct mg_connection *conn){ + const char *prot = mg_get_header(conn, "Sec-WebSocket-Protocol"); + char buf[100]; + if (prot){ + char *p = NULL; + snprintf(buf, sizeof(buf), "%s", prot); + if ((p = strrchr(buf, ',')) != NULL) { + *p = '\0'; + } + mg_printf(conn, "Sec-WebSocket-Protocol: %s\r\n", buf); + } + mg_printf(conn, "\r\n"); +} + + +// Arguments: +// flags: first byte of websocket frame, see websocket RFC, +// http://tools.ietf.org/html/rfc6455, section 5.2 +// data, data_len: payload data. Mask, if any, is already applied. +int websocket_data_handler(struct mg_connection *conn, int flags, + char *data, size_t data_len){ + const char *prot = mg_get_header(conn, "Sec-WebSocket-Protocol"); + if (prot && (strncmp(prot, "foobar", 6) == 0)){ + return 0; + } + const char *uri = mg_get_request_info(conn)->uri; + if (strcmp(uri, "/") == 0 || strcmp(uri, "/echo") == 0){ + return websocket_data(conn, flags, data, data_len); + } + return 0; +}