mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
1454 lines
40 KiB
C++
1454 lines
40 KiB
C++
//
|
|
// Copyright (c) 2013-2021 Winlin
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
#include <srs_utest_service.hpp>
|
|
|
|
using namespace std;
|
|
|
|
#include <srs_kernel_error.hpp>
|
|
#include <srs_app_listener.hpp>
|
|
#include <srs_service_st.hpp>
|
|
#include <srs_service_utility.hpp>
|
|
|
|
#include <srs_service_st.hpp>
|
|
#include <srs_service_http_conn.hpp>
|
|
#include <srs_rtmp_stack.hpp>
|
|
#include <srs_core_autofree.hpp>
|
|
#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 <srs_service_conn.hpp>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
|
|
MockSrsConnection::MockSrsConnection()
|
|
{
|
|
do_switch = false;
|
|
}
|
|
|
|
MockSrsConnection::~MockSrsConnection()
|
|
{
|
|
if (do_switch) {
|
|
srs_usleep(0);
|
|
}
|
|
}
|
|
|
|
const SrsContextId& MockSrsConnection::get_id()
|
|
{
|
|
return _srs_context->get_id();
|
|
}
|
|
|
|
std::string MockSrsConnection::desc()
|
|
{
|
|
return "Mock";
|
|
}
|
|
|
|
std::string MockSrsConnection::remote_ip()
|
|
{
|
|
return "127.0.0.1";
|
|
}
|
|
|
|
VOID TEST(ServiceTimeTest, TimeUnit)
|
|
{
|
|
EXPECT_EQ(1000, SRS_UTIME_MILLISECONDS);
|
|
EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS);
|
|
EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES);
|
|
EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS);
|
|
|
|
EXPECT_TRUE(srs_is_never_timeout(SRS_UTIME_NO_TIMEOUT));
|
|
EXPECT_FALSE(srs_is_never_timeout(0));
|
|
}
|
|
|
|
class MockTcpHandler : public ISrsTcpHandler
|
|
{
|
|
private:
|
|
srs_netfd_t fd;
|
|
public:
|
|
MockTcpHandler();
|
|
virtual ~MockTcpHandler();
|
|
public:
|
|
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
|
};
|
|
|
|
MockTcpHandler::MockTcpHandler()
|
|
{
|
|
fd = NULL;
|
|
}
|
|
|
|
MockTcpHandler::~MockTcpHandler()
|
|
{
|
|
srs_close_stfd(fd);
|
|
}
|
|
|
|
srs_error_t MockTcpHandler::on_tcp_client(srs_netfd_t stfd)
|
|
{
|
|
fd = stfd;
|
|
return srs_success;
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, PingPong)
|
|
{
|
|
srs_error_t err;
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
EXPECT_TRUE(l.fd() > 0);
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
EXPECT_TRUE(h.fd != NULL);
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 5, NULL));
|
|
EXPECT_STREQ(buf, "Hello");
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)" ", 1, NULL));
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)"SRS", 3, NULL));
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_SUCCESS(skt.read_fully(buf, 9, NULL));
|
|
EXPECT_STREQ(buf, "Hello SRS");
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello SRS", 9, NULL));
|
|
EXPECT_EQ(9, c.get_send_bytes());
|
|
EXPECT_EQ(0, c.get_recv_bytes());
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == c.get_send_timeout());
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == c.get_recv_timeout());
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 9, NULL));
|
|
EXPECT_STREQ(buf, "Hello SRS");
|
|
EXPECT_EQ(0, skt.get_send_bytes());
|
|
EXPECT_EQ(9, skt.get_recv_bytes());
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_recv_timeout());
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, PingPongWithTimeout)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_FAILED(skt.read(buf, 9, NULL));
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_FAILED(skt.read_fully(buf, 9, NULL));
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
skt.set_recv_timeout(1 * SRS_UTIME_MILLISECONDS);
|
|
|
|
HELPER_EXPECT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_FAILED(skt.read_fully(buf, 9, NULL));
|
|
EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == skt.get_send_timeout());
|
|
EXPECT_TRUE(1*SRS_UTIME_MILLISECONDS == skt.get_recv_timeout());
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, StringIsDigital)
|
|
{
|
|
EXPECT_EQ(0, ::atoi("0"));
|
|
EXPECT_EQ(0, ::atoi("0000000000"));
|
|
EXPECT_EQ(1, ::atoi("01"));
|
|
EXPECT_EQ(12, ::atoi("012"));
|
|
EXPECT_EQ(1234567890L, ::atol("1234567890"));
|
|
EXPECT_EQ(123456789L, ::atol("0123456789"));
|
|
EXPECT_EQ(1234567890, ::atoi("1234567890a"));
|
|
EXPECT_EQ(10, ::atoi("10e3"));
|
|
EXPECT_EQ(0, ::atoi("!1234567890"));
|
|
EXPECT_EQ(0, ::atoi(""));
|
|
|
|
EXPECT_TRUE(srs_is_digit_number("0"));
|
|
EXPECT_TRUE(srs_is_digit_number("0000000000"));
|
|
EXPECT_TRUE(srs_is_digit_number("1234567890"));
|
|
EXPECT_TRUE(srs_is_digit_number("0123456789"));
|
|
EXPECT_FALSE(srs_is_digit_number("1234567890a"));
|
|
EXPECT_FALSE(srs_is_digit_number("a1234567890"));
|
|
EXPECT_FALSE(srs_is_digit_number("10e3"));
|
|
EXPECT_FALSE(srs_is_digit_number("!1234567890"));
|
|
EXPECT_FALSE(srs_is_digit_number(""));
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, StringIsHex)
|
|
{
|
|
if (true) {
|
|
char* str = (char*)"0";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 1, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"0";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 1, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"0000000000";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 10, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"01";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 2, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"012";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x12, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 3, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"1234567890";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1234567890L, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 10, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"0123456789";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x123456789L, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 10, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"1234567890a";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1234567890a, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 11, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"0x1234567890a";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1234567890a, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 13, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"1234567890f";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1234567890f, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 11, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"10e3";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x10e3, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 4, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"!1234567890";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
|
#ifndef SRS_OSX
|
|
EXPECT_EQ(0, errno);
|
|
#endif
|
|
EXPECT_EQ(str, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"1234567890g";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x1234567890, ::strtol(str, &parsed, 16));
|
|
EXPECT_EQ(0, errno);
|
|
EXPECT_EQ(str + 10, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
|
#ifndef SRS_OSX
|
|
EXPECT_EQ(0, errno);
|
|
#endif
|
|
EXPECT_EQ(str, parsed);
|
|
}
|
|
|
|
if (true) {
|
|
char* str = (char*)"1fffffffffffffffffffffffffffff";
|
|
char* parsed = str; errno = 0;
|
|
EXPECT_EQ(0x7fffffffffffffff, ::strtol(str, &parsed, 16));
|
|
EXPECT_NE(0, errno);
|
|
EXPECT_EQ(str+30, parsed);
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, WritevIOVC)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
|
|
iovec iovs[3];
|
|
iovs[0].iov_base = (void*)"H";
|
|
iovs[0].iov_len = 1;
|
|
iovs[1].iov_base = (void*)"e";
|
|
iovs[1].iov_len = 1;
|
|
iovs[2].iov_base = (void*)"llo";
|
|
iovs[2].iov_len = 3;
|
|
|
|
HELPER_EXPECT_SUCCESS(c.writev(iovs, 3, NULL));
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 5, NULL));
|
|
EXPECT_STREQ(buf, "Hello");
|
|
}
|
|
|
|
if (true) {
|
|
MockTcpHandler h;
|
|
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
|
HELPER_EXPECT_SUCCESS(l.listen());
|
|
|
|
SrsTcpClient c(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
|
HELPER_EXPECT_SUCCESS(c.connect());
|
|
|
|
SrsStSocket skt;
|
|
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
|
#ifdef SRS_OSX
|
|
ASSERT_TRUE(h.fd != NULL);
|
|
#endif
|
|
HELPER_EXPECT_SUCCESS(skt.initialize(h.fd));
|
|
|
|
iovec iovs[3];
|
|
iovs[0].iov_base = (void*)"H";
|
|
iovs[0].iov_len = 1;
|
|
iovs[1].iov_base = (void*)NULL;
|
|
iovs[1].iov_len = 0;
|
|
iovs[2].iov_base = (void*)"llo";
|
|
iovs[2].iov_len = 3;
|
|
|
|
HELPER_EXPECT_SUCCESS(c.writev(iovs, 3, NULL));
|
|
|
|
char buf[16] = {0};
|
|
HELPER_EXPECT_SUCCESS(skt.read(buf, 4, NULL));
|
|
EXPECT_STREQ(buf, "Hllo");
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, MessageConnection)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockSrsConnection conn;
|
|
SrsHttpMessage m;
|
|
m.set_connection(&conn);
|
|
EXPECT_TRUE(&conn == m.connection()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?callback=fn&method=POST", true));
|
|
EXPECT_TRUE(m.jsonp); EXPECT_STREQ("POST", m.jsonp_method.c_str()); EXPECT_TRUE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?callback=fn&method=GET", true));
|
|
EXPECT_EQ(SRS_CONSTS_HTTP_GET, m.method()); EXPECT_STREQ("GET", m.method_str().c_str()); EXPECT_TRUE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?callback=fn&method=PUT", true));
|
|
EXPECT_EQ(SRS_CONSTS_HTTP_PUT, m.method()); EXPECT_STREQ("PUT", m.method_str().c_str()); EXPECT_TRUE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?callback=fn&method=POST", true));
|
|
EXPECT_EQ(SRS_CONSTS_HTTP_POST, m.method()); EXPECT_STREQ("POST", m.method_str().c_str()); EXPECT_TRUE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?callback=fn&method=DELETE", true));
|
|
EXPECT_EQ(SRS_CONSTS_HTTP_DELETE, m.method()); EXPECT_STREQ("DELETE", m.method_str().c_str()); EXPECT_TRUE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
m.set_basic(HTTP_REQUEST, 100, 0, 0); EXPECT_STREQ("OTHER", m.method_str().c_str());
|
|
m.set_basic(HTTP_REQUEST, SRS_CONSTS_HTTP_GET, 0, 0); EXPECT_EQ(SRS_CONSTS_HTTP_GET, m.method()); EXPECT_STREQ("GET", m.method_str().c_str());
|
|
m.set_basic(HTTP_REQUEST, SRS_CONSTS_HTTP_PUT, 0, 0); EXPECT_EQ(SRS_CONSTS_HTTP_PUT, m.method()); EXPECT_STREQ("PUT", m.method_str().c_str());
|
|
m.set_basic(HTTP_REQUEST, SRS_CONSTS_HTTP_POST, 0, 0); EXPECT_EQ(SRS_CONSTS_HTTP_POST, m.method()); EXPECT_STREQ("POST", m.method_str().c_str());
|
|
m.set_basic(HTTP_REQUEST, SRS_CONSTS_HTTP_DELETE, 0, 0); EXPECT_EQ(SRS_CONSTS_HTTP_DELETE, m.method()); EXPECT_STREQ("DELETE", m.method_str().c_str());
|
|
m.set_basic(HTTP_REQUEST, SRS_CONSTS_HTTP_OPTIONS, 0, 0); EXPECT_EQ(SRS_CONSTS_HTTP_OPTIONS, m.method()); EXPECT_STREQ("OPTIONS", m.method_str().c_str());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
EXPECT_TRUE(m.is_keep_alive());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv", false));
|
|
EXPECT_STREQ("http://127.0.0.1/live/livestream.flv", m.uri().c_str()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?domain=ossrs.net", false));
|
|
EXPECT_STREQ("ossrs.net", m.host().c_str()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv", false));
|
|
EXPECT_STREQ(".flv", m.ext().c_str()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/v1/streams/100", false));
|
|
EXPECT_STREQ("100", m.parse_rest_id("/v1/streams/").c_str()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/v1/streams/abc", false));
|
|
EXPECT_STREQ("abc", m.parse_rest_id("/v1/streams/").c_str()); EXPECT_FALSE(m.is_jsonp());
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, MessageTurnRequest)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_ASSERT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv", false));
|
|
SrsRequest* r = m.to_request("ossrs.net");
|
|
EXPECT_STREQ("live", r->app.c_str());
|
|
EXPECT_STREQ("livestream", r->stream.c_str());
|
|
EXPECT_STREQ("rtmp://ossrs.net/live", r->tcUrl.c_str());
|
|
srs_freep(r);
|
|
}
|
|
|
|
if (true) {
|
|
SrsHttpMessage m;
|
|
HELPER_ASSERT_SUCCESS(m.set_url("http://127.0.0.1/live/livestream.flv?token=key", false));
|
|
SrsRequest* r = m.to_request("ossrs.net");
|
|
EXPECT_STREQ("rtmp://ossrs.net/live", r->tcUrl.c_str());
|
|
EXPECT_STREQ("?token=key", r->param.c_str());
|
|
srs_freep(r);
|
|
}
|
|
|
|
if (true) {
|
|
MockSrsConnection conn;
|
|
SrsHttpMessage m;
|
|
m.set_connection(&conn);
|
|
|
|
SrsRequest* r = m.to_request("ossrs.net");
|
|
EXPECT_STREQ("127.0.0.1", r->ip.c_str());
|
|
srs_freep(r);
|
|
}
|
|
|
|
if (true) {
|
|
MockSrsConnection conn;
|
|
SrsHttpMessage m;
|
|
m.set_connection(&conn);
|
|
|
|
SrsHttpHeader hdr;
|
|
hdr.set("X-Real-IP", "10.11.12.13");
|
|
m.set_header(&hdr, false);
|
|
|
|
SrsRequest* r = m.to_request("ossrs.net");
|
|
EXPECT_STREQ("10.11.12.13", r->ip.c_str());
|
|
srs_freep(r);
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, ContentLength)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE));
|
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
|
|
|
char buf[32]; ssize_t nread = 0;
|
|
ISrsHttpResponseReader* r = msg->body_reader();
|
|
|
|
io.append("Hello");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 5, &nread));
|
|
EXPECT_EQ(5, nread);
|
|
EXPECT_STREQ("Hello", buf);
|
|
|
|
io.append("World!");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 6, &nread));
|
|
EXPECT_EQ(6, nread);
|
|
EXPECT_STREQ("World!", buf);
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, HTTPChunked)
|
|
{
|
|
srs_error_t err;
|
|
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE));
|
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
|
|
|
char buf[32]; ssize_t nread = 0;
|
|
ISrsHttpResponseReader* r = msg->body_reader();
|
|
|
|
io.append("5\r\nHello\r\n");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 5, &nread));
|
|
EXPECT_EQ(5, nread);
|
|
EXPECT_STREQ("Hello", buf);
|
|
|
|
io.append("6\r\nWorld!\r\n");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 6, &nread));
|
|
EXPECT_EQ(6, nread);
|
|
EXPECT_STREQ("World!", buf);
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, InfiniteChunked)
|
|
{
|
|
srs_error_t err;
|
|
|
|
// For infinite chunked mode, all data is content.
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE));
|
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
|
SrsAutoFree(ISrsHttpMessage, msg);
|
|
|
|
char buf[32]; ssize_t nread = 0;
|
|
ISrsHttpResponseReader* r = msg->body_reader();
|
|
|
|
io.append("Hello");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 5, &nread));
|
|
EXPECT_EQ(5, nread);
|
|
EXPECT_STREQ("Hello", buf);
|
|
|
|
io.append("\r\nWorld!");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 8, &nread));
|
|
EXPECT_EQ(8, nread);
|
|
EXPECT_STREQ("\r\nWorld!", buf);
|
|
|
|
EXPECT_FALSE(r->eof());
|
|
}
|
|
|
|
// If read error, it's EOF.
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE));
|
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
|
|
|
char buf[32]; ssize_t nread = 0;
|
|
ISrsHttpResponseReader* r = msg->body_reader();
|
|
|
|
io.append("Hello");
|
|
HELPER_ARRAY_INIT(buf, sizeof(buf), 0);
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 10, &nread));
|
|
EXPECT_EQ(5, nread);
|
|
EXPECT_STREQ("Hello", buf);
|
|
|
|
io.in_err = srs_error_new(ERROR_SOCKET_READ, "EOF");
|
|
HELPER_ASSERT_SUCCESS(r->read(buf, 10, &nread));
|
|
EXPECT_TRUE(r->eof());
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, OPTIONSRead)
|
|
{
|
|
srs_error_t err;
|
|
|
|
// If request, it has no content-length, not chunked, it's not infinite chunked,
|
|
// actually, it has no body.
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
|
|
ISrsHttpResponseReader* br = req->body_reader();
|
|
EXPECT_TRUE(br->eof());
|
|
}
|
|
|
|
// If response, it has no content-length, not chunked, it's infinite chunked,
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("HTTP/1.1 200 OK\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE));
|
|
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
|
|
ISrsHttpResponseReader* br = req->body_reader();
|
|
EXPECT_FALSE(br->eof());
|
|
}
|
|
|
|
// So if OPTIONS has body, with chunked or content-length, it's ok to parsing it.
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
|
|
ISrsHttpResponseReader* br = req->body_reader();
|
|
EXPECT_FALSE(br->eof());
|
|
|
|
string b; HELPER_ASSERT_SUCCESS(req->body_read_all(b));
|
|
EXPECT_STREQ("Hello", b.c_str());
|
|
|
|
// The body will use as next HTTP request message.
|
|
io.append("GET /rtc/v1/play HTTP/1.1\r\n\r\n");
|
|
ISrsHttpMessage* req2 = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req2));
|
|
SrsAutoFree(ISrsHttpMessage, req2);
|
|
}
|
|
|
|
// So if OPTIONS has body, but not specified the size, we think it has no body,
|
|
// and the body is parsed fail as the next parsing.
|
|
if (true) {
|
|
MockBufferIO io;
|
|
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\n\r\n");
|
|
|
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST));
|
|
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
|
|
SrsAutoFree(ISrsHttpMessage, req);
|
|
|
|
ISrsHttpResponseReader* br = req->body_reader();
|
|
EXPECT_TRUE(br->eof());
|
|
|
|
// The body will use as next HTTP request message.
|
|
io.append("Hello");
|
|
ISrsHttpMessage* req2 = NULL; HELPER_ASSERT_FAILED(hp.parse_message(&io, &req2));
|
|
SrsAutoFree(ISrsHttpMessage, req2);
|
|
}
|
|
}
|
|
|
|
VOID TEST(HTTPServerTest, MessageWritev)
|
|
{
|
|
srs_error_t err;
|
|
|
|
// Directly writev, merge to one chunk.
|
|
if (true) {
|
|
MockResponseWriter w;
|
|
w.write_header(SRS_CONSTS_HTTP_OK);
|
|
|
|
iovec iovs[] = {
|
|
{(char*)"Hello", 5},
|
|
{(char*)"World", 5},
|
|
{(char*)"!", 1},
|
|
};
|
|
HELPER_ASSERT_SUCCESS(w.writev(iovs, 3, NULL));
|
|
|
|
__MOCK_HTTP_EXPECT_STREQ2(200, "b\r\nHelloWorld!\r\n", w);
|
|
}
|
|
|
|
// Use writev to send one iov, should also be ok.
|
|
if (true) {
|
|
MockResponseWriter w;
|
|
|
|
char data[] = "Hello, world!";
|
|
iovec iovs[] = {{(char*)data, (int)(sizeof(data) - 1)}};
|
|
HELPER_ASSERT_SUCCESS(w.writev(iovs, 1, NULL));
|
|
|
|
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
|
|
}
|
|
|
|
// Write header multiple times, should be ok.
|
|
if (true) {
|
|
MockResponseWriter w;
|
|
w.write_header(SRS_CONSTS_HTTP_OK);
|
|
w.write_header(SRS_CONSTS_HTTP_OK);
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, TCPListen)
|
|
{
|
|
srs_error_t err;
|
|
|
|
// Failed for invalid ip.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_EXPECT_FAILED(srs_tcp_listen("10.0.0.abc", 1935, &pfd));
|
|
srs_close_stfd(pfd);
|
|
}
|
|
|
|
// If listen multiple times, should success for we already set the REUSEPORT.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_ASSERT_SUCCESS(srs_tcp_listen("127.0.0.1", 1935, &pfd));
|
|
|
|
srs_netfd_t pfd2 = NULL;
|
|
srs_error_t err2 = srs_tcp_listen("127.0.0.1", 1935, &pfd2);
|
|
|
|
srs_close_stfd(pfd);
|
|
srs_close_stfd(pfd2);
|
|
HELPER_EXPECT_SUCCESS(err2);
|
|
}
|
|
|
|
// Typical listen.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_ASSERT_SUCCESS(srs_tcp_listen("127.0.0.1", 1935, &pfd));
|
|
srs_close_stfd(pfd);
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, UDPListen)
|
|
{
|
|
srs_error_t err;
|
|
|
|
// Failed for invalid ip.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_EXPECT_FAILED(srs_udp_listen("10.0.0.abc", 1935, &pfd));
|
|
srs_close_stfd(pfd);
|
|
}
|
|
|
|
// If listen multiple times, should success for we already set the REUSEPORT.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_ASSERT_SUCCESS(srs_udp_listen("127.0.0.1", 1935, &pfd));
|
|
|
|
srs_netfd_t pfd2 = NULL;
|
|
srs_error_t err2 = srs_udp_listen("127.0.0.1", 1935, &pfd2);
|
|
|
|
srs_close_stfd(pfd);
|
|
srs_close_stfd(pfd2);
|
|
HELPER_EXPECT_SUCCESS(err2);
|
|
}
|
|
|
|
// Typical listen.
|
|
if (true) {
|
|
srs_netfd_t pfd = NULL;
|
|
HELPER_ASSERT_SUCCESS(srs_udp_listen("127.0.0.1", 1935, &pfd));
|
|
srs_close_stfd(pfd);
|
|
}
|
|
}
|
|
|
|
class MockOnCycleThread : public ISrsCoroutineHandler
|
|
{
|
|
public:
|
|
SrsSTCoroutine trd;
|
|
srs_cond_t cond;
|
|
MockOnCycleThread() : trd("mock", this) {
|
|
cond = srs_cond_new();
|
|
};
|
|
virtual ~MockOnCycleThread() {
|
|
srs_cond_destroy(cond);
|
|
}
|
|
virtual srs_error_t cycle() {
|
|
srs_error_t err = srs_success;
|
|
|
|
for (;;) {
|
|
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
|
srs_cond_signal(cond);
|
|
// If no one waiting on the cond, directly return event signal more than one time.
|
|
// If someone waiting, signal them more than one time.
|
|
srs_cond_signal(cond);
|
|
|
|
if ((err = trd.pull()) != srs_success) {
|
|
return err;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
};
|
|
|
|
VOID TEST(TCPServerTest, ThreadCondWait)
|
|
{
|
|
MockOnCycleThread trd;
|
|
trd.trd.start();
|
|
|
|
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
|
|
srs_cond_wait(trd.cond);
|
|
trd.trd.stop();
|
|
}
|
|
|
|
class MockOnCycleThread2 : public ISrsCoroutineHandler
|
|
{
|
|
public:
|
|
SrsSTCoroutine trd;
|
|
srs_mutex_t lock;
|
|
MockOnCycleThread2() : trd("mock", this) {
|
|
lock = srs_mutex_new();
|
|
};
|
|
virtual ~MockOnCycleThread2() {
|
|
srs_mutex_destroy(lock);
|
|
}
|
|
virtual srs_error_t cycle() {
|
|
srs_error_t err = srs_success;
|
|
|
|
for (;;) {
|
|
srs_mutex_lock(lock);
|
|
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
|
srs_mutex_unlock(lock);
|
|
|
|
srs_error_t err = trd.pull();
|
|
if (err != srs_success) {
|
|
return err;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
};
|
|
|
|
VOID TEST(TCPServerTest, ThreadMutexWait)
|
|
{
|
|
MockOnCycleThread2 trd;
|
|
trd.trd.start();
|
|
|
|
srs_usleep(20 * SRS_UTIME_MILLISECONDS);
|
|
|
|
srs_mutex_lock(trd.lock);
|
|
trd.trd.stop();
|
|
srs_mutex_unlock(trd.lock);
|
|
}
|
|
|
|
class MockOnCycleThread3 : public ISrsCoroutineHandler
|
|
{
|
|
public:
|
|
SrsSTCoroutine trd;
|
|
srs_netfd_t fd;
|
|
MockOnCycleThread3() : trd("mock", this) {
|
|
fd = NULL;
|
|
};
|
|
virtual ~MockOnCycleThread3() {
|
|
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[5];
|
|
if ((err = skt.read_fully(buf, 5, NULL)) != srs_success) {
|
|
return err;
|
|
}
|
|
if ((err = skt.write(buf, 5, 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, TCPClientServer)
|
|
{
|
|
srs_error_t err;
|
|
|
|
MockOnCycleThread3 trd;
|
|
HELPER_ASSERT_SUCCESS(trd.start("127.0.0.1", 1935));
|
|
|
|
SrsTcpClient c("127.0.0.1", 1935, 1 * SRS_UTIME_SECONDS);
|
|
HELPER_ASSERT_SUCCESS(c.connect());
|
|
|
|
c.set_recv_timeout(1 * SRS_UTIME_SECONDS);
|
|
c.set_send_timeout(1 * SRS_UTIME_SECONDS);
|
|
|
|
if (true) {
|
|
HELPER_ASSERT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
|
|
char buf[6]; HELPER_ARRAY_INIT(buf, 6, 0);
|
|
HELPER_ASSERT_SUCCESS(c.read(buf, 5, NULL));
|
|
EXPECT_STREQ("Hello", buf);
|
|
}
|
|
|
|
if (true) {
|
|
HELPER_ASSERT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
|
|
char buf[6]; HELPER_ARRAY_INIT(buf, 6, 0);
|
|
HELPER_ASSERT_SUCCESS(c.read_fully(buf, 5, NULL));
|
|
EXPECT_STREQ("Hello", buf);
|
|
}
|
|
|
|
if (true) {
|
|
HELPER_ASSERT_SUCCESS(c.write((void*)"Hello", 5, NULL));
|
|
|
|
char buf[6]; HELPER_ARRAY_INIT(buf, 6, 0);
|
|
ASSERT_EQ(5, srs_read(c.stfd, buf, 5, 1*SRS_UTIME_SECONDS));
|
|
EXPECT_STREQ("Hello", buf);
|
|
}
|
|
}
|
|
|
|
VOID TEST(TCPServerTest, CoverUtility)
|
|
{
|
|
EXPECT_TRUE(srs_string_is_http("http://"));
|
|
EXPECT_TRUE(srs_string_is_http("https://"));
|
|
EXPECT_TRUE(srs_string_is_http("http://localhost"));
|
|
EXPECT_TRUE(srs_string_is_http("https://localhost"));
|
|
EXPECT_FALSE(srs_string_is_http("ftp://"));
|
|
EXPECT_FALSE(srs_string_is_http("ftps://"));
|
|
EXPECT_FALSE(srs_string_is_http("http:"));
|
|
EXPECT_FALSE(srs_string_is_http("https:"));
|
|
EXPECT_TRUE(srs_string_is_rtmp("rtmp://"));
|
|
EXPECT_TRUE(srs_string_is_rtmp("rtmp://localhost"));
|
|
EXPECT_FALSE(srs_string_is_rtmp("http://"));
|
|
EXPECT_FALSE(srs_string_is_rtmp("rtmp:"));
|
|
|
|
// ipv4 loopback
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("127.0.0.1", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
// ipv4 intranet
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("192.168.0.1", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
if (true) {
|
|
sockaddr_in addr;
|
|
addr.sin_family = AF_INET;
|
|
|
|
addr.sin_addr.s_addr = htonl(0x12000000);
|
|
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0x7f000000);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0x7f000001);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0x0a000000);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0x0a000001);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0x0affffff);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0xc0a80000);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0xc0a80001);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
|
|
addr.sin_addr.s_addr = htonl(0xc0a8ffff);
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)&addr));
|
|
}
|
|
|
|
// Normal ipv6 address.
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("2001:da8:6000:291:21f:d0ff:fed4:928c", NULL, &hints, &r));
|
|
|
|
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("3ffe:dead:beef::1", NULL, &hints, &r));
|
|
|
|
EXPECT_TRUE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
// IN6_IS_ADDR_UNSPECIFIED
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("::", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
// IN6_IS_ADDR_SITELOCAL
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("fec0::", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
// IN6_IS_ADDR_LINKLOCAL
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("FE80::", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
|
|
// IN6_IS_ADDR_LINKLOCAL
|
|
if (true) {
|
|
addrinfo hints;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
|
|
addrinfo* r = NULL;
|
|
SrsAutoFree(addrinfo, r);
|
|
ASSERT_TRUE(!getaddrinfo("::1", NULL, &hints, &r));
|
|
|
|
EXPECT_FALSE(srs_net_device_is_internet((sockaddr*)r->ai_addr));
|
|
}
|
|
}
|
|
|
|
class MockOnCycleThread4 : public ISrsCoroutineHandler
|
|
{
|
|
public:
|
|
SrsSTCoroutine trd;
|
|
srs_netfd_t fd;
|
|
MockOnCycleThread4() : trd("mock", this) {
|
|
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(HTTPClientTest, 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("http", "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("http", "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("http", "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 ISrsResourceManager
|
|
{
|
|
public:
|
|
MockConnectionManager() {
|
|
}
|
|
virtual ~MockConnectionManager() {
|
|
}
|
|
public:
|
|
virtual void remove(ISrsResource* /*c*/) {
|
|
}
|
|
};
|
|
|
|
VOID TEST(TCPServerTest, ContextUtility)
|
|
{
|
|
if (true) {
|
|
SrsThreadContext ctx;
|
|
|
|
if (true) {
|
|
SrsContextId cid;
|
|
EXPECT_TRUE(!ctx.set_id(cid.set_value("100")).compare(cid));
|
|
}
|
|
if (true) {
|
|
SrsContextId cid;
|
|
EXPECT_TRUE(!ctx.set_id(cid.set_value("1000")).compare(cid));
|
|
}
|
|
if (true) {
|
|
SrsContextId cid;
|
|
EXPECT_TRUE(!ctx.get_id().compare(cid.set_value("1000")));
|
|
}
|
|
|
|
ctx.clear_cid();
|
|
if (true) {
|
|
SrsContextId cid;
|
|
EXPECT_TRUE(!ctx.set_id(cid.set_value("100")).compare(cid));
|
|
}
|
|
}
|
|
|
|
SrsContextId cid;
|
|
cid.set_value("100");
|
|
|
|
int base_size = 0;
|
|
if (true) {
|
|
errno = 0;
|
|
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
|
|
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", cid, "Trace", &size));
|
|
base_size = size;
|
|
EXPECT_TRUE(base_size > 0);
|
|
}
|
|
|
|
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, "SRS", cid, "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, cid, "Trace", &size));
|
|
EXPECT_EQ(base_size - 5, 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, false, NULL, cid, "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();
|
|
}
|
|
}
|
|
|