diff --git a/README.md b/README.md index 930a8dd1f..dc95a7f4c 100755 --- a/README.md +++ b/README.md @@ -94,12 +94,8 @@ For previous versions, please read: - [x] Support native HTTP server([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP]) for http api and http live streaming. - [x] Support HTTP CORS for js in http api and http live streaming. - [x] Support HTTP API([CN][v3_CN_HTTPApi], [EN][v3_EN_HTTPApi]) for system management. -- [x] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319]. - [x] Support HTTP callback([CN][v3_CN_HTTPCallback], [EN][v3_EN_HTTPCallback]) for authentication and integration. -- [x] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]) -- [x] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication. - [x] Support DVR([CN][v3_CN_DVR], [EN][v3_EN_DVR]) to record live streaming to FLV file. -- [x] Support DVR in MP4 format, read [#738][bug #738]. - [x] Support DVR control module like NGINX-RTMP, please read [#459][bug #459]. - [x] Support EXEC like NGINX-RTMP, please read [bug #367][bug #367]. - [x] Support security strategy including allow/deny publish/play IP([CN][v2_CN_Security], [EN][v2_EN_Security]). @@ -107,7 +103,6 @@ For previous versions, please read: - [x] Support gop-cache([CN][v3_CN_LowLatency2], [EN][v3_EN_LowLatency2]) for player fast startup. - [x] Support Vhost([CN][v1_CN_RtmpUrlVhost], [EN][v1_EN_RtmpUrlVhost]) and \_\_defaultVhost\_\_. - [x] Support reloading([CN][v1_CN_Reload], [EN][v1_EN_Reload]) to apply changes of config. -- [x] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]) and flash client example. - [x] Support listening at multiple ports. - [x] Support forwarding([CN][v3_CN_Forward], [EN][v3_EN_Forward]) from master to slave server. - [x] Support transcoding([CN][v3_CN_FFMPEG], [EN][v3_EN_FFMPEG]) live streaming by FFMPEG. @@ -121,13 +116,19 @@ 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] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]). +- [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]. - [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250]. - [x] [Experimental] Support pushing RTSP, please read [bug #133][bug #133]. - [x] [Experimental] Support pushing FLV over HTTP POST, please read [wiki]([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]). - [x] [Experimental] Support multiple processes by [dolphin][srs-dolphin] or [oryx][oryx]. - [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb]. +- [x] [Experimental] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]) +- [x] [Experimental] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319]. +- [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. @@ -147,6 +148,10 @@ For previous versions, please read: ## V3 changes +* v3.0, 2019-12-23, Merge SRS2 for running srs-librtmp on Windows. 3.0.80 +* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe FMS/AMS edge token traversing([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication. 3.0.79 +* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate BWT(bandwidth testing)([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]). 3.0.78 +* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe HDS(f4m)([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]). 3.0.77 * v3.0, 2019-12-20, Fix [#1508][bug #1508], http-client support read chunked response. 3.0.76 * v3.0, 2019-12-20, For [#1508][bug #1508], refactor srs_is_digital, support all zeros. * v3.0, 2019-12-19, [3.0 alpha5(3.0.75)][r3.0a5] released. 115362 lines. @@ -248,6 +253,8 @@ For previous versions, please read: ## V2 changes +* 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 +* v2.0, 2019-12-23, Fix [srs-librtmp #25](https://github.com/ossrs/srs-librtmp/issues/25), build srs-librtmp on windows. 2.0.267 * v2.0, 2019-12-13, Support openssl versions greater than 1.1.0. 2.0.266 * v2.0, 2019-11-29, [2.0 release7(2.0.265)][r2.0r7] released. 86994 lines. * v2.0, 2019-11-29, For [srs-docker](https://github.com/ossrs/srs-docker/tree/master/2.0), install Cherrypy without sudo. 2.0.265 @@ -1546,6 +1553,7 @@ Winlin [bug #1520]: https://github.com/ossrs/srs/issues/1520 [bug #1223]: https://github.com/ossrs/srs/issues/1223 [bug #1508]: https://github.com/ossrs/srs/issues/1508 +[bug #1535]: https://github.com/ossrs/srs/issues/1535 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [bug #1111]: https://github.com/ossrs/srs/issues/1111 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index ad70e2fa2..7ba2c3062 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 76 +#define VERSION_REVISION 80 // The macros generated by configure script. #include @@ -93,10 +93,13 @@ } \ (void)0 -// Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm -// @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 -#if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) - #error "only support i386/amd64/x86_64/arm cpu" +// For librtmp, it is pure c++ and supports all OS. +#ifndef SRS_EXPORT_LIBRTMP + // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm + // @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 + #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) + #error "only support i386/amd64/x86_64/arm cpu" + #endif #endif // Error predefined for all modules. diff --git a/trunk/src/kernel/srs_kernel_file.cpp b/trunk/src/kernel/srs_kernel_file.cpp index 832b7727b..6ab9b6a54 100644 --- a/trunk/src/kernel/srs_kernel_file.cpp +++ b/trunk/src/kernel/srs_kernel_file.cpp @@ -129,7 +129,11 @@ srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) ssize_t nwrite; // TODO: FIXME: use st_write. +#ifdef _WIN32 + if ((nwrite = ::_write(fd, buf, (unsigned int)count)) < 0) { +#else if ((nwrite = _srs_write_fn(fd, buf, count)) < 0) { +#endif return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path.c_str()); } @@ -269,7 +273,11 @@ srs_error_t SrsFileReader::read(void* buf, size_t count, ssize_t* pnread) ssize_t nread; // TODO: FIXME: use st_read. +#ifdef _WIN32 + if ((nread = _read(fd, buf, (unsigned int)count)) < 0) { +#else if ((nread = _srs_read_fn(fd, buf, count)) < 0) { +#endif return srs_error_new(ERROR_SYSTEM_FILE_READ, "read from file %s failed", path.c_str()); } diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index b1f8a0cdd..4fab6985a 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -572,7 +572,7 @@ int srs_do_create_dir_recursively(string dir) mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH; if (::mkdir(dir.c_str(), mode) < 0) { #else - if (::mkdir(dir.c_str()) < 0) { + if (::_mkdir(dir.c_str()) < 0) { #endif if (errno == EEXIST) { return ERROR_SYSTEM_DIR_EXISTS; @@ -1102,9 +1102,9 @@ int srs_chunk_header_c0(int perfer_cid, uint32_t timestamp, int32_t payload_leng *p++ = pp[1]; *p++ = pp[0]; } else { - *p++ = 0xFF; - *p++ = 0xFF; - *p++ = 0xFF; + *p++ = (char)0xFF; + *p++ = (char)0xFF; + *p++ = (char)0xFF; } // message_length, 3bytes, big-endian diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index 76dfe3bdc..fb3249cfc 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -92,7 +92,7 @@ struct SrsBlockSyncSocket SOCKET_RESET(fd); SOCKET_SETUP(); } - + virtual ~SrsBlockSyncSocket() { SOCKET_CLOSE(fd); SOCKET_CLEANUP(); @@ -121,7 +121,7 @@ int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner) if (!SOCKET_VALID(skt->fd)) { return ERROR_SOCKET_CREATE; } - + // No TCP cache. int v = 1; setsockopt(skt->fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); @@ -163,7 +163,7 @@ int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nre if (nread) { *nread = nb_read; } - + // On success a non-negative integer indicating the number of bytes actually read is returned // (a value of 0 means the network connection is closed or end of file is reached). if (nb_read <= 0) { @@ -185,7 +185,15 @@ int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nre int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm) { SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - + +#ifdef _WIN32 + DWORD tv = (DWORD)(timeout_us/1000); + + // To convert tv to const char* to make VS2015 happy. + if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } +#else // The default for this option is zero, // which indicates that a receive operation shall not time out. int32_t sec = 0; @@ -200,9 +208,10 @@ int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm) if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { return SOCKET_ERRNO(); } - +#endif + skt->rtm = tm; - + return ERROR_SUCCESS; } int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx) @@ -218,21 +227,30 @@ int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx) int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm) { SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - + +#ifdef _WIN32 + DWORD tv = (DWORD)(timeout_us/1000); + + // To convert tv to const char* to make VS2015 happy. + if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } +#else // The default for this option is zero, // which indicates that a receive operation shall not time out. int32_t sec = 0; int32_t usec = 0; - + if (tm != SRS_UTIME_NO_TIMEOUT) { sec = (int32_t)(tm / 1000); usec = (int32_t)((tm % 1000)*1000); } - + struct timeval tv = { sec , usec }; if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { return SOCKET_ERRNO(); } +#endif skt->stm = tm; @@ -271,7 +289,7 @@ int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ss return ERROR_SOCKET_WRITE; } - + skt->sbytes += nb_write; return ret; diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index d8430188f..143dc426e 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -44,21 +44,24 @@ *************************************************************/ // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifdef _WIN32 +// To disable some security warnings. +#define _CRT_SECURE_NO_WARNINGS // include windows first. #include // the type used by this header for windows. +#if defined(_MSC_VER) + #include +#else + typedef char int8_t; + typedef short int16_t; + typedef int int32_t; + typedef long long int64_t; +#endif typedef unsigned long long u_int64_t; -typedef u_int64_t uint64_t; -typedef long long int64_t; typedef unsigned int u_int32_t; typedef u_int32_t uint32_t; -typedef int int32_t; typedef unsigned char u_int8_t; -typedef u_int8_t uint8_t; -typedef char int8_t; typedef unsigned short u_int16_t; -typedef u_int16_t uint16_t; -typedef short int16_t; typedef int64_t ssize_t; struct iovec { void *iov_base; /* Starting address */ @@ -1175,8 +1178,6 @@ extern int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssiz *************************************************************/ // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifdef _WIN32 -// for time. -#define _CRT_SECURE_NO_WARNINGS #include int gettimeofday(struct timeval* tv, struct timezone* tz); #define PRId64 "lld" @@ -1205,8 +1206,6 @@ typedef int mode_t; #define open _open #define close _close #define lseek _lseek -#define write _write -#define read _read // for socket. ssize_t writev(int fd, const struct iovec *iov, int iovcnt); diff --git a/trunk/src/protocol/srs_protocol_amf0.cpp b/trunk/src/protocol/srs_protocol_amf0.cpp index 9fc5a3bcc..ae98a41c2 100644 --- a/trunk/src/protocol/srs_protocol_amf0.cpp +++ b/trunk/src/protocol/srs_protocol_amf0.cpp @@ -1169,7 +1169,7 @@ void SrsAmf0StrictArray::append(SrsAmf0Any* any) int SrsAmf0Size::utf8(string value) { - return 2 + (int)value.length(); + return (int)(2 + value.length()); } int SrsAmf0Size::str(string value) @@ -1752,7 +1752,7 @@ namespace _srs_internal if (!stream->require(2)) { return srs_error_new(ERROR_RTMP_AMF0_ENCODE, "requires 2 only %d bytes", stream->left()); } - stream->write_2bytes(value.length()); + stream->write_2bytes((int16_t)value.length()); // empty string if (value.length() <= 0) { diff --git a/trunk/src/protocol/srs_protocol_stream.cpp b/trunk/src/protocol/srs_protocol_stream.cpp index dfc24d7e2..96a55c265 100755 --- a/trunk/src/protocol/srs_protocol_stream.cpp +++ b/trunk/src/protocol/srs_protocol_stream.cpp @@ -194,7 +194,7 @@ srs_error_t SrsFastStream::grow(ISrsReader* reader, int required_size) // we just move the ptr to next. srs_assert((int)nread > 0); end += nread; - nb_free_space -= nread; + nb_free_space -= (int)nread; } return err; diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index 5095290bc..1044236a3 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -61,6 +61,7 @@ void srs_vhost_resolve(string& vhost, string& app, string& param) app = srs_string_replace(app, ",", "?"); app = srs_string_replace(app, "...", "?"); app = srs_string_replace(app, "&&", "?"); + app = srs_string_replace(app, "&", "?"); app = srs_string_replace(app, "=", "?"); if (srs_string_ends_with(app, "/_definst_")) { @@ -78,6 +79,11 @@ void srs_vhost_resolve(string& vhost, string& app, string& param) } } } + + // vhost with params. + if ((pos = vhost.find("?")) != std::string::npos) { + vhost = vhost.substr(0, pos); + } /* others */ } diff --git a/trunk/src/protocol/srs_raw_avc.cpp b/trunk/src/protocol/srs_raw_avc.cpp index b09479a3a..6b8f24b9a 100644 --- a/trunk/src/protocol/srs_raw_avc.cpp +++ b/trunk/src/protocol/srs_raw_avc.cpp @@ -183,7 +183,7 @@ srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32 // numOfSequenceParameterSets, always 1 stream.write_1bytes(0x01); // sequenceParameterSetLength - stream.write_2bytes(sps.length()); + stream.write_2bytes((int16_t)sps.length()); // sequenceParameterSetNALUnit stream.write_string(sps); } @@ -194,7 +194,7 @@ srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32 // numOfPictureParameterSets, always 1 stream.write_1bytes(0x01); // pictureParameterSetLength - stream.write_2bytes(pps.length()); + stream.write_2bytes((int16_t)pps.length()); // pictureParameterSetNALUnit stream.write_string(pps); } diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 89105bf6f..b59a41a83 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -220,7 +220,8 @@ srs_error_t SrsPacket::encode_packet(SrsBuffer* stream) SrsProtocol::AckWindowSize::AckWindowSize() { window = 0; - sequence_number = nb_recv_bytes = 0; + sequence_number = 0; + nb_recv_bytes = 0; } SrsProtocol::SrsProtocol(ISrsProtocolReadWriter* io) @@ -253,6 +254,8 @@ SrsProtocol::SrsProtocol(ISrsProtocolReadWriter* io) cs_cache[cid] = cs; } + + out_c0c3_caches = new char[SRS_CONSTS_C0C3_HEADERS_MAX]; } SrsProtocol::~SrsProtocol() @@ -291,6 +294,8 @@ SrsProtocol::~SrsProtocol() srs_freep(cs); } srs_freepa(cs_cache); + + srs_freepa(out_c0c3_caches); } void SrsProtocol::set_auto_response(bool v) @@ -2375,7 +2380,8 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser srs_error_t err = srs_success; SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket(); - + + // @remark For windows, there must be a space between const string and macro. pkt->props->set("fmsVer", SrsAmf0Any::str("FMS/" RTMP_SIG_FMS_VER)); pkt->props->set("capabilities", SrsAmf0Any::number(127)); pkt->props->set("mode", SrsAmf0Any::number(1)); diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 79122f3d9..3a64d47bc 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -213,7 +213,8 @@ private: // The c0c3 caches must use unit SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE bytes. // // @remark, the c0c3 cache cannot be realloc. - char out_c0c3_caches[SRS_CONSTS_C0C3_HEADERS_MAX]; + // To allocate it in heap to make VS2015 happy. + char* out_c0c3_caches; // Whether warned user to increase the c0c3 header cache. bool warned_c0c3_cache_dry; // The output chunk size, default to 128, set by config. diff --git a/trunk/src/utest/srs_utest_rtmp.cpp b/trunk/src/utest/srs_utest_rtmp.cpp index 639f2ab70..09ea6cd5c 100644 --- a/trunk/src/utest/srs_utest_rtmp.cpp +++ b/trunk/src/utest/srs_utest_rtmp.cpp @@ -3271,6 +3271,34 @@ VOID TEST(ProtocolRTMPTest, GenerateURL) */ VOID TEST(ProtocolRTMPTest, DiscoveryTcUrl) { + // vhost and params + if (true) { + int port; std::string tcUrl, schema, ip, vhost, app, stream, param; + + tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo&token=abc"; stream= "show"; + srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param); + EXPECT_STREQ("rtmp", schema.c_str()); + EXPECT_STREQ("127.0.0.1", ip.c_str()); + EXPECT_STREQ("demo", vhost.c_str()); + EXPECT_STREQ("live", app.c_str()); + EXPECT_STREQ("show", stream.c_str()); + EXPECT_EQ(19351, port); + } + + // vhost and params + if (true) { + int port; std::string tcUrl, schema, ip, vhost, app, stream, param; + + tcUrl = "rtmp://127.0.0.1:19351/live"; stream= "show?vhost=demo&token=abc"; + srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param); + EXPECT_STREQ("rtmp", schema.c_str()); + EXPECT_STREQ("127.0.0.1", ip.c_str()); + EXPECT_STREQ("demo", vhost.c_str()); + EXPECT_STREQ("live", app.c_str()); + EXPECT_STREQ("show", stream.c_str()); + EXPECT_EQ(19351, port); + } + // default vhost in param if (true) { int port; std::string tcUrl, schema, ip, vhost, app, stream, param;