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
31c20ab3
Commit
31c20ab3
authored
Mar 14, 2016
by
Alexander Alashkin
Committed by
Marko Mikulicic
Mar 14, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace m-part&endpoints mbufs with plain structs
PUBLISHED_FROM=b30cf26077b7c6374f0d588e5ef5ba504f979bb3
parent
69215cf9
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
92 additions
and
128 deletions
+92
-128
mongoose.c
mongoose.c
+92
-128
No files found.
mongoose.c
View file @
31c20ab3
...
...
@@ -4204,6 +4204,19 @@ struct mg_http_proto_data_chuncked {
int64_t
body_len
;
/* How many bytes of chunked body was reassembled. */
};
struct
mg_http_endpoint
{
struct
mg_http_endpoint
*
next
;
const
char
*
name
;
size_t
name_len
;
mg_event_handler_t
handler
;
};
struct
mg_http_multipart_stream
{
const
char
*
boundary
;
const
char
*
var_name
;
const
char
*
file_name
;
};
struct
mg_http_proto_data
{
#ifndef MG_DISABLE_FILESYSTEM
struct
mg_http_proto_data_file
file
;
...
...
@@ -4212,10 +4225,10 @@ struct mg_http_proto_data {
struct
mg_http_proto_data_cgi
cgi
;
#endif
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
struct
m
buf
strm_state
;
/* Used by multi-part streaming */
struct
m
g_http_multipart_stream
mp_stream
;
#endif
struct
mg_http_proto_data_chuncked
chunk
;
struct
m
buf
endpoints
;
/* Used by mg_register_http_endpoint */
struct
m
g_http_endpoint
*
endpoints
;
mg_event_handler_t
endpoint_handler
;
};
...
...
@@ -4231,6 +4244,18 @@ static struct mg_http_proto_data *mg_http_get_proto_data(
return
(
struct
mg_http_proto_data
*
)
c
->
proto_data
;
}
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
static
void
mg_http_free_proto_data_mp_stream
(
struct
mg_http_multipart_stream
*
mp
)
{
free
((
void
*
)
mp
->
boundary
);
mp
->
boundary
=
NULL
;
free
((
void
*
)
mp
->
var_name
);
mp
->
var_name
=
NULL
;
free
((
void
*
)
mp
->
file_name
);
mp
->
file_name
=
NULL
;
}
#endif
#ifndef MG_DISABLE_FILESYSTEM
static
void
mg_http_free_proto_data_file
(
struct
mg_http_proto_data_file
*
d
)
{
if
(
d
!=
NULL
)
{
...
...
@@ -4251,6 +4276,19 @@ static void mg_http_free_proto_data_cgi(struct mg_http_proto_data_cgi *d) {
}
#endif
static
void
mg_http_free_proto_data_endpoints
(
struct
mg_http_endpoint
**
ep
)
{
struct
mg_http_endpoint
*
current
=
*
ep
;
while
(
current
!=
NULL
)
{
struct
mg_http_endpoint
*
tmp
=
current
->
next
;
free
((
void
*
)
current
->
name
);
free
(
current
);
current
=
tmp
;
}
ep
=
NULL
;
}
static
void
mg_http_conn_destructor
(
void
*
proto_data
)
{
struct
mg_http_proto_data
*
pd
=
(
struct
mg_http_proto_data
*
)
proto_data
;
#ifndef MG_DISABLE_FILESYSTEM
...
...
@@ -4260,9 +4298,9 @@ static void mg_http_conn_destructor(void *proto_data) {
mg_http_free_proto_data_cgi
(
&
pd
->
cgi
);
#endif
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
m
buf_free
(
&
pd
->
strm_state
);
m
g_http_free_proto_data_mp_stream
(
&
pd
->
mp_stream
);
#endif
m
buf_free
(
&
pd
->
endpoints
);
m
g_http_free_proto_data_endpoints
(
&
pd
->
endpoints
);
free
(
proto_data
);
}
...
...
@@ -4948,9 +4986,9 @@ MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
static
mg_event_handler_t
mg_http_get_endpoint_handler
(
struct
mg_connection
*
nc
,
struct
mg_str
*
uri_path
)
{
struct
mg_http_proto_data
*
pd
;
size_t
pos
=
0
;
mg_event_handler_t
ret
=
NULL
;
int
matched
,
matched_max
=
0
;
struct
mg_http_endpoint
*
ep
;
if
(
nc
==
NULL
)
{
return
NULL
;
...
...
@@ -4958,81 +4996,23 @@ static mg_event_handler_t mg_http_get_endpoint_handler(
pd
=
mg_http_get_proto_data
(
nc
);
while
(
pos
<
pd
->
endpoints
.
len
)
{
size_t
name_len
;
memcpy
(
&
name_len
,
pd
->
endpoints
.
buf
+
pos
,
sizeof
(
name_len
));
if
((
matched
=
mg_match_prefix_n
(
pd
->
endpoints
.
buf
+
pos
+
sizeof
(
size_t
),
name_len
,
uri_path
->
p
,
uri_path
->
len
))
!=
-
1
)
{
ep
=
pd
->
endpoints
;
while
(
ep
!=
NULL
)
{
if
((
matched
=
mg_match_prefix_n
(
ep
->
name
,
ep
->
name_len
,
uri_path
->
p
,
uri_path
->
len
))
!=
-
1
)
{
if
(
matched
>
matched_max
)
{
/* Looking for the longest suitable handler */
memcpy
(
&
ret
,
pd
->
endpoints
.
buf
+
pos
+
sizeof
(
name_len
)
+
(
name_len
+
1
),
sizeof
(
ret
));
ret
=
ep
->
handler
;
matched_max
=
matched
;
}
}
pos
+=
sizeof
(
name_len
)
+
(
name_len
+
1
)
+
sizeof
(
ret
)
;
ep
=
ep
->
next
;
}
return
ret
;
}
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
struct
mg_http_stream_info
{
struct
mg_str
endpoint
;
struct
mg_str
boundary
;
struct
mg_str
var_name
;
struct
mg_str
file_name
;
};
/*
* Save/restore state into buf is convinient due to lack of
* protocol/connection parameters in mongoose
* once mongoose will have way to store connection/protocol
* related data these function can be replaced with usual structs
* TODO(alashkin): replace once those way will be implemented
*/
static
void
mg_http_parse_stream_info
(
struct
mbuf
*
buf
,
struct
mg_http_stream_info
*
si
)
{
const
char
*
ptr
=
buf
->
buf
;
memcpy
(
&
si
->
endpoint
.
len
,
ptr
,
sizeof
(
si
->
endpoint
.
len
));
ptr
+=
sizeof
(
si
->
endpoint
.
len
);
si
->
endpoint
.
p
=
ptr
;
ptr
+=
si
->
endpoint
.
len
;
memcpy
(
&
si
->
boundary
.
len
,
ptr
,
sizeof
(
si
->
boundary
.
len
));
ptr
+=
sizeof
(
si
->
boundary
.
len
);
si
->
boundary
.
p
=
ptr
;
ptr
+=
si
->
boundary
.
len
+
1
;
/* Explicitly zero-terminated */
memcpy
(
&
si
->
var_name
.
len
,
ptr
,
sizeof
(
si
->
var_name
.
len
));
ptr
+=
sizeof
(
si
->
var_name
.
len
);
si
->
var_name
.
p
=
ptr
;
ptr
+=
si
->
var_name
.
len
+
1
;
memcpy
(
&
si
->
file_name
.
len
,
ptr
,
sizeof
(
si
->
file_name
.
len
));
ptr
+=
sizeof
(
si
->
file_name
.
len
);
si
->
file_name
.
p
=
ptr
;
ptr
+=
si
->
file_name
.
len
+
1
;
}
static
void
mg_http_store_stream_info
(
struct
mbuf
*
buf
,
struct
mg_http_stream_info
*
si
)
{
char
zero
=
0
;
mbuf_remove
(
buf
,
buf
->
len
);
mbuf_append
(
buf
,
&
si
->
endpoint
.
len
,
sizeof
(
si
->
endpoint
.
len
));
mbuf_append
(
buf
,
si
->
endpoint
.
p
,
si
->
endpoint
.
len
);
mbuf_append
(
buf
,
&
si
->
boundary
.
len
,
sizeof
(
si
->
boundary
.
len
));
mbuf_append
(
buf
,
si
->
boundary
.
p
,
si
->
boundary
.
len
);
mbuf_append
(
buf
,
&
zero
,
1
);
/* Make boundary zero terminated */
mbuf_append
(
buf
,
&
si
->
var_name
.
len
,
sizeof
(
si
->
var_name
.
len
));
mbuf_append
(
buf
,
si
->
var_name
.
p
,
si
->
var_name
.
len
);
mbuf_append
(
buf
,
&
zero
,
1
);
mbuf_append
(
buf
,
&
si
->
file_name
.
len
,
sizeof
(
si
->
file_name
.
len
));
mbuf_append
(
buf
,
si
->
file_name
.
p
,
si
->
file_name
.
len
);
mbuf_append
(
buf
,
&
zero
,
1
);
}
#endif
/* MG_ENABLE_HTTP_STREAMING_MULTIPART */
static
void
mg_http_call_endpoint_handler
(
struct
mg_connection
*
nc
,
int
ev
,
struct
http_message
*
hm
)
{
struct
mg_http_proto_data
*
pd
=
mg_http_get_proto_data
(
nc
);
...
...
@@ -5087,23 +5067,17 @@ void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data) {
#endif
if
(
ev
==
MG_EV_CLOSE
)
{
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
if
(
pd
->
strm_state
.
len
!=
0
)
{
if
(
pd
->
mp_stream
.
boundary
!=
NULL
)
{
/*
* Multipart message is in progress, but we get close
* MG_EV_HTTP_PART_END with error flag
*/
struct
mg_http_stream_info
si
;
struct
mg_http_multipart_part
mp
;
mg_event_handler_t
handler
;
memset
(
&
mp
,
0
,
sizeof
(
mp
));
mg_http_parse_stream_info
(
&
pd
->
strm_state
,
&
si
);
handler
=
mg_http_get_endpoint_handler
(
nc
->
listener
,
&
si
.
endpoint
);
mp
.
status
=
-
1
;
mp
.
var_name
=
si
.
var_name
.
p
;
mp
.
file_name
=
si
.
file_name
.
p
;
mg_call
(
nc
,
(
handler
?
handler
:
nc
->
handler
),
MG_EV_HTTP_PART_END
,
&
mp
);
mp
.
var_name
=
pd
->
mp_stream
.
var_name
;
mp
.
file_name
=
pd
->
mp_stream
.
file_name
;
mg_call
(
nc
,
(
pd
->
endpoint_handler
?
pd
->
endpoint_handler
:
nc
->
handler
),
MG_EV_HTTP_PART_END
,
&
mp
);
}
else
#endif
if
(
io
->
len
>
0
&&
mg_parse_http
(
io
->
buf
,
io
->
len
,
hm
,
is_req
)
>
0
)
{
...
...
@@ -5130,7 +5104,7 @@ void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data) {
struct
mg_str
*
s
;
#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
if
(
pd
->
strm_state
.
len
!=
0
)
{
if
(
pd
->
mp_stream
.
boundary
!=
NULL
)
{
mg_http_multipart_continue
(
nc
,
io
,
ev
,
ev_data
);
return
;
}
...
...
@@ -5250,8 +5224,6 @@ static void mg_http_multipart_begin(struct mg_connection *nc,
const
char
multipart
[]
=
"multipart"
;
char
boundary
[
100
];
int
boundary_len
;
struct
mg_http_stream_info
si
;
mg_event_handler_t
handler
;
if
(
nc
->
listener
==
NULL
)
{
/* No streaming for replies now */
...
...
@@ -5285,24 +5257,22 @@ static void mg_http_multipart_begin(struct mg_connection *nc,
/* If we reach this place - that is multipart request */
if
(
pd
->
strm_state
.
len
!=
0
)
{
if
(
pd
->
mp_stream
.
boundary
!=
NULL
)
{
/*
* Another streaming request was in progress,
* looks like protocol error
*/
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
mbuf_free
(
&
pd
->
strm_state
);
}
else
{
si
.
endpoint
=
hm
->
uri
;
si
.
boundary
.
p
=
boundary
;
si
.
boundary
.
len
=
boundary_len
;
si
.
var_name
.
p
=
si
.
file_name
.
p
=
NULL
;
si
.
var_name
.
len
=
si
.
file_name
.
len
=
0
;
pd
->
mp_stream
.
boundary
=
strdup
(
boundary
);
pd
->
mp_stream
.
var_name
=
pd
->
mp_stream
.
file_name
=
NULL
;
mg_http_store_stream_info
(
&
pd
->
strm_state
,
&
si
);
handler
=
mg_http_get_endpoint_handler
(
nc
->
listener
,
&
si
.
endpoint
);
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_MULTIPART_REQUEST
,
hm
);
pd
->
endpoint_handler
=
mg_http_get_endpoint_handler
(
nc
->
listener
,
&
hm
->
uri
);
if
(
pd
->
endpoint_handler
==
NULL
)
{
pd
->
endpoint_handler
=
nc
->
handler
;
}
mg_call
(
nc
,
pd
->
endpoint_handler
,
MG_EV_HTTP_MULTIPART_REQUEST
,
hm
);
mbuf_remove
(
io
,
req_len
);
}
...
...
@@ -5313,32 +5283,27 @@ exit_mp:
static
void
mg_http_multipart_continue
(
struct
mg_connection
*
nc
,
struct
mbuf
*
io
,
int
ev
,
void
*
ev_data
)
{
/* Continue to stream multipart */
struct
mg_http_stream_info
si
;
mg_event_handler_t
handler
;
struct
mg_http_multipart_part
mp
;
const
char
*
boundary
;
int
req_len
;
struct
mg_http_proto_data
*
pd
=
mg_http_get_proto_data
(
nc
);
mg_http_parse_stream_info
(
&
pd
->
strm_state
,
&
si
);
handler
=
mg_http_get_endpoint_handler
(
nc
->
listener
,
&
si
.
endpoint
);
memset
(
&
mp
,
0
,
sizeof
(
mp
));
mp
.
var_name
=
si
.
var_name
.
p
;
mp
.
file_name
=
si
.
file_name
.
p
;
boundary
=
c_strnstr
(
io
->
buf
,
si
.
boundary
.
p
,
io
->
len
);
mp
.
var_name
=
pd
->
mp_stream
.
var_name
;
mp
.
file_name
=
pd
->
mp_stream
.
file_name
;
boundary
=
c_strnstr
(
io
->
buf
,
pd
->
mp_stream
.
boundary
,
io
->
len
);
if
(
boundary
==
NULL
)
{
mp
.
data
.
p
=
io
->
buf
;
mp
.
data
.
len
=
io
->
len
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mbuf_remove
(
io
,
io
->
len
);
}
else
{
int
has_prefix
=
0
,
has_suffix
=
0
;
int
has_prefix
=
0
,
has_suffix
=
0
,
boundary_len
=
strlen
(
pd
->
mp_stream
.
boundary
);
if
(
boundary
-
2
>=
io
->
buf
)
{
has_prefix
=
(
strncmp
(
boundary
-
2
,
"--"
,
2
)
==
0
);
}
if
(
boundary
+
si
.
boundary
.
len
<=
io
->
buf
+
io
->
len
)
{
has_suffix
=
(
strncmp
(
boundary
+
si
.
boundary
.
len
,
"--"
,
2
)
==
0
);
if
(
boundary
+
boundary_
len
<=
io
->
buf
+
io
->
len
)
{
has_suffix
=
(
strncmp
(
boundary
+
boundary_
len
,
"--"
,
2
)
==
0
);
}
if
(
has_prefix
&&
!
has_suffix
)
{
/* No suffix - not last boundary */
...
...
@@ -5350,9 +5315,9 @@ static void mg_http_multipart_continue(struct mg_connection *nc,
if
(
num_left
>
2
)
{
/* \r\n */
mp
.
data
.
p
=
io
->
buf
;
mp
.
data
.
len
=
num_left
-
2
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mp
.
data
.
len
=
0
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_
handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
mbuf_remove
(
io
,
num_left
);
}
...
...
@@ -5362,18 +5327,16 @@ static void mg_http_multipart_continue(struct mg_connection *nc,
mp
.
file_name
=
filename
;
if
((
req_len
=
mg_http_get_request_len
(
io
->
buf
,
io
->
len
))
>
0
)
{
const
char
*
tmp
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_BEGIN
,
&
mp
);
si
.
var_name
.
p
=
mp
.
var_name
;
si
.
var_name
.
len
=
strlen
(
mp
.
var_name
);
si
.
file_name
.
p
=
mp
.
file_name
;
si
.
file_name
.
len
=
strlen
(
mp
.
file_name
);
mg_http_store_stream_info
(
&
pd
->
strm_state
,
&
si
);
mg_call
(
nc
,
pd
->
endpoint_handler
,
MG_EV_HTTP_PART_BEGIN
,
&
mp
);
free
((
void
*
)
pd
->
mp_stream
.
var_name
);
pd
->
mp_stream
.
var_name
=
strdup
(
mp
.
var_name
);
free
((
void
*
)
pd
->
mp_stream
.
file_name
);
pd
->
mp_stream
.
file_name
=
strdup
(
mp
.
file_name
);
mbuf_remove
(
io
,
req_len
);
mp
.
data
.
p
=
io
->
buf
;
tmp
=
c_strnstr
(
io
->
buf
,
si
.
boundary
.
p
,
io
->
len
);
tmp
=
c_strnstr
(
io
->
buf
,
pd
->
mp_stream
.
boundary
,
io
->
len
);
if
(
tmp
==
NULL
)
{
mp
.
data
.
len
=
io
->
len
;
}
else
{
...
...
@@ -5382,12 +5345,10 @@ static void mg_http_multipart_continue(struct mg_connection *nc,
if
(
mp
.
data
.
len
!=
0
)
{
size_t
data_len
=
mp
.
data
.
len
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
if
(
data_len
!=
io
->
len
)
{
mp
.
data
.
len
=
0
;
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
}
mbuf_remove
(
io
,
data_len
);
}
...
...
@@ -5401,14 +5362,14 @@ static void mg_http_multipart_continue(struct mg_connection *nc,
mp
.
data
.
p
=
io
->
buf
;
mp
.
data
.
len
=
boundary
-
io
->
buf
-
4
;
if
(
mp
.
data
.
len
!=
0
)
{
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_
handler
,
MG_EV_HTTP_PART_DATA
,
&
mp
);
}
mg_call
(
nc
,
handler
?
handler
:
nc
->
handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
mg_call
(
nc
,
pd
->
endpoint_
handler
,
MG_EV_HTTP_PART_END
,
&
mp
);
/* Skip epilogue (if any) */
mbuf_remove
(
io
,
io
->
len
);
m
buf_free
(
&
pd
->
strm_state
);
m
g_http_free_proto_data_mp_stream
(
&
pd
->
mp_stream
);
}
else
{
/* Malformed request */
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
...
...
@@ -7610,10 +7571,13 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
void
mg_register_http_endpoint
(
struct
mg_connection
*
nc
,
const
char
*
uri_path
,
mg_event_handler_t
handler
)
{
struct
mg_http_proto_data
*
pd
=
mg_http_get_proto_data
(
nc
);
size_t
len
=
strlen
(
uri_path
);
mbuf_append
(
&
pd
->
endpoints
,
&
len
,
sizeof
(
len
));
mbuf_append
(
&
pd
->
endpoints
,
uri_path
,
len
+
1
);
mbuf_append
(
&
pd
->
endpoints
,
&
handler
,
sizeof
(
handler
));
struct
mg_http_endpoint
*
new_ep
=
(
struct
mg_http_endpoint
*
)
calloc
(
1
,
sizeof
(
*
new_ep
));
new_ep
->
name
=
strdup
(
uri_path
);
new_ep
->
name_len
=
strlen
(
new_ep
->
name
);
new_ep
->
handler
=
handler
;
new_ep
->
next
=
pd
->
endpoints
;
pd
->
endpoints
=
new_ep
;
}
#endif
/* MG_DISABLE_HTTP */
...
...
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