mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-25 12:04:47 +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 ".
|
||||
"-listening_port 127.0.0.1:$port ".
|
||||
"-access_log_file access.log ".
|
||||
"-error_log_file debug.log ".
|
||||
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo " .
|
||||
"-dav_auth_file $abs_root/passfile " .
|
||||
'-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",
|
||||
'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 /bad2.cgi HTTP/1.0\n\n", "HTTP/1.1 302 Please pass me to the client\r",
|
||||
'CGI Status code text');
|
||||
o("GET /bad2.cgi HTTP/1.0\n\n", "^HTTP/1.1 302", 'CGI Status code');
|
||||
o("GET /sh.cgi HTTP/1.0\n\r\n", 'shell script CGI',
|
||||
'GET sh CGI file') unless on_windows();
|
||||
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);
|
||||
|
||||
This function performs one iteration of IO loop by iterating over all
|
||||
active connections, performing `select()` syscall on all sockets, and sleeping
|
||||
for `milliseconds` number of milliseconds. When `select()` returns, Mongoose
|
||||
active connections, performing `select()` syscall on all sockets with a timeout
|
||||
of `milliseconds` 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. It is an error to have more then
|
||||
one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
|
||||
|
||||
+39
-16
@@ -1,21 +1,44 @@
|
||||
# Mongoose Internals
|
||||
|
||||
Mongoose has single-threaded, event-driven, asynchronous, non-blocking core.
|
||||
When mongoose server instance is created, it contains an information about
|
||||
the configuration and the state of each connection:
|
||||
`mg_create_server()` creates a web server instance. An instance is a container
|
||||
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 {
|
||||
sock_t listening_sock; // Listening socket
|
||||
union socket_address lsa; // Listening socket address
|
||||
struct linked_list_link active_connections;
|
||||
struct linked_list_link uri_handlers;
|
||||
char *config_options[NUM_OPTIONS];
|
||||
...
|
||||
};
|
||||
Mongoose server instance is designed to be used by a single thread.
|
||||
It is an error to have more then
|
||||
one thread calling `mg_poll_server()`, `mg_set_option()` or any other function
|
||||
that take `struct mg_server *` parameter. Mongoose does not
|
||||
mutex-protect `struct mg_server *`, therefore the best practice is
|
||||
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,
|
||||
a server instance has a list
|
||||
of active connections, initially empty. It has a list of URI handlers,
|
||||
initially empty, and configuration parameters. Configuration can be
|
||||
altered by `mg_set_option()`, and new URI handlers could be added by
|
||||
`mg_add_uri_handler()`.
|
||||
It is an error to pass and store `struct mg_connection *` pointers for
|
||||
later use to send data. The reason is that they can be invalidated by the
|
||||
next `mg_poll_server()` call. For such a task,
|
||||
there is `mg_iterate_over_connections()` API
|
||||
exists, which sends a callback function to the IO thread, then IO thread
|
||||
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.
|
||||
|
||||
### url\_rewrite\_patterns
|
||||
### url\_rewrites
|
||||
Comma-separated list of URL rewrites in the form of
|
||||
`uri_pattern=file_or_directory_path`. When Mongoose receives the request,
|
||||
it constructs the file name to show by combining `document_root` and the URI.
|
||||
@@ -119,16 +119,22 @@ However, if the rewrite option is used and `uri_pattern` matches the
|
||||
requested URI, then `document_root` is ignored. Insted,
|
||||
`file_or_directory_path` is used, which should be a full path name or
|
||||
a path relative to the web server's current working directory. Note that
|
||||
`uri_pattern`, as all mongoose patterns, is a prefix pattern.
|
||||
`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`,
|
||||
redirect all requests to scripts, and do other tricky things. For example,
|
||||
to redirect all accesses to `.doc` files to a special script, do:
|
||||
redirect all requests to scripts, and do other tricky things. Examples:
|
||||
|
||||
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.
|
||||
@@ -3,10 +3,10 @@
|
||||
// Start a browser and hit refresh couple of times. The replies will
|
||||
// come from both server instances.
|
||||
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"
|
||||
"This is a reply from server instance # %s",
|
||||
(char *) conn->server_param);
|
||||
return 1;
|
||||
mg_send_header(conn, "Content-Type", "text/plain");
|
||||
mg_printf_data(conn, "This is a reply from server instance # %s",
|
||||
(char *) conn->server_param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *serve(void *server) {
|
||||
@@ -30,7 +30,8 @@ int main(void) {
|
||||
// server1 goes to separate thread, server 2 runs in main thread.
|
||||
// IMPORTANT: NEVER LET DIFFERENT THREADS HANDLE THE SAME SERVER.
|
||||
mg_start_thread(serve, server1);
|
||||
serve(server2);
|
||||
mg_start_thread(serve, server2);
|
||||
getchar();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+9
-11
@@ -21,19 +21,17 @@ static int handler(struct mg_connection *conn) {
|
||||
|
||||
// Send reply to the client, showing submitted form values.
|
||||
// POST data is in conn->content, data length is in conn->content_len
|
||||
mg_printf(conn, "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n"
|
||||
"Submitted data: [%.*s]\n"
|
||||
"Submitted data length: %d bytes\n"
|
||||
"input_1: [%s]\n"
|
||||
"input_2: [%s]\n",
|
||||
conn->content_len, conn->content, conn->content_len, var1, var2);
|
||||
mg_send_header(conn, "Content-Type", "text/plain");
|
||||
mg_printf_data(conn,
|
||||
"Submitted data: [%.*s]\n"
|
||||
"Submitted data length: %d bytes\n"
|
||||
"input_1: [%s]\n"
|
||||
"input_2: [%s]\n",
|
||||
conn->content_len, conn->content,
|
||||
conn->content_len, var1, var2);
|
||||
} else {
|
||||
// Show HTML form.
|
||||
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: text/html\r\n\r\n%s",
|
||||
(int) strlen(html_form), html_form);
|
||||
mg_send_data(conn, html_form, strlen(html_form));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+404
-279
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -20,7 +20,7 @@
|
||||
#ifndef MONGOOSE_HEADER_INCLUDED
|
||||
#define MONGOOSE_HEADER_INCLUDED
|
||||
|
||||
#define MONGOOSE_VERSION "5.0"
|
||||
#define MONGOOSE_VERSION "5.2"
|
||||
|
||||
#include <stdio.h> // required for FILE
|
||||
#include <stddef.h> // required for size_t
|
||||
|
||||
Reference in new issue
Block a user