srs/trunk/src/utest/srs_utest_config2.cpp
Winlin 35e2808f0c Support IPv6 for all protocols: RTMP, HTTP/HTTPS, WebRTC, SRT, RTSP. v7.0.67 (#4457)
This PR adds comprehensive IPv6 support to SRS for all major protocols,
enabling dual-stack (IPv4/IPv6) operation across the entire streaming
server.

Key Features:

* RTMP/RTMPS: IPv6 support for streaming ingestion and playback
* HTTP/HTTPS: IPv6 support for HTTP-FLV streaming and API endpoints
* WebRTC: IPv6 support for UDP/TCP media transport (WHIP/WHEP)
* SRT: IPv6 support for low-latency streaming
* RTSP: IPv6 support for standards-based streaming

For config, see `conf/console.ipv46.conf` for example.

Publish RTMP or RTMPS via IPv6:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv 'rtmp://[::1]:1935/live/livestream'
ffmpeg -re -i ./doc/source.flv -c copy -f flv 'rtmps://[::1]:1443/live/livestream'
```

Play RTMP or RTMPS stream via IPv6 by ffplay:

```bash
ffplay 'rtmp://[::1]:1935/live/livestream'
ffplay 'rtmps://[::1]:1443/live/livestream'
```

Play by IPv6 via HTTP streaming:
* HTTP-FLV:
[http://[::1]:8080/live/livestream.flv](http://[::1]:8080/players/srs_player.html)
* HTTPS-FLV:
[https://[::1]:8088/live/livestream.flv](https://[::1]:8088/players/srs_player.html)

To access HTTP API via IPv6:

* HTTP API: `curl 'http://[::1]:1985/api/v1/versions'`
* HTTPS API: `curl -k 'https://[::1]:1990/api/v1/versions'`

```json
{
  "code": 0,
  "data": {
    "major": 7,
    "minor": 0,
    "revision": 66,
    "version": "7.0.66"
  }
}
```

Using HTTP API, publish by IPv6 WHIP via
[HTTP](http://[::1]:8080/players/whip.html), and play by
[WHEP](http://[::1]:8080/players/whep.html)

* WHIP: `http://[::1]:1985/rtc/v1/whip/?app=live&stream=livestream`
* WHEP: `http://[::1]:1985/rtc/v1/whep/?app=live&stream=livestream`

Using HTTPS API, publish by IPv6 WHIP via
[WHIP](https://[::1]:8088/players/whip.html), and play by
[WHEP](https://[::1]:8088/players/whep.html)

* WHIP: `https://[::1]:1990/rtc/v1/whip/?app=live&stream=livestream`
* WHEP: `https://[::1]:1990/rtc/v1/whep/?app=live&stream=livestream`

Publish SRT stream by FFmpeg via IPv6:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://[::1]:10080?streamid=#!::r=live/livestream,m=publish'
```

Play SRT stream by ffplay via IPv6:

```bash
ffplay 'srt://[::1]:10080?streamid=#!::r=live/livestream,m=request'
```

Play RTSP stream by ffplay via IPv6:

```bash
ffplay -rtsp_transport tcp -i 'rtsp://[::1]:8554/live/livestream'
```

---------

Co-authored-by: OSSRS-AI <winlinam@gmail.com>
2025-08-30 08:52:21 -04:00

166 lines
7.2 KiB
C++

//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#include <srs_utest_config2.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_file.hpp>
#include <srs_utest_kernel.hpp>
VOID TEST(ConfigMainTest, CheckIncludeEmptyConfig)
{
srs_error_t err;
if (true) {
string filepath = _srs_tmp_file_prefix + "utest-main.conf";
MockFileRemover _mfr(filepath);
string included = _srs_tmp_file_prefix + "utest-included-empty.conf";
MockFileRemover _mfr2(included);
if (true) {
SrsFileWriter fw;
fw.open(included);
}
if (true) {
SrsFileWriter fw;
fw.open(filepath);
string content = _MIN_OK_CONF "include " + included + ";";
fw.write((void *)content.data(), (int)content.length(), NULL);
}
SrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse_file(filepath.c_str()));
EXPECT_EQ(1, (int)conf.get_listens().size());
}
if (true) {
MockSrsConfig conf;
conf.mock_include("test.conf", "");
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "include test.conf;"));
EXPECT_EQ(1, (int)conf.get_listens().size());
}
}
VOID TEST(ConfigMainTest, CheckHttpListenFollow)
{
srs_error_t err;
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;listen 4567;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("1985", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("1985", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("4567", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("4567", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;listen 4567;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("8080", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("8080", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("4567", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("4567", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 8080;https{enabled on;}}http_server{enabled on;https{enabled on;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("8080", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("8080", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("8088", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("8088", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;https{enabled on;}}http_server{enabled on;listen 1985;https{enabled on;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("1985", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("1985", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("8088", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("8088", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("1234", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("1234", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("8088", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("8088", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen 1234;https{enabled on;}}http_server{enabled on;listen 1234;https{enabled on;listen 4567;}}"));
EXPECT_TRUE(conf.get_http_stream_enabled());
// If http API use same port to HTTP server.
EXPECT_EQ(1, (int)conf.get_http_stream_listens().size());
EXPECT_STREQ("1234", conf.get_http_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_http_api_listens().size());
EXPECT_STREQ("1234", conf.get_http_api_listens().at(0).c_str());
// Then HTTPS API should use the same port to HTTPS server.
EXPECT_EQ(1, (int)conf.get_https_stream_listens().size());
EXPECT_STREQ("4567", conf.get_https_stream_listens().at(0).c_str());
EXPECT_EQ(1, (int)conf.get_https_api_listens().size());
EXPECT_STREQ("4567", conf.get_https_api_listens().at(0).c_str());
EXPECT_TRUE(conf.get_http_stream_crossdomain());
}
}