Compare commits

..
29 Commits
Author SHA1 Message Date
Sergey Lyubka 7380c65265 5.1 -> 5.2 2014-01-10 22:37:26 +00:00
Sergey Lyubka e9316a4feb CGI fixes 2014-01-10 21:59:37 +00:00
Sergey Lyubka a741d53028 Fixed leak for server creation/destroy 2014-01-10 11:23:29 +00:00
Sergey Lyubka 9ea7b6f8ae Removed unnecessary buffer initializer 2014-01-10 11:11:26 +00:00
Sergey Lyubka 580d3da3c7 Using unicode winapi for stat(), fopen(), open() 2014-01-10 11:03:38 +00:00
Sergey Lyubka aa59dda966 wrapped read_from_cgi() into NO_CGI 2014-01-09 17:50:57 +00:00
Sergey Lyubka 47b92e4145 Added string defs for 301 and 302 codes in status_code_to_str() 2014-01-09 17:24:20 +00:00
Sergey Lyubka fa351959a0 5.0 -> 5.1 2014-01-09 14:08:50 +00:00
Sergey Lyubka 1414e2a236 Documented rewrites for HTTP errors 2014-01-09 12:47:29 +00:00
Sergey Lyubka 5fb275e146 Added URL rewrites for HTTP errors, to allow for error pages. 2014-01-09 12:36:25 +00:00
Sergey Lyubka 9390c66b48 Moved next_option() to the rest of string functions 2014-01-09 12:34:50 +00:00
Sergey Lyubka 2f69ca37d3 Better CGI error diagnostic for UNIX 2014-01-09 10:53:25 +00:00
Sergey Lyubka 4cd11de400 Ping only websocket connections 2014-01-09 10:37:17 +00:00
Sergey Lyubka 15a2639355 Added better diagnostic to send_http_error() 2014-01-09 10:35:43 +00:00
Sergey Lyubka c20f26dbb9 removed mg_fmt() 2014-01-09 09:58:19 +00:00
Sergey Lyubka cae797cf04 Merge branch 'master' of https://github.com/cesanta/mongoose 2014-01-09 09:37:35 +00:00
Sergey Lyubka 0d885add0e Fixed put_dir() 2014-01-09 09:36:58 +00:00
Sergey Lyubka 842231cc5c GetFullPathNameA -> GetFullPathName 2014-01-08 18:20:13 +00:00
Sergey Lyubka dc55a3ae40 Added #undef UNICODE in mongoose.c to force ANSI Win32 functions 2014-01-08 18:10:15 +00:00
Sergey Lyubka 4d85cc6c76 Removed -Wno-empty-translation-unit from unix CFLAGS :-) 2014-01-08 09:27:16 +00:00
Sergey Lyubka 8ac1b40c11 Added -Wno-empty-translation-unit to the unix CFLAGS 2014-01-08 09:19:56 +00:00
Sergey Lyubka 238b43af84 Squashed warnings for gcc 4.6.3 2014-01-08 09:16:36 +00:00
Sergey Lyubka 12c8e99bd5 Removed error_log_file from tests config 2014-01-07 14:57:08 +00:00
EC2 Default User 5f2f359bd6 Squashed warning under gcc 4.6.3 2014-01-07 14:53:48 +00:00
Sergey Lyubka ccf0ce4a1f Using chunked API in post.c example 2014-01-07 09:28:20 +00:00
Sergey Lyubka 134a5b7b9e Using chunked API in multi-threaded example 2014-01-07 09:24:48 +00:00
Sergey Lyubka d39daab29e Updated docs 2014-01-07 09:12:17 +00:00
Sergey Lyubka a798b1a937 Updated docs 2014-01-07 09:10:58 +00:00
Sergey Lyubka 04de3bb2f9 Updated docs 2014-01-07 09:05:34 +00:00
8 changed files with 475 additions and 324 deletions

No files matched your search

+1 -3
View File
@@ -168,7 +168,6 @@ kill_spawned_child();
my $cmd = "$mongoose_exe ". my $cmd = "$mongoose_exe ".
"-listening_port 127.0.0.1:$port ". "-listening_port 127.0.0.1:$port ".
"-access_log_file access.log ". "-access_log_file access.log ".
"-error_log_file debug.log ".
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo " . "-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo " .
"-dav_auth_file $abs_root/passfile " . "-dav_auth_file $abs_root/passfile " .
'-access_control_list -0.0.0.0/0,+127.0.0.1 ' . '-access_control_list -0.0.0.0/0,+127.0.0.1 ' .
@@ -362,8 +361,7 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
o("GET /dir%20with%20spaces/hello.cgi HTTP/1.0\n\r\n", o("GET /dir%20with%20spaces/hello.cgi HTTP/1.0\n\r\n",
'HTTP/1.1 200 OK.+hello', 'CGI script with spaces in path'); 'HTTP/1.1 200 OK.+hello', 'CGI script with spaces in path');
o("GET /env.cgi HTTP/1.0\n\r\n", 'HTTP/1.1 200 OK', 'GET CGI file'); o("GET /env.cgi HTTP/1.0\n\r\n", 'HTTP/1.1 200 OK', 'GET CGI file');
o("GET /bad2.cgi HTTP/1.0\n\n", "HTTP/1.1 302 Please pass me to the client\r", o("GET /bad2.cgi HTTP/1.0\n\n", "^HTTP/1.1 302", 'CGI Status code');
'CGI Status code text');
o("GET /sh.cgi HTTP/1.0\n\r\n", 'shell script CGI', o("GET /sh.cgi HTTP/1.0\n\r\n", 'shell script CGI',
'GET sh CGI file') unless on_windows(); 'GET sh CGI file') unless on_windows();
o("GET /env.cgi?var=HELLO HTTP/1.0\n\n", 'QUERY_STRING=var=HELLO', o("GET /env.cgi?var=HELLO HTTP/1.0\n\n", 'QUERY_STRING=var=HELLO',
+2 -2
View File
@@ -51,8 +51,8 @@ is serving, in between `mg_poll_server()` calls.
void mg_poll_server(struct mg_server *server, int milliseconds); void mg_poll_server(struct mg_server *server, int milliseconds);
This function performs one iteration of IO loop by iterating over all This function performs one iteration of IO loop by iterating over all
active connections, performing `select()` syscall on all sockets, and sleeping active connections, performing `select()` syscall on all sockets with a timeout
for `milliseconds` number of milliseconds. When `select()` returns, Mongoose of `milliseconds` number of milliseconds. When `select()` returns, Mongoose
does an IO for each socket that has data to be sent or received. Application does an IO for each socket that has data to be sent or received. Application
code must call `mg_poll_server()` in a loop. It is an error to have more then code must call `mg_poll_server()` in a loop. It is an error to have more then
one thread calling `mg_poll_server()`, `mg_set_option()` or any other function one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
+39 -16
View File
@@ -1,21 +1,44 @@
# Mongoose Internals # Mongoose Internals
Mongoose has single-threaded, event-driven, asynchronous, non-blocking core. Mongoose has single-threaded, event-driven, asynchronous, non-blocking core.
When mongoose server instance is created, it contains an information about `mg_create_server()` creates a web server instance. An instance is a container
the configuration and the state of each connection: for the config options and list of active connections. To do the actual
serving, user must call `mg_poll_server()`, which iterates over all
active connections, performing `select()` syscall on all sockets with a
timeout of specified number of milliseconds. When `select()` returns, Mongoose
does an IO for each socket that has data to be sent or received. Application
code must call `mg_poll_server()` in a loop.
struct mg_server { Mongoose server instance is designed to be used by a single thread.
sock_t listening_sock; // Listening socket It is an error to have more then
union socket_address lsa; // Listening socket address one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
struct linked_list_link active_connections; that take `struct mg_server *` parameter. Mongoose does not
struct linked_list_link uri_handlers; mutex-protect `struct mg_server *`, therefore the best practice is
char *config_options[NUM_OPTIONS]; to call server management functions from the same thread (an IO thread).
... On a multi-core systems, many server instances can be created, sharing the
}; same listening socket and managed by separate threads (see [multi_threaded.c](https://github.com/cesanta/mongoose/blob/master/examples/multi_threaded.c))
example.
A server instance is capable on listening on only one port. After creation, It is an error to pass and store `struct mg_connection *` pointers for
a server instance has a list later use to send data. The reason is that they can be invalidated by the
of active connections, initially empty. It has a list of URI handlers, next `mg_poll_server()` call. For such a task,
initially empty, and configuration parameters. Configuration can be there is `mg_iterate_over_connections()` API
altered by `mg_set_option()`, and new URI handlers could be added by exists, which sends a callback function to the IO thread, then IO thread
`mg_add_uri_handler()`. calls specified function for all active connection.
When mongoose buffers in HTTP request and successfully parses it, it calls
appropriate URI handler immediately for GET requests. For POST requests,
Mongoose delays the call until the whole POST request is buffered in memory.
POST data is available to the callback as `struct mg_connection::content`,
and POST data length is in `struct mg_connection::content_len`.
Note that websocket connections are treated the same way. Mongoose buffers
websocket frame in memory, and calls URI handler when frame is fully
buffered. Frame data is available `struct mg_connection::content`, and
data length is in `struct mg_connection::content_len`, i.e. very similar to
the POST request. `struct mg_connection::is_websocket` flag indicates
whether the request is websocket or not. Also, for websocket requests,
there is `struct mg_connection::wsbits` field which contains first byte
of the websocket frame which URI handler can examine. Note that to
reply to the websocket client, `mg_websocket_write()` should be used.
To reply to the plain HTTP client, `mg_write()` should be used.
+13 -7
View File
@@ -111,7 +111,7 @@ required when mongoose needs to bind on privileged port on UNIX, e.g.
Default: not set. Default: not set.
### url\_rewrite\_patterns ### url\_rewrites
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 Mongoose 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.
@@ -119,16 +119,22 @@ 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 mongoose patterns, is a prefix pattern. If `uri_patters`
is a number, then it is treated as HTTP error code, and `file_or_directory_path`
should be an URI to redirect to. Mongoose will issue `302` temporary redirect
to the specified URI, appending two parameters:
`?code=<http_error_code&orig_uri=<original_uri>`.
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. Examples:
to redirect all accesses to `.doc` files to a special script, do:
mongoose -url_rewrite_patterns **.doc$=/path/to/cgi-bin/handle_doc.cgi # Redirect all accesses to `.doc` files to a special script
mongoose -url_rewrites **.doc$=/path/to/cgi-bin/handle_doc.cgi
Or, to imitate user home directories support, do: # Implement user home directories support
mongoose -url_rewrites /~joe/=/home/joe/,/~bill=/home/bill/
mongoose -url_rewrite_patterns /~joe/=/home/joe/,/~bill=/home/bill/ # Redirect 404 errors to a specific error page
mongoose -url_rewrites 404=/cgi-bin/error.cgi
Default: not set. Default: not set.
+6 -5
View File
@@ -3,10 +3,10 @@
// Start a browser and hit refresh couple of times. The replies will // Start a browser and hit refresh couple of times. The replies will
// come from both server instances. // come from both server instances.
static int request_handler(struct mg_connection *conn) { static int request_handler(struct mg_connection *conn) {
mg_printf(conn, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n" mg_send_header(conn, "Content-Type", "text/plain");
"This is a reply from server instance # %s", mg_printf_data(conn, "This is a reply from server instance # %s",
(char *) conn->server_param); (char *) conn->server_param);
return 1; return 0;
} }
static void *serve(void *server) { static void *serve(void *server) {
@@ -30,7 +30,8 @@ int main(void) {
// server1 goes to separate thread, server 2 runs in main thread. // server1 goes to separate thread, server 2 runs in main thread.
// IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER. // IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
mg_start_thread(serve, server1); mg_start_thread(serve, server1);
serve(server2); mg_start_thread(serve, server2);
getchar();
return 0; return 0;
} }
+9 -11
View File
@@ -21,19 +21,17 @@ static int handler(struct mg_connection *conn) {
// Send reply to the client, showing submitted form values. // Send reply to the client, showing submitted form values.
// POST data is in conn->content, data length is in conn->content_len // POST data is in conn->content, data length is in conn->content_len
mg_printf(conn, "HTTP/1.0 200 OK\r\n" mg_send_header(conn, "Content-Type", "text/plain");
"Content-Type: text/plain\r\n\r\n" mg_printf_data(conn,
"Submitted data: [%.*s]\n" "Submitted data: [%.*s]\n"
"Submitted data length: %d bytes\n" "Submitted data length: %d bytes\n"
"input_1: [%s]\n" "input_1: [%s]\n"
"input_2: [%s]\n", "input_2: [%s]\n",
conn->content_len, conn->content, conn->content_len, var1, var2); conn->content_len, conn->content,
conn->content_len, var1, var2);
} else { } else {
// Show HTML form. // Show HTML form.
mg_printf(conn, "HTTP/1.1 200 OK\r\n" mg_send_data(conn, html_form, strlen(html_form));
"Content-Length: %d\r\n"
"Content-Type: text/html\r\n\r\n%s",
(int) strlen(html_form), html_form);
} }
return 1; return 1;
+404 -279
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -20,7 +20,7 @@
#ifndef MONGOOSE_HEADER_INCLUDED #ifndef MONGOOSE_HEADER_INCLUDED
#define MONGOOSE_HEADER_INCLUDED #define MONGOOSE_HEADER_INCLUDED
#define MONGOOSE_VERSION "5.0" #define MONGOOSE_VERSION "5.2"
#include <stdio.h> // required for FILE #include <stdio.h> // required for FILE
#include <stddef.h> // required for size_t #include <stddef.h> // required for size_t