mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7380c65265 | ||
|
|
e9316a4feb | ||
|
|
a741d53028 | ||
|
|
9ea7b6f8ae | ||
|
|
580d3da3c7 | ||
|
|
aa59dda966 | ||
|
|
47b92e4145 | ||
|
|
fa351959a0 | ||
|
|
1414e2a236 | ||
|
|
5fb275e146 | ||
|
|
9390c66b48 | ||
|
|
2f69ca37d3 | ||
|
|
4cd11de400 | ||
|
|
15a2639355 | ||
|
|
c20f26dbb9 | ||
|
|
cae797cf04 | ||
|
|
0d885add0e | ||
|
|
842231cc5c | ||
|
|
dc55a3ae40 | ||
|
|
4d85cc6c76 | ||
|
|
8ac1b40c11 | ||
|
|
238b43af84 | ||
|
|
12c8e99bd5 | ||
|
|
5f2f359bd6 | ||
|
|
ccf0ce4a1f | ||
|
|
134a5b7b9e | ||
|
|
d39daab29e | ||
|
|
a798b1a937 | ||
|
|
04de3bb2f9 |
No files matched your search
+1
-3
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||||
@@ -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
@@ -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
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user