Compare commits

...
50 Commits
Author SHA1 Message Date
Sergey Lyubka 409c12a851 Better logic for port resolving 2015-03-18 17:25:46 +00:00
Sergey Lyubka bcdcbf20ee Release 5.6 2015-03-18 17:25:31 +00:00
Sergey Lyubka 8fc5b5a55f Add contribution section to readme 2015-03-18 15:45:52 +00:00
Sergey Lyubka faeedb2930 Sync main 2015-03-18 09:37:52 +00:00
Sergey Lyubka c8e8f94ffe Sync main 2015-03-17 17:35:31 +00:00
Sergey Lyubka 22aeb6111b Update ReleaseNotes 2015-03-17 17:01:16 +00:00
Sergey Lyubka 2d1d2e6534 SIZE_MAX is not defined on MSVC6, use (size_t) ~0 2015-03-17 17:00:59 +00:00
Sergey Lyubka 05c88a98fc Introduce -dav_root option 2015-03-17 15:34:56 +00:00
Marko Mikulicic 5224afb946 Merge pull request #485 from dsrosario/fix_remove_double_dots 2015-03-17 16:07:46 +01:00
Dinis Rosário 3bd79c7cd5 Fix remove_double_dots_and_double_slashes removing all the dots leading http server to serve wrong URI
If the uri is something like '/js/...jquery.js', remove_double_dots_and_double_slashes will remove the 3 dots and the http server will serves the /js/jquery.js file.
remove_double_dots_and_double_slashes should check if a dot or double dots is followed by a slash (or backslash) and only remove this to avoid disclosure attack.
2015-03-17 16:04:59 +01:00
Sergey Lyubka c52e0744cb Squashed warnings after size_t change 2015-03-17 13:18:15 +00:00
Sergey Lyubka 6c09c303d0 Merge pull request #456 from sebgod/fix-win32-examples-using-extra
Enable building of example/Makefile on Win32
2015-03-17 11:45:36 +00:00
Sergey Lyubka b6fde06990 Merge pull request #486 from mmicko/master
Compile fix
2015-03-16 16:52:48 +00:00
Miodrag Milanovic af892c9726 compile fix for visual studio 2015-03-14 09:02:25 +01:00
Miodrag Milanovic df7ad13680 Compile fix 2015-03-13 20:15:19 +01:00
Sergey Lyubka 057c2d4b42 Merge pull request #484 from davidmilligan/master
fix compiler warnings for 64 bit compilation
2015-03-10 18:40:16 +00:00
David Milligan 6c9b43bcf5 fix compiler warnings for 64 bit compilation 2015-03-09 20:01:09 -04:00
Sergey Lyubka a91438acae Fix #477 2015-03-09 16:09:05 +00:00
Sergey Lyubka a6fa51dbc2 Merge pull request #481 from cesanta/web_server_ssl
web_server_ssl
2015-03-06 14:39:50 +00:00
Alexander Alashkin 6ceac6c84c web_server_ssl 2015-03-06 15:08:57 +02:00
Sergey Lyubka 288efe3c23 Add -DMONGOOSE_ENABLE_THREADS to other examples 2015-03-06 09:29:56 +00:00
Sergey Lyubka 5207545a8b Add -DMONGOOSE_ENABLE_THREADS to proxy server example 2015-03-06 09:28:27 +00:00
Sergey Lyubka 716d524f9b Add -DMONGOOSE_ENABLE_THREADS to Makefile 2015-03-06 09:25:30 +00:00
Sergey Lyubka a434bab767 Merge pull request #480 from cesanta/polarssl_examples_1
websocket_ssl_proxy sample for polarsll
2015-03-06 09:03:38 +00:00
Alexander Alashkin e9633a8d2d websocket_ssl_proxy 2015-03-06 09:32:08 +02:00
Sergey Lyubka c7b6a6f0ea Added mg_websocket_printf() 2015-03-05 10:54:51 +00:00
Sergey Lyubka 6cdb9f7ed3 Merge pull request #474 from mmicko/master
OS/2 patches by KO Myung-Hun
2015-03-04 17:18:16 +00:00
Sergey Lyubka 4502dd0c86 s/MONGOOSE_NO_THREADS/MONGOOSE_ENABLE_THREADS 2015-03-03 18:59:23 +00:00
Sergey Lyubka 95055f6048 Add winsock2.h include for win32 2015-03-03 18:32:14 +00:00
Sergey Lyubka 2c36532ec4 Merge pull request #465 from doug16rogers/vs9-compile-ipv6
Allow for compilation in Visual Studio with NS_ENABLE_IPV6.
2015-03-03 18:28:07 +00:00
Sergey Lyubka f2b0b9c737 Fix Win32 build in mg_websocket_write() 2015-02-24 13:32:22 +00:00
Sergey Lyubka b3866439a0 Fix mg_create_server() signature 2015-02-24 13:17:11 +00:00
Miodrag Milanovic 4f2205a667 OS/2 patches by KO Myung-Hun
Upstream patch from MAME project
2015-02-24 11:12:09 +01:00
Sergey Lyubka 6cec1d36a8 Merge pull request #463 from CurlyMoo/patch-1
Replace obsolete gethostbyname by getaddrinfo
2015-02-19 11:48:35 +00:00
CurlyMoo 4238370ae1 Check for getaddrinfo availability. 2015-02-19 12:09:34 +01:00
Sergey Lyubka b4924b715e Merge pull request #473 from mmicko/master
Fix for MINGW builds
2015-02-17 16:19:37 +00:00
Miodrag Milanovic 7a0385dcac Fix for MINGW builds 2015-02-17 11:08:23 +01:00
Sergey Lyubka 44a146faf6 SSL fixes 2015-02-16 18:34:07 +00:00
Sergey Lyubka 53a55da7bc Add type cast in ns_out() 2015-02-16 18:19:15 +00:00
Sergey Lyubka bf44277764 Define _XOPEN_SOURCE for MinGW build 2015-02-16 18:17:30 +00:00
Sergey Lyubka a2e1da6e30 Add overflow checks 2015-02-12 19:12:58 +00:00
Sergey Lyubka bef3f85ba8 Merge pull request #466 from 0-wiz-0/master
Only define _XOPEN_SOURCE on Linux.
2015-02-10 18:07:07 +00:00
Thomas Klausner eb72a63cca Only define _XOPEN_SOURCE on Linux.
Fixes the build on NetBSD.

The comment says it's only needed on Linux, and AFAIK Linux
is the only operating system that only adds symbols when it's defined;
others, like NetBSD or Solaris, also hide symbols.

Signed-off-by: Thomas Klausner <wiz@NetBSD.org>
2015-01-29 15:02:26 +01:00
Doug Rogers f19bbc73cc Allow for compilation in Visual Studio 9 (2008) with NS_ENABLE_IPV6. 2015-01-29 00:12:35 -05:00
Sergey Lyubka 25326b3b12 net skeleton -> fossa 2015-01-28 12:33:48 +00:00
CurlyMoo 10ee430bfd Add debug line and adapt to styling guide
Replaced tabs with spaces.
2015-01-27 22:55:13 +01:00
CurlyMoo 10d0bfdab4 Replace obsolete gethostbyname by getaddrinfo
This also protect against the latest glibc bug
2015-01-27 22:45:34 +01:00
Sergey Lyubka 6b6637c337 Adopt SSL guide to current way of setting SSL cert. 2015-01-21 17:41:45 +00:00
Sergey Lyubka 878acca213 Removed Lua docs 2015-01-21 17:30:30 +00:00
Sebastian Godelet 8082501b9c Enable building of example/Makefile on Win32
Adding example/.gitignore to ignore *.exe
Appending -lws2_32 at the end of CFLAGS_EXTRA if running make on
Windows to enable easy compiling under that platform.
Obsoletes pull request #454
2015-01-10 16:41:58 +08:00
17 changed files with 340 additions and 182 deletions

No files matched your search

+10 -22
View File
@@ -45,24 +45,13 @@ Download, double-click to start, run browser -- that's all!
![shot3](http://cesanta.com/images/tut_sharing/tut3.png)
![shot4](http://cesanta.com/images/tut_sharing/tut4.png)
# Acknowledgements
# Contributions
Mongoose made better thanks to the contribution of following people:
Arnout Vandecappelle, Benoît Amiaux, Boris Pek, Cody Hanson, Colin Leitner,
Daniel Oaks, Eric Bakan, Erik Oomen, Filipp Kovalev, Ger Hobbelt,
Hendrik Polczynski, Igor Okulist, Jay, Joe Mucchiello, John Safranek,
José Miguel Gonçalves, Shueng Chuan, Katerina Blinova, Konstantin Sorokin,
Marin Atanasov, Matt Healy, Mitch Hendrickson, Nigel Stewart, Pavel Khlebovich,
Sebastian Reinhard, Stefan Doehla, abadc0de, nullable.type,
T.Barmann, D.Hughes, J.C.Sloan, R.Romeo, L.E.Spencer, S.Kotay, R.M.Shorter,
W.Mar, J.Wilander, Santa from Memphis, S.Davies, C.Beck,
O.M.Vilhunen, C.Radik, G.Woodcock, M.Szczepkowski,
Eternal Lands Dev Team, T.Tollet, C.Tangerino, G.Karsai, A.Bourgett,
C.Blakemore, D.Fonaryov, T.Andrle, O.IJsselmuiden, R.Womack, M.Tomlinson,
A.Slåttå, L.Farrell, J.D.P.Ballestero, V.Albaev, B.Harker, T.Scheffel, H.Klein,
R.Merit, T.Bennett, H.Solis, A.Zincenko, M.S., S.Krul, K.Cooke, S.McCallum,
F.Morenius, and 10 others.
People who have agreed to the
[Cesanta CLA](http://cesanta.com/contributors_la.html)
can make contributions. Note that the CLA isn't a copyright
_assigment_ but rather a copyright _license_.
You retain the copyright on your contributions.
# Licensing
@@ -72,17 +61,16 @@ source licenses. The GPLv2 open source License does not generally permit
incorporating this software into non-open source programs.
For those customers who do not wish to comply with the GPLv2 open
source license requirements,
[Cesanta Software](http://cesanta.com) offers a full,
[Cesanta](http://cesanta.com) offers a full,
royalty-free commercial license and professional support
without any of the GPL restrictions.
# Other products by Cesanta Software: simple and effective
# Other products by Cesanta
- [Fossa](http://github.com/cesanta/fossa) - Multi-protocol networking library
- [SSL Wrapper](https://github.com/cesanta/ssl_wrapper) - application to
secure network communications
- [Frozen](https://github.com/cesanta/frozen) - JSON parser and generator
- [SLRE](https://github.com/cesanta/slre) - Super Light Regular Expression
library
- [Net Skeleton](https://github.com/cesanta/net_skeleton) - framework for
building network applications
- [SLDR](https://github.com/cesanta/sldr) - Super Light DNS Resolver
- [V7](https://github.com/cesanta/v7) - Embedded JavaScript engine
+13 -10
View File
@@ -1,6 +1,6 @@
# Mongoose API Reference
struct mg_server *mg_create_server(void *server_param);
struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
Creates web server instance. Returns opaque instance pointer, or NULL if
there is not enough memory. `server_param`: Could be any pointer, or NULL.
@@ -173,7 +173,7 @@ a response body. Mongoose provides functions for all three parts:
Mongoose will call a handler repeatedly after each socket write.
<!-- -->
void mg_send_file(struct mg_connection *, const char *path);
Tells Mongoose to serve given file. Mongoose handles file according to
@@ -183,11 +183,14 @@ points to a directory, Mongoose will show directory listing. If this function
is used, no calls to `mg_send*` or `mg_printf*` functions must be made, and
event handler must return `MG_MORE`.
int mg_websocket_write(struct mg_connection* conn, int opcode,
const char *data, size_t data_len);
size_t mg_websocket_write(struct mg_connection* conn, int opcode,
const char *data, size_t data_len);
size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
const char *fmt, ...);
Similar to `mg_write()`, but wraps the data into a websocket frame with a
given websocket `opcode`.
Similar to `mg_write()` and `mg_printf()`, but wraps the data into a
websocket frame with a given websocket `opcode`.
const char *mg_get_header(const struct mg_connection *, const char *name);
@@ -219,15 +222,15 @@ the length of the fetched value, or 0 if variable not found.
const char *user,
const char *password);
Add, edit or delete the entry in the passwords file.
Add, edit or delete the entry in the passwords file.
This function allows an application to manipulate .htpasswd files on the
fly by adding, deleting and changing user records. This is one of the
several ways of implementing authentication on the server side.
several ways of implementing authentication on the server side.
If password is not NULL, entry is added (or modified if already exists).
If password is NULL, entry is deleted.
If password is NULL, entry is deleted.
Return: 1 on success, 0 on error.
int mg_parse_multipart(const char *buf, int buf_len,
char *var_name, int var_name_len,
char *file_name, int file_name_len,
+1 -1
View File
@@ -149,7 +149,7 @@ all Net Skeleton functions will be available too.
-DMONGOOSE_NO_DIRECTORY_LISTING Disable directory listing
-DMONGOOSE_NO_FILESYSTEM Disables all file IO, serving from memory only
-DMONGOOSE_NO_LOGGING Disable access/error logging
-DMONGOOSE_NO_THREADS
-DMONGOOSE_ENABLE_THREADS Enable mg_start_thread() function
-DMONGOOSE_NO_WEBSOCKET Disable WebSocket support
-DMONGOOSE_NO_USER No concept of a user on used platform.
(Platform does not provide getpwnam, setgid or setuid)
-51
View File
@@ -1,51 +0,0 @@
# Mongoose Lua Server Pages
Pre-built Windows and Mac mongoose binaries support Lua Server Pages
functionality.
That means it is possible to write PHP-like scripts with mongoose
using Lua programming language instead of PHP. Lua is known
for it's speed and small size. Mongoose uses Lua version 5.2.3, the
documentation for it can be found at
[Lua 5.2 reference manual](http://www.lua.org/manual/5.2/).
To create a Lua Page, make a file that is called `ANY_NAME.lp`. For example,
`my_page.lp`. It is important to have a file
name that ends up with `.lp`, cause this is the way mongoose recognises
Lua Page file. The contents of the file, just like
with PHP, is HTML with embedded Lua code. Lua code must be enclosed within
`&lt;? ?&gt;` blocks, and can appear anywhere on the page.
Mongoose does not send HTTP headers for Lua pages. Therefore,
every Lua Page must begin with HTTP status line and headers, like this:
<? mg.write('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') ?>
<html><body>
<span>Today is:</span> <? mg.write(os.date("%A")) ?>
</body></html>
Note that this example uses function `mg.write()`, which prints data to the
web page. Using function `mg.write()` is the way to generate web content from
inside Lua code. In addition to `mg.write()`, all standard library functions
are accessible from the Lua code (please check reference manual for details).
Information about the request is available via the `mg.request_info` object.
I contains request method, all headers, etcetera. Please refer to
`struct mg_request_info` definition in
[mongoose.h](https://github.com/cesanta/mongoose/blob/master/mongoose.h)
to see what is available via the `mg.request_info` object.
Check out [prime_numbers.lp](https://github.com/cesanta/mongoose/blob/master/examples/lua/prime_numbers.lp) for some example.
Mongoose exports the following to the Lua Server Page:
mg.write(str) -- writes string to the client
mg.onerror(msg) -- error handler, can be overridden
mg.request_info -- a table with request information
Using Lua scripting it is easy to emulate SSI functionality. For example,
to include the content of another file, one can write:
<? mg.write(io.open('MY_FILE.TXT'):read('*all')) ?>
To serve a Lua Page, mongoose creates Lua context. That context is used for
all Lua blocks within the page. That means, all Lua blocks on the same page
share the same context. If one block defines a variable, for example, that
variable is visible in all following blocks.
+25
View File
@@ -1,5 +1,30 @@
# Mongoose Release Notes
## Release 5.6, 2015-03-17
Changes in Libmongoose library:
- Added `-dav_root` configuration option that gives an ability to mount
a different root directory (not document_root)
- Fixes for build under Win23 and MinGW
- Bugfix: Double dots removal
- Bugfix: final chunked response double-send
- Fixed compilation in 64-bit environments
- Added OS/2 compatibility
- Added `getaddrinfo()` call and `NS_ENABLE_GETADDRINFO`
- Various SSL-related fixes
- Added integer overflow protection in `iobuf_append()` and `deliver_websocket_frame()`
- Fixed NetBSD build
- Enabled `NS_ENABLE_IPV6` build for Visual Studio 2008+
- Enhanced comma detection in `parse_header()`
- Fixed unchanged memory accesses on ARM
- Added ability to use custom memory allocator through NS_MALLOC, NS_FREE, NS_REALLOC
Changes in Mongoose binary:
- Added `-start_browser` option to disable automatic browser launch
- Added experimental SSL support. To listen on HTTPS port, use `ssl://PORT:SSL_CERT` format. For example, to listen on HTTP port 8080 and HTTPS port 8043, use `-listening_port 8080,ssl://8043:ssl_cert.pem`
## Release 5.5, October 28 2014
Changes in Libmongoose library:
+5 -10
View File
@@ -1,20 +1,15 @@
# Mongoose SSL guide
SSL is a protocol that makes web communication secure. To enable SSL
in mongoose, 3 steps are required:
in mongoose, 2 steps are required:
1. Valid certificate file must be created
2. `ssl_certificate` options must be set to contain path to the
certificate file.
3. `listening_ports` option must contain a port number with letter `s`
appended to it, which instructs Mongoose to use SSL for all connections
made to that port.
1. Create valid SSL certificate file
2. Append SSL certificate file path to the `listening_ports` option
Below is the `mongoose.conf` file snippet for typical SSL setup:
document_root www_root # Serve files in www_root directory
listening_ports 80r,443s # Redirect all HTTP requests to HTTPS
ssl_certificate ssl_cert.pem # Location of certificate file
document_root www_root # Serve files in www_root directory
listening_ports 80,443:cert.pem # Listen on ports 80 and 443
## How to create SSL certificate file
+1
View File
@@ -0,0 +1 @@
*.exe
+7 -2
View File
@@ -3,13 +3,18 @@
SUBDIRS = $(sort $(filter-out csharp/, $(dir $(wildcard */))))
X = $(SUBDIRS)
ifdef WINDIR
# appending the Winsock2 library at the end of the compiler
# invocation
CFLAGS_EXTRA += -lws2_32
endif
.PHONY: $(SUBDIRS)
all: $(SUBDIRS)
$(SUBDIRS):
@$(MAKE) -C $@
@$(MAKE) CFLAGS_EXTRA="$(CFLAGS_EXTRA)" -C $@
clean:
for d in $(SUBDIRS) ; do $(MAKE) -C $$d clean ; done
for d in $(SUBDIRS) ; do $(MAKE) -C $$d clean ; done
+1 -1
View File
@@ -2,7 +2,7 @@
# All rights reserved
PROG = multi_threaded_server
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
CFLAGS = -W -Wall -I../.. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS $(CFLAGS_EXTRA)
SOURCES = $(PROG).c ../../mongoose.c
$(PROG): $(SOURCES)
+1 -1
View File
@@ -3,7 +3,7 @@
PROG = proxy_server
FLAGS = -I../.. -DNS_ENABLE_SSL
CFLAGS = -W -Wall -g -O0 -pthread -lssl $(FLAGS) $(CFLAGS_EXTRA)
CFLAGS = -W -Wall -g -O0 -pthread -lssl -DMONGOOSE_ENABLE_THREADS $(FLAGS) $(CFLAGS_EXTRA)
SOURCES = $(PROG).c ../../mongoose.c
unix: $(SOURCES)
+17 -1
View File
@@ -2,11 +2,27 @@
# All rights reserved
PROG = web_server
CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
CFLAGS = -W -Wall -I../.. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS $(CFLAGS_EXTRA)
SOURCES = $(PROG).c ../../mongoose.c
OPENSSL_FLAGS = -DNS_ENABLE_SSL -lssl
# PolarSSL paths and flags
POLARSSL_PATH = /usr/local
POLARSSLCOMPAT_PATH = ./../../../polar
SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR) -DNS_ENABLE_SSL
#
$(PROG): $(SOURCES)
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
openssl:
$(CC) -o $(PROG) $(SOURCES) $(CFLAGS) $(OPENSSL_FLAGS)
polarssl:
$(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
clean:
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
+46
View File
@@ -0,0 +1,46 @@
-----BEGIN CERTIFICATE-----
MIIC+zCCAeOgAwIBAgIJAPhB8jbL+G82MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
BAMMCTEyNy4wLjAuMTAeFw0xNTAzMDYxMjQzMzNaFw0yNTAzMDMxMjQzMzNaMBQx
EjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALi3b3daMgzUEROKob1Caf68i+//cTRkPdBJv2cOBak21CdQzY0Nvx73GLzf
5TKB347BCHNbYRKGJXDbYdmFp20/WeBHkY7RS3Ad2Q5lzyx66u9PxNx7hJIiqBgF
58VU+E3o/I+o8QNIoOT+wtCiq3Nwkp+zGBJmS32rzMEV9bcKxSzMrkfRhF+XAREd
DwM9vfPg6WRb/b+vv06uvVwcw390RprLautGfBdaRddVYkIAKJGRRTqZAvTRFW1J
FcIVOxlN+iA7qP7xjr3tUP78qMmlu0MXsHrUR2cgfveZK2sdUW5G804yHsU5sC8l
FbtLKMEOyLsk2bEIScOXgum7g2sCAwEAAaNQME4wHQYDVR0OBBYEFHtLzUqAsXkH
Il8S5sMhJuVhRJLdMB8GA1UdIwQYMBaAFHtLzUqAsXkHIl8S5sMhJuVhRJLdMAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEzHc0AOr+qs0OFvWMfcSMi7
O/aYlLS6f7Sos+lli69+61EcmCTJVarVeAVUsAoqmzBKDbeOpAK1hGX6/GGcXjR2
BmuU0hUKyX9l1lwdMKU45BayH/riElwnvAyj2GxKoPpdIjlHns4SAITOCUx9NfpM
agd7kjolton0ZQ5DI/2a43PkqHv1lY4Dp60wJlxit9U68bsGOycCJ/BsAyrPROb2
D1MkpMBIdfHc8uxRywM3/l9buFX8yrrMUGOYKgfjDwdzbj0iwIixoGpHL7IfeBtu
dvGO/g2rEhbtAP+xIgOR3GvzqjZh30er3no7zjDMn65tTME18Aq3tBQY7vPDKms=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4t293WjIM1BET
iqG9Qmn+vIvv/3E0ZD3QSb9nDgWpNtQnUM2NDb8e9xi83+Uygd+OwQhzW2EShiVw
22HZhadtP1ngR5GO0UtwHdkOZc8seurvT8Tce4SSIqgYBefFVPhN6PyPqPEDSKDk
/sLQoqtzcJKfsxgSZkt9q8zBFfW3CsUszK5H0YRflwERHQ8DPb3z4OlkW/2/r79O
rr1cHMN/dEaay2rrRnwXWkXXVWJCACiRkUU6mQL00RVtSRXCFTsZTfogO6j+8Y69
7VD+/KjJpbtDF7B61EdnIH73mStrHVFuRvNOMh7FObAvJRW7SyjBDsi7JNmxCEnD
l4Lpu4NrAgMBAAECggEAaFuqbAHXOQwuwZ2XFzgIblTTsrncmT7w9VZU/sIbTKif
X771AnX7vmDX5w2PjeN2DE7emV3NEAwd5w7qz1wFZWFfQ6jrgYaZWjRixxGZ5IVl
aeLlU7OtCGrwEPJ1KTWCO3IgDoHh+Hr1+6o7Imhk+QlmrTcfqHWGvO9s9MGVWt2S
RLAnSTFiOe5brdJnmlqq1sKZmnLmpydBaPUOYpZGAgRasrjdMZB+lZOazd1x23/5
GAcm0rDREMnO9b2Jt+TNEZHT6d5KpVoExztZEZj8QCLXoic/SpFIqHGtpNlQXa+d
BVqgQbIYjO8ldldxZ8YIyJDVF+9e/uBBwu6jBIIsEQKBgQDspEHCyyuh4LG+7BbZ
eXlsfCxPTM6K9w31ZwHAwRtAuGqrOrE+pFJG9CEsFZbAI1aOGmZZdjexuSMcOlXl
TIVJTQHoFtoGEsanYEXO4O1t02Ab/DCYSpXusXUraRBRPpsTC77Sh5mxLUNd23d9
NhnDBuwChAmC+IYexjkXeqPYFwKBgQDH08PEd+2PVo4MD8UVKUlEcgoyCr6ESiyp
HfYyhhfd5x3DbZLoKCkunDfBs/hakQk8DA2nn4tl4ZjfmzXmX0EBx+E5YTdYshW7
ZcjN5x64B5PEOAR/NZA6agNlp3XGXXXgX+gnN6pgE49eVU22nZ4G+QBKD6NcCviB
LBPUxMbvzQKBgHgZYRqonGtaqzsXfP1AjmSFnMNeWtDiU95BOf2Gw/sT3WcrsXr2
UJ+cFR3XkxvOk4YpVdp/igKT0ILqBGAMdvTdtWMB/gLpEpMt5B/7veRoS7XIRy1z
ZSawP6QZfWOOX4vKAT29/j2SmEcRNFKC245EfBFGy8EBuqfxuFX3MyJfAoGBAJ0y
tjsErVmpma1baosvI3g4zlR3p1CimWehLmCopHXorr1iocMIdP0535L+ZU258y3N
vaA0HpFTW9PsYgaMwLMJ7uAY3lVkIzx84e849i2HqHMgLkl0dbW+WFXL2xblxylv
yU2wuNNED/EB4lTawcpycAvTKYvrBXt4lVE4S9exAoGAGl6vZV3zyw4jpIw4uDfk
LTPYUrghFDDGKExyeOnC/W9pqR2veqzfBz02C3jqwhewoqgAcnNc2sg0rJmM+6Oz
Z2mmGZTHO9xR++7+W7e8AkQBbS6TB8a+7yNcM4USLP+b9sX5N+8gFhFs9tG7j/no
G44qLsJ/yve7/QsOA37uEMs=
-----END PRIVATE KEY-----
+2 -5
View File
@@ -96,11 +96,8 @@ static void __cdecl signal_handler(int sig_num) {
}
static void vnotify(const char *fmt, va_list ap, int must_exit) {
char msg[200];
vsnprintf(msg, sizeof(msg), fmt, ap);
fprintf(stderr, "%s\n", msg);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
if (must_exit) {
exit(EXIT_FAILURE);
}
+15 -3
View File
@@ -2,14 +2,26 @@
# All rights reserved
PROG = ws_ssl
CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 $(CFLAGS_EXTRA)
CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS -DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY $(CFLAGS_EXTRA)
LDFLAGS = -lssl
SOURCES = ws_ssl.c ../../mongoose.c ssl_wrapper.c
# PolarSSL paths and flags
POLARSSL_PATH = /usr/local
POLARSSLCOMPAT_PATH = ./../../../polar
SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR)
#
all: $(PROG)
$(PROG): $(SOURCES)
$(CC) -o $(PROG) $(SOURCES) \
-DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY -lssl $(CFLAGS)
$(CC) -o $(PROG) $(SOURCES) $(LDFLAGS) $(CFLAGS)
polarssl: $(SOURCES_POLAR)
$(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
clean:
rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
+181 -64
View File
@@ -34,8 +34,6 @@
//
// Alternatively, you can license this software under a commercial
// license, as set out in <http://cesanta.com/>.
//
// $Date: 2014-09-28 05:04:41 UTC $
#ifndef NS_SKELETON_HEADER_INCLUDED
#define NS_SKELETON_HEADER_INCLUDED
@@ -48,7 +46,9 @@
#define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
#define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
#undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
#ifdef __Linux__
#define _XOPEN_SOURCE 600 // For flockfile() on Linux
#endif
#define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
#define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
#ifndef _LARGEFILE_SOURCE
@@ -78,7 +78,11 @@
#ifdef _WIN32
#ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib") // Linking with winsock library
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <process.h>
#ifndef EINPROGRESS
@@ -122,7 +126,12 @@ typedef struct _stati64 ns_stat_t;
#include <sys/socket.h>
#include <sys/select.h>
#define closesocket(x) close(x)
#ifndef __OS2__
#define __cdecl
#else
#include <sys/time.h>
typedef int socklen_t;
#endif
#define INVALID_SOCKET (-1)
#define to64(x) strtoll(x, NULL, 10)
typedef int sock_t;
@@ -253,7 +262,7 @@ struct ns_connection *ns_bind(struct ns_mgr *, const char *,
struct ns_connection *ns_connect(struct ns_mgr *, const char *,
ns_callback_t, void *);
int ns_send(struct ns_connection *, const void *buf, int len);
int ns_send(struct ns_connection *, const void *buf, size_t len);
int ns_printf(struct ns_connection *, const char *fmt, ...);
int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
@@ -345,6 +354,11 @@ size_t iobuf_append(struct iobuf *io, const void *buf, size_t len) {
assert(io != NULL);
assert(io->len <= io->size);
/* check overflow */
if (len > ~(size_t)0 - (size_t)(io->buf + io->len)) {
return 0;
}
if (len <= 0) {
} else if (io->len + len <= io->size) {
memcpy(io->buf + io->len, buf, len);
@@ -370,7 +384,8 @@ void iobuf_remove(struct iobuf *io, size_t n) {
static size_t ns_out(struct ns_connection *nc, const void *buf, size_t len) {
if (nc->flags & NSF_UDP) {
long n = sendto(nc->sock, buf, len, 0, &nc->sa.sa, sizeof(nc->sa.sin));
long n = sendto(nc->sock, (const char *) buf, len, 0, &nc->sa.sa,
sizeof(nc->sa.sin));
DBG(("%p %d send %ld (%d %s)", nc, nc->sock, n, errno, strerror(errno)));
return n < 0 ? 0 : n;
} else {
@@ -593,6 +608,30 @@ int ns_socketpair(sock_t sp[2]) {
// TODO(lsm): use non-blocking resolver
static int ns_resolve2(const char *host, struct in_addr *ina) {
#ifdef NS_ENABLE_GETADDRINFO
int rv = 0;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_in *h = NULL;
char *ip = NS_MALLOC(17);
memset(ip, '\0', 17);
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if((rv = getaddrinfo(host, NULL , NULL, &servinfo)) != 0) {
DBG(("getaddrinfo(%s) failed: %s", host, strerror(errno)));
return 0;
}
for(p = servinfo; p != NULL; p = p->ai_next) {
memcpy(&h, &p->ai_addr, sizeof(struct sockaddr_in *));
memcpy(ina, &h->sin_addr, sizeof(ina));
}
freeaddrinfo(servinfo);
return 1;
#else
struct hostent *he;
if ((he = gethostbyname(host)) == NULL) {
DBG(("gethostbyname(%s) failed: %s", host, strerror(errno)));
@@ -601,6 +640,7 @@ static int ns_resolve2(const char *host, struct in_addr *ina) {
return 1;
}
return 0;
#endif
}
// Resolve FDQN "host", store IP address in the "ip".
@@ -659,8 +699,8 @@ static int ns_parse_address(const char *str, union socket_address *sa,
sa->sin.sin_port = htons((uint16_t) port);
}
if (*use_ssl && (sscanf(str + len, ":%99[^:]:%99[^:]%n", cert, ca, &n) == 2 ||
sscanf(str + len, ":%99[^:]%n", cert, &n) == 1)) {
if (*use_ssl && (sscanf(str + len, ":%99[^:,]:%99[^:,]%n", cert, ca, &n) == 2 ||
sscanf(str + len, ":%99[^:,]%n", cert, &n) == 1)) {
len += n;
}
@@ -893,6 +933,7 @@ static void ns_read_from_socket(struct ns_connection *conn) {
} else {
ok = 1;
}
conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
}
#endif
conn->flags &= ~NSF_CONNECTING;
@@ -921,6 +962,7 @@ static void ns_read_from_socket(struct ns_connection *conn) {
int ssl_err = ns_ssl_err(conn, res);
if (res == 1) {
conn->flags |= NSF_SSL_HANDSHAKE_DONE;
conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
} else if (ssl_err == SSL_ERROR_WANT_READ ||
ssl_err == SSL_ERROR_WANT_WRITE) {
return; // Call us again
@@ -958,6 +1000,8 @@ static void ns_write_to_socket(struct ns_connection *conn) {
} else {
conn->flags |= NSF_CLOSE_IMMEDIATELY;
}
} else {
conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE);
}
} else
#endif
@@ -973,14 +1017,14 @@ static void ns_write_to_socket(struct ns_connection *conn) {
}
}
int ns_send(struct ns_connection *conn, const void *buf, int len) {
int ns_send(struct ns_connection *conn, const void *buf, size_t len) {
return (int) ns_out(conn, buf, len);
}
static void ns_handle_udp(struct ns_connection *ls) {
struct ns_connection nc;
char buf[NS_UDP_RECEIVE_BUFFER_SIZE];
int n;
ssize_t n;
socklen_t s_len = sizeof(nc.sa);
memset(&nc, 0, sizeof(nc));
@@ -1266,12 +1310,7 @@ void ns_mgr_free(struct ns_mgr *s) {
#define STR(x) STRX(x)
#define __func__ __FILE__ ":" STR(__LINE__)
#endif
/* MINGW has adopted the MSVC formatting for 64-bit ints as of gcc 4.4 till 4.8*/
#if (defined(__MINGW32__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ < 8))) || defined(_MSC_VER)
#define INT64_FMT "I64d"
#else
#define INT64_FMT "lld"
#endif
#define flockfile(x) ((void) (x))
#define funlockfile(x) ((void) (x))
typedef struct _stati64 file_stat_t;
@@ -1342,7 +1381,7 @@ typedef pid_t process_id_t;
struct vec {
const char *ptr;
int len;
size_t len;
};
// For directory listing and WevDAV support
@@ -1365,6 +1404,7 @@ enum {
CGI_PATTERN,
#endif
DAV_AUTH_FILE,
DAV_ROOT,
DOCUMENT_ROOT,
#ifndef MONGOOSE_NO_DIRECTORY_LISTING
ENABLE_DIRECTORY_LISTING,
@@ -1403,6 +1443,7 @@ static const char *static_config_options[] = {
"cgi_pattern", DEFAULT_CGI_PATTERN,
#endif
"dav_auth_file", NULL,
"dav_root", NULL,
"document_root", NULL,
#ifndef MONGOOSE_NO_DIRECTORY_LISTING
"enable_directory_listing", "yes",
@@ -1447,7 +1488,7 @@ enum endpoint_type {
};
#define MG_HEADERS_SENT NSF_USER_1
#define MG_LONG_RUNNING NSF_USER_2
#define MG_USING_CHUNKED_API NSF_USER_2
#define MG_CGI_CONN NSF_USER_3
#define MG_PROXY_CONN NSF_USER_4
#define MG_PROXY_DONT_PARSE NSF_USER_5
@@ -1462,7 +1503,7 @@ struct connection {
char *request;
int64_t num_bytes_recv; // Total number of bytes received
int64_t cl; // Reply content length, for Range support
int request_len; // Request length, including last \r\n after last header
ssize_t request_len; // Request length, including last \r\n after last header
};
#define MG_CONN_2_CONN(c) ((struct connection *) ((char *) (c) - \
@@ -1527,11 +1568,11 @@ static const struct {
{NULL, 0, NULL}
};
#ifndef MONGOOSE_NO_THREADS
#ifdef MONGOOSE_ENABLE_THREADS
void *mg_start_thread(void *(*f)(void *), void *p) {
return ns_start_thread(f, p);
}
#endif // MONGOOSE_NO_THREADS
#endif // MONGOOSE_ENABLE_THREADS
#ifndef MONGOOSE_NO_MMAP
#ifdef _WIN32
@@ -1547,6 +1588,37 @@ static void *mmap(void *addr, int64_t len, int prot, int flags, int fd,
#define MAP_FAILED NULL
#define MAP_PRIVATE 0
#define PROT_READ 0
#elif defined(__OS2__)
static void *mmap(void *addr, int64_t len, int prot, int flags, int fd,
int offset) {
void *p;
int pos = lseek( fd, 0, SEEK_CUR ); /* Get a current position */
if (pos == -1)
return NULL;
/* Seek to offset offset */
if (lseek( fd, offset, SEEK_SET) == -1)
return NULL;
p = malloc(len);
/* Read in a file */
if (!p || read(fd, p, len) == -1) {
free(p);
p = NULL;
}
/* Restore the position */
lseek(fd, pos, SEEK_SET);
return p;
}
#define munmap(x, y) free(x)
#define MAP_FAILED NULL
#define MAP_PRIVATE 0
#define PROT_READ 0
#else
#include <sys/mman.h>
#endif
@@ -1673,9 +1745,9 @@ static int mg_snprintf(char *buf, size_t buflen, const char *fmt, ...) {
// -1 if request is malformed
// 0 if request is not yet fully buffered
// >0 actual request length, including last \r\n\r\n
static int get_request_len(const char *s, int buf_len) {
static int get_request_len(const char *s, size_t buf_len) {
const unsigned char *buf = (unsigned char *) s;
int i;
size_t i;
for (i = 0; i < buf_len; i++) {
// Control characters are not allowed but >=128 are.
@@ -2266,7 +2338,7 @@ static void on_cgi_data(struct ns_connection *nc) {
// If reply has not been parsed yet, parse it
if (conn->ns_conn->flags & NSF_BUFFER_BUT_DONT_SEND) {
struct iobuf *io = &conn->ns_conn->send_iobuf;
int s_len = sizeof(cgi_status) - 1;
size_t s_len = sizeof(cgi_status) - 1;
int len = get_request_len(io->buf + s_len, io->len - s_len);
char buf[MAX_REQUEST_SIZE], *s = buf;
@@ -2358,7 +2430,9 @@ static void remove_double_dots_and_double_slashes(char *s) {
// Skip all following slashes, backslashes and double-dots
while (s[0] != '\0') {
if (s[0] == '/' || s[0] == '\\') { s++; }
else if (s[0] == '.' && s[1] == '.') { s += 2; }
else if (s[0] == '.' && (s[1] == '/' || s[1] == '\\')) { s += 2; }
else if (s[0] == '.' && s[1] == '.' && s[2] == '\0') { s += 2; }
else if (s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\\')) { s += 3; }
else { break; }
}
}
@@ -2366,13 +2440,14 @@ static void remove_double_dots_and_double_slashes(char *s) {
*p = '\0';
}
int mg_url_decode(const char *src, int src_len, char *dst,
int dst_len, int is_form_url_encoded) {
int i, j, a, b;
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
int mg_url_decode(const char *src, size_t src_len, char *dst,
size_t dst_len, int is_form_url_encoded) {
size_t i, j = 0;
int a, b;
#define HEXTOI(x) (isdigit(x) ? (x) - '0' : (x) - 'W')
for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
if (src[i] == '%' && i < src_len - 2 &&
if (src[i] == '%' && i + 2 < src_len &&
isxdigit(* (const unsigned char *) (src + i + 1)) &&
isxdigit(* (const unsigned char *) (src + i + 2))) {
a = tolower(* (const unsigned char *) (src + i + 1));
@@ -2401,7 +2476,8 @@ static int is_valid_http_method(const char *s) {
// This function modifies the buffer by NUL-terminating
// HTTP request components, header names and header values.
// Note that len must point to the last \n of HTTP headers.
static int parse_http_message(char *buf, int len, struct mg_connection *ri) {
static size_t parse_http_message(char *buf, size_t len,
struct mg_connection *ri) {
int is_request, n;
// Reset the connection. Make sure that we don't touch fields that are
@@ -2409,6 +2485,8 @@ static int parse_http_message(char *buf, int len, struct mg_connection *ri) {
ri->request_method = ri->uri = ri->http_version = ri->query_string = NULL;
ri->num_headers = ri->status_code = ri->is_websocket = ri->content_len = 0;
if (len < 1) return ~0;
buf[len - 1] = '\0';
// RFC says that all initial whitespaces should be ingored
@@ -2424,7 +2502,7 @@ static int parse_http_message(char *buf, int len, struct mg_connection *ri) {
is_request = is_valid_http_method(ri->request_method);
if ((is_request && memcmp(ri->http_version, "HTTP/", 5) != 0) ||
(!is_request && memcmp(ri->request_method, "HTTP/", 5) != 0)) {
len = -1;
len = ~0;
} else {
if (is_request) {
ri->http_version += 5;
@@ -2483,7 +2561,7 @@ const char *mg_get_header(const struct mg_connection *ri, const char *s) {
}
// Perform case-insensitive match of string against pattern
int mg_match_prefix(const char *pattern, int pattern_len, const char *str) {
int mg_match_prefix(const char *pattern, ssize_t pattern_len, const char *str) {
const char *or_str;
int len, res, i = 0, j = 0;
@@ -2555,6 +2633,12 @@ void mg_template(struct mg_connection *conn, const char *s,
}
#ifndef MONGOOSE_NO_FILESYSTEM
static int is_dav_request(const struct connection *conn) {
const char *s = conn->mg_conn.request_method;
return !strcmp(s, "PUT") || !strcmp(s, "DELETE") ||
!strcmp(s, "MKCOL") || !strcmp(s, "PROPFIND");
}
static int must_hide_file(struct connection *conn, const char *path) {
const char *pw_pattern = "**" PASSWORDS_FILE_NAME "$";
const char *pattern = conn->server->config_options[HIDE_FILES_PATTERN];
@@ -2567,19 +2651,24 @@ static int convert_uri_to_file_name(struct connection *conn, char *buf,
size_t buf_len, file_stat_t *st) {
struct vec a, b;
const char *rewrites = conn->server->config_options[URL_REWRITES];
const char *root = conn->server->config_options[DOCUMENT_ROOT];
const char *root =
#ifndef MONGOOSE_NO_DAV
is_dav_request(conn) && conn->server->config_options[DAV_ROOT] != NULL ?
conn->server->config_options[DAV_ROOT] :
#endif
conn->server->config_options[DOCUMENT_ROOT];
#ifndef MONGOOSE_NO_CGI
const char *cgi_pat = conn->server->config_options[CGI_PATTERN];
char *p;
#endif
const char *uri = conn->mg_conn.uri;
const char *domain = mg_get_header(&conn->mg_conn, "Host");
int match_len, root_len = root == NULL ? 0 : strlen(root);
size_t match_len, root_len = root == NULL ? 0 : strlen(root);
// Perform virtual hosting rewrites
if (rewrites != NULL && domain != NULL) {
const char *colon = strchr(domain, ':');
int domain_len = colon == NULL ? (int) strlen(domain) : colon - domain;
size_t domain_len = colon == NULL ? strlen(domain) : colon - domain;
while ((rewrites = next_option(rewrites, &a, &b)) != NULL) {
if (a.len > 1 && a.ptr[0] == '@' && a.len == domain_len + 1 &&
@@ -2639,25 +2728,29 @@ static int should_keep_alive(const struct mg_connection *conn) {
(header == NULL && http_version && !strcmp(http_version, "1.1")));
}
size_t mg_write(struct mg_connection *c, const void *buf, int len) {
size_t mg_write(struct mg_connection *c, const void *buf, size_t len) {
struct connection *conn = MG_CONN_2_CONN(c);
ns_send(conn->ns_conn, buf, len);
return conn->ns_conn->send_iobuf.len;
}
void mg_send_status(struct mg_connection *c, int status) {
struct connection *conn = MG_CONN_2_CONN(c);
if (c->status_code == 0) {
c->status_code = status;
mg_printf(c, "HTTP/1.1 %d %s\r\n", status, status_code_to_str(status));
}
conn->ns_conn->flags |= MG_USING_CHUNKED_API;
}
void mg_send_header(struct mg_connection *c, const char *name, const char *v) {
struct connection *conn = MG_CONN_2_CONN(c);
if (c->status_code == 0) {
c->status_code = 200;
mg_printf(c, "HTTP/1.1 %d %s\r\n", 200, status_code_to_str(200));
}
mg_printf(c, "%s: %s\r\n", name, v);
conn->ns_conn->flags |= MG_USING_CHUNKED_API;
}
static void terminate_headers(struct mg_connection *c) {
@@ -2799,8 +2892,8 @@ static void SHA1Init(SHA1_CTX *context) {
}
static void SHA1Update(SHA1_CTX *context, const unsigned char *data,
uint32_t len) {
uint32_t i, j;
size_t len) {
size_t i, j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
@@ -2888,10 +2981,10 @@ static void send_websocket_handshake(struct mg_connection *conn,
mg_write(conn, buf, strlen(buf));
}
static int deliver_websocket_frame(struct connection *conn) {
static size_t deliver_websocket_frame(struct connection *conn) {
// Having buf unsigned char * is important, as it is used below in arithmetic
unsigned char *buf = (unsigned char *) conn->ns_conn->recv_iobuf.buf;
int i, len, buf_len = conn->ns_conn->recv_iobuf.len, frame_len = 0,
size_t i, len, buf_len = conn->ns_conn->recv_iobuf.len, frame_len = 0,
mask_len = 0, header_len = 0, data_len = 0, buffered = 0;
if (buf_len >= 2) {
@@ -2902,10 +2995,10 @@ static int deliver_websocket_frame(struct connection *conn) {
header_len = 2 + mask_len;
} else if (len == 126 && buf_len >= 4 + mask_len) {
header_len = 4 + mask_len;
data_len = ((((int) buf[2]) << 8) + buf[3]);
data_len = ((((size_t) buf[2]) << 8) + buf[3]);
} else if (buf_len >= 10 + mask_len) {
header_len = 10 + mask_len;
data_len = (int) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) +
data_len = (size_t) (((uint64_t) htonl(* (uint32_t *) &buf[2])) << 32) +
htonl(* (uint32_t *) &buf[6]);
}
}
@@ -2936,10 +3029,15 @@ static int deliver_websocket_frame(struct connection *conn) {
}
size_t mg_websocket_write(struct mg_connection *conn, int opcode,
const char *data, size_t data_len) {
const char *data, size_t data_len) {
unsigned char mem[4192], *copy = mem;
size_t copy_len = 0;
/* Check overflow */
if (data_len > ~(size_t)0 - (size_t)10) {
return 0;
}
if (data_len + 10 > sizeof(mem) &&
(copy = (unsigned char *) NS_MALLOC(data_len + 10)) == NULL) {
return 0;
@@ -2961,9 +3059,9 @@ size_t mg_websocket_write(struct mg_connection *conn, int opcode,
copy_len = 4 + data_len;
} else {
// 64-bit length field
copy[1] = 127;
const uint32_t hi = htonl((uint32_t) ((uint64_t) data_len >> 32));
const uint32_t lo = htonl(data_len & 0xffffffff);
copy[1] = 127;
memcpy(copy+2,&hi,sizeof(hi));
memcpy(copy+6,&lo,sizeof(lo));
memcpy(copy + 10, data, data_len);
@@ -3034,7 +3132,8 @@ static int call_request_handler(struct connection *conn) {
int result;
conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
if ((result = call_user(conn, MG_REQUEST)) == MG_TRUE) {
if (conn->ns_conn->flags & MG_HEADERS_SENT) {
if (conn->ns_conn->flags & MG_USING_CHUNKED_API) {
terminate_headers(&conn->mg_conn);
write_terminating_chunk(conn);
}
close_local_endpoint(conn);
@@ -3161,7 +3260,8 @@ static int find_index_file(struct connection *conn, char *path,
const char *list = conn->server->config_options[INDEX_FILES];
file_stat_t st;
struct vec filename_vec;
size_t n = strlen(path), found = 0;
size_t n = strlen(path);
int found = 0;
// The 'path' given to us points to the directory. Remove all trailing
// directory separator characters from the end of the path, and
@@ -3175,8 +3275,12 @@ static int find_index_file(struct connection *conn, char *path,
// path and see if the file exists. If it exists, break the loop
while ((list = next_option(list, &filename_vec, NULL)) != NULL) {
if (path_len <= n + 2) {
continue;
}
// Ignore too long entries that may overflow path buffer
if (filename_vec.len > (int) (path_len - (n + 2)))
if (filename_vec.len > (path_len - (n + 2)))
continue;
// Prepare full path to the index file
@@ -3419,7 +3523,7 @@ static int scan_directory(struct connection *conn, const char *dir,
return arr_ind;
}
int mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len) {
size_t mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len) {
static const char *dont_escape = "._-$,;~()";
static const char *hex = "0123456789abcdef";
size_t i = 0, j = 0;
@@ -3716,7 +3820,7 @@ static void handle_put(struct connection *conn, const char *path) {
static void forward_put_data(struct connection *conn) {
struct iobuf *io = &conn->ns_conn->recv_iobuf;
size_t k = conn->cl < (int64_t) io->len ? conn->cl : (int64_t) io->len; // To write
int n = write(conn->endpoint.fd, io->buf, k); // Write them!
size_t n = write(conn->endpoint.fd, io->buf, k); // Write them!
if (n > 0) {
iobuf_remove(io, n);
conn->cl -= n;
@@ -4095,17 +4199,12 @@ static int is_authorized_for_dav(struct connection *conn) {
return authorized;
}
static int is_dav_request(const struct connection *conn) {
const char *s = conn->mg_conn.request_method;
return !strcmp(s, "PUT") || !strcmp(s, "DELETE") ||
!strcmp(s, "MKCOL") || !strcmp(s, "PROPFIND");
}
#endif // MONGOOSE_NO_AUTH
static int parse_header(const char *str, int str_len, const char *var_name,
static int parse_header(const char *str, size_t str_len, const char *var_name,
char *buf, size_t buf_size) {
int ch = ' ', ch1 = ',', len = 0, n = strlen(var_name);
int ch = ' ', ch1 = ',', len = 0;
size_t n = strlen(var_name);
const char *p, *end = str + str_len, *s = NULL;
if (buf != NULL && buf_size > 0) buf[0] = '\0';
@@ -4146,7 +4245,7 @@ static void send_ssi_file(struct mg_connection *, const char *, FILE *, int);
static void send_file_data(struct mg_connection *conn, FILE *fp) {
char buf[IOBUF_SIZE];
int n;
size_t n;
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
mg_write(conn, buf, n);
}
@@ -4800,7 +4899,7 @@ static void close_local_endpoint(struct connection *conn) {
conn->cl = conn->num_bytes_recv = conn->request_len = 0;
conn->ns_conn->flags &= ~(NSF_FINISHED_SENDING_DATA |
NSF_BUFFER_BUT_DONT_SEND | NSF_CLOSE_IMMEDIATELY |
MG_HEADERS_SENT | MG_LONG_RUNNING);
MG_HEADERS_SENT | MG_USING_CHUNKED_API);
// Do not memset() the whole structure, as some of the fields
// (IP addresses & ports, server_param) must survive. Nullify the rest.
@@ -4818,7 +4917,7 @@ static void close_local_endpoint(struct connection *conn) {
static void transfer_file_data(struct connection *conn) {
char buf[IOBUF_SIZE];
int n;
size_t n;
// If output buffer is too big, don't send anything. Wait until
// mongoose drains already buffered data to the client.
@@ -4839,7 +4938,7 @@ static void transfer_file_data(struct connection *conn) {
}
}
int mg_poll_server(struct mg_server *server, int milliseconds) {
time_t mg_poll_server(struct mg_server *server, int milliseconds) {
return ns_mgr_poll(&server->ns_mgr, milliseconds);
}
@@ -5035,20 +5134,38 @@ const char *mg_set_option(struct mg_server *server, const char *name,
DBG(("%s [%s]", name, *v));
if (ind == LISTENING_PORT) {
char buf[500] = "";
size_t n = 0;
struct vec vec;
/*
* Ports can be specified as 0, meaning that OS has to choose any
* free port that is available. In order to pass chosen port number to
* the user, we rewrite all 0 port to chosen values.
*/
while ((value = next_option(value, &vec, NULL)) != NULL) {
struct ns_connection *c = ns_bind(&server->ns_mgr, vec.ptr,
mg_ev_handler, NULL);
if (c== NULL) {
if (c == NULL) {
error_msg = "Cannot bind to port";
break;
} else {
char buf[100];
ns_sock_to_str(c->sock, buf, sizeof(buf), 2);
NS_FREE(*v);
*v = mg_strdup(buf);
char buf2[50], cert[100], ca[100];
union socket_address sa;
int proto, use_ssl;
ns_parse_address(vec.ptr, &sa, &proto, &use_ssl, cert, ca);
ns_sock_to_str(c->sock, buf2, sizeof(buf2),
memchr(vec.ptr, ':', vec.len) == NULL ? 2 : 3);
n += snprintf(buf + n, sizeof(buf) - n, "%s%s%s%s%s%s%s",
n > 0 ? "," : "",
use_ssl ? "ssl://" : "",
buf2, cert[0] ? ":" : "", cert, ca[0] ? ":" : "", ca);
}
}
buf[sizeof(buf) - 1] = '\0';
NS_FREE(*v);
*v = mg_strdup(buf);
#ifndef MONGOOSE_NO_FILESYSTEM
} else if (ind == HEXDUMP_FILE) {
server->ns_mgr.hexdump_file = *v;
+5 -4
View File
@@ -22,6 +22,7 @@
#include <stdio.h> // required for FILE
#include <stddef.h> // required for size_t
#include <sys/types.h> // required for time_t
#ifdef __cplusplus
extern "C" {
@@ -88,7 +89,7 @@ enum {
struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
void mg_destroy_server(struct mg_server **);
const char *mg_set_option(struct mg_server *, const char *opt, const char *val);
int mg_poll_server(struct mg_server *, int milliseconds);
time_t mg_poll_server(struct mg_server *, int milliseconds);
const char **mg_get_valid_option_names(void);
const char *mg_get_option(const struct mg_server *server, const char *name);
void mg_copy_listeners(struct mg_server *from, struct mg_server *to);
@@ -102,7 +103,7 @@ void mg_send_status(struct mg_connection *, int status_code);
void mg_send_header(struct mg_connection *, const char *name, const char *val);
size_t mg_send_data(struct mg_connection *, const void *data, int data_len);
size_t mg_printf_data(struct mg_connection *, const char *format, ...);
size_t mg_write(struct mg_connection *, const void *buf, int len);
size_t mg_write(struct mg_connection *, const void *buf, size_t len);
size_t mg_printf(struct mg_connection *conn, const char *fmt, ...);
size_t mg_websocket_write(struct mg_connection *, int opcode,
@@ -128,8 +129,8 @@ int mg_parse_multipart(const char *buf, int buf_len,
void *mg_start_thread(void *(*func)(void *), void *param);
char *mg_md5(char buf[33], ...);
int mg_authorize_digest(struct mg_connection *c, FILE *fp);
int mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len);
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int);
size_t mg_url_encode(const char *src, size_t s_len, char *dst, size_t dst_len);
int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len, int);
int mg_terminate_ssl(struct mg_connection *c, const char *cert);
int mg_forward(struct mg_connection *c, const char *addr);
void *mg_mmap(FILE *fp, size_t size);
+10 -7
View File
@@ -120,8 +120,8 @@ static const char *test_parse_http_message() {
ASSERT(strcmp(ri.http_version, "1.1") == 0);
ASSERT(ri.num_headers == 0);
ASSERT(parse_http_message(req2, sizeof(req2) - 1, &ri) == -1);
ASSERT(parse_http_message(req6, 0, &ri) == -1);
ASSERT(parse_http_message(req2, sizeof(req2) - 1, &ri) == (size_t) ~0);
ASSERT(parse_http_message(req6, 0, &ri) == (size_t) ~0);
ASSERT(parse_http_message(req8, sizeof(req8) - 1, &ri) == sizeof(req8) - 1);
// TODO(lsm): Fix this. Header value may span multiple lines.
@@ -198,17 +198,19 @@ static const char *test_match_prefix(void) {
}
static const char *test_remove_double_dots() {
struct { char before[20], after[20]; } data[] = {
struct { char before[30], after[30]; } data[] = {
{"////a", "/a"},
{"/.....", "/."},
{"/......", "/"},
{"/.....", "/....."},
{"/......", "/......"},
{"...", "..."},
{"/...///", "/./"},
{"/...///", "/.../"},
{"/a...///", "/a.../"},
{"/.x", "/.x"},
{"/\\", "/"},
{"/a\\", "/a\\"},
{"/a\\\\...", "/a\\."},
{"/a\\\\...", "/a\\..."},
{"foo/x..y/././y/../../..", "foo/x..y/y/"},
{"foo/..x", "foo/..x"},
};
size_t i;
@@ -261,6 +263,7 @@ static const char *test_url_decode(void) {
ASSERT(strcmp(buf, "a ") == 0);
ASSERT(mg_url_decode("%61", 1, buf, sizeof(buf), 1) == 1);
printf("[%s]\n", buf);
ASSERT(strcmp(buf, "%") == 0);
ASSERT(mg_url_decode("%61", 2, buf, sizeof(buf), 1) == 2);