mirror of
https://github.com/lammertb/libhttp.git
synced 2025-07-31 08:24:23 +03:00
Renamed to Civetweb
This commit is contained in:
48
Makefile
48
Makefile
@ -1,5 +1,5 @@
|
|||||||
# This Makefile is part of Mongoose web server project,
|
# This Makefile is part of Civetweb web server project,
|
||||||
# https://github.com/valenok/mongoose
|
# https://github.com/valenok/civetweb
|
||||||
#
|
#
|
||||||
# Example custom build:
|
# Example custom build:
|
||||||
# COPT="-g -O0 -DNO_SSL_DL -DUSE_LUA -llua -lcrypto -lssl" make linux
|
# COPT="-g -O0 -DNO_SSL_DL -DUSE_LUA -llua -lcrypto -lssl" make linux
|
||||||
@ -14,13 +14,13 @@
|
|||||||
# -DCONFIG_FILE=\"file\" - use `file' as the default config file
|
# -DCONFIG_FILE=\"file\" - use `file' as the default config file
|
||||||
# -DSSL_LIB=\"libssl.so.<version>\" - use system versioned SSL shared object
|
# -DSSL_LIB=\"libssl.so.<version>\" - use system versioned SSL shared object
|
||||||
# -DCRYPTO_LIB=\"libcrypto.so.<version>\" - use system versioned CRYPTO so
|
# -DCRYPTO_LIB=\"libcrypto.so.<version>\" - use system versioned CRYPTO so
|
||||||
# -DUSE_LUA - embed Lua in Mongoose (+100kb)
|
# -DUSE_LUA - embed Lua in Civetweb (+100kb)
|
||||||
|
|
||||||
PROG = mongoose
|
PROG = civetweb
|
||||||
CFLAGS = -std=c99 -O2 -W -Wall -pedantic -pthread -pipe $(COPT)
|
CFLAGS = -std=c99 -O2 -W -Wall -pedantic -pthread -pipe $(COPT)
|
||||||
|
|
||||||
# To build with Lua, download and unzip Lua 5.2.1 source code into the
|
# To build with Lua, download and unzip Lua 5.2.1 source code into the
|
||||||
# mongoose directory, and then add $(LUA_SOURCES) to CFLAGS
|
# civetweb directory, and then add $(LUA_SOURCES) to CFLAGS
|
||||||
LUA = lua-5.2.1/src
|
LUA = lua-5.2.1/src
|
||||||
LUA_FLAGS = -I$(LUA) -DLUA_COMPAT_ALL
|
LUA_FLAGS = -I$(LUA) -DLUA_COMPAT_ALL
|
||||||
LUA_SOURCES = $(LUA)/lapi.c $(LUA)/lcode.c $(LUA)/lctype.c \
|
LUA_SOURCES = $(LUA)/lapi.c $(LUA)/lcode.c $(LUA)/lctype.c \
|
||||||
@ -65,17 +65,17 @@ YASSL_SOURCES = \
|
|||||||
$(YASSL)/ctaocrypt/src/ecc.c $(YASSL)/src/ocsp.c $(YASSL)/src/crl.c \
|
$(YASSL)/ctaocrypt/src/ecc.c $(YASSL)/src/ocsp.c $(YASSL)/src/crl.c \
|
||||||
$(YASSL)/ctaocrypt/src/hc128.c $(YASSL)/ctaocrypt/src/memory.c
|
$(YASSL)/ctaocrypt/src/hc128.c $(YASSL)/ctaocrypt/src/memory.c
|
||||||
|
|
||||||
ALL_SOURCES = main.c mongoose.c build/sqlite3.c build/lsqlite3.c \
|
ALL_SOURCES = main.c civetweb.c build/sqlite3.c build/lsqlite3.c \
|
||||||
$(LUA_SOURCES) $(YASSL_SOURCES)
|
$(LUA_SOURCES) $(YASSL_SOURCES)
|
||||||
ALL_OBJECTS = $(ALL_SOURCES:%.c=%.o)
|
ALL_OBJECTS = $(ALL_SOURCES:%.c=%.o)
|
||||||
ALL_WINOBJS = $(ALL_SOURCES:%.c=%.obj)
|
ALL_WINOBJS = $(ALL_SOURCES:%.c=%.obj)
|
||||||
|
|
||||||
SQLITE_FLAGS = -DTHREADSAFE=1 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
SQLITE_FLAGS = -DTHREADSAFE=1 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
||||||
MONGOOSE_FLAGS = -DNO_SSL_DL -DUSE_LUA -DUSE_LUA_SQLITE3 $(COPT)
|
CIVETWEB_FLAGS = -DNO_SSL_DL -DUSE_LUA -DUSE_LUA_SQLITE3 $(COPT)
|
||||||
|
|
||||||
FLAGS = $(MONGOOSE_FLAGS) $(SQLITE_FLAGS) $(YASSL_FLAGS) $(LUA_FLAGS)
|
FLAGS = $(CIVETWEB_FLAGS) $(SQLITE_FLAGS) $(YASSL_FLAGS) $(LUA_FLAGS)
|
||||||
|
|
||||||
# Using Visual Studio 6.0. To build Mongoose:
|
# Using Visual Studio 6.0. To build Civetweb:
|
||||||
# Set MSVC variable below to where VS 6.0 is installed on your system
|
# Set MSVC variable below to where VS 6.0 is installed on your system
|
||||||
# Run "PATH_TO_VC6\bin\nmake windows"
|
# Run "PATH_TO_VC6\bin\nmake windows"
|
||||||
MSVC = ../vc6
|
MSVC = ../vc6
|
||||||
@ -102,24 +102,24 @@ lua.lib: $(LUA_WINOBJS)
|
|||||||
linux_lua: $(ALL_OBJECTS)
|
linux_lua: $(ALL_OBJECTS)
|
||||||
$(CC) $(ALL_OBJECTS) -o $(PROG) -ldl
|
$(CC) $(ALL_OBJECTS) -o $(PROG) -ldl
|
||||||
|
|
||||||
mongoose.o: mod_lua.c
|
civetweb.o: mod_lua.c
|
||||||
|
|
||||||
# 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 main.c -o $(PROG) -ldl $(CFLAGS)
|
$(CC) civetweb.c main.c -o $(PROG) -ldl $(CFLAGS)
|
||||||
|
|
||||||
mac: bsd
|
mac: bsd
|
||||||
bsd:
|
bsd:
|
||||||
$(CC) mongoose.c main.c -o $(PROG) $(CFLAGS)
|
$(CC) civetweb.c main.c -o $(PROG) $(CFLAGS)
|
||||||
|
|
||||||
bsd_lua: $(ALL_OBJECTS)
|
bsd_lua: $(ALL_OBJECTS)
|
||||||
$(CC) $(ALL_OBJECTS) -o $@
|
$(CC) $(ALL_OBJECTS) -o $@
|
||||||
|
|
||||||
solaris:
|
solaris:
|
||||||
$(CC) mongoose.c main.c -lnsl -lsocket -o $(PROG) $(CFLAGS)
|
$(CC) civetweb.c main.c -lnsl -lsocket -o $(PROG) $(CFLAGS)
|
||||||
|
|
||||||
lib$(PROG).a: $(ALL_OBJECTS)
|
lib$(PROG).a: $(ALL_OBJECTS)
|
||||||
ar cr $@ $(ALL_OBJECTS)
|
ar cr $@ $(ALL_OBJECTS)
|
||||||
@ -130,14 +130,14 @@ $(PROG).lib: $(ALL_WINOBJS)
|
|||||||
# For codesign to work in non-interactive mode, unlock login keychain:
|
# For codesign to work in non-interactive mode, unlock login keychain:
|
||||||
# security unlock ~/Library/Keychains/login.keychain
|
# security unlock ~/Library/Keychains/login.keychain
|
||||||
# See e.g. http://lists.apple.com/archives/apple-cdsa/2008/Jan/msg00027.html
|
# See e.g. http://lists.apple.com/archives/apple-cdsa/2008/Jan/msg00027.html
|
||||||
Mongoose: mongoose.c main.c
|
Civetweb: civetweb.c main.c
|
||||||
$(CC) mongoose.c main.c build/lsqlite3.c build/sqlite3.c \
|
$(CC) civetweb.c main.c build/lsqlite3.c build/sqlite3.c \
|
||||||
-DUSE_COCOA $(CFLAGS) $(FLAGS) -mmacosx-version-min=10.4 \
|
-DUSE_COCOA $(CFLAGS) $(FLAGS) -mmacosx-version-min=10.4 \
|
||||||
$(YASSL_SOURCES) $(LUA_SOURCES) \
|
$(YASSL_SOURCES) $(LUA_SOURCES) \
|
||||||
-framework Cocoa -ObjC -arch i386 -arch x86_64 -o Mongoose
|
-framework Cocoa -ObjC -arch i386 -arch x86_64 -o Civetweb
|
||||||
|
|
||||||
cocoa: Mongoose
|
cocoa: Civetweb
|
||||||
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
|
V=`perl -lne '/define\s+CIVETWEB_VERSION\s+"(\S+)"/ and print $$1' civetweb.c`; DIR=dmg/Civetweb.app && rm -rf $$DIR && mkdir -p $$DIR/Contents/{MacOS,Resources} && install -m 644 build/civetweb_*.png $$DIR/Contents/Resources/ && install -m 644 build/Info.plist $$DIR/Contents/ && install -m 755 Civetweb $$DIR/Contents/MacOS/ && ln -fs /Applications dmg/ ; hdiutil create Civetweb_$$V.dmg -volname "Civetweb $$V" -srcfolder dmg -ov #; rm -rf dmg
|
||||||
|
|
||||||
un:
|
un:
|
||||||
$(CC) test/unit_test.c -o unit_test -I. -I$(LUA) $(LUA_SOURCES) \
|
$(CC) test/unit_test.c -o unit_test -I. -I$(LUA) $(LUA_SOURCES) \
|
||||||
@ -160,9 +160,9 @@ MINGWDBG= -DNDEBUG -Os
|
|||||||
MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,console $(MINGWDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
MINGWOPT= -W -Wall -mthreads -Wl,--subsystem,console $(MINGWDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
||||||
mingw:
|
mingw:
|
||||||
windres build\res.rc build\res.o
|
windres build\res.rc build\res.o
|
||||||
$(CC) $(MINGWOPT) mongoose.c -lws2_32 \
|
$(CC) $(MINGWOPT) civetweb.c -lws2_32 \
|
||||||
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
||||||
$(CC) $(MINGWOPT) mongoose.c main.c build\res.o \
|
$(CC) $(MINGWOPT) civetweb.c main.c build\res.o \
|
||||||
-lws2_32 -ladvapi32 -lcomdlg32 -o $(PROG).exe
|
-lws2_32 -ladvapi32 -lcomdlg32 -o $(PROG).exe
|
||||||
|
|
||||||
# Build for Windows under Cygwin
|
# Build for Windows under Cygwin
|
||||||
@ -171,20 +171,20 @@ CYGWINDBG= -DNDEBUG -Os
|
|||||||
CYGWINOPT= -W -Wall -mthreads -Wl,--subsystem,console $(CYGWINDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
CYGWINOPT= -W -Wall -mthreads -Wl,--subsystem,console $(CYGWINDBG) -DHAVE_STDINT $(GCC_WARNINGS) $(COPT)
|
||||||
cygwin:
|
cygwin:
|
||||||
windres ./build/res.rc ./build/res.o
|
windres ./build/res.rc ./build/res.o
|
||||||
$(CC) $(CYGWINOPT) mongoose.c -lws2_32 \
|
$(CC) $(CYGWINOPT) civetweb.c -lws2_32 \
|
||||||
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
-shared -Wl,--out-implib=$(PROG).lib -o $(PROG).dll
|
||||||
$(CC) $(CYGWINOPT) -Ibuild mongoose.c main.c ./build/res.o \
|
$(CC) $(CYGWINOPT) -Ibuild civetweb.c main.c ./build/res.o \
|
||||||
-lws2_32 -ladvapi32 -o $(PROG).exe
|
-lws2_32 -ladvapi32 -o $(PROG).exe
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
perl test/test.pl $(TEST)
|
perl test/test.pl $(TEST)
|
||||||
|
|
||||||
tarball: 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,examples,test,build,*.[ch],*.md} && mv x mongoose/$$F
|
F=civetweb-`perl -lne '/define\s+CIVETWEB_VERSION\s+"(\S+)"/ and print $$1' civetweb.c`.tgz ; cd .. && tar -czf x civetweb/{LICENSE,Makefile,examples,test,build,*.[ch],*.md} && mv x civetweb/$$F
|
||||||
|
|
||||||
release: tarball cocoa
|
release: tarball cocoa
|
||||||
wine make windows
|
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/
|
V=`perl -lne '/define\s+CIVETWEB_VERSION\s+"(\S+)"/ and print $$1' civetweb.c`; upx civetweb.exe; cp civetweb.exe civetweb-$$V.exe; cp civetweb.exe civetweb_php_bundle/; zip -r civetweb_php_bundle_$$V.zip civetweb_php_bundle/
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cd examples && $(MAKE) clean
|
cd examples && $(MAKE) clean
|
||||||
|
24
README.md
24
README.md
@ -4,30 +4,30 @@ Project mission is to provide easy to use, powerful, embeddable web server.
|
|||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
Mongoose keeps the balance between functionality and
|
Civetweb keeps the balance between functionality and
|
||||||
simplicity by carefully selected list of features:
|
simplicity by carefully selected list of features:
|
||||||
|
|
||||||
- Liberal, commercial-friendly
|
- Liberal, commercial-friendly
|
||||||
[MIT license](http://en.wikipedia.org/wiki/MIT_License)
|
[MIT license](http://en.wikipedia.org/wiki/MIT_License)
|
||||||
- Works on Windows, Mac, UNIX, iPhone, Android, and many other platforms
|
- Works on Windows, Mac, UNIX, iPhone, Android, and many other platforms
|
||||||
- Scripting and database support (Lua Server Pages + Sqlite, see
|
- Scripting and database support (Lua Server Pages + Sqlite, see
|
||||||
[page.lp](https://github.com/valenok/mongoose/blob/master/test/page.lp) ),
|
[page.lp](https://github.com/valenok/civetweb/blob/master/test/page.lp) ),
|
||||||
which provides ready to go, powerful web development platform in
|
which provides ready to go, powerful web development platform in
|
||||||
one single-click executable with **no dependencies**: forget LAMP!
|
one single-click executable with **no dependencies**: forget LAMP!
|
||||||
- Support for CGI, SSL, SSI, Digest (MD5) authorization, Websocket, WEbDAV
|
- Support for CGI, SSL, SSI, Digest (MD5) authorization, Websocket, WEbDAV
|
||||||
- Resumed download, URL rewrite, file blacklist, IP-based ACL, Windows service
|
- Resumed download, URL rewrite, file blacklist, IP-based ACL, Windows service
|
||||||
- Download speed limit based on client subnet or URI pattern
|
- Download speed limit based on client subnet or URI pattern
|
||||||
- Simple and clean embedding API,
|
- Simple and clean embedding API,
|
||||||
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h).
|
[civetweb.h](https://github.com/valenok/civetweb/blob/master/civetweb.h).
|
||||||
The source is in single
|
The source is in single
|
||||||
[mongoose.c](https://github.com/valenok/mongoose/blob/master/mongoose.c) file
|
[civetweb.c](https://github.com/valenok/civetweb/blob/master/civetweb.c) file
|
||||||
to make things easy. Embedding examples:
|
to make things easy. Embedding examples:
|
||||||
[hello.c](https://github.com/valenok/mongoose/blob/master/examples/hello.c),
|
[hello.c](https://github.com/valenok/civetweb/blob/master/examples/hello.c),
|
||||||
[post.c](https://github.com/valenok/mongoose/blob/master/examples/post.c),
|
[post.c](https://github.com/valenok/civetweb/blob/master/examples/post.c),
|
||||||
[upload.c](https://github.com/valenok/mongoose/blob/master/examples/upload.c),
|
[upload.c](https://github.com/valenok/civetweb/blob/master/examples/upload.c),
|
||||||
[websocket.c](https://github.com/valenok/mongoose/blob/master/examples/websocket.c)
|
[websocket.c](https://github.com/valenok/civetweb/blob/master/examples/websocket.c)
|
||||||
- HTTP client capable of sending arbitrary HTTP/HTTPS requests
|
- HTTP client capable of sending arbitrary HTTP/HTTPS requests
|
||||||
- [User Manual](https://github.com/valenok/mongoose/blob/master/UserManual.md)
|
- [User Manual](https://github.com/valenok/civetweb/blob/master/UserManual.md)
|
||||||
|
|
||||||
Note that Windows and MacOS binaries have following 3rd party software
|
Note that Windows and MacOS binaries have following 3rd party software
|
||||||
compiled in:
|
compiled in:
|
||||||
@ -36,16 +36,16 @@ compiled in:
|
|||||||
<a href="http://lua.org">Lua embedded scripting engine</a>.
|
<a href="http://lua.org">Lua embedded scripting engine</a>.
|
||||||
|
|
||||||
Questions can be asked at
|
Questions can be asked at
|
||||||
[mongoose-users@google.com](http://groups.google.com/group/mongoose-users)
|
[civetweb-users@google.com](http://groups.google.com/group/civetweb-users)
|
||||||
mailing list.
|
mailing list.
|
||||||
|
|
||||||
[](http://githalytics.com/valenok/mongoose)
|
[](http://githalytics.com/valenok/civetweb)
|
||||||
|
|
||||||
|
|
||||||
# Author
|
# Author
|
||||||
|
|
||||||
I am Sergey Lyubka, a software engineer from Galway, Ireland. I started
|
I am Sergey Lyubka, a software engineer from Galway, Ireland. I started
|
||||||
working on Mongoose in 2004, and since then continuously improve it,
|
working on Civetweb in 2004, and since then continuously improve it,
|
||||||
investing thousands of hours of work. My other project I'm contributing to the
|
investing thousands of hours of work. My other project I'm contributing to the
|
||||||
community for free is
|
community for free is
|
||||||
[Super Light Regular Expression library](http://code.google.com/p/slre).
|
[Super Light Regular Expression library](http://code.google.com/p/slre).
|
||||||
|
176
UserManual.md
176
UserManual.md
@ -1,68 +1,68 @@
|
|||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
Mongoose is small and easy to use web server. It is self-contained, and does
|
Civetweb is small and easy to use web server. It is self-contained, and does
|
||||||
not require any external software to run.
|
not require any external software to run.
|
||||||
|
|
||||||
On Windows, mongoose iconifies itself to the system tray icon when started.
|
On Windows, civetweb iconifies itself to the system tray icon when started.
|
||||||
Right-click on the icon pops up a menu, where it is possible to stop
|
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
|
civetweb, 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,
|
to share a folder on Windows is to copy `civetweb.exe` to a folder,
|
||||||
double-click the exe, and launch a browser at
|
double-click the exe, and launch a browser at
|
||||||
[http://localhost:8080](http://localhost:8080). Note that 'localhost' should
|
[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.
|
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
|
On UNIX and Mac, civetweb is a command line utility. Running `civetweb` in
|
||||||
terminal, optionally followed by configuration parameters
|
terminal, optionally followed by configuration parameters
|
||||||
(`mongoose [OPTIONS]`) or configuration file name
|
(`civetweb [OPTIONS]`) or configuration file name
|
||||||
(`mongoose [config_file_name]`) starts the
|
(`civetweb [config_file_name]`) starts the
|
||||||
web server. Mongoose does not detach from terminal. Pressing `Ctrl-C` keys
|
web server. Civetweb does not detach from terminal. Pressing `Ctrl-C` keys
|
||||||
would stop the server.
|
would stop the server.
|
||||||
|
|
||||||
When started, mongoose first searches for the configuration file.
|
When started, civetweb first searches for the configuration file.
|
||||||
If configuration file is specified explicitly in the command line, i.e.
|
If configuration file is specified explicitly in the command line, i.e.
|
||||||
`mongoose path_to_config_file`, then specified configuration file is used.
|
`civetweb path_to_config_file`, then specified configuration file is used.
|
||||||
Otherwise, mongoose would search for file `mongoose.conf` in the same directory
|
Otherwise, civetweb would search for file `civetweb.conf` in the same directory
|
||||||
where binary is located, and use it. Configuration file can be absent.
|
where binary is located, and use it. Configuration file can be absent.
|
||||||
|
|
||||||
|
|
||||||
Configuration file is a sequence of lines, each line containing
|
Configuration file is a sequence of lines, each line containing
|
||||||
command line argument name and it's value. Empty lines, and lines beginning
|
command line argument name and it's value. Empty lines, and lines beginning
|
||||||
with `#`, are ignored. Here is the example of `mongoose.conf` file:
|
with `#`, are ignored. Here is the example of `civetweb.conf` file:
|
||||||
|
|
||||||
document_root c:\www
|
document_root c:\www
|
||||||
listening_ports 8080,8043s
|
listening_ports 8080,8043s
|
||||||
ssl_certificate c:\mongoose\ssl_cert.pem
|
ssl_certificate c:\civetweb\ssl_cert.pem
|
||||||
|
|
||||||
When configuration file is processed, mongoose process command line arguments,
|
When configuration file is processed, civetweb process command line arguments,
|
||||||
if they are specified. Command line arguments therefore can override
|
if they are specified. Command line arguments therefore can override
|
||||||
configuration file settings. Command line arguments must start with `-`.
|
configuration file settings. Command line arguments must start with `-`.
|
||||||
For example, if `mongoose.conf` has line
|
For example, if `civetweb.conf` has line
|
||||||
`document_root /var/www`, and mongoose has been started as
|
`document_root /var/www`, and civetweb has been started as
|
||||||
`mongoose -document_root /etc`, then `/etc` directory will be served as
|
`civetweb -document_root /etc`, then `/etc` directory will be served as
|
||||||
document root, because command line options take priority over
|
document root, because command line options take priority over
|
||||||
configuration file. Configuration options section below provide a good
|
configuration file. Configuration options section below provide a good
|
||||||
overview of Mongoose features.
|
overview of Civetweb features.
|
||||||
|
|
||||||
Note that configuration options on the command line must start with `-`,
|
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
|
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:
|
listed in the next section. Thus, the following two setups are equivalent:
|
||||||
|
|
||||||
# Using command line arguments
|
# Using command line arguments
|
||||||
$ mongoose -listening_ports 1234 -document_root /var/www
|
$ civetweb -listening_ports 1234 -document_root /var/www
|
||||||
|
|
||||||
# Using config file
|
# Using config file
|
||||||
$ cat mongoose.conf
|
$ cat civetweb.conf
|
||||||
listening_ports 1234
|
listening_ports 1234
|
||||||
document_root /var/www
|
document_root /var/www
|
||||||
$ mongoose
|
$ civetweb
|
||||||
|
|
||||||
Mongoose can also be used to modify `.htpasswd` passwords file:
|
Civetweb can also be used to modify `.htpasswd` passwords file:
|
||||||
|
|
||||||
mongoose -A <htpasswd_file> <realm> <user> <passwd>
|
civetweb -A <htpasswd_file> <realm> <user> <passwd>
|
||||||
|
|
||||||
Unlike other web servers, mongoose does not require CGI scripts be located in
|
Unlike other web servers, civetweb does not require CGI scripts be located in
|
||||||
a special directory. CGI scripts can be anywhere. CGI (and SSI) files are
|
a special directory. CGI scripts can be anywhere. CGI (and SSI) files are
|
||||||
recognized by the file name pattern. Mongoose uses shell-like glob
|
recognized by the file name pattern. Civetweb uses shell-like glob
|
||||||
patterns. Pattern match starts at the beginning of the string, so essentially
|
patterns. Pattern match starts at the beginning of the string, so essentially
|
||||||
patterns are prefix patterns. Syntax is as follows:
|
patterns are prefix patterns. Syntax is as follows:
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ All other characters in the pattern match themselves. Examples:
|
|||||||
|
|
||||||
# Configuration Options
|
# Configuration Options
|
||||||
|
|
||||||
Below is a list of configuration options Mongoose understands. Every option
|
Below is a list of configuration options Civetweb understands. Every option
|
||||||
is followed by it's default value. If default value is not present, then
|
is followed by it's default value. If default value is not present, then
|
||||||
it is empty.
|
it is empty.
|
||||||
|
|
||||||
@ -102,15 +102,15 @@ will fail.
|
|||||||
### cgi_interpreter
|
### cgi_interpreter
|
||||||
Path to an executable to use as CGI interpreter for __all__ CGI scripts
|
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),
|
regardless script extension. If this option is not set (which is a default),
|
||||||
Mongoose looks at first line of a CGI script,
|
Civetweb looks at first line of a CGI script,
|
||||||
[shebang line](http://en.wikipedia.org/wiki/Shebang_(Unix\)), for an interpreter.
|
[shebang line](http://en.wikipedia.org/wiki/Shebang_(Unix\)), for an interpreter.
|
||||||
|
|
||||||
For example, if both PHP and perl CGIs are used, then
|
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
|
`#!/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,
|
respective CGI scripts. Note that paths should be either full file paths,
|
||||||
or file paths relative to the current working directory of mongoose server.
|
or file paths relative to the current working directory of civetweb server.
|
||||||
If mongoose is started by mouse double-click on Windows, current working
|
If civetweb is started by mouse double-click on Windows, current working
|
||||||
directory is a directory where mongoose executable is located.
|
directory is a directory where civetweb executable is located.
|
||||||
|
|
||||||
If all CGIs use the same interpreter, for example they are all PHP, then
|
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
|
`cgi_interpreter` can be set to the path to `php-cgi.exe` executable and
|
||||||
@ -137,7 +137,7 @@ 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
|
should end with a special extension, by default the extension should be
|
||||||
either `.shtml` or `.shtm`.
|
either `.shtml` or `.shtm`.
|
||||||
|
|
||||||
Unknown SSI directives are silently ignored by mongoose. Currently, two SSI
|
Unknown SSI directives are silently ignored by civetweb. Currently, two SSI
|
||||||
directives are supported, `<!--#include ...>` and
|
directives are supported, `<!--#include ...>` and
|
||||||
`<!--#exec "command">`. Note that `<!--#include ...>` directive supports
|
`<!--#exec "command">`. Note that `<!--#include ...>` directive supports
|
||||||
three path specifications:
|
three path specifications:
|
||||||
@ -216,7 +216,7 @@ files.
|
|||||||
|
|
||||||
### access\_control\_list
|
### access\_control\_list
|
||||||
An Access Control List (ACL) allows restrictions to be put on the list of IP
|
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
|
addresses which have access to the web server. In the case of the Civetweb
|
||||||
web server, the ACL is a comma separated list of IP subnets, where each
|
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,
|
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`,
|
where a minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
|
||||||
@ -258,20 +258,20 @@ directory is commonly referenced as dot (`.`).
|
|||||||
Path to SSL certificate file. This option is only required when at least one
|
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,
|
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
|
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)
|
[ssl_cert.pem](https://github.com/valenok/civetweb/blob/master/build/ssl_cert.pem)
|
||||||
|
|
||||||
### num_threads `50`
|
### num_threads `50`
|
||||||
Number of worker threads. Mongoose handles each incoming connection in a
|
Number of worker threads. Civetweb handles each incoming connection in a
|
||||||
separate thread. Therefore, the value of this option is effectively a number
|
separate thread. Therefore, the value of this option is effectively a number
|
||||||
of concurrent HTTP connections Mongoose can handle.
|
of concurrent HTTP connections Civetweb can handle.
|
||||||
|
|
||||||
### run\_as\_user
|
### run\_as\_user
|
||||||
Switch to given user credentials after startup. Usually, this option is
|
Switch to given user credentials after startup. Usually, this option is
|
||||||
required when mongoose needs to bind on privileged port on UNIX. To do
|
required when civetweb 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,
|
that, civetweb needs to be started as root. But running as root is a bad idea,
|
||||||
therefore this option can be used to drop privileges. Example:
|
therefore this option can be used to drop privileges. Example:
|
||||||
|
|
||||||
mongoose -listening_ports 80 -run_as_user nobody
|
civetweb -listening_ports 80 -run_as_user nobody
|
||||||
|
|
||||||
### request\_timeout\_ms `30000`
|
### request\_timeout\_ms `30000`
|
||||||
Timeout for network read and network write operations, in milliseconds.
|
Timeout for network read and network write operations, in milliseconds.
|
||||||
@ -281,36 +281,36 @@ or use keep-alive messages.
|
|||||||
|
|
||||||
### url\_rewrite\_patterns
|
### url\_rewrite\_patterns
|
||||||
Comma-separated list of URL rewrites in the form of
|
Comma-separated list of URL rewrites in the form of
|
||||||
`uri_pattern=file_or_directory_path`. When Mongoose receives the request,
|
`uri_pattern=file_or_directory_path`. When Civetweb receives the request,
|
||||||
it constructs the file name to show by combining `document_root` and the URI.
|
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
|
However, if the rewrite option is used and `uri_pattern` matches the
|
||||||
requested URI, then `document_root` is ignored. Insted,
|
requested URI, then `document_root` is ignored. Insted,
|
||||||
`file_or_directory_path` is used, which should be a full path name or
|
`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
|
a path relative to the web server's current working directory. Note that
|
||||||
`uri_pattern`, as all mongoose patterns, is a prefix pattern.
|
`uri_pattern`, as all civetweb patterns, is a prefix pattern.
|
||||||
|
|
||||||
This makes it possible to serve many directories outside from `document_root`,
|
This makes it possible to serve many directories outside from `document_root`,
|
||||||
redirect all requests to scripts, and do other tricky things. For example,
|
redirect all requests to scripts, and do other tricky things. For example,
|
||||||
to redirect all accesses to `.doc` files to a special script, do:
|
to redirect all accesses to `.doc` files to a special script, do:
|
||||||
|
|
||||||
mongoose -url_rewrite_patterns **.doc$=/path/to/cgi-bin/handle_doc.cgi
|
civetweb -url_rewrite_patterns **.doc$=/path/to/cgi-bin/handle_doc.cgi
|
||||||
|
|
||||||
Or, to imitate user home directories support, do:
|
Or, to imitate user home directories support, do:
|
||||||
|
|
||||||
mongoose -url_rewrite_patterns /~joe/=/home/joe/,/~bill=/home/bill/
|
civetweb -url_rewrite_patterns /~joe/=/home/joe/,/~bill=/home/bill/
|
||||||
|
|
||||||
### hide\_files\_patterns
|
### hide\_files\_patterns
|
||||||
A pattern for the files to hide. Files that match the pattern will not
|
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
|
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:
|
must be for a file name only, not including directory name. Example:
|
||||||
|
|
||||||
mongoose -hide_files_patterns secret.txt|even_more_secret.txt
|
civetweb -hide_files_patterns secret.txt|even_more_secret.txt
|
||||||
|
|
||||||
# Lua Server Pages
|
# Lua Server Pages
|
||||||
Pre-built Windows and Mac mongoose binaries have built-in Lua Server Pages
|
Pre-built Windows and Mac civetweb binaries have built-in Lua Server Pages
|
||||||
support. That means it is possible to write PHP-like scripts with mongoose,
|
support. That means it is possible to write PHP-like scripts with civetweb,
|
||||||
using Lua programming language instead of PHP. Lua is known
|
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
|
for it's speed and small size. Civetweb uses Lua version 5.2.1, the
|
||||||
documentation for it can be found at
|
documentation for it can be found at
|
||||||
[Lua 5.2 reference manual](http://www.lua.org/manual/5.2/).
|
[Lua 5.2 reference manual](http://www.lua.org/manual/5.2/).
|
||||||
|
|
||||||
@ -332,20 +332,20 @@ 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,
|
and also information about the request is available in `mg.request_info` object,
|
||||||
like request method, all headers, etcetera. Please refer to
|
like request method, all headers, etcetera. Please refer to
|
||||||
`struct mg_request_info` definition in
|
`struct mg_request_info` definition in
|
||||||
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h)
|
[civetweb.h](https://github.com/valenok/civetweb/blob/master/civetweb.h)
|
||||||
to see what kind of information is present in `mg.request_info` object. Also,
|
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
|
[page.lp](https://github.com/valenok/civetweb/blob/master/test/page.lp) and
|
||||||
[prime_numbers.lp](https://github.com/valenok/mongoose/blob/master/examples/lua/prime_numbers.lp)
|
[prime_numbers.lp](https://github.com/valenok/civetweb/blob/master/examples/lua/prime_numbers.lp)
|
||||||
contains some example code that uses `request_info` and other functions(form submitting for example).
|
contains some example code that uses `request_info` and other functions(form submitting for example).
|
||||||
|
|
||||||
Mongoose exports the following to the Lua server page:
|
Civetweb exports the following to the Lua server page:
|
||||||
|
|
||||||
mg.read() -- reads a chunk from POST data, returns it as a string
|
mg.read() -- reads a chunk from POST data, returns it as a string
|
||||||
mg.write(str) -- writes string to the client
|
mg.write(str) -- writes string to the client
|
||||||
mg.include(path) -- sources another Lua file
|
mg.include(path) -- sources another Lua file
|
||||||
mg.redirect(uri) -- internal redirect to a given URI
|
mg.redirect(uri) -- internal redirect to a given URI
|
||||||
mg.onerror(msg) -- error handler, can be overridden
|
mg.onerror(msg) -- error handler, can be overridden
|
||||||
mg.version -- a string that holds Mongoose version
|
mg.version -- a string that holds Civetweb version
|
||||||
mg.request_info -- a table with request information
|
mg.request_info -- a table with request information
|
||||||
|
|
||||||
-- Connect to the remote TCP server. This function is an implementation
|
-- Connect to the remote TCP server. This function is an implementation
|
||||||
@ -358,22 +358,22 @@ Mongoose exports the following to the Lua server page:
|
|||||||
local host = 'code.google.com' -- IP address or domain name
|
local host = 'code.google.com' -- IP address or domain name
|
||||||
local ok, sock = pcall(connect, host, 80, 1)
|
local ok, sock = pcall(connect, host, 80, 1)
|
||||||
if ok then
|
if ok then
|
||||||
sock:send('GET /p/mongoose/ HTTP/1.0\r\n' ..
|
sock:send('GET /p/civetweb/ HTTP/1.0\r\n' ..
|
||||||
'Host: ' .. host .. '\r\n\r\n')
|
'Host: ' .. host .. '\r\n\r\n')
|
||||||
local reply = sock:recv()
|
local reply = sock:recv()
|
||||||
sock:close()
|
sock:close()
|
||||||
-- reply now contains the web page https://code.google.com/p/mongoose
|
-- reply now contains the web page https://code.google.com/p/civetweb
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
**IMPORTANT: Mongoose does not send HTTP headers for Lua pages. Therefore,
|
**IMPORTANT: Civetweb does not send HTTP headers for Lua pages. Therefore,
|
||||||
every Lua Page must begin with HTTP reply line and headers**, like this:
|
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') ?>
|
<? print('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') ?>
|
||||||
<html><body>
|
<html><body>
|
||||||
... the rest of the web page ...
|
... the rest of the web page ...
|
||||||
|
|
||||||
To serve Lua Page, mongoose creates Lua context. That context is used for
|
To serve Lua Page, civetweb creates Lua context. That context is used for
|
||||||
all Lua blocks within the page. That means, all Lua blocks on the same page
|
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
|
share the same context. If one block defines a variable, for example, that
|
||||||
variable is visible in the block that follows.
|
variable is visible in the block that follows.
|
||||||
@ -383,39 +383,39 @@ variable is visible in the block that follows.
|
|||||||
reason for that is wrong paths to the interpreter. Remember that with PHP,
|
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
|
correct interpreter is `php-cgi.exe` (`php-cgi` on UNIX). Solution: specify
|
||||||
full path to the PHP interpreter, e.g.:
|
full path to the PHP interpreter, e.g.:
|
||||||
`mongoose -cgi_interpreter /full/path/to/php-cgi`
|
`civetweb -cgi_interpreter /full/path/to/php-cgi`
|
||||||
|
|
||||||
- Mongoose fails to start. If Mongoose exits immediately when run, this
|
- Civetweb fails to start. If Civetweb exits immediately when run, this
|
||||||
usually indicates a syntax error in the configuration file
|
usually indicates a syntax error in the configuration file
|
||||||
(named `mongoose.conf` by default) or the command-line arguments.
|
(named `civetweb.conf` by default) or the command-line arguments.
|
||||||
Syntax checking is omitted from Mongoose to keep its size low. However,
|
Syntax checking is omitted from Civetweb to keep its size low. However,
|
||||||
the Manual should be of help. Note: the syntax changes from time to time,
|
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.
|
so updating the config file might be necessary after executable update.
|
||||||
|
|
||||||
- Embedding with OpenSSL on Windows might fail because of calling convention.
|
- Embedding with OpenSSL on Windows might fail because of calling convention.
|
||||||
To force Mongoose to use `__stdcall` convention, add `/Gz` compilation
|
To force Civetweb to use `__stdcall` convention, add `/Gz` compilation
|
||||||
flag in Visual Studio compiler.
|
flag in Visual Studio compiler.
|
||||||
|
|
||||||
# Embedding
|
# Embedding
|
||||||
Embedding Mongoose is easy. Copy
|
Embedding Civetweb is easy. Copy
|
||||||
[mongoose.c](https://github.com/valenok/mongoose/blob/master/mongoose.c) and
|
[civetweb.c](https://github.com/valenok/civetweb/blob/master/civetweb.c) and
|
||||||
[mongoose.h](https://github.com/valenok/mongoose/blob/master/mongoose.h)
|
[civetweb.h](https://github.com/valenok/civetweb/blob/master/civetweb.h)
|
||||||
to your application's source tree and include them in the build. For
|
to your application's source tree and include them in the build. For
|
||||||
example, your application's code lives in C file `my_app.c`, then on UNIX
|
example, your application's code lives in C file `my_app.c`, then on UNIX
|
||||||
this command embeds Mongoose:
|
this command embeds Civetweb:
|
||||||
|
|
||||||
$ ls
|
$ ls
|
||||||
my_app.c mongoose.c mongoose.h
|
my_app.c civetweb.c civetweb.h
|
||||||
$ gcc my_app.c mongoose.c -o my_app -ldl -pthread
|
$ gcc my_app.c civetweb.c -o my_app -ldl -pthread
|
||||||
|
|
||||||
Somewhere in the application code, call `mg_start()` to start the server.
|
Somewhere in the application code, call `mg_start()` to start the server.
|
||||||
Pass configuration options and event handlers to `mg_start()`.
|
Pass configuration options and event handlers to `mg_start()`.
|
||||||
Mongoose then calls handlers when certain events happen.
|
Civetweb then calls handlers when certain events happen.
|
||||||
For example, when new request arrives, Mongoose calls `begin_request`
|
For example, when new request arrives, Civetweb calls `begin_request`
|
||||||
handler function to let user handle the request. In the handler, user code
|
handler function to let user handle the request. In the handler, user code
|
||||||
can get all information about the request -- parsed headers, etcetera.
|
can get all information about the request -- parsed headers, etcetera.
|
||||||
|
|
||||||
Mongoose API is logically divided in three categories: server setup/shutdown
|
Civetweb API is logically divided in three categories: server setup/shutdown
|
||||||
functions, functions to be used by user-written event handlers, and
|
functions, functions to be used by user-written event handlers, and
|
||||||
convenience utility functions.
|
convenience utility functions.
|
||||||
|
|
||||||
@ -423,9 +423,9 @@ convenience utility functions.
|
|||||||
To start the embedded web server, call `mg_start()`. To stop it, call
|
To start the embedded web server, call `mg_start()`. To stop it, call
|
||||||
`mg_stop()`.
|
`mg_stop()`.
|
||||||
|
|
||||||
// This structure needs to be passed to mg_start(), to let mongoose know
|
// This structure needs to be passed to mg_start(), to let civetweb know
|
||||||
// which callbacks to invoke. For detailed description, see
|
// which callbacks to invoke. For detailed description, see
|
||||||
// https://github.com/valenok/mongoose/blob/master/UserManual.md
|
// https://github.com/valenok/civetweb/blob/master/UserManual.md
|
||||||
struct mg_callbacks {
|
struct mg_callbacks {
|
||||||
int (*begin_request)(struct mg_connection *);
|
int (*begin_request)(struct mg_connection *);
|
||||||
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
||||||
@ -441,7 +441,7 @@ To start the embedded web server, call `mg_start()`. To stop it, call
|
|||||||
int (*http_error)(struct mg_connection *, int status);
|
int (*http_error)(struct mg_connection *, int status);
|
||||||
};
|
};
|
||||||
|
|
||||||
[hello.c](https://github.com/valenok/mongoose/blob/master/examples/hello.c)
|
[hello.c](https://github.com/valenok/civetweb/blob/master/examples/hello.c)
|
||||||
provides a minimalistic example.
|
provides a minimalistic example.
|
||||||
|
|
||||||
Common pattern is to implement `begin_request` callback, and serve static files
|
Common pattern is to implement `begin_request` callback, and serve static files
|
||||||
@ -453,18 +453,18 @@ encrypted database or encryption dongles would be a better choice.
|
|||||||
|
|
||||||
# Build on Android
|
# Build on Android
|
||||||
|
|
||||||
This is a small guide to help you run mongoose on Android. Currently it is
|
This is a small guide to help you run civetweb on Android. Currently it is
|
||||||
tested on the HTC Wildfire. If you have managed to run it on other devices
|
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.
|
as well, please comment or drop an email in the mailing list.
|
||||||
Note : You dont need root access to run mongoose on Android.
|
Note : You dont need root access to run civetweb on Android.
|
||||||
|
|
||||||
- Download the source from the Downloads page.
|
- Download the source from the Downloads page.
|
||||||
- Download the Android NDK from [http://developer.android.com/tools/sdk/ndk/index.html](http://developer.android.com/tools/sdk/ndk/index.html)
|
- Download the Android NDK from [http://developer.android.com/tools/sdk/ndk/index.html](http://developer.android.com/tools/sdk/ndk/index.html)
|
||||||
- Run `/path-to-ndk/ndk-build -C /path-to-mongoose/build`
|
- Run `/path-to-ndk/ndk-build -C /path-to-civetweb/build`
|
||||||
That should generate mongoose/lib/armeabi/mongoose
|
That should generate civetweb/lib/armeabi/civetweb
|
||||||
- Using the adb tool (you need to have Android SDK installed for that),
|
- Using the adb tool (you need to have Android SDK installed for that),
|
||||||
push the generated mongoose binary to `/data/local` folder on device.
|
push the generated civetweb binary to `/data/local` folder on device.
|
||||||
- From adb shell, navigate to `/data/local` and execute `./mongoose`.
|
- From adb shell, navigate to `/data/local` and execute `./civetweb`.
|
||||||
- To test if the server is running fine, visit your web-browser and
|
- 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.
|
navigate to `http://127.0.0.1:8080` You should see the `Index of /` page.
|
||||||
|
|
||||||
@ -474,18 +474,18 @@ Note : You dont need root access to run mongoose on Android.
|
|||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- `jni` stands for Java Native Interface. Read up on Android NDK if you want
|
- `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
|
to know how to interact with the native C functions of civetweb in Android
|
||||||
Java applications.
|
Java applications.
|
||||||
- TODO: A Java application that interacts with the native binary or a
|
- TODO: A Java application that interacts with the native binary or a
|
||||||
shared library.
|
shared library.
|
||||||
|
|
||||||
# Mongoose internals
|
# Civetweb internals
|
||||||
|
|
||||||
Mongoose is multithreaded web server. `mg_start()` function allocates
|
Civetweb is multithreaded web server. `mg_start()` function allocates
|
||||||
web server context (`struct mg_context`), which holds all information
|
web server context (`struct mg_context`), which holds all information
|
||||||
about web server instance:
|
about web server instance:
|
||||||
|
|
||||||
- configuration options. Note that mongoose makes internal copies of
|
- configuration options. Note that civetweb makes internal copies of
|
||||||
passed options.
|
passed options.
|
||||||
- SSL context, if any
|
- SSL context, if any
|
||||||
- user-defined callbacks
|
- user-defined callbacks
|
||||||
@ -498,11 +498,11 @@ When `mg_start()` returns, all initialization is quaranteed to be complete
|
|||||||
two threads: a master thread, that accepts new connections, and several
|
two threads: a master thread, that accepts new connections, and several
|
||||||
worker threads, that process accepted connections. The number of worker threads
|
worker threads, that process accepted connections. The number of worker threads
|
||||||
is configurable via `num_threads` configuration option. That number puts a
|
is configurable via `num_threads` configuration option. That number puts a
|
||||||
limit on number of simultaneous requests that can be handled by mongoose.
|
limit on number of simultaneous requests that can be handled by civetweb.
|
||||||
|
|
||||||
When master thread accepts new connection, a new accepted socket (described by
|
When master thread accepts new connection, a new accepted socket (described by
|
||||||
`struct socket`) it placed into the accepted sockets queue,
|
`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
|
which has size of 20 (see [code](https://github.com/valenok/civetweb/blob/3892e0199e6ca9613b160535d9d107ede09daa43/civetweb.c#L486)). Any idle worker thread
|
||||||
can grab accepted sockets from that queue. If all worker threads are busy,
|
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,
|
master thread can accept and queue up to 20 more TCP connections,
|
||||||
filling up the queue.
|
filling up the queue.
|
||||||
@ -510,7 +510,7 @@ 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
|
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.
|
full queue, TCP layer in OS can also queue incoming connection.
|
||||||
The number is limited by the `listen()` call parameter on listening socket,
|
The number is limited by the `listen()` call parameter on listening socket,
|
||||||
which is `SOMAXCONN` in case of Mongoose, and depends on a platform.
|
which is `SOMAXCONN` in case of Civetweb, and depends on a platform.
|
||||||
|
|
||||||
Worker threads are running in an infinite loop, which in simplified form
|
Worker threads are running in an infinite loop, which in simplified form
|
||||||
looks something like this:
|
looks something like this:
|
||||||
@ -521,7 +521,7 @@ looks something like this:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function `consume_socket()` gets new accepted socket from the mongoose socket
|
Function `consume_socket()` gets new accepted socket from the civetweb socket
|
||||||
queue, atomically removing it from the queue. If the queue is empty,
|
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
|
`consume_socket()` blocks and waits until new sockets are placed in a queue
|
||||||
by the master thread. `process_new_connection()` actually processes the
|
by the master thread. `process_new_connection()` actually processes the
|
||||||
@ -534,7 +534,7 @@ listening sockets. `poll()` is used to avoid `FD_SETSIZE` limitation of
|
|||||||
to use hi-performance alternatives like `epoll()` or `kqueue()`. Worker
|
to use hi-performance alternatives like `epoll()` or `kqueue()`. Worker
|
||||||
threads use blocking IO on accepted sockets for reading and writing data.
|
threads use blocking IO on accepted sockets for reading and writing data.
|
||||||
All accepted sockets have `SO_RCVTIMEO` and `SO_SNDTIMEO` socket options set
|
All accepted sockets have `SO_RCVTIMEO` and `SO_SNDTIMEO` socket options set
|
||||||
(controlled by `request_timeout_ms` mongoose option, 30 seconds default) which
|
(controlled by `request_timeout_ms` civetweb option, 30 seconds default) which
|
||||||
specify read/write timeout on client connection.
|
specify read/write timeout on client connection.
|
||||||
|
|
||||||
# Other Resources
|
# Other Resources
|
||||||
@ -544,4 +544,4 @@ specify read/write timeout on client connection.
|
|||||||
([pdf](http://mind.be/content/110206_Web-ui.pdf) |
|
([pdf](http://mind.be/content/110206_Web-ui.pdf) |
|
||||||
[odp](http://mind.be/content/110206_Web-ui.odp))
|
[odp](http://mind.be/content/110206_Web-ui.odp))
|
||||||
- Linux Journal article by Michel J.Hammel, 2010-04-01, called
|
- Linux Journal article by Michel J.Hammel, 2010-04-01, called
|
||||||
[Mongoose: an Embeddable Web Server in C](http://www.linuxjournal.com/article/10680)
|
[Civetweb: an Embeddable Web Server in C](http://www.linuxjournal.com/article/10680)
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleExecutable</key> <string>Mongoose</string>
|
<key>CFBundleExecutable</key> <string>Civetweb</string>
|
||||||
<key>CFBundlePackageType</key> <string>APPL</string>
|
<key>CFBundlePackageType</key> <string>APPL</string>
|
||||||
<key>CFBundleTypeRole</key> <string>None</string>
|
<key>CFBundleTypeRole</key> <string>None</string>
|
||||||
<key>CFBundleIconFiles</key> <array>
|
<key>CFBundleIconFiles</key> <array>
|
||||||
<string>mongoose_16x16.png</string>
|
<string>civetweb_16x16.png</string>
|
||||||
<string>mongoose_22x22.png</string>
|
<string>civetweb_22x22.png</string>
|
||||||
<string>mongoose_32x32.png</string>
|
<string>civetweb_32x32.png</string>
|
||||||
<string>mongoose_64x64.png</string>
|
<string>civetweb_64x64.png</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LSUIElement</key> <true/>
|
<key>LSUIElement</key> <true/>
|
||||||
<key>RunAtLoad</key> <true/>
|
<key>RunAtLoad</key> <true/>
|
||||||
<key>Label</key> <string>com.kolkin.mongoose</string>
|
<key>Label</key> <string>com.kolkin.civetweb</string>
|
||||||
<key>ProgramArguments</key> <array> </array>
|
<key>ProgramArguments</key> <array> </array>
|
||||||
<key>KeepAlive</key> <true/>
|
<key>KeepAlive</key> <true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
LOCAL_PATH := $(call my-dir)/../..
|
LOCAL_PATH := $(call my-dir)/../..
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_CFLAGS := -std=c99 -O2 -W -Wall -pthread -pipe $(COPT)
|
LOCAL_CFLAGS := -std=c99 -O2 -W -Wall -pthread -pipe $(COPT)
|
||||||
LOCAL_MODULE := mongoose
|
LOCAL_MODULE := civetweb
|
||||||
LOCAL_SRC_FILES := main.c mongoose.c
|
LOCAL_SRC_FILES := main.c civetweb.c
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
@ -247,9 +247,9 @@ typedef int SOCKET;
|
|||||||
|
|
||||||
#endif // End of Windows and UNIX specific includes
|
#endif // End of Windows and UNIX specific includes
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
#define MONGOOSE_VERSION "3.9"
|
#define CIVETWEB_VERSION "1.0"
|
||||||
#define PASSWORDS_FILE_NAME ".htpasswd"
|
#define PASSWORDS_FILE_NAME ".htpasswd"
|
||||||
#define CGI_ENVIRONMENT_SIZE 4096
|
#define CGI_ENVIRONMENT_SIZE 4096
|
||||||
#define MAX_CGI_ENVIR_VARS 64
|
#define MAX_CGI_ENVIR_VARS 64
|
||||||
@ -488,7 +488,7 @@ static const char *config_options[] = {
|
|||||||
struct mg_context {
|
struct mg_context {
|
||||||
volatile int stop_flag; // Should we stop event loop
|
volatile int stop_flag; // Should we stop event loop
|
||||||
SSL_CTX *ssl_ctx; // SSL context
|
SSL_CTX *ssl_ctx; // SSL context
|
||||||
char *config[NUM_OPTIONS]; // Mongoose configuration parameters
|
char *config[NUM_OPTIONS]; // Civetweb configuration parameters
|
||||||
struct mg_callbacks callbacks; // User-defined callback function
|
struct mg_callbacks callbacks; // User-defined callback function
|
||||||
void *user_data; // User-defined data
|
void *user_data; // User-defined data
|
||||||
|
|
||||||
@ -666,7 +666,7 @@ static struct mg_connection *fc(struct mg_context *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *mg_version(void) {
|
const char *mg_version(void) {
|
||||||
return MONGOOSE_VERSION;
|
return CIVETWEB_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_request_info *mg_get_request_info(struct mg_connection *conn) {
|
struct mg_request_info *mg_get_request_info(struct mg_connection *conn) {
|
||||||
@ -2732,7 +2732,7 @@ static int scan_directory(struct mg_connection *conn, const char *dir,
|
|||||||
// garbage and strftime() will segfault later on in
|
// garbage and strftime() will segfault later on in
|
||||||
// print_dir_entry(). memset is required only if mg_stat()
|
// print_dir_entry(). memset is required only if mg_stat()
|
||||||
// fails. For more details, see
|
// fails. For more details, see
|
||||||
// http://code.google.com/p/mongoose/issues/detail?id=79
|
// http://code.google.com/p/civetweb/issues/detail?id=79
|
||||||
memset(&de.file, 0, sizeof(de.file));
|
memset(&de.file, 0, sizeof(de.file));
|
||||||
mg_stat(conn, path, &de.file);
|
mg_stat(conn, path, &de.file);
|
||||||
|
|
||||||
@ -2768,7 +2768,7 @@ static int remove_directory(struct mg_connection *conn, const char *dir) {
|
|||||||
// garbage and strftime() will segfault later on in
|
// garbage and strftime() will segfault later on in
|
||||||
// print_dir_entry(). memset is required only if mg_stat()
|
// print_dir_entry(). memset is required only if mg_stat()
|
||||||
// fails. For more details, see
|
// fails. For more details, see
|
||||||
// http://code.google.com/p/mongoose/issues/detail?id=79
|
// http://code.google.com/p/civetweb/issues/detail?id=79
|
||||||
memset(&de.file, 0, sizeof(de.file));
|
memset(&de.file, 0, sizeof(de.file));
|
||||||
mg_stat(conn, path, &de.file);
|
mg_stat(conn, path, &de.file);
|
||||||
if(de.file.modification_time) {
|
if(de.file.modification_time) {
|
||||||
@ -3287,7 +3287,7 @@ static void prepare_cgi_environment(struct mg_connection *conn,
|
|||||||
addenv(blk, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
|
addenv(blk, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
|
||||||
addenv(blk, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
|
addenv(blk, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
|
||||||
addenv(blk, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
|
addenv(blk, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
|
||||||
addenv(blk, "SERVER_SOFTWARE=%s/%s", "Mongoose", mg_version());
|
addenv(blk, "SERVER_SOFTWARE=%s/%s", "Civetweb", mg_version());
|
||||||
|
|
||||||
// Prepare the environment block
|
// Prepare the environment block
|
||||||
addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
|
addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
|
||||||
@ -4416,9 +4416,9 @@ static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) {
|
|||||||
lsa.sin.sin_port), conn->request_info.uri);
|
lsa.sin.sin_port), conn->request_info.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the heart of the Mongoose's logic.
|
// This is the heart of the Civetweb's logic.
|
||||||
// This function is called when the request is read, parsed and validated,
|
// This function is called when the request is read, parsed and validated,
|
||||||
// and Mongoose must decide what action to take: serve a file, or
|
// and Civetweb must decide what action to take: serve a file, or
|
||||||
// a directory, or call embedded function, etcetera.
|
// a directory, or call embedded function, etcetera.
|
||||||
static void handle_request(struct mg_connection *conn) {
|
static void handle_request(struct mg_connection *conn) {
|
||||||
struct mg_request_info *ri = &conn->request_info;
|
struct mg_request_info *ri = &conn->request_info;
|
@ -18,8 +18,8 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#ifndef MONGOOSE_HEADER_INCLUDED
|
#ifndef CIVETWEB_HEADER_INCLUDED
|
||||||
#define MONGOOSE_HEADER_INCLUDED
|
#define CIVETWEB_HEADER_INCLUDED
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -53,30 +53,30 @@ struct mg_request_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// This structure needs to be passed to mg_start(), to let mongoose know
|
// This structure needs to be passed to mg_start(), to let civetweb know
|
||||||
// which callbacks to invoke. For detailed description, see
|
// which callbacks to invoke. For detailed description, see
|
||||||
// https://github.com/valenok/mongoose/blob/master/UserManual.md
|
// https://github.com/valenok/civetweb/blob/master/UserManual.md
|
||||||
struct mg_callbacks {
|
struct mg_callbacks {
|
||||||
// Called when mongoose has received new HTTP request.
|
// Called when civetweb has received new HTTP request.
|
||||||
// If callback returns non-zero,
|
// If callback returns non-zero,
|
||||||
// callback must process the request by sending valid HTTP headers and body,
|
// callback must process the request by sending valid HTTP headers and body,
|
||||||
// and mongoose will not do any further processing.
|
// and civetweb will not do any further processing.
|
||||||
// If callback returns 0, mongoose processes the request itself. In this case,
|
// If callback returns 0, civetweb processes the request itself. In this case,
|
||||||
// callback must not send any data to the client.
|
// callback must not send any data to the client.
|
||||||
int (*begin_request)(struct mg_connection *);
|
int (*begin_request)(struct mg_connection *);
|
||||||
|
|
||||||
// Called when mongoose has finished processing request.
|
// Called when civetweb has finished processing request.
|
||||||
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
void (*end_request)(const struct mg_connection *, int reply_status_code);
|
||||||
|
|
||||||
// Called when mongoose is about to log a message. If callback returns
|
// Called when civetweb is about to log a message. If callback returns
|
||||||
// non-zero, mongoose does not log anything.
|
// non-zero, civetweb does not log anything.
|
||||||
int (*log_message)(const struct mg_connection *, const char *message);
|
int (*log_message)(const struct mg_connection *, const char *message);
|
||||||
|
|
||||||
// Called when mongoose initializes SSL library.
|
// Called when civetweb initializes SSL library.
|
||||||
int (*init_ssl)(void *ssl_context, void *user_data);
|
int (*init_ssl)(void *ssl_context, void *user_data);
|
||||||
|
|
||||||
// Called when websocket request is received, before websocket handshake.
|
// Called when websocket request is received, before websocket handshake.
|
||||||
// If callback returns 0, mongoose proceeds with handshake, otherwise
|
// If callback returns 0, civetweb proceeds with handshake, otherwise
|
||||||
// cinnection is closed immediately.
|
// cinnection is closed immediately.
|
||||||
int (*websocket_connect)(const struct mg_connection *);
|
int (*websocket_connect)(const struct mg_connection *);
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ struct mg_callbacks {
|
|||||||
int (*websocket_data)(struct mg_connection *, int bits,
|
int (*websocket_data)(struct mg_connection *, int bits,
|
||||||
char *data, size_t data_len);
|
char *data, size_t data_len);
|
||||||
|
|
||||||
// Called when mongoose tries to open a file. Used to intercept file open
|
// Called when civetweb tries to open a file. Used to intercept file open
|
||||||
// calls, and serve file data from memory instead.
|
// calls, and serve file data from memory instead.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// path: Full path to the file to open.
|
// path: Full path to the file to open.
|
||||||
@ -107,19 +107,19 @@ struct mg_callbacks {
|
|||||||
const char * (*open_file)(const struct mg_connection *,
|
const char * (*open_file)(const struct mg_connection *,
|
||||||
const char *path, size_t *data_len);
|
const char *path, size_t *data_len);
|
||||||
|
|
||||||
// Called when mongoose is about to serve Lua server page (.lp file), if
|
// Called when civetweb is about to serve Lua server page (.lp file), if
|
||||||
// Lua support is enabled.
|
// Lua support is enabled.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// lua_context: "lua_State *" pointer.
|
// lua_context: "lua_State *" pointer.
|
||||||
void (*init_lua)(struct mg_connection *, void *lua_context);
|
void (*init_lua)(struct mg_connection *, void *lua_context);
|
||||||
|
|
||||||
// Called when mongoose has uploaded a file to a temporary directory as a
|
// Called when civetweb has uploaded a file to a temporary directory as a
|
||||||
// result of mg_upload() call.
|
// result of mg_upload() call.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// file_file: full path name to the uploaded file.
|
// file_file: full path name to the uploaded file.
|
||||||
void (*upload)(struct mg_connection *, const char *file_name);
|
void (*upload)(struct mg_connection *, const char *file_name);
|
||||||
|
|
||||||
// Called when mongoose is about to send HTTP error to the client.
|
// Called when civetweb is about to send HTTP error to the client.
|
||||||
// Implementing this callback allows to create custom error pages.
|
// Implementing this callback allows to create custom error pages.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// status: HTTP error status code.
|
// status: HTTP error status code.
|
||||||
@ -131,7 +131,7 @@ struct mg_callbacks {
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// callbacks: mg_callbacks structure with user-defined callbacks.
|
// callbacks: mg_callbacks structure with user-defined callbacks.
|
||||||
// options: NULL terminated list of option_name, option_value pairs that
|
// options: NULL terminated list of option_name, option_value pairs that
|
||||||
// specify Mongoose configuration parameters.
|
// specify Civetweb configuration parameters.
|
||||||
//
|
//
|
||||||
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
|
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
|
||||||
// processing is required for these, signal handlers must be set up
|
// processing is required for these, signal handlers must be set up
|
||||||
@ -146,7 +146,7 @@ struct mg_callbacks {
|
|||||||
// };
|
// };
|
||||||
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
|
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
|
||||||
//
|
//
|
||||||
// Refer to https://github.com/valenok/mongoose/blob/master/UserManual.md
|
// Refer to https://github.com/valenok/civetweb/blob/master/UserManual.md
|
||||||
// for the list of valid option and their possible values.
|
// for the list of valid option and their possible values.
|
||||||
//
|
//
|
||||||
// Return:
|
// Return:
|
||||||
@ -159,13 +159,13 @@ struct mg_context *mg_start(const struct mg_callbacks *callbacks,
|
|||||||
// Stop the web server.
|
// Stop the web server.
|
||||||
//
|
//
|
||||||
// Must be called last, when an application wants to stop the web server and
|
// Must be called last, when an application wants to stop the web server and
|
||||||
// release all associated resources. This function blocks until all Mongoose
|
// release all associated resources. This function blocks until all Civetweb
|
||||||
// threads are stopped. Context pointer becomes invalid.
|
// threads are stopped. Context pointer becomes invalid.
|
||||||
void mg_stop(struct mg_context *);
|
void mg_stop(struct mg_context *);
|
||||||
|
|
||||||
|
|
||||||
// Get the value of particular configuration parameter.
|
// Get the value of particular configuration parameter.
|
||||||
// The value returned is read-only. Mongoose does not allow changing
|
// The value returned is read-only. Civetweb does not allow changing
|
||||||
// configuration at run time.
|
// configuration at run time.
|
||||||
// If given parameter name is not valid, NULL is returned. For valid
|
// If given parameter name is not valid, NULL is returned. For valid
|
||||||
// names, return value is guaranteed to be non-NULL. If parameter is not
|
// names, return value is guaranteed to be non-NULL. If parameter is not
|
||||||
@ -212,7 +212,7 @@ int mg_write(struct mg_connection *, const void *buf, size_t len);
|
|||||||
|
|
||||||
// Send data to a websocket client wrapped in a websocket frame.
|
// Send data to a websocket client wrapped in a websocket frame.
|
||||||
// It is unsafe to read/write to this connection from another thread.
|
// It is unsafe to read/write to this connection from another thread.
|
||||||
// This function is available when mongoose is compiled with -DUSE_WEBSOCKET
|
// This function is available when civetweb is compiled with -DUSE_WEBSOCKET
|
||||||
//
|
//
|
||||||
// Return:
|
// Return:
|
||||||
// 0 when the connection has been closed
|
// 0 when the connection has been closed
|
||||||
@ -358,7 +358,7 @@ int mg_start_thread(mg_thread_func_t f, void *p);
|
|||||||
const char *mg_get_builtin_mime_type(const char *file_name);
|
const char *mg_get_builtin_mime_type(const char *file_name);
|
||||||
|
|
||||||
|
|
||||||
// Return Mongoose version.
|
// Return Civetweb version.
|
||||||
const char *mg_version(void);
|
const char *mg_version(void);
|
||||||
|
|
||||||
// URL-decode input buffer into destination buffer.
|
// URL-decode input buffer into destination buffer.
|
||||||
@ -383,4 +383,4 @@ char *mg_md5(char buf[33], ...);
|
|||||||
}
|
}
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // MONGOOSE_HEADER_INCLUDED
|
#endif // CIVETWEB_HEADER_INCLUDED
|
@ -3,11 +3,11 @@ CFLAGS= -W -Wall -I.. -pthread -g
|
|||||||
all:
|
all:
|
||||||
OS=`uname`; \
|
OS=`uname`; \
|
||||||
test "$$OS" = Linux && LIBS="-ldl" ; \
|
test "$$OS" = Linux && LIBS="-ldl" ; \
|
||||||
$(CC) $(CFLAGS) hello.c ../mongoose.c $$LIBS $(ADD) -o hello;
|
$(CC) $(CFLAGS) hello.c ../civetweb.c $$LIBS $(ADD) -o hello;
|
||||||
$(CC) $(CFLAGS) upload.c ../mongoose.c $$LIBS $(ADD) -o upload;
|
$(CC) $(CFLAGS) upload.c ../civetweb.c $$LIBS $(ADD) -o upload;
|
||||||
$(CC) $(CFLAGS) post.c ../mongoose.c $$LIBS $(ADD) -o post;
|
$(CC) $(CFLAGS) post.c ../civetweb.c $$LIBS $(ADD) -o post;
|
||||||
$(CC) $(CFLAGS) -DUSE_WEBSOCKET websocket.c ../mongoose.c $$LIBS $(ADD) -o websocket;
|
$(CC) $(CFLAGS) -DUSE_WEBSOCKET websocket.c ../civetweb.c $$LIBS $(ADD) -o websocket;
|
||||||
$(CC) $(CFLAGS) chat.c ../mongoose.c $$LIBS $(ADD) -o chat
|
$(CC) $(CFLAGS) chat.c ../civetweb.c $$LIBS $(ADD) -o chat
|
||||||
|
|
||||||
|
|
||||||
MSVC = e:/vc6
|
MSVC = e:/vc6
|
||||||
@ -17,12 +17,12 @@ CLFLAGS = /MD /TC /nologo $(DBG) /W3 /DNO_SSL \
|
|||||||
/link /incremental:no /libpath:$(MSVC)/lib /machine:IX86
|
/link /incremental:no /libpath:$(MSVC)/lib /machine:IX86
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
$(CL) upload.c ../mongoose.c $(CLFLAGS)
|
$(CL) upload.c ../civetweb.c $(CLFLAGS)
|
||||||
$(CL) hello.c ../mongoose.c $(CLFLAGS)
|
$(CL) hello.c ../civetweb.c $(CLFLAGS)
|
||||||
$(CL) upload.c ../mongoose.c $(CLFLAGS)
|
$(CL) upload.c ../civetweb.c $(CLFLAGS)
|
||||||
$(CL) post.c ../mongoose.c $(CLFLAGS)
|
$(CL) post.c ../civetweb.c $(CLFLAGS)
|
||||||
$(CL) post.c ../mongoose.c $(CLFLAGS)
|
$(CL) post.c ../civetweb.c $(CLFLAGS)
|
||||||
$(CL) /DUSE_WEBSOCKET websocket.c ../mongoose.c $(CLFLAGS)
|
$(CL) /DUSE_WEBSOCKET websocket.c ../civetweb.c $(CLFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf hello upload post websocket chat *.exe *.dSYM *.obj
|
rm -rf hello upload post websocket chat *.exe *.dSYM *.obj
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// This file is part of the Mongoose project, http://code.google.com/p/mongoose
|
// This file is part of the Civetweb project, http://code.google.com/p/civetweb
|
||||||
// It implements an online chat server. For more details,
|
// It implements an online chat server. For more details,
|
||||||
// see the documentation on the project web site.
|
// see the documentation on the project web site.
|
||||||
// To test the application,
|
// To test the application,
|
||||||
@ -13,7 +13,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
#define MAX_USER_LEN 20
|
#define MAX_USER_LEN 20
|
||||||
#define MAX_MESSAGE_LEN 100
|
#define MAX_MESSAGE_LEN 100
|
||||||
@ -341,7 +341,7 @@ static int begin_request_handler(struct mg_connection *conn) {
|
|||||||
} else if (strcmp(request_info->uri, "/ajax/send_message") == 0) {
|
} else if (strcmp(request_info->uri, "/ajax/send_message") == 0) {
|
||||||
ajax_send_message(conn, request_info);
|
ajax_send_message(conn, request_info);
|
||||||
} else {
|
} else {
|
||||||
// No suitable handler found, mark as not processed. Mongoose will
|
// No suitable handler found, mark as not processed. Civetweb will
|
||||||
// try to serve the request.
|
// try to serve the request.
|
||||||
processed = 0;
|
processed = 0;
|
||||||
}
|
}
|
||||||
@ -364,7 +364,7 @@ int main(void) {
|
|||||||
// the session identifier creation.
|
// the session identifier creation.
|
||||||
srand((unsigned) time(0));
|
srand((unsigned) time(0));
|
||||||
|
|
||||||
// Setup and start Mongoose
|
// Setup and start Civetweb
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
callbacks.begin_request = begin_request_handler;
|
callbacks.begin_request = begin_request_handler;
|
||||||
if ((ctx = mg_start(&callbacks, NULL, options)) == NULL) {
|
if ((ctx = mg_start(&callbacks, NULL, options)) == NULL) {
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
// This function will be called by mongoose on every new request.
|
// This function will be called by civetweb on every new request.
|
||||||
static int begin_request_handler(struct mg_connection *conn) {
|
static int begin_request_handler(struct mg_connection *conn) {
|
||||||
const struct mg_request_info *request_info = mg_get_request_info(conn);
|
const struct mg_request_info *request_info = mg_get_request_info(conn);
|
||||||
char content[100];
|
char content[100];
|
||||||
|
|
||||||
// Prepare the message we're going to send
|
// Prepare the message we're going to send
|
||||||
int content_length = snprintf(content, sizeof(content),
|
int content_length = snprintf(content, sizeof(content),
|
||||||
"Hello from mongoose! Remote port: %d",
|
"Hello from civetweb! Remote port: %d",
|
||||||
request_info->remote_port);
|
request_info->remote_port);
|
||||||
|
|
||||||
// Send HTTP reply to the client
|
// Send HTTP reply to the client
|
||||||
@ -21,8 +21,8 @@ static int begin_request_handler(struct mg_connection *conn) {
|
|||||||
"%s",
|
"%s",
|
||||||
content_length, content);
|
content_length, content);
|
||||||
|
|
||||||
// Returning non-zero tells mongoose that our function has replied to
|
// Returning non-zero tells civetweb that our function has replied to
|
||||||
// the client, and mongoose should not send client any more data.
|
// the client, and civetweb should not send client any more data.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
||||||
<!-- This file is part of the Mongoose project,
|
<!-- This file is part of the Civetweb project,
|
||||||
http://code.google.com/p/mongoose -->
|
http://code.google.com/p/civetweb -->
|
||||||
<head>
|
<head>
|
||||||
<title>Mongoose chat server</title>
|
<title>Civetweb chat server</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
||||||
<link type="text/css" rel="stylesheet" href="style.css"/>
|
<link type="text/css" rel="stylesheet" href="style.css"/>
|
||||||
<script src="jquery.js"></script>
|
<script src="jquery.js"></script>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<div id="logo"></div>
|
<div id="logo"></div>
|
||||||
<div class="rounded infobox help-message" id="motd">
|
<div class="rounded infobox help-message" id="motd">
|
||||||
Chat room implemented using
|
Chat room implemented using
|
||||||
<a href="http://code.google.com/p/mongoose" target="_blank">Mongoose</a>
|
<a href="http://code.google.com/p/civetweb" target="_blank">Civetweb</a>
|
||||||
embeddable web server.
|
embeddable web server.
|
||||||
This application was written for educational purposes demonstrating
|
This application was written for educational purposes demonstrating
|
||||||
how web interface could be decoupled from the business logic. Not a
|
how web interface could be decoupled from the business logic. Not a
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
|
||||||
<!-- This file is part of the Mongoose project,
|
<!-- This file is part of the Civetweb project,
|
||||||
http://code.google.com/p/mongoose -->
|
http://code.google.com/p/civetweb -->
|
||||||
<head>
|
<head>
|
||||||
<title>Mongoose chat: login</title>
|
<title>Civetweb chat: login</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
||||||
<!--
|
<!--
|
||||||
Note that this page is self-sufficient, it does not load any other
|
Note that this page is self-sufficient, it does not load any other
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<center>
|
<center>
|
||||||
<h2>Mongoose chat server login</h2>
|
<h2>Civetweb chat server login</h2>
|
||||||
<div style="max-width: 30em;">
|
<div style="max-width: 30em;">
|
||||||
Username and password can be any non-empty strings.
|
Username and password can be any non-empty strings.
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// This file is part of Mongoose project, http://code.google.com/p/mongoose
|
// This file is part of Civetweb project, http://code.google.com/p/civetweb
|
||||||
|
|
||||||
var chat = {
|
var chat = {
|
||||||
// Backend URL, string.
|
// Backend URL, string.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
static const char *html_form =
|
static const char *html_form =
|
||||||
"<html><body>POST example."
|
"<html><body>POST example."
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Copyright (c) 2004-2012 Sergey Lyubka
|
// Copyright (c) 2004-2012 Sergey Lyubka
|
||||||
// This file is a part of mongoose project, http://github.com/valenok/mongoose
|
// This file is a part of civetweb project, http://github.com/valenok/civetweb
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -15,7 +15,7 @@ typedef __int64 int64_t;
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif // !_WIN32
|
#endif // !_WIN32
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
static int begin_request_handler(struct mg_connection *conn) {
|
static int begin_request_handler(struct mg_connection *conn) {
|
||||||
if (!strcmp(mg_get_request_info(conn)->uri, "/handle_post_request")) {
|
if (!strcmp(mg_get_request_info(conn)->uri, "/handle_post_request")) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// Copyright (c) 2004-2012 Sergey Lyubka
|
// Copyright (c) 2004-2012 Sergey Lyubka
|
||||||
// This file is a part of mongoose project, http://github.com/valenok/mongoose
|
// This file is a part of civetweb project, http://github.com/valenok/civetweb
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
static void websocket_ready_handler(struct mg_connection *conn) {
|
static void websocket_ready_handler(struct mg_connection *conn) {
|
||||||
static const char *message = "server ready";
|
static const char *message = "server ready";
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style> div {font: small Verdana; } </style>
|
<style> div {font: small Verdana; } </style>
|
||||||
<h2>Mongoose WebSocket Test</h2>
|
<h2>Civetweb WebSocket Test</h2>
|
||||||
|
|
||||||
<div style="width: 400px; color: #aaa; padding: 1em; ">
|
<div style="width: 400px; color: #aaa; padding: 1em; ">
|
||||||
This page code creates websocket to the URI "/foo",
|
This page code creates websocket to the URI "/foo",
|
||||||
|
66
main.c
66
main.c
@ -35,7 +35,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -70,10 +70,10 @@
|
|||||||
static int exit_flag;
|
static int exit_flag;
|
||||||
static char server_name[40]; // Set by init_server_name()
|
static char server_name[40]; // Set by init_server_name()
|
||||||
static char config_file[PATH_MAX]; // Set by process_command_line_arguments()
|
static char config_file[PATH_MAX]; // Set by process_command_line_arguments()
|
||||||
static struct mg_context *ctx; // Set by start_mongoose()
|
static struct mg_context *ctx; // Set by start_civetweb()
|
||||||
|
|
||||||
#if !defined(CONFIG_FILE)
|
#if !defined(CONFIG_FILE)
|
||||||
#define CONFIG_FILE "mongoose.conf"
|
#define CONFIG_FILE "civetweb.conf"
|
||||||
#endif /* !CONFIG_FILE */
|
#endif /* !CONFIG_FILE */
|
||||||
|
|
||||||
static void WINCDECL signal_handler(int sig_num) {
|
static void WINCDECL signal_handler(int sig_num) {
|
||||||
@ -101,12 +101,12 @@ static void show_usage_and_exit(void) {
|
|||||||
const char **names;
|
const char **names;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf(stderr, "Mongoose version %s (c) Sergey Lyubka, built on %s\n",
|
fprintf(stderr, "Civetweb version %s (c) Sergey Lyubka, built on %s\n",
|
||||||
mg_version(), __DATE__);
|
mg_version(), __DATE__);
|
||||||
fprintf(stderr, "Usage:\n");
|
fprintf(stderr, "Usage:\n");
|
||||||
fprintf(stderr, " mongoose -A <htpasswd_file> <realm> <user> <passwd>\n");
|
fprintf(stderr, " civetweb -A <htpasswd_file> <realm> <user> <passwd>\n");
|
||||||
fprintf(stderr, " mongoose [config_file]\n");
|
fprintf(stderr, " civetweb [config_file]\n");
|
||||||
fprintf(stderr, " mongoose [-option value ...]\n");
|
fprintf(stderr, " civetweb [-option value ...]\n");
|
||||||
fprintf(stderr, "\nOPTIONS:\n");
|
fprintf(stderr, "\nOPTIONS:\n");
|
||||||
|
|
||||||
names = mg_get_valid_option_names();
|
names = mg_get_valid_option_names();
|
||||||
@ -119,12 +119,12 @@ static void show_usage_and_exit(void) {
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(USE_COCOA)
|
#if defined(_WIN32) || defined(USE_COCOA)
|
||||||
static const char *config_file_top_comment =
|
static const char *config_file_top_comment =
|
||||||
"# Mongoose web server configuration file.\n"
|
"# Civetweb web server configuration file.\n"
|
||||||
"# For detailed description of every option, visit\n"
|
"# For detailed description of every option, visit\n"
|
||||||
"# https://github.com/valenok/mongoose/blob/master/UserManual.md\n"
|
"# https://github.com/valenok/civetweb/blob/master/UserManual.md\n"
|
||||||
"# Lines starting with '#' and empty lines are ignored.\n"
|
"# Lines starting with '#' and empty lines are ignored.\n"
|
||||||
"# To make a change, remove leading '#', modify option's value,\n"
|
"# To make a change, remove leading '#', modify option's value,\n"
|
||||||
"# save this file and then restart Mongoose.\n\n";
|
"# save this file and then restart Civetweb.\n\n";
|
||||||
|
|
||||||
static const char *get_url_to_first_open_port(const struct mg_context *ctx) {
|
static const char *get_url_to_first_open_port(const struct mg_context *ctx) {
|
||||||
static char url[100];
|
static char url[100];
|
||||||
@ -258,7 +258,7 @@ static void process_command_line_arguments(char *argv[], char **options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void init_server_name(void) {
|
static void init_server_name(void) {
|
||||||
snprintf(server_name, sizeof(server_name), "Mongoose web server v.%s",
|
snprintf(server_name, sizeof(server_name), "Civetweb web server v.%s",
|
||||||
mg_version());
|
mg_version());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,13 +296,13 @@ static void verify_existence(char **options, const char *option_name,
|
|||||||
if (path != NULL && (stat(path, &st) != 0 ||
|
if (path != NULL && (stat(path, &st) != 0 ||
|
||||||
((S_ISDIR(st.st_mode) ? 1 : 0) != must_be_dir))) {
|
((S_ISDIR(st.st_mode) ? 1 : 0) != must_be_dir))) {
|
||||||
die("Invalid path for %s: [%s]: (%s). Make sure that path is either "
|
die("Invalid path for %s: [%s]: (%s). Make sure that path is either "
|
||||||
"absolute, or it is relative to mongoose executable.",
|
"absolute, or it is relative to civetweb executable.",
|
||||||
option_name, path, strerror(errno));
|
option_name, path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_absolute_path(char *options[], const char *option_name,
|
static void set_absolute_path(char *options[], const char *option_name,
|
||||||
const char *path_to_mongoose_exe) {
|
const char *path_to_civetweb_exe) {
|
||||||
char path[PATH_MAX], abs[PATH_MAX], *option_value;
|
char path[PATH_MAX], abs[PATH_MAX], *option_value;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
@ -312,14 +312,14 @@ static void set_absolute_path(char *options[], const char *option_name,
|
|||||||
// If option is already set and it is an absolute path,
|
// If option is already set and it is an absolute path,
|
||||||
// leave it as it is -- it's already absolute.
|
// leave it as it is -- it's already absolute.
|
||||||
if (option_value != NULL && !is_path_absolute(option_value)) {
|
if (option_value != NULL && !is_path_absolute(option_value)) {
|
||||||
// Not absolute. Use the directory where mongoose executable lives
|
// Not absolute. Use the directory where civetweb executable lives
|
||||||
// be the relative directory for everything.
|
// be the relative directory for everything.
|
||||||
// Extract mongoose executable directory into path.
|
// Extract civetweb executable directory into path.
|
||||||
if ((p = strrchr(path_to_mongoose_exe, DIRSEP)) == NULL) {
|
if ((p = strrchr(path_to_civetweb_exe, DIRSEP)) == NULL) {
|
||||||
getcwd(path, sizeof(path));
|
getcwd(path, sizeof(path));
|
||||||
} else {
|
} else {
|
||||||
snprintf(path, sizeof(path), "%.*s", (int) (p - path_to_mongoose_exe),
|
snprintf(path, sizeof(path), "%.*s", (int) (p - path_to_civetweb_exe),
|
||||||
path_to_mongoose_exe);
|
path_to_civetweb_exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncat(path, "/", sizeof(path) - 1);
|
strncat(path, "/", sizeof(path) - 1);
|
||||||
@ -331,7 +331,7 @@ static void set_absolute_path(char *options[], const char *option_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_mongoose(int argc, char *argv[]) {
|
static void start_civetweb(int argc, char *argv[]) {
|
||||||
struct mg_callbacks callbacks;
|
struct mg_callbacks callbacks;
|
||||||
char *options[MAX_OPTIONS];
|
char *options[MAX_OPTIONS];
|
||||||
int i;
|
int i;
|
||||||
@ -357,7 +357,7 @@ static void start_mongoose(int argc, char *argv[]) {
|
|||||||
process_command_line_arguments(argv, options);
|
process_command_line_arguments(argv, options);
|
||||||
|
|
||||||
// Make sure we have absolute paths for files and directories
|
// Make sure we have absolute paths for files and directories
|
||||||
// https://github.com/valenok/mongoose/issues/181
|
// https://github.com/valenok/civetweb/issues/181
|
||||||
set_absolute_path(options, "document_root", argv[0]);
|
set_absolute_path(options, "document_root", argv[0]);
|
||||||
set_absolute_path(options, "put_delete_auth_file", argv[0]);
|
set_absolute_path(options, "put_delete_auth_file", argv[0]);
|
||||||
set_absolute_path(options, "cgi_interpreter", argv[0]);
|
set_absolute_path(options, "cgi_interpreter", argv[0]);
|
||||||
@ -375,7 +375,7 @@ static void start_mongoose(int argc, char *argv[]) {
|
|||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
// Start Mongoose
|
// Start Civetweb
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
callbacks.log_message = &log_message;
|
callbacks.log_message = &log_message;
|
||||||
ctx = mg_start(&callbacks, NULL, (const char **) options);
|
ctx = mg_start(&callbacks, NULL, (const char **) options);
|
||||||
@ -384,7 +384,7 @@ static void start_mongoose(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
die("%s", "Failed to start Mongoose.");
|
die("%s", "Failed to start Civetweb.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +516,7 @@ static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP) {
|
|||||||
save_config(hDlg, fp);
|
save_config(hDlg, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
mg_stop(ctx);
|
mg_stop(ctx);
|
||||||
start_mongoose(__argc, __argv);
|
start_civetweb(__argc, __argv);
|
||||||
}
|
}
|
||||||
EnableWindow(GetDlgItem(hDlg, ID_SAVE), TRUE);
|
EnableWindow(GetDlgItem(hDlg, ID_SAVE), TRUE);
|
||||||
break;
|
break;
|
||||||
@ -572,7 +572,7 @@ static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP) {
|
|||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_SMALL, (LPARAM) hIcon);
|
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_SMALL, (LPARAM) hIcon);
|
||||||
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_BIG, (LPARAM) hIcon);
|
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_BIG, (LPARAM) hIcon);
|
||||||
SetWindowText(hDlg, "Mongoose settings");
|
SetWindowText(hDlg, "Civetweb settings");
|
||||||
SetFocus(GetDlgItem(hDlg, ID_SAVE));
|
SetFocus(GetDlgItem(hDlg, ID_SAVE));
|
||||||
for (i = 0; options[i * 2] != NULL; i++) {
|
for (i = 0; options[i * 2] != NULL; i++) {
|
||||||
name = options[i * 2];
|
name = options[i * 2];
|
||||||
@ -712,7 +712,7 @@ static void show_settings_dialog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int manage_service(int action) {
|
static int manage_service(int action) {
|
||||||
static const char *service_name = "Mongoose";
|
static const char *service_name = "Civetweb";
|
||||||
SC_HANDLE hSCM = NULL, hService = NULL;
|
SC_HANDLE hSCM = NULL, hService = NULL;
|
||||||
SERVICE_DESCRIPTION descr = {server_name};
|
SERVICE_DESCRIPTION descr = {server_name};
|
||||||
char path[PATH_MAX + 20]; // Path to executable plus magic argument
|
char path[PATH_MAX + 20]; // Path to executable plus magic argument
|
||||||
@ -767,11 +767,11 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
|||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
if (__argv[1] != NULL &&
|
if (__argv[1] != NULL &&
|
||||||
!strcmp(__argv[1], service_magic_argument)) {
|
!strcmp(__argv[1], service_magic_argument)) {
|
||||||
start_mongoose(1, service_argv);
|
start_civetweb(1, service_argv);
|
||||||
StartServiceCtrlDispatcher(service_table);
|
StartServiceCtrlDispatcher(service_table);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
start_mongoose(__argc, __argv);
|
start_civetweb(__argc, __argv);
|
||||||
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -876,12 +876,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdline, int show) {
|
|||||||
#elif defined(USE_COCOA)
|
#elif defined(USE_COCOA)
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
@interface Mongoose : NSObject<NSApplicationDelegate>
|
@interface Civetweb : NSObject<NSApplicationDelegate>
|
||||||
- (void) openBrowser;
|
- (void) openBrowser;
|
||||||
- (void) shutDown;
|
- (void) shutDown;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation Mongoose
|
@implementation Civetweb
|
||||||
- (void) openBrowser {
|
- (void) openBrowser {
|
||||||
[[NSWorkspace sharedWorkspace]
|
[[NSWorkspace sharedWorkspace]
|
||||||
openURL:[NSURL URLWithString:
|
openURL:[NSURL URLWithString:
|
||||||
@ -900,13 +900,13 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdline, int show) {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
init_server_name();
|
init_server_name();
|
||||||
start_mongoose(argc, argv);
|
start_civetweb(argc, argv);
|
||||||
|
|
||||||
[NSAutoreleasePool new];
|
[NSAutoreleasePool new];
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
// Add delegate to process menu item actions
|
// Add delegate to process menu item actions
|
||||||
Mongoose *myDelegate = [[Mongoose alloc] autorelease];
|
Civetweb *myDelegate = [[Civetweb alloc] autorelease];
|
||||||
[NSApp setDelegate: myDelegate];
|
[NSApp setDelegate: myDelegate];
|
||||||
|
|
||||||
// Run this app as agent
|
// Run this app as agent
|
||||||
@ -945,7 +945,7 @@ int main(int argc, char *argv[]) {
|
|||||||
id item = [[[NSStatusBar systemStatusBar]
|
id item = [[[NSStatusBar systemStatusBar]
|
||||||
statusItemWithLength:NSVariableStatusItemLength] retain];
|
statusItemWithLength:NSVariableStatusItemLength] retain];
|
||||||
[item setHighlightMode:YES];
|
[item setHighlightMode:YES];
|
||||||
[item setImage:[NSImage imageNamed:@"mongoose_22x22.png"]];
|
[item setImage:[NSImage imageNamed:@"civetweb_22x22.png"]];
|
||||||
[item setMenu:menu];
|
[item setMenu:menu];
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
@ -959,7 +959,7 @@ int main(int argc, char *argv[]) {
|
|||||||
#else
|
#else
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
init_server_name();
|
init_server_name();
|
||||||
start_mongoose(argc, argv);
|
start_civetweb(argc, argv);
|
||||||
printf("%s started on port(s) %s with web root [%s]\n",
|
printf("%s started on port(s) %s with web root [%s]\n",
|
||||||
server_name, mg_get_option(ctx, "listening_ports"),
|
server_name, mg_get_option(ctx, "listening_ports"),
|
||||||
mg_get_option(ctx, "document_root"));
|
mg_get_option(ctx, "document_root"));
|
||||||
|
@ -269,7 +269,7 @@ static void prepare_lua_environment(struct mg_connection *conn, lua_State *L) {
|
|||||||
reg_function(L, "cry", lsp_cry, conn);
|
reg_function(L, "cry", lsp_cry, conn);
|
||||||
reg_function(L, "include", lsp_include, conn);
|
reg_function(L, "include", lsp_include, conn);
|
||||||
reg_function(L, "redirect", lsp_redirect, conn);
|
reg_function(L, "redirect", lsp_redirect, conn);
|
||||||
reg_string(L, "version", MONGOOSE_VERSION);
|
reg_string(L, "version", CIVETWEB_VERSION);
|
||||||
|
|
||||||
// Export request_info
|
// Export request_info
|
||||||
lua_pushstring(L, "request_info");
|
lua_pushstring(L, "request_info");
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
//
|
//
|
||||||
// Unit test for the mongoose web server. Tests embedded API.
|
// Unit test for the civetweb web server. Tests embedded API.
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "civetweb.h"
|
||||||
|
|
||||||
#if !defined(LISTENING_PORT)
|
#if !defined(LISTENING_PORT)
|
||||||
#define LISTENING_PORT "23456"
|
#define LISTENING_PORT "23456"
|
||||||
|
@ -5,8 +5,8 @@ Content-Type: text/html
|
|||||||
|
|
||||||
|
|
||||||
<p>This is an example Lua server page served by
|
<p>This is an example Lua server page served by
|
||||||
<a href="http://code.google.com/p/mongoose">Mongoose web server</a>.
|
<a href="http://code.google.com/p/civetweb">Civetweb web server</a>.
|
||||||
Mongoose has Lua, Sqlite, and other functionality built in the binary.
|
Civetweb has Lua, Sqlite, and other functionality built in the binary.
|
||||||
This example page stores the request in the Sqlite database, and shows
|
This example page stores the request in the Sqlite database, and shows
|
||||||
all requests done previously.</p>
|
all requests done previously.</p>
|
||||||
<p> Today is <? mg.write(os.date("%A")) ?>
|
<p> Today is <? mg.write(os.date("%A")) ?>
|
||||||
|
18
test/test.pl
18
test/test.pl
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
# This script is used to test Mongoose web server
|
# This script is used to test Civetweb web server
|
||||||
# $Id: test.pl 516 2010-05-03 12:54:37Z valenok $
|
# $Id: test.pl 516 2010-05-03 12:54:37Z valenok $
|
||||||
|
|
||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
@ -19,9 +19,9 @@ my $copy_cmd = on_windows() ? 'copy' : 'cp';
|
|||||||
my $test_dir_uri = "test_dir";
|
my $test_dir_uri = "test_dir";
|
||||||
my $root = 'test';
|
my $root = 'test';
|
||||||
my $test_dir = $root . $dir_separator. $test_dir_uri;
|
my $test_dir = $root . $dir_separator. $test_dir_uri;
|
||||||
my $config = 'mongoose.conf';
|
my $config = 'civetweb.conf';
|
||||||
my $exe_ext = on_windows() ? '.exe' : '';
|
my $exe_ext = on_windows() ? '.exe' : '';
|
||||||
my $mongoose_exe = '.' . $dir_separator . 'mongoose' . $exe_ext;
|
my $civetweb_exe = '.' . $dir_separator . 'civetweb' . $exe_ext;
|
||||||
my $embed_exe = '.' . $dir_separator . 'embed' . $exe_ext;
|
my $embed_exe = '.' . $dir_separator . 'embed' . $exe_ext;
|
||||||
my $unit_test_exe = '.' . $dir_separator . 'unit_test' . $exe_ext;
|
my $unit_test_exe = '.' . $dir_separator . 'unit_test' . $exe_ext;
|
||||||
my $exit_code = 0;
|
my $exit_code = 0;
|
||||||
@ -141,7 +141,7 @@ $SIG{ALRM} = sub { die "timeout\n" };
|
|||||||
# Make sure we export only symbols that start with "mg_", and keep local
|
# Make sure we export only symbols that start with "mg_", and keep local
|
||||||
# symbols static.
|
# symbols static.
|
||||||
if ($^O =~ /darwin|bsd|linux/) {
|
if ($^O =~ /darwin|bsd|linux/) {
|
||||||
my $out = `(cc -c mongoose.c && nm mongoose.o) | grep ' T '`;
|
my $out = `(cc -c civetweb.c && nm civetweb.o) | grep ' T '`;
|
||||||
foreach (split /\n/, $out) {
|
foreach (split /\n/, $out) {
|
||||||
/T\s+_?mg_.+/ or fail("Exported symbol $_")
|
/T\s+_?mg_.+/ or fail("Exported symbol $_")
|
||||||
}
|
}
|
||||||
@ -156,13 +156,13 @@ if (scalar(@ARGV) > 0 and $ARGV[0] eq 'unit') {
|
|||||||
# Command line options override config files settings
|
# Command line options override config files settings
|
||||||
write_file($config, "access_log_file access.log\n" .
|
write_file($config, "access_log_file access.log\n" .
|
||||||
"listening_ports 127.0.0.1:12345\n");
|
"listening_ports 127.0.0.1:12345\n");
|
||||||
spawn("$mongoose_exe -listening_ports 127.0.0.1:$port");
|
spawn("$civetweb_exe -listening_ports 127.0.0.1:$port");
|
||||||
o("GET /test/hello.txt HTTP/1.0\n\n", 'HTTP/1.1 200 OK', 'Loading config file');
|
o("GET /test/hello.txt HTTP/1.0\n\n", 'HTTP/1.1 200 OK', 'Loading config file');
|
||||||
unlink $config;
|
unlink $config;
|
||||||
kill_spawned_child();
|
kill_spawned_child();
|
||||||
|
|
||||||
# Spawn the server on port $port
|
# Spawn the server on port $port
|
||||||
my $cmd = "$mongoose_exe ".
|
my $cmd = "$civetweb_exe ".
|
||||||
"-listening_ports 127.0.0.1:$port ".
|
"-listening_ports 127.0.0.1:$port ".
|
||||||
"-access_log_file access.log ".
|
"-access_log_file access.log ".
|
||||||
"-error_log_file debug.log ".
|
"-error_log_file debug.log ".
|
||||||
@ -415,9 +415,9 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
|
|||||||
# Manipulate the passwords file
|
# Manipulate the passwords file
|
||||||
my $path = 'test_htpasswd';
|
my $path = 'test_htpasswd';
|
||||||
unlink $path;
|
unlink $path;
|
||||||
system("$mongoose_exe -A $path a b c") == 0
|
system("$civetweb_exe -A $path a b c") == 0
|
||||||
or fail("Cannot add user in a passwd file");
|
or fail("Cannot add user in a passwd file");
|
||||||
system("$mongoose_exe -A $path a b c2") == 0
|
system("$civetweb_exe -A $path a b c2") == 0
|
||||||
or fail("Cannot edit user in a passwd file");
|
or fail("Cannot edit user in a passwd file");
|
||||||
my $content = read_file($path);
|
my $content = read_file($path);
|
||||||
$content =~ /^b:a:\w+$/gs or fail("Bad content of the passwd file");
|
$content =~ /^b:a:\w+$/gs or fail("Bad content of the passwd file");
|
||||||
@ -429,7 +429,7 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub do_PUT_test {
|
sub do_PUT_test {
|
||||||
# This only works because mongoose currently doesn't look at the nonce.
|
# This only works because civetweb currently doesn't look at the nonce.
|
||||||
# It should really be rejected...
|
# It should really be rejected...
|
||||||
my $auth_header = "Authorization: Digest username=guest, ".
|
my $auth_header = "Authorization: Digest username=guest, ".
|
||||||
"realm=mydomain.com, nonce=1145872809, uri=/put.txt, ".
|
"realm=mydomain.com, nonce=1145872809, uri=/put.txt, ".
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
//
|
//
|
||||||
// Unit test for the mongoose web server. Tests embedded API.
|
// Unit test for the civetweb web server. Tests embedded API.
|
||||||
|
|
||||||
#define USE_WEBSOCKET
|
#define USE_WEBSOCKET
|
||||||
#define USE_LUA
|
#define USE_LUA
|
||||||
@ -28,9 +28,9 @@
|
|||||||
#define USE_IPV6
|
#define USE_IPV6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// USE_* definitions must be made before #include "mongoose.c" !
|
// USE_* definitions must be made before #include "civetweb.c" !
|
||||||
|
|
||||||
#include "mongoose.c"
|
#include "civetweb.c"
|
||||||
|
|
||||||
static int s_total_tests = 0;
|
static int s_total_tests = 0;
|
||||||
static int s_failed_tests = 0;
|
static int s_failed_tests = 0;
|
||||||
@ -223,7 +223,7 @@ static void upload_cb(struct mg_connection *conn, const char *path) {
|
|||||||
|
|
||||||
if (atoi(ri->query_string) == 1) {
|
if (atoi(ri->query_string) == 1) {
|
||||||
ASSERT(!strcmp(path, "./upload_test.txt"));
|
ASSERT(!strcmp(path, "./upload_test.txt"));
|
||||||
ASSERT((p1 = read_file("mongoose.c", &len1)) != NULL);
|
ASSERT((p1 = read_file("civetweb.c", &len1)) != NULL);
|
||||||
ASSERT((p2 = read_file(path, &len2)) != NULL);
|
ASSERT((p2 = read_file(path, &len2)) != NULL);
|
||||||
ASSERT(len1 == len2);
|
ASSERT(len1 == len2);
|
||||||
ASSERT(memcmp(p1, p2, len1) == 0);
|
ASSERT(memcmp(p1, p2, len1) == 0);
|
||||||
@ -231,7 +231,7 @@ static void upload_cb(struct mg_connection *conn, const char *path) {
|
|||||||
remove(upload_filename);
|
remove(upload_filename);
|
||||||
} else if (atoi(ri->query_string) == 2) {
|
} else if (atoi(ri->query_string) == 2) {
|
||||||
if (!strcmp(path, "./upload_test.txt")) {
|
if (!strcmp(path, "./upload_test.txt")) {
|
||||||
ASSERT((p1 = read_file("mongoose.h", &len1)) != NULL);
|
ASSERT((p1 = read_file("civetweb.h", &len1)) != NULL);
|
||||||
ASSERT((p2 = read_file(path, &len2)) != NULL);
|
ASSERT((p2 = read_file(path, &len2)) != NULL);
|
||||||
ASSERT(len1 == len2);
|
ASSERT(len1 == len2);
|
||||||
ASSERT(memcmp(p1, p2, len1) == 0);
|
ASSERT(memcmp(p1, p2, len1) == 0);
|
||||||
@ -328,12 +328,12 @@ static void test_mg_download(void) {
|
|||||||
"GET / HTTP/1.0\r\n\r\n")) != NULL);
|
"GET / HTTP/1.0\r\n\r\n")) != NULL);
|
||||||
mg_close_connection(conn);
|
mg_close_connection(conn);
|
||||||
|
|
||||||
// Fetch mongoose.c, should succeed
|
// Fetch civetweb.c, should succeed
|
||||||
ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
|
ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
|
||||||
"GET /mongoose.c HTTP/1.0\r\n\r\n")) != NULL);
|
"GET /civetweb.c HTTP/1.0\r\n\r\n")) != NULL);
|
||||||
ASSERT(!strcmp(conn->request_info.uri, "200"));
|
ASSERT(!strcmp(conn->request_info.uri, "200"));
|
||||||
ASSERT((p1 = read_conn(conn, &len1)) != NULL);
|
ASSERT((p1 = read_conn(conn, &len1)) != NULL);
|
||||||
ASSERT((p2 = read_file("mongoose.c", &len2)) != NULL);
|
ASSERT((p2 = read_file("civetweb.c", &len2)) != NULL);
|
||||||
ASSERT(len1 == len2);
|
ASSERT(len1 == len2);
|
||||||
ASSERT(memcmp(p1, p2, len1) == 0);
|
ASSERT(memcmp(p1, p2, len1) == 0);
|
||||||
free(p1), free(p2);
|
free(p1), free(p2);
|
||||||
@ -395,7 +395,7 @@ static void test_mg_upload(void) {
|
|||||||
ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL);
|
ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL);
|
||||||
|
|
||||||
// Upload one file
|
// Upload one file
|
||||||
ASSERT((file_data = read_file("mongoose.c", &file_len)) != NULL);
|
ASSERT((file_data = read_file("civetweb.c", &file_len)) != NULL);
|
||||||
post_data = NULL;
|
post_data = NULL;
|
||||||
post_data_len = alloc_printf(&post_data, 0,
|
post_data_len = alloc_printf(&post_data, 0,
|
||||||
"--%s\r\n"
|
"--%s\r\n"
|
||||||
@ -421,7 +421,7 @@ static void test_mg_upload(void) {
|
|||||||
mg_close_connection(conn);
|
mg_close_connection(conn);
|
||||||
|
|
||||||
// Upload two files
|
// Upload two files
|
||||||
ASSERT((file_data = read_file("mongoose.h", &file_len)) != NULL);
|
ASSERT((file_data = read_file("civetweb.h", &file_len)) != NULL);
|
||||||
ASSERT((file2_data = read_file("README.md", &file2_len)) != NULL);
|
ASSERT((file2_data = read_file("README.md", &file2_len)) != NULL);
|
||||||
post_data = NULL;
|
post_data = NULL;
|
||||||
post_data_len = alloc_printf(&post_data, 0,
|
post_data_len = alloc_printf(&post_data, 0,
|
||||||
|
Reference in New Issue
Block a user