mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e645b33b6c | ||
|
|
30f71a8bc4 | ||
|
|
faa030385c | ||
|
|
feb3b5db96 | ||
|
|
508b67d6f5 | ||
|
|
133aec777d | ||
|
|
389ed4e099 | ||
|
|
bc40aa5442 | ||
|
|
5fb9aca2e1 | ||
|
|
c68df310b8 | ||
|
|
70ce6c5ad3 | ||
|
|
460738f11b | ||
|
|
a09ec8988e | ||
|
|
c46aa050ae | ||
|
|
348db16245 | ||
|
|
c0ca6a53be | ||
|
|
e58d622d5f | ||
|
|
bcb294620f | ||
|
|
15937a9c5c | ||
|
|
fa160cb9a3 | ||
|
|
137d6484e2 | ||
|
|
e7c34c26cb | ||
|
|
dfb7d928c2 | ||
|
|
4bb9faaf50 | ||
|
|
a856971b6d | ||
|
|
4a88ad5ca9 | ||
|
|
17ecb0a459 | ||
|
|
afd39abc6f | ||
|
|
4babcff8de | ||
|
|
17d48b1d04 | ||
|
|
6ab20ed9a3 | ||
|
|
a0e5494569 | ||
|
|
f62c733990 | ||
|
|
d283e3167f | ||
|
|
94050d44e4 | ||
|
|
dee97cbf22 | ||
|
|
be01471968 | ||
|
|
a74c44c463 | ||
|
|
81e53d8375 | ||
|
|
ca626abcac | ||
|
|
b5e7730ac7 | ||
|
|
33b920ed2c | ||
|
|
b5b234fab2 | ||
|
|
af89d2446b | ||
|
|
791ad49651 | ||
|
|
063b26fece | ||
|
|
add079a949 | ||
|
|
6e59ad8a0d | ||
|
|
f4862b646d | ||
|
|
91fa767efb | ||
|
|
5e78711467 | ||
|
|
b4a622cfd6 | ||
|
|
8c118bf4cc | ||
|
|
728ebdaafa | ||
|
|
3a186976d7 | ||
|
|
2e232b3304 | ||
|
|
d72645bf91 | ||
|
|
7d5bcec92d | ||
|
|
215ea28db0 | ||
|
|
9b76d60b38 | ||
|
|
63ccf8199f | ||
|
|
6bc6022aa9 | ||
|
|
b68db66e97 | ||
|
|
94e1c5a41b | ||
|
|
ab16220861 | ||
|
|
c0eb3e56b4 | ||
|
|
5591aa5a0d | ||
|
|
6f946f5eea | ||
|
|
39cd5b8323 | ||
|
|
ca96db714a | ||
|
|
a7f97bf2f2 | ||
|
|
e579355b01 | ||
|
|
cfbaf7f1ae | ||
|
|
ce26234ace | ||
|
|
c28dc45d4c | ||
|
|
98b6c5e16a | ||
|
|
1d9d1111e1 | ||
|
|
2a0b55b30b | ||
|
|
1e3b167208 | ||
|
|
f7821b757c | ||
|
|
c352486abb | ||
|
|
4120b9bcc0 | ||
|
|
f7725f2eeb | ||
|
|
be06c3620c | ||
|
|
272644e39f | ||
|
|
55ef3afea4 | ||
|
|
9e07c742ff | ||
|
|
cd2e50c2c4 | ||
|
|
fdef2b8643 | ||
|
|
ce55924a02 | ||
|
|
fbca54bcaf | ||
|
|
41c25d60d6 | ||
|
|
a9b5bb351f | ||
|
|
51ed3efcd1 | ||
|
|
67cffc8db5 | ||
|
|
72abaa043b | ||
|
|
b3a511f9c5 | ||
|
|
8d1f6377c4 | ||
|
|
22dddc2eeb | ||
|
|
daab527743 | ||
|
|
dd49c0791f | ||
|
|
4b539d4b95 | ||
|
|
5eabfe5da2 | ||
|
|
36b7c8d60d | ||
|
|
aa37b728ad | ||
|
|
62085e5215 | ||
|
|
d036f8a3f0 | ||
|
|
fb5e2b8c2f | ||
|
|
4505b00733 | ||
|
|
c485b8264e | ||
|
|
8edd710c00 | ||
|
|
3984e9f5cc | ||
|
|
d4fa794c83 | ||
|
|
3892e0199e | ||
|
|
67f5de624e | ||
|
|
10234b07c4 | ||
|
|
36a83e1452 | ||
|
|
34df4ec1fd | ||
|
|
69cb94f3fb | ||
|
|
7204d71136 | ||
|
|
283f590349 | ||
|
|
27735f293b | ||
|
|
a560334fbb | ||
|
|
cd1707034c | ||
|
|
5ce1fc3c2a | ||
|
|
c78fe425a0 | ||
|
|
a58bb71c19 | ||
|
|
fc9a9593d2 | ||
|
|
eb1fdf56e6 | ||
|
|
ab960df8a9 | ||
|
|
08048bd5bb | ||
|
|
800517ac16 | ||
|
|
690eff4fa2 | ||
|
|
e47b5b775a | ||
|
|
c15e2af897 | ||
|
|
d8536b011c | ||
|
|
a2239c2b4b | ||
|
|
d3c02331d4 | ||
|
|
d707841166 | ||
|
|
affd82a885 | ||
|
|
8322c82790 | ||
|
|
08708435a7 | ||
|
|
1c6036c3ac | ||
|
|
6c3cb6f3eb | ||
|
|
a123874ac5 | ||
|
|
7931929a42 | ||
|
|
cc4a4fb2ab | ||
|
|
3d211d89c5 | ||
|
|
fbf1ccee45 | ||
|
|
0bd43bcae3 | ||
|
|
b809665cad | ||
|
|
463b49f1bd | ||
|
|
a881aad5c6 | ||
|
|
aae0995cd2 | ||
|
|
26b3f227d9 | ||
|
|
665770d602 | ||
|
|
fcafaa73d6 | ||
|
|
079b9ec2c1 | ||
|
|
7bd9a85897 | ||
|
|
2efc5d9fce | ||
|
|
1cb094e059 | ||
|
|
27fe9c8f01 | ||
|
|
9178fbd153 | ||
|
|
b2b43ab0cd | ||
|
|
1415d187eb | ||
|
|
a65078b858 | ||
|
|
7107afae5c | ||
|
|
f6a807c5a4 | ||
|
|
47b11dd19e | ||
|
|
61cdc93405 | ||
|
|
7a52bd643c | ||
|
|
63e8052e4b | ||
|
|
782d0cda46 | ||
|
|
72803eb7f8 | ||
|
|
c7fd221ab7 | ||
|
|
492185e35f | ||
|
|
845d7b08e1 | ||
|
|
49bac31d2d | ||
|
|
9baf2d4ba4 | ||
|
|
1becd26a8f | ||
|
|
ffa983552f | ||
|
|
13d0b67c00 | ||
|
|
bda8e90733 | ||
|
|
fed2057a33 | ||
|
|
a27f62f89f | ||
|
|
d53902844c | ||
|
|
9870b80c65 | ||
|
|
cde25a8b82 | ||
|
|
1b7f036199 | ||
|
|
b80157b7ea | ||
|
|
f9311f0b30 | ||
|
|
bdd933f597 | ||
|
|
ee55d38b55 | ||
|
|
62162ff3e4 | ||
|
|
98f66c8867 | ||
|
|
c132191cad | ||
|
|
d73aa1ad09 | ||
|
|
d5bc58c38d | ||
|
|
51a80e4844 | ||
|
|
54f15a8fe3 | ||
|
|
ce0826e285 | ||
|
|
b21a8b2193 | ||
|
|
8bb49642da | ||
|
|
3f78df86ac | ||
|
|
c30f7a5258 | ||
|
|
7ed94d1918 | ||
|
|
dc513a9a15 | ||
|
|
8ce6cf61b7 | ||
|
|
e63f7fe33a | ||
|
|
b589e0cdf4 | ||
|
|
2b87f909ce | ||
|
|
ec7d0b1abd | ||
|
|
5bb3ede46d | ||
|
|
5105717f78 | ||
|
|
9d1e356709 | ||
|
|
3d7192d9fa | ||
|
|
1b3cbb17c1 | ||
|
|
f1f03e4378 | ||
|
|
625a2a3652 | ||
|
|
33a31d9308 | ||
|
|
5e9bd1f05e | ||
|
|
75d9a6c844 | ||
|
|
179761fd99 | ||
|
|
b783813e54 | ||
|
|
4b29689a42 | ||
|
|
9c4853471c | ||
|
|
81e21a3a0b | ||
|
|
bec6ea00ea | ||
|
|
ed32e3be0f | ||
|
|
83fae879bf | ||
|
|
2169e6d77f | ||
|
|
850e0a5922 | ||
|
|
322ed3cc6f | ||
|
|
6d4d53c247 | ||
|
|
e6f8d40942 | ||
|
|
7e051206ad | ||
|
|
76d913796c | ||
|
|
4c2609df2c | ||
|
|
f79bd71fd4 | ||
|
|
5d4f5b6000 | ||
|
|
fe7c245a6b | ||
|
|
f24bebaca8 | ||
|
|
08afdfa8b6 | ||
|
|
05f7d65fc9 | ||
|
|
a194e07545 | ||
|
|
dbb8a5bbf4 | ||
|
|
d3005df019 | ||
|
|
ef9b103a00 | ||
|
|
f0a2924a7c | ||
|
|
f109030cd0 | ||
|
|
eebdd06532 | ||
|
|
ca2fc71a01 | ||
|
|
e61e371c16 | ||
|
|
d5f07f5b9b | ||
|
|
0a8d5dde51 | ||
|
|
5646caa572 | ||
|
|
c7e5573d08 | ||
|
|
b9a226d109 | ||
|
|
fcf8b86288 | ||
|
|
a8b08c6784 | ||
|
|
1fb6f391a1 | ||
|
|
fcbc36ecde | ||
|
|
70771f29ce | ||
|
|
121391504f | ||
|
|
8455742440 | ||
|
|
5b786a5089 | ||
|
|
a6e74e7707 | ||
|
|
acf72a6109 | ||
|
|
2b76f5fc2a | ||
|
|
c0150606f0 | ||
|
|
cdb6588973 | ||
|
|
eecf24b20c | ||
|
|
0470e813a9 | ||
|
|
52c2b6a407 | ||
|
|
d0ce4b9d81 | ||
|
|
f08af96294 | ||
|
|
315ab663df | ||
|
|
fbd46f9b1c | ||
|
|
74c099fe63 | ||
|
|
2acfab62f0 | ||
|
|
0f9a6266e2 | ||
|
|
ca447d9a23 | ||
|
|
444dbe1cec | ||
|
|
20ce55eb3a | ||
|
|
3956aba429 | ||
|
|
6a37f5e4d6 | ||
|
|
f71bfd5e28 | ||
|
|
38cc14a1af | ||
|
|
bde9a63390 | ||
|
|
8eb816c314 | ||
|
|
50c05c4eed | ||
|
|
4eb5cfab7b | ||
|
|
df6fe7a379 | ||
|
|
78eec961a2 | ||
|
|
adff33c889 | ||
|
|
372fcd722c | ||
|
|
0982863e2d | ||
|
|
9b58a951f0 | ||
|
|
ba04f3fd5d | ||
|
|
ff52367c1c | ||
|
|
a0a017d54d | ||
|
|
6cad2c6f28 | ||
|
|
cec98ee9e2 | ||
|
|
dbef400762 | ||
|
|
1bd85de19a | ||
|
|
0b206129ac | ||
|
|
5e491801da | ||
|
|
eed09600f7 | ||
|
|
8d6634ff7e | ||
|
|
6c9ed3ca53 | ||
|
|
ede1befffa | ||
|
|
2cd4852321 | ||
|
|
1eb719f2d9 | ||
|
|
bf633082ac | ||
|
|
075a152779 | ||
|
|
c079a13b24 | ||
|
|
113c9d5a02 | ||
|
|
05fa677382 | ||
|
|
ab3c070e1c | ||
|
|
2e6a01b931 | ||
|
|
9fa66bf237 | ||
|
|
98c382e7af | ||
|
|
94c7a3862a | ||
|
|
6869b64b31 | ||
|
|
8faf6f7b72 | ||
|
|
99ddb2f12a | ||
|
|
ca9212c3ca | ||
|
|
c9183f3851 | ||
|
|
0912a7f473 | ||
|
|
38421657b3 | ||
|
|
64cfe1d389 | ||
|
|
69b0b58d46 | ||
|
|
0d442058e5 | ||
|
|
1ef31461bc | ||
|
|
0b09df97ac | ||
|
|
0263e39584 | ||
|
|
d8424726bb | ||
|
|
080cb2dd4b | ||
|
|
786caaecb2 | ||
|
|
eb92b5f1b3 | ||
|
|
c5ba6016aa | ||
|
|
73a845a327 | ||
|
|
6eec552ea4 | ||
|
|
cb62203cf3 | ||
|
|
4fcb64fe90 | ||
|
|
8966f47c7a | ||
|
|
e251375c0c | ||
|
|
672e1ec8c6 | ||
|
|
f8713ede2d | ||
|
|
0b5f854bf0 | ||
|
|
3770020b74 | ||
|
|
9f9a1638f7 | ||
|
|
fb07a937e7 | ||
|
|
025cd283c4 | ||
|
|
b39426dbf7 | ||
|
|
5157bd0960 | ||
|
|
2aaedef4af | ||
|
|
a0b037d288 | ||
|
|
011bdc22b2 | ||
|
|
b437d56736 | ||
|
|
6205e69ab2 | ||
|
|
038f8823f1 | ||
|
|
03dd8367bf | ||
|
|
b597da34da | ||
|
|
bf387f9544 | ||
|
|
365b5e8f8a | ||
|
|
47651766fb | ||
|
|
043ea54a2a | ||
|
|
55c8c82c4b | ||
|
|
557d1f4c49 | ||
|
|
2539a473fe | ||
|
|
6bd35a4c18 | ||
|
|
fb8f0ed4d6 | ||
|
|
3ffdf5459a | ||
|
|
02098b1903 | ||
|
|
c189553c8b | ||
|
|
d970705596 | ||
|
|
5c9ab40601 | ||
|
|
451d077170 | ||
|
|
30d1573346 | ||
|
|
0adef2db5b | ||
|
|
8c1866a4af | ||
|
|
2a7a594b49 | ||
|
|
78ea04556f | ||
|
|
7fe2944477 | ||
|
|
93131417e6 | ||
|
|
6ef5eb0665 | ||
|
|
24103ff5df | ||
|
|
2118de37c3 | ||
|
|
0804ce71d5 | ||
|
|
2ffb558e30 | ||
|
|
05062be889 | ||
|
|
ba6c01e602 | ||
|
|
dfc0f00478 | ||
|
|
ecb2b0e53d | ||
|
|
ed74cd82f5 | ||
|
|
d2be594262 | ||
|
|
1e632d3215 | ||
|
|
5642dfcf38 | ||
|
|
4dff36ffde | ||
|
|
771ce9059c | ||
|
|
e490b30c38 | ||
|
|
f935ef832b | ||
|
|
79cdb77e5d | ||
|
|
ff0c2d3f91 | ||
|
|
6f9901b65c | ||
|
|
bce3a85702 | ||
|
|
f741349d51 | ||
|
|
25863b59a6 | ||
|
|
72c861bb83 | ||
|
|
586574e176 | ||
|
|
0f15954727 | ||
|
|
167338f216 | ||
|
|
d82f6b7607 | ||
|
|
614b219a27 | ||
|
|
35cf8687df | ||
|
|
d883b0f0f9 | ||
|
|
0b942aaaba | ||
|
|
364235e7ae | ||
|
|
ba1f2ced8e | ||
|
|
c4c34a8f4d | ||
|
|
a866f4e174 | ||
|
|
c5916814cd | ||
|
|
349717ac0e | ||
|
|
5d27766424 | ||
|
|
97668ba6c9 | ||
|
|
98fb44f836 | ||
|
|
2260c8ddc0 | ||
|
|
edffc46b98 | ||
|
|
7bd8cc3c0c | ||
|
|
828f6cd7fe | ||
|
|
f9873eb87a | ||
|
|
358e4ffbf5 | ||
|
|
9aad922983 | ||
|
|
d9ab7af8b4 | ||
|
|
05b2a04267 | ||
|
|
4408083b4d | ||
|
|
4f01f101fc | ||
|
|
d9f9911d9b | ||
|
|
93b4562515 | ||
|
|
0bb67e06c1 | ||
|
|
518b3aa726 | ||
|
|
07f3554db3 | ||
|
|
acab70ee7c | ||
|
|
c388bc2dd3 | ||
|
|
8072b0a7d4 | ||
|
|
3f4be595a6 | ||
|
|
5d11901af8 | ||
|
|
43953782f9 | ||
|
|
12e133a5e9 | ||
|
|
e92d4451ef | ||
|
|
fadb60d776 | ||
|
|
0521d78982 | ||
|
|
3602d54a5b | ||
|
|
8428f362c1 | ||
|
|
fafc9c6a20 | ||
|
|
66e088d843 | ||
|
|
4a760ad324 | ||
|
|
c92d7c3bc8 | ||
|
|
ee91109d9f | ||
|
|
30fe257691 | ||
|
|
ab6f145e3e | ||
|
|
83dc425e25 | ||
|
|
001cd78b45 | ||
|
|
3d3359910f | ||
|
|
ee8111e424 | ||
|
|
1861b1137b | ||
|
|
ccf43fe3e3 | ||
|
|
8b491d75b5 | ||
|
|
d70c18d692 |
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
language: c
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
# Change this to your needs
|
||||||
|
script: make linux
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2004-2010 Sergey Lyubka
|
Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,146 +1,187 @@
|
|||||||
# This file is part of Mongoose project, http://code.google.com/p/mongoose
|
# This Makefile is part of Mongoose web server project,
|
||||||
# $Id: Makefile 473 2009-09-02 11:20:06Z valenok $
|
# https://github.com/valenok/mongoose
|
||||||
|
#
|
||||||
|
# Example custom build:
|
||||||
|
# COPT="-g -O0 -DNO_SSL_DL -DUSE_LUA -llua -lcrypto -lssl" make linux
|
||||||
|
#
|
||||||
|
# Flags are:
|
||||||
|
# -DHAVE_MD5 - use system md5 library (-2kb)
|
||||||
|
# -DNDEBUG - strip off all debug code (-5kb)
|
||||||
|
# -DDEBUG - build debug version (very noisy) (+7kb)
|
||||||
|
# -DNO_CGI - disable CGI support (-5kb)
|
||||||
|
# -DNO_SSL - disable SSL functionality (-2kb)
|
||||||
|
# -DNO_SSL_DL - link against system libssl library (-1kb)
|
||||||
|
# -DCONFIG_FILE=\"file\" - use `file' as the default config file
|
||||||
|
# -DSSL_LIB=\"libssl.so.<version>\" - use system versioned SSL shared object
|
||||||
|
# -DCRYPTO_LIB=\"libcrypto.so.<version>\" - use system versioned CRYPTO so
|
||||||
|
# -DUSE_LUA - embed Lua in Mongoose (+100kb)
|
||||||
|
|
||||||
PROG= mongoose
|
PROG = mongoose
|
||||||
|
CFLAGS = -std=c99 -O2 -W -Wall -pedantic -pthread
|
||||||
|
|
||||||
|
# To build with Lua, download and unzip Lua 5.2.1 source code into the
|
||||||
|
# mongoose directory, and then add $(LUA_SOURCES) to CFLAGS
|
||||||
|
LUA = lua-5.2.1/src
|
||||||
|
LUA_FLAGS = -I$(LUA) -DLUA_COMPAT_ALL
|
||||||
|
LUA_SOURCES = $(LUA)/lapi.c $(LUA)/lcode.c $(LUA)/lctype.c \
|
||||||
|
$(LUA)/ldebug.c $(LUA)/ldo.c $(LUA)/ldump.c \
|
||||||
|
$(LUA)/lfunc.c $(LUA)/lgc.c $(LUA)/llex.c \
|
||||||
|
$(LUA)/lmem.c $(LUA)/lobject.c $(LUA)/lopcodes.c \
|
||||||
|
$(LUA)/lparser.c $(LUA)/lstate.c $(LUA)/lstring.c \
|
||||||
|
$(LUA)/ltable.c $(LUA)/ltm.c $(LUA)/lundump.c \
|
||||||
|
$(LUA)/lvm.c $(LUA)/lzio.c $(LUA)/lauxlib.c \
|
||||||
|
$(LUA)/lbaselib.c $(LUA)/lbitlib.c $(LUA)/lcorolib.c \
|
||||||
|
$(LUA)/ldblib.c $(LUA)/liolib.c $(LUA)/lmathlib.c \
|
||||||
|
$(LUA)/loslib.c $(LUA)/lstrlib.c $(LUA)/ltablib.c \
|
||||||
|
$(LUA)/loadlib.c $(LUA)/linit.c
|
||||||
|
LUA_WINOBJS = $(LUA_SOURCES:%.c=%.obj)
|
||||||
|
|
||||||
|
# Stock windows binary builds with Lua and YASSL library.
|
||||||
|
YASSL = ../cyassl-2.4.6
|
||||||
|
YASSL_FLAGS = -I $(YASSL) -I $(YASSL)/cyassl \
|
||||||
|
-D _LIB -D OPENSSL_EXTRA -D HAVE_ERRNO_H \
|
||||||
|
-D HAVE_GETHOSTBYNAME -D HAVE_INET_NTOA -D HAVE_LIMITS_H \
|
||||||
|
-D HAVE_MEMSET -D HAVE_SOCKET -D HAVE_STDDEF_H -D HAVE_STDLIB_H \
|
||||||
|
-D HAVE_STRING_H -D HAVE_SYS_STAT_H -D HAVE_SYS_TYPES_H
|
||||||
|
YASSL_SOURCES = \
|
||||||
|
$(YASSL)/src/internal.c $(YASSL)/src/io.c $(YASSL)/src/keys.c \
|
||||||
|
$(YASSL)/src/ssl.c $(YASSL)/src/tls.c $(YASSL)/ctaocrypt/src/hmac.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/random.c $(YASSL)/ctaocrypt/src/sha.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/sha256.c $(YASSL)/ctaocrypt/src/logging.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/error.c $(YASSL)/ctaocrypt/src/rsa.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/des3.c $(YASSL)/ctaocrypt/src/asn.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/coding.c $(YASSL)/ctaocrypt/src/arc4.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/md4.c $(YASSL)/ctaocrypt/src/md5.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/dh.c $(YASSL)/ctaocrypt/src/dsa.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/pwdbased.c $(YASSL)/ctaocrypt/src/aes.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/md2.c $(YASSL)/ctaocrypt/src/ripemd.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/sha512.c $(YASSL)/src/sniffer.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/rabbit.c $(YASSL)/ctaocrypt/src/misc.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/tfm.c $(YASSL)/ctaocrypt/src/integer.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/ecc.c $(YASSL)/src/ocsp.c $(YASSL)/src/crl.c \
|
||||||
|
$(YASSL)/ctaocrypt/src/hc128.c $(YASSL)/ctaocrypt/src/memory.c
|
||||||
|
|
||||||
|
ALL_SOURCES = main.c mongoose.c build/sqlite3.c build/lsqlite3.c \
|
||||||
|
$(LUA_SOURCES) $(YASSL_SOURCES)
|
||||||
|
ALL_OBJECTS = $(ALL_SOURCES:%.c=%.o)
|
||||||
|
ALL_WINOBJS = $(ALL_SOURCES:%.c=%.obj)
|
||||||
|
|
||||||
|
SQLITE_FLAGS = -DTHREADSAFE=1 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
||||||
|
MONGOOSE_FLAGS = -DNO_SSL_DL -DUSE_LUA -DUSE_LUA_SQLITE3 $(COPT)
|
||||||
|
|
||||||
|
FLAGS = $(MONGOOSE_FLAGS) $(SQLITE_FLAGS) $(YASSL_FLAGS) $(LUA_FLAGS)
|
||||||
|
|
||||||
|
# Using Visual Studio 6.0. To build Mongoose:
|
||||||
|
# Set MSVC variable below to where VS 6.0 is installed on your system
|
||||||
|
# Run "PATH_TO_VC6\bin\nmake windows"
|
||||||
|
MSVC = ../vc6
|
||||||
|
#DBG = /Zi /Od
|
||||||
|
DBG = /DNDEBUG /O1
|
||||||
|
CL = $(MSVC)/bin/cl /MD /TC /nologo $(DBG) /W3 /GA /I$(MSVC)/include
|
||||||
|
LINK = $(MSVC)/bin/link /incremental:no /libpath:$(MSVC)/lib /machine:IX86 \
|
||||||
|
user32.lib shell32.lib comdlg32.lib ws2_32.lib advapi32.lib
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "make (linux|bsd|solaris|mac|windows|mingw)"
|
@echo "make (linux|bsd|solaris|mac|windows|mingw|cygwin)"
|
||||||
|
|
||||||
# Possible COPT values: (in brackets are rough numbers for 'gcc -O2' on i386)
|
%.obj: %.c
|
||||||
# -DHAVE_MD5 - use system md5 library (-2kb)
|
$(CL) /c $(FLAGS) /Fo$@ $<
|
||||||
# -DNDEBUG - strip off all debug code (-5kb)
|
|
||||||
# -DDEBUG - build debug version (very noisy) (+7kb)
|
|
||||||
# -DNO_CGI - disable CGI support (-5kb)
|
|
||||||
# -DNO_SSL - disable SSL functionality (-2kb)
|
|
||||||
# -DCONFIG_FILE=\"file\" - use `file' as the default config file
|
|
||||||
# -DHAVE_STRTOUI64 - use system strtoui64() function for strtoull()
|
|
||||||
# -DSSL_LIB=\"libssl.so.<version>\" - use system versioned SSL shared object
|
|
||||||
# -DCRYPTO_LIB=\"libcrypto.so.<version>\" - use system versioned CRYPTO so
|
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) -o $@ $< -c $(FLAGS) $(CFLAGS)
|
||||||
|
|
||||||
##########################################################################
|
# Lua library for Windows
|
||||||
### UNIX build: linux, bsd, mac, rtems
|
lua.lib: $(LUA_WINOBJS)
|
||||||
##########################################################################
|
$(MSVC)/bin/lib /out:$@ $(LUA_WINOBJS)
|
||||||
|
|
||||||
CFLAGS = -W -Wall -std=c99 -pedantic -O2 $(COPT)
|
# To build with lua, make sure you have Lua unpacked into lua-5.2.1 directory
|
||||||
MAC_SHARED = -flat_namespace -bundle -undefined suppress
|
linux_lua: $(ALL_OBJECTS)
|
||||||
LINFLAGS = -ldl -pthread $(CFLAGS)
|
$(CC) $(ALL_OBJECTS) -o $(PROG) -ldl
|
||||||
LIB = _$(PROG).so
|
|
||||||
#CC = g++
|
|
||||||
|
|
||||||
# Make sure that the compiler flags come last in the compilation string.
|
# Make sure that the compiler flags come last in the compilation string.
|
||||||
# If not so, this can break some on some Linux distros which use
|
# If not so, this can break some on some Linux distros which use
|
||||||
# "-Wl,--as-needed" turned on by default in cc command.
|
# "-Wl,--as-needed" turned on by default in cc command.
|
||||||
# Also, this is turned in many other distros in static linkage builds.
|
# Also, this is turned in many other distros in static linkage builds.
|
||||||
linux:
|
linux:
|
||||||
$(CC) mongoose.c -shared -fPIC -fpic -o $(LIB) $(LINFLAGS)
|
$(CC) mongoose.c main.c -o $(PROG) -ldl $(CFLAGS)
|
||||||
$(CC) mongoose.c main.c -o $(PROG) $(LINFLAGS)
|
|
||||||
|
|
||||||
|
mac: bsd
|
||||||
bsd:
|
bsd:
|
||||||
$(CC) mongoose.c -shared -pthread -fpic -fPIC -o $(LIB) $(CFLAGS)
|
$(CC) mongoose.c main.c -o $(PROG) $(CFLAGS)
|
||||||
$(CC) mongoose.c main.c -pthread -o $(PROG) $(CFLAGS)
|
|
||||||
|
|
||||||
mac:
|
bsd_lua: $(ALL_OBJECTS)
|
||||||
$(CC) mongoose.c -pthread -o $(LIB) $(MAC_SHARED) $(CFLAGS)
|
$(CC) $(ALL_OBJECTS) -o $@
|
||||||
$(CC) mongoose.c main.c -pthread -o $(PROG) $(CFLAGS)
|
|
||||||
|
|
||||||
solaris:
|
solaris:
|
||||||
gcc mongoose.c -pthread -lnsl \
|
$(CC) mongoose.c main.c -lnsl -lsocket -o $(PROG) $(CFLAGS)
|
||||||
-lsocket -fpic -fPIC -shared -o $(LIB) $(CFLAGS)
|
|
||||||
gcc mongoose.c main.c -pthread -lnsl -lsocket -o $(PROG) $(CFLAGS)
|
|
||||||
|
|
||||||
|
lib$(PROG).a: $(ALL_OBJECTS)
|
||||||
|
ar cr $@ $(ALL_OBJECTS)
|
||||||
|
|
||||||
##########################################################################
|
$(PROG).lib: $(ALL_WINOBJS)
|
||||||
### WINDOWS build: Using Visual Studio or Mingw
|
$(MSVC)/bin/lib /out:$@ $(ALL_WINOBJS)
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
# Using Visual Studio 6.0. To build Mongoose:
|
# For codesign to work in non-interactive mode, unlock login keychain:
|
||||||
# o Set VC variable below to where VS 6.0 is installed on your system
|
# security unlock ~/Library/Keychains/login.keychain
|
||||||
# o Run "PATH_TO_VC6\bin\nmake windows"
|
# See e.g. http://lists.apple.com/archives/apple-cdsa/2008/Jan/msg00027.html
|
||||||
|
Mongoose: mongoose.c main.c
|
||||||
|
$(CC) mongoose.c main.c build/lsqlite3.c build/sqlite3.c \
|
||||||
|
-DUSE_COCOA $(CFLAGS) $(FLAGS) -mmacosx-version-min=10.4 \
|
||||||
|
$(YASSL_SOURCES) $(LUA_SOURCES) \
|
||||||
|
-framework Cocoa -ObjC -arch i386 -arch x86_64 -o Mongoose
|
||||||
|
|
||||||
VC= z:
|
cocoa: Mongoose
|
||||||
CYA= y:
|
V=`perl -lne '/define\s+MONGOOSE_VERSION\s+"(\S+)"/ and print $$1' mongoose.c`; DIR=dmg/Mongoose.app && rm -rf $$DIR && mkdir -p $$DIR/Contents/{MacOS,Resources} && install -m 644 build/mongoose_*.png $$DIR/Contents/Resources/ && install -m 644 build/Info.plist $$DIR/Contents/ && install -m 755 Mongoose $$DIR/Contents/MacOS/ && ln -fs /Applications dmg/ ; hdiutil create Mongoose_$$V.dmg -volname "Mongoose $$V" -srcfolder dmg -ov #; rm -rf dmg
|
||||||
#DBG= /Zi /DDEBUG /Od
|
|
||||||
DBG= /DNDEBUG /O1
|
|
||||||
CL= cl /MD /TC /nologo $(DBG) /Gz /W3 /DNO_SSL_DL
|
|
||||||
GUILIB= user32.lib shell32.lib
|
|
||||||
LINK= /link /incremental:no /libpath:$(VC)\lib /subsystem:windows \
|
|
||||||
ws2_32.lib advapi32.lib cyassl.lib
|
|
||||||
CYAFL = /c /I $(CYA)/include -I $(CYA)/include/openssl \
|
|
||||||
/I $(CYA)/ctaocrypt/include /D _LIB /D OPENSSL_EXTRA
|
|
||||||
|
|
||||||
CYASRC= \
|
un:
|
||||||
$(CYA)/src/cyassl_int.c \
|
$(CC) test/unit_test.c -o unit_test -I. -I$(LUA) $(LUA_SOURCES) \
|
||||||
$(CYA)/src/cyassl_io.c \
|
$(CFLAGS) -g -O0
|
||||||
$(CYA)/src/keys.c \
|
./unit_test
|
||||||
$(CYA)/src/tls.c \
|
|
||||||
$(CYA)/src/ssl.c \
|
|
||||||
$(CYA)/ctaocrypt/src/aes.c \
|
|
||||||
$(CYA)/ctaocrypt/src/arc4.c \
|
|
||||||
$(CYA)/ctaocrypt/src/asn.c \
|
|
||||||
$(CYA)/ctaocrypt/src/coding.c \
|
|
||||||
$(CYA)/ctaocrypt/src/ctc_asm.c \
|
|
||||||
$(CYA)/ctaocrypt/src/ctc_misc.c \
|
|
||||||
$(CYA)/ctaocrypt/src/cyassl_memory.c \
|
|
||||||
$(CYA)/ctaocrypt/src/des3.c \
|
|
||||||
$(CYA)/ctaocrypt/src/dh.c \
|
|
||||||
$(CYA)/ctaocrypt/src/dsa.c \
|
|
||||||
$(CYA)/ctaocrypt/src/ecc.c \
|
|
||||||
$(CYA)/ctaocrypt/src/hc128.c \
|
|
||||||
$(CYA)/ctaocrypt/src/hmac.c \
|
|
||||||
$(CYA)/ctaocrypt/src/integer.c \
|
|
||||||
$(CYA)/ctaocrypt/src/md4.c \
|
|
||||||
$(CYA)/ctaocrypt/src/md5.c \
|
|
||||||
$(CYA)/ctaocrypt/src/pwdbased.c \
|
|
||||||
$(CYA)/ctaocrypt/src/rabbit.c \
|
|
||||||
$(CYA)/ctaocrypt/src/random.c \
|
|
||||||
$(CYA)/ctaocrypt/src/ripemd.c \
|
|
||||||
$(CYA)/ctaocrypt/src/rsa.c \
|
|
||||||
$(CYA)/ctaocrypt/src/sha.c \
|
|
||||||
$(CYA)/ctaocrypt/src/sha256.c \
|
|
||||||
$(CYA)/ctaocrypt/src/sha512.c \
|
|
||||||
$(CYA)/ctaocrypt/src/tfm.c
|
|
||||||
|
|
||||||
cyassl:
|
wi:
|
||||||
$(CL) $(CYASRC) $(CYAFL) $(DEF)
|
$(CL) test/unit_test.c $(LUA_SOURCES) $(LUA_FLAGS) \
|
||||||
lib *.obj /out:cyassl.lib
|
$(YASSL_SOURCES) $(YASSL_FLAGS) /I. /DNO_SSL_DL \
|
||||||
|
/link /libpath:$(MSVC)/lib advapi32.lib /out:unit_test.exe
|
||||||
|
./unit_test.exe
|
||||||
|
|
||||||
windows:
|
windows: $(ALL_WINOBJS)
|
||||||
rc win32\res.rc
|
$(MSVC)/bin/rc build/res.rc
|
||||||
$(CL) main.c mongoose.c /GA $(LINK) win32\res.res \
|
$(LINK) /nologo $(ALL_WINOBJS) build/res.res /out:$(PROG).exe
|
||||||
$(GUILIB) /out:$(PROG).exe
|
|
||||||
$(CL) mongoose.c /GD $(LINK) /DLL /DEF:win32\dll.def /out:_$(PROG).dll
|
|
||||||
|
|
||||||
# Build for Windows under MinGW
|
# Build for Windows under MinGW
|
||||||
#MINGWDBG= -DDEBUG -O0
|
#MINGWDBG= -DDEBUG -O0 -ggdb
|
||||||
MINGWDBG= -DNDEBUG -Os
|
MINGWDBG= -DNDEBUG -Os
|
||||||
#MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,console $(MINGWDBG) -DHAVE_STDINT
|
MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,console $(MINGWDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
||||||
MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,windows $(MINGWDBG)
|
|
||||||
mingw:
|
mingw:
|
||||||
windres win32\res.rc win32\res.o
|
windres build\res.rc build\res.o
|
||||||
gcc $(MINGWOPT) mongoose.c -lws2_32 \
|
$(CC) $(MINGWOPT) mongoose.c -lws2_32 \
|
||||||
-shared -Wl,--out-implib=$(PROG).lib -o _$(PROG).dll
|
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
||||||
gcc $(MINGWOPT) mongoose.c main.c win32\res.o -lws2_32 -ladvapi32 \
|
$(CC) $(MINGWOPT) mongoose.c main.c build\res.o \
|
||||||
-o $(PROG).exe
|
-lws2_32 -ladvapi32 -lcomdlg32 -o $(PROG).exe
|
||||||
|
|
||||||
|
# Build for Windows under Cygwin
|
||||||
|
#CYGWINDBG= -DDEBUG -O0 -ggdb
|
||||||
|
CYGWINDBG= -DNDEBUG -Os
|
||||||
|
CYGWINOPT= -W -Wall -mthreads -Wl,--subsystem,console $(CYGWINDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
||||||
|
cygwin:
|
||||||
|
windres ./build/res.rc ./build/res.o
|
||||||
|
$(CC) $(CYGWINOPT) mongoose.c -lws2_32 \
|
||||||
|
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
||||||
|
$(CC) $(CYGWINOPT) -Ibuild mongoose.c main.c ./build/res.o \
|
||||||
|
-lws2_32 -ladvapi32 -o $(PROG).exe
|
||||||
|
|
||||||
##########################################################################
|
tests:
|
||||||
### Manuals, cleanup, test, release
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
man:
|
|
||||||
groff -man -T ascii mongoose.1 | col -b > mongoose.txt
|
|
||||||
groff -man -T ascii mongoose.1 | less
|
|
||||||
|
|
||||||
# "TEST=unit make test" - perform unit test only
|
|
||||||
# "TEST=embedded" - test embedded API by building and testing test/embed.c
|
|
||||||
# "TEST=basic_tests" - perform basic tests only (no CGI, SSI..)
|
|
||||||
test: do_test
|
|
||||||
do_test:
|
|
||||||
perl test/test.pl $(TEST)
|
perl test/test.pl $(TEST)
|
||||||
|
|
||||||
release: clean
|
tarball: clean
|
||||||
F=mongoose-`perl -lne '/define\s+MONGOOSE_VERSION\s+"(\S+)"/ and print $$1' mongoose.c`.tgz ; cd .. && tar -czf x mongoose/{LICENSE,Makefile,bindings,examples,test,win32,mongoose.c,mongoose.h,mongoose.1,main.c} && mv x mongoose/$$F
|
F=mongoose-`perl -lne '/define\s+MONGOOSE_VERSION\s+"(\S+)"/ and print $$1' mongoose.c`.tgz ; cd .. && tar -czf x mongoose/{LICENSE,Makefile,examples,test,build,*.[ch],*.md} && mv x mongoose/$$F
|
||||||
|
|
||||||
|
release: tarball cocoa
|
||||||
|
wine make windows
|
||||||
|
V=`perl -lne '/define\s+MONGOOSE_VERSION\s+"(\S+)"/ and print $$1' mongoose.c`; upx mongoose.exe; cp mongoose.exe mongoose-$$V.exe; cp mongoose.exe mongoose_php_bundle/; zip -r mongoose_php_bundle_$$V.zip mongoose_php_bundle/
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o *.core $(PROG) *.obj *.so $(PROG).txt *.dSYM *.tgz
|
cd examples && $(MAKE) clean
|
||||||
|
rm -rf *.o *.core $(PROG) *.obj *.so $(PROG).txt *.dSYM *.tgz \
|
||||||
|
$(PROG).exe *.dll *.lib build/res.o build/res.RES *.dSYM *.zip *.pdb \
|
||||||
|
*.exe *.dmg $(ALL_OBJECTS) $(ALL_WINOBJS)
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Project Mission
|
||||||
|
|
||||||
|
Project mission is to provide simple, functional, embeddable web server to
|
||||||
|
make it easy for application and device developers to implement web interface
|
||||||
|
for their application and devices, and to offer a simple web development
|
||||||
|
environment.
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
To accomplish it's mission, Mongoose keeps balance on functionality and
|
||||||
|
simplicity by carefully selected list of features:
|
||||||
|
|
||||||
|
- Liberal, commercial-friendly
|
||||||
|
[MIT license](http://en.wikipedia.org/wiki/MIT_License)
|
||||||
|
- Works on Windows, Mac, UNIX, iPhone, Android, and many other platforms
|
||||||
|
- Support for CGI, SSL, SSI, Digest (MD5) authorization, Websocket, WEbDAV
|
||||||
|
- Lua server pages with Sqlite, see
|
||||||
|
[page.lp](https://github.com/valenok/mongoose/blob/master/test/page.lp)
|
||||||
|
- Resumed download, URL rewrite, IP-based ACL, Windows service
|
||||||
|
- Excluding files from serving by URI pattern (file blacklist)
|
||||||
|
- Download speed limit based on client subnet or URI pattern
|
||||||
|
- Small footprint: executable size is 50 kB on Linux 2.6 i386 system
|
||||||
|
- 130 kilobytes Windows executable with all of the above and no dependencies
|
||||||
|
- Simple and clean embedding API,
|
||||||
|
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h).
|
||||||
|
The source is in single
|
||||||
|
[mongoose.c](https://github.com/valenok/mongoose/blob/master/mongoose.c) file
|
||||||
|
to make things easy
|
||||||
|
- Embedding examples:
|
||||||
|
[hello.c](https://github.com/valenok/mongoose/blob/master/examples/hello.c),
|
||||||
|
[post.c](https://github.com/valenok/mongoose/blob/master/examples/post.c),
|
||||||
|
[upload.c](https://github.com/valenok/mongoose/blob/master/examples/upload.c),
|
||||||
|
[websocket.c](https://github.com/valenok/mongoose/blob/master/examples/websocket.c)
|
||||||
|
- HTTP client functionality for embedded usage, capable of
|
||||||
|
sending arbitrary HTTP/HTTPS requests
|
||||||
|
- [User Manual](https://github.com/valenok/mongoose/blob/master/UserManual.md)
|
||||||
|
|
||||||
|
Continuous build status: 
|
||||||
|
|
||||||
|
Questions can be asked at
|
||||||
|
[mongoose-users@google.com](http://groups.google.com/group/mongoose-users)
|
||||||
|
mailing list.
|
||||||
|
|
||||||
|
|
||||||
|
# Keep Sergey happy
|
||||||
|
|
||||||
|
I am Sergey Lyubka, a software engineer from Galway, Ireland. I started
|
||||||
|
working on Mongoose in 2004, and since then continuously improve it,
|
||||||
|
investing thousands of hours of work. My other project I'm contributing to the
|
||||||
|
community for free is
|
||||||
|
[Super Light Regular Expression library](http://code.google.com/p/slre).
|
||||||
|
|
||||||
|
If you feel grateful for the stuff I've done, you can buy me a book from my
|
||||||
|
[Amazon wishlist](http://amzn.com/w/1OC2ZCPTQYIEP?sort=priority). Many thanks
|
||||||
|
to all who already did so: T.Barmann, D.Hughes, J.C.Sloan, R.Romeo,
|
||||||
|
L.E.Spencer, S.Kotay, R.M.Shorter, W.Mar, J.Wilander, Santa from Memphis,
|
||||||
|
S.Davies and 8 others.
|
||||||
|
Appreciated guys, you keep my brains going! Cash is also welcome indeed.
|
||||||
|
Press [<img src="http://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif">](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DGZ2FMP95TAL6)
|
||||||
|
button to donate. Donation progress: 710/1000 €
|
||||||
|
(thanks to O.M.Vilhunen, C.Radik, G.Woodcock, M.Szczepkowski,
|
||||||
|
Eternal Lands Dev Team, T.Tollet, C.Tangerino, G.Karsai, A.Bourgett,
|
||||||
|
C.Blakemore, D.Fonaryov, T.Andrle, O.IJsselmuiden, R.Womack, M.Tomlinson,
|
||||||
|
A.Slåttå, L.Farrell, J.D.P.Ballestero, V.Albaev, B.Harker, T.Scheffel, H.Klein,
|
||||||
|
R.Merit, T.Bennett, H.Solis, A.Zincenko, M.S., S.Krul, K.Cooke, S.McCallum,
|
||||||
|
F.Morenius)
|
||||||
|
|
||||||
|

|
||||||
+553
@@ -0,0 +1,553 @@
|
|||||||
|
# Overview
|
||||||
|
|
||||||
|
Mongoose is small and easy to use web server. It is self-contained, and does
|
||||||
|
not require any external software to run.
|
||||||
|
|
||||||
|
On Windows, mongoose iconifies itself to the system tray icon when started.
|
||||||
|
Right-click on the icon pops up a menu, where it is possible to stop
|
||||||
|
mongoose, or configure it, or install it as Windows service. The easiest way
|
||||||
|
to share a folder on Windows is to copy `mongoose.exe` to a folder,
|
||||||
|
double-click the exe, and launch a browser at
|
||||||
|
[http://localhost:8080](http://localhost:8080). Note that 'localhost' should
|
||||||
|
be changed to a machine's name if a folder is accessed from other computer.
|
||||||
|
|
||||||
|
On UNIX and Mac, mongoose is a command line utility. Running `mongoose` in
|
||||||
|
terminal, optionally followed by configuration parameters
|
||||||
|
(`mongoose [OPTIONS]`) or configuration file name
|
||||||
|
(`mongoose [config_file_name]`) starts the
|
||||||
|
web server. Mongoose does not detach from terminal. Pressing `Ctrl-C` keys
|
||||||
|
would stop the server.
|
||||||
|
|
||||||
|
When started, mongoose first searches for the configuration file.
|
||||||
|
If configuration file is specified explicitly in the command line, i.e.
|
||||||
|
`mongoose path_to_config_file`, then specified configuration file is used.
|
||||||
|
Otherwise, mongoose would search for file `mongoose.conf` in the same directory
|
||||||
|
where binary is located, and use it. Configuration file can be absent.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration file is a sequence of lines, each line containing
|
||||||
|
command line argument name and it's value. Empty lines, and lines beginning
|
||||||
|
with `#`, are ignored. Here is the example of `mongoose.conf` file:
|
||||||
|
|
||||||
|
document_root c:\www
|
||||||
|
listening_ports 8080,8043s
|
||||||
|
ssl_certificate c:\mongoose\ssl_cert.pem
|
||||||
|
|
||||||
|
When configuration file is processed, mongoose process command line arguments,
|
||||||
|
if they are specified. Command line arguments therefore can override
|
||||||
|
configuration file settings. Command line arguments must start with `-`.
|
||||||
|
For example, if `mongoose.conf` has line
|
||||||
|
`document_root /var/www`, and mongoose has been started as
|
||||||
|
`mongoose -document_root /etc`, then `/etc` directory will be served as
|
||||||
|
document root, because command line options take priority over
|
||||||
|
configuration file. Configuration options section below provide a good
|
||||||
|
overview of Mongoose features.
|
||||||
|
|
||||||
|
Note that configuration options on the command line must start with `-`,
|
||||||
|
but their names are the same as in the config file. All option names are
|
||||||
|
listed in the next section. Thus, the following two setups are equivalent:
|
||||||
|
|
||||||
|
# Using command line arguments
|
||||||
|
$ mongoose -listening_ports 1234 -document_root /var/www
|
||||||
|
|
||||||
|
# Using config file
|
||||||
|
$ cat mongoose.conf
|
||||||
|
listening_ports 1234
|
||||||
|
document_root /var/www
|
||||||
|
$ mongoose
|
||||||
|
|
||||||
|
Mongoose can also be used to modify `.htpasswd` passwords file:
|
||||||
|
|
||||||
|
mongoose -A <htpasswd_file> <realm> <user> <passwd>
|
||||||
|
|
||||||
|
Unlike other web servers, mongoose does not require CGI scripts be located in
|
||||||
|
a special directory. CGI scripts can be anywhere. CGI (and SSI) files are
|
||||||
|
recognized by the file name pattern. Mongoose uses shell-like glob
|
||||||
|
patterns. Pattern match starts at the beginning of the string, so essentially
|
||||||
|
patterns are prefix patterns. Syntax is as follows:
|
||||||
|
|
||||||
|
** Matches everything
|
||||||
|
* Matches everything but slash character, '/'
|
||||||
|
? Matches any character
|
||||||
|
$ Matches the end of the string
|
||||||
|
| Matches if pattern on the left side or the right side matches.
|
||||||
|
|
||||||
|
All other characters in the pattern match themselves. Examples:
|
||||||
|
|
||||||
|
**.cgi$ Any string that ends with .cgi
|
||||||
|
/foo Any string that begins with /foo
|
||||||
|
**a$|**b$ Any string that ends with a or b
|
||||||
|
|
||||||
|
# Configuration Options
|
||||||
|
|
||||||
|
Below is a list of configuration options Mongoose understands. Every option
|
||||||
|
is followed by it's default value. If default value is not present, then
|
||||||
|
it is empty.
|
||||||
|
|
||||||
|
### cgi_pattern `**.cgi$|**.pl$|**.php$`
|
||||||
|
All files that match `cgi_pattern` are treated as CGI files. Default pattern
|
||||||
|
allows CGI files be anywhere. To restrict CGIs to a certain directory,
|
||||||
|
use `/path/to/cgi-bin/**.cgi` as pattern. Note that full file path is
|
||||||
|
matched against the pattern, not the URI.
|
||||||
|
|
||||||
|
### cgi_environment
|
||||||
|
Extra environment variables to be passed to the CGI script in
|
||||||
|
addition to standard ones. The list must be comma-separated list
|
||||||
|
of name=value pairs, like this: `VARIABLE1=VALUE1,VARIABLE2=VALUE2`.
|
||||||
|
|
||||||
|
### put\_delete\_auth\_file
|
||||||
|
Passwords file for PUT and DELETE requests. Without it, PUT and DELETE requests
|
||||||
|
will fail.
|
||||||
|
|
||||||
|
### cgi_interpreter
|
||||||
|
Path to an executable to use as CGI interpreter for __all__ CGI scripts
|
||||||
|
regardless script extension. If this option is not set (which is a default),
|
||||||
|
Mongoose looks at first line of a CGI script,
|
||||||
|
[shebang line](http://en.wikipedia.org/wiki/Shebang_(Unix)), for an interpreter.
|
||||||
|
|
||||||
|
For example, if both PHP and perl CGIs are used, then
|
||||||
|
`#!/path/to/php-cgi.exe` and `#!/path/to/perl.exe` must be first lines of the
|
||||||
|
respective CGI scripts. Note that paths should be either full file paths,
|
||||||
|
or file paths relative to the current working directory of mongoose server.
|
||||||
|
If mongoose is started by mouse double-click on Windows, current working
|
||||||
|
directory is a directory where mongoose executable is located.
|
||||||
|
|
||||||
|
If all CGIs use the same interpreter, for example they are all PHP, then
|
||||||
|
`cgi_interpreter` can be set to the path to `php-cgi.exe` executable and
|
||||||
|
shebang line in the CGI scripts can be omitted.
|
||||||
|
Note that PHP scripts must use `php-cgi.exe` executable, not `php.exe`.
|
||||||
|
|
||||||
|
### protect_uri
|
||||||
|
Comma separated list of URI=PATH pairs, specifying that given
|
||||||
|
URIs must be protected with respected password files. Paths must be full
|
||||||
|
file paths.
|
||||||
|
|
||||||
|
### authentication_domain `mydomain.com`
|
||||||
|
Authorization realm used in `.htpasswd` authorization.
|
||||||
|
|
||||||
|
### ssi_pattern `**.shtml$|**.shtm$`
|
||||||
|
All files that match `ssi_pattern` are treated as SSI.
|
||||||
|
|
||||||
|
Server Side Includes (SSI) is a simple interpreted server-side scripting
|
||||||
|
language which is most commonly used to include the contents of a file into
|
||||||
|
a web page. It can be useful when it is desirable to include a common piece
|
||||||
|
of code throughout a website, for example, headers and footers.
|
||||||
|
|
||||||
|
In order for a webpage to recognize an SSI-enabled HTML file, the filename
|
||||||
|
should end with a special extension, by default the extension should be
|
||||||
|
either `.shtml` or `.shtm`.
|
||||||
|
|
||||||
|
Unknown SSI directives are silently ignored by mongoose. Currently, two SSI
|
||||||
|
directives are supported, `<!--#include ...>` and
|
||||||
|
`<!--#exec "command">`. Note that `<!--#include ...>` directive supports
|
||||||
|
three path specifications:
|
||||||
|
|
||||||
|
<!--#include virtual="path"> Path is relative to web server root
|
||||||
|
<!--#include file="path"> Path is relative to web server working dir
|
||||||
|
<!--#include "path"> Path is relative to current document
|
||||||
|
|
||||||
|
The `include` directive may be used to include the contents of a file or the
|
||||||
|
result of running a CGI script. The `exec` directive is used to execute a
|
||||||
|
command on a server, and show command's output. Example:
|
||||||
|
|
||||||
|
<!--#exec "ls -l" -->
|
||||||
|
|
||||||
|
For more information on Server Side Includes, take a look at the Wikipedia:
|
||||||
|
[Server Side Includes](http://en.wikipedia.org/wiki/Server_Side_Includes)
|
||||||
|
|
||||||
|
### throttle
|
||||||
|
Limit download speed for clients. `throttle` is a comma-separated
|
||||||
|
list of key=value pairs, where key could be:
|
||||||
|
|
||||||
|
* limit speed for all connections
|
||||||
|
x.x.x.x/mask limit speed for specified subnet
|
||||||
|
uri_prefix_pattern limit speed for given URIs
|
||||||
|
|
||||||
|
The value is a floating-point number of bytes per second, optionally
|
||||||
|
followed by a `k` or `m` character, meaning kilobytes and
|
||||||
|
megabytes respectively. A limit of 0 means unlimited rate. The
|
||||||
|
last matching rule wins. Examples:
|
||||||
|
|
||||||
|
*=1k,10.0.0.0/8=0 limit all accesses to 1 kilobyte per second,
|
||||||
|
but give connections from 10.0.0.0/8 subnet
|
||||||
|
unlimited speed
|
||||||
|
|
||||||
|
/downloads/=5k limit accesses to all URIs in `/downloads/` to
|
||||||
|
5 kilobytes per secods. All other accesses are unlimited
|
||||||
|
|
||||||
|
### access\_log\_file
|
||||||
|
Path to a file for access logs. Either full path, or relative to current
|
||||||
|
working directory. If absent (default), then accesses are not logged.
|
||||||
|
|
||||||
|
### error\_log\_file
|
||||||
|
Path to a file for error logs. Either full path, or relative to current
|
||||||
|
working directory. If absent (default), then errors are not logged.
|
||||||
|
|
||||||
|
### enable\_directory\_listing `yes`
|
||||||
|
Enable directory listing, either `yes` or `no`.
|
||||||
|
|
||||||
|
### enable\_keep\_alive `no`
|
||||||
|
Enable connection keep alive, either `yes` or `no`.
|
||||||
|
|
||||||
|
Experimental feature. Allows clients to reuse TCP connection for
|
||||||
|
subsequent HTTP requests, which improves performance.
|
||||||
|
For this to work when using request handlers it's important to add the correct
|
||||||
|
Content-Length HTTP header for each request. If this is forgotten the client
|
||||||
|
will time out.
|
||||||
|
|
||||||
|
|
||||||
|
### global\_auth\_file
|
||||||
|
Path to a global passwords file, either full path or relative to the current
|
||||||
|
working directory. If set, per-directory `.htpasswd` files are ignored,
|
||||||
|
and all requests are authorised against that file.
|
||||||
|
|
||||||
|
The file has to include the realm set through `authentication_domain` and the password in digest format:
|
||||||
|
|
||||||
|
user:realm:digest
|
||||||
|
test:test.com:ce0220efc2dd2fad6185e1f1af5a4327
|
||||||
|
|
||||||
|
(e.g. use [this generator](http://www.askapache.com/online-tools/htpasswd-generator))
|
||||||
|
|
||||||
|
### index_files `index.html,index.htm,index.cgi,index.shtml,index.php`
|
||||||
|
Comma-separated list of files to be treated as directory index
|
||||||
|
files.
|
||||||
|
|
||||||
|
### access\_control\_list
|
||||||
|
An Access Control List (ACL) allows restrictions to be put on the list of IP
|
||||||
|
addresses which have access to the web server. In the case of the Mongoose
|
||||||
|
web server, the ACL is a comma separated list of IP subnets, where each
|
||||||
|
subnet is prepended by either a `-` or a `+` sign. A plus sign means allow,
|
||||||
|
where a minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
|
||||||
|
this means to deny only that single IP address.
|
||||||
|
|
||||||
|
Subnet masks may vary from 0 to 32, inclusive. The default setting is to allow
|
||||||
|
all accesses. On each request the full list is traversed, and
|
||||||
|
the last match wins. Examples:
|
||||||
|
|
||||||
|
-0.0.0.0/0,+192.168/16 deny all acccesses, only allow 192.168/16 subnet
|
||||||
|
|
||||||
|
To learn more about subnet masks, see the
|
||||||
|
[Wikipedia page on Subnetwork](http://en.wikipedia.org/wiki/Subnetwork)
|
||||||
|
|
||||||
|
### extra\_mime\_types
|
||||||
|
Extra mime types to recognize, in form `extension1=type1,exten-
|
||||||
|
sion2=type2,...`. Extension must include dot. Example:
|
||||||
|
`.cpp=plain/text,.java=plain/text`
|
||||||
|
|
||||||
|
### listening_ports `8080`
|
||||||
|
Comma-separated list of ports to listen on. If the port is SSL, a
|
||||||
|
letter `s` must be appeneded, for example, `80,443s` will open
|
||||||
|
port 80 and port 443, and connections on port 443 will be SSL-ed.
|
||||||
|
For non-SSL ports, it is allowed to append letter `r`, meaning 'redirect'.
|
||||||
|
Redirect ports will redirect all their traffic to the first configured
|
||||||
|
SSL port. For example, if `listening_ports` is `80r,443s`, then all
|
||||||
|
HTTP traffic coming at port 80 will be redirected to HTTPS port 443.
|
||||||
|
|
||||||
|
It is possible to specify an IP address to bind to. In this case,
|
||||||
|
an IP address and a colon must be prepended to the port number.
|
||||||
|
For example, to bind to a loopback interface on port 80 and to
|
||||||
|
all interfaces on HTTPS port 443, use `127.0.0.1:80,443s`.
|
||||||
|
|
||||||
|
### document_root `.`
|
||||||
|
A directory to serve. By default, currect directory is served. Current
|
||||||
|
directory is commonly referenced as dot (`.`).
|
||||||
|
|
||||||
|
### ssl_certificate
|
||||||
|
Path to SSL certificate file. This option is only required when at least one
|
||||||
|
of the `listening_ports` is SSL. The file must be in PEM format,
|
||||||
|
and it must have both private key and certificate, see for example
|
||||||
|
[ssl_cert.pem](https://github.com/valenok/mongoose/blob/master/build/ssl_cert.pem)
|
||||||
|
|
||||||
|
### num_threads `50`
|
||||||
|
Number of worker threads. Mongoose handles each incoming connection in a
|
||||||
|
separate thread. Therefore, the value of this option is effectively a number
|
||||||
|
of concurrent HTTP connections Mongoose can handle.
|
||||||
|
|
||||||
|
### run\_as\_user
|
||||||
|
Switch to given user credentials after startup. Usually, this option is
|
||||||
|
required when mongoose needs to bind on privileged port on UNIX. To do
|
||||||
|
that, mongoose needs to be started as root. But running as root is a bad idea,
|
||||||
|
therefore this option can be used to drop privileges. Example:
|
||||||
|
|
||||||
|
mongoose -listening_ports 80 -run_as_user nobody
|
||||||
|
|
||||||
|
### url\_rewrite\_patterns
|
||||||
|
Comma-separated list of URL rewrites in the form of
|
||||||
|
`uri_pattern=file_or_directory_path`. When Mongoose receives the request,
|
||||||
|
it constructs the file name to show by combining `document_root` and the URI.
|
||||||
|
However, if the rewrite option is used and `uri_pattern` matches the
|
||||||
|
requested URI, then `document_root` is ignored. Insted,
|
||||||
|
`file_or_directory_path` is used, which should be a full path name or
|
||||||
|
a path relative to the web server's current working directory. Note that
|
||||||
|
`uri_pattern`, as all mongoose patterns, is a prefix pattern.
|
||||||
|
|
||||||
|
This makes it possible to serve many directories outside from `document_root`,
|
||||||
|
redirect all requests to scripts, and do other tricky things. For example,
|
||||||
|
to redirect all accesses to `.doc` files to a special script, do:
|
||||||
|
|
||||||
|
mongoose -url_rewrite_patterns **.doc$=/path/to/cgi-bin/handle_doc.cgi
|
||||||
|
|
||||||
|
Or, to imitate user home directories support, do:
|
||||||
|
|
||||||
|
mongoose -url_rewrite_patterns /~joe/=/home/joe/,/~bill=/home/bill/
|
||||||
|
|
||||||
|
### hide\_files\_patterns
|
||||||
|
A pattern for the files to hide. Files that match the pattern will not
|
||||||
|
show up in directory listing and return `404 Not Found` if requested. Pattern
|
||||||
|
must be for a file name only, not including directory name. Example:
|
||||||
|
|
||||||
|
mongoose -hide_files_patterns secret.txt|even_more_secret.txt
|
||||||
|
|
||||||
|
# Lua Server Pages
|
||||||
|
Pre-built Windows and Mac mongoose binaries have built-in Lua Server Pages
|
||||||
|
support. That means it is possible to write PHP-like scripts with mongoose,
|
||||||
|
using Lua programming language instead of PHP. Lua is known
|
||||||
|
for it's speed and small size. Mongoose uses Lua version 5.2.1, the
|
||||||
|
documentation for it can be found at
|
||||||
|
[Lua 5.2 reference manual](http://www.lua.org/manual/5.2/).
|
||||||
|
|
||||||
|
To create a Lua Page, make sure a file has `.lp` extension. For example,
|
||||||
|
let's say it is going to be `my_page.lp`. The contents of the file, just like
|
||||||
|
with PHP, is HTML with embedded Lua code. Lua code must be enclosed in
|
||||||
|
`<? ?>` blocks, and can appear anywhere on the page. For example, to
|
||||||
|
print current weekday name, one can write:
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span>Today is:</span>
|
||||||
|
<? mg.write(os.date("%A")) ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Note that this example uses function `mg.write()`, which prints data to the
|
||||||
|
web page. Using function `mg.write()` is the way to generate web content from
|
||||||
|
inside Lua code. In addition to `mg.write()`, all standard library functions
|
||||||
|
are accessible from the Lua code (please check reference manual for details),
|
||||||
|
and also information about the request is available in `mg.request_info` object,
|
||||||
|
like request method, all headers, etcetera. Please refer to
|
||||||
|
`struct mg_request_info` definition in
|
||||||
|
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h)
|
||||||
|
to see what kind of information is present in `mg.request_info` object. Also,
|
||||||
|
[page.lp](https://github.com/valenok/mongoose/blob/master/test/page.lp) and
|
||||||
|
[prime_numbers.lp](https://github.com/valenok/mongoose/blob/master/examples/lua/prime_numbers.lp)
|
||||||
|
contains some example code that uses `request_info` and other functions(form submitting for example).
|
||||||
|
|
||||||
|
Mongoose exports the following to the Lua server page:
|
||||||
|
|
||||||
|
mg.read() -- reads a chunk from POST data, returns it as a string
|
||||||
|
mg.write(str) -- writes string to the client
|
||||||
|
mg.include(path) -- sources another Lua file
|
||||||
|
mg.redirect(uri) -- internal redirect to a given URI
|
||||||
|
mg.onerror(msg) -- error handler, can be overridden
|
||||||
|
mg.version -- a string that holds Mongoose version
|
||||||
|
mg.request_info -- a table with request information
|
||||||
|
|
||||||
|
-- Connect to the remote TCP server. This function is an implementation
|
||||||
|
-- of simple socket interface. It returns a socket object with three
|
||||||
|
-- methods: send, recv, close, which are synchronous (blocking).
|
||||||
|
-- connect() throws an exception on connection error.
|
||||||
|
connect(host, port, use_ssl)
|
||||||
|
|
||||||
|
-- Example of using connect() interface:
|
||||||
|
local host = 'code.google.com' -- IP address or domain name
|
||||||
|
local ok, sock = pcall(connect, host, 80, 1)
|
||||||
|
if ok then
|
||||||
|
sock:send('GET /p/mongoose/ HTTP/1.0\r\n' ..
|
||||||
|
'Host: ' .. host .. '\r\n\r\n')
|
||||||
|
local reply = sock:recv()
|
||||||
|
sock:close()
|
||||||
|
-- reply now contains the web page https://code.google.com/p/mongoose
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
**IMPORTANT: Mongoose does not send HTTP headers for Lua pages. Therefore,
|
||||||
|
every Lua Page must begin with HTTP reply line and headers**, like this:
|
||||||
|
|
||||||
|
<? print('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') ?>
|
||||||
|
<html><body>
|
||||||
|
... the rest of the web page ...
|
||||||
|
|
||||||
|
To serve Lua Page, mongoose creates Lua context. That context is used for
|
||||||
|
all Lua blocks within the page. That means, all Lua blocks on the same page
|
||||||
|
share the same context. If one block defines a variable, for example, that
|
||||||
|
variable is visible in the block that follows.
|
||||||
|
|
||||||
|
# Common Problems
|
||||||
|
- PHP doesn't work - getting empty page, or 'File not found' error. The
|
||||||
|
reason for that is wrong paths to the interpreter. Remember that with PHP,
|
||||||
|
correct interpreter is `php-cgi.exe` (`php-cgi` on UNIX). Solution: specify
|
||||||
|
full path to the PHP interpreter, e.g.:
|
||||||
|
`mongoose -cgi_interpreter /full/path/to/php-cgi`
|
||||||
|
|
||||||
|
- Mongoose fails to start. If Mongoose exits immediately when run, this
|
||||||
|
usually indicates a syntax error in the configuration file
|
||||||
|
(named `mongoose.conf` by default) or the command-line arguments.
|
||||||
|
Syntax checking is omitted from Mongoose to keep its size low. However,
|
||||||
|
the Manual should be of help. Note: the syntax changes from time to time,
|
||||||
|
so updating the config file might be necessary after executable update.
|
||||||
|
|
||||||
|
- Embedding with OpenSSL on Windows might fail because of calling convention.
|
||||||
|
To force Mongoose to use `__stdcall` convention, add `/Gz` compilation
|
||||||
|
flag in Visual Studio compiler.
|
||||||
|
|
||||||
|
# Embedding
|
||||||
|
Embedding Mongoose is easy. Copy
|
||||||
|
[mongoose.c](https://github.com/valenok/mongoose/blob/master/mongoose.c) and
|
||||||
|
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h)
|
||||||
|
to your application's source tree and include them in the build. For
|
||||||
|
example, your application's code lives in C++ file `my_app.cpp`, then on UNIX
|
||||||
|
this command embeds Mongoose:
|
||||||
|
|
||||||
|
$ ls
|
||||||
|
my_app.cpp mongoose.c mongoose.h
|
||||||
|
$ g++ my_app.cc mongoose.c -o my_app
|
||||||
|
|
||||||
|
Somewhere in the application code, call `mg_start()` to start the server.
|
||||||
|
Pass configuration options and event handlers to `mg_start()`.
|
||||||
|
Mongoose then calls handlers when certain events happen.
|
||||||
|
For example, when new request arrives, Mongoose calls `begin_request`
|
||||||
|
handler function to let user handle the request. In the handler, user code
|
||||||
|
can get all information about the request -- parsed headers, etcetera.
|
||||||
|
|
||||||
|
Mongoose API is logically divided in three categories: server setup/shutdown
|
||||||
|
functions, functions to be used by user-written event handlers, and
|
||||||
|
convenience utility functions.
|
||||||
|
|
||||||
|
### Starting and stopping embedded web server
|
||||||
|
To start the embedded web server, call `mg_start()`. To stop it, call
|
||||||
|
`mg_stop()`.
|
||||||
|
|
||||||
|
// This structure needs to be passed to mg_start(), to let mongoose know
|
||||||
|
// which callbacks to invoke. For detailed description, see
|
||||||
|
// https://github.com/valenok/mongoose/blob/master/UserManual.md
|
||||||
|
struct mg_callbacks {
|
||||||
|
int (*begin_request)(struct mg_connection *);
|
||||||
|
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
||||||
|
int (*log_message)(const struct mg_connection *, const char *message);
|
||||||
|
int (*init_ssl)(void *ssl_context);
|
||||||
|
int (*websocket_connect)(const struct mg_connection *);
|
||||||
|
void (*websocket_ready)(struct mg_connection *);
|
||||||
|
int (*websocket_data)(struct mg_connection *);
|
||||||
|
const char * (*open_file)(const struct mg_connection *,
|
||||||
|
const char *path, size_t *data_len);
|
||||||
|
void (*init_lua)(struct mg_connection *, void *lua_context);
|
||||||
|
void (*upload)(struct mg_connection *, const char *file_name);
|
||||||
|
int (*http_error)(struct mg_connection *, int status);
|
||||||
|
};
|
||||||
|
|
||||||
|
[hello.c](https://github.com/valenok/mongoose/blob/master/examples/hello.c)
|
||||||
|
provides a minimalistic example.
|
||||||
|
|
||||||
|
Common pattern is to implement `begin_request` callback, and serve static files
|
||||||
|
from memory, and/or construct dynamic replies on the fly. Here is
|
||||||
|
my [embed.c](https://gist.github.com/valenok/4714740) gist
|
||||||
|
that shows how to easily any data can be embedded
|
||||||
|
directly into the executable. If such data needs to be encrypted, then
|
||||||
|
encrypted database or encryption dongles would be a better choice.
|
||||||
|
|
||||||
|
# Build on Android
|
||||||
|
|
||||||
|
This is a small guide to help you run mongoose on Android. Currently it is
|
||||||
|
tested on the HTC Wildfire. If you have managed to run it on other devices
|
||||||
|
as well, please comment or drop an email in the mailing list.
|
||||||
|
Note : You dont need root access to run mongoose on Android.
|
||||||
|
|
||||||
|
- Download the source from the Downloads page.
|
||||||
|
- Download the Android NDK from
|
||||||
|
[here](http://developer.android.com/tools/sdk/ndk/index.html)
|
||||||
|
- Make a folder (e.g. mongoose) and inside that make a folder named "jni".
|
||||||
|
- Add `mongoose.h`, `mongoose.c` and `main.c` from the source to the jni folder.
|
||||||
|
- Make a new file in the jni folder named "Android.mk".
|
||||||
|
This is the make file for ndk-build.
|
||||||
|
|
||||||
|
Android.mk:
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := mongoose
|
||||||
|
LOCAL_SRC_FILES := main.c mongoose.c
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
- Run `./ndk-build -C /path/to/mongoose/`.
|
||||||
|
This should generate mongoose/lib/armeabi/mongoose
|
||||||
|
- Using the adb tool, push the generated mongoose binary to `/data/local`
|
||||||
|
folder on device.
|
||||||
|
- From adb shell, navigate to `/data/local` and execute `./mongoose`.
|
||||||
|
- To test if the server is running fine, visit your web-browser and
|
||||||
|
navigate to `http://127.0.0.1:8080` You should see the `Index of /` page.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- jni stands for Java Native Interface. Read up on Android NDK if you want
|
||||||
|
to know how to interact with the native C functions of mongoose in Android
|
||||||
|
Java applications.
|
||||||
|
- Download android-sdk for the adb tool.
|
||||||
|
- TODO: A Java application that interacts with the native binary or a
|
||||||
|
shared library.
|
||||||
|
|
||||||
|
# Mongoose internals
|
||||||
|
|
||||||
|
Mongoose is multithreaded web server. `mg_start()` function allocates
|
||||||
|
web server context (`struct mg_context`), which holds all information
|
||||||
|
about web server instance:
|
||||||
|
|
||||||
|
- configuration options. Note that mongoose makes internal copies of
|
||||||
|
passed options.
|
||||||
|
- SSL context, if any
|
||||||
|
- user-defined callbacks
|
||||||
|
- opened listening sockets
|
||||||
|
- a queue for accepted sockets
|
||||||
|
- mutexes and condition variables for inter-thread synchronization
|
||||||
|
|
||||||
|
When `mg_start()` returns, all initialization is quaranteed to be complete
|
||||||
|
(e.g. listening ports are opened, SSL is initialized, etc). `mg_start()` starts
|
||||||
|
two threads: a master thread, that accepts new connections, and several
|
||||||
|
worker threads, that process accepted connections. The number of worker threads
|
||||||
|
is configurable via `num_threads` configuration option. That number puts a
|
||||||
|
limit on number of simultaneous requests that can be handled by mongoose.
|
||||||
|
|
||||||
|
When master thread accepts new connection, a new accepted socket (described by
|
||||||
|
`struct socket`) it placed into the accepted sockets queue,
|
||||||
|
which has size of 20 (see [code](https://github.com/valenok/mongoose/blob/3892e0199e6ca9613b160535d9d107ede09daa43/mongoose.c#L486)). Any idle worker thread
|
||||||
|
can grab accepted sockets from that queue. If all worker threads are busy,
|
||||||
|
master thread can accept and queue up to 20 more TCP connections,
|
||||||
|
filling up the queue.
|
||||||
|
In the attempt to queue next accepted connection, master thread blocks
|
||||||
|
until there is space in a queue. When master thread is blocked on a
|
||||||
|
full queue, TCP layer in OS can also queue incoming connection.
|
||||||
|
The number is limited by the `listen()` call parameter on listening socket,
|
||||||
|
which is `SOMAXCONN` in case of Mongoose, and depends on a platform.
|
||||||
|
|
||||||
|
Worker threads are running in an infinite loop, which in simplified form
|
||||||
|
looks something like this:
|
||||||
|
|
||||||
|
static void *worker_thread() {
|
||||||
|
while (consume_socket()) {
|
||||||
|
process_new_connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function `consume_socket()` gets new accepted socket from the mongoose socket
|
||||||
|
queue, atomically removing it from the queue. If the queue is empty,
|
||||||
|
`consume_socket()` blocks and waits until new sockets are placed in a queue
|
||||||
|
by the master thread. `process_new_connection()` actually processes the
|
||||||
|
connection, i.e. reads the request, parses it, and performs appropriate action
|
||||||
|
depending on a parsed request.
|
||||||
|
|
||||||
|
Master thread uses `poll()` and `accept()` to accept new connections on
|
||||||
|
listening sockets. `poll()` is used to avoid `FD_SETSIZE` limitation of
|
||||||
|
`select()`. Since there are only a few listening sockets, there is no reason
|
||||||
|
to use hi-performance alternatives like `epoll()` or `kqueue()`. Worker
|
||||||
|
threads use blocking IO on accepted sockets for reading and writing data.
|
||||||
|
All accepted sockets have `SO_RCVTIMEO` and `SO_SNDTIMEO` socket options set
|
||||||
|
(controlled by `request_timeout_ms` mongoose option, 30 seconds default) which
|
||||||
|
specify read/write timeout on client connection.
|
||||||
|
|
||||||
|
# Other Resources
|
||||||
|
- Presentation made by Arnout Vandecappelle at FOSDEM 2011 on 2011-02-06
|
||||||
|
in Brussels, Belgium, called
|
||||||
|
"Creating secure web based user interfaces for Embedded Devices"
|
||||||
|
([pdf](http://mind.be/content/110206_Web-ui.pdf) |
|
||||||
|
[odp](http://mind.be/content/110206_Web-ui.odp))
|
||||||
|
- Linux Journal article by Michel J.Hammel, 2010-04-01, called
|
||||||
|
[Mongoose: an Embeddable Web Server in C](http://www.linuxjournal.com/article/10680)
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// This is C# example on how to use Mongoose embeddable web server,
|
|
||||||
// http://code.google.com/p/mongoose
|
|
||||||
//
|
|
||||||
// Before using the mongoose module, make sure that Mongoose shared library is
|
|
||||||
// built and present in the current (or system library) directory
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
public class Program {
|
|
||||||
|
|
||||||
// This function is called when user types in his browser http://127.0.0.1:8080/foo
|
|
||||||
static private void UriHandler(MongooseConnection conn, MongooseRequestInfo ri) {
|
|
||||||
conn.write("HTTP/1.1 200 OK\r\n\r\n");
|
|
||||||
conn.write("Hello from C#!\n");
|
|
||||||
conn.write("Your user-agent is: " + conn.get_header("User-Agent") + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static private void UriDumpInfo(MongooseConnection conn, MongooseRequestInfo ri)
|
|
||||||
{
|
|
||||||
conn.write("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
|
|
||||||
conn.write("<html><body><head>Calling Info</head>");
|
|
||||||
conn.write("<p>Request: " + ri.request_method + "</p>");
|
|
||||||
conn.write("<p>URI: " + ri.uri + "</p>");
|
|
||||||
conn.write("<p>Query: " + ri.query_string + "</p>");
|
|
||||||
if (ri.post_data_len > 0) conn.write("<p>Post(" + ri.post_data_len + ")[@" + ri.post_data + "]: '" + Marshal.PtrToStringAnsi(ri.post_data) + "'</p>");
|
|
||||||
conn.write("<p>User:" + ri.remote_user + "</p>");
|
|
||||||
conn.write("<p>IP: " + ri.remote_ip + "</p>");
|
|
||||||
conn.write("<p>HTTP: " + ri.http_version + "</p>");
|
|
||||||
conn.write("<p>Port: " + ri.remote_port + "</p>");
|
|
||||||
conn.write("<p>NUM Headers: " + ri.num_headers + "</p>");
|
|
||||||
for (int i = 0; i < Math.Min(64, ri.num_headers); i++)
|
|
||||||
{
|
|
||||||
conn.write("<p>" + i + ":" + Marshal.PtrToStringAnsi(ri.http_headers[i].name)
|
|
||||||
+ ":" + Marshal.PtrToStringAnsi(ri.http_headers[i].value) + "</p>");
|
|
||||||
}
|
|
||||||
conn.write("</body></html>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Main() {
|
|
||||||
Mongoose web_server = new Mongoose();
|
|
||||||
|
|
||||||
// Set options and /foo URI handler
|
|
||||||
web_server.set_option("ports", "8080");
|
|
||||||
web_server.set_option("root", "c:\\");
|
|
||||||
web_server.set_uri_callback("/foo", new MongooseCallback(UriHandler));
|
|
||||||
web_server.set_uri_callback("/dumpinfo", new MongooseCallback(UriDumpInfo));
|
|
||||||
|
|
||||||
// Serve requests until user presses "enter" on a keyboard
|
|
||||||
Console.ReadLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
// Copyright (c) 2004-2009 Sergey Lyubka
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// $Id: mongoose.cs 472 2009-08-30 22:40:29Z spsone1 $
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)] public struct MongooseHeader {
|
|
||||||
public IntPtr name; // Using IntPtr here because if we use strings here,
|
|
||||||
public IntPtr value; // it won't be properly marshalled.
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is "struct mg_request_info" from mongoose.h header file
|
|
||||||
[StructLayout(LayoutKind.Sequential)] public struct MongooseRequestInfo {
|
|
||||||
public string request_method;
|
|
||||||
public string uri;
|
|
||||||
public string http_version;
|
|
||||||
public string query_string;
|
|
||||||
public IntPtr post_data;
|
|
||||||
public string remote_user;
|
|
||||||
public int remote_ip; //int to match the 32bit declaration in c
|
|
||||||
public int remote_port;
|
|
||||||
public int post_data_len;
|
|
||||||
public int status_code;
|
|
||||||
public int num_headers;
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray,SizeConst=64)] public MongooseHeader[] http_headers;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a delegate for mg_callback_t from mongoose.h header file
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
||||||
public delegate void MongooseCallback2(IntPtr conn, ref MongooseRequestInfo ri, IntPtr user_data);
|
|
||||||
|
|
||||||
// This is a delegate to be used by the application
|
|
||||||
public delegate void MongooseCallback(MongooseConnection conn, MongooseRequestInfo ri);
|
|
||||||
|
|
||||||
public class Mongoose {
|
|
||||||
public string version;
|
|
||||||
private IntPtr ctx;
|
|
||||||
//These two events are here to store a ref to the callbacks while they are over in unmanaged code.
|
|
||||||
private event MongooseCallback2 delegates2;
|
|
||||||
private event MongooseCallback delegates1;
|
|
||||||
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern IntPtr mg_start();
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_stop(IntPtr ctx);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_version();
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern int mg_set_option(IntPtr ctx, string name, string value);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_option(IntPtr ctx, string name);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_set_uri_callback(IntPtr ctx, string uri_regex, MulticastDelegate func, IntPtr data);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_set_log_callback(IntPtr ctx, MulticastDelegate func);
|
|
||||||
|
|
||||||
public Mongoose() {
|
|
||||||
ctx = mg_start();
|
|
||||||
version = mg_version();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Mongoose() {
|
|
||||||
mg_stop(this.ctx);
|
|
||||||
this.ctx = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int set_option(string option_name, string option_value) {
|
|
||||||
return mg_set_option(this.ctx, option_name, option_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string get_option(string option_name) {
|
|
||||||
return mg_get_option(this.ctx, option_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set_uri_callback(string uri_regex, MongooseCallback func) {
|
|
||||||
// Build a closure around user function. Initialize connection object there which wraps
|
|
||||||
// mg_write() and other useful methods, and then call user specified handler.
|
|
||||||
MongooseCallback2 callback = delegate(IntPtr conn, ref MongooseRequestInfo ri, IntPtr user_data) {
|
|
||||||
MongooseConnection connection = new MongooseConnection(conn, this);
|
|
||||||
func(connection, ri);
|
|
||||||
};
|
|
||||||
// store a reference to the callback so it won't be GC'ed while its over in unmanged code
|
|
||||||
delegates2 += callback;
|
|
||||||
mg_set_uri_callback(this.ctx, uri_regex, callback, IntPtr.Zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set_log_callback(MongooseCallback func) {
|
|
||||||
delegates1 += func;
|
|
||||||
mg_set_log_callback(this.ctx, func);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MongooseConnection {
|
|
||||||
public Mongoose mongoose;
|
|
||||||
private IntPtr conn;
|
|
||||||
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_header(IntPtr ctx, string name);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern string mg_get_var(IntPtr ctx, string name);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern void mg_free(IntPtr ptr);
|
|
||||||
[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] public static extern int mg_write(IntPtr conn, string data, int length);
|
|
||||||
|
|
||||||
public MongooseConnection(IntPtr conn_, Mongoose mongoose_) {
|
|
||||||
mongoose = mongoose_;
|
|
||||||
conn = conn_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string get_header(string header_name) {
|
|
||||||
return mg_get_header(this.conn, header_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string get_var(string header_name) {
|
|
||||||
string s = mg_get_var(this.conn, header_name);
|
|
||||||
string copy = "" + s;
|
|
||||||
mg_free(Marshal.StringToHGlobalAnsi(s));
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int write(string data) {
|
|
||||||
return mg_write(this.conn, data, data.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
# This is Python example on how to use Mongoose embeddable web server,
|
|
||||||
# http://code.google.com/p/mongoose
|
|
||||||
#
|
|
||||||
# Before using the mongoose module, make sure that Mongoose shared library is
|
|
||||||
# built and present in the current (or system library) directory
|
|
||||||
|
|
||||||
import mongoose
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Handle /show and /form URIs.
|
|
||||||
def EventHandler(event, conn):
|
|
||||||
info = conn.info
|
|
||||||
if event == mongoose.HTTP_ERROR:
|
|
||||||
conn.printf('%s', 'HTTP/1.0 200 OK\r\n')
|
|
||||||
conn.printf('%s', 'Content-Type: text/plain\r\n\r\n')
|
|
||||||
conn.printf('HTTP error: %d\n', info.status_code)
|
|
||||||
return True
|
|
||||||
elif event == mongoose.NEW_REQUEST and info.uri == '/show':
|
|
||||||
conn.printf('%s', 'HTTP/1.0 200 OK\r\n')
|
|
||||||
conn.printf('%s', 'Content-Type: text/plain\r\n\r\n')
|
|
||||||
conn.printf('%s %s\n', info.request_method, info.uri)
|
|
||||||
if info.request_method == 'POST':
|
|
||||||
content_len = conn.get_header('Content-Length')
|
|
||||||
post_data = conn.read(int(content_len))
|
|
||||||
my_var = conn.get_var(post_data, 'my_var')
|
|
||||||
else:
|
|
||||||
my_var = conn.get_var(info.query_string, 'my_var')
|
|
||||||
conn.printf('my_var: %s\n', my_var or '<not set>')
|
|
||||||
conn.printf('HEADERS: \n')
|
|
||||||
for header in info.http_headers[:info.num_headers]:
|
|
||||||
conn.printf(' %s: %s\n', header.name, header.value)
|
|
||||||
return True
|
|
||||||
elif event == mongoose.NEW_REQUEST and info.uri == '/form':
|
|
||||||
conn.write('HTTP/1.0 200 OK\r\n'
|
|
||||||
'Content-Type: text/html\r\n\r\n'
|
|
||||||
'Use GET: <a href="/show?my_var=hello">link</a>'
|
|
||||||
'<form action="/show" method="POST">'
|
|
||||||
'Use POST: type text and submit: '
|
|
||||||
'<input type="text" name="my_var"/>'
|
|
||||||
'<input type="submit"/>'
|
|
||||||
'</form>')
|
|
||||||
return True
|
|
||||||
elif event == mongoose.NEW_REQUEST and info.uri == '/secret':
|
|
||||||
conn.send_file('/etc/passwd')
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# Create mongoose object, and register '/foo' URI handler
|
|
||||||
# List of options may be specified in the contructor
|
|
||||||
server = mongoose.Mongoose(EventHandler,
|
|
||||||
document_root='/tmp',
|
|
||||||
listening_ports='8080')
|
|
||||||
|
|
||||||
print ('Mongoose started on port %s, press enter to quit'
|
|
||||||
% server.get_option('listening_ports'))
|
|
||||||
|
|
||||||
sys.stdin.read(1)
|
|
||||||
|
|
||||||
# Deleting server object stops all serving threads
|
|
||||||
print 'Stopping server.'
|
|
||||||
del server
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
# Copyright (c) 2004-2009 Sergey Lyubka
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
#
|
|
||||||
# $Id: mongoose.py 471 2009-08-30 14:30:21Z valenok $
|
|
||||||
|
|
||||||
"""
|
|
||||||
This module provides python binding for the Mongoose web server.
|
|
||||||
|
|
||||||
There are two classes defined:
|
|
||||||
|
|
||||||
Connection: - wraps all functions that accept struct mg_connection pointer
|
|
||||||
as first argument.
|
|
||||||
|
|
||||||
Mongoose: wraps all functions that accept struct mg_context pointer as
|
|
||||||
first argument.
|
|
||||||
|
|
||||||
Creating Mongoose object automatically starts server, deleting object
|
|
||||||
automatically stops it. There is no need to call mg_start() or mg_stop().
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import ctypes
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
NEW_REQUEST = 0
|
|
||||||
HTTP_ERROR = 1
|
|
||||||
EVENT_LOG = 2
|
|
||||||
INIT_SSL = 3
|
|
||||||
|
|
||||||
|
|
||||||
class mg_header(ctypes.Structure):
|
|
||||||
"""A wrapper for struct mg_header."""
|
|
||||||
_fields_ = [
|
|
||||||
('name', ctypes.c_char_p),
|
|
||||||
('value', ctypes.c_char_p),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class mg_request_info(ctypes.Structure):
|
|
||||||
"""A wrapper for struct mg_request_info."""
|
|
||||||
_fields_ = [
|
|
||||||
('user_data', ctypes.c_char_p),
|
|
||||||
('request_method', ctypes.c_char_p),
|
|
||||||
('uri', ctypes.c_char_p),
|
|
||||||
('http_version', ctypes.c_char_p),
|
|
||||||
('query_string', ctypes.c_char_p),
|
|
||||||
('remote_user', ctypes.c_char_p),
|
|
||||||
('log_message', ctypes.c_char_p),
|
|
||||||
('remote_ip', ctypes.c_long),
|
|
||||||
('remote_port', ctypes.c_int),
|
|
||||||
('status_code', ctypes.c_int),
|
|
||||||
('is_ssl', ctypes.c_int),
|
|
||||||
('num_headers', ctypes.c_int),
|
|
||||||
('http_headers', mg_header * 64),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
mg_callback_t = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p)
|
|
||||||
|
|
||||||
|
|
||||||
class Connection(object):
|
|
||||||
"""A wrapper class for all functions that take
|
|
||||||
struct mg_connection * as the first argument."""
|
|
||||||
|
|
||||||
def __init__(self, mongoose, connection):
|
|
||||||
self.m = mongoose
|
|
||||||
self.conn = ctypes.c_void_p(connection)
|
|
||||||
self.info = self.m.dll.mg_get_request_info(self.conn).contents
|
|
||||||
|
|
||||||
def get_header(self, name):
|
|
||||||
val = self.m.dll.mg_get_header(self.conn, name)
|
|
||||||
return ctypes.c_char_p(val).value
|
|
||||||
|
|
||||||
def get_var(self, data, name):
|
|
||||||
size = data and len(data) or 0
|
|
||||||
buf = ctypes.create_string_buffer(size)
|
|
||||||
n = self.m.dll.mg_get_var(data, size, name, buf, size)
|
|
||||||
return n >= 0 and buf or None
|
|
||||||
|
|
||||||
def printf(self, fmt, *args):
|
|
||||||
val = self.m.dll.mg_printf(self.conn, fmt, *args)
|
|
||||||
return ctypes.c_int(val).value
|
|
||||||
|
|
||||||
def write(self, data):
|
|
||||||
val = self.m.dll.mg_write(self.conn, data, len(data))
|
|
||||||
return ctypes.c_int(val).value
|
|
||||||
|
|
||||||
def read(self, size):
|
|
||||||
buf = ctypes.create_string_buffer(size)
|
|
||||||
n = self.m.dll.mg_read(self.conn, buf, size)
|
|
||||||
return n <= 0 and None or buf[:n]
|
|
||||||
|
|
||||||
def send_file(self, path):
|
|
||||||
self.m.dll.mg_send_file(self.conn, path)
|
|
||||||
|
|
||||||
|
|
||||||
class Mongoose(object):
|
|
||||||
"""A wrapper class for Mongoose shared library."""
|
|
||||||
|
|
||||||
def __init__(self, callback, **kwargs):
|
|
||||||
if os.name == 'nt':
|
|
||||||
self.dll = ctypes.WinDLL('_mongoose.dll')
|
|
||||||
else:
|
|
||||||
self.dll = ctypes.CDLL('_mongoose.so')
|
|
||||||
|
|
||||||
self.dll.mg_start.restype = ctypes.c_void_p
|
|
||||||
self.dll.mg_modify_passwords_file.restype = ctypes.c_int
|
|
||||||
self.dll.mg_read.restype = ctypes.c_int
|
|
||||||
self.dll.mg_write.restype = ctypes.c_int
|
|
||||||
self.dll.mg_printf.restype = ctypes.c_int
|
|
||||||
self.dll.mg_get_header.restype = ctypes.c_char_p
|
|
||||||
self.dll.mg_get_var.restype = ctypes.c_int
|
|
||||||
self.dll.mg_get_cookie.restype = ctypes.c_int
|
|
||||||
self.dll.mg_get_option.restype = ctypes.c_char_p
|
|
||||||
self.dll.mg_get_request_info.restype = ctypes.POINTER(mg_request_info)
|
|
||||||
|
|
||||||
if callback:
|
|
||||||
# Create a closure that will be called by the shared library.
|
|
||||||
def func(event, connection):
|
|
||||||
# Wrap connection pointer into the connection
|
|
||||||
# object and call Python callback
|
|
||||||
conn = Connection(self, connection)
|
|
||||||
return callback(event, conn) and 1 or 0
|
|
||||||
|
|
||||||
# Convert the closure into C callable object
|
|
||||||
self.callback = mg_callback_t(func)
|
|
||||||
self.callback.restype = ctypes.c_char_p
|
|
||||||
else:
|
|
||||||
self.callback = ctypes.c_void_p(0)
|
|
||||||
|
|
||||||
args = [y for x in kwargs.items() for y in x] + [None]
|
|
||||||
options = (ctypes.c_char_p * len(args))(*args)
|
|
||||||
|
|
||||||
ret = self.dll.mg_start(self.callback, 0, options)
|
|
||||||
self.ctx = ctypes.c_void_p(ret)
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
"""Destructor, stop Mongoose instance."""
|
|
||||||
self.dll.mg_stop(self.ctx)
|
|
||||||
|
|
||||||
def get_option(self, name):
|
|
||||||
return self.dll.mg_get_option(self.ctx, name)
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key> <string>Mongoose</string>
|
||||||
|
<key>CFBundlePackageType</key> <string>APPL</string>
|
||||||
|
<key>CFBundleTypeRole</key> <string>None</string>
|
||||||
|
<key>CFBundleIconFiles</key> <array>
|
||||||
|
<string>mongoose_16x16.png</string>
|
||||||
|
<string>mongoose_22x22.png</string>
|
||||||
|
<string>mongoose_32x32.png</string>
|
||||||
|
<string>mongoose_64x64.png</string>
|
||||||
|
</array>
|
||||||
|
<key>LSUIElement</key> <true/>
|
||||||
|
<key>RunAtLoad</key> <true/>
|
||||||
|
<key>Label</key> <string>com.kolkin.mongoose</string>
|
||||||
|
<key>ProgramArguments</key> <array> </array>
|
||||||
|
<key>KeepAlive</key> <true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
File renamed without changes.
+1885
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,589 @@
|
|||||||
|
%PDF-1.5␍%âãÏÓ
|
||||||
|
1 0 obj␍<</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R]/Order 6 0 R/RBGroups[]>>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>>␍endobj␍2 0 obj␍<</Length 16195/Subtype/XML/Type/Metadata>>stream
|
||||||
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.3-c011 66.145661, 2012/02/06-14:56:27 ">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
||||||
|
xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
|
||||||
|
<xmp:CreatorTool>Adobe Illustrator CS6 (Windows)</xmp:CreatorTool>
|
||||||
|
<xmp:CreateDate>2013-01-02T17:27:47+01:00</xmp:CreateDate>
|
||||||
|
<xmp:ModifyDate>2013-01-02T17:27:47Z</xmp:ModifyDate>
|
||||||
|
<xmp:MetadataDate>2013-01-02T17:27:47Z</xmp:MetadataDate>
|
||||||
|
<xmp:Thumbnails>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<xmpGImg:width>256</xmpGImg:width>
|
||||||
|
<xmpGImg:height>228</xmpGImg:height>
|
||||||
|
<xmpGImg:format>JPEG</xmpGImg:format>
|
||||||
|
<xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA5AEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FVsssUUbSyuscSAs7sQqqo3JJPQDFWOL+ZXk
Rrj6uNat/UrTkSQn/Iwjh+OR4wx4wyG3ube4iEtvKk0TfZkjYMp+RFRkmSpirsVYj+ZvnFfLPl2R
4XA1O8rDYr3BI+KT5IPxpkJyoMJyoI38vbs3fknRZmbkwtY4yx3NYh6f/GuGPJMeTIckydirsVdi
rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVeG/nX55mutQby3YSlbO1I+v
lD/eTdfTNP2Y+4/m+WUZJdGnJLoiX/Lfybo/5fxavr31prq4SCWS4t6c4WnA4osbHgVUt8Vdz2pj
wgCyvAAN3nd9aW1gzXGiayLmDvx9S1uFB2AaNqBuv7DNkGs+SyHzf5sh/utavkFa0W5mA29uWPEV
4ijI/wAxfPMYIXW7o1/mfl/xKuHjKeMpbrfmLW9cnjn1a7e7liT042eg4rWuwUAfTgJJQSS9/wDy
ZufW/L+xStTBJPEf+RrOPwfL8fJvx8mb5Nm7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FUr8063Hofl6/1V6H6rEWjU9GkPwxqf8AWdgMEjQRI0Hy9pdhqHmHX4LRGMt7
qM/xyHclnPJ5G+QqxzF5uMBZer/n3fww6bpek290EKsXmsFO5jVQsbt7KQQK9foy3IejblLxbKml
2KuxV2KvWvyR8721lI3lq9pGl1KZbGc7fvWAUxN/rcRx99u4y3HLo245dHtuXNzsVdirsVdirsVd
irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVeffnjfRQeSGt2I53lxFGi9/gJkJ/4TK8
h2a8h2Yl+TWn6RpNrdebNauYrSM8rawaZgtQN5XUHdidlFPfIY6G5Y4xW5YP5+vtM1DzZf32m3cl
7aXL+ok0oYEEihQc6HitKL7ZCXNhI7sewMUw0bQNZ1q5a30u0e6lQcnCUAVfFmYhVHzOICQCUZfe
SPNVlA9xNp0j28ZIkngKXEakdeTwmRRT3ONJMCEjxYqlupaZaMU4/EXHUBRyJHuAMVfR35U+cbjz
L5ff63ve2DiCaQmpkUrVHbp8RGx9xmRCVhyISsM1ybN2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku
xV2KuxV2KuxV2KuxV2KuxV87/nF5wi13zAtlZvz0/S+USOD8LzMf3jj2FAo+Ve+Y+SVlx8krLAmd
2ChmJCiigmtBWtBkGC3FXYqyifzCLv8AK++8qaYq2GryTJK8wf0xexcqvG0jEBWApsTxYCnU0MMt
mFDm5OCYB3Tb/nHLyP590bzNdahqNpPpujPbFJYriqCeRipj4xk78dzzp7d8r0eKYlZ2DlZZAhEf
nXp3ly18wRzaXNEL2YN+kbOL9hxTi54/CrPXcde/fMrIBezgZALedxuyOrrsykEfRkGt67+QV2qa
nq1on93cwxzotfsmFirD/ksPwy3EW3E9oy5udirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV
dirsVdirsVdiryD80PzahWGbQ/LsweVwY7zUIzVVU7FIWHUnuw6dt9xVOfQNU59A8XylpdirsVdi
rsVTy287+bbXTf0Zb6rcRWQHFYlehVT+yrfaUewOHiLLiKSMxYlmJLE1JPUnAxZ9+UXkjSvM2o3s
mqgyWlgkZ+rKxTm8palWUhuICHofDJwjZbMcbet6f+XuheX9QXVtAhktpkHCe2EjyRywtTmtJC7c
h9pd+op0y3grcNoiByZbk2TsVdirsVdirsVdirsVdirsVdirsVdirsVdirH9Z8/eT9HLJfapCsq7
NDGTNID4FIw5H05EyAYmQDDtR/P7y9CzLYafc3ZHRpCkKk+3941PmMgcoYHKEof/AJyFuix4aGgX
sDcEn7/TGDxUeK0v/OQt3yHLRIytdwLgg0+fpnHxV8VHW3/OQmntT6zo00Xj6Uyyf8SWPD4qfFTQ
fnx5ONs0noXgmUfDA0aVY+HIOVw+KE+IHm3nL82PMXmNHtYyNO0xtjawsSzjwlk2LfIAD2yuUyWu
UyWEZBg7FXYq7FXYq7FV8cMktfTXkR+yOv0DqfoxV0kMsRAkRkJFQGBFR9OKsl/LzzbeeWdeF3FC
9zayr6d7boKkx1ryX/KU7j7u+GMqLKEqL3fR/P2m69epZaNDcSOV9S5nliaKOGMdal/tOTsoAP3D
LxO+TeJWyjJsnYq7FXYq7FXYq7FXYq7FXYq7FXYqoXt9ZWNs91ezx21vGKvLKwRR9JxtbeZeZvz3
0q1LwaBbG/lG31qascHzVdnf/hcqOXuajk7nl2v/AJgebddLLfajJ6Df8esJ9KKngVSnL/ZVysyJ
azIljuRYuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVWt3uSwhh5OZCAIQOYZjsPg3BP0Yq9G8r/k1
5l1f059bkOl2H2hAQPXI/wAmIfDH/st/bLI4yebYMZPN7H5Z8paH5as2tdKg9ISEGaViWkkZdgXY
/PoNsuEQG4RATjCl2KuxV2KuxV2KuxV2KuxV2KuxVgvnv819I8t87K0Av9YGxgU/u4j/AMWsO/8A
kjfxpkJTphKdPCfMXmrXfMN39Z1W6aYgn0oR8MUYPZEGw+fU98oMiWgyJSjAh2KuxV2KuxV2KuxV
2KuxV2KuxV2KuxV2KuxV2KvS/wAh9LW581XN861WxtjwPhJKwUH/AIDllmIbtmMbvfMvb3Yq7FXY
q7FXYq7FXYq7FXYq7FXYq8p/Nb803055NB0KUfXaFb68U1MNdjGh/wB+eJ/Z+fSqc+gapz6B4ezM
zFmJZmNSTuSTlLS1irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir3D/nH2y4aPq17T+/uI
4a/8YU5f8zsuxN2J6vlra7FXYq7FXYq7FXYq7FXYq7FXYqwX81fPv+GtJFpZOP0zfKRB3MUfRpSP
Hsvv8shOVMJyp85szOxdyWZjVmO5JPUk5juO1irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV
dirsVfTH5TaQ+meRdPWReMt2Gu3H/GY1T/knxzIgKDkQFBl+TZuxV2KuxV2KuxV2KuxV2KuxVC6p
qVppenXOoXb8La1jaSVvZR0HuegwE0gmnyt5m8wXnmDW7rVbs/HO3wR9QkY2RB/qrmMTZcYmyleB
DsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVT7yR5Zm8x+Y7TTUB9At6l24/ZgQ1c/T9k
e5wxFllEWX1PHGkcaxxqFjQBUUbAACgAzKcldirsVdirsVdirsVdirsVdirsVeO/nz5pIFt5bt32
YC5vqHtX91Gfu5Ef6uU5ZdGnLLo8aypqdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs
VfR35T+Sf8OaF9Zu4+OragFkuARvHH1SL2IrVvf5ZkQjQciEaDOcmzdirsVdirsVdirsVdirsVdi
qld3UFpazXVwwSC3RpZXPRUQFmP0AYq+TvMOsz61rd7qs/8AeXcrSBf5V6Iv+xUAZik2XFJspdgQ
7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXqH5M+Qjqd6PMOoR/7j7N/9DjYbSzr+1v1
WP8A4l8jlmON7tmON7vd8vb3YLine truncated
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</xmp:Thumbnails>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
|
||||||
|
xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
|
||||||
|
xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
|
||||||
|
<xmpTPg:NPages>1</xmpTPg:NPages>
|
||||||
|
<xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
|
||||||
|
<xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
|
||||||
|
<xmpTPg:MaxPageSize rdf:parseType="Resource">
|
||||||
|
<stDim:w>64.000000</stDim:w>
|
||||||
|
<stDim:h>64.000000</stDim:h>
|
||||||
|
<stDim:unit>Points</stDim:unit>
|
||||||
|
</xmpTPg:MaxPageSize>
|
||||||
|
<xmpTPg:PlateNames>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>Cyan</rdf:li>
|
||||||
|
<rdf:li>Magenta</rdf:li>
|
||||||
|
<rdf:li>Yellow</rdf:li>
|
||||||
|
<rdf:li>Black</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</xmpTPg:PlateNames>
|
||||||
|
<xmpTPg:SwatchGroups>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li rdf:parseType="Resource">
|
||||||
|
<xmpG:groupName>Default Swatch Group</xmpG:groupName>
|
||||||
|
<xmpG:groupType>0</xmpG:groupType>
|
||||||
|
</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</xmpTPg:SwatchGroups>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
|
||||||
|
<illustrator:Type>Document</illustrator:Type>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<dc:format>application/pdf</dc:format>
|
||||||
|
<dc:title>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Mongoo 3 smooth green</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:title>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
|
||||||
|
<xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
|
||||||
|
<xmpMM:DocumentID>uuid:a2f6b830-2598-49b9-8770-4f9fa14f1be3</xmpMM:DocumentID>
|
||||||
|
<xmpMM:InstanceID>uuid:42245d04-b042-4038-b450-94c7cfb8ee6f</xmpMM:InstanceID>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
|
||||||
|
<pdf:Producer>Adobe PDF library 10.01</pdf:Producer>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?xpacket end="w"?>
|
||||||
|
endstream␍endobj␍3 0 obj␍<</Count 1/Kids[7 0 R]/Type/Pages>>␍endobj␍7 0 obj␍<</ArtBox[0.643066 4.46875 63.2324 59.6494]/BleedBox[0.0 0.0 64.0 64.0]/Contents 8 0 R/LastModified(D:20130102172747+01'00')/MediaBox[0.0 0.0 64.0 64.0]/Parent 3 0 R/PieceInfo<</Illustrator 9 0 R>>/Resources<</ExtGState<</GS0 10 0 R>>/Properties<</MC0 5 0 R>>>>/Thumb 11 0 R/TrimBox[0.0 0.0 64.0 64.0]/Type/Page>>␍endobj␍8 0 obj␍<</Filter/FlateDecode/Length 1251>>stream
|
||||||
|
H‰t–KŽ•7…çÿ*¼�kì²]¶§!#Y@+�A "±û|§Ü}i"E4}»ü¨Ç©SÇ÷Õ¯¯Ó«·¯Kúéç×éú|•ä]?7þùãú=ýu•Ül¤’»u~7éˇëÕ›÷%}øûúœj*ü«©ö<gÉfÞ{zøtiãÓu«yøL–K[øÍ¥®ÄRK_ÙÂoÌb5ÝêÊ}Xº�\pp«5ouµ§‡ëÖòžø°�}�ÔKøºÕ�7Oß.㪱P
|
||||||
|
Õ¼†‡Ûʹ¯—åÞ,üY›ªhN,Ï«,,ëºjyt#V˶å»äéÆîZ-vw_©åÚ”é¬ÅÙ™{ìŽ<¨¥äíÖÄ/‡ÌG˜»ê°NùЏըÙ#�Îåª"
|
||||||
|
Þw\¨»§ÇËH;ʹ�•¬e¯Ç¡¨qùýþC€Pq¸ù°D,OrµžW·€Ö÷ÔiúÑçk¢EÓmåmç|9Φ%eÒ´Õ,"�CºÍ<F�¬¦ºÛÆÒ�ä¶:Y)žÍ¥;Í6•¨¤h#‘¢À8âɆæŽ>Ò»\µ¢(JØ\›^v@_ÈŸ=,ñ<•Ûf€³pÒÈÐOǽˆ!,L÷XèKå²ÐK‹nP.6mj~X±ì,¬ÚO»è. 6oDh:�œw:ĉ G‡a÷Ȃh½žŠ`ÖhJ˃,¿ÊÁò㱪€1³G›j 'ž6ì„55WÌ`mu��¢¼E*âdžpƒyé\„—¤×-C*�ß›s�ÐД'ÜÁ"=E‚N’ÕÓS¹¥B€à¤êÇ«“ÇàôŽšî64nSxq~Žž åÄŸî×%›D£†³SMSqXcXÕöV¹␍Ö[¶&Žê–è)øÜ¼˜ì…~¨␍H–8Â]@ôVí">vñ°„Ikw»,ãP0QºIl†§k[jHž ñªaµc¸èg-¢2*u]Ù | ||||||