mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-25 12:04:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63be1ebd38 | ||
|
|
796dc18cfb | ||
|
|
14e116553f | ||
|
|
c82ccd6cf7 | ||
|
|
0adb080319 | ||
|
|
dbb38fffae | ||
|
|
672a68219a | ||
|
|
22cb0efd00 | ||
|
|
a68d3d63b2 | ||
|
|
cf48c7280a | ||
|
|
1295973028 | ||
|
|
d5b9eda0f2 | ||
|
|
41c078d25c | ||
|
|
5614224e7d | ||
|
|
9ba44cb0d5 | ||
|
|
c18828af7b | ||
|
|
8a5f8439b4 | ||
|
|
8f0374569e | ||
|
|
09dde636d2 | ||
|
|
d347247bf3 | ||
|
|
a6c66fb669 | ||
|
|
b4dbc825b1 | ||
|
|
4a0cc8223e | ||
|
|
7db10857b3 | ||
|
|
7e927b43ad | ||
|
|
9eea072f2a | ||
|
|
aa2ff674db | ||
|
|
de24bfdf2f | ||
|
|
2a084c3d98 | ||
|
|
db8df41396 | ||
|
|
bda05d9372 | ||
|
|
59bc2af4d6 | ||
|
|
00a23ee330 | ||
|
|
51ad50a641 | ||
|
|
148e1926e8 | ||
|
|
96c023df41 | ||
|
|
44f37f49a1 | ||
|
|
a8a30f6d3f | ||
|
|
ba80b1cd55 | ||
|
|
b56e985ccc | ||
|
|
67521fd9f6 | ||
|
|
8c394f44b8 | ||
|
|
77b4fff268 | ||
|
|
f56a0c6075 | ||
|
|
9ce8486059 | ||
|
|
04a321150a | ||
|
|
d333c3c09e | ||
|
|
81d977c720 | ||
|
|
f477898c7c | ||
|
|
566193a1eb | ||
|
|
5d6eeb5d1d | ||
|
|
d9b9d71b2d | ||
|
|
643ee1df14 | ||
|
|
6c4d37ee68 | ||
|
|
97b79cd04a | ||
|
|
56c6229dd6 | ||
|
|
0fe2dd9b48 | ||
|
|
910aee7f7b | ||
|
|
97063937ff | ||
|
|
7e68b097d1 | ||
|
|
4d41dff4fd | ||
|
|
05082cec88 | ||
|
|
f05733da69 | ||
|
|
3c53909e82 | ||
|
|
1e53ec47a9 | ||
|
|
17802735d7 | ||
|
|
d2eb67a1ae | ||
|
|
3f254dd3fc | ||
|
|
e139bde6ae | ||
|
|
5f62951143 | ||
|
|
2207e87c8f | ||
|
|
5bd59c7b70 | ||
|
|
02f6867a2f | ||
|
|
b93fa3144a | ||
|
|
a68e0d9a3f | ||
|
|
cfe80ba9b7 | ||
|
|
35abfd44dd | ||
|
|
e98b5a691e | ||
|
|
ed24afd172 | ||
|
|
714556de65 | ||
|
|
547ec85b58 | ||
|
|
845d751e87 | ||
|
|
518a7f8a71 | ||
|
|
31323b01bc | ||
|
|
3a138ecc83 | ||
|
|
7294674a8b | ||
|
|
423b978395 | ||
|
|
ecf20ec7b8 | ||
|
|
c948a509fb | ||
|
|
f5ad19d76b | ||
|
|
d665d9e90e | ||
|
|
a5e10450dd | ||
|
|
e9d79b130d | ||
|
|
7951dac9d5 | ||
|
|
6c77351c58 | ||
|
|
7c4cda622f | ||
|
|
d8f8c1cb99 | ||
|
|
d2b9ad570f | ||
|
|
5b36f32996 | ||
|
|
3298030b8e | ||
|
|
6cfc696439 | ||
|
|
a93b3a06dd | ||
|
|
79e8d77ea0 | ||
|
|
d68fab9ee5 | ||
|
|
bda470245e | ||
|
|
0c95290f93 | ||
|
|
8989739d32 | ||
|
|
1112981e6e | ||
|
|
0cf82744ce | ||
|
|
5cdf838325 | ||
|
|
6418cad39f | ||
|
|
46529fd51e | ||
|
|
c09ba40a48 | ||
|
|
47d52896a1 | ||
|
|
d60c99b01c | ||
|
|
b8aeba06a2 | ||
|
|
8a0bc2d614 | ||
|
|
e34747d1ad | ||
|
|
1a6bc7c514 | ||
|
|
ffa0ddfdbf | ||
|
|
ca55bff1cf | ||
|
|
cfee5c4fdb | ||
|
|
e46185068b | ||
|
|
6ef2fea45e | ||
|
|
e244dd84a9 | ||
|
|
5034937a15 | ||
|
|
060045be65 | ||
|
|
9adfe8d484 | ||
|
|
799cc369e0 | ||
|
|
b97d3fea4b | ||
|
|
2a4ca9d5c3 | ||
|
|
747e40e74e | ||
|
|
cf279e7885 | ||
|
|
cbf968735a | ||
|
|
57b35e6007 | ||
|
|
1eaabdd8e5 | ||
|
|
dcd4e660a3 | ||
|
|
96409e74e5 | ||
|
|
e28ee097a1 | ||
|
|
2b4e544867 | ||
|
|
ee042a3481 | ||
|
|
63075f6846 | ||
|
|
7f2e42a06d | ||
|
|
3fbfa33b9a | ||
|
|
179aa75047 | ||
|
|
4658194d08 | ||
|
|
b35657814c | ||
|
|
a2322c77c6 | ||
|
|
b50c183c19 | ||
|
|
a941687db0 | ||
|
|
c2eef52b65 | ||
|
|
3e6cbbde04 | ||
|
|
6400536282 | ||
|
|
776103068f | ||
|
|
93beff3b65 | ||
|
|
22f8d86b05 | ||
|
|
3a9a9c7ad0 | ||
|
|
13238b1ad2 | ||
|
|
56f661e9c6 | ||
|
|
5351f46efb | ||
|
|
0cd3335b78 | ||
|
|
0611627448 | ||
|
|
f014918435 | ||
|
|
51e016089e |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
People who have agreed to the
|
||||
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
|
||||
can make contributions. Note that the CLA isn't a copyright
|
||||
_assigment_ but rather a copyright _license_.
|
||||
You retain the copyright on your contributions.
|
||||
|
||||
We follow the Google C/C++ style guide: https://google.github.io/styleguide/cppguide.html
|
||||
We'd appreciate if your contribution follows the same style guide.
|
||||
@@ -1,5 +1,5 @@
|
||||
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||
Copyright (c) 2013-2015 Cesanta Software Limited
|
||||
Copyright (c) 2013-2016 Cesanta Software Limited
|
||||
All rights reserved
|
||||
|
||||
This software is dual-licensed: you can redistribute it and/or modify
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
# <img src="http://www.cesanta.com/hubfs/www.cesanta.com/Images/mongoose_library.png" width="64" height="64"> Mongoose - Embedded Web Server
|
||||
|
||||
[](https://gitter.im/cesanta/mongoose?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# <img src="http://www.cesanta.com/hubfs/www.cesanta.com/Images/mongoose_library.png" width="64" height="64"> Mongoose - Embedded Web Server / Embedded Networking Library
|
||||
|
||||

|
||||
|
||||
|
||||
Mongoose is ideal for embedded environments, it has been designed as an open
|
||||
source platform for connecting devices and bringing them online.
|
||||
Mongoose is ideal for embedded environments. It has been designed
|
||||
for connecting devices and bringing them online.
|
||||
[Mongoose](https://www.cesanta.com/products)
|
||||
has been on the market since 2004 and attracted
|
||||
over 1 million cumulative downloads.
|
||||
@@ -16,21 +13,32 @@ network protocols or scalable network applications with little effort.
|
||||
Mongoose helps developers to manage the complexity of network programming
|
||||
and let them concentrate on the logic, saving time and money.
|
||||
|
||||
[Download Mongoose Source Code here](http://hubs.ly/H0150FK0)
|
||||
- [Download Mongoose Source Code here](http://hubs.ly/H01bWvx0)
|
||||
- [Check our latest releases] (https://github.com/cesanta/mongoose/releases)
|
||||
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
|
||||
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
|
||||
|
||||
> Nothing overdone. Nothing less. So unbelievably easy to use.
|
||||
> Just how good software should be!
|
||||
> - Pritin Tyagaraj, SAP
|
||||
> Just how good software should be! -- Pritin Tyagaraj, SAP
|
||||
|
||||
If you are looking for a complete IoT platform with firmware and cloud compotent, check out [Smart.js.] (https://github.com/cesanta/smart.js)
|
||||
|
||||
# Support
|
||||
- [Support Forum - Ask your technical questions here] (http://forum.cesanta.com/index.php?p=/categories/smart-js)
|
||||
- [Chat - Visit www.cesanta.com for our live chat] (http://www.cesanta.com)
|
||||
- [Commercial one-to-one support - Available to all commercial license holders] (https://www.cesanta.com/services-support)
|
||||
|
||||
# Features
|
||||
|
||||
* Cross-platform: works on Linux/UNIX, QNX, eCos, Windows, Android, iPhone, etc
|
||||
* Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
|
||||
iPhone, FreeRTOS (TI CC3200, ESP8266), etc
|
||||
* Single-threaded, asynchronous, non-blocking core with simple event-based API
|
||||
* Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
|
||||
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
|
||||
* Builtin protocols:
|
||||
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
||||
- HTTP client, HTTP server
|
||||
- Websocket client, Websocket server
|
||||
- WebSocket client, WebSocket server
|
||||
- JSON-RPC client, JSON-RPC server
|
||||
- MQTT client, MQTT broker
|
||||
- CoAP client, CoAP server
|
||||
@@ -41,13 +49,16 @@ and let them concentrate on the logic, saving time and money.
|
||||
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
||||
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
||||
files to your build tree
|
||||
* Extensively tested and production-ready, trusted by many blue chip businesses
|
||||
|
||||
# Examples & Documentation
|
||||
# Licensing
|
||||
|
||||
- [User Guide](https://docs.cesanta.com/mongoose) - Detailed User Guide and API reference
|
||||
- [examples](examples) - Collection of well-commented examples. To build any example,
|
||||
go into respective directory and type `make`
|
||||
Mongoose is released under commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
|
||||
|
||||
Commercial Projects:
|
||||
Once your project becomes commercialised GPLv2 licensing dictates that you need to either open your source fully or purchase a commercial license. Cesanta offer full, royalty-free commercial licenses without any GPL restrictions. If your needs require a custom license, we’d be happy to work on a solution with you. [Contact us for pricing.] (https://www.cesanta.com/contact)
|
||||
|
||||
Prototyping:
|
||||
While your project is still in prototyping stage and not for sale, you can use Mongoose’s open source code without license restrictions.
|
||||
|
||||
# Dashboard Example
|
||||
|
||||
@@ -60,42 +71,8 @@ the functionality:
|
||||
[Developing a new product? Contact us today to discuss how Mongoose can help
|
||||
](https://www.cesanta.com/contact)
|
||||
|
||||
# Contributions
|
||||
|
||||
# Licensing
|
||||
People who have agreed to the [Cesanta CLA] (https://docs.cesanta.com/contributors_la.shtml) can make contributions. Note that the CLA isn't a copyright assigment but rather a copyright license. You retain the copyright on your contributions.
|
||||
|
||||
You are using Mongoose under
|
||||
[GPLv2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
and until you commercialize your
|
||||
application, can continue to use Mongoose free of charge.
|
||||
|
||||
Once you commercialize your product, in order to comply with GPLv2
|
||||
you need to either open the source code of your product fully or
|
||||
alternatively purchase a commercial license.
|
||||
We offer [three levels of commercial licensing](https://www.cesanta.com/products):
|
||||
|
||||
- Mongoose Lite: cross platform integration, SSL/TLS, HTTP support
|
||||
- Mongoose: Mongoose Lite + HTTP CGI, HTTP SSI, HTTP Digest Auth,
|
||||
WebSocket support
|
||||
- Mongoose Premium: Mongoose + Plain TCP, UDP, JSON-RPC, MQTT, DNS,
|
||||
CoAP support
|
||||
|
||||
|
||||
[Enquire about commercial licensing here](https://www.cesanta.com/contact)
|
||||
|
||||
# Mongoose Binary
|
||||
|
||||
This is our easy to use web server for web developers (PHP, Ruby, Python, etc)
|
||||
and web designers. Available in three editions to suit your needs: free, pro
|
||||
(USD 5) and dev edition (from USD 8). To install, simply download, double-click
|
||||
to start and run browser - that's all!
|
||||
|
||||
[Download Mongoose Binary here](https://www.cesanta.com/mongoose)
|
||||
|
||||
# Other products by Cesanta
|
||||
|
||||
- [Smart.js](https://github.com/cesanta/smart.js) -
|
||||
Generic, hardware independent, full-stack IoT software platform
|
||||
- [V7](https://github.com/cesanta/v7) - Embedded JavaScript engine
|
||||
- [Frozen](https://github.com/cesanta/frozen) - JSON parser and generator
|
||||
- [SLRE](https://github.com/cesanta/slre) - Super Light Regular Expression
|
||||
library
|
||||
[](https://github.com/cesanta/mongoose)
|
||||
@@ -0,0 +1,118 @@
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of object file images to be generated ()
|
||||
# GEN_BINS - list of binaries to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
TARGET = eagle
|
||||
#FLAVOR = release
|
||||
FLAVOR = debug
|
||||
|
||||
EXTRA_CCFLAGS += -Wall -Werror
|
||||
|
||||
ifndef PDIR # {
|
||||
GEN_IMAGES= eagle.app.v6.out
|
||||
GEN_BINS= eagle.app.v6.bin
|
||||
SPECIAL_MKTARGETS=$(APP_MKTARGETS)
|
||||
SUBDIRS=user
|
||||
|
||||
endif # } PDIR
|
||||
|
||||
LDDIR = $(SDK_PATH)/ld
|
||||
|
||||
CCFLAGS += -Os
|
||||
|
||||
TARGET_LDFLAGS = \
|
||||
-nostdlib \
|
||||
-Wl,-EL \
|
||||
--longcalls \
|
||||
--text-section-literals
|
||||
|
||||
ifeq ($(FLAVOR),debug)
|
||||
TARGET_LDFLAGS += -g -O2
|
||||
endif
|
||||
|
||||
ifeq ($(FLAVOR),release)
|
||||
TARGET_LDFLAGS += -g -O0
|
||||
endif
|
||||
|
||||
COMPONENTS_eagle.app.v6 = \
|
||||
user/libuser.a
|
||||
|
||||
LINKFLAGS_eagle.app.v6 = \
|
||||
-L$(SDK_PATH)/lib \
|
||||
-Wl,--gc-sections \
|
||||
-nostdlib \
|
||||
-T$(LD_FILE) \
|
||||
-Wl,--no-check-sections \
|
||||
-u call_user_start \
|
||||
-Wl,-static \
|
||||
-Wl,--start-group \
|
||||
-lc \
|
||||
-lgcc \
|
||||
-lhal \
|
||||
-lphy \
|
||||
-lpp \
|
||||
-lnet80211 \
|
||||
-lwpa \
|
||||
-lcrypto \
|
||||
-lmain \
|
||||
-lfreertos \
|
||||
-llwip \
|
||||
$(DEP_LIBS_eagle.app.v6) \
|
||||
-Wl,--end-group
|
||||
|
||||
DEPENDS_eagle.app.v6 = \
|
||||
$(LD_FILE) \
|
||||
$(LDDIR)/eagle.rom.addr.v6.ld
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
|
||||
#UNIVERSAL_TARGET_DEFINES = \
|
||||
|
||||
# Other potential configuration flags include:
|
||||
# -DTXRX_TXBUF_DEBUG
|
||||
# -DTXRX_RXBUF_DEBUG
|
||||
# -DWLAN_CONFIG_CCX
|
||||
CONFIGURATION_DEFINES = -DICACHE_FLASH
|
||||
|
||||
DEFINES += \
|
||||
$(UNIVERSAL_TARGET_DEFINES) \
|
||||
$(CONFIGURATION_DEFINES)
|
||||
|
||||
DDEFINES += \
|
||||
$(UNIVERSAL_TARGET_DEFINES) \
|
||||
$(CONFIGURATION_DEFINES)
|
||||
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
sinclude $(SDK_PATH)/Makefile
|
||||
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
This is a Mongoose "Hello, world" that can be compiled under ESP8266 RTOS SDK.
|
||||
|
||||
It sets up an AP (SSID `Mongoose`) and serves a "hello world" page on http://192.168.4.1/
|
||||
|
||||
Most of the the boilerplate comes from [project_template](https://github.com/espressif/ESP8266_RTOS_SDK/tree/master/examples/project_template) (@ [3ca6af5](https://github.com/espressif/ESP8266_RTOS_SDK/tree/3ca6af5da68678d809b34c7cd98bee71e0235039/examples/project_template)) with minimal changes.
|
||||
|
||||
To build with no changes to the SDK, you will need a module with 1MB (8Mb) flash or more.
|
||||
|
||||
Compile (for NodeMCU 1.0):
|
||||
|
||||
```
|
||||
$ export SDK_PATH=/path/to/ESP8266_RTOS_SDK
|
||||
$ export BIN_PATH=./bin
|
||||
$ make clean; make BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=dio SPI_SIZE_MAP=6
|
||||
```
|
||||
|
||||
Flash (using [esptool](https://github.com/themadinventor/esptool)):
|
||||
|
||||
```
|
||||
$ esptool.py --port /dev/ttyUSB0 --baud 230400 \
|
||||
write_flash --flash_mode=dio --flash_size=32m \
|
||||
0x00000 ${SDK_PATH}/bin/boot_v1.4\(b1\).bin \
|
||||
0x01000 ${BIN_PATH}/upgrade/user1.4096.new.6.bin
|
||||
```
|
||||
|
||||
|
||||
The output can be made to fit in 512KB (4Mb), but stock linker scripts do not reserve enough space for code.
|
||||
Custom linker script is provided for that, so you can use it for smaller devices like so (example that will work with ESP-01):
|
||||
|
||||
```
|
||||
$ make clean; make BOOT=none APP=0 SPI_SPEED=40 SPI_MODE=qio SPI_SIZE_MAP=0 LD_FILE=ld/eagle.app.v6.512.compact.ld
|
||||
$ esptool.py --port /dev/ttyUSB0 --baud 230400 \
|
||||
write_flash --flash_mode=qio --flash_size=4m \
|
||||
0x00000 ${BIN_PATH}/eagle.flash.bin \
|
||||
0x10000 ${BIN_PATH}/eagle.irom0text.bin
|
||||
```
|
||||
@@ -0,0 +1,173 @@
|
||||
#!/bin/bash
|
||||
|
||||
:<<!
|
||||
******NOTICE******
|
||||
MUST set SDK_PATH & BIN_PATH firstly!!!
|
||||
example:
|
||||
export SDK_PATH=~/ESP8266_RTOS_SDK
|
||||
export BIN_PATH=~/esp8266_bin
|
||||
!
|
||||
|
||||
echo "gen_misc.sh version 20150911"
|
||||
echo ""
|
||||
|
||||
if [ $SDK_PATH ]; then
|
||||
echo "SDK_PATH:"
|
||||
echo "$SDK_PATH"
|
||||
echo ""
|
||||
else
|
||||
echo "ERROR: Please export SDK_PATH in gen_misc.sh firstly, exit!!!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ $BIN_PATH ]; then
|
||||
echo "BIN_PATH:"
|
||||
echo "$BIN_PATH"
|
||||
echo ""
|
||||
else
|
||||
echo "ERROR: Please export BIN_PATH in gen_misc.sh firstly, exit!!!"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "Please check SDK_PATH & BIN_PATH, enter (Y/y) to continue:"
|
||||
read input
|
||||
|
||||
if [[ $input != Y ]] && [[ $input != y ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
echo "Please follow below steps(1-5) to generate specific bin(s):"
|
||||
echo "STEP 1: use boot_v1.2+ by default"
|
||||
boot=new
|
||||
|
||||
echo "boot mode: $boot"
|
||||
echo ""
|
||||
|
||||
echo "STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)"
|
||||
echo "enter (0/1/2, default 0):"
|
||||
read input
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
if [ $boot != none ]; then
|
||||
boot=none
|
||||
echo "ignore boot"
|
||||
fi
|
||||
app=0
|
||||
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
|
||||
elif [ $input == 1 ]; then
|
||||
if [ $boot == none ]; then
|
||||
app=0
|
||||
echo "choose no boot before"
|
||||
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
|
||||
else
|
||||
app=1
|
||||
echo "generate bin: user1.bin"
|
||||
fi
|
||||
elif [ $input == 2 ]; then
|
||||
if [ $boot == none ]; then
|
||||
app=0
|
||||
echo "choose no boot before"
|
||||
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
|
||||
else
|
||||
app=2
|
||||
echo "generate bin: user2.bin"
|
||||
fi
|
||||
else
|
||||
if [ $boot != none ]; then
|
||||
boot=none
|
||||
echo "ignore boot"
|
||||
fi
|
||||
app=0
|
||||
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
echo "STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)"
|
||||
echo "enter (0/1/2/3, default 2):"
|
||||
read input
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
spi_speed=40
|
||||
elif [ $input == 0 ]; then
|
||||
spi_speed=20
|
||||
elif [ $input == 1 ]; then
|
||||
spi_speed=26.7
|
||||
elif [ $input == 3 ]; then
|
||||
spi_speed=80
|
||||
else
|
||||
spi_speed=40
|
||||
fi
|
||||
|
||||
echo "spi speed: $spi_speed MHz"
|
||||
echo ""
|
||||
|
||||
echo "STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)"
|
||||
echo "enter (0/1/2/3, default 0):"
|
||||
read input
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
spi_mode=QIO
|
||||
elif [ $input == 1 ]; then
|
||||
spi_mode=QOUT
|
||||
elif [ $input == 2 ]; then
|
||||
spi_mode=DIO
|
||||
elif [ $input == 3 ]; then
|
||||
spi_mode=DOUT
|
||||
else
|
||||
spi_mode=QIO
|
||||
fi
|
||||
|
||||
echo "spi mode: $spi_mode"
|
||||
echo ""
|
||||
|
||||
echo "STEP 5: choose spi size and map"
|
||||
echo " 0= 512KB( 256KB+ 256KB)"
|
||||
echo " 2=1024KB( 512KB+ 512KB)"
|
||||
echo " 3=2048KB( 512KB+ 512KB)"
|
||||
echo " 4=4096KB( 512KB+ 512KB)"
|
||||
echo " 5=2048KB(1024KB+1024KB)"
|
||||
echo " 6=4096KB(1024KB+1024KB)"
|
||||
echo "enter (0/2/3/4/5/6, default 0):"
|
||||
read input
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
spi_size_map=0
|
||||
echo "spi size: 512KB"
|
||||
echo "spi ota map: 256KB + 256KB"
|
||||
elif [ $input == 2 ]; then
|
||||
spi_size_map=2
|
||||
echo "spi size: 1024KB"
|
||||
echo "spi ota map: 512KB + 512KB"
|
||||
elif [ $input == 3 ]; then
|
||||
spi_size_map=3
|
||||
echo "spi size: 2048KB"
|
||||
echo "spi ota map: 512KB + 512KB"
|
||||
elif [ $input == 4 ]; then
|
||||
spi_size_map=4
|
||||
echo "spi size: 4096KB"
|
||||
echo "spi ota map: 512KB + 512KB"
|
||||
elif [ $input == 5 ]; then
|
||||
spi_size_map=5
|
||||
echo "spi size: 2048KB"
|
||||
echo "spi ota map: 1024KB + 1024KB"
|
||||
elif [ $input == 6 ]; then
|
||||
spi_size_map=6
|
||||
echo "spi size: 4096KB"
|
||||
echo "spi ota map: 1024KB + 1024KB"
|
||||
else
|
||||
spi_size_map=0
|
||||
echo "spi size: 512KB"
|
||||
echo "spi ota map: 256KB + 256KB"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
echo "start..."
|
||||
echo ""
|
||||
|
||||
make clean
|
||||
|
||||
make BOOT=$boot APP=$app SPI_SPEED=$spi_speed SPI_MODE=$spi_mode SPI_SIZE_MAP=$spi_size_map
|
||||
@@ -0,0 +1,20 @@
|
||||
/* eagle.flash.bin @ 0x00000 */
|
||||
/* eagle.irom0text.bin @ 0x10000 */
|
||||
|
||||
/*
|
||||
* Flash map for 512KB flash.
|
||||
*
|
||||
* There is 0x8000 (32KB) available between 0x8000 and 0x10000.
|
||||
*
|
||||
* Note: IROM images starts at 0x10000 (ignore Makefile output which says 0x40000.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x18000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x6C000
|
||||
}
|
||||
|
||||
INCLUDE "../ld/eagle.app.v6.common.ld"
|
||||
@@ -0,0 +1,56 @@
|
||||
This is a simple project template.
|
||||
|
||||
sample_lib is an example for multi-level folder Makefile, notice the folder structure and each Makefile, you can get the clue.
|
||||
|
||||
|
||||
HOWTO:
|
||||
1. Copy this folder to anywhere.
|
||||
Example:
|
||||
Copy to ~/workspace/project_template
|
||||
You can rename this folder as you like.
|
||||
|
||||
2. Export SDK_PATH and BIN_PATH.
|
||||
Example:
|
||||
Your SDK path is ~/esp_iot_rtos_sdk, and want generate bin at ~/esp8266_bin.
|
||||
Do follow steps:
|
||||
1>. export SDK_PATH=~/esp_iot_rtos_sdk
|
||||
2>. export BIN_PATH=~/esp8266_bin
|
||||
SDK and project are seperate, you can update SDK without change your project.
|
||||
|
||||
3. Enter project_template folder, run ./gen_misc.sh, and follow the tips and steps.
|
||||
|
||||
|
||||
Compile Options:
|
||||
(1) COMPILE
|
||||
Possible value: xcc
|
||||
Default value:
|
||||
If not set, use gcc by default.
|
||||
|
||||
(2) BOOT
|
||||
Possible value: none/old/new
|
||||
none: no need boot
|
||||
old: use boot_v1.1
|
||||
new: use boot_v1.2
|
||||
Default value: new
|
||||
|
||||
(3) APP
|
||||
Possible value: 0/1/2
|
||||
0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin
|
||||
1: generate user1
|
||||
2: generate user2
|
||||
Default value: 0
|
||||
|
||||
(3) SPI_SPEED
|
||||
Possible value: 20/26.7/40/80
|
||||
Default value: 40
|
||||
|
||||
(4) SPI_MODE
|
||||
Possible value: QIO/QOUT/DIO/DOUT
|
||||
Default value: QIO
|
||||
|
||||
(4) SPI_SIZE_MAP
|
||||
Possible value: 0/2/3/4/5/6
|
||||
Default value: 0
|
||||
|
||||
For example:
|
||||
make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of images to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libuser.a
|
||||
endif
|
||||
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
DEFINES += -DMG_LOCALS \
|
||||
-DMG_NO_BSD_SOCKETS \
|
||||
-DMG_DISABLE_FILESYSTEM \
|
||||
-DMG_DISABLE_STDIO \
|
||||
-DMG_MAX_HTTP_HEADERS=20 -DMG_MAX_HTTP_REQUEST_SIZE=1024 \
|
||||
-DMG_MAX_PATH=40 -DMG_MAX_HTTP_SEND_MBUF=1024 \
|
||||
-DRTOS_SDK -DMG_LWIP -DLWIP_TIMEVAL_PRIVATE=0 \
|
||||
-DMG_INTERNAL=
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES += -I ./
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
|
||||
/* Makes fprintf(stdout) and stderr work. */
|
||||
/*
|
||||
_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) {
|
||||
if (fd == 1 || fd == 2) {
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++) {
|
||||
os_putc(((char *) buf)[i]);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* You'll need to implement _open_r and friends if you want file operations. See
|
||||
* https://github.com/cesanta/smart.js/blob/master/platforms/esp8266/user/esp_fs.c
|
||||
* for SPIFFS-based implementation.
|
||||
*/
|
||||
|
||||
void abort(void) __attribute__((no_instrument_function));
|
||||
void abort(void) {
|
||||
/* cause an unaligned access exception, that will drop you into gdb */
|
||||
*(int *) 1 = 1;
|
||||
while (1)
|
||||
; /* avoid gcc warning because stdlib abort() has noreturn attribute */
|
||||
}
|
||||
|
||||
void _exit(int status) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tzp) {
|
||||
uint32_t time = system_get_time();
|
||||
tp->tv_sec = time / 1000000;
|
||||
tp->tv_usec = time % 1000000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long int random(void) {
|
||||
return os_random();
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../mongoose.c
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../mongoose.h
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*/
|
||||
|
||||
#include "esp_common.h"
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
#define AP_SSID "Mongoose"
|
||||
#define AP_PASS "Mongoose"
|
||||
#define AP_CHAN 9
|
||||
#define MG_LISTEN_ADDR "80"
|
||||
|
||||
#define MG_TASK_STACK_SIZE 2048
|
||||
#define MG_TASK_PRIORITY 1
|
||||
|
||||
void uart_div_modify(int uart_no, unsigned int freq);
|
||||
|
||||
void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
static const char *reply_fmt =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"\r\n"
|
||||
"Hello %s\n";
|
||||
LOG(LL_DEBUG, ("conn %p ev %d", nc, ev));
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_ACCEPT: {
|
||||
char addr[32];
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
||||
LOG(LL_INFO, ("Connection %p from %s", nc, addr));
|
||||
break;
|
||||
}
|
||||
case MG_EV_HTTP_REQUEST: {
|
||||
char addr[32];
|
||||
struct http_message *hm = (struct http_message *) p;
|
||||
(void) hm;
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
|
||||
LOG(LL_INFO,
|
||||
("HTTP request from %s: %.*s %.*s", addr, (int) hm->method.len,
|
||||
hm->method.p, (int) hm->uri.len, hm->uri.p));
|
||||
mg_printf(nc, reply_fmt, addr);
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
break;
|
||||
}
|
||||
case MG_EV_CLOSE: {
|
||||
LOG(LL_INFO, ("Connection %p closed", nc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup_ap() {
|
||||
struct softap_config cfg;
|
||||
|
||||
wifi_set_opmode_current(SOFTAP_MODE);
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
strcpy((char *) cfg.ssid, AP_SSID);
|
||||
strcpy((char *) cfg.password, AP_PASS);
|
||||
cfg.ssid_len = strlen((const char *) cfg.ssid);
|
||||
cfg.authmode =
|
||||
strlen((const char *) cfg.password) ? AUTH_WPA2_PSK : AUTH_OPEN;
|
||||
cfg.channel = AP_CHAN;
|
||||
cfg.ssid_hidden = 0;
|
||||
cfg.max_connection = 10;
|
||||
cfg.beacon_interval = 100; /* ms */
|
||||
|
||||
LOG(LL_INFO, ("Setting up AP '%s' on channel %d", cfg.ssid, cfg.channel));
|
||||
wifi_softap_set_config_current(&cfg);
|
||||
}
|
||||
|
||||
static void mg_task(void *arg) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
|
||||
cs_log_set_level(LL_INFO);
|
||||
|
||||
LOG(LL_INFO, ("SDK version: %s", system_get_sdk_version()));
|
||||
setup_ap();
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
|
||||
nc = mg_bind(&mgr, MG_LISTEN_ADDR, ev_handler);
|
||||
if (nc == NULL) {
|
||||
LOG(LL_ERROR, ("Error setting up listener!"));
|
||||
return;
|
||||
}
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
|
||||
while (1) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
xTaskHandle s_mg_task_handle;
|
||||
|
||||
void user_init(void) {
|
||||
uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||
|
||||
// setvbuf(stdout, NULL, _IONBF, 0);
|
||||
// setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
||||
xTaskCreate(mg_task, (const signed char *) "mongoose", MG_TASK_STACK_SIZE,
|
||||
NULL, MG_TASK_PRIORITY, &s_mg_task_handle);
|
||||
}
|
||||
|
||||
void call_user_start(void) {
|
||||
user_init();
|
||||
}
|
||||
@@ -10,9 +10,9 @@ static struct mg_serve_http_opts s_http_server_opts;
|
||||
static int s_sig_num = 0;
|
||||
static void *s_db_handle = NULL;
|
||||
static const char *s_db_path = "api_server.db";
|
||||
static const struct mg_str s_get_method = MG_STR("GET");
|
||||
static const struct mg_str s_put_method = MG_STR("PUT");
|
||||
static const struct mg_str s_delele_method = MG_STR("DELETE");
|
||||
static const struct mg_str s_get_method = MG_MK_STR("GET");
|
||||
static const struct mg_str s_put_method = MG_MK_STR("PUT");
|
||||
static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
|
||||
|
||||
static void signal_handler(int sig_num) {
|
||||
signal(sig_num, signal_handler);
|
||||
@@ -28,7 +28,7 @@ static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
static const struct mg_str api_prefix = MG_STR("/api/v1");
|
||||
static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
struct mg_str key;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ static uint8_t board_ip[] = {192, 168, 10, 177};
|
||||
#ifdef WIFI_CC3000
|
||||
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
||||
static uint8_t gateway[] = {192, 168, 10, 254};
|
||||
static uint8_t dmg_ip[] = {192, 168, 10, 254};
|
||||
static uint8_t dns_ip[] = {192, 168, 10, 254};
|
||||
|
||||
static const char *wlan_ssid = "mynetwork";
|
||||
static const char *wlan_pwd = "mypassword";
|
||||
@@ -117,7 +117,7 @@ void setup()
|
||||
avr_netinit(board_mac, board_ip);
|
||||
#elif defined(WIFI_CC3000)
|
||||
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dmg_ip)) != 0) {
|
||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dns_ip)) != 0) {
|
||||
Serial.println("Initialization error, check network settings");
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ static uint8_t board_ip[] = {192, 168, 10, 8};
|
||||
#ifdef WIFI_CC3000
|
||||
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
||||
static uint8_t gateway[] = {192, 168, 10, 254};
|
||||
static uint8_t dmg_ip[] = {192, 168, 10, 254};
|
||||
static uint8_t dns_ip[] = {192, 168, 10, 254};
|
||||
|
||||
static const char *wlan_ssid = "mynetwork";
|
||||
static const char *wlan_pwd = "mypassword";
|
||||
@@ -116,7 +116,7 @@ void setup() {
|
||||
avr_netinit(board_mac, board_ip);
|
||||
#elif defined(WIFI_CC3000)
|
||||
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dmg_ip)) != 0) {
|
||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dns_ip)) != 0) {
|
||||
Serial.println("Initialization error, check network settings");
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
PROG = big_upload
|
||||
MODULE_CFLAGS = -DMG_ENABLE_HTTP_STREAMING_MULTIPART
|
||||
include ../examples.mk
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// This example demonstrates how to handle very large requests without keeping
|
||||
// them in memory.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
|
||||
struct file_writer_data {
|
||||
FILE *fp;
|
||||
size_t bytes_written;
|
||||
};
|
||||
|
||||
static void handle_request(struct mg_connection *nc) {
|
||||
// This handler gets for all endpoints but /upload
|
||||
mg_printf(nc, "%s",
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n"
|
||||
"<html><body>Upload example."
|
||||
"<form method=\"POST\" action=\"/upload\" "
|
||||
" enctype=\"multipart/form-data\">"
|
||||
"<input type=\"file\" name=\"file\" /> <br/>"
|
||||
"<input type=\"submit\" value=\"Upload\" />"
|
||||
"</form></body></html>");
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
}
|
||||
|
||||
static void handle_upload(struct mg_connection *nc, int ev, void *p) {
|
||||
struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
|
||||
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part*)p;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_PART_BEGIN: {
|
||||
if (data == NULL) {
|
||||
data = calloc(1, sizeof(struct file_writer_data));
|
||||
data->fp = tmpfile();
|
||||
data->bytes_written = 0;
|
||||
|
||||
if (data->fp == NULL) {
|
||||
mg_printf(nc, "%s",
|
||||
"HTTP/1.1 500 Failed to open a file\r\n"
|
||||
"Content-Length: 0\r\n\r\n");
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
return;
|
||||
}
|
||||
nc->user_data = (void *) data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MG_EV_HTTP_PART_DATA: {
|
||||
if (fwrite(mp->data.p, 1, mp->data.len, data->fp) != mp->data.len) {
|
||||
mg_printf(nc, "%s",
|
||||
"HTTP/1.1 500 Failed to write to a file\r\n"
|
||||
"Content-Length: 0\r\n\r\n");
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
return;
|
||||
}
|
||||
data->bytes_written += mp->data.len;
|
||||
break;
|
||||
}
|
||||
case MG_EV_HTTP_PART_END: {
|
||||
mg_printf(nc,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"Connection: close\r\n\r\n"
|
||||
"Written %ld of POST data to a temp file\n\n",
|
||||
(long) ftell(data->fp));
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
fclose(data->fp);
|
||||
free(data);
|
||||
nc->user_data = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
(void) ev_data;
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_REQUEST:
|
||||
// Invoked when the full HTTP request is in the buffer (including body).
|
||||
handle_request(nc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
|
||||
mg_register_http_endpoint(nc, "/upload", handle_upload);
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -17,20 +17,20 @@ static in_addr_t s_our_ip_addr;
|
||||
static const char *s_listening_addr = "udp://:5533";
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct mg_dmg_message *msg;
|
||||
struct mg_dmg_resource_record *rr;
|
||||
struct mg_dmg_reply reply;
|
||||
struct mg_dns_message *msg;
|
||||
struct mg_dns_resource_record *rr;
|
||||
struct mg_dns_reply reply;
|
||||
int i;
|
||||
|
||||
switch (ev) {
|
||||
case MG_DNS_MESSAGE:
|
||||
msg = (struct mg_dmg_message *) ev_data;
|
||||
reply = mg_dmg_create_reply(&nc->send_mbuf, msg);
|
||||
msg = (struct mg_dns_message *) ev_data;
|
||||
reply = mg_dns_create_reply(&nc->send_mbuf, msg);
|
||||
|
||||
for (i = 0; i < msg->num_questions; i++) {
|
||||
rr = &msg->questions[i];
|
||||
if (rr->rtype == MG_DNS_A_RECORD) {
|
||||
mg_dmg_reply_record(&reply, rr, NULL, rr->rtype, 3600,
|
||||
mg_dns_reply_record(&reply, rr, NULL, rr->rtype, 3600,
|
||||
&s_our_ip_addr, 4);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
* See http://goo.gl/QWvufr for a distinction between NXDOMAIN and NODATA.
|
||||
*/
|
||||
|
||||
mg_dmg_send_reply(nc, &reply);
|
||||
mg_dns_send_reply(nc, &reply);
|
||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
* Copyright (c) 2015 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* This program sends CoAP CON-message to server (coap.me by default)
|
||||
* This program sends CoAP CON-message to server (coap.me by default)
|
||||
* and waits for answer.
|
||||
*/
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static int s_time_to_exit = 0;
|
||||
static char* s_default_address = "udp://coap.me:5683";
|
||||
static char *s_default_address = "udp://coap.me:5683";
|
||||
|
||||
static void coap_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
switch (ev) {
|
||||
@@ -31,17 +31,16 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
break;
|
||||
}
|
||||
case MG_EV_COAP_ACK:
|
||||
case MG_EV_COAP_RST: {
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *)p;
|
||||
printf("ACK/RST for message with msg_id = %d received\n",
|
||||
cm->msg_id);
|
||||
case MG_EV_COAP_RST: {
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *) p;
|
||||
printf("ACK/RST for message with msg_id = %d received\n", cm->msg_id);
|
||||
s_time_to_exit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
char *address = s_default_address;
|
||||
@@ -50,7 +49,7 @@ int main(int argc, char* argv[]) {
|
||||
address = argv[1];
|
||||
}
|
||||
|
||||
printf("Using %s as CoAP server\n", address);
|
||||
printf("Using %s as CoAP server\n", address);
|
||||
|
||||
mg_mgr_init(&mgr, 0);
|
||||
|
||||
@@ -63,10 +62,10 @@ int main(int argc, char* argv[]) {
|
||||
mg_set_protocol_coap(nc);
|
||||
|
||||
while (!s_time_to_exit) {
|
||||
mg_mgr_poll(&mgr, 1);
|
||||
mg_mgr_poll(&mgr, 1000000);
|
||||
}
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2,18 +2,18 @@
|
||||
* Copyright (c) 2015 Cesanta Software Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* This program listens on 5683 for CoAP messages,
|
||||
* This program listens on 5683 for CoAP messages,
|
||||
* sends ACK is nessesary and dump everything received.
|
||||
* It is possible to use ../coap_client to send message.
|
||||
*/
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static char* s_default_address = "udp://:5683";
|
||||
static char *s_default_address = "udp://:5683";
|
||||
static int s_sig_received = 0;
|
||||
|
||||
static void signal_handler(int sig_num) {
|
||||
signal(sig_num, signal_handler);
|
||||
signal(sig_num, signal_handler);
|
||||
s_sig_received = sig_num;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
switch (ev) {
|
||||
case MG_EV_COAP_CON: {
|
||||
uint32_t res;
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *)p;
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *) p;
|
||||
printf("CON with msg_id = %d received\n", cm->msg_id);
|
||||
res = mg_coap_send_ack(nc, cm->msg_id);
|
||||
if (res == 0) {
|
||||
@@ -34,10 +34,9 @@ static void coap_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
}
|
||||
case MG_EV_COAP_NOC:
|
||||
case MG_EV_COAP_ACK:
|
||||
case MG_EV_COAP_RST: {
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *)p;
|
||||
printf("ACK/RST/NOC with msg_id = %d received\n",
|
||||
cm->msg_id);
|
||||
case MG_EV_COAP_RST: {
|
||||
struct mg_coap_message *cm = (struct mg_coap_message *) p;
|
||||
printf("ACK/RST/NOC with msg_id = %d received\n", cm->msg_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -58,12 +57,12 @@ int main() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Listening for CoAP messages at %s\n", s_default_address);
|
||||
printf("Listening for CoAP messages at %s\n", s_default_address);
|
||||
|
||||
mg_set_protocol_coap(nc);
|
||||
|
||||
while (!s_sig_received) {
|
||||
mg_mgr_poll(&mgr, 1);
|
||||
mg_mgr_poll(&mgr, 1000000);
|
||||
}
|
||||
|
||||
printf("Exiting on signal %d\n", s_sig_received);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
PROG = server
|
||||
include ../examples.mk
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
if (ev == MG_EV_HTTP_REQUEST) {
|
||||
mg_serve_http(nc, p, s_http_server_opts); // Serves static content
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
cs_stat_t st;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
fprintf(stderr, "Cannot bind to %s\n", s_http_port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "web_root"; // Set up web root directory
|
||||
|
||||
if (mg_stat(s_http_server_opts.document_root, &st) != 0) {
|
||||
fprintf(stderr, "%s", "Cannot find web_root directory, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Connected device demo</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<img src="logo.png" style="float:right; height: 50px; border-radius: 3px;">
|
||||
<h1>Connected device demo - static content only</h1>
|
||||
|
||||
<p>
|
||||
This page shows initial steps on how to make a device connected.
|
||||
Mongoose serves static content from the <code>web_root</code>
|
||||
directory. Images, CSS, HTML, JavaScript files could be dropped into the
|
||||
<code>web_root</code> directory - and they'll be served happily
|
||||
by Mongoose.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Below is a placeholder for the
|
||||
settings section, and a real-time dashboard, which will be
|
||||
implemented in the following examples.
|
||||
Both settings section, and a dashboard section, could be organised
|
||||
differently on this UI - for example, in different tabs. But, to
|
||||
make the demonstration clearer, we show everything on one page.
|
||||
</p>
|
||||
|
||||
<h1>Settings section</h1>
|
||||
<p>Nothing here yet</p>
|
||||
|
||||
<h1>Dashboard section</h1>
|
||||
<p>Nothing here yet</p>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,31 @@
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #36c;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 16px/1.4 Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 800px;
|
||||
margin: 1em auto;
|
||||
padding: 2em;
|
||||
background-color: #fff;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #f0f0f0;
|
||||
padding: 0 0.3em;
|
||||
color: #396;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #69c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
PROG = server
|
||||
include ../examples.mk
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
struct device_settings {
|
||||
char setting1[100];
|
||||
char setting2[100];
|
||||
};
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
static struct device_settings s_settings = { "value1", "value2" };
|
||||
|
||||
static void handle_save(struct mg_connection *nc, struct http_message *hm) {
|
||||
// Get form variables and store settings values
|
||||
mg_get_http_var(&hm->body, "setting1", s_settings.setting1,
|
||||
sizeof(s_settings.setting1));
|
||||
mg_get_http_var(&hm->body, "setting2", s_settings.setting2,
|
||||
sizeof(s_settings.setting2));
|
||||
|
||||
// Send response
|
||||
mg_printf(nc, "%s", "HTTP/1.1 302 OK\r\nLocation: /\r\n\r\n");
|
||||
}
|
||||
|
||||
static void handle_ssi_call(struct mg_connection *nc, const char *param) {
|
||||
if (strcmp(param, "setting1") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting1);
|
||||
} else if (strcmp(param, "setting2") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting2);
|
||||
}
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_REQUEST:
|
||||
if (mg_vcmp(&hm->uri, "/save") == 0) {
|
||||
handle_save(nc, hm);
|
||||
} else {
|
||||
mg_serve_http(nc, hm, s_http_server_opts); // Serve static content
|
||||
}
|
||||
break;
|
||||
case MG_EV_SSI_CALL:
|
||||
handle_ssi_call(nc, ev_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
cs_stat_t st;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
fprintf(stderr, "Cannot bind to %s\n", s_http_port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "web_root"; // Set up web root directory
|
||||
|
||||
if (mg_stat(s_http_server_opts.document_root, &st) != 0) {
|
||||
fprintf(stderr, "%s", "Cannot find web_root directory, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Connected device demo</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<img src="logo.png" style="float:right; height: 50px; border-radius: 3px;">
|
||||
<h1>Connected device demo - settings section</h1>
|
||||
|
||||
<p>
|
||||
This page is one of the series of examples that show how to make
|
||||
devices connected with Mongoose. Here, we create a settings section
|
||||
that expose some internal device variables, and allow user to change
|
||||
them. They could be some stored in a database, in a file, or in
|
||||
firmware RAM. In this example, we store them in RAM, and use two
|
||||
variables, one integer and one string. We use SSI
|
||||
<code><!--#call parameter_name --></code> directive to fetch
|
||||
variable values from Mongoose.
|
||||
</p>
|
||||
|
||||
<h1>Settings section</h1>
|
||||
<form method="POST" action="/save">
|
||||
<fieldset>
|
||||
<legend>Device settings</legend>
|
||||
<label>Setting 1:</label> <input type="text"
|
||||
name="setting1" value="<!--#call setting1 -->" >
|
||||
<label>Setting 2:</label> <input type="text"
|
||||
name="setting2" value="<!--#call setting2 -->" >
|
||||
|
||||
<div>
|
||||
<button type="submit">Save Settings</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h1>Dashboard section</h1>
|
||||
<p>Nothing here yet</p>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,67 @@
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #36c;
|
||||
color: #555;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 16px/1.4 Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 800px;
|
||||
margin: 1em auto;
|
||||
padding: 2em;
|
||||
background-color: #fff;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #ccc;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
font-style: italic;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
fieldset label {
|
||||
text-align: right;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
font-size: 100%;
|
||||
padding: 0.2em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #666;
|
||||
background: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.2em 2em;
|
||||
font-size: 100%;
|
||||
cursor: pointer;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #f0f0f0;
|
||||
padding: 0 0.3em;
|
||||
color: #396;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #69c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
PROG = server
|
||||
include ../examples.mk
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
struct device_settings {
|
||||
char setting1[100];
|
||||
char setting2[100];
|
||||
};
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
static struct device_settings s_settings = { "value1", "value2" };
|
||||
|
||||
static void handle_save(struct mg_connection *nc, struct http_message *hm) {
|
||||
// Get form variables and store settings values
|
||||
mg_get_http_var(&hm->body, "setting1", s_settings.setting1,
|
||||
sizeof(s_settings.setting1));
|
||||
mg_get_http_var(&hm->body, "setting2", s_settings.setting2,
|
||||
sizeof(s_settings.setting2));
|
||||
|
||||
// Send response
|
||||
mg_printf(nc, "%s", "HTTP/1.1 302 OK\r\nLocation: /\r\n\r\n");
|
||||
}
|
||||
|
||||
static void handle_get_cpu_usage(struct mg_connection *nc) {
|
||||
// Generate random value, as an example of changing CPU usage
|
||||
// Getting real CPU usage depends on the OS.
|
||||
int cpu_usage = (double) rand() / RAND_MAX * 100.0;
|
||||
|
||||
// Use chunked encoding in order to avoid calculating Content-Length
|
||||
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
|
||||
// Output JSON object which holds CPU usage data
|
||||
mg_printf_http_chunk(nc, "{ \"result\": %d }", cpu_usage);
|
||||
|
||||
// Send empty chunk, the end of response
|
||||
mg_send_http_chunk(nc, "", 0);
|
||||
}
|
||||
|
||||
static void handle_ssi_call(struct mg_connection *nc, const char *param) {
|
||||
if (strcmp(param, "setting1") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting1);
|
||||
} else if (strcmp(param, "setting2") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting2);
|
||||
}
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_REQUEST:
|
||||
if (mg_vcmp(&hm->uri, "/save") == 0) {
|
||||
handle_save(nc, hm);
|
||||
} else if (mg_vcmp(&hm->uri, "/get_cpu_usage") == 0) {
|
||||
handle_get_cpu_usage(nc);
|
||||
} else {
|
||||
mg_serve_http(nc, hm, s_http_server_opts); // Serve static content
|
||||
}
|
||||
break;
|
||||
case MG_EV_SSI_CALL:
|
||||
handle_ssi_call(nc, ev_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
cs_stat_t st;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
fprintf(stderr, "Cannot bind to %s\n", s_http_port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "web_root"; // Set up web root directory
|
||||
|
||||
if (mg_stat(s_http_server_opts.document_root, &st) != 0) {
|
||||
fprintf(stderr, "%s", "Cannot find web_root directory, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Connected device demo</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
|
||||
<script type="text/javascript" src="main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<img src="logo.png" style="float:right; height: 50px; border-radius: 3px;">
|
||||
<h1>Connected device demo - RESTful call</h1>
|
||||
|
||||
<p>
|
||||
This page is one of the series of examples that show how to make
|
||||
devices connected with Mongoose. Here we add a RESTful call
|
||||
to the Mongoose to show CPU usage stats on a dashboard.
|
||||
RESTful call is done using Jquery's <code>ajax</code> call.
|
||||
</p>
|
||||
|
||||
<h1>Settings section</h1>
|
||||
<form method="POST" action="/save">
|
||||
<fieldset>
|
||||
<legend>Device settings</legend>
|
||||
<label>Setting 1:</label> <input type="text"
|
||||
name="setting1" value="<!--#call setting1 -->" >
|
||||
<label>Setting 2:</label> <input type="text"
|
||||
name="setting2" value="<!--#call setting2 -->" >
|
||||
|
||||
<div>
|
||||
<button type="submit">Save Settings</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h1>Dashboard section</h1>
|
||||
<label>CPU usage:</label> <span id="cpu_usage"> </span>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^Line truncated
|
||||
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[cLine truncated
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,12 @@
|
||||
$(document).ready(function() {
|
||||
// Start 1-second timer to call RESTful endpoint
|
||||
setInterval(function() {
|
||||
$.ajax({
|
||||
url: '/get_cpu_usage',
|
||||
dataType: 'json',
|
||||
success: function(json) {
|
||||
$('#cpu_usage').text(json.result + '% ');
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #36c;
|
||||
color: #555;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 16px/1.4 Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 800px;
|
||||
margin: 1em auto;
|
||||
padding: 2em;
|
||||
background-color: #fff;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #ccc;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
font-style: italic;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
fieldset label {
|
||||
text-align: right;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
font-size: 100%;
|
||||
padding: 0.2em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #666;
|
||||
background: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.2em 2em;
|
||||
font-size: 100%;
|
||||
cursor: pointer;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #f0f0f0;
|
||||
padding: 0 0.3em;
|
||||
color: #396;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #69c;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
PROG = server
|
||||
include ../examples.mk
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright (c) 2015 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
struct device_settings {
|
||||
char setting1[100];
|
||||
char setting2[100];
|
||||
};
|
||||
|
||||
static const char *s_http_port = "8000";
|
||||
static struct mg_serve_http_opts s_http_server_opts;
|
||||
static struct device_settings s_settings = { "value1", "value2" };
|
||||
|
||||
static void handle_save(struct mg_connection *nc, struct http_message *hm) {
|
||||
// Get form variables and store settings values
|
||||
mg_get_http_var(&hm->body, "setting1", s_settings.setting1,
|
||||
sizeof(s_settings.setting1));
|
||||
mg_get_http_var(&hm->body, "setting2", s_settings.setting2,
|
||||
sizeof(s_settings.setting2));
|
||||
|
||||
// Send response
|
||||
mg_printf(nc, "%s", "HTTP/1.1 302 OK\r\nLocation: /\r\n\r\n");
|
||||
}
|
||||
|
||||
static void handle_get_cpu_usage(struct mg_connection *nc) {
|
||||
// Generate random value, as an example of changing CPU usage
|
||||
// Getting real CPU usage depends on the OS.
|
||||
int cpu_usage = (double) rand() / RAND_MAX * 100.0;
|
||||
|
||||
// Use chunked encoding in order to avoid calculating Content-Length
|
||||
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
|
||||
// Output JSON object which holds CPU usage data
|
||||
mg_printf_http_chunk(nc, "{ \"result\": %d }", cpu_usage);
|
||||
|
||||
// Send empty chunk, the end of response
|
||||
mg_send_http_chunk(nc, "", 0);
|
||||
}
|
||||
|
||||
static void handle_ssi_call(struct mg_connection *nc, const char *param) {
|
||||
if (strcmp(param, "setting1") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting1);
|
||||
} else if (strcmp(param, "setting2") == 0) {
|
||||
mg_printf_html_escape(nc, "%s", s_settings.setting2);
|
||||
}
|
||||
}
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_HTTP_REQUEST:
|
||||
if (mg_vcmp(&hm->uri, "/save") == 0) {
|
||||
handle_save(nc, hm);
|
||||
} else if (mg_vcmp(&hm->uri, "/get_cpu_usage") == 0) {
|
||||
handle_get_cpu_usage(nc);
|
||||
} else {
|
||||
mg_serve_http(nc, hm, s_http_server_opts); // Serve static content
|
||||
}
|
||||
break;
|
||||
case MG_EV_SSI_CALL:
|
||||
handle_ssi_call(nc, ev_data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void push_data_to_all_websocket_connections(struct mg_mgr *m) {
|
||||
struct mg_connection *c;
|
||||
int memory_usage = (double) rand() / RAND_MAX * 100.0;
|
||||
|
||||
for (c = mg_next(m, NULL); c != NULL; c = mg_next(m, c)) {
|
||||
if (c->flags & MG_F_IS_WEBSOCKET) {
|
||||
mg_printf_websocket_frame(c, WEBSOCKET_OP_TEXT, "%d", memory_usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
cs_stat_t st;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_bind(&mgr, s_http_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
fprintf(stderr, "Cannot bind to %s\n", s_http_port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "web_root"; // Set up web root directory
|
||||
|
||||
if (mg_stat(s_http_server_opts.document_root, &st) != 0) {
|
||||
fprintf(stderr, "%s", "Cannot find web_root directory, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
for (;;) {
|
||||
static time_t last_time;
|
||||
time_t now = time(NULL);
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
if (now - last_time > 0) {
|
||||
push_data_to_all_websocket_connections(&mgr);
|
||||
last_time = now;
|
||||
}
|
||||
}
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Connected device demo</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
|
||||
<script src="jquery.flot.min.js"></script>
|
||||
<script src="jquery.flot.time.js"></script>
|
||||
<script type="text/javascript" src="main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<img src="logo.png" style="float:right; height: 50px; border-radius: 3px;">
|
||||
<h1>Connected device demo - Websocket push</h1>
|
||||
|
||||
<p>
|
||||
This page is one of the series of examples that show how to make
|
||||
devices connected with Mongoose. Here we add a real-time Websocket
|
||||
server push, and update dashboard graph as data arrives.
|
||||
</p>
|
||||
|
||||
<h1>Settings section</h1>
|
||||
<form method="POST" action="/save">
|
||||
<fieldset>
|
||||
<legend>Device settings</legend>
|
||||
<label>Setting 1:</label> <input type="text"
|
||||
name="setting1" value="<!--#call setting1 -->" >
|
||||
<label>Setting 2:</label> <input type="text"
|
||||
name="setting2" value="<!--#call setting2 -->" >
|
||||
|
||||
<div>
|
||||
<button type="submit">Save Settings</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h1>Dashboard section</h1>
|
||||
<label>CPU usage:</label> <span id="cpu_usage"> </span>
|
||||
<div id="graphs"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^Line truncated
|
||||
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[cLine truncated
|
||||
@@ -0,0 +1,8 @@
|
||||
/* Javascript plotting library for jQuery, version 0.8.3.
|
||||
|
||||
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
*/
|
||||
(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function($){var hasOwnProperty=Object.prototype.hasOwnProperty;if(!$.fn.detach){$.fn.detach=function(){return this.each(function(){if(this.parentNode){this.parentNode.removeChild(this)}})}}function Canvas(cls,container){var element=container.children("."+cls)[0];if(element==null){element=document.createElement("canvas");element.className=cls;$(element).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(container);if(!element.getContext){if(window.G_vmlCanvasManager){element=window.G_vmlCanvasManager.initElement(element)}else{throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.")}}}this.element=element;var context=this.context=element.getContext("2d");var devicePixelRatio=window.devicePixelRatio||1,backingStoreRatio=context.webkitBackingStorePixelRatio||context.mozBackingStorePixelRatio||context.msBackingStorePixelRatio||context.oBackingStorePixelRatio||context.backingStorePixelRatio||1;this.pixelRatio=devicePixelRatio/backingStoreRatio;this.resize(container.width(),container.height());this.textContainer=null;this.text={};this._textCache={}}Canvas.prototype.resize=function(width,height){if(width<=0||height<=0){throw new Error("Invalid dimensions for plot, width = "+width+", height = "+height)}var element=this.element,context=this.context,pixelRatio=this.pixelRatio;if(this.width!=width){element.width=width*pixelRatio;element.style.width=width+"px";this.width=width}if(this.height!=height){element.height=height*pixelRatio;element.style.height=height+"px";this.height=height}context.restore();context.save();context.scale(pixelRatio,pixelRatio)};Canvas.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)};Canvas.prototype.render=function(){vaLine truncated
|
||||
if(yrange.from==null)yrange.from=yrange.axis.min;if(yrange.to==null)yrange.to=yrange.axis.max;if(xrange.to<xrange.axis.min||xrange.from>xrange.axis.max||yrange.to<yrange.axis.min||yrange.from>yrange.axis.max)continue;xrange.from=Math.max(xrange.from,xrange.axis.min);xrange.to=Math.min(xrange.to,xrange.axis.max);yrange.from=Math.max(yrange.from,yrange.axis.min);yrange.to=Math.min(yrange.to,yrange.axis.max);var xequal=xrange.from===xrange.to,yequal=yrange.from===yrange.to;if(xequal&&yequal){continue}xrange.from=Math.floor(xrange.axis.p2c(xrange.from));xrange.to=Math.floor(xrange.axis.p2c(xrange.to));yrange.from=Math.floor(yrange.axis.p2c(yrange.from));yrange.to=Math.floor(yrange.axis.p2c(yrange.to));if(xequal||yequal){var lineWidth=m.lineWidth||options.grid.markingsLineWidth,subPixel=lineWidth%2?.5:0;ctx.beginPath();ctx.strokeStyle=m.color||options.grid.markingsColor;ctx.lineWidth=lineWidth;if(xequal){ctx.moveTo(xrange.to+subPixel,yrange.from);ctx.lineTo(xrange.to+subPixel,yrange.to)}else{ctx.moveTo(xrange.from,yrange.to+subPixel);ctx.lineTo(xrange.to,yrange.to+subPixel)}ctx.stroke()}else{ctx.fillStyle=m.color||options.grid.markingsColor;ctx.fillRect(xrange.from,yrange.to,xrange.to-xrange.from,yrange.from-yrange.to)}}}axes=allAxes();bw=options.grid.borderWidth;for(var j=0;j<axes.length;++j){var axis=axes[j],box=axis.box,t=axis.tickLength,x,y,xoff,yoff;if(!axis.show||axis.ticks.length==0)continue;ctx.lineWidth=1;if(axis.direction=="x"){x=0;if(t=="full")y=axis.position=="top"?0:plotHeight;else y=box.top-plotOffset.top+(axis.position=="top"?box.height:0)}else{y=0;if(t=="full")x=axis.position=="left"?0:plotWidth;else x=box.left-plotOffset.left+(axis.position=="left"?box.width:0)}if(!axis.innermost){ctx.strokeStyle=axis.options.color;ctx.beginPath();xoff=yoff=0;if(axis.direction=="x")xoff=plotWidth+1;else yoff=plotHeight+1;if(ctx.lineWidth==1){if(axis.direction=="x"){y=Math.floor(y)+.5}else{x=Math.floor(x)+.5}}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff);ctx.stroke()}ctx.strokeStyle=axis.options.tickColor;ctx.beginPath();for(i=0;i<axis.ticks.length;++i){var v=axis.ticks[i].v;xoff=yoff=0;if(isNaN(v)||v<axis.min||v>axis.max||t=="full"&&(typeof bw=="object"&&bw[axis.position]>0||bw>0)&&(v==axis.min||v==axis.max))continue;if(axis.direction=="x"){x=axis.p2c(v);yoff=t=="full"?-plotHeight:t;if(axis.position=="top")yoff=-yoff}else{y=axis.p2c(v);xoff=t=="full"?-plotWidth:t;if(axis.position=="left")xoff=-xoff}if(ctx.lineWidth==1){if(axis.direction=="x")x=Math.floor(x)+.5;else y=Math.floor(y)+.5}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff)}ctx.stroke()}if(bw){bc=options.grid.borderColor;if(typeof bw=="object"||typeof bc=="object"){if(typeof bw!=="object"){bw={top:bw,right:bw,bottom:bw,left:bw}}if(typeof bc!=="object"){bc={top:bc,right:bc,bottom:bc,left:bc}}if(bw.top>0){ctx.strokeStyle=bc.top;ctx.lineWidth=bw.top;ctx.beginPath();ctx.moveTo(0-bw.left,0-bw.top/2);ctx.lineTo(plotWidth,0-bw.top/2);ctx.stroke()}if(bw.right>0){ctx.strokeStyle=bc.right;ctx.lineWidth=bw.right;ctx.beginPath();ctx.moveTo(plotWidth+bw.right/2,0-bw.top);ctx.lineTo(plotWidth+bw.right/2,plotHeight);ctx.stroke()}if(bw.bottom>0){ctx.strokeStyle=bc.bottom;ctx.lineWidth=bw.bottom;ctx.beginPath();ctx.moveTo(plotWidth+bw.right,plotHeight+bw.bottom/2);ctx.lineTo(0,plotHeight+bw.bottom/2);ctx.stroke()}if(bw.left>0){ctx.strokeStyle=bc.left;ctx.lineWidth=bw.left;ctx.beginPath();ctx.moveTo(0-bw.left/2,plotHeight+bw.bottom);ctx.lineTo(0-bw.left/2,0);ctx.stroke()}}else{ctx.lineWidth=bw;ctx.strokeStyle=options.grid.borderColor;ctx.strokeRect(-bw/2,-bw/2,plotWidth+bw,plotHeight+bw)}}ctx.restore()}function drawAxisLabels(){$.each(allAxes(),function(_,axis){var box=axis.box,legacyStyles=axis.direction+"Axis "+axis.direction+axis.n+"Axis",layer="flot-"+axis.direction+"-axis flot-"+axis.direction+axis.n+"-axis "+legacyStyles,font=axis.options.font||"flot-tick-label tickLabel",tick,x,y,halign,valign;surface.removeText(layer);if(!axis.show||axis.ticks.length==0)return;for(var i=0;i<axis.ticks.length;++i){tick=axis.ticks[i];if(!tick.label||tick.v<axis.min||tick.v>axis.max)continue;if(axis.direction=="x"){halign="center";x=plotOffset.left+axis.p2c(tick.v);if(axis.position=="bottom"){y=box.top+box.padding}else{y=box.top+box.height-box.padding;valign="bottom"}}else{valign="middle";y=plotOffset.top+axis.p2c(tick.v);if(axis.position=="left"){x=box.left+box.width-box.padding;halign="right"}else{x=box.left+box.padding}}surface.addText(layer,x,y,tick.label,font,null,null,halign,valign)}})}function drawSeries(series){if(series.lines.show)drawSeriesLines(series);if(series.bars.show)drawSeriesBars(series);if(series.points.show)drawSeriesPoints(series)}function drawSeriesLines(series){function plotLine(datapoints,xoffset,yoffset,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null;ctx.beginPath();for(var i=ps;i<points.length;i+=ps){var x1=points[i-ps],y1=points[i-ps+1],x2=points[i],y2=points[i+1];if(x1==null||x2==null)continue;if(y1<=y2&&y1<axisy.min){if(y2<axLine truncated
|
||||
@@ -0,0 +1,432 @@
|
||||
/* Pretty handling of time axes.
|
||||
|
||||
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
Set axis.mode to "time" to enable. See the section "Time series data" in
|
||||
API.txt for details.
|
||||
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var options = {
|
||||
xaxis: {
|
||||
timezone: null, // "browser" for local to the client or timezone for timezone-js
|
||||
timeformat: null, // format string to use
|
||||
twelveHourClock: false, // 12 or 24 time in time mode
|
||||
monthNames: null // list of names of months
|
||||
}
|
||||
};
|
||||
|
||||
// round to nearby lower multiple of base
|
||||
|
||||
function floorInBase(n, base) {
|
||||
return base * Math.floor(n / base);
|
||||
}
|
||||
|
||||
// Returns a string with the date d formatted according to fmt.
|
||||
// A subset of the Open Group's strftime format is supported.
|
||||
|
||||
function formatDate(d, fmt, monthNames, dayNames) {
|
||||
|
||||
if (typeof d.strftime == "function") {
|
||||
return d.strftime(fmt);
|
||||
}
|
||||
|
||||
var leftPad = function(n, pad) {
|
||||
n = "" + n;
|
||||
pad = "" + (pad == null ? "0" : pad);
|
||||
return n.length == 1 ? pad + n : n;
|
||||
};
|
||||
|
||||
var r = [];
|
||||
var escape = false;
|
||||
var hours = d.getHours();
|
||||
var isAM = hours < 12;
|
||||
|
||||
if (monthNames == null) {
|
||||
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
}
|
||||
|
||||
if (dayNames == null) {
|
||||
dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
}
|
||||
|
||||
var hours12;
|
||||
|
||||
if (hours > 12) {
|
||||
hours12 = hours - 12;
|
||||
} else if (hours == 0) {
|
||||
hours12 = 12;
|
||||
} else {
|
||||
hours12 = hours;
|
||||
}
|
||||
|
||||
for (var i = 0; i < fmt.length; ++i) {
|
||||
|
||||
var c = fmt.charAt(i);
|
||||
|
||||
if (escape) {
|
||||
switch (c) {
|
||||
case 'a': c = "" + dayNames[d.getDay()]; break;
|
||||
case 'b': c = "" + monthNames[d.getMonth()]; break;
|
||||
case 'd': c = leftPad(d.getDate()); break;
|
||||
case 'e': c = leftPad(d.getDate(), " "); break;
|
||||
case 'h': // For back-compat with 0.7; remove in 1.0
|
||||
case 'H': c = leftPad(hours); break;
|
||||
case 'I': c = leftPad(hours12); break;
|
||||
case 'l': c = leftPad(hours12, " "); break;
|
||||
case 'm': c = leftPad(d.getMonth() + 1); break;
|
||||
case 'M': c = leftPad(d.getMinutes()); break;
|
||||
// quarters not in Open Group's strftime specification
|
||||
case 'q':
|
||||
c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
|
||||
case 'S': c = leftPad(d.getSeconds()); break;
|
||||
case 'y': c = leftPad(d.getFullYear() % 100); break;
|
||||
case 'Y': c = "" + d.getFullYear(); break;
|
||||
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
|
||||
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
|
||||
case 'w': c = "" + d.getDay(); break;
|
||||
}
|
||||
r.push(c);
|
||||
escape = false;
|
||||
} else {
|
||||
if (c == "%") {
|
||||
escape = true;
|
||||
} else {
|
||||
r.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r.join("");
|
||||
}
|
||||
|
||||
// To have a consistent view of time-based data independent of which time
|
||||
// zone the client happens to be in we need a date-like object independent
|
||||
// of time zones. This is done through a wrapper that only calls the UTC
|
||||
// versions of the accessor methods.
|
||||
|
||||
function makeUtcWrapper(d) {
|
||||
|
||||
function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
|
||||
sourceObj[sourceMethod] = function() {
|
||||
return targetObj[targetMethod].apply(targetObj, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
var utc = {
|
||||
date: d
|
||||
};
|
||||
|
||||
// support strftime, if found
|
||||
|
||||
if (d.strftime != undefined) {
|
||||
addProxyMethod(utc, "strftime", d, "strftime");
|
||||
}
|
||||
|
||||
addProxyMethod(utc, "getTime", d, "getTime");
|
||||
addProxyMethod(utc, "setTime", d, "setTime");
|
||||
|
||||
var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
|
||||
|
||||
for (var p = 0; p < props.length; p++) {
|
||||
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
|
||||
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
|
||||
}
|
||||
|
||||
return utc;
|
||||
};
|
||||
|
||||
// select time zone strategy. This returns a date-like object tied to the
|
||||
// desired timezone
|
||||
|
||||
function dateGenerator(ts, opts) {
|
||||
if (opts.timezone == "browser") {
|
||||
return new Date(ts);
|
||||
} else if (!opts.timezone || opts.timezone == "utc") {
|
||||
return makeUtcWrapper(new Date(ts));
|
||||
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
|
||||
var d = new timezoneJS.Date();
|
||||
// timezone-js is fickle, so be sure to set the time zone before
|
||||
// setting the time.
|
||||
d.setTimezone(opts.timezone);
|
||||
d.setTime(ts);
|
||||
return d;
|
||||
} else {
|
||||
return makeUtcWrapper(new Date(ts));
|
||||
}
|
||||
}
|
||||
|
||||
// map of app. size of time units in milliseconds
|
||||
|
||||
var timeUnitSize = {
|
||||
"second": 1000,
|
||||
"minute": 60 * 1000,
|
||||
"hour": 60 * 60 * 1000,
|
||||
"day": 24 * 60 * 60 * 1000,
|
||||
"month": 30 * 24 * 60 * 60 * 1000,
|
||||
"quarter": 3 * 30 * 24 * 60 * 60 * 1000,
|
||||
"year": 365.2425 * 24 * 60 * 60 * 1000
|
||||
};
|
||||
|
||||
// the allowed tick sizes, after 1 year we use
|
||||
// an integer algorithm
|
||||
|
||||
var baseSpec = [
|
||||
[1, "second"], [2, "second"], [5, "second"], [10, "second"],
|
||||
[30, "second"],
|
||||
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
|
||||
[30, "minute"],
|
||||
[1, "hour"], [2, "hour"], [4, "hour"],
|
||||
[8, "hour"], [12, "hour"],
|
||||
[1, "day"], [2, "day"], [3, "day"],
|
||||
[0.25, "month"], [0.5, "month"], [1, "month"],
|
||||
[2, "month"]
|
||||
];
|
||||
|
||||
// we don't know which variant(s) we'll need yet, but generating both is
|
||||
// cheap
|
||||
|
||||
var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
|
||||
[1, "year"]]);
|
||||
var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
|
||||
[1, "year"]]);
|
||||
|
||||
function init(plot) {
|
||||
plot.hooks.processOptions.push(function (plot, options) {
|
||||
$.each(plot.getAxes(), function(axisName, axis) {
|
||||
|
||||
var opts = axis.options;
|
||||
|
||||
if (opts.mode == "time") {
|
||||
axis.tickGenerator = function(axis) {
|
||||
|
||||
var ticks = [];
|
||||
var d = dateGenerator(axis.min, opts);
|
||||
var minSize = 0;
|
||||
|
||||
// make quarter use a possibility if quarters are
|
||||
// mentioned in either of these options
|
||||
|
||||
var spec = (opts.tickSize && opts.tickSize[1] ===
|
||||
"quarter") ||
|
||||
(opts.minTickSize && opts.minTickSize[1] ===
|
||||
"quarter") ? specQuarters : specMonths;
|
||||
|
||||
if (opts.minTickSize != null) {
|
||||
if (typeof opts.tickSize == "number") {
|
||||
minSize = opts.tickSize;
|
||||
} else {
|
||||
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < spec.length - 1; ++i) {
|
||||
if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
|
||||
+ spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
|
||||
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var size = spec[i][0];
|
||||
var unit = spec[i][1];
|
||||
|
||||
// special-case the possibility of several years
|
||||
|
||||
if (unit == "year") {
|
||||
|
||||
// if given a minTickSize in years, just use it,
|
||||
// ensuring that it's an integer
|
||||
|
||||
if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
|
||||
size = Math.floor(opts.minTickSize[0]);
|
||||
} else {
|
||||
|
||||
var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
|
||||
var norm = (axis.delta / timeUnitSize.year) / magn;
|
||||
|
||||
if (norm < 1.5) {
|
||||
size = 1;
|
||||
} else if (norm < 3) {
|
||||
size = 2;
|
||||
} else if (norm < 7.5) {
|
||||
size = 5;
|
||||
} else {
|
||||
size = 10;
|
||||
}
|
||||
|
||||
size *= magn;
|
||||
}
|
||||
|
||||
// minimum size for years is 1
|
||||
|
||||
if (size < 1) {
|
||||
size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
axis.tickSize = opts.tickSize || [size, unit];
|
||||
var tickSize = axis.tickSize[0];
|
||||
unit = axis.tickSize[1];
|
||||
|
||||
var step = tickSize * timeUnitSize[unit];
|
||||
|
||||
if (unit == "second") {
|
||||
d.setSeconds(floorInBase(d.getSeconds(), tickSize));
|
||||
} else if (unit == "minute") {
|
||||
d.setMinutes(floorInBase(d.getMinutes(), tickSize));
|
||||
} else if (unit == "hour") {
|
||||
d.setHours(floorInBase(d.getHours(), tickSize));
|
||||
} else if (unit == "month") {
|
||||
d.setMonth(floorInBase(d.getMonth(), tickSize));
|
||||
} else if (unit == "quarter") {
|
||||
d.setMonth(3 * floorInBase(d.getMonth() / 3,
|
||||
tickSize));
|
||||
} else if (unit == "year") {
|
||||
d.setFullYear(floorInBase(d.getFullYear(), tickSize));
|
||||
}
|
||||
|
||||
// reset smaller components
|
||||
|
||||
d.setMilliseconds(0);
|
||||
|
||||
if (step >= timeUnitSize.minute) {
|
||||
d.setSeconds(0);
|
||||
}
|
||||
if (step >= timeUnitSize.hour) {
|
||||
d.setMinutes(0);
|
||||
}
|
||||
if (step >= timeUnitSize.day) {
|
||||
d.setHours(0);
|
||||
}
|
||||
if (step >= timeUnitSize.day * 4) {
|
||||
d.setDate(1);
|
||||
}
|
||||
if (step >= timeUnitSize.month * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 3));
|
||||
}
|
||||
if (step >= timeUnitSize.quarter * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 6));
|
||||
}
|
||||
if (step >= timeUnitSize.year) {
|
||||
d.setMonth(0);
|
||||
}
|
||||
|
||||
var carry = 0;
|
||||
var v = Number.NaN;
|
||||
var prev;
|
||||
|
||||
do {
|
||||
|
||||
prev = v;
|
||||
v = d.getTime();
|
||||
ticks.push(v);
|
||||
|
||||
if (unit == "month" || unit == "quarter") {
|
||||
if (tickSize < 1) {
|
||||
|
||||
// a bit complicated - we'll divide the
|
||||
// month/quarter up but we need to take
|
||||
// care of fractions so we don't end up in
|
||||
// the middle of a day
|
||||
|
||||
d.setDate(1);
|
||||
var start = d.getTime();
|
||||
d.setMonth(d.getMonth() +
|
||||
(unit == "quarter" ? 3 : 1));
|
||||
var end = d.getTime();
|
||||
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
|
||||
carry = d.getHours();
|
||||
d.setHours(0);
|
||||
} else {
|
||||
d.setMonth(d.getMonth() +
|
||||
tickSize * (unit == "quarter" ? 3 : 1));
|
||||
}
|
||||
} else if (unit == "year") {
|
||||
d.setFullYear(d.getFullYear() + tickSize);
|
||||
} else {
|
||||
d.setTime(v + step);
|
||||
}
|
||||
} while (v < axis.max && v != prev);
|
||||
|
||||
return ticks;
|
||||
};
|
||||
|
||||
axis.tickFormatter = function (v, axis) {
|
||||
|
||||
var d = dateGenerator(v, axis.options);
|
||||
|
||||
// first check global format
|
||||
|
||||
if (opts.timeformat != null) {
|
||||
return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
|
||||
}
|
||||
|
||||
// possibly use quarters if quarters are mentioned in
|
||||
// any of these places
|
||||
|
||||
var useQuarters = (axis.options.tickSize &&
|
||||
axis.options.tickSize[1] == "quarter") ||
|
||||
(axis.options.minTickSize &&
|
||||
axis.options.minTickSize[1] == "quarter");
|
||||
|
||||
var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
|
||||
var span = axis.max - axis.min;
|
||||
var suffix = (opts.twelveHourClock) ? " %p" : "";
|
||||
var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
|
||||
var fmt;
|
||||
|
||||
if (t < timeUnitSize.minute) {
|
||||
fmt = hourCode + ":%M:%S" + suffix;
|
||||
} else if (t < timeUnitSize.day) {
|
||||
if (span < 2 * timeUnitSize.day) {
|
||||
fmt = hourCode + ":%M" + suffix;
|
||||
} else {
|
||||
fmt = "%b %d " + hourCode + ":%M" + suffix;
|
||||
}
|
||||
} else if (t < timeUnitSize.month) {
|
||||
fmt = "%b %d";
|
||||
} else if ((useQuarters && t < timeUnitSize.quarter) ||
|
||||
(!useQuarters && t < timeUnitSize.year)) {
|
||||
if (span < timeUnitSize.year) {
|
||||
fmt = "%b";
|
||||
} else {
|
||||
fmt = "%b %Y";
|
||||
}
|
||||
} else if (useQuarters && t < timeUnitSize.year) {
|
||||
if (span < timeUnitSize.year) {
|
||||
fmt = "Q%q";
|
||||
} else {
|
||||
fmt = "Q%q %Y";
|
||||
}
|
||||
} else {
|
||||
fmt = "%Y";
|
||||
}
|
||||
|
||||
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
|
||||
|
||||
return rt;
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: 'time',
|
||||
version: '1.0'
|
||||
});
|
||||
|
||||
// Time-axis support used to be in Flot core, which exposed the
|
||||
// formatDate function on the plot object. Various plugins depend
|
||||
// on the function, so we need to re-expose it here.
|
||||
|
||||
$.plot.formatDate = formatDate;
|
||||
$.plot.dateGenerator = dateGenerator;
|
||||
|
||||
})(jQuery);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,75 @@
|
||||
$(document).ready(function() {
|
||||
// Start 1-second timer to call RESTful endpoint
|
||||
setInterval(function() {
|
||||
$.ajax({
|
||||
url: '/get_cpu_usage',
|
||||
dataType: 'json',
|
||||
success: function(json) {
|
||||
$('#cpu_usage').text(json.result + '% ');
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
// Initialize graph
|
||||
var $c = $('<div class="graph"/>').appendTo('#graphs');
|
||||
var dur = 120;
|
||||
var past = Date.now() - dur * 1000;
|
||||
var options = {
|
||||
lines: {
|
||||
fill: true,
|
||||
lineWidth: 0,
|
||||
fillColor: {colors: [ { opacity: 0 }, { opacity: 1 } ] }
|
||||
},
|
||||
grid: { borderWidth: 1, borderColor: '#ccc'},
|
||||
xaxis: { mode: 'time', ticks: 5 },
|
||||
legend: { labelBoxBorderColor: '#fff' },
|
||||
colors: [ '#fec', '#396', '#e39', '9e2' ],
|
||||
hooks: {
|
||||
draw: [function(plot, canvas) {
|
||||
canvas.font = '13px sans-serif';
|
||||
canvas.fillStyle = '#aaa';
|
||||
canvas.fillText('Resource Usage', 35, 25);
|
||||
}]
|
||||
}
|
||||
};
|
||||
var plot = $.plot($c, [], options);
|
||||
|
||||
var updateGraph = function(counter) {
|
||||
var data = plot.getData();
|
||||
var now = Date.now();
|
||||
var oldest = now - dur * 1000;
|
||||
data[0] = {
|
||||
show: false,
|
||||
data: [[oldest, null], [now, null]]
|
||||
};
|
||||
|
||||
console.log(data);
|
||||
|
||||
// Remove old points
|
||||
$.each(data, function(di, d) {
|
||||
while (d.data.length > 0 && d.data[0][0] < oldest) {
|
||||
d.data.shift();
|
||||
}
|
||||
});
|
||||
|
||||
// Add new points
|
||||
var new_datapoint = [now, counter];
|
||||
if (data[1]) {
|
||||
data[1].label = 'memory';
|
||||
data[1].data.push(new_datapoint);
|
||||
} else {
|
||||
data[1] = [{ data: [new_datapoint] }];
|
||||
}
|
||||
|
||||
// Redraw the graph
|
||||
plot.setData(data);
|
||||
plot.setupGrid();
|
||||
plot.draw();
|
||||
};
|
||||
|
||||
// Create Websocket connection. For simplicity, no reconnect logic is here.
|
||||
var ws = new WebSocket('ws://' + location.host);
|
||||
ws.onmessage = function(ev) {
|
||||
updateGraph(ev.data);
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #36c;
|
||||
color: #555;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font: 16px/1.4 Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 800px;
|
||||
margin: 1em auto;
|
||||
padding: 2em;
|
||||
background-color: #fff;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #ccc;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
font-style: italic;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
fieldset label {
|
||||
text-align: right;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
font-size: 100%;
|
||||
padding: 0.2em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #666;
|
||||
background: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.2em 2em;
|
||||
font-size: 100%;
|
||||
cursor: pointer;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #f0f0f0;
|
||||
padding: 0 0.3em;
|
||||
color: #396;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #69c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#graphs {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.graph {
|
||||
min-height: 12em;
|
||||
border: 0px solid #ccc;
|
||||
position: relative;
|
||||
margin: 0 1em 1em 0;
|
||||
width: 36em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.graph_title {
|
||||
position: absolute;
|
||||
top: 0.5em; left: 1em;
|
||||
color: #ccc;
|
||||
font-weight: bold;
|
||||
z-index: 999;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
SOURCES = $(PROG).c ../../mongoose.c
|
||||
CFLAGS = -g -W -Wall -I../.. -Wno-unused-function $(CFLAGS_EXTRA) $(MODULE_CFLAGS)
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(SOURCES)
|
||||
$(CC) $(SOURCES) -o $@ $(CFLAGS)
|
||||
|
||||
$(PROG).exe: $(SOURCES)
|
||||
cl $(SOURCES) /I../.. /MD /Fe$@
|
||||
|
||||
clean:
|
||||
rm -rf *.gc* *.dSYM *.exe *.obj *.o a.out $(PROG)
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\mongoose.c">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="http_client.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\mongoose.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BDF3FC6F-2658-4A27-846D-6A45FB53C602}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>http_client</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;MG_ENABLE_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;MG_ENABLE_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -233,6 +233,12 @@ static void forward(struct conn_data *conn, struct http_message *hm,
|
||||
/* We always rewrite the connection header depending on the settings. */
|
||||
if (mg_vcasecmp(&hn, "Connection") == 0) continue;
|
||||
|
||||
/* Don't pass chunked transfer encoding to the client */
|
||||
if (mg_vcasecmp(&hn, "Transfer-encoding") == 0 &&
|
||||
mg_vcasecmp(&hv, "chunked") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mg_printf(dst, "%.*s: %.*s\r\n", (int) hn.len, hn.p, (int) hv.len, hv.p);
|
||||
}
|
||||
|
||||
@@ -272,7 +278,7 @@ static int connect_backend(struct conn_data *conn, struct http_message *hm) {
|
||||
struct http_backend *be = choose_backend(hm);
|
||||
|
||||
write_log("%.*s %.*s backend=%s\n", (int) hm->method.len, hm->method.p,
|
||||
(int) hm->uri.len, hm->uri.p, be->host_port);
|
||||
(int) hm->uri.len, hm->uri.p, be ? be->host_port : "not defined");
|
||||
|
||||
if (be == NULL) return 0;
|
||||
if (be->redirect != 0) {
|
||||
@@ -413,7 +419,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
if (ev != MG_EV_POLL) {
|
||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ grabbing application can handle. The device automatically attempts reconnecting.
|
||||
|
||||
The cloud side serves the webapp static pages and serves an MPJEG image on `/mpjg`.
|
||||
The MPJEG image handler blocks all the clients until a JPEG frame arrives via websocket
|
||||
and then every client will recieve a copy of the frame.
|
||||
and then every client will receive a copy of the frame.
|
||||
|
||||
The web app can turn on and off the LED via a RESTful api accessible via the `/api` handler.
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ grabbing application can handle. The device automatically attempts reconnecting.
|
||||
<div class="paragraph">
|
||||
<p>The cloud side serves the webapp static pages and serves an MPJEG image on <code>/mpjg</code>.
|
||||
The MPJEG image handler blocks all the clients until a JPEG frame arrives via websocket
|
||||
and then every client will recieve a copy of the frame.</p>
|
||||
and then every client will receive a copy of the frame.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The web app can turn on and off the LED via a RESTful api accessible via the <code>/api</code> handler.</p>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "mongoose.h"
|
||||
|
||||
/* RESTful server host and request URI */
|
||||
static const char *s_target_address = "ajax.googleapis.com:80";
|
||||
static const char *s_request = "/ajax/services/search/web?v=1.0&q=cesanta";
|
||||
static const char *s_url =
|
||||
"http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=cesanta";
|
||||
|
||||
static int s_exit_flag = 0;
|
||||
|
||||
@@ -17,14 +17,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
|
||||
switch (ev) {
|
||||
case MG_EV_CONNECT:
|
||||
connect_status = * (int *) ev_data;
|
||||
if (connect_status == 0) {
|
||||
printf("Connected to %s, sending request...\n", s_target_address);
|
||||
mg_printf(nc, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n",
|
||||
s_request, s_target_address);
|
||||
} else {
|
||||
printf("Error connecting to %s: %s\n",
|
||||
s_target_address, strerror(connect_status));
|
||||
connect_status = *(int *) ev_data;
|
||||
if (connect_status != 0) {
|
||||
printf("Error connecting to %s: %s\n", s_url, strerror(connect_status));
|
||||
s_exit_flag = 1;
|
||||
}
|
||||
break;
|
||||
@@ -43,10 +38,10 @@ int main(void) {
|
||||
struct mg_connection *nc;
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
nc = mg_connect(&mgr, s_target_address, ev_handler);
|
||||
nc = mg_connect_http(&mgr, ev_handler, s_url, NULL, NULL);
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
|
||||
printf("Starting RESTful client against %s\n", s_target_address);
|
||||
printf("Starting RESTful client against %s\n", s_url);
|
||||
while (s_exit_flag == 0) {
|
||||
mg_mgr_poll(&mgr, 1000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BDC33376-C2B4-4D19-8F6F-F88116F1DE9A}</ProjectGuid>
|
||||
<RootNamespace>restful_client</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions);MG_ENABLE_THREADS</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions);MG_ENABLE_THREADS</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\mongoose.c" />
|
||||
<ClCompile Include="restful_client.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\mongoose.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -8,6 +8,11 @@ else ifeq ($(SSL), krypton)
|
||||
CFLAGS += -DMG_ENABLE_SSL ../../../krypton/krypton.c
|
||||
endif
|
||||
|
||||
ifeq ($(JS), yes)
|
||||
V7_PATH = ../../deps/v7
|
||||
CFLAGS_EXTRA += -DMG_ENABLE_JAVASCRIPT -I $(V7_PATH) $(V7_PATH)/v7.c
|
||||
endif
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(SOURCES)
|
||||
|
||||
@@ -67,9 +67,14 @@ int main(int argc, char *argv[]) {
|
||||
s_http_port = argv[++i];
|
||||
} else if (strcmp(argv[i], "-a") == 0 && i + 1 < argc) {
|
||||
s_http_server_opts.auth_domain = argv[++i];
|
||||
#ifdef MG_ENABLE_JAVASCRIPT
|
||||
} else if (strcmp(argv[i], "-j") == 0 && i + 1 < argc) {
|
||||
const char *init_file = argv[++i];
|
||||
mg_enable_javascript(&mgr, v7_create(), init_file);
|
||||
#endif
|
||||
} else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) {
|
||||
s_http_server_opts.global_auth_file = argv[++i];
|
||||
} else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
|
||||
} else if (strcmp(argv[i], "-A") == 0 && i + 1 < argc) {
|
||||
s_http_server_opts.per_directory_auth_file = argv[++i];
|
||||
} else if (strcmp(argv[i], "-r") == 0 && i + 1 < argc) {
|
||||
s_http_server_opts.url_rewrites = argv[++i];
|
||||
@@ -81,6 +86,9 @@ int main(int argc, char *argv[]) {
|
||||
} else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) {
|
||||
ssl_cert = argv[++i];
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr, "Unknown option: [%s]\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{26BC7405-4171-4B98-B5F2-B3159D4A8F5C}</ProjectGuid>
|
||||
<RootNamespace>restful_server</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions);MG_ENABLE_THREADS</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>./../../</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions);MG_ENABLE_THREADS</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\mongoose.c">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="restful_server.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\mongoose.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
+1
-1
@@ -4,7 +4,7 @@ CFLAGS = -W -Wall -I../.. -pthread -DMG_ENABLE_SSL -DMG_ENABLE_IPV6 -DMG_ENABLE_
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(SOURCES)
|
||||
$(CC) $(SOURCES) -o $@ $(CFLAGS)
|
||||
$(CC) $(SOURCES) -g -o $@ $(CFLAGS)
|
||||
|
||||
$(PROG).exe: $(SOURCES)
|
||||
cl $(SOURCES) /I../.. /DMG_ENABLE_SSL /MD /Fe$@
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1,6 +1,7 @@
|
||||
PROG = simplest_web_server
|
||||
SOURCES = $(PROG).c ../../mongoose.c
|
||||
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA)
|
||||
CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA) -DMG_DISABLE_DAV_AUTH \
|
||||
-DMG_ENABLE_FAKE_DAVLOCK
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ static struct mg_serve_http_opts s_http_server_opts;
|
||||
|
||||
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
if (ev == MG_EV_HTTP_REQUEST) {
|
||||
mg_serve_http(nc, p, s_http_server_opts);
|
||||
mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ int main(void) {
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = "."; // Serve current directory
|
||||
s_http_server_opts.dav_document_root = "."; // Allow access via WebDav
|
||||
s_http_server_opts.enable_directory_listing = "yes";
|
||||
|
||||
printf("Starting web server on port %s\n", s_http_port);
|
||||
|
||||
+4633
-2781
File diff suppressed because it is too large.
Load diff
+1102
-245
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user