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
14526a21
Commit
14526a21
authored
Jan 28, 2014
by
Sergey Lyubka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mg_add_uri_handler -> mg_set_request_handler()
parent
a6cfbd25
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
117 additions
and
121 deletions
+117
-121
API.md
docs/API.md
+26
-15
Makefile
examples/Makefile
+1
-1
auth.c
examples/auth.c
+1
-1
hello.c
examples/hello.c
+2
-2
multi_threaded.c
examples/multi_threaded.c
+3
-3
post.c
examples/post.c
+2
-2
upload.c
examples/upload.c
+2
-2
websocket.c
examples/websocket.c
+6
-5
websocket.html
examples/websocket.html
+7
-4
mongoose.c
mongoose.c
+36
-61
mongoose.h
mongoose.h
+7
-6
unit_test.c
unit_test.c
+24
-19
No files found.
docs/API.md
View file @
14526a21
...
...
@@ -60,12 +60,26 @@ that take `struct mg_server *` parameter. Mongoose does not
mutex-protect
`struct mg_server *`
, therefore the best practice is
to call server management functions from the same thread (an IO thread).
void mg_add_uri_handler(struct mg_server *, const char *uri, mg_handler_t);
Adds an URI handler. If Mongoose gets a request and request's URI starts
with
`uri`
, then specified handler is called to serve the request. Thus, an
`uri`
is a match prefix. For example, if
`uri`
is "/", then all requests will
be routed to the handler, because all URIs start with
`/`
character.
void mg_set_auth_handler(struct mg_server *, mg_handler_t handler);
Sets authorization handler. Called by Mongoose on each request, before
performing any other action. Handler can return either
`MG_AUTH_OK`
or
`MG_AUTH_FAIL`
. If
`handler`
returns
`MG_AUTH_FAIL`
, then Mongoose sends
digest authorization request to the client. If
`handler returns `
MG_AUTH_OK
`,
then mongoose proceeds with handling the request. Handler function can use
`
mg_authorize_digest()
` function to verify authorization, or implement any other
custom authorization mechanism.
void mg_set_request_handler(struct mg_server *, mg_handler_t handler);
Sets a request handler. When set, `
handler
` will be called for each request.
Possible return values from a handler function are `
MG_REQUEST_NOT_PROCESSED
`,
`
MG_REQUEST_PROCESSED
` and `
MG_REQUEST_CALL_AGAIN
`. If handler returns
`
MG_REQUEST_NOT_PROCESSED
`, mongoose will proceed with handling the request.
If handler returns `
MG_REQUEST_PROCESSED
`, that signals mongoose that handler
has already processed the connection, and mongoose will skip to the next
request. `
MG_REQUEST_CALL_AGAIN
` tells mongoose to call request handler
again and again on each `
mg_poll_server()
` iteration.
When mongoose buffers in HTTP request and successfully parses it, it calls
appropriate URI handler immediately for GET requests. For POST requests,
...
...
@@ -82,19 +96,16 @@ whether the request is websocket or not. Also, for websocket requests,
there is `
struct mg_connection::wsbits
` field which contains first byte
of the websocket frame which URI handler can examine. Note that to
reply to the websocket client, `
mg_websocket_write()
` should be used.
To reply to the plain HTTP client,
`mg_write_data()`
should be used.
An URI handler must return a value. If URI handler has sent all data,
it should return
`1`
. If URI handler returns
`0`
, that signals Mongoose
that URI handler hasn't finished sending data to the client. In this case,
Mongoose will call URI handler after each successful socket write.
`struct mg_connection::wsbits`
flag will indicate the status of the write,
`1`
means that write has failed and connection will be closed.
To reply to the plain HTTP client, `
mg_write_data()
` should be used. Note that
websocket handler must return either `
MG_CLIENT_CLOSE
` or `
MG_CLIENT_CONTINUE
`
value.
void mg_set_http_error_handler(struct mg_server *, mg_handler_t);
Adds HTTP error handler. An actual HTTP error is passed as
`struct mg_connection::status_code`
parameter. If handler returns 0, it
`
struct mg_connection::status_code
` parameter.
Hanlder should return either `
MG_ERROR_PROCESSED
` or `
MG_ERROR_NOT_PROCESSED
`.
If handler returns `
MG_ERROR_NOT_PROCESSED
`, it
means a handler has not processed the connection, and mongoose proceeds
with sending HTTP error to the client. Otherwise, mongoose does nothing.
...
...
examples/Makefile
View file @
14526a21
CFLAGS
=
-W
-Wall
-I
..
-pthread
-g
-pipe
$(C
OPT
)
CFLAGS
=
-W
-Wall
-I
..
-pthread
-g
-pipe
$(C
FLAGS_EXTRA
)
DLL_FLAGS
=
-DLUA_COMPAT_ALL
-I
../build
RM
=
rm
-rf
...
...
examples/auth.c
View file @
14526a21
...
...
@@ -3,7 +3,7 @@
#include "mongoose.h"
static
int
auth_handler
(
struct
mg_connection
*
conn
)
{
int
result
=
0
;
// Not authorized
int
result
=
MG_AUTH_FAIL
;
// Not authorized
FILE
*
fp
;
// To populate passwords file, do
...
...
examples/hello.c
View file @
14526a21
...
...
@@ -5,7 +5,7 @@
// This function will be called by mongoose on every new request
static
int
index_html
(
struct
mg_connection
*
conn
)
{
mg_printf_data
(
conn
,
"Hello! Requested URI is [%s]"
,
conn
->
uri
);
return
1
;
return
MG_REQUEST_PROCESSED
;
}
int
main
(
void
)
{
...
...
@@ -14,7 +14,7 @@ int main(void) {
// Create and configure the server
server
=
mg_create_server
(
NULL
);
mg_set_option
(
server
,
"listening_port"
,
"8080"
);
mg_
add_uri_handler
(
server
,
"/"
,
index_html
);
mg_
set_request_handler
(
server
,
index_html
);
// Serve request. Hit Ctrl-C to terminate the program
printf
(
"Starting on port %s
\n
"
,
mg_get_option
(
server
,
"listening_port"
));
...
...
examples/multi_threaded.c
View file @
14526a21
...
...
@@ -6,7 +6,7 @@ static int request_handler(struct mg_connection *conn) {
mg_send_header
(
conn
,
"Content-Type"
,
"text/plain"
);
mg_printf_data
(
conn
,
"This is a reply from server instance # %s"
,
(
char
*
)
conn
->
server_param
);
return
0
;
return
MG_REQUEST_PROCESSED
;
}
static
void
*
serve
(
void
*
server
)
{
...
...
@@ -20,8 +20,8 @@ int main(void) {
server1
=
mg_create_server
((
void
*
)
"1"
);
server2
=
mg_create_server
((
void
*
)
"2"
);
mg_
add_uri_handler
(
server1
,
"/"
,
request_handler
);
mg_
add_uri_handler
(
server2
,
"/"
,
request_handler
);
mg_
set_request_handler
(
server1
,
request_handler
);
mg_
set_request_handler
(
server2
,
request_handler
);
// Make both server1 and server2 listen on the same socket
mg_set_option
(
server1
,
"listening_port"
,
"8080"
);
...
...
examples/post.c
View file @
14526a21
...
...
@@ -34,13 +34,13 @@ static int handler(struct mg_connection *conn) {
mg_send_data
(
conn
,
html_form
,
strlen
(
html_form
));
}
return
1
;
return
MG_REQUEST_PROCESSED
;
}
int
main
(
void
)
{
struct
mg_server
*
server
=
mg_create_server
(
NULL
);
mg_set_option
(
server
,
"listening_port"
,
"8080"
);
mg_
add_uri_handler
(
server
,
"/"
,
handler
);
mg_
set_request_handler
(
server
,
handler
);
printf
(
"Starting on port %s
\n
"
,
mg_get_option
(
server
,
"listening_port"
));
for
(;;)
{
mg_poll_server
(
server
,
1000
);
...
...
examples/upload.c
View file @
14526a21
...
...
@@ -30,7 +30,7 @@ static int index_html(struct mg_connection *conn) {
mg_printf_data
(
conn
,
"%s"
,
"</body></html>"
);
return
1
;
return
MG_REQUEST_PROCESSED
;
}
int
main
(
void
)
{
...
...
@@ -39,7 +39,7 @@ int main(void) {
// Create and configure the server
server
=
mg_create_server
(
NULL
);
mg_set_option
(
server
,
"listening_port"
,
"8080"
);
mg_
add_uri_handler
(
server
,
"/"
,
index_html
);
mg_
set_request_handler
(
server
,
index_html
);
// Serve request. Hit Ctrl-C to terminate the program
printf
(
"Starting on port %s
\n
"
,
mg_get_option
(
server
,
"listening_port"
));
...
...
examples/websocket.c
View file @
14526a21
...
...
@@ -9,7 +9,7 @@ static int iterate_callback(struct mg_connection *c) {
int
len
=
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
*
(
int
*
)
c
->
connection_param
);
mg_websocket_write
(
c
,
1
,
buf
,
len
);
}
return
1
;
return
MG_REQUEST_PROCESSED
;
}
static
int
index_html
(
struct
mg_connection
*
conn
)
{
...
...
@@ -21,11 +21,12 @@ static int index_html(struct mg_connection *conn) {
// times for connection lifetime.
// Echo websocket data back to the client.
mg_websocket_write
(
conn
,
1
,
conn
->
content
,
conn
->
content_len
);
return
conn
->
content_len
==
4
&&
!
memcmp
(
conn
->
content
,
"exit"
,
4
);
return
conn
->
content_len
==
4
&&
!
memcmp
(
conn
->
content
,
"exit"
,
4
)
?
MG_CLIENT_CLOSE
:
MG_CLIENT_CONTINUE
;
}
else
{
mg_send_header
(
conn
,
"Content-Type"
,
"text/html"
);
mg_send_data
(
conn
,
index_html
,
index_size
);
return
1
;
return
MG_REQUEST_PROCESSED
;
}
}
...
...
@@ -34,12 +35,12 @@ int main(void) {
unsigned
int
current_timer
=
0
,
last_timer
=
0
;
mg_set_option
(
server
,
"listening_port"
,
"8080"
);
mg_
add_uri_handler
(
server
,
"/"
,
index_html
);
mg_
set_request_handler
(
server
,
index_html
);
printf
(
"Started on port %s
\n
"
,
mg_get_option
(
server
,
"listening_port"
));
for
(;;)
{
current_timer
=
mg_poll_server
(
server
,
100
);
if
(
current_timer
-
last_timer
>
1
)
{
if
(
current_timer
-
last_timer
>
0
)
{
last_timer
=
current_timer
;
mg_iterate_over_connections
(
server
,
iterate_callback
,
&
current_timer
);
}
...
...
examples/websocket.html
View file @
14526a21
...
...
@@ -24,10 +24,13 @@
out
(
'DISCONNECTED'
);
};
websocket
.
onmessage
=
function
(
ev
)
{
if
(
!
ev
.
data
)
return
;
// No data, this is a PING message, ignore it
if
(
!
ev
.
data
)
{
out
(
'<span style="color: blue;">PING... </span>'
);
}
else
{
out
(
'<span style="color: blue;">RESPONSE: '
+
ev
.
data
+
' </span>'
);
num_messages
++
;
if
(
num_messages
>
100
)
{
}
if
(
num_messages
>
15
)
{
websocket
.
send
(
'exit'
);
}
};
...
...
mongoose.c
View file @
14526a21
...
...
@@ -203,12 +203,6 @@ struct vec {
int
len
;
};
struct
uri_handler
{
struct
ll
link
;
char
*
uri
;
mg_handler_t
handler
;
};
// For directory listing and WevDAV support
struct
dir_entry
{
struct
connection
*
conn
;
...
...
@@ -275,7 +269,7 @@ struct mg_server {
sock_t
listening_sock
;
union
socket_address
lsa
;
// Listening socket address
struct
ll
active_connections
;
struct
ll
uri_handlers
;
mg_handler_t
request_handler
;
mg_handler_t
error_handler
;
mg_handler_t
auth_handler
;
char
*
config_options
[
NUM_OPTIONS
];
...
...
@@ -300,7 +294,6 @@ union endpoint {
int
fd
;
// Opened regular local file
sock_t
cgi_sock
;
// CGI socket
void
*
ssl
;
// SSL descriptor
struct
uri_handler
*
uh
;
// URI handler user function
};
enum
endpoint_type
{
EP_NONE
,
EP_FILE
,
EP_CGI
,
EP_USER
,
EP_PUT
,
EP_CLIENT
};
...
...
@@ -338,6 +331,7 @@ struct connection {
#endif
};
static
void
open_local_endpoint
(
struct
connection
*
conn
,
int
skip_user
);
static
void
close_local_endpoint
(
struct
connection
*
conn
);
static
const
struct
{
...
...
@@ -664,7 +658,7 @@ static void send_http_error(struct connection *conn, int code,
// Invoke error handler if it is set
if
(
conn
->
server
->
error_handler
!=
NULL
&&
conn
->
server
->
error_handler
(
&
conn
->
mg_conn
))
{
conn
->
server
->
error_handler
(
&
conn
->
mg_conn
)
==
MG_ERROR_PROCESSED
)
{
close_local_endpoint
(
conn
);
return
;
}
...
...
@@ -1861,7 +1855,7 @@ static int deliver_websocket_frame(struct connection *conn) {
}
// Call the handler and remove frame from the iobuf
if
(
conn
->
endpoint
.
uh
->
handler
(
&
conn
->
mg_conn
)
)
{
if
(
conn
->
server
->
request_handler
(
&
conn
->
mg_conn
)
==
MG_CLIENT_CLOSE
)
{
conn
->
flags
|=
CONN_SPOOL_DONE
;
}
discard_leading_iobuf_bytes
(
&
conn
->
local_iobuf
,
frame_len
);
...
...
@@ -1934,16 +1928,20 @@ static void write_terminating_chunk(struct connection *conn) {
mg_write
(
&
conn
->
mg_conn
,
"0
\r\n\r\n
"
,
5
);
}
static
void
call_uri_handler
(
struct
connection
*
conn
)
{
static
int
call_request_handler
(
struct
connection
*
conn
)
{
int
result
;
conn
->
mg_conn
.
content
=
conn
->
local_iobuf
.
buf
;
if
(
conn
->
endpoint
.
uh
->
handler
(
&
conn
->
mg_conn
))
{
switch
((
result
=
conn
->
server
->
request_handler
(
&
conn
->
mg_conn
)))
{
case
MG_REQUEST_CALL_AGAIN
:
conn
->
flags
|=
CONN_LONG_RUNNING
;
break
;
case
MG_REQUEST_NOT_PROCESSED
:
break
;
default:
if
(
conn
->
flags
&
CONN_HEADERS_SENT
)
{
write_terminating_chunk
(
conn
);
}
close_local_endpoint
(
conn
);
}
else
{
conn
->
flags
|=
CONN_LONG_RUNNING
;
break
;
}
return
result
;
}
static
void
callback_http_client_on_connect
(
struct
connection
*
conn
)
{
...
...
@@ -2021,19 +2019,6 @@ const char *mg_get_mime_type(const char *path, const char *default_mime_type) {
return
default_mime_type
;
}
static
struct
uri_handler
*
find_uri_handler
(
struct
mg_server
*
server
,
const
char
*
uri
)
{
struct
ll
*
lp
,
*
tmp
;
struct
uri_handler
*
uh
;
LINKED_LIST_FOREACH
(
&
server
->
uri_handlers
,
lp
,
tmp
)
{
uh
=
LINKED_LIST_ENTRY
(
lp
,
struct
uri_handler
,
link
);
if
(
!
strncmp
(
uh
->
uri
,
uri
,
strlen
(
uh
->
uri
)))
return
uh
;
}
return
NULL
;
}
#ifndef MONGOOSE_NO_FILESYSTEM
// Convert month to the month number. Return -1 on error, or month number
static
int
get_month_index
(
const
char
*
s
)
{
...
...
@@ -2247,7 +2232,7 @@ static void open_file_endpoint(struct connection *conn, const char *path,
#endif // MONGOOSE_NO_FILESYSTEM
static
void
call_
uri
_handler_if_data_is_buffered
(
struct
connection
*
conn
)
{
static
void
call_
request
_handler_if_data_is_buffered
(
struct
connection
*
conn
)
{
struct
iobuf
*
loc
=
&
conn
->
local_iobuf
;
struct
mg_connection
*
c
=
&
conn
->
mg_conn
;
...
...
@@ -2256,8 +2241,9 @@ static void call_uri_handler_if_data_is_buffered(struct connection *conn) {
do
{
}
while
(
deliver_websocket_frame
(
conn
));
}
else
#endif
if
((
size_t
)
loc
->
len
>=
c
->
content_len
)
{
call_uri_handler
(
conn
);
if
((
size_t
)
loc
->
len
>=
c
->
content_len
&&
call_request_handler
(
conn
)
==
MG_REQUEST_NOT_PROCESSED
)
{
open_local_endpoint
(
conn
,
1
);
}
}
...
...
@@ -2984,7 +2970,8 @@ static int check_password(const char *method, const char *ha1, const char *uri,
mg_md5
(
expected_response
,
ha1
,
":"
,
nonce
,
":"
,
nc
,
":"
,
cnonce
,
":"
,
qop
,
":"
,
ha2
,
NULL
);
return
mg_strcasecmp
(
response
,
expected_response
)
==
0
;
return
mg_strcasecmp
(
response
,
expected_response
)
==
0
?
MG_AUTH_OK
:
MG_AUTH_FAIL
;
}
...
...
@@ -3014,14 +3001,14 @@ int mg_authorize_digest(struct mg_connection *c, FILE *fp) {
return
check_password
(
c
->
request_method
,
ha1
,
uri
,
nonce
,
nc
,
cnonce
,
qop
,
resp
);
}
return
0
;
return
MG_AUTH_FAIL
;
}
// Return 1 if request is authorised, 0 otherwise.
static
int
is_authorized
(
struct
connection
*
conn
,
const
char
*
path
)
{
FILE
*
fp
;
int
authorized
=
1
;
int
authorized
=
MG_AUTH_OK
;
if
((
fp
=
open_auth_file
(
conn
,
path
))
!=
NULL
)
{
authorized
=
mg_authorize_digest
(
&
conn
->
mg_conn
,
fp
);
...
...
@@ -3034,7 +3021,7 @@ static int is_authorized(struct connection *conn, const char *path) {
static
int
is_authorized_for_dav
(
struct
connection
*
conn
)
{
const
char
*
auth_file
=
conn
->
server
->
config_options
[
DAV_AUTH_FILE
];
FILE
*
fp
;
int
authorized
=
0
;
int
authorized
=
MG_AUTH_FAIL
;
if
(
auth_file
!=
NULL
&&
(
fp
=
fopen
(
auth_file
,
"r"
))
!=
NULL
)
{
authorized
=
mg_authorize_digest
(
&
conn
->
mg_conn
,
fp
);
...
...
@@ -3359,7 +3346,7 @@ static void handle_lsp_request(struct connection *conn, const char *path,
}
#endif // MONGOOSE_USE_LUA
static
void
open_local_endpoint
(
struct
connection
*
conn
)
{
static
void
open_local_endpoint
(
struct
connection
*
conn
,
int
skip_user
)
{
#ifndef MONGOOSE_NO_FILESYSTEM
static
const
char
lua_pat
[]
=
LUA_SCRIPT_PATTERN
;
file_stat_t
st
;
...
...
@@ -3372,17 +3359,15 @@ static void open_local_endpoint(struct connection *conn) {
#ifndef MONGOOSE_NO_AUTH
// Call auth handler
if
(
conn
->
server
->
auth_handler
!=
NULL
&&
conn
->
server
->
auth_handler
(
&
conn
->
mg_conn
)
==
0
)
{
conn
->
server
->
auth_handler
(
&
conn
->
mg_conn
)
==
MG_AUTH_FAIL
)
{
mg_send_digest_auth_request
(
&
conn
->
mg_conn
);
return
;
}
#endif
// Call URI handler if one is registered for this URI
conn
->
endpoint
.
uh
=
find_uri_handler
(
conn
->
server
,
conn
->
mg_conn
.
uri
);
if
(
conn
->
endpoint
.
uh
!=
NULL
)
{
if
(
skip_user
==
0
&&
conn
->
server
->
request_handler
!=
NULL
)
{
conn
->
endpoint_type
=
EP_USER
;
conn
->
mg_conn
.
content
=
conn
->
local_iobuf
.
buf
;
#if MONGOOSE_USE_POST_SIZE_LIMIT > 1
{
const
char
*
cl
=
mg_get_header
(
&
conn
->
mg_conn
,
"Content-Length"
);
...
...
@@ -3525,7 +3510,7 @@ static void process_request(struct connection *conn) {
send_websocket_handshake_if_requested
(
&
conn
->
mg_conn
);
#endif
send_continue_if_expected
(
conn
);
open_local_endpoint
(
conn
);
open_local_endpoint
(
conn
,
0
);
}
#ifndef MONGOOSE_NO_CGI
...
...
@@ -3534,7 +3519,7 @@ static void process_request(struct connection *conn) {
}
#endif
if
(
conn
->
endpoint_type
==
EP_USER
)
{
call_
uri
_handler_if_data_is_buffered
(
conn
);
call_
request
_handler_if_data_is_buffered
(
conn
);
}
#ifndef MONGOOSE_NO_DAV
if
(
conn
->
endpoint_type
==
EP_PUT
&&
io
->
len
>
0
)
{
...
...
@@ -3859,7 +3844,9 @@ unsigned int mg_poll_server(struct mg_server *server, int milliseconds) {
}
if
(
conn
->
flags
&
CONN_LONG_RUNNING
)
{
conn
->
mg_conn
.
wsbits
=
conn
->
flags
&
CONN_CLOSE
?
1
:
0
;
call_uri_handler
(
conn
);
if
(
call_request_handler
(
conn
)
==
MG_REQUEST_PROCESSED
)
{
conn
->
flags
|=
CONN_CLOSE
;
}
}
if
(
conn
->
flags
&
CONN_CLOSE
||
conn
->
last_activity_time
<
expire_time
)
{
close_conn
(
conn
);
...
...
@@ -3883,10 +3870,6 @@ void mg_destroy_server(struct mg_server **server) {
LINKED_LIST_FOREACH
(
&
s
->
active_connections
,
lp
,
tmp
)
{
close_conn
(
LINKED_LIST_ENTRY
(
lp
,
struct
connection
,
link
));
}
LINKED_LIST_FOREACH
(
&
s
->
uri_handlers
,
lp
,
tmp
)
{
free
(
LINKED_LIST_ENTRY
(
lp
,
struct
uri_handler
,
link
)
->
uri
);
free
(
LINKED_LIST_ENTRY
(
lp
,
struct
uri_handler
,
link
));
}
for
(
i
=
0
;
i
<
(
int
)
ARRAY_SIZE
(
s
->
config_options
);
i
++
)
{
free
(
s
->
config_options
[
i
]);
// It is OK to free(NULL)
}
...
...
@@ -3909,16 +3892,6 @@ void mg_iterate_over_connections(struct mg_server *server, mg_handler_t handler,
send
(
server
->
ctl
[
0
],
(
void
*
)
msg
,
sizeof
(
msg
),
0
);
}
void
mg_add_uri_handler
(
struct
mg_server
*
server
,
const
char
*
uri
,
mg_handler_t
handler
)
{
struct
uri_handler
*
p
=
(
struct
uri_handler
*
)
malloc
(
sizeof
(
*
p
));
if
(
p
!=
NULL
)
{
LINKED_LIST_ADD_TO_TAIL
(
&
server
->
uri_handlers
,
&
p
->
link
);
p
->
uri
=
mg_strdup
(
uri
);
p
->
handler
=
handler
;
}
}
static
int
get_var
(
const
char
*
data
,
size_t
data_len
,
const
char
*
name
,
char
*
dst
,
size_t
dst_len
)
{
const
char
*
p
,
*
e
,
*
s
;
...
...
@@ -4145,6 +4118,9 @@ const char *mg_set_option(struct mg_server *server, const char *name,
return
error_msg
;
}
void
mg_set_request_handler
(
struct
mg_server
*
server
,
mg_handler_t
handler
)
{
server
->
request_handler
=
handler
;
}
void
mg_set_http_error_handler
(
struct
mg_server
*
server
,
mg_handler_t
handler
)
{
server
->
error_handler
=
handler
;
...
...
@@ -4184,7 +4160,6 @@ struct mg_server *mg_create_server(void *server_data) {
#endif
LINKED_LIST_INIT
(
&
server
->
active_connections
);
LINKED_LIST_INIT
(
&
server
->
uri_handlers
);
// Create control socket pair. Do it in a loop to protect from
// interrupted syscalls in mg_socketpair().
...
...
mongoose.h
View file @
14526a21
...
...
@@ -65,7 +65,7 @@ struct mg_server *mg_create_server(void *server_param);
void
mg_destroy_server
(
struct
mg_server
**
);
const
char
*
mg_set_option
(
struct
mg_server
*
,
const
char
*
opt
,
const
char
*
val
);
unsigned
int
mg_poll_server
(
struct
mg_server
*
,
int
milliseconds
);
void
mg_
add_uri_handler
(
struct
mg_server
*
,
const
char
*
uri
,
mg_handler_t
);
void
mg_
set_request_handler
(
struct
mg_server
*
,
mg_handler_t
);
void
mg_set_http_error_handler
(
struct
mg_server
*
,
mg_handler_t
);
void
mg_set_auth_handler
(
struct
mg_server
*
,
mg_handler_t
);
const
char
**
mg_get_valid_option_names
(
void
);
...
...
@@ -87,9 +87,8 @@ int mg_websocket_write(struct mg_connection *, int opcode,
int
mg_write
(
struct
mg_connection
*
,
const
void
*
buf
,
int
len
);
int
mg_printf
(
struct
mg_connection
*
conn
,
const
char
*
fmt
,
...);
const
char
*
mg_get_header
(
const
struct
mg_connection
*
,
const
char
*
name
);
const
char
*
mg_get_mime_type
(
const
char
*
file_
name
,
const
char
*
default_mime_type
);
const
char
*
mg_get_mime_type
(
const
char
*
name
,
const
char
*
default_mime_type
);
int
mg_get_var
(
const
struct
mg_connection
*
conn
,
const
char
*
var_name
,
char
*
buf
,
size_t
buf_len
);
int
mg_parse_header
(
const
char
*
hdr
,
const
char
*
var_name
,
char
*
buf
,
size_t
);
...
...
@@ -102,10 +101,12 @@ int mg_parse_multipart(const char *buf, int buf_len,
void
*
mg_start_thread
(
void
*
(
*
func
)(
void
*
),
void
*
param
);
char
*
mg_md5
(
char
buf
[
33
],
...);
int
mg_authorize_digest
(
struct
mg_connection
*
c
,
FILE
*
fp
);
void
mg_send_digest_auth_request
(
struct
mg_connection
*
conn
);
// Callback return codes
enum
{
MG_REPLY_TO_BE_CONTINUED
,
MG_REPLY_COMPLETED
};
// Callback function return codes
enum
{
MG_REQUEST_NOT_PROCESSED
,
MG_REQUEST_PROCESSED
,
MG_REQUEST_CALL_AGAIN
};
enum
{
MG_AUTH_FAIL
,
MG_AUTH_OK
};
enum
{
MG_ERROR_NOT_PROCESSED
,
MG_ERROR_PROCESSED
};
enum
{
MG_CLIENT_CONTINUE
,
MG_CLIENT_CLOSE
};
// HTTP client events
enum
{
...
...
unit_test.c
View file @
14526a21
...
...
@@ -364,39 +364,41 @@ static const char *test_next_option(void) {
}
static
int
cb1
(
struct
mg_connection
*
conn
)
{
// We're not sending HTTP headers here, to make testing easier
//mg_printf(conn, "HTTP/1.0 200 OK\r\n\r\n%s %s %s",
int
result
=
MG_REQUEST_NOT_PROCESSED
;
if
(
!
strcmp
(
conn
->
uri
,
"/cb1"
))
{
mg_printf
(
conn
,
"%s %s %s"
,
conn
->
server_param
==
NULL
?
"?"
:
(
char
*
)
conn
->
server_param
,
conn
->
connection_param
==
NULL
?
"?"
:
"!"
,
conn
->
remote_ip
);
return
1
;
result
=
MG_REQUEST_PROCESSED
;
}
return
result
;
}
static
int
error_handler
(
struct
mg_connection
*
conn
)
{
mg_printf
(
conn
,
"HTTP/1.0 404 NF
\r\n\r\n
ERR: %d"
,
conn
->
status_code
);
return
1
;
return
MG_ERROR_PROCESSED
;
}
static
int
ts1
(
struct
mg_connection
*
conn
)
{
if
(
conn
->
status_code
==
MG_CONNECT_SUCCESS
)
{
mg_printf
(
conn
,
"%s"
,
"GET /cb1 HTTP/1.0
\r\n\r\n
"
);
return
0
;
return
MG_CLIENT_CONTINUE
;
}
else
if
(
conn
->
status_code
==
MG_DOWNLOAD_SUCCESS
)
{
sprintf
((
char
*
)
conn
->
connection_param
,
"%.*s"
,
(
int
)
conn
->
content_len
,
conn
->
content
);
}
return
1
;
return
MG_CLIENT_CLOSE
;
}
static
int
ts2
(
struct
mg_connection
*
conn
)
{
if
(
conn
->
status_code
==
MG_CONNECT_SUCCESS
)
{
mg_printf
(
conn
,
"%s"
,
"GET /non_exist HTTP/1.0
\r\n\r\n
"
);
return
0
;
return
MG_CLIENT_CONTINUE
;
}
else
if
(
conn
->
status_code
==
MG_DOWNLOAD_SUCCESS
)
{
sprintf
((
char
*
)
conn
->
connection_param
,
"%s %.*s"
,
conn
->
uri
,
(
int
)
conn
->
content_len
,
conn
->
content
);
}
return
1
;
return
MG_CLIENT_CLOSE
;
}
static
const
char
*
test_server
(
void
)
{
...
...
@@ -406,7 +408,7 @@ static const char *test_server(void) {
ASSERT
(
server
!=
NULL
);
ASSERT
(
mg_set_option
(
server
,
"listening_port"
,
LISTENING_ADDR
)
==
NULL
);
ASSERT
(
mg_set_option
(
server
,
"document_root"
,
"."
)
==
NULL
);
mg_
add_uri_handler
(
server
,
"/cb1"
,
cb1
);
mg_
set_request_handler
(
server
,
cb1
);
mg_set_http_error_handler
(
server
,
error_handler
);
ASSERT
(
mg_connect
(
server
,
"127.0.0.1"
,
atoi
(
HTTP_PORT
),
0
,
ts1
,
buf1
)
==
1
);
...
...
@@ -460,25 +462,28 @@ static int cb2(struct mg_connection *conn) {
}
static
int
cb4h
(
struct
mg_connection
*
conn
)
{
int
result
=
MG_REQUEST_NOT_PROCESSED
;
if
(
!
strcmp
(
conn
->
uri
,
"/x"
))
{
mg_send_data
(
conn
,
":-)"
,
3
);
return
MG_REPLY_COMPLETED
;
result
=
MG_REQUEST_PROCESSED
;
}
return
result
;
}
static
int
cb4
(
struct
mg_connection
*
conn
)
{
if
(
conn
->
status_code
==
MG_CONNECT_SUCCESS
)
{
mg_printf
(
conn
,
"%s"
,
"POST /x HTTP/1.0
\r\n
Content-Length: 999999
\r\n\r\n
"
);
return
MG_
REPLY_TO_BE_CONTINUED
;
return
MG_
CLIENT_CONTINUE
;
}
else
{
sprintf
((
char
*
)
conn
->
connection_param
,
"%.*s"
,
(
int
)
conn
->
content_len
,
conn
->
content
);
}
return
MG_
REPLY_COMPLETED
;
return
MG_
CLIENT_CLOSE
;
}
static
int
cb3
(
struct
mg_connection
*
conn
)
{
fflush
(
stdout
);
sprintf
((
char
*
)
conn
->
connection_param
,
"%d"
,
conn
->
status_code
);
return
1
;
return
MG_CLIENT_CLOSE
;
}
static
const
char
*
test_mg_connect
(
void
)
{
...
...
@@ -487,7 +492,7 @@ static const char *test_mg_connect(void) {
ASSERT
(
mg_set_option
(
server
,
"listening_port"
,
LISTENING_ADDR
)
==
NULL
);
ASSERT
(
mg_set_option
(
server
,
"document_root"
,
"."
)
==
NULL
);
mg_
add_uri_handler
(
server
,
"/x"
,
cb4h
);
mg_
set_request_handler
(
server
,
cb4h
);
ASSERT
(
mg_connect
(
server
,
""
,
0
,
0
,
NULL
,
NULL
)
==
0
);
ASSERT
(
mg_connect
(
server
,
"127.0.0.1"
,
atoi
(
HTTP_PORT
),
0
,
cb2
,
buf2
)
==
1
);
ASSERT
(
mg_connect
(
server
,
"127.0.0.1"
,
29
,
0
,
cb3
,
buf3
)
==
1
);
...
...
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