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
e28ee097
Commit
e28ee097
authored
9 years ago
by
Sergey Lyubka
Committed by
Marko Mikulicic
9 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move mongoose binary to dev repo
PUBLISHED_FROM=224a216abc4a7cca50d80f762dca602f54470105
parent
2b4e5448
Changes
2
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 */
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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