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
2a7e720f
Commit
2a7e720f
authored
Dec 06, 2013
by
Sergey Lyubka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
app code moved to qcomm.c
parent
ec22250d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
149 deletions
+96
-149
core.c
build/src/core.c
+96
-149
No files found.
build/src/core.c
View file @
2a7e720f
...
...
@@ -93,7 +93,6 @@ typedef struct stat file_stat_t;
#define to64(x) strtoll(x, NULL, 10)
#endif
//#include "mongoose.h"
#include "core.h"
struct
linked_list_link
{
struct
linked_list_link
*
prev
,
*
next
;
};
...
...
@@ -160,30 +159,6 @@ enum {
SSL_CERTIFICATE
,
SSI_PATTERN
,
URL_REWRITES
,
NUM_OPTIONS
};
static
const
char
*
static_config_options
[]
=
{
"access_control_list"
,
NULL
,
"access_log_file"
,
NULL
,
"auth_domain"
,
"mydomain.com"
,
"cgi_interpreter"
,
NULL
,
"cgi_pattern"
,
"**.cgi$|**.pl$|**.php$"
,
"document_root"
,
NULL
,
"enable_directory_listing"
,
"yes"
,
"error_log_file"
,
NULL
,
"extra_mime_types"
,
NULL
,
"global_auth_file"
,
NULL
,
"hide_files_patterns"
,
NULL
,
"idle_timeout_ms"
,
"30000"
,
"index_files"
,
"index.html,index.htm,index.cgi,index.shtml,index.php,index.lp"
,
"listening_port"
,
NULL
,
"num_threads"
,
"50"
,
"put_delete_auth_file"
,
NULL
,
"run_as_user"
,
NULL
,
"ssl_certificate"
,
NULL
,
"ssi_pattern"
,
"**.shtml$|**.shtm$"
,
"url_rewrites"
,
NULL
,
NULL
};
struct
mg_server
{
sock_t
listening_sock
;
union
socket_address
lsa
;
// Listening socket address
...
...
@@ -194,12 +169,14 @@ struct mg_server {
sock_t
ctl
[
2
];
// Control socketpair. Used to wake up from select() call
};
// Expandable IO buffer
struct
iobuf
{
char
*
buf
;
// Buffer that holds the data
int
size
;
// Buffer size
int
len
;
// Number of bytes currently in a buffer
};
// Local endpoint representation
union
endpoint
{
int
fd
;
// Opened regular local file
sock_t
cgi_sock
;
// CGI socket
...
...
@@ -284,32 +261,35 @@ static const struct {
{
NULL
,
0
,
NULL
}
};
static
const
char
*
static_config_options
[]
=
{
"access_control_list"
,
NULL
,
"access_log_file"
,
NULL
,
"auth_domain"
,
"mydomain.com"
,
"cgi_interpreter"
,
NULL
,
"cgi_pattern"
,
"**.cgi$|**.pl$|**.php$"
,
"document_root"
,
NULL
,
"enable_directory_listing"
,
"yes"
,
"error_log_file"
,
NULL
,
"extra_mime_types"
,
NULL
,
"global_auth_file"
,
NULL
,
"hide_files_patterns"
,
NULL
,
"idle_timeout_ms"
,
"30000"
,
"index_files"
,
"index.html,index.htm,index.cgi,index.shtml,index.php,index.lp"
,
"listening_port"
,
NULL
,
"num_threads"
,
"50"
,
"put_delete_auth_file"
,
NULL
,
"run_as_user"
,
NULL
,
"ssl_certificate"
,
NULL
,
"ssi_pattern"
,
"**.shtml$|**.shtm$"
,
"url_rewrites"
,
NULL
,
NULL
};
static
const
char
*
static_month_names
[]
=
{
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
};
const
char
**
mg_get_valid_option_names
(
void
)
{
return
static_config_options
;
}
static
int
get_option_index
(
const
char
*
name
)
{
int
i
;
for
(
i
=
0
;
static_config_options
[
i
*
2
]
!=
NULL
;
i
++
)
{
if
(
strcmp
(
static_config_options
[
i
*
2
],
name
)
==
0
)
{
return
i
;
}
}
return
-
1
;
}
const
char
*
mg_get_option
(
const
struct
mg_server
*
srv
,
const
char
*
name
)
{
int
i
=
get_option_index
(
name
);
return
i
==
-
1
?
NULL
:
srv
->
config_options
[
i
]
==
NULL
?
""
:
srv
->
config_options
[
i
];
}
int
mg_start_thread
(
void
*
(
*
f
)(
void
*
),
void
*
p
)
{
#ifdef _WIN32
return
(
long
)
_beginthread
((
void
(
__cdecl
*
)(
void
*
))
f
,
0
,
p
)
==
-
1L
?
-
1
:
0
;
...
...
@@ -477,7 +457,7 @@ static pid_t start_process(const char *interp, const char *cmd, const char *env,
return
pid
;
}
#endif
#endif
// _WIN32
// This structure helps to create an environment for the spawned CGI program.
// Environment is an array of "VARIABLE=VALUE\0" ASCIIZ strings,
...
...
@@ -690,40 +670,6 @@ static char *mg_strdup(const char *str) {
return
copy
;
}
// Valid listening port spec is: [ip_address:]port, e.g. "80", "127.0.0.1:3128"
static
int
parse_port_string
(
const
char
*
str
,
union
socket_address
*
sa
)
{
unsigned
int
a
,
b
,
c
,
d
,
port
;
#if defined(USE_IPV6)
char
buf
[
100
];
#endif
// MacOS needs that. If we do not zero it, subsequent bind() will fail.
// Also, all-zeroes in the socket address means binding to all addresses
// for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).
memset
(
sa
,
0
,
sizeof
(
*
sa
));
sa
->
sin
.
sin_family
=
AF_INET
;
if
(
sscanf
(
str
,
"%u.%u.%u.%u:%u"
,
&
a
,
&
b
,
&
c
,
&
d
,
&
port
)
==
5
)
{
// Bind to a specific IPv4 address, e.g. 192.168.1.5:8080
sa
->
sin
.
sin_addr
.
s_addr
=
htonl
((
a
<<
24
)
|
(
b
<<
16
)
|
(
c
<<
8
)
|
d
);
sa
->
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
#if defined(USE_IPV6)
}
else
if
(
sscanf
(
str
,
"[%49[^]]]:%d%n"
,
buf
,
&
port
,
&
len
)
==
2
&&
inet_pton
(
AF_INET6
,
buf
,
&
so
->
lsa
.
sin6
.
sin6_addr
))
{
// IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080
so
->
lsa
.
sin6
.
sin6_family
=
AF_INET6
;
so
->
lsa
.
sin6
.
sin6_port
=
htons
((
uint16_t
)
port
);
#endif
}
else
if
(
sscanf
(
str
,
"%u"
,
&
port
)
==
1
)
{
// If only port is specified, bind to IPv4, INADDR_ANY
sa
->
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
}
else
{
port
=
0
;
// Parsing failure. Make port invalid.
}
return
port
>
0
&&
port
<
0xffff
;
}
static
int
isbyte
(
int
n
)
{
return
n
>=
0
&&
n
<=
255
;
}
...
...
@@ -1923,7 +1869,7 @@ void mg_destroy_server(struct mg_server **server) {
// Apply function to all active connections. Return number of active
// connections. Function could be NULL.
static
int
mg_iterate_over_connections
(
struct
mg_server
*
server
,
int
mg_iterate_over_connections
(
struct
mg_server
*
server
,
void
(
*
func
)(
struct
mg_connection
*
,
void
*
),
void
*
param
)
{
struct
linked_list_link
*
lp
,
*
tmp
;
...
...
@@ -1951,6 +1897,67 @@ void mg_add_uri_handler(struct mg_server *server, const char *uri,
}
}
const
char
**
mg_get_valid_option_names
(
void
)
{
return
static_config_options
;
}
static
int
get_option_index
(
const
char
*
name
)
{
int
i
;
for
(
i
=
0
;
static_config_options
[
i
*
2
]
!=
NULL
;
i
++
)
{
if
(
strcmp
(
static_config_options
[
i
*
2
],
name
)
==
0
)
{
return
i
;
}
}
return
-
1
;
}
static
void
set_default_option_values
(
char
**
opts
)
{
const
char
*
value
,
**
all_opts
=
mg_get_valid_option_names
();
int
i
;
for
(
i
=
0
;
all_opts
[
i
*
2
]
!=
NULL
;
i
++
)
{
value
=
all_opts
[
i
*
2
+
1
];
if
(
opts
[
i
]
==
NULL
&&
value
!=
NULL
)
{
opts
[
i
]
=
mg_strdup
(
value
);
}
}
}
// Valid listening port spec is: [ip_address:]port, e.g. "80", "127.0.0.1:3128"
static
int
parse_port_string
(
const
char
*
str
,
union
socket_address
*
sa
)
{
unsigned
int
a
,
b
,
c
,
d
,
port
;
#if defined(USE_IPV6)
char
buf
[
100
];
#endif
// MacOS needs that. If we do not zero it, subsequent bind() will fail.
// Also, all-zeroes in the socket address means binding to all addresses
// for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).
memset
(
sa
,
0
,
sizeof
(
*
sa
));
sa
->
sin
.
sin_family
=
AF_INET
;
if
(
sscanf
(
str
,
"%u.%u.%u.%u:%u"
,
&
a
,
&
b
,
&
c
,
&
d
,
&
port
)
==
5
)
{
// Bind to a specific IPv4 address, e.g. 192.168.1.5:8080
sa
->
sin
.
sin_addr
.
s_addr
=
htonl
((
a
<<
24
)
|
(
b
<<
16
)
|
(
c
<<
8
)
|
d
);
sa
->
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
#if defined(USE_IPV6)
}
else
if
(
sscanf
(
str
,
"[%49[^]]]:%d%n"
,
buf
,
&
port
,
&
len
)
==
2
&&
inet_pton
(
AF_INET6
,
buf
,
&
so
->
lsa
.
sin6
.
sin6_addr
))
{
// IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080
so
->
lsa
.
sin6
.
sin6_family
=
AF_INET6
;
so
->
lsa
.
sin6
.
sin6_port
=
htons
((
uint16_t
)
port
);
#endif
}
else
if
(
sscanf
(
str
,
"%u"
,
&
port
)
==
1
)
{
// If only port is specified, bind to IPv4, INADDR_ANY
sa
->
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
}
else
{
port
=
0
;
// Parsing failure. Make port invalid.
}
return
port
>
0
&&
port
<
0xffff
;
}
const
char
*
mg_set_option
(
struct
mg_server
*
server
,
const
char
*
name
,
const
char
*
value
)
{
int
ind
=
get_option_index
(
name
);
...
...
@@ -1981,10 +1988,14 @@ const char *mg_set_option(struct mg_server *server, const char *name,
return
error_msg
;
}
const
char
*
mg_get_option
(
const
struct
mg_server
*
server
,
const
char
*
name
)
{
const
char
*
const
*
opts
=
server
->
config_options
;
int
i
=
get_option_index
(
name
);
return
i
==
-
1
?
NULL
:
opts
[
i
]
==
NULL
?
""
:
opts
[
i
];
}
struct
mg_server
*
mg_create_server
(
void
*
server_data
)
{
struct
mg_server
*
server
=
(
struct
mg_server
*
)
calloc
(
1
,
sizeof
(
*
server
));
const
char
*
value
;
int
i
;
#ifdef _WIN32
WSADATA
data
;
...
...
@@ -1996,71 +2007,7 @@ struct mg_server *mg_create_server(void *server_data) {
mg_socketpair
(
server
->
ctl
);
server
->
server_data
=
server_data
;
server
->
listening_sock
=
INVALID_SOCKET
;
// Set default options values
for
(
i
=
0
;
static_config_options
[
i
*
2
]
!=
NULL
;
i
++
)
{
value
=
static_config_options
[
i
*
2
+
1
];
if
(
server
->
config_options
[
i
]
==
NULL
&&
value
!=
NULL
)
{
server
->
config_options
[
i
]
=
mg_strdup
(
value
);
}
}
set_default_option_values
(
server
->
config_options
);
return
server
;
}
// End of library, start of the application code
static
void
iterate_callback
(
struct
mg_connection
*
c
,
void
*
param
)
{
if
(
c
->
is_websocket
)
{
char
buf
[
20
];
int
len
=
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
*
(
int
*
)
param
);
mg_websocket_write
(
c
,
1
,
buf
,
len
);
}
}
// This thread sends heartbeats to all websocket connections with 1s interval.
// The heartbeat message is simply an iteration counter.
static
void
*
timer_thread
(
void
*
param
)
{
struct
mg_server
*
server
=
(
struct
mg_server
*
)
param
;
int
i
;
for
(
i
=
0
;
i
<
9999999
;
i
++
)
{
sleep
(
1
);
mg_iterate_over_connections
(
server
,
iterate_callback
,
&
i
);
}
return
NULL
;
}
// This handler is called for each incoming websocket frame, one or more
// times for connection lifetime.
static
int
handler
(
struct
mg_connection
*
conn
)
{
static
const
char
oops
[]
=
"HTTP/1.0 200 OK
\r\n\r\n
websocket data expected
\n
"
;
if
(
!
conn
->
is_websocket
)
{
mg_write
(
conn
,
oops
,
sizeof
(
oops
)
-
1
);
return
1
;
}
mg_websocket_write
(
conn
,
1
,
conn
->
content
,
conn
->
content_len
);
DBG
((
"WS msg len: %d"
,
conn
->
content_len
));
return
conn
->
content_len
==
4
&&
!
memcmp
(
conn
->
content
,
"exit"
,
4
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
struct
mg_server
*
server
=
mg_create_server
(
NULL
);
mg_set_option
(
server
,
"listening_port"
,
"8080"
);
mg_set_option
(
server
,
"document_root"
,
argc
>
1
?
argv
[
1
]
:
"."
);
mg_add_uri_handler
(
server
,
"/ws"
,
handler
);
mg_start_thread
(
timer_thread
,
server
);
printf
(
"Started on port %s
\n
"
,
mg_get_option
(
server
,
"listening_port"
));
for
(;;)
{
mg_poll_server
(
server
,
3000
);
}
mg_destroy_server
(
&
server
);
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