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 1 commit
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
Next Next commit
Support include import configuration
  • Loading branch information
pengfei.ma committed Jan 17, 2022
commit d3fa81a02b6dd0396f10b1c867b374c3840151f4
101 changes: 84 additions & 17 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <vector>
#include <algorithm>
#include <glob.h>
using namespace std;

#include <srs_kernel_error.hpp>
Expand Down Expand Up @@ -842,9 +843,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 +972,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 +1014,50 @@ 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[0] == "include") {
if (args.size() < 2) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: include is empty directive", buffer->line);
}

std::string file = args[1];
if (!srs_string_contains(file, "*", "?", "[")) {
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
srs_trace("config parse include %s", file.c_str());
srs_freep(err);
if ((err = conf->parse_include_file(file.c_str())) != srs_success) {
return srs_error_wrap(err, "parse file");
}
} else {
unsigned long i = 0;
glob_t glob_buf;

if (glob((char *) file.c_str(), 0, NULL, &glob_buf) != 0) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "line %d: parse include %s failed", buffer->line, file.c_str());
}

while(i < glob_buf.gl_pathc) {
srs_trace("include %s", *(glob_buf.gl_pathv+i));
srs_freep(err);
if ((err = conf->parse_include_file(*(glob_buf.gl_pathv+i))) != srs_success) {
return srs_error_wrap(err, "parse file");
}
i ++;
}
}
} 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,29 @@ 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;
winlinvip marked this conversation as resolved.
Show resolved Hide resolved

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

if ((err = parse_include_buffer(&buffer)) != srs_success) {
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
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 +3010,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 All @@ -2979,6 +3034,18 @@ srs_error_t SrsConfig::parse_buffer(SrsConfigBuffer* buffer)
return err;
}

srs_error_t SrsConfig::parse_include_buffer(SrsConfigBuffer *buffer)
{
srs_error_t err = srs_success;

// Parse root tree from buffer.
if ((err = root->parse(buffer, this)) != srs_success) {
winlinvip marked this conversation as resolved.
Show resolved Hide resolved
return srs_error_wrap(err, "root parse");
}

return err;
}

string SrsConfig::cwd()
{
return _cwd;
Expand Down
10 changes: 8 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 All @@ -366,6 +368,10 @@ class SrsConfig
// @param buffer, the config buffer, user must delete it.
// @remark, use protected for the utest to override with mock.
virtual srs_error_t parse_buffer(srs_internal::SrsConfigBuffer* buffer);
// Parse include config from the buffer.
// @param buffer, the config buffer, user must delete it.
// @remark, use protected for the utest to override with mock.
virtual srs_error_t parse_include_buffer(srs_internal::SrsConfigBuffer* buffer);
// global env
public:
// Get the current work directory.
Expand Down