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
31c20ab3
Commit
31c20ab3
authored
9 years ago
by
Alexander Alashkin
Committed by
Marko Mikulicic
9 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace m-part&endpoints mbufs with plain structs
PUBLISHED_FROM=b30cf26077b7c6374f0d588e5ef5ba504f979bb3
parent
69215cf9
Changes
1
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 */
...
...
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