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
5d217a12
Commit
5d217a12
authored
Jun 11, 2020
by
Sergey Lyubka
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of github.com:cesanta/mongoose into dev
parents
80d74e9e
f778d22e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
100 additions
and
46 deletions
+100
-46
struct_http_message.md
docs/c-api/mg_http.h/struct_http_message.md
+6
-0
mongoose.c
mongoose.c
+0
-0
mongoose.h
mongoose.h
+8
-0
mg_common.h
src/mg_common.h
+1
-1
mg_http.c
src/mg_http.c
+68
-39
mg_http.h
src/mg_http.h
+8
-0
mg_http_ssi.c
src/mg_http_ssi.c
+4
-2
mg_net.c
src/mg_net.c
+1
-1
mg_ssl_if_openssl.c
src/mg_ssl_if_openssl.c
+4
-3
unit_test.c
test/unit_test.c
+0
-0
No files found.
docs/c-api/mg_http.h/struct_http_message.md
View file @
5d217a12
...
...
@@ -29,6 +29,12 @@ signature: |
/* Headers */
struct mg_str header_names[MG_MAX_HTTP_HEADERS];
struct mg_str header_values[MG_MAX_HTTP_HEADERS];
/*
* Value of the Content-Length header if present,
* otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN.
*/
size_t content_length;
};
---
...
...
mongoose.c
View file @
5d217a12
This diff is collapsed.
Click to expand it.
mongoose.h
View file @
5d217a12
...
...
@@ -4420,8 +4420,16 @@ struct http_message {
/* Headers */
struct
mg_str
header_names
[
MG_MAX_HTTP_HEADERS
];
struct
mg_str
header_values
[
MG_MAX_HTTP_HEADERS
];
/*
* Value of the Content-Length header if present,
* otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN.
*/
size_t
content_length
;
};
#define MG_HTTP_CONTENT_LENGTH_UNKNOWN ((size_t) -1)
#if MG_ENABLE_HTTP_WEBSOCKET
/* WebSocket message */
struct
websocket_message
{
...
...
src/mg_common.h
View file @
5d217a12
#ifndef CS_MONGOOSE_SRC_COMMON_H_
#define CS_MONGOOSE_SRC_COMMON_H_
#define MG_VERSION "6.1
7
"
#define MG_VERSION "6.1
8
"
/* Local tweaks, applied before any of Mongoose's own headers. */
#ifdef MG_LOCALS
...
...
src/mg_http.c
View file @
5d217a12
...
...
@@ -174,7 +174,10 @@ struct mg_http_proto_data {
struct
mg_http_endpoint
*
endpoints
;
mg_event_handler_t
endpoint_handler
;
struct
mg_reverse_proxy_data
reverse_proxy_data
;
size_t
rcvd
;
/* How many bytes we have received. */
size_t
rcvd
;
/* How many bytes we have received. */
size_t
body_rcvd
;
/* How many bytes of body we have received. */
size_t
body_processed
;
/* How many bytes of body we have processed. */
int
finished
;
};
static
void
mg_http_proto_data_destructor
(
void
*
proto_data
);
...
...
@@ -405,6 +408,7 @@ static int mg_http_get_request_len(const char *s, int buf_len) {
static
const
char
*
mg_http_parse_headers
(
const
char
*
s
,
const
char
*
end
,
int
len
,
struct
http_message
*
req
)
{
int
i
=
0
;
req
->
content_length
=
MG_HTTP_CONTENT_LENGTH_UNKNOWN
;
while
(
i
<
(
int
)
ARRAY_SIZE
(
req
->
header_names
)
-
1
)
{
struct
mg_str
*
k
=
&
req
->
header_names
[
i
],
*
v
=
&
req
->
header_values
[
i
];
...
...
@@ -430,9 +434,10 @@ static const char *mg_http_parse_headers(const char *s, const char *end,
break
;
}
if
(
!
mg_ncasecmp
(
k
->
p
,
"Content-Length"
,
14
)
)
{
if
(
mg_ncasecmp
(
k
->
p
,
"Content-Length"
,
14
)
==
0
)
{
req
->
body
.
len
=
(
size_t
)
to64
(
v
->
p
);
req
->
message
.
len
=
len
+
req
->
body
.
len
;
req
->
content_length
=
req
->
body
.
len
;
}
i
++
;
...
...
@@ -548,6 +553,7 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) {
pd
->
file
.
keepalive
));
if
(
!
pd
->
file
.
keepalive
)
nc
->
flags
|=
MG_F_SEND_AND_CLOSE
;
mg_http_free_proto_data_file
(
&
pd
->
file
);
pd
->
finished
=
1
;
}
}
else
if
(
pd
->
file
.
type
==
DATA_PUT
)
{
struct
mbuf
*
io
=
&
nc
->
recv_mbuf
;
...
...
@@ -560,6 +566,7 @@ static void mg_http_transfer_file_data(struct mg_connection *nc) {
if
(
n
==
0
||
pd
->
file
.
sent
>=
pd
->
file
.
cl
)
{
if
(
!
pd
->
file
.
keepalive
)
nc
->
flags
|=
MG_F_SEND_AND_CLOSE
;
mg_http_free_proto_data_file
(
&
pd
->
file
);
pd
->
finished
=
1
;
}
}
#if MG_ENABLE_HTTP_CGI
...
...
@@ -715,13 +722,26 @@ static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev,
struct
http_message
*
hm
);
static
void
deliver_chunk
(
struct
mg_connection
*
c
,
struct
http_message
*
hm
,
int
req_len
)
{
struct
mg_http_proto_data
*
pd
,
int
req_len
)
{
/* Incomplete message received. Send MG_EV_HTTP_CHUNK event */
hm
->
body
.
len
=
c
->
recv_mbuf
.
len
-
req_len
;
if
(
hm
->
content_length
!=
MG_HTTP_CONTENT_LENGTH_UNKNOWN
)
{
size_t
body_remain
=
hm
->
content_length
-
pd
->
body_processed
;
if
(
hm
->
body
.
len
>
body_remain
)
{
hm
->
body
.
len
=
body_remain
;
}
}
if
(
pd
!=
NULL
)
{
pd
->
body_rcvd
=
pd
->
body_processed
+
hm
->
body
.
len
;
}
c
->
flags
&=
~
MG_F_DELETE_CHUNK
;
mg_call
(
c
,
c
->
handler
,
c
->
user_data
,
MG_EV_HTTP_CHUNK
,
hm
);
/* Delete processed data if user set MG_F_DELETE_CHUNK flag */
if
(
c
->
flags
&
MG_F_DELETE_CHUNK
)
c
->
recv_mbuf
.
len
=
req_len
;
if
(
c
->
flags
&
MG_F_DELETE_CHUNK
)
{
pd
->
body_processed
+=
hm
->
body
.
len
;
c
->
recv_mbuf
.
len
=
req_len
;
hm
->
body
.
len
=
0
;
}
}
/*
...
...
@@ -792,7 +812,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
int
ev2
=
is_req
?
MG_EV_HTTP_REQUEST
:
MG_EV_HTTP_REPLY
;
hm
->
message
.
len
=
io
->
len
;
hm
->
body
.
len
=
io
->
buf
+
io
->
len
-
hm
->
body
.
p
;
deliver_chunk
(
nc
,
hm
,
req_len
);
deliver_chunk
(
nc
,
hm
,
pd
,
req_len
);
mg_http_call_endpoint_handler
(
nc
,
ev2
,
hm
);
}
if
(
pd
!=
NULL
&&
pd
->
endpoint_handler
!=
NULL
&&
...
...
@@ -804,6 +824,8 @@ void mg_http_handler(struct mg_connection *nc, int ev,
#if MG_ENABLE_FILESYSTEM
if
(
pd
!=
NULL
&&
pd
->
file
.
fp
!=
NULL
)
{
mg_http_transfer_file_data
(
nc
);
if
(
pd
->
finished
)
{
}
}
#endif
...
...
@@ -828,8 +850,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
again:
req_len
=
mg_parse_http
(
io
->
buf
,
io
->
len
,
hm
,
is_req
);
if
(
req_len
>
0
)
{
if
(
req_len
>
0
&&
(
pd
==
NULL
||
pd
->
finished
))
{
/* New request - new proto data */
pd
=
mg_http_create_proto_data
(
nc
);
pd
->
rcvd
=
io
->
len
;
...
...
@@ -911,42 +932,50 @@ void mg_http_handler(struct mg_connection *nc, int ev,
}
}
#endif
/* MG_ENABLE_HTTP_WEBSOCKET */
else
if
(
hm
->
message
.
len
>
pd
->
rcvd
)
{
/* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */
deliver_chunk
(
nc
,
hm
,
req_len
);
if
(
nc
->
recv_mbuf_limit
>
0
&&
nc
->
recv_mbuf
.
len
>=
nc
->
recv_mbuf_limit
)
{
LOG
(
LL_ERROR
,
(
"%p recv buffer (%lu bytes) exceeds the limit "
"%lu bytes, and not drained, closing"
,
nc
,
(
unsigned
long
)
nc
->
recv_mbuf
.
len
,
(
unsigned
long
)
nc
->
recv_mbuf_limit
));
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
}
}
else
{
/* We did receive all HTTP body. */
int
request_done
=
1
;
int
trigger_ev
=
nc
->
listener
?
MG_EV_HTTP_REQUEST
:
MG_EV_HTTP_REPLY
;
char
addr
[
32
];
mg_sock_addr_to_str
(
&
nc
->
sa
,
addr
,
sizeof
(
addr
),
MG_SOCK_STRINGIFY_IP
|
MG_SOCK_STRINGIFY_PORT
);
DBG
((
"%p %s %.*s %.*s"
,
nc
,
addr
,
(
int
)
hm
->
method
.
len
,
hm
->
method
.
p
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
));
deliver_chunk
(
nc
,
hm
,
req_len
);
/* Whole HTTP message is fully buffered, call event handler */
mg_http_call_endpoint_handler
(
nc
,
trigger_ev
,
hm
);
mbuf_remove
(
io
,
hm
->
message
.
len
);
pd
->
rcvd
-=
hm
->
message
.
len
;
else
{
deliver_chunk
(
nc
,
hm
,
pd
,
req_len
);
if
(
hm
->
message
.
len
>
pd
->
rcvd
&&
(
hm
->
content_length
==
MG_HTTP_CONTENT_LENGTH_UNKNOWN
||
pd
->
body_rcvd
<
hm
->
content_length
))
{
/* Not yet received all HTTP body, deliver MG_EV_HTTP_CHUNK */
if
(
nc
->
recv_mbuf_limit
>
0
&&
nc
->
recv_mbuf
.
len
>=
nc
->
recv_mbuf_limit
)
{
LOG
(
LL_ERROR
,
(
"%p recv buffer (%lu bytes) exceeds the limit "
"%lu bytes, and not drained, closing"
,
nc
,
(
unsigned
long
)
nc
->
recv_mbuf
.
len
,
(
unsigned
long
)
nc
->
recv_mbuf_limit
));
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
}
}
else
{
/* We did receive all HTTP body. */
int
request_done
=
1
;
int
trigger_ev
=
nc
->
listener
?
MG_EV_HTTP_REQUEST
:
MG_EV_HTTP_REPLY
;
char
addr
[
32
];
mg_sock_addr_to_str
(
&
nc
->
sa
,
addr
,
sizeof
(
addr
),
MG_SOCK_STRINGIFY_IP
|
MG_SOCK_STRINGIFY_PORT
);
DBG
((
"%p %s %.*s %.*s"
,
nc
,
addr
,
(
int
)
hm
->
method
.
len
,
hm
->
method
.
p
,
(
int
)
hm
->
uri
.
len
,
hm
->
uri
.
p
));
/* Whole HTTP message is fully buffered, call event handler */
mg_http_call_endpoint_handler
(
nc
,
trigger_ev
,
hm
);
mbuf_remove
(
io
,
req_len
+
hm
->
body
.
len
);
pd
->
rcvd
-=
hm
->
message
.
len
;
pd
->
body_rcvd
=
0
;
#if MG_ENABLE_FILESYSTEM
/* We don't have a generic mechanism of communicating that we are done
* responding to a request (should probably add one). But if we are
* serving
* a file, we are definitely not done. */
if
(
pd
->
file
.
fp
!=
NULL
)
request_done
=
0
;
/* We don't have a generic mechanism of communicating that we are done
* responding to a request (should probably add one). But if we are
* serving
* a file, we are definitely not done. */
if
(
pd
->
file
.
fp
!=
NULL
)
request_done
=
0
;
#endif
#if MG_ENABLE_HTTP_CGI
/* If this is a CGI request, we are not done either. */
if
(
pd
->
cgi
.
cgi_nc
!=
NULL
)
request_done
=
0
;
/* If this is a CGI request, we are not done either. */
if
(
pd
->
cgi
.
cgi_nc
!=
NULL
)
request_done
=
0
;
#endif
if
(
request_done
&&
io
->
len
>
0
)
goto
again
;
pd
->
finished
=
request_done
;
DBG
((
"%p finished %d ml %d bl %d"
,
nc
,
pd
->
finished
,
(
int
)
hm
->
message
.
len
,
(
int
)
hm
->
body
.
len
));
if
(
request_done
&&
io
->
len
>
0
)
goto
again
;
}
}
}
}
...
...
src/mg_http.h
View file @
5d217a12
...
...
@@ -62,8 +62,16 @@ struct http_message {
/* Headers */
struct
mg_str
header_names
[
MG_MAX_HTTP_HEADERS
];
struct
mg_str
header_values
[
MG_MAX_HTTP_HEADERS
];
/*
* Value of the Content-Length header if present,
* otherwise MG_HTTP_CONTENT_LENGTH_UNKNOWN.
*/
size_t
content_length
;
};
#define MG_HTTP_CONTENT_LENGTH_UNKNOWN ((size_t) -1)
#if MG_ENABLE_HTTP_WEBSOCKET
/* WebSocket message */
struct
websocket_message
{
...
...
src/mg_http_ssi.c
View file @
5d217a12
...
...
@@ -29,13 +29,15 @@ static void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm,
*/
if
(
sscanf
(
tag
,
" virtual=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
/* File name is relative to the webserver root */
snprintf
(
path
,
sizeof
(
path
),
"%s/%s"
,
opts
->
document_root
,
file_name
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s"
,
opts
->
document_root
,
file_name
)
<
0
)
{
return
;
}
}
else
if
(
sscanf
(
tag
,
" abspath=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
/*
* File name is relative to the webserver working directory
* or it is absolute system path
*/
snprintf
(
path
,
sizeof
(
path
),
"%s"
,
file_name
)
;
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s"
,
file_name
)
<
0
)
return
;
}
else
if
(
sscanf
(
tag
,
" file=
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
||
sscanf
(
tag
,
"
\"
%[^
\"
]
\"
"
,
file_name
)
==
1
)
{
/* File name is relative to the currect document */
...
...
src/mg_net.c
View file @
5d217a12
...
...
@@ -707,13 +707,13 @@ static int mg_recv_udp(struct mg_connection *nc, char *buf, size_t len) {
}
else
{
mbuf_append
(
&
nc
->
recv_mbuf
,
buf
,
n
);
}
mbuf_trim
(
&
lc
->
recv_mbuf
);
lc
->
last_io_time
=
nc
->
last_io_time
=
(
time_t
)
mg_time
();
#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP
if
(
nc
->
mgr
&&
nc
->
mgr
->
hexdump_file
!=
NULL
)
{
mg_hexdump_connection
(
nc
,
nc
->
mgr
->
hexdump_file
,
buf
,
n
,
MG_EV_RECV
);
}
#endif
mbuf_trim
(
&
lc
->
recv_mbuf
);
if
(
n
!=
0
)
{
mg_call
(
nc
,
NULL
,
nc
->
user_data
,
MG_EV_RECV
,
&
n
);
}
...
...
src/mg_ssl_if_openssl.c
View file @
5d217a12
...
...
@@ -78,9 +78,10 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
SSL_CTX_set_options
(
ctx
->
ssl_ctx
,
SSL_OP_NO_SSLv2
);
SSL_CTX_set_options
(
ctx
->
ssl_ctx
,
SSL_OP_NO_SSLv3
);
SSL_CTX_set_options
(
ctx
->
ssl_ctx
,
SSL_OP_NO_TLSv1
);
SSL_CTX_set_session_id_context
(
ctx
->
ssl_ctx
,
(
void
*
)
mg_default_session_id_context
,
strlen
(
mg_default_session_id_context
));
SSL_CTX_set_session_id_context
(
ctx
->
ssl_ctx
,
(
const
unsigned
char
*
)
mg_default_session_id_context
,
strlen
(
mg_default_session_id_context
));
#ifdef MG_SSL_OPENSSL_NO_COMPRESSION
SSL_CTX_set_options
(
ctx
->
ssl_ctx
,
SSL_OP_NO_COMPRESSION
);
#endif
...
...
test/unit_test.c
View file @
5d217a12
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