Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
mongoose
Commits
e28ee097
Commit
e28ee097
authored
Oct 20, 2015
by
Sergey Lyubka
Committed by
Marko Mikulicic
Oct 21, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move mongoose binary to dev repo
PUBLISHED_FROM=224a216abc4a7cca50d80f762dca602f54470105
parent
2b4e5448
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
128 additions
and
82 deletions
+128
-82
mongoose.c
mongoose.c
+104
-81
mongoose.h
mongoose.h
+24
-1
No files found.
mongoose.c
View file @
e28ee097
...
...
@@ -662,6 +662,42 @@ void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) {
memset
((
char
*
)
ctx
,
0
,
sizeof
(
*
ctx
));
}
/*
* Stringify binary data. Output buffer size must be 2 * size_of_input + 1
* because each byte of input takes 2 bytes in string representation
* plus 1 byte for the terminating \0 character.
*/
void
cs_to_hex
(
char
*
to
,
const
unsigned
char
*
p
,
size_t
len
)
{
static
const
char
*
hex
=
"0123456789abcdef"
;
for
(;
len
--
;
p
++
)
{
*
to
++
=
hex
[
p
[
0
]
>>
4
];
*
to
++
=
hex
[
p
[
0
]
&
0x0f
];
}
*
to
=
'\0'
;
}
char
*
cs_md5
(
char
buf
[
33
],
...)
{
unsigned
char
hash
[
16
];
const
unsigned
char
*
p
;
va_list
ap
;
MD5_CTX
ctx
;
MD5_Init
(
&
ctx
);
va_start
(
ap
,
buf
);
while
((
p
=
va_arg
(
ap
,
const
unsigned
char
*
)
)
!=
NULL
)
{
size_t
len
=
va_arg
(
ap
,
size_t
);
MD5_Update
(
&
ctx
,
p
,
len
);
}
va_end
(
ap
);
MD5_Final
(
hash
,
&
ctx
);
cs_to_hex
(
buf
,
hash
,
sizeof
(
hash
));
return
buf
;
}
#endif
/* EXCLUDE_COMMON */
#ifdef NS_MODULE_LINES
#line 1 "src/../../common/base64.c"
...
...
@@ -3481,7 +3517,7 @@ static int get_request_len(const char *s, int buf_len) {
static
const
char
*
parse_http_headers
(
const
char
*
s
,
const
char
*
end
,
int
len
,
struct
http_message
*
req
)
{
int
i
;
for
(
i
=
0
;
i
<
(
int
)
ARRAY_SIZE
(
req
->
header_names
);
i
++
)
{
for
(
i
=
0
;
i
<
(
int
)
ARRAY_SIZE
(
req
->
header_names
)
-
1
;
i
++
)
{
struct
mg_str
*
k
=
&
req
->
header_names
[
i
],
*
v
=
&
req
->
header_values
[
i
];
s
=
mg_skip
(
s
,
end
,
": "
,
k
);
...
...
@@ -3573,7 +3609,7 @@ int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req) {
struct
mg_str
*
mg_get_http_header
(
struct
http_message
*
hm
,
const
char
*
name
)
{
size_t
i
,
len
=
strlen
(
name
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
hm
->
header_names
)
;
i
++
)
{
for
(
i
=
0
;
hm
->
header_names
[
i
].
len
>
0
;
i
++
)
{
struct
mg_str
*
h
=
&
hm
->
header_names
[
i
],
*
v
=
&
hm
->
header_values
[
i
];
if
(
h
->
p
!=
NULL
&&
h
->
len
==
len
&&
!
mg_ncasecmp
(
h
->
p
,
name
,
len
))
return
v
;
...
...
@@ -4619,9 +4655,10 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...) {
int
mg_http_parse_header
(
struct
mg_str
*
hdr
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_size
)
{
int
ch
=
' '
,
ch1
=
','
,
len
=
0
,
n
=
strlen
(
var_name
);
const
char
*
p
,
*
end
=
hdr
->
p
+
hdr
->
len
,
*
s
=
NULL
;
const
char
*
p
,
*
end
=
hdr
?
hdr
->
p
+
hdr
->
len
:
NULL
,
*
s
=
NULL
;
if
(
buf
!=
NULL
&&
buf_size
>
0
)
buf
[
0
]
=
'\0'
;
if
(
hdr
==
NULL
)
return
0
;
/* Find where variable starts */
for
(
s
=
hdr
->
p
;
s
!=
NULL
&&
s
+
n
<
end
;
s
++
)
{
...
...
@@ -4663,66 +4700,6 @@ static int is_file_hidden(const char *path,
}
#ifndef MG_DISABLE_HTTP_DIGEST_AUTH
static
FILE
*
open_auth_file
(
const
char
*
path
,
int
is_directory
,
const
struct
mg_serve_http_opts
*
opts
)
{
char
buf
[
MAX_PATH_SIZE
];
const
char
*
p
;
FILE
*
fp
=
NULL
;
if
(
opts
->
global_auth_file
!=
NULL
)
{
fp
=
fopen
(
opts
->
global_auth_file
,
"r"
);
}
else
if
(
is_directory
&&
opts
->
per_directory_auth_file
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"%s%c%s"
,
path
,
DIRSEP
,
opts
->
per_directory_auth_file
);
fp
=
fopen
(
buf
,
"r"
);
}
else
if
(
opts
->
per_directory_auth_file
)
{
if
((
p
=
strrchr
(
path
,
'/'
))
==
NULL
&&
(
p
=
strrchr
(
path
,
'\\'
))
==
NULL
)
{
p
=
path
;
}
snprintf
(
buf
,
sizeof
(
buf
),
"%.*s/%s"
,
(
int
)
(
p
-
path
),
path
,
opts
->
per_directory_auth_file
);
fp
=
fopen
(
buf
,
"r"
);
}
return
fp
;
}
/*
* Stringify binary data. Output buffer size must be 2 * size_of_input + 1
* because each byte of input takes 2 bytes in string representation
* plus 1 byte for the terminating \0 character.
*/
static
void
bin2str
(
char
*
to
,
const
unsigned
char
*
p
,
size_t
len
)
{
static
const
char
*
hex
=
"0123456789abcdef"
;
for
(;
len
--
;
p
++
)
{
*
to
++
=
hex
[
p
[
0
]
>>
4
];
*
to
++
=
hex
[
p
[
0
]
&
0x0f
];
}
*
to
=
'\0'
;
}
static
char
*
mg_md5
(
char
*
buf
,
...)
{
unsigned
char
hash
[
16
];
const
unsigned
char
*
p
;
va_list
ap
;
MD5_CTX
ctx
;
MD5_Init
(
&
ctx
);
va_start
(
ap
,
buf
);
while
((
p
=
va_arg
(
ap
,
const
unsigned
char
*
)
)
!=
NULL
)
{
size_t
len
=
va_arg
(
ap
,
size_t
);
MD5_Update
(
&
ctx
,
p
,
len
);
}
va_end
(
ap
);
MD5_Final
(
hash
,
&
ctx
);
bin2str
(
buf
,
hash
,
sizeof
(
hash
));
return
buf
;
}
static
void
mkmd5resp
(
const
char
*
method
,
size_t
method_len
,
const
char
*
uri
,
size_t
uri_len
,
const
char
*
ha1
,
size_t
ha1_len
,
const
char
*
nonce
,
size_t
nonce_len
,
const
char
*
nc
,
...
...
@@ -4732,8 +4709,8 @@ static void mkmd5resp(const char *method, size_t method_len, const char *uri,
static
const
size_t
one
=
1
;
char
ha2
[
33
];
mg
_md5
(
ha2
,
method
,
method_len
,
colon
,
one
,
uri
,
uri_len
,
NULL
);
mg
_md5
(
resp
,
ha1
,
ha1_len
,
colon
,
one
,
nonce
,
nonce_len
,
colon
,
one
,
nc
,
cs
_md5
(
ha2
,
method
,
method_len
,
colon
,
one
,
uri
,
uri_len
,
NULL
);
cs
_md5
(
resp
,
ha1
,
ha1_len
,
colon
,
one
,
nonce
,
nonce_len
,
colon
,
one
,
nc
,
nc_len
,
colon
,
one
,
cnonce
,
cnonce_len
,
colon
,
one
,
qop
,
qop_len
,
colon
,
one
,
ha2
,
sizeof
(
ha2
)
-
1
,
NULL
);
}
...
...
@@ -4747,7 +4724,7 @@ int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
char
ha1
[
33
],
resp
[
33
],
cnonce
[
40
];
snprintf
(
cnonce
,
sizeof
(
cnonce
),
"%x"
,
(
unsigned
int
)
time
(
NULL
));
mg
_md5
(
ha1
,
user
,
(
size_t
)
strlen
(
user
),
colon
,
one
,
auth_domain
,
cs
_md5
(
ha1
,
user
,
(
size_t
)
strlen
(
user
),
colon
,
one
,
auth_domain
,
(
size_t
)
strlen
(
auth_domain
),
colon
,
one
,
passwd
,
(
size_t
)
strlen
(
passwd
),
NULL
);
mkmd5resp
(
method
,
strlen
(
method
),
uri
,
strlen
(
uri
),
ha1
,
sizeof
(
ha1
)
-
1
,
...
...
@@ -4820,26 +4797,47 @@ static int mg_http_check_digest_auth(struct http_message *hm,
}
static
int
is_authorized
(
struct
http_message
*
hm
,
const
char
*
path
,
int
is_directory
,
struct
mg_serve_http_opts
*
opts
)
{
int
is_directory
,
const
char
*
domain
,
const
char
*
passwords_file
,
int
is_global_pass_file
)
{
char
buf
[
MAX_PATH_SIZE
];
const
char
*
p
;
FILE
*
fp
;
int
authorized
=
1
;
if
(
opts
->
auth_domain
!=
NULL
&&
(
opts
->
per_directory_auth_file
!=
NULL
||
opts
->
global_auth_file
!=
NULL
)
&&
(
fp
=
open_auth_file
(
path
,
is_directory
,
opts
))
!=
NULL
)
{
authorized
=
mg_http_check_digest_auth
(
hm
,
opts
->
auth_domain
,
fp
);
fclose
(
fp
);
if
(
domain
!=
NULL
&&
passwords_file
!=
NULL
)
{
if
(
is_global_pass_file
)
{
fp
=
fopen
(
passwords_file
,
"r"
);
}
else
if
(
is_directory
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"%s%c%s"
,
path
,
DIRSEP
,
passwords_file
);
fp
=
fopen
(
buf
,
"r"
);
}
else
{
if
((
p
=
strrchr
(
path
,
'/'
))
==
NULL
&&
(
p
=
strrchr
(
path
,
'\\'
))
==
NULL
)
{
p
=
path
;
}
snprintf
(
buf
,
sizeof
(
buf
),
"%.*s/%s"
,
(
int
)
(
p
-
path
),
path
,
passwords_file
);
fp
=
fopen
(
buf
,
"r"
);
}
if
(
fp
!=
NULL
)
{
authorized
=
mg_http_check_digest_auth
(
hm
,
domain
,
fp
);
fclose
(
fp
);
}
}
return
authorized
;
}
#else
static
int
is_authorized
(
struct
http_message
*
hm
,
const
char
*
path
,
int
is_directory
,
struct
mg_serve_http_opts
*
opts
)
{
int
is_directory
,
const
char
*
domain
,
const
char
*
passwords_file
,
int
is_global_pass_file
)
{
(
void
)
hm
;
(
void
)
path
;
(
void
)
is_directory
;
(
void
)
opts
;
(
void
)
domain
;
(
void
)
passwords_file
;
(
void
)
is_global_pass_file
;
return
1
;
}
#endif
...
...
@@ -5691,6 +5689,16 @@ static void handle_cgi(struct mg_connection *nc, const char *prog,
}
#endif
static
void
mg_send_digest_auth_request
(
struct
mg_connection
*
c
,
const
char
*
domain
)
{
mg_printf
(
c
,
"HTTP/1.1 401 Unauthorized
\r\n
"
"WWW-Authenticate: Digest qop=
\"
auth
\"
, "
"realm=
\"
%s
\"
, nonce=
\"
%lu
\"\r\n
"
"Content-Length: 0
\r\n\r\n
"
,
domain
,
(
unsigned
long
)
time
(
NULL
));
}
void
mg_send_http_file
(
struct
mg_connection
*
nc
,
char
*
path
,
size_t
path_buf_len
,
struct
http_message
*
hm
,
struct
mg_serve_http_opts
*
opts
)
{
...
...
@@ -5706,13 +5714,11 @@ void mg_send_http_file(struct mg_connection *nc, char *path,
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
}
else
if
(
is_dav
&&
opts
->
dav_document_root
==
NULL
)
{
send_http_error
(
nc
,
501
,
NULL
);
}
else
if
(
!
is_authorized
(
hm
,
path
,
is_directory
,
opts
))
{
mg_printf
(
nc
,
"HTTP/1.1 401 Unauthorized
\r\n
"
"WWW-Authenticate: Digest qop=
\"
auth
\"
, "
"realm=
\"
%s
\"
, nonce=
\"
%lu
\"\r\n
"
"Content-Length: 0
\r\n\r\n
"
,
opts
->
auth_domain
,
(
unsigned
long
)
time
(
NULL
));
}
else
if
(
!
is_authorized
(
hm
,
path
,
is_directory
,
opts
->
auth_domain
,
opts
->
global_auth_file
,
1
)
||
!
is_authorized
(
hm
,
path
,
is_directory
,
opts
->
auth_domain
,
opts
->
per_directory_auth_file
,
0
))
{
mg_send_digest_auth_request
(
nc
,
opts
->
auth_domain
);
}
else
if
((
stat_result
!=
0
||
is_file_hidden
(
path
,
opts
))
&&
!
is_dav
)
{
mg_printf
(
nc
,
"%s"
,
"HTTP/1.1 404 Not Found
\r\n
Content-Length: 0
\r\n\r\n
"
);
}
else
if
(
is_directory
&&
path
[
strlen
(
path
)
-
1
]
!=
'/'
&&
!
is_dav
)
{
...
...
@@ -5723,6 +5729,13 @@ void mg_send_http_file(struct mg_connection *nc, char *path,
#ifndef MG_DISABLE_DAV
}
else
if
(
!
mg_vcmp
(
&
hm
->
method
,
"PROPFIND"
))
{
handle_propfind
(
nc
,
path
,
&
st
,
hm
,
opts
);
#ifndef MG_DISABLE_DAV_AUTH
}
else
if
(
is_dav
&&
(
opts
->
dav_auth_file
==
NULL
||
!
is_authorized
(
hm
,
path
,
is_directory
,
opts
->
auth_domain
,
opts
->
dav_auth_file
,
1
)))
{
mg_send_digest_auth_request
(
nc
,
opts
->
auth_domain
);
#endif
}
else
if
(
!
mg_vcmp
(
&
hm
->
method
,
"MKCOL"
))
{
handle_mkcol
(
nc
,
path
,
hm
);
}
else
if
(
!
mg_vcmp
(
&
hm
->
method
,
"DELETE"
))
{
...
...
@@ -5756,6 +5769,7 @@ void mg_send_http_file(struct mg_connection *nc, char *path,
void
mg_serve_http
(
struct
mg_connection
*
nc
,
struct
http_message
*
hm
,
struct
mg_serve_http_opts
opts
)
{
char
path
[
MG_MAX_PATH
];
struct
mg_str
*
hdr
;
uri_to_path
(
hm
,
path
,
sizeof
(
path
),
&
opts
);
if
(
opts
.
per_directory_auth_file
==
NULL
)
{
opts
.
per_directory_auth_file
=
".htpasswd"
;
...
...
@@ -5773,6 +5787,15 @@ void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
opts
.
index_files
=
"index.html,index.htm,index.shtml,index.cgi,index.php"
;
}
mg_send_http_file
(
nc
,
path
,
sizeof
(
path
),
hm
,
&
opts
);
/* Close connection for non-keep-alive requests */
if
(
mg_vcmp
(
&
hm
->
proto
,
"HTTP/1.1"
)
!=
0
||
((
hdr
=
mg_get_http_header
(
hm
,
"Connection"
))
!=
NULL
&&
mg_vcmp
(
hdr
,
"keep-alive"
)
!=
0
))
{
#if 0
nc->flags |= MG_F_SEND_AND_CLOSE;
#endif
}
}
#endif
/* MG_DISABLE_FILESYSTEM */
...
...
mongoose.h
View file @
e28ee097
...
...
@@ -404,6 +404,22 @@ void MD5_Init(MD5_CTX *c);
void
MD5_Update
(
MD5_CTX
*
c
,
const
unsigned
char
*
data
,
size_t
len
);
void
MD5_Final
(
unsigned
char
*
md
,
MD5_CTX
*
c
);
/*
* Return stringified MD5 hash for NULL terminated list of strings.
* Example:
*
* char buf[33];
* cs_md5(buf, "foo", "bar", NULL);
*/
char
*
cs_md5
(
char
buf
[
33
],
...);
/*
* Stringify binary data. Output buffer size must be 2 * size_of_input + 1
* because each byte of input takes 2 bytes in string representation
* plus 1 byte for the terminating \0 character.
*/
void
cs_to_hex
(
char
*
to
,
const
unsigned
char
*
p
,
size_t
len
);
#ifdef __cplusplus
}
#endif
/* __cplusplus */
...
...
@@ -1259,10 +1275,11 @@ extern "C" {
struct
http_message
{
struct
mg_str
message
;
/* Whole message: request line + headers + body */
struct
mg_str
proto
;
/* "HTTP/1.1" -- for both request and response */
/* HTTP Request line (or HTTP response line) */
struct
mg_str
method
;
/* "GET" */
struct
mg_str
uri
;
/* "/my_file.html" */
struct
mg_str
proto
;
/* "HTTP/1.1" -- for both request and response */
/* For responses, code and response status message are set */
int
resp_code
;
struct
mg_str
resp_status_msg
;
...
...
@@ -1561,6 +1578,9 @@ struct mg_serve_http_opts {
/* List of index files. Default is "" */
const
char
*
index_files
;
/* Path to a HTTP requests log file. Leave as NULL to disable access log. */
const
char
*
access_log_file
;
/*
* Leave as NULL to disable authentication.
* To enable directory protection with authentication, set this to ".htpasswd"
...
...
@@ -1614,6 +1634,9 @@ struct mg_serve_http_opts {
/* DAV document root. If NULL, DAV requests are going to fail. */
const
char
*
dav_document_root
;
/* DAV passwords file. If NULL, DAV requests are going to fail. */
const
char
*
dav_auth_file
;
/* Glob pattern for the files to hide. */
const
char
*
hidden_file_pattern
;
...
...
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