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
51ad50a6
Commit
51ad50a6
authored
9 years ago
by
Deomid Ryabkov
Committed by
rojer
9 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite URI -> path mapping, Windows fixes
PUBLISHED_FROM=6088958e92af2b028646816435892828ce9f7625
parent
148e1926
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
378 additions
and
183 deletions
+378
-183
mongoose.c
mongoose.c
+372
-182
mongoose.h
mongoose.h
+6
-1
No files found.
mongoose.c
View file @
51ad50a6
#include "mongoose.h"
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/internal.h"
#endif
/*
...
...
@@ -84,14 +84,15 @@ MG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max);
MG_INTERNAL
struct
mg_connection
*
mg_create_connection
(
struct
mg_mgr
*
mgr
,
mg_event_handler_t
callback
,
struct
mg_add_sock_opts
opts
);
#ifndef MG_DISABLE_FILESYSTEM
MG_INTERNAL
int
find_index_file
(
char
*
path
,
size_t
path_len
,
const
char
*
list
,
cs_stat_t
*
stp
);
MG_INTERNAL
int
mg_uri_to_local_path
(
struct
http_message
*
hm
,
const
struct
mg_serve_http_opts
*
opts
,
char
**
local_path
,
struct
mg_str
*
remainder
);
#endif
#ifdef _WIN32
void
to_wchar
(
const
char
*
path
,
wchar_t
*
wbuf
,
size_t
wbuf_len
);
/* Retur value is the same as for MultiByteToWideChar. */
int
to_wchar
(
const
char
*
path
,
wchar_t
*
wbuf
,
size_t
wbuf_len
);
#endif
/*
...
...
@@ -124,7 +125,7 @@ extern void *(*test_malloc)(size_t size);
extern
void
*
(
*
test_calloc
)(
size_t
count
,
size_t
size
);
#endif
/* MG_INTERNAL_HEADER_INCLUDED */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/base64.c"
#endif
/*
...
...
@@ -325,7 +326,7 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst) {
}
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/cs_dbg.c"
#endif
/*
...
...
@@ -357,7 +358,7 @@ void cs_log_printf(const char *fmt, ...) {
void
cs_log_set_level
(
enum
cs_log_level
level
)
{
s_cs_log_level
=
level
;
}
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/cs_dirent.c"
#endif
/*
...
...
@@ -425,7 +426,7 @@ int closedir(DIR *dir) {
}
struct
dirent
*
readdir
(
DIR
*
dir
)
{
struct
dirent
*
result
=
0
;
struct
dirent
*
result
=
NULL
;
if
(
dir
)
{
if
(
dir
->
handle
!=
INVALID_HANDLE_VALUE
)
{
...
...
@@ -493,7 +494,7 @@ int mkdir(const char *path, mode_t mode) {
#endif
/* CS_ENABLE_SPIFFS */
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/cs_time.c"
#endif
/*
...
...
@@ -521,7 +522,7 @@ double cs_time() {
#endif
return
now
;
}
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../deps/frozen/frozen.c"
#endif
/*
...
...
@@ -1021,7 +1022,7 @@ int json_emit(char *buf, int buf_len, const char *fmt, ...) {
return
len
;
}
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/md5.c"
#endif
/*
...
...
@@ -1268,7 +1269,7 @@ char *cs_md5(char buf[33], ...) {
}
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/mbuf.c"
#endif
/*
...
...
@@ -1365,7 +1366,7 @@ void mbuf_remove(struct mbuf *mb, size_t n) {
}
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/sha1.c"
#endif
/* Copyright(c) By Steve Reid <steve@edmweb.com> */
...
...
@@ -1619,7 +1620,7 @@ void cs_hmac_sha1(const unsigned char *key, size_t keylen,
}
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/../../common/str_util.c"
#endif
/*
...
...
@@ -1842,7 +1843,8 @@ int c_snprintf(char *buf, size_t buf_size, const char *fmt, ...) {
}
#ifdef _WIN32
void
to_wchar
(
const
char
*
path
,
wchar_t
*
wbuf
,
size_t
wbuf_len
)
{
int
to_wchar
(
const
char
*
path
,
wchar_t
*
wbuf
,
size_t
wbuf_len
)
{
int
ret
;
char
buf
[
MAX_PATH
*
2
],
buf2
[
MAX_PATH
*
2
],
*
p
;
strncpy
(
buf
,
path
,
sizeof
(
buf
));
...
...
@@ -1852,22 +1854,26 @@ void to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
p
=
buf
+
strlen
(
buf
)
-
1
;
while
(
p
>
buf
&&
p
[
-
1
]
!=
':'
&&
(
p
[
0
]
==
'\\'
||
p
[
0
]
==
'/'
))
*
p
--
=
'\0'
;
memset
(
wbuf
,
0
,
wbuf_len
*
sizeof
(
wchar_t
));
ret
=
MultiByteToWideChar
(
CP_UTF8
,
0
,
buf
,
-
1
,
wbuf
,
(
int
)
wbuf_len
);
/*
* Convert
to Unicode and back. If doubly-converted string does not
*
match the
original, something is fishy, reject.
* Convert
back to Unicode. If doubly-converted string does not match the
* original, something is fishy, reject.
*/
memset
(
wbuf
,
0
,
wbuf_len
*
sizeof
(
wchar_t
));
MultiByteToWideChar
(
CP_UTF8
,
0
,
buf
,
-
1
,
wbuf
,
(
int
)
wbuf_len
);
WideCharToMultiByte
(
CP_UTF8
,
0
,
wbuf
,
(
int
)
wbuf_len
,
buf2
,
sizeof
(
buf2
),
NULL
,
NULL
);
if
(
strcmp
(
buf
,
buf2
)
!=
0
)
{
wbuf
[
0
]
=
L'\0'
;
ret
=
0
;
}
return
ret
;
}
#endif
/* _WIN32 */
#endif
/* EXCLUDE_COMMON */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/net.c"
#endif
/*
...
...
@@ -2818,6 +2824,7 @@ int mg_check_ip_acl(const char *acl, uint32_t remote_ip) {
}
}
DBG
((
"%08x %c"
,
remote_ip
,
allowed
));
return
allowed
==
'+'
;
}
...
...
@@ -2846,7 +2853,7 @@ double mg_set_timer(struct mg_connection *c, double timestamp) {
double
mg_time
()
{
return
cs_time
();
}
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/net_if_socket.c"
#endif
/*
...
...
@@ -2927,7 +2934,9 @@ void mg_if_connect_udp(struct mg_connection *nc) {
int
mg_if_listen_tcp
(
struct
mg_connection
*
nc
,
union
socket_address
*
sa
)
{
sock_t
sock
=
mg_open_listening_socket
(
sa
,
SOCK_STREAM
);
if
(
sock
<
0
)
return
(
errno
?
errno
:
1
);
if
(
sock
==
INVALID_SOCKET
)
{
return
(
errno
?
errno
:
1
);
}
mg_sock_set
(
nc
,
sock
);
return
0
;
}
...
...
@@ -3197,7 +3206,7 @@ static int mg_ssl_err(struct mg_connection *conn, int res) {
static
void
mg_ssl_begin
(
struct
mg_connection
*
nc
)
{
int
server_side
=
nc
->
listener
!=
NULL
;
int
res
=
server_side
?
SSL_accept
(
nc
->
ssl
)
:
SSL_connect
(
nc
->
ssl
);
DBG
((
"%p %d res %d %d
%d"
,
nc
,
server_side
,
res
,
errno
,
mg_ssl_err
(
nc
,
res
)
));
DBG
((
"%p %d res %d %d
"
,
nc
,
server_side
,
res
,
errno
));
if
(
res
==
1
)
{
nc
->
flags
|=
MG_F_SSL_HANDSHAKE_DONE
;
...
...
@@ -3650,16 +3659,14 @@ int mg_socketpair(sock_t sp[2], int sock_type) {
static
void
mg_sock_get_addr
(
sock_t
sock
,
int
remote
,
union
socket_address
*
sa
)
{
socklen_t
slen
=
sizeof
(
*
sa
);
memset
(
sa
,
0
,
slen
);
#ifndef MG_CC3200
socklen_t
slen
=
sizeof
(
sa
);
memset
(
sa
,
0
,
sizeof
(
*
sa
));
if
(
remote
)
{
getpeername
(
sock
,
&
sa
->
sa
,
&
slen
);
}
else
{
getsockname
(
sock
,
&
sa
->
sa
,
&
slen
);
}
#else
memset
(
sa
,
0
,
sizeof
(
*
sa
));
#endif
}
...
...
@@ -3675,7 +3682,7 @@ void mg_if_get_conn_addr(struct mg_connection *nc, int remote,
}
#endif
/* !MG_DISABLE_SOCKET_IF */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/multithreading.c"
#endif
/*
...
...
@@ -3782,7 +3789,7 @@ void mg_enable_multithreading(struct mg_connection *nc) {
nc
->
handler
=
multithreaded_ev_handler
;
}
#endif
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/uri.c"
#endif
/*
...
...
@@ -3807,7 +3814,7 @@ static void parse_uri_component(const char **p, const char *end, char sep,
}
}
res
->
len
=
(
*
p
)
-
res
->
p
;
(
*
p
)
++
;
if
(
*
p
<
end
)
(
*
p
)
++
;
}
int
mg_parse_uri
(
struct
mg_str
uri
,
struct
mg_str
*
scheme
,
...
...
@@ -3924,7 +3931,42 @@ int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
return
0
;
}
#ifdef NS_MODULE_LINES
/* Normalize the URI path. Remove/resolve "." and "..". */
int
mg_normalize_uri_path
(
const
struct
mg_str
*
in
,
struct
mg_str
*
out
)
{
const
char
*
s
=
in
->
p
,
*
se
=
s
+
in
->
len
;
char
*
cp
=
(
char
*
)
out
->
p
,
*
d
;
if
(
in
->
len
==
0
||
*
s
!=
'/'
)
{
out
->
len
=
0
;
return
0
;
}
d
=
cp
;
while
(
s
<
se
)
{
const
char
*
next
=
s
;
struct
mg_str
component
;
parse_uri_component
(
&
next
,
se
,
'/'
,
&
component
);
if
(
mg_vcmp
(
&
component
,
"."
)
==
0
)
{
/* Yum. */
}
else
if
(
mg_vcmp
(
&
component
,
".."
)
==
0
)
{
/* Backtrack to previous slash. */
if
(
d
>
cp
+
1
&&
*
(
d
-
1
)
==
'/'
)
d
--
;
while
(
d
>
cp
&&
*
(
d
-
1
)
!=
'/'
)
d
--
;
}
else
{
memmove
(
d
,
s
,
next
-
s
);
d
+=
next
-
s
;
}
s
=
next
;
}
if
(
d
==
cp
)
*
d
++
=
'/'
;
out
->
p
=
cp
;
out
->
len
=
d
-
cp
;
return
1
;
}
#ifdef MG_MODULE_LINES
#line 0 "./src/http.c"
#endif
/*
...
...
@@ -4828,6 +4870,15 @@ void mg_send_response_line(struct mg_connection *nc, int status_code,
case
302
:
status_message
=
"Found"
;
break
;
case
401
:
status_message
=
"Unauthorized"
;
break
;
case
403
:
status_message
=
"Forbidden"
;
break
;
case
404
:
status_message
=
"Not Found"
;
break
;
case
416
:
status_message
=
"Requested range not satisfiable"
;
break
;
...
...
@@ -4898,7 +4949,7 @@ static void do_ssi_include(struct mg_connection *nc, const char *ssi, char *tag,
sscanf
(
tag
,
"
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
/* File name is relative to the currect document */
snprintf
(
path
,
sizeof
(
path
),
"%s"
,
ssi
);
if
((
p
=
strrchr
(
path
,
'/'
))
!=
NULL
)
{
if
((
p
=
strrchr
(
path
,
DIRSEP
))
!=
NULL
)
{
p
[
1
]
=
'\0'
;
}
snprintf
(
path
+
strlen
(
path
),
sizeof
(
path
)
-
strlen
(
path
),
"%s"
,
file_name
);
...
...
@@ -5024,7 +5075,7 @@ static void handle_ssi_request(struct mg_connection *nc, const char *path,
struct
mg_str
mime_type
;
if
((
fp
=
fopen
(
path
,
"rb"
))
==
NULL
)
{
send_http_error
(
nc
,
404
,
"Not Found"
);
send_http_error
(
nc
,
404
,
NULL
);
}
else
{
mg_set_close_on_exec
(
fileno
(
fp
));
...
...
@@ -5078,13 +5129,25 @@ static void mg_send_http_file2(struct mg_connection *nc, const char *path,
struct
proto_data_http
*
dp
;
struct
mg_str
mime_type
;
DBG
((
"%p [%s]"
,
nc
,
path
));
free_http_proto_data
(
nc
);
if
((
dp
=
(
struct
proto_data_http
*
)
MG_CALLOC
(
1
,
sizeof
(
*
dp
)))
==
NULL
)
{
send_http_error
(
nc
,
500
,
"Server Error"
);
/* LCOV_EXCL_LINE */
}
else
if
((
dp
->
fp
=
fopen
(
path
,
"rb"
))
==
NULL
)
{
int
code
;
switch
(
errno
)
{
case
EACCES
:
code
=
403
;
break
;
case
ENOENT
:
code
=
404
;
break
;
default:
code
=
500
;
};
MG_FREE
(
dp
);
nc
->
proto_data
=
NULL
;
send_http_error
(
nc
,
500
,
"Server Error
"
);
send_http_error
(
nc
,
code
,
"Open failed
"
);
}
else
if
(
mg_match_prefix
(
opts
->
ssi_pattern
,
strlen
(
opts
->
ssi_pattern
),
path
)
>
0
)
{
nc
->
proto_data
=
(
void
*
)
dp
;
...
...
@@ -5154,26 +5217,6 @@ static void mg_send_http_file2(struct mg_connection *nc, const char *path,
}
}
static
void
remove_double_dots
(
char
*
s
)
{
char
*
p
=
s
;
while
(
*
s
!=
'\0'
)
{
*
p
++
=
*
s
++
;
if
(
s
[
-
1
]
==
'/'
||
s
[
-
1
]
==
'\\'
)
{
while
(
s
[
0
]
!=
'\0'
)
{
if
(
s
[
0
]
==
'/'
||
s
[
0
]
==
'\\'
)
{
s
++
;
}
else
if
(
s
[
0
]
==
'.'
&&
s
[
1
]
==
'.'
)
{
s
+=
2
;
}
else
{
break
;
}
}
}
}
*
p
=
'\0'
;
}
#endif
int
mg_url_decode
(
const
char
*
src
,
int
src_len
,
char
*
dst
,
int
dst_len
,
...
...
@@ -5337,7 +5380,8 @@ int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
#ifndef MG_DISABLE_FILESYSTEM
static
int
is_file_hidden
(
const
char
*
path
,
const
struct
mg_serve_http_opts
*
opts
)
{
const
struct
mg_serve_http_opts
*
opts
,
int
exclude_specials
)
{
const
char
*
p1
=
opts
->
per_directory_auth_file
;
const
char
*
p2
=
opts
->
hidden_file_pattern
;
...
...
@@ -5347,8 +5391,9 @@ static int is_file_hidden(const char *path,
path
=
pdir
+
1
;
}
return
!
strcmp
(
path
,
"."
)
||
!
strcmp
(
path
,
".."
)
||
(
p1
!=
NULL
&&
!
strcmp
(
path
,
p1
))
||
return
(
exclude_specials
&&
(
!
strcmp
(
path
,
"."
)
||
!
strcmp
(
path
,
".."
)))
||
(
p1
!=
NULL
&&
mg_match_prefix
(
p1
,
strlen
(
p1
),
path
)
==
(
int
)
strlen
(
p1
))
||
(
p2
!=
NULL
&&
mg_match_prefix
(
p2
,
strlen
(
p2
),
path
)
>
0
);
}
...
...
@@ -5452,7 +5497,7 @@ 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
,
const
char
*
domain
,
const
char
*
passwords_file
,
int
is_global_pass_file
)
{
char
buf
[
M
AX_PATH_SIZE
];
char
buf
[
M
G_MAX_PATH
];
const
char
*
p
;
FILE
*
fp
;
int
authorized
=
1
;
...
...
@@ -5464,11 +5509,9 @@ static int is_authorized(struct http_message *hm, const char *path,
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
,
p
=
strrchr
(
path
,
DIRSEP
);
if
(
p
==
NULL
)
p
=
path
;
snprintf
(
buf
,
sizeof
(
buf
),
"%.*s%c%s"
,
(
int
)
(
p
-
path
),
path
,
DIRSEP
,
passwords_file
);
fp
=
fopen
(
buf
,
"r"
);
}
...
...
@@ -5479,6 +5522,8 @@ static int is_authorized(struct http_message *hm, const char *path,
}
}
DBG
((
"%s %s %d %d"
,
path
,
passwords_file
?
passwords_file
:
""
,
is_global_pass_file
,
authorized
));
return
authorized
;
}
#else
...
...
@@ -5574,10 +5619,11 @@ static void scan_directory(struct mg_connection *nc, const char *dir,
struct
dirent
*
dp
;
DIR
*
dirp
;
DBG
((
"%p [%s]"
,
nc
,
dir
));
if
((
dirp
=
(
opendir
(
dir
)))
!=
NULL
)
{
while
((
dp
=
readdir
(
dirp
))
!=
NULL
)
{
/* Do not show current dir and hidden files */
if
(
is_file_hidden
((
const
char
*
)
dp
->
d_name
,
opts
))
{
if
(
is_file_hidden
((
const
char
*
)
dp
->
d_name
,
opts
,
1
))
{
continue
;
}
snprintf
(
path
,
sizeof
(
path
),
"%s/%s"
,
dir
,
dp
->
d_name
);
...
...
@@ -5586,6 +5632,8 @@ static void scan_directory(struct mg_connection *nc, const char *dir,
}
}
closedir
(
dirp
);
}
else
{
DBG
((
"%p opendir(%s) -> %d"
,
nc
,
dir
,
errno
));
}
}
...
...
@@ -5748,7 +5796,7 @@ static int remove_directory(const struct mg_serve_http_opts *opts,
if
((
dirp
=
opendir
(
dir
))
==
NULL
)
return
0
;
while
((
dp
=
readdir
(
dirp
))
!=
NULL
)
{
if
(
is_file_hidden
((
const
char
*
)
dp
->
d_name
,
opts
))
{
if
(
is_file_hidden
((
const
char
*
)
dp
->
d_name
,
opts
,
1
))
{
continue
;
}
snprintf
(
path
,
sizeof
(
path
),
"%s%c%s"
,
dir
,
'/'
,
dp
->
d_name
);
...
...
@@ -5890,43 +5938,35 @@ static int is_dav_request(const struct mg_str *s) {
* appended to the `path`, stat-ed, and result of `stat()` passed to `stp`.
* If index file is not found, then `path` and `stp` remain unchanged.
*/
MG_INTERNAL
int
find_index_file
(
char
*
path
,
size_t
path_len
,
const
char
*
list
,
cs_stat_t
*
stp
)
{
cs_stat_t
st
;
size_t
n
=
strlen
(
path
);
MG_INTERNAL
void
find_index_file
(
const
char
*
path
,
const
char
*
list
,
char
**
index_file
,
cs_stat_t
*
stp
)
{
struct
mg_str
vec
;
size_t
path_len
=
strlen
(
path
);
int
found
=
0
;
/* The 'path' given to us points to the directory. Remove all trailing */
/* directory separator characters from the end of the path, and */
/* then append single directory separator character. */
while
(
n
>
0
&&
(
path
[
n
-
1
]
==
'/'
||
path
[
n
-
1
]
==
'\\'
))
{
n
--
;
}
*
index_file
=
NULL
;
/* Traverse index files list. For each entry, append it to the given */
/* path and see if the file exists. If it exists, break the loop */
while
((
list
=
mg_next_comma_list_entry
(
list
,
&
vec
,
NULL
))
!=
NULL
)
{
/* Prepare full path to the index file */
snprintf
(
path
+
n
,
path_len
-
n
,
"/%.*s"
,
(
int
)
vec
.
len
,
vec
.
p
);
path
[
path_len
-
1
]
=
'\0'
;
cs_stat_t
st
;
size_t
len
=
path_len
+
1
+
vec
.
len
+
1
;
*
index_file
=
(
char
*
)
MG_REALLOC
(
*
index_file
,
len
);
if
(
*
index_file
==
NULL
)
break
;
snprintf
(
*
index_file
,
len
,
"%s%c%.*s"
,
path
,
DIRSEP
,
(
int
)
vec
.
len
,
vec
.
p
);
/* Does it exist? */
if
(
!
mg_stat
(
path
,
&
st
))
{
/* Does it exist?
Is it a file?
*/
if
(
mg_stat
(
*
index_file
,
&
st
)
==
0
&&
S_ISREG
(
st
.
st_mode
))
{
/* Yes it does, break the loop */
*
stp
=
st
;
found
=
1
;
break
;
}
}
/* If no index file exists, restore directory path, keep trailing slash. */
if
(
!
found
)
{
path
[
n
]
=
'\0'
;
strncat
(
path
+
n
,
"/"
,
path_len
-
n
)
;
MG_FREE
(
*
index_file
)
;
*
index_file
=
NULL
;
}
return
found
;
DBG
((
"[%s] [%s]"
,
path
,
(
*
index_file
?
*
index_file
:
""
)));
}
static
int
send_port_based_redirect
(
struct
mg_connection
*
c
,
...
...
@@ -5957,39 +5997,155 @@ static int send_port_based_redirect(struct mg_connection *c,
return
0
;
}
static
void
uri_to_path
(
struct
http_message
*
hm
,
char
*
buf
,
size_t
buf_len
,
const
struct
mg_serve_http_opts
*
opts
)
{
char
uri
[
MG_MAX_PATH
];
struct
mg_str
a
,
b
,
*
host_hdr
=
mg_get_http_header
(
hm
,
"Host"
);
MG_INTERNAL
int
mg_uri_to_local_path
(
struct
http_message
*
hm
,
const
struct
mg_serve_http_opts
*
opts
,
char
**
local_path
,
struct
mg_str
*
remainder
)
{
int
ok
=
1
;
const
char
*
cp
=
hm
->
uri
.
p
,
*
cp_end
=
hm
->
uri
.
p
+
hm
->
uri
.
len
;
struct
mg_str
root
=
{
NULL
,
0
};
const
char
*
file_uri_start
=
cp
;
*
local_path
=
NULL
;
remainder
->
p
=
NULL
;
remainder
->
len
=
0
;
{
/* 1. Determine which root to use. */
const
char
*
rewrites
=
opts
->
url_rewrites
;
mg_url_decode
(
hm
->
uri
.
p
,
hm
->
uri
.
len
,
uri
,
sizeof
(
uri
),
0
);
remove_double_dots
(
uri
);
snprintf
(
buf
,
buf_len
,
"%s%s"
,
opts
->
document_root
,
uri
);
#ifndef MG_DISABLE_DAV
if
(
is_dav_request
(
&
hm
->
method
)
&&
opts
->
dav_document_root
!=
NULL
)
{
snprintf
(
buf
,
buf_len
,
"%s%s"
,
opts
->
dav_document_root
,
uri
);
struct
mg_str
*
hh
=
mg_get_http_header
(
hm
,
"Host"
);
struct
mg_str
a
,
b
;
/* Check rewrites first. */
while
((
rewrites
=
mg_next_comma_list_entry
(
rewrites
,
&
a
,
&
b
))
!=
NULL
)
{
if
(
a
.
len
>
1
&&
a
.
p
[
0
]
==
'@'
)
{
/* Host rewrite. */
if
(
hh
!=
NULL
&&
hh
->
len
==
a
.
len
-
1
&&
mg_ncasecmp
(
a
.
p
+
1
,
hh
->
p
,
a
.
len
-
1
)
==
0
)
{
root
=
b
;
break
;
}
}
else
{
/* Regular rewrite, URI=directory */
int
match_len
=
mg_match_prefix
(
a
.
p
,
a
.
len
,
cp
);
if
(
match_len
>
0
)
{
file_uri_start
=
cp
+
match_len
;
if
(
*
file_uri_start
==
'/'
||
file_uri_start
==
cp_end
)
{
/* Match ended at component boundary, ok. */
}
else
if
(
*
(
file_uri_start
-
1
)
==
'/'
)
{
/* Pattern ends with '/', backtrack. */
file_uri_start
--
;
}
else
{
/* No match: must fall on the component boundary. */
continue
;
}
root
=
b
;
break
;
}
}
}
/* If no rewrite rules matched, use DAV or regular document root. */
if
(
root
.
p
==
NULL
)
{
#ifndef MG_DISABLE_DAV
if
(
opts
->
dav_document_root
!=
NULL
&&
is_dav_request
(
&
hm
->
method
))
{
root
.
p
=
opts
->
dav_document_root
;
root
.
len
=
strlen
(
opts
->
dav_document_root
);
}
else
#endif
{
root
.
p
=
opts
->
document_root
;
root
.
len
=
strlen
(
opts
->
document_root
);
}
}
assert
(
root
.
p
!=
NULL
&&
root
.
len
>
0
);
}
/* Handle URL rewrites */
while
((
rewrites
=
mg_next_comma_list_entry
(
rewrites
,
&
a
,
&
b
))
!=
NULL
)
{
if
(
a
.
len
>
1
&&
a
.
p
[
0
]
==
'@'
&&
host_hdr
!=
NULL
&&
host_hdr
->
len
==
a
.
len
-
1
&&
mg_ncasecmp
(
a
.
p
+
1
,
host_hdr
->
p
,
a
.
len
-
1
)
==
0
)
{
/* This is a virtual host rewrite: @domain.name=document_root_dir */
snprintf
(
buf
,
buf_len
,
"%.*s%s"
,
(
int
)
b
.
len
,
b
.
p
,
uri
);
{
/* 2. Find where in the canonical URI path the local path ends. */
const
char
*
u
=
file_uri_start
+
1
;
char
*
lp
=
(
char
*
)
MG_MALLOC
(
root
.
len
+
hm
->
uri
.
len
+
1
);
char
*
lp_end
=
lp
+
root
.
len
+
hm
->
uri
.
len
+
1
;
char
*
p
=
lp
,
*
ps
;
int
exists
=
1
;
if
(
lp
==
NULL
)
{
ok
=
0
;
goto
out
;
}
memcpy
(
p
,
root
.
p
,
root
.
len
);
p
+=
root
.
len
;
if
(
*
(
p
-
1
)
==
DIRSEP
)
p
--
;
*
p
=
'\0'
;
ps
=
p
;
/* Chop off URI path components one by one and build local path. */
while
(
u
<=
cp_end
)
{
const
char
*
next
=
u
;
struct
mg_str
component
;
if
(
exists
)
{
cs_stat_t
st
;
exists
=
(
mg_stat
(
lp
,
&
st
)
==
0
);
if
(
exists
&&
S_ISREG
(
st
.
st_mode
))
{
/* We found the terminal, the rest of the URI (if any) is path_info.
*/
if
(
*
(
u
-
1
)
==
'/'
)
u
--
;
break
;
}
}
if
(
u
>=
cp_end
)
break
;
parse_uri_component
((
const
char
**
)
&
next
,
cp_end
,
'/'
,
&
component
);
if
(
component
.
len
>
0
)
{
int
len
;
memmove
(
p
+
1
,
component
.
p
,
component
.
len
);
len
=
mg_url_decode
(
p
+
1
,
component
.
len
,
p
+
1
,
lp_end
-
p
-
1
,
0
);
if
(
len
<=
0
)
{
ok
=
0
;
break
;
}
component
.
p
=
p
+
1
;
component
.
len
=
len
;
if
(
mg_vcmp
(
&
component
,
"."
)
==
0
)
{
/* Yum. */
}
else
if
(
mg_vcmp
(
&
component
,
".."
)
==
0
)
{
while
(
p
>
ps
&&
*
p
!=
DIRSEP
)
p
--
;
*
p
=
'\0'
;
}
else
{
/* This is a usual rewrite, URI=directory */
int
match_len
=
mg_match_prefix
(
a
.
p
,
a
.
len
,
uri
);
if
(
match_len
>
0
)
{
snprintf
(
buf
,
buf_len
,
"%.*s%s"
,
(
int
)
b
.
len
,
b
.
p
,
uri
+
match_len
);
size_t
i
;
#ifdef _WIN32
/* On Windows, make sure it's valid Unicode (no funny stuff). */
wchar_t
buf
[
MG_MAX_PATH
*
2
];
if
(
to_wchar
(
component
.
p
,
buf
,
MG_MAX_PATH
)
==
0
)
{
DBG
((
"[%.*s] smells funny"
,
(
int
)
component
.
len
,
component
.
p
));
ok
=
0
;
break
;
}
#endif
*
p
++
=
DIRSEP
;
/* No NULs and DIRSEPs in the component (percent-encoded). */
for
(
i
=
0
;
i
<
component
.
len
;
i
++
,
p
++
)
{
if
(
*
p
==
'\0'
||
*
p
==
DIRSEP
#ifdef _WIN32
/* On Windows, "/" is also accepted, so check for that too. */
||
*
p
==
'/'
#endif
)
{
ok
=
0
;
break
;
}
}
}
}
u
=
next
;
}
if
(
ok
)
{
*
local_path
=
lp
;
remainder
->
p
=
u
;
remainder
->
len
=
cp_end
-
u
;
}
else
{
MG_FREE
(
lp
);
}
}
out:
DBG
((
"'%.*s' -> '%s' + '%.*s'"
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
,
*
local_path
?
*
local_path
:
""
,
(
int
)
remainder
->
len
,
remainder
->
p
));
return
ok
;
}
#ifndef MG_DISABLE_CGI
...
...
@@ -6221,10 +6377,11 @@ static void addenv2(struct cgi_env_block *blk, const char *name) {
}
static
void
prepare_cgi_environment
(
struct
mg_connection
*
nc
,
const
char
*
prog
,
const
struct
mg_str
*
path_info
,
const
struct
http_message
*
hm
,
const
struct
mg_serve_http_opts
*
opts
,
struct
cgi_env_block
*
blk
)
{
const
char
*
s
,
*
slash
;
const
char
*
s
;
struct
mg_str
*
h
;
char
*
p
;
size_t
i
;
...
...
@@ -6260,27 +6417,22 @@ static void prepare_cgi_environment(struct mg_connection *nc, const char *prog,
hm
->
query_string
.
len
==
0
?
""
:
"?"
,
(
int
)
hm
->
query_string
.
len
,
hm
->
query_string
.
p
);
/* SCRIPT_NAME */
#if 0
if (nc->path_info != NULL) {
addenv(blk, "SCRIPT_NAME=%.*s",
(int) (strlen(ri->uri) - strlen(nc->path_info)), ri->uri);
addenv(blk, "PATH_INFO=%s", nc->path_info);
s
=
hm
->
uri
.
p
+
hm
->
uri
.
len
-
path_info
->
len
-
1
;
if
(
*
s
==
'/'
)
{
const
char
*
base_name
=
strrchr
(
prog
,
DIRSEP
);
addenv
(
blk
,
"SCRIPT_NAME=%.*s/%s"
,
(
int
)
(
s
-
hm
->
uri
.
p
),
hm
->
uri
.
p
,
(
base_name
!=
NULL
?
base_name
+
1
:
prog
));
}
else
{
#endif
s
=
strrchr
(
prog
,
'/'
);
slash
=
hm
->
uri
.
p
+
hm
->
uri
.
len
;
while
(
slash
>
hm
->
uri
.
p
&&
*
slash
!=
'/'
)
{
slash
--
;
addenv
(
blk
,
"SCRIPT_NAME=%.*s"
,
(
int
)
(
s
-
hm
->
uri
.
p
+
1
),
hm
->
uri
.
p
);
}
addenv
(
blk
,
"SCRIPT_NAME=%.*s%s"
,
(
int
)
(
slash
-
hm
->
uri
.
p
),
hm
->
uri
.
p
,
s
==
NULL
?
prog
:
s
);
#if 0
addenv
(
blk
,
"SCRIPT_FILENAME=%s"
,
prog
);
if
(
path_info
!=
NULL
&&
path_info
->
len
>
0
)
{
addenv
(
blk
,
"PATH_INFO=%.*s"
,
(
int
)
path_info
->
len
,
path_info
->
p
);
/* Not really translated... */
addenv
(
blk
,
"PATH_TRANSLATED=%.*s"
,
(
int
)
path_info
->
len
,
path_info
->
p
);
}
#endif
addenv
(
blk
,
"SCRIPT_FILENAME=%s"
,
prog
);
addenv
(
blk
,
"PATH_TRANSLATED=%s"
,
prog
);
addenv
(
blk
,
"HTTPS=%s"
,
nc
->
ssl
!=
NULL
?
"on"
:
"off"
);
if
((
h
=
mg_get_http_header
((
struct
http_message
*
)
hm
,
"Content-Type"
))
!=
...
...
@@ -6367,7 +6519,6 @@ static void cgi_ev_handler(struct mg_connection *cgi_nc, int ev,
struct
http_message
hm
;
struct
mg_str
*
h
;
parse_http_headers
(
io
->
buf
,
io
->
buf
+
io
->
len
,
io
->
len
,
&
hm
);
/*printf("=== %d [%.*s]\n", k, k, io->buf);*/
if
(
mg_get_http_header
(
&
hm
,
"Location"
)
!=
NULL
)
{
mg_printf
(
nc
,
"%s"
,
"HTTP/1.1 302 Moved
\r\n
"
);
}
else
if
((
h
=
mg_get_http_header
(
&
hm
,
"Status"
))
!=
NULL
)
{
...
...
@@ -6391,6 +6542,7 @@ static void cgi_ev_handler(struct mg_connection *cgi_nc, int ev,
}
static
void
handle_cgi
(
struct
mg_connection
*
nc
,
const
char
*
prog
,
const
struct
mg_str
*
path_info
,
const
struct
http_message
*
hm
,
const
struct
mg_serve_http_opts
*
opts
)
{
struct
proto_data_http
*
dp
;
...
...
@@ -6399,13 +6551,14 @@ static void handle_cgi(struct mg_connection *nc, const char *prog,
const
char
*
p
;
sock_t
fds
[
2
];
prepare_cgi_environment
(
nc
,
prog
,
hm
,
opts
,
&
blk
);
DBG
((
"%p [%s]"
,
nc
,
prog
));
prepare_cgi_environment
(
nc
,
prog
,
path_info
,
hm
,
opts
,
&
blk
);
/*
* CGI must be executed in its own directory. 'dir' must point to the
* directory containing executable program, 'p' must point to the
* executable program name relative to 'dir'.
*/
if
((
p
=
strrchr
(
prog
,
'/'
))
==
NULL
)
{
if
((
p
=
strrchr
(
prog
,
DIRSEP
))
==
NULL
)
{
snprintf
(
dir
,
sizeof
(
dir
),
"%s"
,
"."
);
}
else
{
snprintf
(
dir
,
sizeof
(
dir
),
"%.*s"
,
(
int
)
(
p
-
prog
),
prog
);
...
...
@@ -6526,35 +6679,61 @@ static int is_creation_request(const struct http_message *hm) {
return
mg_vcmp
(
&
hm
->
method
,
"MKCOL"
)
==
0
||
mg_vcmp
(
&
hm
->
method
,
"PUT"
)
==
0
;
}
void
mg_send_http_file
(
struct
mg_connection
*
nc
,
char
*
path
,
size_t
path_buf_len
,
struct
http_message
*
hm
,
MG_INTERNAL
void
mg_send_http_file
(
struct
mg_connection
*
nc
,
char
*
path
,
const
struct
mg_str
*
path_info
,
struct
http_message
*
hm
,
struct
mg_serve_http_opts
*
opts
)
{
int
stat_result
,
is_directory
,
is_dav
=
is_dav_request
(
&
hm
->
method
);
uint32_t
remote_ip
=
ntohl
(
*
(
uint32_t
*
)
&
nc
->
sa
.
sin
.
sin_addr
);
int
exists
,
is_directory
,
is_dav
=
is_dav_request
(
&
hm
->
method
);
int
is_cgi
;
char
*
index_file
=
NULL
;
cs_stat_t
st
;
DBG
((
"serving [%s]"
,
path
));
stat_result
=
mg_stat
(
path
,
&
st
);
is_directory
=
!
stat_result
&&
S_ISDIR
(
st
.
st_mode
);
exists
=
(
mg_stat
(
path
,
&
st
)
==
0
);
is_directory
=
exists
&&
S_ISDIR
(
st
.
st_mode
);
if
(
mg_check_ip_acl
(
opts
->
ip_acl
,
remote_ip
)
!=
1
)
{
/* Not allowed to connect */
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
}
else
if
(
is_dav
&&
opts
->
dav_document_root
==
NULL
)
{
if
(
is_directory
)
find_index_file
(
path
,
opts
->
index_files
,
&
index_file
,
&
st
);
is_cgi
=
(
mg_match_prefix
(
opts
->
cgi_file_pattern
,
strlen
(
opts
->
cgi_file_pattern
),
index_file
?
index_file
:
path
)
>
0
);
DBG
((
"%p %.*s [%s] exists=%d is_dir=%d is_dav=%d is_cgi=%d index=%s"
,
nc
,
(
int
)
hm
->
method
.
len
,
hm
->
method
.
p
,
path
,
exists
,
is_directory
,
is_dav
,
is_cgi
,
index_file
?
index_file
:
""
));
if
(
is_directory
&&
hm
->
uri
.
p
[
hm
->
uri
.
len
-
1
]
!=
'/'
&&
!
is_dav
)
{
mg_printf
(
nc
,
"HTTP/1.1 301 Moved
\r\n
Location: %.*s/
\r\n
"
"Content-Length: 0
\r\n\r\n
"
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
);
MG_FREE
(
index_file
);
return
;
}
/* If we have path_info, the only way to handle it is CGI. */
if
(
path_info
->
len
>
0
&&
!
is_cgi
)
{
send_http_error
(
nc
,
501
,
NULL
);
return
;
}
else
if
(
is_cgi
)
{
#if !defined(MG_DISABLE_CGI)
handle_cgi
(
nc
,
index_file
?
index_file
:
path
,
path_info
,
hm
,
opts
);
#else
send_http_error
(
nc
,
501
,
NULL
);
#endif
/* MG_DISABLE_CGI */
MG_FREE
(
index_file
);
return
;
}
if
(
is_dav
&&
opts
->
dav_document_root
==
NULL
)
{
send_http_error
(
nc
,
501
,
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
))
&&
}
else
if
((
!
exists
||
is_file_hidden
(
path
,
opts
,
0
/* specials are ok */
))
&&
!
is_creation_request
(
hm
))
{
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
)
{
mg_printf
(
nc
,
"HTTP/1.1 301 Moved
\r\n
Location: %.*s/
\r\n
"
"Content-Length: 0
\r\n\r\n
"
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
);
send_http_error
(
nc
,
404
,
NULL
);
#ifndef MG_DISABLE_DAV
}
else
if
(
!
mg_vcmp
(
&
hm
->
method
,
"PROPFIND"
))
{
handle_propfind
(
nc
,
path
,
&
st
,
hm
,
opts
);
...
...
@@ -6581,35 +6760,36 @@ void mg_send_http_file(struct mg_connection *nc, char *path,
#endif
}
else
if
(
!
mg_vcmp
(
&
hm
->
method
,
"OPTIONS"
))
{
send_options
(
nc
);
}
else
if
(
S_ISDIR
(
st
.
st_mode
)
&&
!
find_index_file
(
path
,
path_buf_len
,
opts
->
index_files
,
&
st
))
{
if
(
strcmp
(
opts
->
enable_directory_listing
,
"yes"
)
==
0
)
{
}
else
if
(
is_directory
&&
index_file
==
NULL
)
{
#ifndef MG_DISABLE_DIRECTORY_LISTING
if
(
strcmp
(
opts
->
enable_directory_listing
,
"yes"
)
==
0
)
{
send_directory_listing
(
nc
,
path
,
hm
,
opts
);
#else
send_http_error
(
nc
,
501
,
NULL
);
#endif
}
else
{
send_http_error
(
nc
,
403
,
NULL
);
}
}
else
if
(
mg_match_prefix
(
opts
->
cgi_file_pattern
,
strlen
(
opts
->
cgi_file_pattern
),
path
)
>
0
)
{
#if !defined(MG_DISABLE_CGI)
handle_cgi
(
nc
,
path
,
hm
,
opts
);
#else
send_http_error
(
nc
,
501
,
NULL
);
#endif
/* MG_DISABLE_CGI */
#endif
}
else
if
(
mg_is_not_modified
(
hm
,
&
st
))
{
send_http_error
(
nc
,
304
,
"Not Modified"
);
}
else
{
mg_send_http_file2
(
nc
,
path
,
&
st
,
hm
,
opts
);
mg_send_http_file2
(
nc
,
index_file
?
index_file
:
path
,
&
st
,
hm
,
opts
);
}
MG_FREE
(
index_file
);
}
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
;
char
*
path
=
NULL
;
struct
mg_str
*
hdr
,
path_info
;
uint32_t
remote_ip
=
ntohl
(
*
(
uint32_t
*
)
&
nc
->
sa
.
sin
.
sin_addr
);
if
(
mg_check_ip_acl
(
opts
.
ip_acl
,
remote_ip
)
!=
1
)
{
/* Not allowed to connect */
send_http_error
(
nc
,
403
,
NULL
);
nc
->
flags
|=
MG_F_SEND_AND_CLOSE
;
return
;
}
if
(
send_port_based_redirect
(
nc
,
hm
,
&
opts
))
{
return
;
...
...
@@ -6633,9 +6813,19 @@ void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
if
(
opts
.
index_files
==
NULL
)
{
opts
.
index_files
=
"index.html,index.htm,index.shtml,index.cgi,index.php"
;
}
/* Normalize path - resolve "." and ".." (in-place). */
if
(
!
mg_normalize_uri_path
(
&
hm
->
uri
,
&
hm
->
uri
))
{
send_http_error
(
nc
,
400
,
NULL
);
return
;
}
if
(
mg_uri_to_local_path
(
hm
,
&
opts
,
&
path
,
&
path_info
)
==
0
)
{
send_http_error
(
nc
,
404
,
NULL
);
return
;
}
mg_send_http_file
(
nc
,
path
,
&
path_info
,
hm
,
&
opts
);
uri_to_path
(
hm
,
path
,
sizeof
(
path
),
&
opts
);
mg_send_http_file
(
nc
,
path
,
sizeof
(
path
),
hm
,
&
opts
)
;
MG_FREE
(
path
);
path
=
NULL
;
/* Close connection for non-keep-alive requests */
if
(
mg_vcmp
(
&
hm
->
proto
,
"HTTP/1.1"
)
!=
0
||
...
...
@@ -6764,7 +6954,7 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
}
#endif
/* MG_DISABLE_HTTP */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/util.c"
#endif
/*
...
...
@@ -7130,7 +7320,7 @@ struct mg_str mg_mk_str(const char *s) {
struct
mg_str
ret
=
{
s
,
strlen
(
s
)};
return
ret
;
}
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/json-rpc.c"
#endif
/* Copyright (c) 2014 Cesanta Software Limited */
...
...
@@ -7291,7 +7481,7 @@ int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
}
#endif
/* MG_DISABLE_JSON_RPC */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/mqtt.c"
#endif
/*
...
...
@@ -7592,7 +7782,7 @@ void mg_mqtt_disconnect(struct mg_connection *nc) {
}
#endif
/* MG_DISABLE_MQTT */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/mqtt-broker.c"
#endif
/*
...
...
@@ -7765,7 +7955,7 @@ struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
}
#endif
/* MG_ENABLE_MQTT_BROKER */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/dns.c"
#endif
/*
...
...
@@ -8125,7 +8315,7 @@ void mg_set_protocol_dns(struct mg_connection *nc) {
}
#endif
/* MG_DISABLE_DNS */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/dns-server.c"
#endif
/*
...
...
@@ -8199,7 +8389,7 @@ int mg_dns_reply_record(struct mg_dns_reply *reply,
}
#endif
/* MG_ENABLE_DNS_SERVER */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/resolv.c"
#endif
/*
...
...
@@ -8458,7 +8648,7 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
}
#endif
/* MG_DISABLE_RESOLVE */
#ifdef
NS
_MODULE_LINES
#ifdef
MG
_MODULE_LINES
#line 0 "./src/coap.c"
#endif
/*
...
...
This diff is collapsed.
Click to expand it.
mongoose.h
View file @
51ad50a6
...
...
@@ -181,7 +181,10 @@ typedef struct stat cs_stat_t;
typedef
struct
_stati64
cs_stat_t
;
#endif
#ifndef S_ISDIR
#define S_ISDIR(x) ((x) &_S_IFDIR)
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
#endif
#define DIRSEP '\\'
...
...
@@ -1278,6 +1281,8 @@ int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
unsigned
int
*
port
,
struct
mg_str
*
path
,
struct
mg_str
*
query
,
struct
mg_str
*
fragment
);
int
mg_normalize_uri_path
(
const
struct
mg_str
*
in
,
struct
mg_str
*
out
);
#ifdef __cplusplus
}
#endif
/* __cplusplus */
...
...
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