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
ed707936
Commit
ed707936
authored
Jan 24, 2012
by
valenok
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Options ssi_extensions, cgi_extensions became cgi_pattern, ssi_pattern
parent
01c5ee09
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
109 deletions
+115
-109
mongoose.1
mongoose.1
+41
-20
mongoose.c
mongoose.c
+49
-88
test.pl
test/test.pl
+19
-1
unit_test.c
test/unit_test.c
+6
-0
No files found.
mongoose.1
View file @
ed707936
...
@@ -29,8 +29,22 @@ mongoose listen on HTTP port 80 and HTTPS port 443, one should start it as:
...
@@ -29,8 +29,22 @@ mongoose listen on HTTP port 80 and HTTPS port 443, one should start it as:
.Pp
.Pp
Unlike other web servers,
Unlike other web servers,
.Nm
.Nm
does not expect CGI scripts to be put in a special directory. CGI scripts can
does not require CGI scripts be put in a special directory. CGI scripts can
be anywhere. CGI (and SSI) files are recognized by the file extension.
be anywhere. CGI (and SSI) files are recognized by the file name pattern.
.Nm
uses shell-like glob patterns with the following syntax:
.Bl -tag -compact -width indent
.It **
Matches everything
.It *
Matches everything but slash character, '/'
.It ?
Matches any character
.It |
Matches if pattern on the left side or the right side matches. Pattern on the
left side is matched first
.El
All other characters in the pattern match themselves.
.Pp
.Pp
If no arguments are given,
If no arguments are given,
.Nm
.Nm
...
@@ -48,9 +62,11 @@ Add/edit user's password in the passwords file. Deleting users can be done
...
@@ -48,9 +62,11 @@ Add/edit user's password in the passwords file. Deleting users can be done
with any text editor. Functionality is similar to Apache's
with any text editor. Functionality is similar to Apache's
.Ic htdigest
.Ic htdigest
utility.
utility.
.It Fl C Ar cgi_extensions
.It Fl C Ar cgi_pattern
Comma-separated list of CGI extensions. All files having these extensions
All files that fully match cgi_pattern are treated as CGI.
are treated as CGI scripts. Default: ".cgi,.pl,.php"
Default pattern allows CGI files be
anywhere. To restrict CGIs to certain directory, use e.g. "-C /cgi-bin/**.cgi".
Default: "**.cgi|**.pl|**.php"
.It Fl E Ar cgi_environment
.It Fl E Ar cgi_environment
Extra environment variables to be passed to the CGI script in addition to
Extra environment variables to be passed to the CGI script in addition to
standard ones. The list must be comma-separated list of X=Y pairs, like this:
standard ones. The list must be comma-separated list of X=Y pairs, like this:
...
@@ -62,8 +78,8 @@ DELETE methods are used. Default: ""
...
@@ -62,8 +78,8 @@ DELETE methods are used. Default: ""
Use
Use
.Ar cgi_interpreter
.Ar cgi_interpreter
as a CGI interpreter for all CGI scripts regardless script extension.
as a CGI interpreter for all CGI scripts regardless script extension.
Default: "".
Mongoose decides which interpreter to use by looking at
Mongoose decides which interpreter to use by looking at
the first line of a CGI script.
the first line of a CGI script.
Default: "".
.It Fl M Ar max_request_size
.It Fl M Ar max_request_size
Maximum HTTP request size in bytes. Default: "16384"
Maximum HTTP request size in bytes. Default: "16384"
.It Fl P Ar protect_uri
.It Fl P Ar protect_uri
...
@@ -71,10 +87,10 @@ Comma separated list of URI=PATH pairs, specifying that given URIs
...
@@ -71,10 +87,10 @@ Comma separated list of URI=PATH pairs, specifying that given URIs
must be protected with respected password files. Default: ""
must be protected with respected password files. Default: ""
.It Fl R Ar authentication_domain
.It Fl R Ar authentication_domain
Authorization realm. Default: "mydomain.com"
Authorization realm. Default: "mydomain.com"
.It Fl S Ar ssi_
extensions
.It Fl S Ar ssi_
pattern
Comma separated list of SSI extensions. Unknown SSI directives are silently
All files that fully match ssi_pattern are treated as SSI.
ignored. Currently, two SSI directives supported, "include" and "exec".
Unknown SSI directives are silently ignored. Currently, two SSI directives
Default: "shtml,
shtm"
are supported, "include" and "exec". Default: "**.shtml|**.
shtm"
.It Fl a Ar access_log_file
.It Fl a Ar access_log_file
Access log file. Default: "", no logging is done.
Access log file. Default: "", no logging is done.
.It Fl d Ar enable_directory_listing
.It Fl d Ar enable_directory_listing
...
@@ -109,17 +125,21 @@ prepended to the port number. For example, to bind to a loopback interface
...
@@ -109,17 +125,21 @@ prepended to the port number. For example, to bind to a loopback interface
on port 80 and to all interfaces on HTTPS port 443, use
on port 80 and to all interfaces on HTTPS port 443, use
"mongoose -p 127.0.0.1:80,443s". Default: "8080"
"mongoose -p 127.0.0.1:80,443s". Default: "8080"
.It Fl r Ar document_root
.It Fl r Ar document_root
Location of the WWW root directory. A comma separated list of
Location of the WWW root directory. Default: "."
URI_PREFIX=DIRECTORY
pairs could be appended to it, allowing Mongoose to serve from multiple
directories. For example, "mongoose -p /var/www,/config=/etc,/garbage=/tmp".
Default: "."
.It Fl s Ar ssl_certificate
.It Fl s Ar ssl_certificate
Location of SSL certificate file. Default: ""
Location of SSL certificate file. Default: ""
.It Fl t Ar num_threads
.It Fl t Ar num_threads
Number of worker threads to start. Default: "10"
Number of worker threads to start. Default: "10"
.It Fl u Ar run_as_user
.It Fl u Ar run_as_user
Switch to given user's credentials after startup. Default: ""
Switch to given user's credentials after startup. Default: ""
.It Fl w Ar url_rewrite_patterns
Comma-separated list of URL rewrites in the form of
"pattern=substitution,..." If the "pattern" matches some prefix
of the requested URL, then matched prefix gets substituted with "substitution".
For example, "-w /config=/etc,**.doc|**.rtf=/cgi-bin/handle_doc.cgi"
will serve all URLs that start with "/config" from the "/etc" directory, and
call handle_doc.cgi script for .doc and .rtf file requests.
Default: ""
.El
.El
.Pp
.Pp
.Sh EMBEDDING
.Sh EMBEDDING
...
@@ -131,13 +151,14 @@ for details.
...
@@ -131,13 +151,14 @@ for details.
.Pp
.Pp
.Sh EXAMPLES
.Sh EXAMPLES
.Bl -tag -width indent
.Bl -tag -width indent
.It Nm Fl r Ar /var/www,/aa=/tmp,/bb=/etc Fl s Ar /etc/cert.pem Fl p Ar 8080,8043s
.It Nm Fl r Ar /var/www Fl s Ar /etc/cert.pem Fl p Ar 8080,8043s
Start listening on port 8080 for HTTP, and 8043 for HTTPS connections.
Start serving files from /var/www. Listen on port 8080 for HTTP, and 8043
Use /etc/cert.pem as SSL certificate file. Web root is /var/www. In addition,
for HTTPS connections. Use /etc/cert.pem as SSL certificate file.
map directory /tmp to URI /aa, directory /etc to URI /bb.
.It Nm Fl l Ar -0.0.0.0/0,+10.0.0.0/8,+1.2.3.4
.It Nm Fl l Ar -0.0.0.0/0,+10.0.0.0/8,+1.2.3.4
Deny connections from everywhere, allow only IP address 1.2.3.4 and
Deny connections from everywhere, allow only IP address 1.2.3.4 and
all IP addresses from 10.0.0.0/8 subnet to connect.
all IP addresses from 10.0.0.0/8 subnet to connect.
.It Nm Fl w Ar **=/my/script.cgi
Invoke /my/script.cgi for every incoming request, regardless of the URL.
.El
.El
.Pp
.Pp
.Sh COPYRIGHT
.Sh COPYRIGHT
...
...
mongoose.c
View file @
ed707936
...
@@ -410,13 +410,13 @@ enum {
...
@@ -410,13 +410,13 @@ enum {
};
};
static
const
char
*
config_options
[]
=
{
static
const
char
*
config_options
[]
=
{
"C"
,
"cgi_
extensions"
,
".cgi,.pl,
.php"
,
"C"
,
"cgi_
pattern"
,
"**.cgi|**.pl|**
.php"
,
"E"
,
"cgi_environment"
,
NULL
,
"E"
,
"cgi_environment"
,
NULL
,
"G"
,
"put_delete_passwords_file"
,
NULL
,
"G"
,
"put_delete_passwords_file"
,
NULL
,
"I"
,
"cgi_interpreter"
,
NULL
,
"I"
,
"cgi_interpreter"
,
NULL
,
"P"
,
"protect_uri"
,
NULL
,
"P"
,
"protect_uri"
,
NULL
,
"R"
,
"authentication_domain"
,
"mydomain.com"
,
"R"
,
"authentication_domain"
,
"mydomain.com"
,
"S"
,
"ssi_
extensions"
,
".shtml,
.shtm"
,
"S"
,
"ssi_
pattern"
,
"**.shtml|**
.shtm"
,
"a"
,
"access_log_file"
,
NULL
,
"a"
,
"access_log_file"
,
NULL
,
"c"
,
"ssl_chain_file"
,
NULL
,
"c"
,
"ssl_chain_file"
,
NULL
,
"d"
,
"enable_directory_listing"
,
"yes"
,
"d"
,
"enable_directory_listing"
,
"yes"
,
...
@@ -432,7 +432,7 @@ static const char *config_options[] = {
...
@@ -432,7 +432,7 @@ static const char *config_options[] = {
"s"
,
"ssl_certificate"
,
NULL
,
"s"
,
"ssl_certificate"
,
NULL
,
"t"
,
"num_threads"
,
"10"
,
"t"
,
"num_threads"
,
"10"
,
"u"
,
"run_as_user"
,
NULL
,
"u"
,
"run_as_user"
,
NULL
,
"w"
,
"
rewrite
"
,
NULL
,
"w"
,
"
url_rewrite_patterns
"
,
NULL
,
NULL
NULL
};
};
#define ENTRIES_PER_CONFIG_OPTION 3
#define ENTRIES_PER_CONFIG_OPTION 3
...
@@ -761,19 +761,44 @@ static const char *next_option(const char *list, struct vec *val,
...
@@ -761,19 +761,44 @@ static const char *next_option(const char *list, struct vec *val,
return
list
;
return
list
;
}
}
static
int
match_
extension
(
const
char
*
path
,
const
char
*
ext_list
)
{
static
int
match_
prefix
(
const
char
*
pattern
,
int
pattern_len
,
const
char
*
str
)
{
struct
vec
ext_vec
;
const
char
*
or_str
;
size_t
path_len
;
int
i
,
j
,
len
,
res
;
path_len
=
strlen
(
path
);
if
((
or_str
=
memchr
(
pattern
,
'|'
,
pattern_len
))
!=
NULL
)
{
res
=
match_prefix
(
pattern
,
or_str
-
pattern
,
str
);
return
res
>
0
?
res
:
match_prefix
(
or_str
+
1
,
(
pattern
+
pattern_len
)
-
(
or_str
+
1
),
str
);
}
while
((
ext_list
=
next_option
(
ext_list
,
&
ext_vec
,
NULL
))
!=
NULL
)
i
=
j
=
res
=
0
;
if
(
ext_vec
.
len
<
path_len
&&
for
(;
i
<
pattern_len
;
i
++
,
j
++
)
{
mg_strncasecmp
(
path
+
path_len
-
ext_vec
.
len
,
if
(
pattern
[
i
]
==
'?'
&&
str
[
j
]
!=
'\0'
)
{
ext_vec
.
ptr
,
ext_vec
.
len
)
==
0
)
continue
;
return
1
;
}
else
if
(
pattern
[
i
]
==
'*'
)
{
i
++
;
if
(
pattern
[
i
]
==
'*'
)
{
i
++
;
len
=
strlen
(
str
+
j
);
}
else
{
len
=
strcspn
(
str
+
j
,
"/"
);
}
if
(
i
==
pattern_len
)
{
return
j
+
len
;
}
do
{
res
=
match_prefix
(
pattern
+
i
,
pattern_len
-
i
,
str
+
j
+
len
);
}
while
(
res
==
0
&&
len
--
>
0
);
return
res
==
0
?
0
:
j
+
res
+
len
;
}
else
if
(
pattern
[
i
]
!=
str
[
j
])
{
return
0
;
}
}
return
j
;
}
return
0
;
static
int
full_match
(
const
char
*
path
,
const
char
*
pattern
)
{
return
match_prefix
(
pattern
,
strlen
(
pattern
),
path
)
==
(
int
)
strlen
(
path
);
}
}
// HTTP 1.1 assumes keep alive if "Connection:" header is not set
// HTTP 1.1 assumes keep alive if "Connection:" header is not set
...
@@ -1521,74 +1546,15 @@ int mg_get_cookie(const struct mg_connection *conn, const char *cookie_name,
...
@@ -1521,74 +1546,15 @@ int mg_get_cookie(const struct mg_connection *conn, const char *cookie_name,
return
len
;
return
len
;
}
}
// Mongoose allows to specify multiple directories to serve,
// like /var/www,/~bob=/home/bob. That means that root directory depends on URI.
// This function returns root dir for given URI.
static
int
get_document_root
(
const
struct
mg_connection
*
conn
,
struct
vec
*
document_root
)
{
const
char
*
root
,
*
uri
;
int
len_of_matched_uri
;
struct
vec
uri_vec
,
path_vec
;
uri
=
conn
->
request_info
.
uri
;
len_of_matched_uri
=
0
;
root
=
next_option
(
conn
->
ctx
->
config
[
DOCUMENT_ROOT
],
document_root
,
NULL
);
while
((
root
=
next_option
(
root
,
&
uri_vec
,
&
path_vec
))
!=
NULL
)
{
if
(
memcmp
(
uri
,
uri_vec
.
ptr
,
uri_vec
.
len
)
==
0
)
{
*
document_root
=
path_vec
;
len_of_matched_uri
=
uri_vec
.
len
;
break
;
}
}
return
len_of_matched_uri
;
}
static
int
match_prefix
(
const
char
*
pattern
,
int
pattern_len
,
const
char
*
str
)
{
const
char
*
or_str
;
int
i
,
j
,
len
,
res
;
if
((
or_str
=
memchr
(
pattern
,
'|'
,
pattern_len
))
!=
NULL
)
{
res
=
match_prefix
(
or_str
+
1
,
(
pattern
+
pattern_len
)
-
(
or_str
+
1
),
str
);
return
res
>
0
?
res
:
match_prefix
(
pattern
,
or_str
-
pattern
,
str
);
}
i
=
j
=
res
=
0
;
for
(;
i
<
pattern_len
;
i
++
,
j
++
)
{
if
(
pattern
[
i
]
==
'?'
&&
str
[
j
]
!=
'\0'
)
{
continue
;
}
else
if
(
pattern
[
i
]
==
'*'
)
{
i
++
;
if
(
pattern
[
i
]
==
'*'
)
{
i
++
;
len
=
strlen
(
str
+
j
);
}
else
{
len
=
strcspn
(
str
+
j
,
"/"
);
}
if
(
i
==
pattern_len
)
{
return
j
+
len
;
}
do
{
res
=
match_prefix
(
pattern
+
i
,
pattern_len
-
i
,
str
+
j
+
len
);
}
while
(
res
==
0
&&
len
--
>
0
);
return
res
==
0
?
0
:
j
+
res
+
len
;
}
else
if
(
pattern
[
i
]
!=
str
[
j
])
{
return
0
;
}
}
return
j
;
}
static
void
convert_uri_to_file_name
(
struct
mg_connection
*
conn
,
static
void
convert_uri_to_file_name
(
struct
mg_connection
*
conn
,
const
char
*
uri
,
char
*
buf
,
const
char
*
uri
,
char
*
buf
,
size_t
buf_len
)
{
size_t
buf_len
)
{
struct
vec
vec
,
a
,
b
;
struct
vec
a
,
b
;
const
char
*
rewrite
;
const
char
*
rewrite
;
int
match_len
;
int
match_len
;
m
atch_len
=
get_document_root
(
conn
,
&
vec
);
m
g_snprintf
(
conn
,
buf
,
buf_len
,
"%s%s"
,
conn
->
ctx
->
config
[
DOCUMENT_ROOT
],
mg_snprintf
(
conn
,
buf
,
buf_len
,
"%.*s%s"
,
vec
.
len
,
vec
.
ptr
,
uri
+
match_len
);
uri
);
rewrite
=
conn
->
ctx
->
config
[
REWRITE
];
rewrite
=
conn
->
ctx
->
config
[
REWRITE
];
while
((
rewrite
=
next_option
(
rewrite
,
&
a
,
&
b
))
!=
NULL
)
{
while
((
rewrite
=
next_option
(
rewrite
,
&
a
,
&
b
))
!=
NULL
)
{
...
@@ -2852,18 +2818,16 @@ static void prepare_cgi_environment(struct mg_connection *conn,
...
@@ -2852,18 +2818,16 @@ static void prepare_cgi_environment(struct mg_connection *conn,
const
char
*
prog
,
const
char
*
prog
,
struct
cgi_env_block
*
blk
)
{
struct
cgi_env_block
*
blk
)
{
const
char
*
s
,
*
slash
;
const
char
*
s
,
*
slash
;
struct
vec
var_vec
,
root
;
struct
vec
var_vec
;
char
*
p
;
char
*
p
;
int
i
;
int
i
;
blk
->
len
=
blk
->
nvars
=
0
;
blk
->
len
=
blk
->
nvars
=
0
;
blk
->
conn
=
conn
;
blk
->
conn
=
conn
;
get_document_root
(
conn
,
&
root
);
addenv
(
blk
,
"SERVER_NAME=%s"
,
conn
->
ctx
->
config
[
AUTHENTICATION_DOMAIN
]);
addenv
(
blk
,
"SERVER_NAME=%s"
,
conn
->
ctx
->
config
[
AUTHENTICATION_DOMAIN
]);
addenv
(
blk
,
"SERVER_ROOT=%
.*s"
,
root
.
len
,
root
.
ptr
);
addenv
(
blk
,
"SERVER_ROOT=%
s"
,
conn
->
ctx
->
config
[
DOCUMENT_ROOT
]
);
addenv
(
blk
,
"DOCUMENT_ROOT=%
.*s"
,
root
.
len
,
root
.
ptr
);
addenv
(
blk
,
"DOCUMENT_ROOT=%
s"
,
conn
->
ctx
->
config
[
DOCUMENT_ROOT
]
);
// Prepare the environment block
// Prepare the environment block
addenv
(
blk
,
"%s"
,
"GATEWAY_INTERFACE=CGI/1.1"
);
addenv
(
blk
,
"%s"
,
"GATEWAY_INTERFACE=CGI/1.1"
);
...
@@ -3139,18 +3103,15 @@ static void send_ssi_file(struct mg_connection *, const char *, FILE *, int);
...
@@ -3139,18 +3103,15 @@ static void send_ssi_file(struct mg_connection *, const char *, FILE *, int);
static
void
do_ssi_include
(
struct
mg_connection
*
conn
,
const
char
*
ssi
,
static
void
do_ssi_include
(
struct
mg_connection
*
conn
,
const
char
*
ssi
,
char
*
tag
,
int
include_level
)
{
char
*
tag
,
int
include_level
)
{
char
file_name
[
BUFSIZ
],
path
[
PATH_MAX
],
*
p
;
char
file_name
[
BUFSIZ
],
path
[
PATH_MAX
],
*
p
;
struct
vec
root
;
int
is_ssi
;
int
is_ssi
;
FILE
*
fp
;
FILE
*
fp
;
get_document_root
(
conn
,
&
root
);
// sscanf() is safe here, since send_ssi_file() also uses buffer
// sscanf() is safe here, since send_ssi_file() also uses buffer
// of size BUFSIZ to get the tag. So strlen(tag) is always < BUFSIZ.
// of size BUFSIZ to get the tag. So strlen(tag) is always < BUFSIZ.
if
(
sscanf
(
tag
,
" virtual=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
if
(
sscanf
(
tag
,
" virtual=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
// File name is relative to the webserver root
// File name is relative to the webserver root
(
void
)
mg_snprintf
(
conn
,
path
,
sizeof
(
path
),
"%
.*
s%c%s"
,
(
void
)
mg_snprintf
(
conn
,
path
,
sizeof
(
path
),
"%s%c%s"
,
root
.
len
,
root
.
ptr
,
DIRSEP
,
file_name
);
conn
->
ctx
->
config
[
DOCUMENT_ROOT
]
,
DIRSEP
,
file_name
);
}
else
if
(
sscanf
(
tag
,
" file=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
}
else
if
(
sscanf
(
tag
,
" file=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
// File name is relative to the webserver working directory
// File name is relative to the webserver working directory
// or it is absolute system path
// or it is absolute system path
...
@@ -3173,7 +3134,7 @@ static void do_ssi_include(struct mg_connection *conn, const char *ssi,
...
@@ -3173,7 +3134,7 @@ static void do_ssi_include(struct mg_connection *conn, const char *ssi,
tag
,
path
,
strerror
(
ERRNO
));
tag
,
path
,
strerror
(
ERRNO
));
}
else
{
}
else
{
set_close_on_exec
(
fileno
(
fp
));
set_close_on_exec
(
fileno
(
fp
));
is_ssi
=
match_extension
(
path
,
conn
->
ctx
->
config
[
SSI_EXTENSIONS
]);
is_ssi
=
full_match
(
path
,
conn
->
ctx
->
config
[
SSI_EXTENSIONS
]);
if
(
is_ssi
)
{
if
(
is_ssi
)
{
send_ssi_file
(
conn
,
path
,
fp
,
include_level
+
1
);
send_ssi_file
(
conn
,
path
,
fp
,
include_level
+
1
);
}
else
{
}
else
{
...
@@ -3408,7 +3369,7 @@ static void handle_request(struct mg_connection *conn) {
...
@@ -3408,7 +3369,7 @@ static void handle_request(struct mg_connection *conn) {
"Directory listing denied"
);
"Directory listing denied"
);
}
}
#if !defined(NO_CGI)
#if !defined(NO_CGI)
}
else
if
(
match_extension
(
path
,
conn
->
ctx
->
config
[
CGI_EXTENSIONS
]))
{
}
else
if
(
full_match
(
path
,
conn
->
ctx
->
config
[
CGI_EXTENSIONS
]))
{
if
(
strcmp
(
ri
->
request_method
,
"POST"
)
&&
if
(
strcmp
(
ri
->
request_method
,
"POST"
)
&&
strcmp
(
ri
->
request_method
,
"GET"
))
{
strcmp
(
ri
->
request_method
,
"GET"
))
{
send_http_error
(
conn
,
501
,
"Not Implemented"
,
send_http_error
(
conn
,
501
,
"Not Implemented"
,
...
@@ -3417,7 +3378,7 @@ static void handle_request(struct mg_connection *conn) {
...
@@ -3417,7 +3378,7 @@ static void handle_request(struct mg_connection *conn) {
handle_cgi_request
(
conn
,
path
);
handle_cgi_request
(
conn
,
path
);
}
}
#endif // !NO_CGI
#endif // !NO_CGI
}
else
if
(
match_extension
(
path
,
conn
->
ctx
->
config
[
SSI_EXTENSIONS
]))
{
}
else
if
(
full_match
(
path
,
conn
->
ctx
->
config
[
SSI_EXTENSIONS
]))
{
handle_ssi_file_request
(
conn
,
path
);
handle_ssi_file_request
(
conn
,
path
);
}
else
if
(
is_not_modified
(
conn
,
&
st
))
{
}
else
if
(
is_not_modified
(
conn
,
&
st
))
{
send_http_error
(
conn
,
304
,
"Not Modified"
,
""
);
send_http_error
(
conn
,
304
,
"Not Modified"
,
""
);
...
...
test/test.pl
View file @
ed707936
...
@@ -150,6 +150,11 @@ if (scalar(@ARGV) > 0 and $ARGV[0] eq 'embedded') {
...
@@ -150,6 +150,11 @@ if (scalar(@ARGV) > 0 and $ARGV[0] eq 'embedded') {
exit
0
;
exit
0
;
}
}
if
(
scalar
(
@ARGV
)
>
0
and
$ARGV
[
0
]
eq
'unit'
)
{
do_unit_test
();
exit
0
;
}
# Make sure we load config file if no options are given.
# Make sure we load config file if no options are given.
# Command line options override config files settings
# Command line options override config files settings
write_file
(
$config
,
"access_log_file access.log\nlistening_ports 12345\n"
);
write_file
(
$config
,
"access_log_file access.log\nlistening_ports 12345\n"
);
...
@@ -166,7 +171,7 @@ my $cmd = "$exe $config -listening_ports $port -access_log_file access.log ".
...
@@ -166,7 +171,7 @@ my $cmd = "$exe $config -listening_ports $port -access_log_file access.log ".
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
"-extra_mime_types .bar=foo/bar,.tar.gz=blah,.baz=foo "
.
'-put_delete_passwords_file test/passfile '
.
'-put_delete_passwords_file test/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 '
.
"-document_root $root
,
/aiased=/etc/,/ta=$test_dir"
;
"-document_root $root
-url_rewrite_patterns
/aiased=/etc/,/ta=$test_dir"
;
$cmd
.=
' -cgi_interpreter perl'
if
on_windows
();
$cmd
.=
' -cgi_interpreter perl'
if
on_windows
();
spawn
(
$cmd
);
spawn
(
$cmd
);
...
@@ -386,6 +391,7 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
...
@@ -386,6 +391,7 @@ unless (scalar(@ARGV) > 0 and $ARGV[0] eq "basic_tests") {
do_PUT_test
();
do_PUT_test
();
kill_spawned_child
();
kill_spawned_child
();
do_unit_test
();
do_embedded_test
();
do_embedded_test
();
}
}
...
@@ -415,6 +421,18 @@ sub do_PUT_test {
...
@@ -415,6 +421,18 @@ sub do_PUT_test {
"HTTP/1.1 100 Continue.+HTTP/1.1 200"
,
'PUT 100-Continue'
);
"HTTP/1.1 100 Continue.+HTTP/1.1 200"
,
'PUT 100-Continue'
);
}
}
sub
do_unit_test
{
my
$cmd
=
"cc -W -Wall -o $unit_test_exe $root/unit_test.c -I. "
.
"-pthread -DNO_SSL "
;
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 "
;
}
print
$cmd
,
"\n"
;
system
(
$cmd
)
==
0
or
fail
(
"Cannot compile unit test"
);
system
(
$unit_test_exe
)
==
0
or
fail
(
"Unit test failed!"
);
}
sub
do_embedded_test
{
sub
do_embedded_test
{
my
$cmd
=
"cc -W -Wall -o $embed_exe $root/embed.c mongoose.c -I. "
.
my
$cmd
=
"cc -W -Wall -o $embed_exe $root/embed.c mongoose.c -I. "
.
"-pthread -DNO_SSL -DLISTENING_PORT=\\\"$port\\\""
;
"-pthread -DNO_SSL -DLISTENING_PORT=\\\"$port\\\""
;
...
...
test/unit_test.c
View file @
ed707936
...
@@ -8,6 +8,12 @@ int main(void) {
...
@@ -8,6 +8,12 @@ int main(void) {
assert
(
match_prefix
(
"/*"
,
2
,
"/a/b/c"
)
==
2
);
assert
(
match_prefix
(
"/*"
,
2
,
"/a/b/c"
)
==
2
);
assert
(
match_prefix
(
"*/*"
,
3
,
"/a/b/c"
)
==
2
);
assert
(
match_prefix
(
"*/*"
,
3
,
"/a/b/c"
)
==
2
);
assert
(
match_prefix
(
"**/"
,
3
,
"/a/b/c"
)
==
5
);
assert
(
match_prefix
(
"**/"
,
3
,
"/a/b/c"
)
==
5
);
assert
(
match_prefix
(
"**.foo|**.bar"
,
13
,
"a.bar"
)
==
5
);
assert
(
match_prefix
(
"a|b|cd"
,
6
,
"cdef"
)
==
2
);
assert
(
match_prefix
(
"a|b|c?"
,
6
,
"cdef"
)
==
2
);
assert
(
match_prefix
(
"a|?|cd"
,
6
,
"cdef"
)
==
1
);
assert
(
match_prefix
(
"/a/**.cgi"
,
9
,
"/foo/bar/x.cgi"
)
==
0
);
assert
(
match_prefix
(
"/a/**.cgi"
,
9
,
"/a/bar/x.cgi"
)
==
12
);
return
0
;
return
0
;
}
}
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