Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support include directive for config file #2878

Merged
merged 20 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions trunk/conf/include_test/include.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# the config for srs to test include function

listen 1935;
include ./conf/include_test/include_1.conf;
19 changes: 19 additions & 0 deletions trunk/conf/include_test/include_1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
max_connections 1000;
daemon off;
srs_log_tank console;

http_server {
enabled on;
listen xxx;
dir xxx2;
}
vhost ossrs.net {
hls {
enabled on;
hls_path xxx;
hls_m3u8_file xxx1;
hls_ts_file xxx2;
hls_fragment 10;
hls_window 60;
}
}
13 changes: 13 additions & 0 deletions trunk/conf/include_test/include_2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;

http_server {
enabled on;
listen xxx;
dir xxx2;
}
vhost ossrs.net {
include ./conf/include_test/include_3.conf;
}
8 changes: 8 additions & 0 deletions trunk/conf/include_test/include_3.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
hls {
enabled on;
hls_path xxx;
hls_m3u8_file xxx1;
hls_ts_file xxx2;
hls_fragment 10;
hls_window 60;
}
14 changes: 14 additions & 0 deletions trunk/conf/include_test/include_4.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# the config for srs to test include function

listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;

include ./conf/include_test/include_5.conf;

vhost ossrs.net {
include ./conf/include_test/include_3.conf;
}

include ./conf/include_test/include_6.conf;
5 changes: 5 additions & 0 deletions trunk/conf/include_test/include_5.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
http_server {
enabled on;
listen xxx;
dir xxx2;
}
4 changes: 4 additions & 0 deletions trunk/conf/include_test/include_6.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
http_api {
enabled on;
listen xxx;
}
90 changes: 73 additions & 17 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,9 @@ bool SrsConfDirective::is_stream_caster()
return name == "stream_caster";
}

srs_error_t SrsConfDirective::parse(SrsConfigBuffer* buffer)
srs_error_t SrsConfDirective::parse(SrsConfigBuffer* buffer, SrsConfig* conf)
{
return parse_conf(buffer, parse_file);
return parse_conf(buffer, parse_file, conf);
}

srs_error_t SrsConfDirective::persistence(SrsFileWriter* writer, int level)
Expand Down Expand Up @@ -971,7 +971,7 @@ SrsJsonAny* SrsConfDirective::dumps_arg0_to_boolean()
// LCOV_EXCL_STOP

// see: ngx_conf_parse
srs_error_t SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type)
srs_error_t SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type, SrsConfig* conf)
{
srs_error_t err = srs_success;

Expand Down Expand Up @@ -1013,19 +1013,51 @@ srs_error_t SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveTy
}

// build directive tree.
SrsConfDirective* directive = new SrsConfDirective();

directive->conf_line = line_start;
directive->name = args[0];
args.erase(args.begin());
directive->args.swap(args);

directives.push_back(directive);

if (srs_error_code(err) == ERROR_SYSTEM_CONFIG_BLOCK_START) {
srs_freep(err);
if ((err = directive->parse_conf(buffer, parse_block)) != srs_success) {
return srs_error_wrap(err, "parse dir");
if (args.at(0) == "include") {
if (args.size() < 2) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: include is empty directive", buffer->line);
}

for (int i = 1; i < (int)args.size(); i++) {
std::string file = args.at(i);

srs_trace("config parse include %s", file.c_str());
srs_freep(err);
if (type != parse_block) {
if ((err = conf->parse_include_file(file.c_str())) != srs_success) {
return srs_error_wrap(err, "parse file");
}
} else {
if (file.empty()) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "empty include config");
}

SrsConfigBuffer buffer;

if ((err = buffer.fullfill(file.c_str())) != srs_success) {
return srs_error_wrap(err, "buffer fullfil");
}

if ((err = parse_conf(&buffer, parse_file, conf)) != srs_success) {
return srs_error_wrap(err, "parse include buffer");
}
}
}
} else {
SrsConfDirective* directive = new SrsConfDirective();

directive->conf_line = line_start;
directive->name = args[0];
args.erase(args.begin());
directive->args.swap(args);

directives.push_back(directive);

if (srs_error_code(err) == ERROR_SYSTEM_CONFIG_BLOCK_START) {
srs_freep(err);
if ((err = directive->parse_conf(buffer, parse_block, conf)) != srs_success) {
return srs_error_wrap(err, "parse dir");
}
}
}
srs_freep(err);
Expand Down Expand Up @@ -2419,6 +2451,30 @@ srs_error_t SrsConfig::parse_file(const char* filename)

return err;
}

srs_error_t SrsConfig::parse_include_file(const char *filename)
{
srs_error_t err = srs_success;

std::string include_file = filename;

if (include_file.empty()) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "empty include config");
}

SrsConfigBuffer buffer;

if ((err = buffer.fullfill(include_file.c_str())) != srs_success) {
return srs_error_wrap(err, "buffer fullfil");
}

// Parse root tree from buffer.
if ((err = root->parse(&buffer, this)) != srs_success) {
return srs_error_wrap(err, "parse include buffer");
}

return err;
}
// LCOV_EXCL_STOP

srs_error_t SrsConfig::check_config()
Expand Down Expand Up @@ -2955,7 +3011,7 @@ srs_error_t SrsConfig::parse_buffer(SrsConfigBuffer* buffer)
root = new SrsConfDirective();

// Parse root tree from buffer.
if ((err = root->parse(buffer)) != srs_success) {
if ((err = root->parse(buffer, this)) != srs_success) {
return srs_error_wrap(err, "root parse");
}

Expand Down
6 changes: 4 additions & 2 deletions trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ class SrsConfDirective
// Parse utilities
public:
// Parse config directive from file buffer.
virtual srs_error_t parse(srs_internal::SrsConfigBuffer* buffer);
virtual srs_error_t parse(srs_internal::SrsConfigBuffer* buffer, SrsConfig* conf = NULL);
// Marshal the directive to writer.
// @param level, the root is level0, all its directives are level1, and so on.
virtual srs_error_t persistence(SrsFileWriter* writer, int level);
Expand All @@ -234,7 +234,7 @@ class SrsConfDirective
// 1. read a token(directive args and a ret flag),
// 2. initialize the directive by args, args[0] is name, args[1-N] is args of directive,
// 3. if ret flag indicates there are child-directives, read_conf(directive, block) recursively.
virtual srs_error_t parse_conf(srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type);
virtual srs_error_t parse_conf(srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type, SrsConfig* conf);
// Read a token from buffer.
// A token, is the directive args and a flag indicates whether has child-directives.
// @param args, the output directive args, the first is the directive name, left is the args.
Expand Down Expand Up @@ -356,6 +356,8 @@ class SrsConfig
public:
// Parse the config file, which is specified by cli.
virtual srs_error_t parse_file(const char* filename);
// Parse the include config file.
virtual srs_error_t parse_include_file(const char* filename);
// Check the parsed config.
virtual srs_error_t check_config();
protected:
Expand Down
95 changes: 95 additions & 0 deletions trunk/src/utest/srs_utest_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3622,3 +3622,98 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5)
}
}

VOID TEST(ConfigMainTest, CheckIncludeConfig)
{
srs_error_t err;

if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include.conf;"));

vector<string> listens = conf.get_listens();
EXPECT_EQ(1, (int)listens.size());
EXPECT_STREQ("1935", listens.at(0).c_str());

EXPECT_FALSE(conf.get_log_tank_file());

EXPECT_TRUE(conf.get_http_stream_enabled());
EXPECT_STREQ("xxx", conf.get_http_stream_listen().c_str());
EXPECT_STREQ("xxx2", conf.get_http_stream_dir().c_str());

EXPECT_TRUE(conf.get_hls_enabled("ossrs.net"));
EXPECT_STREQ("xxx", conf.get_hls_path("ossrs.net").c_str());
EXPECT_STREQ("xxx1", conf.get_hls_m3u8_file("ossrs.net").c_str());
EXPECT_STREQ("xxx2", conf.get_hls_ts_file("ossrs.net").c_str());
EXPECT_EQ(10*SRS_UTIME_SECONDS, conf.get_hls_fragment("ossrs.net"));
EXPECT_EQ(60*SRS_UTIME_SECONDS, conf.get_hls_window("ossrs.net"));
}

if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "include ./conf/include_test/include_1.conf;"));

vector<string> listens = conf.get_listens();
EXPECT_EQ(1, (int)listens.size());
EXPECT_STREQ("1935", listens.at(0).c_str());

EXPECT_FALSE(conf.get_log_tank_file());

EXPECT_TRUE(conf.get_http_stream_enabled());
EXPECT_STREQ("xxx", conf.get_http_stream_listen().c_str());
EXPECT_STREQ("xxx2", conf.get_http_stream_dir().c_str());

EXPECT_TRUE(conf.get_hls_enabled("ossrs.net"));
EXPECT_STREQ("xxx", conf.get_hls_path("ossrs.net").c_str());
EXPECT_STREQ("xxx1", conf.get_hls_m3u8_file("ossrs.net").c_str());
EXPECT_STREQ("xxx2", conf.get_hls_ts_file("ossrs.net").c_str());
EXPECT_EQ(10*SRS_UTIME_SECONDS, conf.get_hls_fragment("ossrs.net"));
EXPECT_EQ(60*SRS_UTIME_SECONDS, conf.get_hls_window("ossrs.net"));
}

if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_2.conf;"));

vector<string> listens = conf.get_listens();
EXPECT_EQ(1, (int)listens.size());
EXPECT_STREQ("1935", listens.at(0).c_str());

EXPECT_FALSE(conf.get_log_tank_file());

EXPECT_TRUE(conf.get_http_stream_enabled());
EXPECT_STREQ("xxx", conf.get_http_stream_listen().c_str());
EXPECT_STREQ("xxx2", conf.get_http_stream_dir().c_str());

EXPECT_TRUE(conf.get_hls_enabled("ossrs.net"));
EXPECT_STREQ("xxx", conf.get_hls_path("ossrs.net").c_str());
EXPECT_STREQ("xxx1", conf.get_hls_m3u8_file("ossrs.net").c_str());
EXPECT_STREQ("xxx2", conf.get_hls_ts_file("ossrs.net").c_str());
EXPECT_EQ(10*SRS_UTIME_SECONDS, conf.get_hls_fragment("ossrs.net"));
EXPECT_EQ(60*SRS_UTIME_SECONDS, conf.get_hls_window("ossrs.net"));
}

if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse("include ./conf/include_test/include_4.conf;"));

vector<string> listens = conf.get_listens();
EXPECT_EQ(1, (int)listens.size());
EXPECT_STREQ("1935", listens.at(0).c_str());

EXPECT_FALSE(conf.get_log_tank_file());

EXPECT_TRUE(conf.get_http_stream_enabled());
EXPECT_STREQ("xxx", conf.get_http_stream_listen().c_str());
EXPECT_STREQ("xxx2", conf.get_http_stream_dir().c_str());

EXPECT_TRUE(conf.get_hls_enabled("ossrs.net"));
EXPECT_STREQ("xxx", conf.get_hls_path("ossrs.net").c_str());
EXPECT_STREQ("xxx1", conf.get_hls_m3u8_file("ossrs.net").c_str());
EXPECT_STREQ("xxx2", conf.get_hls_ts_file("ossrs.net").c_str());
EXPECT_EQ(10*SRS_UTIME_SECONDS, conf.get_hls_fragment("ossrs.net"));
EXPECT_EQ(60*SRS_UTIME_SECONDS, conf.get_hls_window("ossrs.net"));

EXPECT_TRUE(conf.get_http_api_enabled());
EXPECT_STREQ("xxx", conf.get_http_api_listen().c_str());
}
}