winlin

refine config, add comments.

@@ -42,6 +42,7 @@ using namespace std; @@ -42,6 +42,7 @@ using namespace std;
42 #include <srs_protocol_utility.hpp> 42 #include <srs_protocol_utility.hpp>
43 #include <srs_core_autofree.hpp> 43 #include <srs_core_autofree.hpp>
44 #include <srs_app_source.hpp> 44 #include <srs_app_source.hpp>
  45 +#include <srs_kernel_file.hpp>
45 46
46 #define SRS_WIKI_URL_LOG "https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLog" 47 #define SRS_WIKI_URL_LOG "https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLog"
47 48
@@ -104,16 +105,9 @@ string SrsConfDirective::arg2() @@ -104,16 +105,9 @@ string SrsConfDirective::arg2()
104 return ""; 105 return "";
105 } 106 }
106 107
107 -void SrsConfDirective::set_arg0(string value)  
108 -{  
109 - if (args.size() > 0) {  
110 - args[0] = value;  
111 - }  
112 - args.push_back(value);  
113 -}  
114 -  
115 SrsConfDirective* SrsConfDirective::at(int index) 108 SrsConfDirective* SrsConfDirective::at(int index)
116 { 109 {
  110 + srs_assert(index < (int)directives.size());
117 return directives.at(index); 111 return directives.at(index);
118 } 112 }
119 113
@@ -143,21 +137,18 @@ SrsConfDirective* SrsConfDirective::get(string _name, string _arg0) @@ -143,21 +137,18 @@ SrsConfDirective* SrsConfDirective::get(string _name, string _arg0)
143 return NULL; 137 return NULL;
144 } 138 }
145 139
146 -int SrsConfDirective::parse(const char* filename) 140 +bool SrsConfDirective::is_vhost()
147 { 141 {
148 - int ret = ERROR_SUCCESS;  
149 -  
150 - _srs_internal::SrsFileBuffer buffer;  
151 -  
152 - if ((ret = buffer.fullfill(filename)) != ERROR_SUCCESS) {  
153 - return ret;  
154 - }  
155 -  
156 - return parse_conf(&buffer, parse_file); 142 + return name == "vhost";
  143 +}
  144 +
  145 +int SrsConfDirective::parse(_srs_internal::SrsConfigBuffer* buffer)
  146 +{
  147 + return parse_conf(buffer, parse_file);
157 } 148 }
158 149
159 // see: ngx_conf_parse 150 // see: ngx_conf_parse
160 -int SrsConfDirective::parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirectiveType type) 151 +int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type)
161 { 152 {
162 int ret = ERROR_SUCCESS; 153 int ret = ERROR_SUCCESS;
163 154
@@ -167,11 +158,11 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirect @@ -167,11 +158,11 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirect
167 158
168 /** 159 /**
169 * ret maybe: 160 * ret maybe:
170 - * ERROR_SYSTEM_CONFIG_INVALID error.  
171 - * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found  
172 - * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found  
173 - * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found  
174 - * ERROR_SYSTEM_CONFIG_EOF the config file is done 161 + * ERROR_SYSTEM_CONFIG_INVALID error.
  162 + * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found
  163 + * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found
  164 + * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found
  165 + * ERROR_SYSTEM_CONFIG_EOF the config file is done
175 */ 166 */
176 if (ret == ERROR_SYSTEM_CONFIG_INVALID) { 167 if (ret == ERROR_SYSTEM_CONFIG_INVALID) {
177 return ret; 168 return ret;
@@ -217,7 +208,7 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirect @@ -217,7 +208,7 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirect
217 } 208 }
218 209
219 // see: ngx_conf_read_token 210 // see: ngx_conf_read_token
220 -int SrsConfDirective::read_token(_srs_internal::SrsFileBuffer* buffer, vector<string>& args) 211 +int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector<string>& args)
221 { 212 {
222 int ret = ERROR_SUCCESS; 213 int ret = ERROR_SUCCESS;
223 214
@@ -358,11 +349,6 @@ int SrsConfDirective::read_token(_srs_internal::SrsFileBuffer* buffer, vector<st @@ -358,11 +349,6 @@ int SrsConfDirective::read_token(_srs_internal::SrsFileBuffer* buffer, vector<st
358 return ret; 349 return ret;
359 } 350 }
360 351
361 -bool SrsConfDirective::is_vhost()  
362 -{  
363 - return name == "vhost";  
364 -}  
365 -  
366 SrsConfig::SrsConfig() 352 SrsConfig::SrsConfig()
367 { 353 {
368 show_help = false; 354 show_help = false;
@@ -1092,7 +1078,13 @@ int SrsConfig::parse_file(const char* filename) @@ -1092,7 +1078,13 @@ int SrsConfig::parse_file(const char* filename)
1092 return ERROR_SYSTEM_CONFIG_INVALID; 1078 return ERROR_SYSTEM_CONFIG_INVALID;
1093 } 1079 }
1094 1080
1095 - if ((ret = root->parse(config_file.c_str())) != ERROR_SUCCESS) { 1081 + _srs_internal::SrsConfigBuffer buffer;
  1082 +
  1083 + if ((ret = buffer.fullfill(config_file.c_str())) != ERROR_SUCCESS) {
  1084 + return ret;
  1085 + }
  1086 +
  1087 + if ((ret = root->parse(&buffer)) != ERROR_SUCCESS) {
1096 return ret; 1088 return ret;
1097 } 1089 }
1098 1090
@@ -2772,7 +2764,7 @@ bool SrsConfig::get_heartbeat_summaries() @@ -2772,7 +2764,7 @@ bool SrsConfig::get_heartbeat_summaries()
2772 2764
2773 namespace _srs_internal 2765 namespace _srs_internal
2774 { 2766 {
2775 - SrsFileBuffer::SrsFileBuffer() 2767 + SrsConfigBuffer::SrsConfigBuffer()
2776 { 2768 {
2777 line = 0; 2769 line = 0;
2778 2770
@@ -2780,54 +2772,43 @@ namespace _srs_internal @@ -2780,54 +2772,43 @@ namespace _srs_internal
2780 end = start; 2772 end = start;
2781 } 2773 }
2782 2774
2783 - SrsFileBuffer::~SrsFileBuffer() 2775 + SrsConfigBuffer::~SrsConfigBuffer()
2784 { 2776 {
2785 srs_freep(start); 2777 srs_freep(start);
2786 } 2778 }
2787 2779
2788 - int SrsFileBuffer::fullfill(const char* filename) 2780 + int SrsConfigBuffer::fullfill(const char* filename)
2789 { 2781 {
2790 int ret = ERROR_SUCCESS; 2782 int ret = ERROR_SUCCESS;
2791 2783
2792 - int fd = -1;  
2793 - int nread = 0;  
2794 - int filesize = 0; 2784 + SrsFileReader reader;
2795 2785
2796 - // TODO: FIXME: refine the file stream.  
2797 - if ((fd = ::open(filename, O_RDONLY, 0)) < 0) {  
2798 - ret = ERROR_SYSTEM_CONFIG_INVALID; 2786 + // open file reader.
  2787 + if ((ret = reader.open(filename)) != ERROR_SUCCESS) {
2799 srs_error("open conf file error. ret=%d", ret); 2788 srs_error("open conf file error. ret=%d", ret);
2800 - goto finish; 2789 + return ret;
2801 } 2790 }
2802 2791
2803 - if ((filesize = FILE_SIZE(fd) - FILE_OFFSET(fd)) <= 0) {  
2804 - ret = ERROR_SYSTEM_CONFIG_EOF;  
2805 - srs_error("read conf file error. ret=%d", ret);  
2806 - goto finish;  
2807 - }  
2808 - 2792 + // read all.
  2793 + int filesize = (int)reader.filesize();
  2794 +
  2795 + // create buffer
2809 srs_freep(start); 2796 srs_freep(start);
2810 pos = last = start = new char[filesize]; 2797 pos = last = start = new char[filesize];
2811 end = start + filesize; 2798 end = start + filesize;
2812 2799
2813 - if ((nread = read(fd, start, filesize)) != filesize) {  
2814 - ret = ERROR_SYSTEM_CONFIG_INVALID; 2800 + // read total content from file.
  2801 + ssize_t nread = 0;
  2802 + if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) {
2815 srs_error("read file read error. expect %d, actual %d bytes, ret=%d", 2803 srs_error("read file read error. expect %d, actual %d bytes, ret=%d",
2816 filesize, nread, ret); 2804 filesize, nread, ret);
2817 - goto finish;  
2818 - }  
2819 -  
2820 - line = 1;  
2821 -  
2822 - finish:  
2823 - if (fd > 0) {  
2824 - ::close(fd); 2805 + return ret;
2825 } 2806 }
2826 2807
2827 return ret; 2808 return ret;
2828 } 2809 }
2829 2810
2830 - bool SrsFileBuffer::empty() 2811 + bool SrsConfigBuffer::empty()
2831 { 2812 {
2832 return pos >= end; 2813 return pos >= end;
2833 } 2814 }
@@ -84,35 +84,129 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -84,35 +84,129 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
84 84
85 namespace _srs_internal 85 namespace _srs_internal
86 { 86 {
87 - class SrsFileBuffer; 87 + class SrsConfigBuffer;
88 }; 88 };
89 89
  90 +/**
  91 +* the config directive.
  92 +* the config file is a group of directives,
  93 +* all directive has name, args and child-directives.
  94 +* for example, the following config text:
  95 + vhost vhost.ossrs.net {
  96 + enabled on;
  97 + ingest livestream {
  98 + enabled on;
  99 + ffmpeg /bin/ffmpeg;
  100 + }
  101 + }
  102 +* will be parsed to:
  103 +* SrsConfDirective: name="vhost", arg0="vhost.ossrs.net", child-directives=[
  104 +* SrsConfDirective: name="enabled", arg0="on", child-directives=[]
  105 +* SrsConfDirective: name="ingest", arg0="livestream", child-directives=[
  106 +* SrsConfDirective: name="enabled", arg0="on", child-directives=[]
  107 +* SrsConfDirective: name="ffmpeg", arg0="/bin/ffmpeg", child-directives=[]
  108 +* ]
  109 +* ]
  110 +*/
90 class SrsConfDirective 111 class SrsConfDirective
91 { 112 {
92 public: 113 public:
  114 + /**
  115 + * the line of config file in which the directive from
  116 + */
93 int conf_line; 117 int conf_line;
  118 + /**
  119 + * the name of directive, for example, the following config text:
  120 + * enabled on;
  121 + * will be parsed to a directive, its name is "enalbed"
  122 + */
94 std::string name; 123 std::string name;
  124 + /**
  125 + * the args of directive, for example, the following config text:
  126 + * listen 1935 1936;
  127 + * will be parsed to a directive, its args is ["1935", "1936"].
  128 + */
95 std::vector<std::string> args; 129 std::vector<std::string> args;
  130 + /**
  131 + * the child directives, for example, the following config text:
  132 + * vhost vhost.ossrs.net {
  133 + * enabled on;
  134 + * }
  135 + * will be parsed to a directive, its directives is a vector contains
  136 + * a directive, which is:
  137 + * name:"enalbed", args:["on"], directives:[]
  138 + *
  139 + * @remark, the directives can contains directives.
  140 + */
96 std::vector<SrsConfDirective*> directives; 141 std::vector<SrsConfDirective*> directives;
97 public: 142 public:
98 SrsConfDirective(); 143 SrsConfDirective();
99 virtual ~SrsConfDirective(); 144 virtual ~SrsConfDirective();
  145 +// args
100 public: 146 public:
  147 + /**
  148 + * get the args0,1,2, if user want to get more args,
  149 + * directly use the args.at(index).
  150 + */
101 virtual std::string arg0(); 151 virtual std::string arg0();
102 - virtual std::string arg1(); 152 + virtual std::string arg1();
103 virtual std::string arg2(); 153 virtual std::string arg2();
104 - virtual void set_arg0(std::string value); 154 +// directives
  155 +public:
  156 + /**
  157 + * get the directive by index.
  158 + * @remark, assert the index<directives.size().
  159 + */
105 virtual SrsConfDirective* at(int index); 160 virtual SrsConfDirective* at(int index);
  161 + /**
  162 + * get the directive by name, return the first match.
  163 + */
106 virtual SrsConfDirective* get(std::string _name); 164 virtual SrsConfDirective* get(std::string _name);
  165 + /**
  166 + * get the directive by name and its arg0, return the first match.
  167 + */
107 virtual SrsConfDirective* get(std::string _name, std::string _arg0); 168 virtual SrsConfDirective* get(std::string _name, std::string _arg0);
  169 +// help utilities
108 public: 170 public:
109 - virtual int parse(const char* filename);  
110 -public:  
111 - enum SrsDirectiveType{parse_file, parse_block};  
112 - virtual int parse_conf(_srs_internal::SrsFileBuffer* buffer, SrsDirectiveType type);  
113 - virtual int read_token(_srs_internal::SrsFileBuffer* buffer, std::vector<std::string>& args);  
114 -public: 171 + /**
  172 + * whether current directive is vhost.
  173 + */
115 virtual bool is_vhost(); 174 virtual bool is_vhost();
  175 +// parse utilities
  176 +public:
  177 + /**
  178 + * parse config directive from file buffer.
  179 + */
  180 + virtual int parse(_srs_internal::SrsConfigBuffer* buffer);
  181 +// private parse.
  182 +private:
  183 + /**
  184 + * the directive parsing type.
  185 + */
  186 + enum SrsDirectiveType {
  187 + /**
  188 + * the root directives, parsing file.
  189 + */
  190 + parse_file,
  191 + /**
  192 + * for each direcitve, parsing text block.
  193 + */
  194 + parse_block
  195 + };
  196 + /**
  197 + * parse the conf from buffer. the work flow:
  198 + * 1. read a token(directive args and a ret flag),
  199 + * 2. initialize the directive by args, args[0] is name, args[1-N] is args of directive,
  200 + * 3. if ret flag indicates there are child-directives, read_conf(directive, block) recursively.
  201 + */
  202 + virtual int parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type);
  203 + /**
  204 + * read a token from buffer.
  205 + * a token, is the directive args and a flag indicates whether has child-directives.
  206 + * @param args, the output directive args, the first is the directive name, left is the args.
  207 + * @return, an error code indicates error or has child-directives.
  208 + */
  209 + virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args);
116 }; 210 };
117 211
118 /** 212 /**
@@ -294,10 +388,12 @@ public: @@ -294,10 +388,12 @@ public:
294 388
295 namespace _srs_internal 389 namespace _srs_internal
296 { 390 {
297 - // TODO: FIXME: use SrsFileReader.  
298 - class SrsFileBuffer 391 + /**
  392 + * the buffer of config content.
  393 + */
  394 + class SrsConfigBuffer
299 { 395 {
300 - private: 396 + protected:
301 // last available position. 397 // last available position.
302 char* last; 398 char* last;
303 // end of buffer. 399 // end of buffer.
@@ -309,10 +405,17 @@ namespace _srs_internal @@ -309,10 +405,17 @@ namespace _srs_internal
309 char* pos; 405 char* pos;
310 // current parsed line. 406 // current parsed line.
311 int line; 407 int line;
312 -  
313 - SrsFileBuffer();  
314 - virtual ~SrsFileBuffer(); 408 + public:
  409 + SrsConfigBuffer();
  410 + virtual ~SrsConfigBuffer();
  411 + public:
  412 + /**
  413 + * fullfill the buffer with content of file specified by filename.
  414 + */
315 virtual int fullfill(const char* filename); 415 virtual int fullfill(const char* filename);
  416 + /**
  417 + * whether buffer is empty.
  418 + */
316 virtual bool empty(); 419 virtual bool empty();
317 }; 420 };
318 }; 421 };