Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2016-01-13 12:44:51 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
28080efec86eeafa91caddae7977ceabe049d9b9
28080efe
1 parent
e2e6e76f
fix http reader bug, support infinite chunkted. 2.0.209
隐藏空白字符变更
内嵌
并排对比
正在显示
8 个修改的文件
包含
160 行增加
和
23 行删除
README.md
trunk/src/app/srs_app_http_api.cpp
trunk/src/app/srs_app_http_conn.cpp
trunk/src/app/srs_app_http_conn.hpp
trunk/src/app/srs_app_utility.cpp
trunk/src/app/srs_app_utility.hpp
trunk/src/core/srs_core.hpp
trunk/src/protocol/srs_http_stack.hpp
README.md
查看文件 @
28080ef
...
...
@@ -338,6 +338,7 @@ Remark:
## History
*
v2.0, 2016-01-13, fix http reader bug, support infinite chunkted. 2.0.209
*
v2.0, 2016-01-09, merge
[
#559
][
pr #559
]
fix memory leak bug. 2.0.208
*
v2.0, 2016-01-09, merge
[
#558
][
pr #558
]
add tcUrl for on_publish.
*
v2.0, 2016-01-05, add keyword XCORE for coredump to identify the version. 2.0.207
...
...
trunk/src/app/srs_app_http_api.cpp
100755 → 100644
查看文件 @
28080ef
...
...
@@ -950,8 +950,12 @@ int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
int
ret
=
ERROR_SUCCESS
;
srs_trace
(
"HTTP %s %s, content-length=%"
PRId64
""
,
r
->
method_str
().
c_str
(),
r
->
url
().
c_str
(),
r
->
content_length
());
SrsHttpMessage
*
hm
=
dynamic_cast
<
SrsHttpMessage
*>
(
r
);
srs_assert
(
hm
);
srs_trace
(
"HTTP API %s %s, content-length=%"
PRId64
", chunked=%d/%d"
,
r
->
method_str
().
c_str
(),
r
->
url
().
c_str
(),
r
->
content_length
(),
hm
->
is_chunked
(),
hm
->
is_infinite_chunked
());
// method is OPTIONS and enable crossdomain, required crossdomain header.
if
(
r
->
is_http_options
()
&&
_srs_config
->
get_http_api_crossdomain
())
{
...
...
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
28080ef
...
...
@@ -55,6 +55,7 @@ using namespace std;
#include <srs_app_http_static.hpp>
#include <srs_app_http_stream.hpp>
#include <srs_app_http_api.hpp>
#include <srs_app_utility.hpp>
#endif
...
...
@@ -347,15 +348,29 @@ int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
}
// read by specified content-length
int
max
=
(
int
)
owner
->
content_length
()
-
(
int
)
nb_total_read
;
if
(
max
<=
0
)
{
is_eof
=
true
;
return
ret
;
if
(
owner
->
content_length
()
!=
-
1
)
{
int
max
=
(
int
)
owner
->
content_length
()
-
(
int
)
nb_total_read
;
if
(
max
<=
0
)
{
is_eof
=
true
;
return
ret
;
}
// change the max to read.
nb_data
=
srs_min
(
nb_data
,
max
);
return
read_specified
(
data
,
nb_data
,
nb_read
);
}
// infinite chunked mode, directly read.
if
(
owner
->
is_infinite_chunked
())
{
srs_assert
(
!
owner
->
is_chunked
()
&&
owner
->
content_length
()
==
-
1
);
return
read_specified
(
data
,
nb_data
,
nb_read
);
}
// change the max to read.
nb_data
=
srs_min
(
nb_data
,
max
);
return
read_specified
(
data
,
nb_data
,
nb_read
);
// infinite chunked mode, but user not set it,
// we think there is no data left.
is_eof
=
true
;
return
ret
;
}
int
SrsHttpResponseReader
::
read_chunked
(
char
*
data
,
int
nb_data
,
int
*
nb_read
)
...
...
@@ -480,8 +495,8 @@ int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
// increase the total read to determine whether EOF.
nb_total_read
+=
nb_bytes
;
// for not chunked
if
(
!
owner
->
is_chunked
())
{
// for not chunked and specified content length.
if
(
!
owner
->
is_chunked
()
&&
owner
->
content_length
()
!=
-
1
)
{
// when read completed, eof.
if
(
nb_total_read
>=
(
int
)
owner
->
content_length
())
{
is_eof
=
true
;
...
...
@@ -495,6 +510,7 @@ SrsHttpMessage::SrsHttpMessage(SrsStSocket* io, SrsConnection* c) : ISrsHttpMess
{
conn
=
c
;
chunked
=
false
;
infinite_chunked
=
false
;
keep_alive
=
true
;
_uri
=
new
SrsHttpUri
();
_body
=
new
SrsHttpResponseReader
(
this
,
io
);
...
...
@@ -532,11 +548,10 @@ int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body,
// parse uri from url.
std
::
string
host
=
get_request_header
(
"Host"
);
// donot parse the empty host for uri,
// for example, the response contains no host,
// ignore it is ok.
// use server public ip when no host specified.
// to make telnet happy.
if
(
host
.
empty
())
{
return
ret
;
host
=
srs_get_public_internet_address
()
;
}
// parse uri to schema/server:port/path?query
...
...
@@ -674,6 +689,11 @@ bool SrsHttpMessage::is_keep_alive()
return
keep_alive
;
}
bool
SrsHttpMessage
::
is_infinite_chunked
()
{
return
infinite_chunked
;
}
string
SrsHttpMessage
::
uri
()
{
std
::
string
uri
=
_uri
->
get_schema
();
...
...
@@ -728,6 +748,25 @@ int SrsHttpMessage::parse_rest_id(string pattern)
return
-
1
;
}
int
SrsHttpMessage
::
enter_infinite_chunked
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
infinite_chunked
)
{
return
ret
;
}
if
(
is_chunked
()
||
content_length
()
!=
-
1
)
{
ret
=
ERROR_HTTP_DATA_INVALID
;
srs_error
(
"infinite chunkted not supported in specified codec. ret=%d"
,
ret
);
return
ret
;
}
infinite_chunked
=
true
;
return
ret
;
}
int
SrsHttpMessage
::
body_read_all
(
string
&
body
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
trunk/src/app/srs_app_http_conn.hpp
查看文件 @
28080ef
...
...
@@ -156,9 +156,6 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// The field semantics differ slightly between client and server
// usage. In addition to the notes on the fields below, see the
// documentation for Request.Write and RoundTripper.
/**
* the http message, request or response.
*/
class
SrsHttpMessage
:
public
ISrsHttpMessage
{
private
:
...
...
@@ -184,6 +181,10 @@ private:
*/
bool
chunked
;
/**
* whether the body is infinite chunked.
*/
bool
infinite_chunked
;
/**
* whether the request indicates should keep alive
* for the http connection.
*/
...
...
@@ -236,6 +237,11 @@ public:
*/
virtual
bool
is_chunked
();
/**
* whether body is infinite chunked encoding.
* @remark set by enter_infinite_chunked.
*/
virtual
bool
is_infinite_chunked
();
/**
* whether should keep the connection alive.
*/
virtual
bool
is_keep_alive
();
...
...
@@ -256,6 +262,8 @@ public:
*/
virtual
int
parse_rest_id
(
std
::
string
pattern
);
public
:
virtual
int
enter_infinite_chunked
();
public
:
/**
* read body to string.
* @remark for small http body.
...
...
trunk/src/app/srs_app_utility.cpp
查看文件 @
28080ef
...
...
@@ -485,7 +485,7 @@ void srs_update_proc_stat()
static
int
user_hz
=
0
;
if
(
user_hz
<=
0
)
{
user_hz
=
(
int
)
sysconf
(
_SC_CLK_TCK
);
srs_
trace
(
"USER_HZ=%d"
,
user_hz
);
srs_
info
(
"USER_HZ=%d"
,
user_hz
);
srs_assert
(
user_hz
>
0
);
}
...
...
@@ -1279,6 +1279,66 @@ vector<string>& srs_get_local_ipv4_ips()
return
_srs_system_ipv4_ips
;
}
std
::
string
_public_internet_address
;
string
srs_get_public_internet_address
()
{
if
(
!
_public_internet_address
.
empty
())
{
return
_public_internet_address
;
}
std
::
vector
<
std
::
string
>&
ips
=
srs_get_local_ipv4_ips
();
// find the best match public address.
for
(
int
i
=
0
;
i
<
(
int
)
ips
.
size
();
i
++
)
{
std
::
string
ip
=
ips
[
i
];
in_addr_t
addr
=
inet_addr
(
ip
.
c_str
());
u_int32_t
addr_h
=
ntohl
(
addr
);
// lo, 127.0.0.0-127.0.0.1
if
(
addr_h
>=
0x7f000000
&&
addr_h
<=
0x7f000001
)
{
srs_trace
(
"ignore private address: %s"
,
ip
.
c_str
());
continue
;
}
// Class A 10.0.0.0-10.255.255.255
if
(
addr_h
>=
0x0a000000
&&
addr_h
<=
0x0affffff
)
{
srs_trace
(
"ignore private address: %s"
,
ip
.
c_str
());
continue
;
}
// Class B 172.16.0.0-172.31.255.255
if
(
addr_h
>=
0xac100000
&&
addr_h
<=
0xac1fffff
)
{
srs_trace
(
"ignore private address: %s"
,
ip
.
c_str
());
continue
;
}
// Class C 192.168.0.0-192.168.255.255
if
(
addr_h
>=
0xc0a80000
&&
addr_h
<=
0xc0a8ffff
)
{
srs_trace
(
"ignore private address: %s"
,
ip
.
c_str
());
continue
;
}
srs_warn
(
"use public address as ip: %s"
,
ip
.
c_str
());
_public_internet_address
=
ip
;
return
ip
;
}
// no public address, use private address.
for
(
int
i
=
0
;
i
<
(
int
)
ips
.
size
();
i
++
)
{
std
::
string
ip
=
ips
[
i
];
in_addr_t
addr
=
inet_addr
(
ip
.
c_str
());
u_int32_t
addr_h
=
ntohl
(
addr
);
// lo, 127.0.0.0-127.0.0.1
if
(
addr_h
>=
0x7f000000
&&
addr_h
<=
0x7f000001
)
{
srs_trace
(
"ignore private address: %s"
,
ip
.
c_str
());
continue
;
}
srs_warn
(
"use private address as ip: %s"
,
ip
.
c_str
());
_public_internet_address
=
ip
;
return
ip
;
}
return
""
;
}
string
srs_get_local_ip
(
int
fd
)
{
std
::
string
ip
;
...
...
trunk/src/app/srs_app_utility.hpp
查看文件 @
28080ef
...
...
@@ -660,6 +660,9 @@ extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps);
// get local ip, fill to @param ips
extern
std
::
vector
<
std
::
string
>&
srs_get_local_ipv4_ips
();
// get local public ip, empty string if no public internet address found.
extern
std
::
string
srs_get_public_internet_address
();
// get local or peer ip.
// where local ip is the server ip which client connected.
extern
std
::
string
srs_get_local_ip
(
int
fd
);
...
...
trunk/src/core/srs_core.hpp
查看文件 @
28080ef
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 20
8
#define VERSION_REVISION 20
9
// generated by configure, only macros.
#include <srs_auto_headers.hpp>
...
...
trunk/src/protocol/srs_http_stack.hpp
查看文件 @
28080ef
...
...
@@ -231,6 +231,12 @@ public:
* @param nb_data, the max size of data buffer.
* @param nb_read, the actual read size of bytes. NULL to ignore.
* @remark when eof(), return error.
* @remark for some server, the content-length not specified and not chunked,
* which is actually the infinite chunked encoding, which after http header
* is http response data, it's ok for browser. that is,
* when user call this read, please ensure there is data to read(by content-length
* or by chunked), because the sdk never know whether there is no data or
* infinite chunked.
*/
virtual
int
read
(
char
*
data
,
int
nb_data
,
int
*
nb_read
)
=
0
;
};
...
...
@@ -445,9 +451,19 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// The field semantics differ slightly between client and server
// usage. In addition to the notes on the fields below, see the
// documentation for Request.Write and RoundTripper.
/**
* the http message, request or response.
*/
//
// There are some modes to determine the length of body:
// 1. content-length and chunked.
// 2. user confirmed infinite chunked.
// 3. no body or user not confirmed infinite chunked.
// For example:
// ISrsHttpMessage* r = ...;
// while (!r->eof()) r->read(); // read in mode 1 or 3.
// For some server, we can confirm the body is infinite chunked:
// ISrsHttpMessage* r = ...;
// r->enter_infinite_chunked();
// while (!r->eof()) r->read(); // read in mode 2
// @rmark for mode 2, the infinite chunked, all left data is body.
class
ISrsHttpMessage
{
private
:
...
...
@@ -503,6 +519,12 @@ public:
virtual
int
parse_rest_id
(
std
::
string
pattern
)
=
0
;
public
:
/**
* the left all data is chunked body, the infinite chunked mode,
* which is chunked encoding without chunked header.
* @remark error when message is in chunked or content-length specified.
*/
virtual
int
enter_infinite_chunked
()
=
0
;
/**
* read body to string.
* @remark for small http body.
*/
...
...
请
注册
或
登录
后发表评论