Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
546bec33
Commit
546bec33
authored
Aug 29, 2010
by
valenok
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
API change for mg_start: most binary compatible across releases.
parent
0b1e621c
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
707 additions
and
719 deletions
+707
-719
main.c
main.c
+191
-217
mongoose.c
mongoose.c
+300
-254
mongoose.h
mongoose.h
+86
-79
embed.c
test/embed.c
+114
-138
test.pl
test/test.pl
+16
-31
No files found.
main.c
View file @
546bec33
This diff is collapsed.
Click to expand it.
mongoose.c
View file @
546bec33
This diff is collapsed.
Click to expand it.
mongoose.h
View file @
546bec33
...
@@ -29,8 +29,7 @@ struct mg_context; // Handle for the HTTP service itself
...
@@ -29,8 +29,7 @@ struct mg_context; // Handle for the HTTP service itself
struct
mg_connection
;
// Handle for the individual connection
struct
mg_connection
;
// Handle for the individual connection
// This structure contains full information about the HTTP request.
// This structure contains information about the HTTP request.
// It is passed to the user-specified callback function as a parameter.
struct
mg_request_info
{
struct
mg_request_info
{
char
*
request_method
;
// "GET", "POST", etc
char
*
request_method
;
// "GET", "POST", etc
char
*
uri
;
// URL-decoded URI
char
*
uri
;
// URL-decoded URI
...
@@ -40,7 +39,7 @@ struct mg_request_info {
...
@@ -40,7 +39,7 @@ struct mg_request_info {
char
*
log_message
;
// Mongoose error log message
char
*
log_message
;
// Mongoose error log message
long
remote_ip
;
// Client's IP address
long
remote_ip
;
// Client's IP address
int
remote_port
;
// Client's port
int
remote_port
;
// Client's port
int
status_code
;
// HTTP status code
int
status_code
;
// HTTP
reply
status code
int
is_ssl
;
// 1 if SSL-ed, 0 if not
int
is_ssl
;
// 1 if SSL-ed, 0 if not
int
num_headers
;
// Number of headers
int
num_headers
;
// Number of headers
struct
mg_header
{
struct
mg_header
{
...
@@ -49,65 +48,57 @@ struct mg_request_info {
...
@@ -49,65 +48,57 @@ struct mg_request_info {
}
http_headers
[
64
];
// Maximum 64 headers
}
http_headers
[
64
];
// Maximum 64 headers
};
};
// User-defined handler function. It must return MG_SUCCESS or MG_ERROR.
// Various events on which user-defined function is called by Mongoose.
//
enum
mg_event
{
// If handler returns MG_SUCCESS, that means that handler has processed the
MG_NEW_REQUEST
,
// New HTTP request has arrived from the client
// request by sending appropriate HTTP reply to the client. Mongoose treats
MG_HTTP_ERROR
,
// HTTP error must be returned to the client
// the request as served.
MG_EVENT_LOG
,
// Mongoose logs an event, request_info.log_message
//
MG_INIT_SSL
,
// Mongoose initializes SSL. Instead of mg_connection *,
// If callback returns MG_ERROR, that means that callback has not processed
// SSL context is passed to the callback function.
// the request. Handler must not send any data to the client in this case.
// Mongoose proceeds with request handling as if nothing happened.
//
// NOTE: ssl_password_handler must have the following prototype:
// int (*)(char *, int, int, void *)
// Refer to OpenSSL documentation for more details.
enum
mg_error_t
{
MG_ERROR
,
MG_SUCCESS
,
MG_NOT_FOUND
,
MG_BUFFER_TOO_SMALL
};
typedef
enum
mg_error_t
(
*
mg_callback_t
)(
struct
mg_connection
*
,
const
struct
mg_request_info
*
);
// This structure describes Mongoose configuration.
struct
mg_config
{
char
*
document_root
;
char
*
index_files
;
char
*
ssl_certificate
;
char
*
listening_ports
;
char
*
cgi_extensions
;
char
*
cgi_interpreter
;
char
*
cgi_environment
;
char
*
ssi_extensions
;
char
*
auth_domain
;
char
*
protect
;
char
*
global_passwords_file
;
char
*
put_delete_passwords_file
;
char
*
access_log_file
;
char
*
error_log_file
;
char
*
acl
;
char
*
uid
;
char
*
mime_types
;
char
*
enable_directory_listing
;
char
*
num_threads
;
mg_callback_t
new_request_handler
;
mg_callback_t
http_error_handler
;
mg_callback_t
event_log_handler
;
mg_callback_t
ssl_password_handler
;
};
};
// Prototype for the user-defined function. Mongoose calls this function
// Start the web server.
// on every event mentioned above.
//
// Parameters:
// event: which event has been triggered.
// conn: opaque connection handler. Could be used to read, write data to the
// client, etc. See functions below that accept "mg_connection *".
// request_info: Information about HTTP request.
//
//
// This must be the first function called by the application.
// Return:
// It creates a serving thread, and returns a context structure that
// If handler returns non-NULL, that means that handler has processed the
// can be used to stop the server.
// request by sending appropriate HTTP reply to the client. Mongoose treats
// After calling mg_start(), configuration data must not be changed.
// the request as served.
struct
mg_context
*
mg_start
(
const
struct
mg_config
*
);
// If callback returns NULL, that means that callback has not processed
// the request. Handler must not send any data to the client in this case.
// Mongoose proceeds with request handling as if nothing happened.
typedef
void
*
(
*
mg_callback_t
)(
enum
mg_event
event
,
struct
mg_connection
*
conn
,
struct
mg_request_info
*
request_info
);
// Start web server.
//
// Parameters:
// callback: user defined event handling function or NULL.
// options: NULL terminated list of option_name, option_value pairs that
// specify Mongoose configuration parameters.
//
// Example:
// const char *options[] = {
// "document_root", "/var/www",
// "listening_ports", "80,443s",
// NULL
// };
// struct mg_context *ctx = mg_start(&my_func, options);
//
// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
// for the list of valid option and their possible values.
//
// Return:
// web server context, or NULL on error.
struct
mg_context
*
mg_start
(
mg_callback_t
callback
,
const
char
**
options
);
// Stop the web server.
// Stop the web server.
...
@@ -118,6 +109,19 @@ struct mg_context *mg_start(const struct mg_config *);
...
@@ -118,6 +109,19 @@ struct mg_context *mg_start(const struct mg_config *);
void
mg_stop
(
struct
mg_context
*
);
void
mg_stop
(
struct
mg_context
*
);
// Get the value of particular configuration parameter.
// The value returned is read-only. Mongoose does not allow changing
// configuration at run time.
// 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
// set, zero-length string is returned.
const
char
*
mg_get_option
(
const
struct
mg_context
*
ctx
,
const
char
*
name
);
// Return array of valid configuration options.
const
char
**
mg_get_valid_option_names
(
void
);
// 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
// This function allows an application to manipulate .htpasswd files on the
...
@@ -129,9 +133,9 @@ void mg_stop(struct mg_context *);
...
@@ -129,9 +133,9 @@ void mg_stop(struct mg_context *);
// If password is NULL, entry is deleted.
// If password is NULL, entry is deleted.
//
//
// Return:
// Return:
//
MG_ERROR, MG_SUCCESS
//
1 on success, 0 on error.
enum
mg_error_
t
mg_modify_passwords_file
(
struct
mg_context
*
ctx
,
in
t
mg_modify_passwords_file
(
struct
mg_context
*
ctx
,
const
char
*
file_name
,
const
char
*
user
,
const
char
*
password
);
const
char
*
passwords_
file_name
,
const
char
*
user
,
const
char
*
password
);
// Send data to the client.
// Send data to the client.
int
mg_write
(
struct
mg_connection
*
,
const
void
*
buf
,
size_t
len
);
int
mg_write
(
struct
mg_connection
*
,
const
void
*
buf
,
size_t
len
);
...
@@ -160,32 +164,35 @@ const char *mg_get_header(const struct mg_connection *, const char *name);
...
@@ -160,32 +164,35 @@ const char *mg_get_header(const struct mg_connection *, const char *name);
// Get a value of particular form variable.
// Get a value of particular form variable.
//
//
// Either request_info->query_string or read POST data can be scanned.
// Parameters:
// mg_get_qsvar() is convenience method to get variable from the query string.
// data: pointer to form-uri-encoded buffer. This could be either POST data,
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// or request_info.query_string.
// failure, dst[0] == '\0'.
// data_len: length of the encoded data.
// var_name: variable name to decode from the buffer
// buf: destination buffer for the decoded variable
// buf_len: length of the destination buffer
//
//
// Return:
// Return:
//
MG_SUCCESS Variable value was successfully copied in the buffer
.
//
On success, length of the decoded variable
.
//
MG_NOT_FOUND Requested variable not found
.
//
On error, -1 (variable not found, or destination buffer is too small)
.
//
MG_BUFFER_TOO_SMALL Destination buffer is too small to hold the value.
//
enum
mg_error_t
mg_get_var
(
const
char
*
data
,
size_t
data_len
,
// Destination buffer is guaranteed to be '\0' - terminated. In case of
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
// failure, dst[0] == '\0'.
enum
mg_error_t
mg_get_qsvar
(
const
struct
mg_request_info
*
,
int
mg_get_var
(
const
char
*
data
,
size_t
data_len
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
// Fetch value of certain cookie variable into the destination buffer.
// Fetch value of certain cookie variable into the destination buffer.
//
//
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'. Note that RFC allows many occurences of the same
// failure, dst[0] == '\0'. Note that RFC allows many occur
r
ences of the same
// parameter. This function returns only first occur
a
nce.
// parameter. This function returns only first occur
re
nce.
//
//
// Return:
// Return:
//
MG_SUCCESS Cookie parameter was successfully copied in the buffer
.
//
On success, value length
.
//
MG_NOT_FOUND E
ither "Cookie:" header is not present at all, or the
//
On error, -1 (e
ither "Cookie:" header is not present at all, or the
//
requested parameter is not found.
//
requested parameter is not found, or destination buffer is too small
//
MG_BUFFER_TOO_SMALL Destination buffer is too small to hold the value
.
//
to hold the value)
.
enum
mg_error_
t
mg_get_cookie
(
const
struct
mg_connection
*
,
in
t
mg_get_cookie
(
const
struct
mg_connection
*
,
const
char
*
cookie_name
,
char
*
buf
,
size_t
buf_len
);
const
char
*
cookie_name
,
char
*
buf
,
size_t
buf_len
);
...
...
test/embed.c
View file @
546bec33
This diff is collapsed.
Click to expand it.
test/test.pl
View file @
546bec33
...
@@ -146,7 +146,7 @@ if (scalar(@ARGV) > 0 and $ARGV[0] eq 'embedded') {
...
@@ -146,7 +146,7 @@ if (scalar(@ARGV) > 0 and $ARGV[0] eq 'embedded') {
}
}
# Make sure we load config file if no options are given
# Make sure we load config file if no options are given
write_file
(
$config
,
"
ports 12345\naccess_log
access.log\n"
);
write_file
(
$config
,
"
listening_ports 12345\naccess_log_file
access.log\n"
);
spawn
(
$exe
);
spawn
(
$exe
);
my
$saved_port
=
$port
;
my
$saved_port
=
$port
;
$port
=
12345
;
$port
=
12345
;
...
@@ -156,11 +156,13 @@ unlink $config;
...
@@ -156,11 +156,13 @@ unlink $config;
kill_spawned_child
();
kill_spawned_child
();
# Spawn the server on port $port
# Spawn the server on port $port
my
$cmd
=
"$exe -ports $port -access_log access.log -error_log debug.log "
.
my
$cmd
=
"$exe -listening_ports $port -access_log_file access.log "
.
"-cgi_env CGI_FOO=foo,CGI_BAR=bar,CGI_BAZ=baz "
.
"-error_log_file debug.log "
.
"-mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
"-cgi_environment CGI_FOO=foo,CGI_BAR=bar,CGI_BAZ=baz "
.
"-root $root,/aiased=/etc/,/ta=$test_dir"
;
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
$cmd
.=
' -cgi_interp perl'
if
on_windows
();
'-put_delete_passwords_file test/passfile '
.
"-document_root $root,/aiased=/etc/,/ta=$test_dir"
;
$cmd
.=
' -cgi_interpreter perl'
if
on_windows
();
spawn
(
$cmd
);
spawn
(
$cmd
);
# Try to overflow: Send very long request
# Try to overflow: Send very long request
...
@@ -349,15 +351,12 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
...
@@ -349,15 +351,12 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
$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"
);
unlink
$path
;
unlink
$path
;
kill_spawned_child
();
do_PUT_test
();
do_PUT_test
();
#do_embedded_test();
kill_spawned_child
();
do_embedded_test
();
}
}
sub
do_PUT_test
{
sub
do_PUT_test
{
$cmd
.=
' -auth_PUT test/passfile'
;
spawn
(
$cmd
);
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, "
.
"response=896327350763836180c61d87578037d9, qop=auth, "
.
"response=896327350763836180c61d87578037d9, qop=auth, "
.
...
@@ -379,16 +378,14 @@ sub do_PUT_test {
...
@@ -379,16 +378,14 @@ sub do_PUT_test {
o
(
"PUT /put.txt HTTP/1.0\nExpect: 100-continue\nContent-Length: 4\n"
.
o
(
"PUT /put.txt HTTP/1.0\nExpect: 100-continue\nContent-Length: 4\n"
.
"$auth_header\nabcd"
,
"$auth_header\nabcd"
,
"HTTP/1.1 100 Continue.+HTTP/1.1 200"
,
'PUT 100-Continue'
);
"HTTP/1.1 100 Continue.+HTTP/1.1 200"
,
'PUT 100-Continue'
);
kill_spawned_child
();
}
}
sub
do_embedded_test
{
sub
do_embedded_test
{
my
$cmd
=
"cc -o $embed_exe $root/embed.c mongoose.c -I. "
.
my
$cmd
=
"cc -
W -Wall -
o $embed_exe $root/embed.c mongoose.c -I. "
.
"-
DNO_SSL -l
pthread -DLISTENING_PORT=\\\"$port\\\""
;
"-pthread -DLISTENING_PORT=\\\"$port\\\""
;
if
(
on_windows
())
{
if
(
on_windows
())
{
$cmd
=
"cl $root/embed.c mongoose.c /I. /nologo "
.
$cmd
=
"cl $root/embed.c mongoose.c /I. /nologo "
.
"/DNO_SSL /DLISTENING_PORT=\\\"$port\\\" "
.
"/DLISTENING_PORT=\\\"$port\\\" /link /out:$embed_exe.exe ws2_32.lib "
;
"/link /out:$embed_exe.exe ws2_32.lib "
;
}
}
print
$cmd
,
"\n"
;
print
$cmd
,
"\n"
;
system
(
$cmd
)
==
0
or
fail
(
"Cannot compile embedded unit test"
);
system
(
$cmd
)
==
0
or
fail
(
"Cannot compile embedded unit test"
);
...
@@ -415,30 +412,24 @@ sub do_embedded_test {
...
@@ -415,30 +412,24 @@ sub do_embedded_test {
# + in form data MUST be decoded to space
# + in form data MUST be decoded to space
o
(
"POST /test_get_var HTTP/1.0\nContent-Length: 10\n\n"
.
o
(
"POST /test_get_var HTTP/1.0\nContent-Length: 10\n\n"
.
"my_var=b+c"
,
'Value: \[b c\]'
,
'mg_get_var
7
'
,
0
);
"my_var=b+c"
,
'Value: \[b c\]'
,
'mg_get_var
9
'
,
0
);
# Test that big POSTed vars are not truncated
# Test that big POSTed vars are not truncated
my
$my_var
=
'x'
x
64000
;
my
$my_var
=
'x'
x
64000
;
o
(
"POST /test_get_var HTTP/1.0\nContent-Length: 64007\n\n"
.
o
(
"POST /test_get_var HTTP/1.0\nContent-Length: 64007\n\n"
.
"my_var=$my_var"
,
'Value size: \[64000\]'
,
'mg_get_var 8'
,
0
);
"my_var=$my_var"
,
'Value size: \[64000\]'
,
'mg_get_var 10'
,
0
);
# Test PUT
o
(
"PUT /put HTTP/1.0\nContent-Length: 3\n\nabc"
,
'\nabc$'
,
'put callback'
,
0
);
o
(
"POST /test_get_request_info?xx=yy HTTP/1.0\nFoo: bar\n"
.
o
(
"POST /test_get_request_info?xx=yy HTTP/1.0\nFoo: bar\n"
.
"Content-Length: 3\n\na=b"
,
"Content-Length: 3\n\na=b"
,
'Method: \[POST\].URI: \[/test_get_request_info\].'
.
'Method: \[POST\].URI: \[/test_get_request_info\].'
.
'HTTP version: \[1.0\].HTTP header \[Foo\]: \[bar\].'
.
'HTTP version: \[1.0\].HTTP header \[Foo\]: \[bar\].'
.
'HTTP header \[Content-Length\]: \[3\].'
.
'HTTP header \[Content-Length\]: \[3\].'
.
'Query string: \[xx=yy\].
POST data: \[a=b\].
'
.
'Query string: \[xx=yy\].'
.
'Remote IP: \[\d+\].Remote port: \[\d+\].'
.
'Remote IP: \[\d+\].Remote port: \[\d+\].'
.
'Remote user: \[\]'
'Remote user: \[\]'
,
'request_info'
,
0
);
,
'request_info'
,
0
);
o
(
"GET /not_exist HTTP/1.0\n\n"
,
'Error: \[404\]'
,
'404 handler'
,
0
);
o
(
"GET /not_exist HTTP/1.0\n\n"
,
'Error: \[404\]'
,
'404 handler'
,
0
);
o
(
"bad request\n\n"
,
'Error: \[400\]'
,
'* error handler'
,
0
);
o
(
"bad request\n\n"
,
'Error: \[400\]'
,
'* error handler'
,
0
);
o
(
"GET /test_user_data HTTP/1.0\n\n"
,
'User data: \[1234\]'
,
'user data in callback'
,
0
);
# o("GET /foo/secret HTTP/1.0\n\n",
# o("GET /foo/secret HTTP/1.0\n\n",
# '401 Unauthorized', 'mg_protect_uri', 0);
# '401 Unauthorized', 'mg_protect_uri', 0);
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=bill\n\n",
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=bill\n\n",
...
@@ -446,12 +437,6 @@ sub do_embedded_test {
...
@@ -446,12 +437,6 @@ sub do_embedded_test {
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=joe\n\n",
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=joe\n\n",
# '200 OK', 'mg_protect_uri (joe)', 0);
# '200 OK', 'mg_protect_uri (joe)', 0);
# Test un-binding the URI
o
(
"GET /foo/bar HTTP/1.0\n\n"
,
'HTTP/1.1 200 OK'
,
'/foo bound'
,
0
);
o
(
"GET /test_remove_callback HTTP/1.0\n\n"
,
'Removing callbacks'
,
'Callback removal'
,
0
);
o
(
"GET /foo/bar HTTP/1.0\n\n"
,
'HTTP/1.1 404'
,
'/foo unbound'
,
0
);
kill_spawned_child
();
kill_spawned_child
();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment