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
Show 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
struct
mg_connection
;
// Handle for the individual connection
// This structure contains full information about the HTTP request.
// It is passed to the user-specified callback function as a parameter.
// This structure contains information about the HTTP request.
struct
mg_request_info
{
char
*
request_method
;
// "GET", "POST", etc
char
*
uri
;
// URL-decoded URI
...
...
@@ -40,7 +39,7 @@ struct mg_request_info {
char
*
log_message
;
// Mongoose error log message
long
remote_ip
;
// Client's IP address
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
num_headers
;
// Number of headers
struct
mg_header
{
...
...
@@ -49,65 +48,57 @@ struct mg_request_info {
}
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
{
MG_NEW_REQUEST
,
// New HTTP request has arrived from the client
MG_HTTP_ERROR
,
// HTTP error must be returned to the client
MG_EVENT_LOG
,
// Mongoose logs an event, request_info.log_message
MG_INIT_SSL
,
// Mongoose initializes SSL. Instead of mg_connection *,
// SSL context is passed to the callback function.
};
// Prototype for the user-defined function. Mongoose calls this function
// 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.
//
// If handler returns MG_SUCCESS, that means that handler has processed the
// Return:
// If handler returns non-NULL, that means that handler has processed the
// request by sending appropriate HTTP reply to the client. Mongoose treats
// the request as served.
//
// If callback returns MG_ERROR, that means that callback has not processed
// 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.
//
// 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
;
};
typedef
void
*
(
*
mg_callback_t
)(
enum
mg_event
event
,
struct
mg_connection
*
conn
,
struct
mg_request_info
*
request_info
);
// Start the web server.
// 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.
//
// This must be the first function called by the application.
// It creates a serving thread, and returns a context structure that
// can be used to stop the server.
// After calling mg_start(), configuration data must not be changed.
struct
mg_context
*
mg_start
(
const
struct
mg_config
*
);
// Return:
// web server context, or NULL on error.
struct
mg_context
*
mg_start
(
mg_callback_t
callback
,
const
char
**
options
);
// Stop the web server.
...
...
@@ -118,6 +109,19 @@ struct mg_context *mg_start(const struct mg_config *);
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.
//
// This function allows an application to manipulate .htpasswd files on the
...
...
@@ -129,9 +133,9 @@ void mg_stop(struct mg_context *);
// If password is NULL, entry is deleted.
//
// Return:
//
MG_ERROR, MG_SUCCESS
enum
mg_error_
t
mg_modify_passwords_file
(
struct
mg_context
*
ctx
,
const
char
*
file_name
,
const
char
*
user
,
const
char
*
password
);
//
1 on success, 0 on error.
in
t
mg_modify_passwords_file
(
struct
mg_context
*
ctx
,
const
char
*
passwords_
file_name
,
const
char
*
user
,
const
char
*
password
);
// Send data to the client.
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);
// Get a value of particular form variable.
//
// Either request_info->query_string or read POST data can be scanned.
// mg_get_qsvar() is convenience method to get variable from the query string.
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'.
// Parameters:
// data: pointer to form-uri-encoded buffer. This could be either POST data,
// or request_info.query_string.
// 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:
//
MG_SUCCESS Variable value was successfully copied in the buffer
.
//
MG_NOT_FOUND Requested variable not found
.
//
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
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
enum
mg_error_t
mg_get_qsvar
(
const
struct
mg_request_info
*
,
//
On success, length of the decoded variable
.
//
On error, -1 (variable not found, or destination buffer is too small)
.
//
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'.
int
mg_get_var
(
const
char
*
data
,
size_t
data_len
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
// Fetch value of certain cookie variable into the destination buffer.
//
// Destination buffer is guaranteed to be '\0' - terminated. In case of
// failure, dst[0] == '\0'. Note that RFC allows many occurences of the same
// parameter. This function returns only first occur
a
nce.
// failure, dst[0] == '\0'. Note that RFC allows many occur
r
ences of the same
// parameter. This function returns only first occur
re
nce.
//
// Return:
//
MG_SUCCESS Cookie parameter was successfully copied in the buffer
.
//
MG_NOT_FOUND E
ither "Cookie:" header is not present at all, or the
//
requested parameter is not found.
//
MG_BUFFER_TOO_SMALL Destination buffer is too small to hold the value
.
enum
mg_error_
t
mg_get_cookie
(
const
struct
mg_connection
*
,
//
On success, value length
.
//
On error, -1 (e
ither "Cookie:" header is not present at all, or the
//
requested parameter is not found, or destination buffer is too small
//
to hold the value)
.
in
t
mg_get_cookie
(
const
struct
mg_connection
*
,
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') {
}
# 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
);
my
$saved_port
=
$port
;
$port
=
12345
;
...
...
@@ -156,11 +156,13 @@ unlink $config;
kill_spawned_child
();
# Spawn the server on port $port
my
$cmd
=
"$exe -ports $port -access_log access.log -error_log debug.log "
.
"-cgi_env CGI_FOO=foo,CGI_BAR=bar,CGI_BAZ=baz "
.
"-mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
"-root $root,/aiased=/etc/,/ta=$test_dir"
;
$cmd
.=
' -cgi_interp perl'
if
on_windows
();
my
$cmd
=
"$exe -listening_ports $port -access_log_file access.log "
.
"-error_log_file debug.log "
.
"-cgi_environment CGI_FOO=foo,CGI_BAR=bar,CGI_BAZ=baz "
.
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
'-put_delete_passwords_file test/passfile '
.
"-document_root $root,/aiased=/etc/,/ta=$test_dir"
;
$cmd
.=
' -cgi_interpreter perl'
if
on_windows
();
spawn
(
$cmd
);
# Try to overflow: Send very long request
...
...
@@ -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"
);
unlink
$path
;
kill_spawned_child
();
do_PUT_test
();
#do_embedded_test();
kill_spawned_child
();
do_embedded_test
();
}
sub
do_PUT_test
{
$cmd
.=
' -auth_PUT test/passfile'
;
spawn
(
$cmd
);
my
$auth_header
=
"Authorization: Digest username=guest, "
.
"realm=mydomain.com, nonce=1145872809, uri=/put.txt, "
.
"response=896327350763836180c61d87578037d9, qop=auth, "
.
...
...
@@ -379,16 +378,14 @@ sub do_PUT_test {
o
(
"PUT /put.txt HTTP/1.0\nExpect: 100-continue\nContent-Length: 4\n"
.
"$auth_header\nabcd"
,
"HTTP/1.1 100 Continue.+HTTP/1.1 200"
,
'PUT 100-Continue'
);
kill_spawned_child
();
}
sub
do_embedded_test
{
my
$cmd
=
"cc -o $embed_exe $root/embed.c mongoose.c -I. "
.
"-
DNO_SSL -l
pthread -DLISTENING_PORT=\\\"$port\\\""
;
my
$cmd
=
"cc -
W -Wall -
o $embed_exe $root/embed.c mongoose.c -I. "
.
"-pthread -DLISTENING_PORT=\\\"$port\\\""
;
if
(
on_windows
())
{
$cmd
=
"cl $root/embed.c mongoose.c /I. /nologo "
.
"/DNO_SSL /DLISTENING_PORT=\\\"$port\\\" "
.
"/link /out:$embed_exe.exe ws2_32.lib "
;
"/DLISTENING_PORT=\\\"$port\\\" /link /out:$embed_exe.exe ws2_32.lib "
;
}
print
$cmd
,
"\n"
;
system
(
$cmd
)
==
0
or
fail
(
"Cannot compile embedded unit test"
);
...
...
@@ -415,30 +412,24 @@ sub do_embedded_test {
# + in form data MUST be decoded to space
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
my
$my_var
=
'x'
x
64000
;
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
);
# Test PUT
o
(
"PUT /put HTTP/1.0\nContent-Length: 3\n\nabc"
,
'\nabc$'
,
'put callback'
,
0
);
"my_var=$my_var"
,
'Value size: \[64000\]'
,
'mg_get_var 10'
,
0
);
o
(
"POST /test_get_request_info?xx=yy HTTP/1.0\nFoo: bar\n"
.
"Content-Length: 3\n\na=b"
,
'Method: \[POST\].URI: \[/test_get_request_info\].'
.
'HTTP version: \[1.0\].HTTP header \[Foo\]: \[bar\].'
.
'HTTP header \[Content-Length\]: \[3\].'
.
'Query string: \[xx=yy\].
POST data: \[a=b\].
'
.
'Query string: \[xx=yy\].'
.
'Remote IP: \[\d+\].Remote port: \[\d+\].'
.
'Remote user: \[\]'
,
'request_info'
,
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
(
"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",
# '401 Unauthorized', 'mg_protect_uri', 0);
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=bill\n\n",
...
...
@@ -446,12 +437,6 @@ sub do_embedded_test {
# o("GET /foo/secret HTTP/1.0\nAuthorization: Digest username=joe\n\n",
# '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
();
}
...
...
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