Merge branch '3.0release' into develop

min
winlin 5 years ago
commit 4a5a2db69d

@ -50,4 +50,5 @@ CONTRIBUTORS ordered by first contribution.
* HungMingWu<u9089000@gmail.com>
* Himer<xishizhaohua@qq.com>
* xialixin<xlx0625@163.com>
* alphonsetai<tyh_123@163.com>
* alphonsetai<tyh_123@163.com>
* Michael.Ma<wnpllr@gmail.com>

@ -116,6 +116,7 @@ For previous versions, please read:
- [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92].
- [x] Support listen at IPv4 and IPv6, read [#460][bug #460].
- [x] Support SO_REUSEPORT, to improve edge server performance, read [#775][bug #775].
- [x] Improve test coverage for core/kernel/protocol/service.
- [x] [Experimental] Support docker by [srs-docker](https://github.com/ossrs/srs-docker).
- [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738].
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
@ -129,7 +130,6 @@ For previous versions, please read:
- [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]) and [#1535][bug #1535].
- [x] [Deprecated] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]), please read [#1535][bug #1535].
- [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication, please read [#1535][bug #1535].
- [ ] Utest cover almost all kernel code.
- [ ] Enhanced forwarding with vhost and variables.
- [ ] Support source cleanup for idle streams.
- [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465].
@ -148,6 +148,12 @@ For previous versions, please read:
## V3 changes
* v3.0, 2020-01-16, For [#1575][bug #1575], correct RTMP redirect as tcUrl, add redirect2 as RTMP URL. 3.0.100
* v3.0, 2020-01-15, For [#1509][bug #1509], decrease the fast vector init size from 64KB to 64B. 3.0.99
* v3.0, 2020-01-15, For [#1509][bug #1509], release coroutine when source is idle. 3.0.98
* <strong>v3.0, 2020-01-10, [3.0 alpha8(3.0.97)][r3.0a8] released. 121555 lines.</strong>
* v3.0, 2020-01-09, For [#1042][bug #1042], improve test coverage for service. 3.0.97
* v3.0, 2020-01-08, Merge [#1554][bug #1554], support logrotate copytruncate. 3.0.96
* v3.0, 2020-01-05, Always use string instance to avoid crash risk. 3.0.95
* v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 hostport parsing bug. 3.0.94
* v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 intranet address filter bug. 3.0.93
@ -274,6 +280,7 @@ For previous versions, please read:
## V2 changes
* v2.0, 2020-01-08, Merge [#1554][bug #1554], support logrotate copytruncate. 2.0.272
* v2.0, 2020-01-05, Merge [#1551][bug #1551], fix memory leak in RTSP stack. 2.0.270
* v2.0, 2019-12-26, For [#1488][bug #1488], pass client ip to http callback. 2.0.269
* v2.0, 2019-12-23, Fix [srs-librtmp #22](https://github.com/ossrs/srs-librtmp/issues/22), parse vhost splited by single seperator. 2.0.268
@ -710,6 +717,7 @@ For previous versions, please read:
## Releases
* 2020-01-10, [Release v3.0-a8][r3.0a8], 3.0 alpha8, 3.0.97, 121555 lines.
* 2019-12-29, [Release v3.0-a7][r3.0a7], 3.0 alpha7, 3.0.90, 116356 lines.
* 2019-12-26, [Release v3.0-a6][r3.0a6], 3.0 alpha6, 3.0.85, 116056 lines.
* 2019-12-19, [Release v3.0-a5][r3.0a5], 3.0 alpha5, 3.0.75, 115362 lines.
@ -1553,6 +1561,7 @@ Winlin
[bug #1524]: https://github.com/ossrs/srs/issues/1524
[bug #1488]: https://github.com/ossrs/srs/issues/1488
[bug #1551]: https://github.com/ossrs/srs/pull/1551
[bug #1554]: https://github.com/ossrs/srs/pull/1554
[bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
[bug #735]: https://github.com/ossrs/srs/issues/735
@ -1588,6 +1597,8 @@ Winlin
[bug #1544]: https://github.com/ossrs/srs/issues/1544
[bug #1255]: https://github.com/ossrs/srs/issues/1255
[bug #1543]: https://github.com/ossrs/srs/issues/1543
[bug #1509]: https://github.com/ossrs/srs/issues/1509
[bug #1575]: https://github.com/ossrs/srs/issues/1575
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
[bug #1111]: https://github.com/ossrs/srs/issues/1111
@ -1596,6 +1607,7 @@ Winlin
[exo #828]: https://github.com/google/ExoPlayer/pull/828
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
@ -1660,6 +1672,4 @@ Winlin
[branch2]: https://github.com/ossrs/srs/tree/2.0release
[release2]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release30
[centos0]: http://winlinvip.github.io/srs.release/releases/files/SRS-CentOS6-x86_64-3.0.56.zip
[centos1]: http://ossrs.net/srs.release/releases/files/SRS-CentOS6-x86_64-3.0.56.zip

@ -122,6 +122,7 @@ Options:
--with-research build the research tools.
--with-utest build the utest for SRS.
--with-gperf build SRS with gperf tools(no gmd/gmc/gmp/gcp, with tcmalloc only).
https://blog.csdn.net/win_lin/article/details/53503869
--with-gmc build memory check for SRS with gperf tools.
--with-gmd build memory defense(corrupt memory) for SRS with gperf tools.
--with-gmp build memory profile for SRS with gperf tools.
@ -198,6 +199,7 @@ Experts:
--memory-watch enable memory watch to detect memory leaking(hurts performance).
--export-librtmp-project=<path> export srs-librtmp to specified project in path.
--export-librtmp-single=<path> export srs-librtmp to a single file(.h+.cpp) in path.
--with-valgrind support valgrind for memory check.
--without-valgrind donot support valgrind for memory check.
Workflow:
@ -207,10 +209,7 @@ Workflow:
4. generate detail features.
Remark:
1. both ubuntu12 and ubuntu14 are ok for SRS.
2. the centos5, centos6 and centos7 are ok for SRS.
3. all linux and unix-like os are ok for SRS.
4. windows is absolutely impossible for SRS.
1. For performance improving, read https://blog.csdn.net/win_lin/article/details/53503869
END
}
@ -289,6 +288,7 @@ function parse_user_option() {
--memory-watch) SRS_MEM_WATCH=YES ;;
--export-librtmp-project) SRS_EXPORT_LIBRTMP_PROJECT=${value} ;;
--export-librtmp-single) SRS_EXPORT_LIBRTMP_SINGLE=${value} ;;
--with-valgrind) SRS_VALGRIND=YES ;;
--without-valgrind) SRS_VALGRIND=NO ;;
--with-http-callback) SRS_HTTP_CALLBACK=YES ;;
@ -395,18 +395,6 @@ function apply_user_presets() {
SRS_STATIC=NO
fi
# for osx(darwin)
if [ $SRS_OSX = YES ]; then
SRS_HDS=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
SRS_UTEST=YES
SRS_STATIC=NO
# valgrind is not supported by macOS sierra, read
# https://stackoverflow.com/questions/40650338/valgrind-on-macos-sierra
SRS_VALGRIND=NO
fi
# if dev specified, open features if possible.
if [ $SRS_DEV = YES ]; then
SRS_HDS=YES

@ -43,16 +43,13 @@ echo -e " \${BLACK}+--------------------------------------------------------
echo -e " |\${GREEN}The main server usage: ./objs/srs -c conf/srs.conf, start the srs server\${BLACK}"
echo -e " | ${SrsHlsSummaryColor}About HLS, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}"
echo -e " | ${SrsDvrSummaryColor}About DVR, please read https://github.com/ossrs/srs/wiki/v3_CN_DVR\${BLACK}"
echo -e " | ${SrsNginxSummaryColor}About NGINX, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}"
echo -e " | ${SrsSslSummaryColor}About SSL, please read https://github.com/ossrs/srs/wiki/v1_CN_RTMPHandshake\${BLACK}"
echo -e " | ${SrsFfmpegSummaryColor}About FFMPEG, please read https://github.com/ossrs/srs/wiki/v3_CN_FFMPEG\${BLACK}"
echo -e " | ${SrsTranscodeSummaryColor}About transcoding, please read https://github.com/ossrs/srs/wiki/v3_CN_FFMPEG\${BLACK}"
echo -e " | ${SrsIngestSummaryColor}About ingester, please read https://github.com/ossrs/srs/wiki/v1_CN_Ingest\${BLACK}"
echo -e " | ${SrsHttpCallbackSummaryColor}About http-callback, please read https://github.com/ossrs/srs/wiki/v3_CN_HTTPCallback\${BLACK}"
echo -e " | ${SrsHttpServerSummaryColor}Aoubt embeded http-server, please read https://github.com/ossrs/srs/wiki/v2_CN_HTTPServer\${BLACK}"
echo -e " | ${SrsHttpServerSummaryColor}Aoubt http-server, please read https://github.com/ossrs/srs/wiki/v2_CN_HTTPServer\${BLACK}"
echo -e " | ${SrsHttpApiSummaryColor}About http-api, please read https://github.com/ossrs/srs/wiki/v3_CN_HTTPApi\${BLACK}"
echo -e " | ${SrsStreamCasterSummaryColor}About stream-caster, please read https://github.com/ossrs/srs/wiki/v2_CN_Streamer\${BLACK}"
echo -e " | ${SrsKafkaSummaryColor}About kafka, please read https://github.com/ossrs/srs/wiki/v3_CN_Kafka\${BLACK}"
echo -e " | ${SrsValgrindSummaryColor}About VALGRIND, please read https://github.com/ossrs/state-threads/issues/2\${BLACK}"
echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
echo -e "\${GREEN}binaries, please read https://github.com/ossrs/srs/wiki/v2_CN_Build\${BLACK}"

@ -6771,22 +6771,22 @@ string SrsConfig::get_vhost_http_dir(string vhost)
bool SrsConfig::get_vhost_http_remux_enabled(string vhost)
{
static bool DEFAULT = false;
SrsConfDirective* conf = get_vhost(vhost);
if (!conf) {
return DEFAULT;
}
conf = conf->get("http_remux");
if (!conf) {
return DEFAULT;
}
conf = conf->get("enabled");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return SRS_CONF_PERFER_FALSE(conf->arg0());
}

@ -609,13 +609,25 @@ srs_error_t SrsDvrPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsReque
return srs_error_wrap(err, "segmenter");
}
return err;
}
srs_error_t SrsDvrPlan::on_publish()
{
srs_error_t err = srs_success;
if ((err = async->start()) != srs_success) {
return srs_error_wrap(err, "async");
}
return err;
}
void SrsDvrPlan::on_unpublish()
{
async->stop();
}
srs_error_t SrsDvrPlan::on_meta_data(SrsSharedPtrMessage* shared_metadata)
{
srs_error_t err = srs_success;
@ -699,6 +711,10 @@ SrsDvrSessionPlan::~SrsDvrSessionPlan()
srs_error_t SrsDvrSessionPlan::on_publish()
{
srs_error_t err = srs_success;
if ((err = SrsDvrPlan::on_publish()) != srs_success) {
return err;
}
// support multiple publish.
if (dvr_enabled) {
@ -724,6 +740,8 @@ srs_error_t SrsDvrSessionPlan::on_publish()
void SrsDvrSessionPlan::on_unpublish()
{
SrsDvrPlan::on_unpublish();
// support multiple publish.
if (!dvr_enabled) {
return;
@ -766,6 +784,10 @@ srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, S
srs_error_t SrsDvrSegmentPlan::on_publish()
{
srs_error_t err = srs_success;
if ((err = SrsDvrPlan::on_publish()) != srs_success) {
return err;
}
// support multiple publish.
if (dvr_enabled) {
@ -791,6 +813,7 @@ srs_error_t SrsDvrSegmentPlan::on_publish()
void SrsDvrSegmentPlan::on_unpublish()
{
SrsDvrPlan::on_unpublish();
}
srs_error_t SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)

@ -185,8 +185,8 @@ public:
virtual ~SrsDvrPlan();
public:
virtual srs_error_t initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r);
virtual srs_error_t on_publish() = 0;
virtual void on_unpublish() = 0;
virtual srs_error_t on_publish();
virtual void on_unpublish();
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata);
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);

@ -416,9 +416,14 @@ srs_error_t SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg, stri
return err;
}
SrsAmf0Object* ex = prop->to_object();
if ((prop = ex->ensure_property_string("redirect")) == NULL) {
return err;
// The redirect is tcUrl while redirect2 is RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574999798
if ((prop = ex->ensure_property_string("redirect2")) == NULL) {
// TODO: FIXME: Remove it when SRS3 released, it's temporarily support for SRS3 alpha versions(a0 to a8).
if ((prop = ex->ensure_property_string("redirect")) == NULL) {
return err;
}
}
redirect = prop->to_str();

@ -268,16 +268,27 @@ int SrsHlsMuxer::deviation()
}
srs_error_t SrsHlsMuxer::initialize()
{
return srs_success;
}
srs_error_t SrsHlsMuxer::on_publish(SrsRequest* req)
{
srs_error_t err = srs_success;
if ((err = async->start()) != srs_success) {
return srs_error_wrap(err, "async start");
}
return err;
}
srs_error_t SrsHlsMuxer::on_unpublish()
{
async->stop();
return srs_success;
}
srs_error_t SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
string path, string m3u8_file, string ts_file, srs_utime_t fragment, srs_utime_t window,
bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe, bool keys,
@ -899,8 +910,11 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
// TODO: FIXME: support load exists m3u8, to continue publish stream.
// for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
if ((err = muxer->on_publish(req)) != srs_success) {
return srs_error_wrap(err, "muxer publish");
}
// open muxer
if ((err = muxer->update_config(req, entry_prefix, path, m3u8_file, ts_file, hls_fragment,
hls_window, ts_floor, hls_aof_ratio, cleanup, wait_keyframe,hls_keys,hls_fragments_per_key,
hls_key_file, hls_key_file_path, hls_key_url)) != srs_success ) {
@ -924,6 +938,10 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
srs_error_t SrsHlsController::on_unpublish()
{
srs_error_t err = srs_success;
if ((err = muxer->on_unpublish()) != srs_success) {
return srs_error_wrap(err, "muxer unpublish");
}
if ((err = muxer->flush_audio(tsmc)) != srs_success) {
return srs_error_wrap(err, "hls: flush audio");

@ -185,6 +185,9 @@ public:
public:
// Initialize the hls muxer.
virtual srs_error_t initialize();
// When publish or unpublish stream.
virtual srs_error_t on_publish(SrsRequest* req);
virtual srs_error_t on_unpublish();
// When publish, update the config for muxer.
virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix,
std::string path, std::string m3u8_file, std::string ts_file,

@ -1023,7 +1023,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandle
if (it == tflvs.end()) {
return err;
}
// hstrs always enabled.
// for origin, the http stream will be mount already when publish,
// so it must never enter this line for stream already mounted.
@ -1064,7 +1064,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandle
if (srs_string_count(upath, "/") != srs_string_count(entry->mount, "/")) {
return err;
}
// convert to concreate class.
SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request);
srs_assert(hreq);
@ -1127,7 +1127,7 @@ srs_error_t SrsHttpStreamServer::initialize_flv_streaming()
if (!conf->is_vhost()) {
continue;
}
if ((err = initialize_flv_entry(conf->arg0())) != srs_success) {
return srs_error_wrap(err, "init flv entries");
}
@ -1139,7 +1139,7 @@ srs_error_t SrsHttpStreamServer::initialize_flv_streaming()
srs_error_t SrsHttpStreamServer::initialize_flv_entry(std::string vhost)
{
srs_error_t err = srs_success;
if (!_srs_config->get_vhost_http_remux_enabled(vhost)) {
return err;
}

@ -318,11 +318,10 @@ void SrsFastLog::open_log_file()
if (filename.empty()) {
return;
}
fd = ::open(filename.c_str(), O_RDWR | O_APPEND);
if(fd == -1 && errno == ENOENT) {
fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
}
fd = ::open(filename.c_str(),
O_RDWR | O_CREAT | O_APPEND,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
);
}

@ -621,8 +621,10 @@ srs_error_t SrsRtmpConn::playing(SrsSource* source)
}
return srs_error_wrap(err, "discover coworkers, url=%s", url.c_str());
}
srs_trace("rtmp: redirect in cluster, from=%s:%d, target=%s:%d, url=%s",
req->host.c_str(), req->port, host.c_str(), port, url.c_str());
string rurl = srs_generate_rtmp_url(host, port, req->host, req->vhost, req->app, req->stream, req->param);
srs_trace("rtmp: redirect in cluster, from=%s:%d, target=%s:%d, url=%s, rurl=%s",
req->host.c_str(), req->port, host.c_str(), port, url.c_str(), rurl.c_str());
// Ignore if host or port is invalid.
if (host.empty() || port == 0) {
@ -630,7 +632,7 @@ srs_error_t SrsRtmpConn::playing(SrsSource* source)
}
bool accepted = false;
if ((err = rtmp->redirect(req, host, port, accepted)) != srs_success) {
if ((err = rtmp->redirect(req, rurl, accepted)) != srs_success) {
srs_error_reset(err);
} else {
return srs_error_new(ERROR_CONTROL_REDIRECT, "redirected");

@ -154,7 +154,7 @@ int64_t SrsRtmpJitter::get_time()
SrsFastVector::SrsFastVector()
{
count = 0;
nb_msgs = SRS_PERF_MW_MSGS * 8;
nb_msgs = 8;
msgs = new SrsSharedPtrMessage*[nb_msgs];
}
@ -212,12 +212,12 @@ void SrsFastVector::push_back(SrsSharedPtrMessage* msg)
{
// increase vector.
if (count >= nb_msgs) {
int size = nb_msgs * 2;
int size = srs_max(SRS_PERF_MW_MSGS * 8, nb_msgs * 2);
SrsSharedPtrMessage** buf = new SrsSharedPtrMessage*[size];
for (int i = 0; i < nb_msgs; i++) {
buf[i] = msgs[i];
}
srs_warn("fast vector incrase %d=>%d", nb_msgs, size);
srs_info("fast vector incrase %d=>%d", nb_msgs, size);
// use new array.
srs_freepa(msgs);

@ -27,7 +27,7 @@
// The version config.
#define VERSION_MAJOR 3
#define VERSION_MINOR 0
#define VERSION_REVISION 95
#define VERSION_REVISION 100
// The macros generated by configure script.
#include <srs_auto_headers.hpp>

@ -2415,17 +2415,20 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser
}
#define SRS_RTMP_REDIRECT_TIMEOUT (3 * SRS_UTIME_SECONDS)
srs_error_t SrsRtmpServer::redirect(SrsRequest* r, string host, int port, bool& accepted)
srs_error_t SrsRtmpServer::redirect(SrsRequest* r, string url, bool& accepted)
{
srs_error_t err = srs_success;
if (true) {
string url = srs_generate_rtmp_url(host, port, r->host, r->vhost, r->app, r->stream, r->param);
SrsAmf0Object* ex = SrsAmf0Any::object();
ex->set("code", SrsAmf0Any::number(302));
ex->set("redirect", SrsAmf0Any::str(url.c_str()));
// The redirect is tcUrl while redirect2 is RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574999798
string tcUrl = srs_path_dirname(url);
ex->set("redirect", SrsAmf0Any::str(tcUrl.c_str()));
ex->set("redirect2", SrsAmf0Any::str(url.c_str()));
SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
pkt->data->set(StatusLevel, SrsAmf0Any::str(StatusLevelError));

@ -707,9 +707,9 @@ public:
// @param server_ip the ip of server.
virtual srs_error_t response_connect_app(SrsRequest* req, const char* server_ip = NULL);
// Redirect the connection to another rtmp server.
// @param the hostname or ip of target.
// @param a RTMP url to redirect to.
// @param whether the client accept the redirect.
virtual srs_error_t redirect(SrsRequest* r, std::string host, int port, bool& accepted);
virtual srs_error_t redirect(SrsRequest* r, std::string url, bool& accepted);
// Reject the connect app request.
virtual void response_connect_reject(SrsRequest* req, const char* desc);
// Response client the onBWDone message.

@ -41,7 +41,7 @@ SrsHttpClient::SrsHttpClient()
clk = new SrsWallClock();
kbps = new SrsKbps(clk);
parser = NULL;
timeout = SRS_UTIME_NO_TIMEOUT;
recv_timeout = timeout = SRS_UTIME_NO_TIMEOUT;
port = 0;
}
@ -68,7 +68,7 @@ srs_error_t SrsHttpClient::initialize(string h, int p, srs_utime_t tm)
// Always disconnect the transport.
host = h;
port = p;
timeout = tm;
recv_timeout = timeout = tm;
disconnect();
// ep used for host in header.
@ -187,7 +187,7 @@ srs_error_t SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg)
void SrsHttpClient::set_recv_timeout(srs_utime_t tm)
{
transport->set_recv_timeout(tm);
recv_timeout = tm;
}
void SrsHttpClient::kbps_sample(const char* label, int64_t age)
@ -222,11 +222,12 @@ srs_error_t SrsHttpClient::connect()
transport = new SrsTcpClient(host, port, timeout);
if ((err = transport->connect()) != srs_success) {
disconnect();
return srs_error_wrap(err, "http: tcp connect %s:%d to=%dms", host.c_str(), port, srsu2msi(timeout));
return srs_error_wrap(err, "http: tcp connect %s:%d to=%dms, rto=%dms",
host.c_str(), port, srsu2msi(timeout), srsu2msi(recv_timeout));
}
// Set the recv/send timeout in srs_utime_t.
transport->set_recv_timeout(timeout);
transport->set_recv_timeout(recv_timeout);
transport->set_send_timeout(timeout);
kbps->set_io(transport, transport);

@ -63,6 +63,7 @@ private:
private:
// The timeout in srs_utime_t.
srs_utime_t timeout;
srs_utime_t recv_timeout;
// The host name or ip.
std::string host;
int port;

@ -82,6 +82,7 @@ void SrsThreadContext::clear_cid()
}
}
// LCOV_EXCL_START
SrsConsoleLog::SrsConsoleLog(SrsLogLevel l, bool u)
{
level = l;
@ -208,6 +209,7 @@ void SrsConsoleLog::error(const char* tag, int context_id, const char* fmt, ...)
fprintf(stderr, "%s\n", buffer);
}
// LCOV_EXCL_STOP
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize)
{

@ -33,12 +33,12 @@ using namespace std;
#include <srs_protocol_utility.hpp>
#include <srs_service_utility.hpp>
SrsBasicRtmpClient::SrsBasicRtmpClient(string u, srs_utime_t ctm, srs_utime_t stm)
SrsBasicRtmpClient::SrsBasicRtmpClient(string r, srs_utime_t ctm, srs_utime_t stm)
{
clk = new SrsWallClock();
kbps = new SrsKbps(clk);
url = u;
url = r;
connect_timeout = ctm;
stream_timeout = stm;

@ -60,10 +60,10 @@ private:
int stream_id;
public:
// Constructor.
// @param u The RTMP url, for example, rtmp://ip:port/app/stream?domain=vhost
// @param r The RTMP url, for example, rtmp://ip:port/app/stream?domain=vhost
// @param ctm The timeout in srs_utime_t to connect to server.
// @param stm The timeout in srs_utime_t to delivery A/V stream.
SrsBasicRtmpClient(std::string u, srs_utime_t ctm, srs_utime_t stm);
SrsBasicRtmpClient(std::string r, srs_utime_t ctm, srs_utime_t stm);
virtual ~SrsBasicRtmpClient();
public:
// Connect, handshake and connect app to RTMP server.

@ -131,7 +131,7 @@ VOID TEST(SrsAVCTest, H264SequenceHeader)
if (true) {
SrsRawH264Stream h; string sh;
HELPER_ASSERT_SUCCESS(h.mux_sequence_header("Hello", "world", 0, 0, sh));
EXPECT_EQ(11+5+5, sh.length());
EXPECT_EQ(11+5+5, (int)sh.length());
EXPECT_STREQ("Hello", sh.substr(8, 5).c_str());
EXPECT_STREQ("world", sh.substr(16).c_str());
}
@ -247,7 +247,8 @@ VOID TEST(SrsAVCTest, H264IPBFrame)
SrsRawH264Stream h; string frame;
HELPER_ASSERT_SUCCESS(h.mux_ipb_frame((char*)"Hello", 5, frame));
EXPECT_EQ(4+5, frame.length());
EXPECT_EQ(0, frame.at(0)); EXPECT_EQ(0, frame.at(1)); EXPECT_EQ(0, frame.at(2)); EXPECT_EQ(5, frame.at(3));
EXPECT_EQ(0, (uint8_t)frame.at(0)); EXPECT_EQ(0, (uint8_t)frame.at(1));
EXPECT_EQ(0, (uint8_t)frame.at(2)); EXPECT_EQ(5, (uint8_t)frame.at(3));
EXPECT_STREQ("Hello", frame.substr(4).c_str());
}
}

@ -2675,13 +2675,13 @@ VOID TEST(ConfigMainTest, CheckGlobalConfig)
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse("listen 1935;"));
EXPECT_EQ(1, conf.get_listens().size());
EXPECT_EQ(1, (int)conf.get_listens().size());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse("listen 1935 1936;"));
EXPECT_EQ(2, conf.get_listens().size());
EXPECT_EQ(2, (int)conf.get_listens().size());
}
if (true) {

@ -4788,13 +4788,13 @@ VOID TEST(KernelMP4Test, CoverMP4All)
if (true) {
SrsMp4ElstEntry e;
EXPECT_EQ(0, e.media_time);
EXPECT_EQ(0, e.segment_duration);
EXPECT_EQ(0, (int)e.segment_duration);
}
if (true) {
SrsMp4CttsEntry e;
EXPECT_EQ(0, e.sample_count);
EXPECT_EQ(0, e.sample_offset);
EXPECT_EQ(0, (int)e.sample_count);
EXPECT_EQ(0, (int)e.sample_offset);
}
}

@ -492,7 +492,7 @@ VOID TEST(KernelMp4Test, FullBoxDump)
SrsMp4FullBox box;
HELPER_ASSERT_SUCCESS(box.decode(&b));
EXPECT_EQ(1, box.version);
EXPECT_EQ(2, box.flags);
EXPECT_EQ(2, (int)box.flags);
}
if (true) {
@ -564,7 +564,7 @@ VOID TEST(KernelMp4Test, MFHDBox)
SrsMp4MovieFragmentHeaderBox box;
HELPER_ASSERT_SUCCESS(box.decode(&b));
EXPECT_EQ(3, box.sequence_number);
EXPECT_EQ(3, (int)box.sequence_number);
}
if (true) {
@ -596,7 +596,7 @@ VOID TEST(KernelMp4Test, TFHDBox)
if (true) {
SrsMp4TrackFragmentHeaderBox box;
box.track_id = 100;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -631,7 +631,7 @@ VOID TEST(KernelMp4Test, TFHDBox)
box.default_sample_duration = 12;
box.default_sample_size = 13;
box.default_sample_flags = 14;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -646,12 +646,12 @@ VOID TEST(KernelMp4Test, TFHDBox)
b.skip(-1 * b.pos());
SrsMp4TrackFragmentHeaderBox box;
HELPER_EXPECT_SUCCESS(box.decode(&b));
EXPECT_EQ(100, box.track_id);
EXPECT_EQ(box.base_data_offset, 10);
EXPECT_EQ(box.sample_description_index, 11);
EXPECT_EQ(box.default_sample_duration, 12);
EXPECT_EQ(box.default_sample_size, 13);
EXPECT_EQ(box.default_sample_flags, 14);
EXPECT_EQ((int)box.track_id, 100);
EXPECT_EQ((int)box.base_data_offset, 10);
EXPECT_EQ((int)box.sample_description_index, 11);
EXPECT_EQ((int)box.default_sample_duration, 12);
EXPECT_EQ((int)box.default_sample_size, 13);
EXPECT_EQ((int)box.default_sample_flags, 14);
}
}
}
@ -667,7 +667,7 @@ VOID TEST(KernelMp4Test, TFDTBox)
if (true) {
SrsMp4TrackFragmentDecodeTimeBox box;
box.base_media_decode_time = 100;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -682,7 +682,7 @@ VOID TEST(KernelMp4Test, TFDTBox)
b.skip(-1 * b.pos());
SrsMp4TrackFragmentDecodeTimeBox box;
HELPER_EXPECT_SUCCESS(box.decode(&b));
EXPECT_EQ(100, box.base_media_decode_time);
EXPECT_EQ(100, (int)box.base_media_decode_time);
}
}
@ -694,7 +694,7 @@ VOID TEST(KernelMp4Test, TFDTBox)
SrsMp4TrackFragmentDecodeTimeBox box;
box.version = 1;
box.base_media_decode_time = 100;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -709,7 +709,7 @@ VOID TEST(KernelMp4Test, TFDTBox)
b.skip(-1 * b.pos());
SrsMp4TrackFragmentDecodeTimeBox box;
HELPER_EXPECT_SUCCESS(box.decode(&b));
EXPECT_EQ(100, box.base_media_decode_time);
EXPECT_EQ(100, (int)box.base_media_decode_time);
}
}
}
@ -724,7 +724,7 @@ VOID TEST(KernelMp4Test, TRUNBox)
if (true) {
SrsMp4TrackFragmentRunBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -754,7 +754,7 @@ VOID TEST(KernelMp4Test, TRUNBox)
entry->sample_duration = 1000;
box.entries.push_back(entry);
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -788,7 +788,7 @@ VOID TEST(KernelMp4Test, FreeBox)
if (true) {
SrsMp4FreeSpaceBox box(SrsMp4BoxTypeFREE);
box.data.resize(4);
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -818,7 +818,7 @@ VOID TEST(KernelMp4Test, MOOVBox)
if (true) {
SrsMp4MovieBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -891,7 +891,7 @@ VOID TEST(KernelMp4Test, TREXBox)
SrsMp4TrackExtendsBox box;
box.track_ID = 1; box.default_sample_description_index = 2; box.default_sample_size = 3;
box.default_sample_duration = 4; box.default_sample_flags = 5;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -933,7 +933,7 @@ VOID TEST(KernelMp4Test, TKHDBox)
if (true) {
SrsMp4TrackHeaderBox box;
box.track_ID = 1;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -960,7 +960,7 @@ VOID TEST(KernelMp4Test, TKHDBox)
SrsMp4TrackHeaderBox box;
box.version = 1;
box.track_ID = 1;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -990,7 +990,7 @@ VOID TEST(KernelMp4Test, ELSTBox)
if (true) {
SrsMp4EditListBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1018,7 +1018,7 @@ VOID TEST(KernelMp4Test, ELSTBox)
SrsMp4ElstEntry entry;
box.entries.push_back(entry);
}
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1054,7 +1054,7 @@ VOID TEST(KernelMp4Test, MDHDBox)
if (true) {
SrsMp4MediaHeaderBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1081,7 +1081,7 @@ VOID TEST(KernelMp4Test, MDHDBox)
box.set_language0('C');
box.set_language1('N');
box.set_language2('E');
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1136,7 +1136,7 @@ VOID TEST(KernelMp4Test, HDLRBox)
if (true) {
SrsMp4HandlerReferenceBox box;
box.handler_type = SrsMp4HandlerTypeSOUN;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1162,7 +1162,7 @@ VOID TEST(KernelMp4Test, HDLRBox)
if (true) {
SrsMp4HandlerReferenceBox box;
box.handler_type = SrsMp4HandlerTypeVIDE;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1189,7 +1189,7 @@ VOID TEST(KernelMp4Test, HDLRBox)
SrsMp4HandlerReferenceBox box;
box.handler_type = SrsMp4HandlerTypeVIDE;
box.name = "srs";
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1247,7 +1247,7 @@ VOID TEST(KernelMp4Test, URLBox)
if (true) {
SrsMp4DataEntryUrlBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1271,7 +1271,7 @@ VOID TEST(KernelMp4Test, URLBox)
if (true) {
SrsMp4DataEntryUrnBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1304,7 +1304,7 @@ VOID TEST(KernelMp4Test, URLBox)
SrsMp4DataReferenceBox box;
SrsMp4DataEntryUrnBox* urn = new SrsMp4DataEntryUrnBox();
box.append(urn);
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1341,7 +1341,7 @@ VOID TEST(KernelMp4Test, SampleDescBox)
if (true) {
SrsMp4VisualSampleEntry box;
box.data_reference_index = 1;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1365,7 +1365,7 @@ VOID TEST(KernelMp4Test, SampleDescBox)
if (true) {
SrsMp4AvccBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1390,7 +1390,7 @@ VOID TEST(KernelMp4Test, SampleDescBox)
if (true) {
SrsMp4AudioSampleEntry box;
box.data_reference_index = 1;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1420,7 +1420,7 @@ VOID TEST(KernelMp4Test, SpecificInfoBox)
if (true) {
SrsMp4DecoderSpecificInfo box;
box.asc.resize(2);
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1444,7 +1444,7 @@ VOID TEST(KernelMp4Test, SpecificInfoBox)
if (true) {
SrsMp4DecoderConfigDescriptor box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1468,7 +1468,7 @@ VOID TEST(KernelMp4Test, SpecificInfoBox)
if (true) {
SrsMp4ES_Descriptor box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1498,7 +1498,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4SampleDescriptionBox box;
box.entries.push_back(new SrsMp4SampleEntry());
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1523,7 +1523,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4DecodingTime2SampleBox box;
box.entries.push_back(SrsMp4SttsEntry());
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1548,7 +1548,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4CompositionTime2SampleBox box;
box.entries.push_back(SrsMp4CttsEntry());
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1572,7 +1572,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4SyncSampleBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1596,7 +1596,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4Sample2ChunkBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1620,7 +1620,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4ChunkOffsetBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1644,7 +1644,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4ChunkLargeOffsetBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1668,7 +1668,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4SampleSizeBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1693,7 +1693,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4UserDataBox box;
box.data.resize(2);
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1717,7 +1717,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4SegmentIndexBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1741,7 +1741,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4MovieHeaderBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;
@ -1772,7 +1772,7 @@ VOID TEST(KernelMp4Test, STSDBox)
if (true) {
SrsMp4CompositionTime2SampleBox box;
EXPECT_EQ(sizeof(buf), box.nb_bytes());
EXPECT_EQ((int)sizeof(buf), box.nb_bytes());
HELPER_EXPECT_SUCCESS(box.encode(&b));
stringstream ss;

@ -5804,8 +5804,8 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 70, nparsed = 70, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(70, (int)parser.parsed);
EXPECT_EQ(0, (int)parser.parser->nread);
EXPECT_TRUE(!parser.body);
EXPECT_TRUE(parser.headers_complete);
EXPECT_TRUE(!parser.message_complete);
@ -5815,7 +5815,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 75, nparsed = 75, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(75, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_TRUE(parser.body && 5 == parser.body->length);
EXPECT_TRUE(parser.headers_complete);
@ -5826,7 +5826,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 150, nparsed = 150, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
EXPECT_EQ(150, parser.parsed);
EXPECT_EQ(150, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5834,13 +5834,13 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(70, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(5, parser.parser->content_length);
// size = 79, nparsed = 5, nread = 1, content_length = -1, Header("Content-Length", 5)
HELPER_EXPECT_FAILED(parser.parse("elloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(5, parser.parsed);
EXPECT_EQ(5, (int)parser.parsed);
EXPECT_EQ(1, parser.parser->nread);
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
}
@ -5849,13 +5849,13 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(70, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(5, parser.parser->content_length);
// size = 80, nparsed = 70, nread = 0, content_length = 0, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("HelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
EXPECT_EQ(80, parser.parsed);
EXPECT_EQ(80, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(0, parser.parser->content_length);
}
@ -5864,7 +5864,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 73, nparsed = 73, nread = 0, content_length = 2, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHel"));
EXPECT_EQ(73, parser.parsed);
EXPECT_EQ(73, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(2, parser.parser->content_length);
}
@ -5873,7 +5873,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 82, nparsed = 75, nread = 1, content_length = -1, Header("Content-Length", 5)
HELPER_EXPECT_FAILED(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello World!"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(75, (int)parser.parsed);
EXPECT_EQ(1, parser.parser->nread);
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
}
@ -5882,12 +5882,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 34, nparsed = 34, nread = 34
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHo"));
EXPECT_EQ(34, parser.parsed);
EXPECT_EQ(34, (int)parser.parsed);
EXPECT_EQ(34, parser.parser->nread);
// size = 41, nparsed = 41, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("st: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(41, parser.parsed);
EXPECT_EQ(41, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5895,12 +5895,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 41, nparsed = 41, nread = 41
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: oss"));
EXPECT_EQ(41, parser.parsed);
EXPECT_EQ(41, (int)parser.parsed);
EXPECT_EQ(41, parser.parser->nread);
// size = 34, nparsed = 34, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("rs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(34, parser.parsed);
EXPECT_EQ(34, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5908,12 +5908,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 48, nparsed = 48, nread = 48
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r"));
EXPECT_EQ(48, parser.parsed);
EXPECT_EQ(48, (int)parser.parsed);
EXPECT_EQ(48, parser.parser->nread);
// size = 27, nparsed = 27, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(27, parser.parsed);
EXPECT_EQ(27, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5921,12 +5921,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 68, nparsed = 68, nread = 68
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n"));
EXPECT_EQ(68, parser.parsed);
EXPECT_EQ(68, (int)parser.parsed);
EXPECT_EQ(68, parser.parser->nread);
// size = 7, nparsed = 7, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\r\nHello"));
EXPECT_EQ(7, parser.parsed);
EXPECT_EQ(7, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5934,12 +5934,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 69, nparsed = 69, nread = 69
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r"));
EXPECT_EQ(69, parser.parsed);
EXPECT_EQ(69, (int)parser.parsed);
EXPECT_EQ(69, parser.parser->nread);
// size = 6, nparsed = 6, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\nHello"));
EXPECT_EQ(6, parser.parsed);
EXPECT_EQ(6, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5947,7 +5947,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 75, nparsed = 75, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(75, (int)parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
@ -5955,12 +5955,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// nparsed = 2, size = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, (int)parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 0, nparsed = 1, nread=2
HELPER_EXPECT_FAILED(parser.parse(""));
EXPECT_EQ(1, parser.parsed);
EXPECT_EQ(1, (int)parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
}
@ -5968,12 +5968,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 2, nparsed = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, (int)parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 1, nparsed = 0, nread = 3
HELPER_EXPECT_FAILED(parser.parse("X"));
EXPECT_EQ(0, parser.parsed);
EXPECT_EQ(0, (int)parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
@ -5981,12 +5981,12 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 2, nparsed = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, (int)parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 1, nparsed = 1, nread = 3
HELPER_EXPECT_SUCCESS(parser.parse("T"));
EXPECT_EQ(1, parser.parsed);
EXPECT_EQ(1, (int)parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
@ -5994,7 +5994,7 @@ VOID TEST(ProtocolHTTPTest, HTTPParser)
MockParser parser;
// size = 3, nparsed = 3, nread = 3
HELPER_EXPECT_SUCCESS(parser.parse("GET"));
EXPECT_EQ(3, parser.parsed);
EXPECT_EQ(3, (int)parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
}

@ -1314,7 +1314,7 @@ VOID TEST(ProtocolRTMPTest, HandshakeC0C1)
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c0c1(&io));
EXPECT_EQ(0x01020304, hs.proxy_real_ip);
EXPECT_EQ((uint32_t)0x01020304, (uint32_t)hs.proxy_real_ip);
}
// It's extended c0c1 prefixed with ip, which should be ok.
@ -1330,7 +1330,7 @@ VOID TEST(ProtocolRTMPTest, HandshakeC0C1)
SrsRtmpServer r(&io);
HELPER_EXPECT_SUCCESS(r.hs_bytes->read_c0c1(&io));
EXPECT_EQ(0x01020304, r.proxy_real_ip());
EXPECT_EQ((uint32_t)0x01020304, (uint32_t)r.proxy_real_ip());
}
// It seems a normal c0c1, but it's extended, so it fail.
@ -1751,7 +1751,8 @@ VOID TEST(ProtocolRTMPTest, ServerRedirect)
string host = "target.net";
int port = 8888;
bool accepted = false;
HELPER_EXPECT_SUCCESS(r.redirect(&req, host, port, accepted));
string rurl = srs_generate_rtmp_url(host, port, req.host, req.vhost, req.app, req.stream, req.param);
HELPER_EXPECT_SUCCESS(r.redirect(&req, rurl, accepted));
if (true) {
MockBufferIO tio;
@ -1776,6 +1777,14 @@ VOID TEST(ProtocolRTMPTest, ServerRedirect)
prop = ex->get_property("redirect");
ASSERT_TRUE(prop && prop->is_string());
// The recirect is tcUrl, not RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574995475
EXPECT_STREQ("rtmp://target.net:8888/live", prop->to_str().c_str());
prop = ex->get_property("redirect2");
ASSERT_TRUE(prop && prop->is_string());
// The recirect2 is RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574999798
EXPECT_STREQ("rtmp://target.net:8888/live/livestream", prop->to_str().c_str());
srs_freep(msg);
@ -1808,7 +1817,8 @@ VOID TEST(ProtocolRTMPTest, ServerRedirect)
string host = "target.net";
int port = 8888;
bool accepted = false;
HELPER_EXPECT_SUCCESS(r.redirect(&req, host, port, accepted));
string rurl = srs_generate_rtmp_url(host, port, req.host, req.vhost, req.app, req.stream, req.param);
HELPER_EXPECT_SUCCESS(r.redirect(&req, rurl, accepted));
EXPECT_TRUE(accepted);
if (true) {
@ -1834,6 +1844,14 @@ VOID TEST(ProtocolRTMPTest, ServerRedirect)
prop = ex->get_property("redirect");
ASSERT_TRUE(prop && prop->is_string());
// The recirect is tcUrl, not RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574995475
EXPECT_STREQ("rtmp://target.net:8888/live", prop->to_str().c_str());
prop = ex->get_property("redirect2");
ASSERT_TRUE(prop && prop->is_string());
// The recirect2 is RTMP URL.
// https://github.com/ossrs/srs/issues/1575#issuecomment-574999798
EXPECT_STREQ("rtmp://target.net:8888/live/livestream", prop->to_str().c_str());
srs_freep(msg);

@ -36,6 +36,8 @@ using namespace std;
#include <srs_utest_protocol.hpp>
#include <srs_utest_http.hpp>
#include <srs_service_utility.hpp>
#include <srs_service_http_client.hpp>
#include <srs_service_rtmp_conn.hpp>
#include <sys/socket.h>
#include <netdb.h>
@ -833,6 +835,7 @@ public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread3() : trd("mock", this, 0) {
fd = NULL;
};
virtual ~MockOnCycleThread3() {
trd.stop();
@ -1079,3 +1082,207 @@ VOID TEST(TCPServerTest, CoverUtility)
}
}
class MockOnCycleThread4 : public ISrsCoroutineHandler
{
public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread4() : trd("mock", this, 0) {
fd = NULL;
};
virtual ~MockOnCycleThread4() {
trd.stop();
srs_close_stfd(fd);
}
virtual srs_error_t start(string ip, int port) {
srs_error_t err = srs_success;
if ((err = srs_tcp_listen(ip, port, &fd)) != srs_success) {
return err;
}
return trd.start();
}
virtual srs_error_t do_cycle(srs_netfd_t cfd) {
srs_error_t err = srs_success;
SrsStSocket skt;
if ((err = skt.initialize(cfd)) != srs_success) {
return err;
}
skt.set_recv_timeout(1 * SRS_UTIME_SECONDS);
skt.set_send_timeout(1 * SRS_UTIME_SECONDS);
while (true) {
if ((err = trd.pull()) != srs_success) {
return err;
}
char buf[1024];
if ((err = skt.read(buf, 1024, NULL)) != srs_success) {
return err;
}
string res = mock_http_response(200, "OK");
if ((err = skt.write((char*)res.data(), (int)res.length(), NULL)) != srs_success) {
return err;
}
}
return err;
}
virtual srs_error_t cycle() {
srs_error_t err = srs_success;
srs_netfd_t cfd = srs_accept(fd, NULL, NULL, SRS_UTIME_NO_TIMEOUT);
if (cfd == NULL) {
return err;
}
err = do_cycle(cfd);
srs_close_stfd(cfd);
srs_freep(err);
return err;
}
};
VOID TEST(TCPServerTest, HTTPClientUtility)
{
srs_error_t err;
// Typical HTTP POST.
if (true) {
MockOnCycleThread4 trd;
HELPER_ASSERT_SUCCESS(trd.start("127.0.0.1", 8080));
SrsHttpClient client;
HELPER_ASSERT_SUCCESS(client.initialize("127.0.0.1", 8080, 1*SRS_UTIME_SECONDS));
ISrsHttpMessage* res = NULL;
SrsAutoFree(ISrsHttpMessage, res);
HELPER_ASSERT_SUCCESS(client.post("/api/v1", "", &res));
ISrsHttpResponseReader* br = res->body_reader();
ASSERT_FALSE(br->eof());
ssize_t nn = 0; char buf[1024];
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
HELPER_ASSERT_SUCCESS(br->read(buf, sizeof(buf), &nn));
ASSERT_EQ(2, nn);
EXPECT_STREQ("OK", buf);
}
// Typical HTTP GET.
if (true) {
MockOnCycleThread4 trd;
HELPER_ASSERT_SUCCESS(trd.start("127.0.0.1", 8080));
SrsHttpClient client;
HELPER_ASSERT_SUCCESS(client.initialize("127.0.0.1", 8080, 1*SRS_UTIME_SECONDS));
ISrsHttpMessage* res = NULL;
SrsAutoFree(ISrsHttpMessage, res);
HELPER_ASSERT_SUCCESS(client.get("/api/v1", "", &res));
ISrsHttpResponseReader* br = res->body_reader();
ASSERT_FALSE(br->eof());
ssize_t nn = 0; char buf[1024];
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
HELPER_ASSERT_SUCCESS(br->read(buf, sizeof(buf), &nn));
ASSERT_EQ(2, nn);
EXPECT_STREQ("OK", buf);
}
// Set receive timeout and Kbps ample.
if (true) {
MockOnCycleThread4 trd;
HELPER_ASSERT_SUCCESS(trd.start("127.0.0.1", 8080));
SrsHttpClient client;
HELPER_ASSERT_SUCCESS(client.initialize("127.0.0.1", 8080, 1*SRS_UTIME_SECONDS));
client.set_recv_timeout(1 * SRS_UTIME_SECONDS);
client.set_header("agent", "srs");
ISrsHttpMessage* res = NULL;
SrsAutoFree(ISrsHttpMessage, res);
HELPER_ASSERT_SUCCESS(client.get("/api/v1", "", &res));
ISrsHttpResponseReader* br = res->body_reader();
ASSERT_FALSE(br->eof());
ssize_t nn = 0; char buf[1024];
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
HELPER_ASSERT_SUCCESS(br->read(buf, sizeof(buf), &nn));
ASSERT_EQ(2, nn);
EXPECT_STREQ("OK", buf);
client.kbps_sample("SRS", 0);
}
}
class MockConnectionManager : public IConnectionManager
{
public:
MockConnectionManager() {
}
virtual ~MockConnectionManager() {
}
public:
virtual void remove(ISrsConnection* /*c*/) {
}
};
VOID TEST(TCPServerTest, ContextUtility)
{
if (true) {
SrsThreadContext ctx;
EXPECT_EQ(0, ctx.set_id(100));
EXPECT_EQ(100, ctx.set_id(1000));
EXPECT_EQ(1000, ctx.get_id());
ctx.clear_cid();
EXPECT_EQ(0, ctx.set_id(100));
}
int base_size = 0;
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", 100, "Trace", &size));
base_size = size;
EXPECT_TRUE(base_size > 0);
}
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, "SRS", 100, "Trace", &size));
EXPECT_EQ(base_size, size);
}
if (true) {
errno = 0;
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, NULL, 100, "Trace", &size));
EXPECT_EQ(base_size - 5, size);
}
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, false, NULL, 100, "Trace", &size));
EXPECT_EQ(base_size - 8, size);
}
if (true) {
MockConnectionManager cm;
cm.remove(NULL);
}
if (true) {
srs_utime_t to = 1*SRS_UTIME_SECONDS;
SrsBasicRtmpClient rc("rtmp://127.0.0.1/live/livestream", to, to);
rc.close();
}
}

Loading…
Cancel
Save