winlin

support nginx-style config file

@@ -46,6 +46,7 @@ url: rtmp://127.0.0.1:1935/live/livestream @@ -46,6 +46,7 @@ url: rtmp://127.0.0.1:1935/live/livestream
46 * nginx v1.5.0: 139524 lines <br/> 46 * nginx v1.5.0: 139524 lines <br/>
47 47
48 ### History 48 ### History
  49 +* v0.3, 2013-11-02, support config file in nginx-conf style.
49 * v0.3, 2013-10-29, support pithy print log message specified by stage. 50 * v0.3, 2013-10-29, support pithy print log message specified by stage.
50 * v0.3, 2013-10-28, support librtmp without extended-timestamp in 0xCX chunk packet. 51 * v0.3, 2013-10-28, support librtmp without extended-timestamp in 0xCX chunk packet.
51 * v0.3, 2013-10-27, support cache last gop for client fast startup. 52 * v0.3, 2013-10-27, support cache last gop for client fast startup.
  1 +listen 1935;
  2 +vhost __defaultVhost__ {
  3 + application live {
  4 + }
  5 +}
@@ -90,7 +90,8 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server" @@ -90,7 +90,8 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
90 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer" 90 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer"
91 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0" 91 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
92 "srs_core_stream" "srs_core_source" "srs_core_codec" 92 "srs_core_stream" "srs_core_source" "srs_core_codec"
93 - "srs_core_complex_handshake" "srs_core_pithy_print") 93 + "srs_core_complex_handshake" "srs_core_pithy_print"
  94 + "srs_core_config")
94 MODULE_DIR="src/core" . auto/modules.sh 95 MODULE_DIR="src/core" . auto/modules.sh
95 CORE_OBJS="${MODULE_OBJS[@]}" 96 CORE_OBJS="${MODULE_OBJS[@]}"
96 97
@@ -63,7 +63,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -63,7 +63,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
63 (void)0 63 (void)0
64 64
65 // current release version 65 // current release version
66 -#define RTMP_SIG_SRS_VERSION "0.2" 66 +#define RTMP_SIG_SRS_VERSION "0.2.0"
67 // server info. 67 // server info.
68 #define RTMP_SIG_SRS_KEY "srs" 68 #define RTMP_SIG_SRS_KEY "srs"
69 #define RTMP_SIG_SRS_ROLE "origin server" 69 #define RTMP_SIG_SRS_ROLE "origin server"
@@ -76,8 +76,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -76,8 +76,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76 #define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin" 76 #define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin"
77 77
78 // compare 78 // compare
79 -#define srs_min(a, b) ((a < b)? a : b)  
80 -#define srs_max(a, b) ((a < b)? b : a) 79 +#define srs_min(a, b) (((a) < (b))? (a) : (b))
  80 +#define srs_max(a, b) (((a) < (b))? (b) : (a))
81 81
82 // get current system time in ms, use cache to avoid performance problem 82 // get current system time in ms, use cache to avoid performance problem
83 extern int64_t srs_get_system_time_ms(); 83 extern int64_t srs_get_system_time_ms();
@@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #include <srs_core_pithy_print.hpp> 35 #include <srs_core_pithy_print.hpp>
36 36
37 #define SRS_PULSE_TIMEOUT_MS 100 37 #define SRS_PULSE_TIMEOUT_MS 100
38 -#define SRS_SEND_TIMEOUT_MS 5000 38 +#define SRS_SEND_TIMEOUT_MS 5000000L
39 #define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS 39 #define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS
40 40
41 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) 41 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
@@ -63,7 +63,7 @@ int SrsClient::do_cycle() @@ -63,7 +63,7 @@ int SrsClient::do_cycle()
63 srs_error("get peer ip failed. ret=%d", ret); 63 srs_error("get peer ip failed. ret=%d", ret);
64 return ret; 64 return ret;
65 } 65 }
66 - srs_trace("get peer ip success. ip=%s, send_to=%d, recv_to=%d", 66 + srs_trace("get peer ip success. ip=%s, send_to=%"PRId64", recv_to=%"PRId64"",
67 ip, SRS_SEND_TIMEOUT_MS, SRS_RECV_TIMEOUT_MS); 67 ip, SRS_SEND_TIMEOUT_MS, SRS_RECV_TIMEOUT_MS);
68 68
69 rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_MS * 1000); 69 rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_MS * 1000);
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_config.hpp>
  25 +
  26 +#include <stdio.h>
  27 +#include <stdlib.h>
  28 +#include <errno.h>
  29 +#include <string.h>
  30 +// file operations.
  31 +#include <unistd.h>
  32 +#include <sys/types.h>
  33 +#include <sys/stat.h>
  34 +#include <fcntl.h>
  35 +
  36 +#include <vector>
  37 +
  38 +#include <srs_core_error.hpp>
  39 +
  40 +#define FILE_OFFSET(fd) lseek(fd, 0, SEEK_CUR)
  41 +
  42 +int64_t FILE_SIZE(int fd)
  43 +{
  44 + int64_t pre = FILE_OFFSET(fd);
  45 + int64_t pos = lseek(fd, 0, SEEK_END);
  46 + lseek(fd, pre, SEEK_SET);
  47 + return pos;
  48 +}
  49 +
  50 +#define LF (char)0x0a
  51 +#define CR (char)0x0d
  52 +
  53 +bool is_common_space(char ch)
  54 +{
  55 + return (ch == ' ' || ch == '\t' || ch == CR || ch == LF);
  56 +}
  57 +
  58 +#define CONF_BUFFER_SIZE 4096
  59 +
  60 +SrsFileBuffer::SrsFileBuffer()
  61 +{
  62 + fd = -1;
  63 + line = 0;
  64 +
  65 + pos = last = start = new char[CONF_BUFFER_SIZE];
  66 + end = start + CONF_BUFFER_SIZE;
  67 +}
  68 +
  69 +SrsFileBuffer::~SrsFileBuffer()
  70 +{
  71 + if (fd > 0) {
  72 + close(fd);
  73 + }
  74 + srs_freepa(start);
  75 +}
  76 +
  77 +int SrsFileBuffer::open(const char* filename)
  78 +{
  79 + assert(fd == -1);
  80 +
  81 + if ((fd = ::open(filename, O_RDONLY, 0)) < 0) {
  82 + fprintf(stderr, "open conf file error. errno=%d(%s)\n", errno, strerror(errno));
  83 + return ERROR_SYSTEM_CONFIG_INVALID;
  84 + }
  85 +
  86 + return ERROR_SUCCESS;
  87 +}
  88 +
  89 +SrsConfDirective::SrsConfDirective()
  90 +{
  91 +}
  92 +
  93 +SrsConfDirective::~SrsConfDirective()
  94 +{
  95 + std::vector<SrsConfDirective*>::iterator it;
  96 + for (it = directives.begin(); it != directives.end(); ++it) {
  97 + SrsConfDirective* directive = *it;
  98 + srs_freep(directive);
  99 + }
  100 + directives.clear();
  101 +}
  102 +
  103 +SrsConfDirective* SrsConfDirective::at(int index)
  104 +{
  105 + return directives.at(index);
  106 +}
  107 +
  108 +int SrsConfDirective::parse(const char* filename)
  109 +{
  110 + int ret = ERROR_SUCCESS;
  111 +
  112 + SrsFileBuffer buffer;
  113 +
  114 + if ((ret = buffer.open(filename)) != ERROR_SUCCESS) {
  115 + return ret;
  116 + }
  117 +
  118 + return parse_conf(&buffer, parse_file);
  119 +}
  120 +
  121 +// see: ngx_conf_parse
  122 +int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type)
  123 +{
  124 + int ret = ERROR_SUCCESS;
  125 +
  126 + while (true) {
  127 + std::vector<std::string> args;
  128 + ret = read_token(buffer, args);
  129 +
  130 + /**
  131 + * ret maybe:
  132 + * ERROR_SYSTEM_CONFIG_INVALID error.
  133 + * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found
  134 + * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found
  135 + * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found
  136 + * ERROR_SYSTEM_CONFIG_EOF the config file is done
  137 + */
  138 + if (ret == ERROR_SYSTEM_CONFIG_INVALID) {
  139 + return ret;
  140 + }
  141 + if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
  142 + if (type != parse_block) {
  143 + fprintf(stderr, "line %d: unexpected \"}\"\n", buffer->line);
  144 + return ret;
  145 + }
  146 + return ERROR_SUCCESS;
  147 + }
  148 + if (ret == ERROR_SYSTEM_CONFIG_EOF) {
  149 + if (type == parse_block) {
  150 + fprintf(stderr, "line %d: unexpected end of file, expecting \"}\"\n", buffer->line);
  151 + return ret;
  152 + }
  153 + return ERROR_SUCCESS;
  154 + }
  155 +
  156 + if (args.empty()) {
  157 + fprintf(stderr, "line %d: empty directive.\n", buffer->line);
  158 + return ret;
  159 + }
  160 +
  161 + // build directive tree.
  162 + SrsConfDirective* directive = new SrsConfDirective();
  163 +
  164 + directive->name = args[0];
  165 + args.erase(args.begin());
  166 + directive->args.swap(args);
  167 +
  168 + directives.push_back(directive);
  169 +
  170 + if (ret == ERROR_SYSTEM_CONFIG_BLOCK_START) {
  171 + if ((ret = directive->parse_conf(buffer, parse_block)) != ERROR_SUCCESS) {
  172 + return ret;
  173 + }
  174 + }
  175 + }
  176 +
  177 + return ret;
  178 +}
  179 +
  180 +// see: ngx_conf_read_token
  181 +int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>& args)
  182 +{
  183 + int ret = ERROR_SUCCESS;
  184 +
  185 + char* pstart = buffer->pos;
  186 + int startline = buffer->line;
  187 +
  188 + bool sharp_comment = false;
  189 +
  190 + bool d_quoted = false;
  191 + bool s_quoted = false;
  192 +
  193 + bool need_space = false;
  194 + bool last_space = true;
  195 +
  196 + while (true) {
  197 + if ((ret = refill_buffer(buffer, d_quoted, s_quoted, startline, pstart)) != ERROR_SUCCESS) {
  198 + if (!args.empty() || !last_space) {
  199 + fprintf(stderr, "line %d: unexpected end of file, expecting ; or \"}\"\n", buffer->line);
  200 + return ERROR_SYSTEM_CONFIG_INVALID;
  201 + }
  202 + return ret;
  203 + }
  204 +
  205 + char ch = *buffer->pos++;
  206 +
  207 + if (ch == LF) {
  208 + buffer->line++;
  209 + sharp_comment = false;
  210 + }
  211 +
  212 + if (sharp_comment) {
  213 + continue;
  214 + }
  215 +
  216 + if (need_space) {
  217 + if (is_common_space(ch)) {
  218 + last_space = true;
  219 + need_space = false;
  220 + continue;
  221 + }
  222 + if (ch == ';') {
  223 + return ERROR_SYSTEM_CONFIG_DIRECTIVE;
  224 + }
  225 + if (ch == '{') {
  226 + return ERROR_SYSTEM_CONFIG_BLOCK_START;
  227 + }
  228 + fprintf(stderr, "line %d: unexpected '%c'\n", buffer->line, ch);
  229 + return ERROR_SYSTEM_CONFIG_INVALID;
  230 + }
  231 +
  232 + // last charecter is space.
  233 + if (last_space) {
  234 + if (is_common_space(ch)) {
  235 + continue;
  236 + }
  237 + pstart = buffer->pos - 1;
  238 + startline = buffer->line;
  239 + switch (ch) {
  240 + case ';':
  241 + if (args.size() == 0) {
  242 + fprintf(stderr, "line %d: unexpected ';'\n", buffer->line);
  243 + return ERROR_SYSTEM_CONFIG_INVALID;
  244 + }
  245 + return ERROR_SYSTEM_CONFIG_DIRECTIVE;
  246 + case '{':
  247 + if (args.size() == 0) {
  248 + fprintf(stderr, "line %d: unexpected '{'\n", buffer->line);
  249 + return ERROR_SYSTEM_CONFIG_INVALID;
  250 + }
  251 + return ERROR_SYSTEM_CONFIG_BLOCK_START;
  252 + case '}':
  253 + if (args.size() != 0) {
  254 + fprintf(stderr, "line %d: unexpected '}'\n", buffer->line);
  255 + return ERROR_SYSTEM_CONFIG_INVALID;
  256 + }
  257 + return ERROR_SYSTEM_CONFIG_BLOCK_END;
  258 + case '#':
  259 + sharp_comment = 1;
  260 + continue;
  261 + case '"':
  262 + pstart++;
  263 + d_quoted = true;
  264 + last_space = 0;
  265 + continue;
  266 + case '\'':
  267 + pstart++;
  268 + s_quoted = true;
  269 + last_space = 0;
  270 + continue;
  271 + default:
  272 + last_space = 0;
  273 + continue;
  274 + }
  275 + } else {
  276 + // last charecter is not space
  277 + bool found = false;
  278 + if (d_quoted) {
  279 + if (ch == '"') {
  280 + d_quoted = false;
  281 + need_space = true;
  282 + found = true;
  283 + }
  284 + } else if (s_quoted) {
  285 + if (ch == '\'') {
  286 + s_quoted = false;
  287 + need_space = true;
  288 + found = true;
  289 + }
  290 + } else if (is_common_space(ch) || ch == ';' || ch == '{') {
  291 + last_space = true;
  292 + found = 1;
  293 + }
  294 +
  295 + if (found) {
  296 + int len = buffer->pos - pstart;
  297 + char* word = new char[len];
  298 + memcpy(word, pstart, len);
  299 + word[len - 1] = 0;
  300 +
  301 + args.push_back(word);
  302 + srs_freepa(word);
  303 +
  304 + if (ch == ';') {
  305 + return ERROR_SYSTEM_CONFIG_DIRECTIVE;
  306 + }
  307 + if (ch == '{') {
  308 + return ERROR_SYSTEM_CONFIG_BLOCK_START;
  309 + }
  310 + }
  311 + }
  312 + }
  313 +
  314 + return ret;
  315 +}
  316 +
  317 +int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s_quoted, int startline, char*& pstart)
  318 +{
  319 + int ret = ERROR_SUCCESS;
  320 +
  321 + if (buffer->pos < buffer->last) {
  322 + return ret;
  323 + }
  324 +
  325 + int size = FILE_SIZE(buffer->fd) - FILE_OFFSET(buffer->fd);
  326 +
  327 + if (size <= 0) {
  328 + return ERROR_SYSTEM_CONFIG_EOF;
  329 + }
  330 +
  331 + int len = buffer->pos - buffer->start;
  332 + if (len >= CONF_BUFFER_SIZE) {
  333 + buffer->line = startline;
  334 +
  335 + if (!d_quoted && !s_quoted) {
  336 + fprintf(stderr, "line %d: too long parameter \"%*s...\" started\n",
  337 + buffer->line, 10, buffer->start);
  338 +
  339 + } else {
  340 + fprintf(stderr, "line %d: too long parameter, "
  341 + "probably missing terminating '%c' character\n", buffer->line, d_quoted? '"':'\'');
  342 + }
  343 + return ERROR_SYSTEM_CONFIG_INVALID;
  344 + }
  345 +
  346 + if (len) {
  347 + memmove(buffer->start, pstart, len);
  348 + }
  349 +
  350 + size = srs_min(size, buffer->end - (buffer->start + len));
  351 + int n = read(buffer->fd, buffer->start + len, size);
  352 + if (n != size) {
  353 + fprintf(stderr, "read file read error. expect %d, actual %d bytes.\n", size, n);
  354 + return ERROR_SYSTEM_CONFIG_INVALID;
  355 + }
  356 +
  357 + buffer->pos = buffer->start + len;
  358 + buffer->last = buffer->pos + n;
  359 + pstart = buffer->start;
  360 +
  361 + return ret;
  362 +}
  363 +
  364 +Config::Config()
  365 +{
  366 + show_help = false;
  367 + show_version = false;
  368 + config_file = NULL;
  369 +}
  370 +
  371 +Config::~Config()
  372 +{
  373 +}
  374 +
  375 +// see: ngx_get_options
  376 +int Config::parse_options(int argc, char** argv)
  377 +{
  378 + int ret = ERROR_SUCCESS;
  379 +
  380 + for (int i = 1; i < argc; i++) {
  381 + if ((ret = parse_argv(i, argv)) != ERROR_SUCCESS) {
  382 + return ret;
  383 + }
  384 + }
  385 +
  386 + if (show_help) {
  387 + print_help(argv);
  388 + }
  389 +
  390 + if (show_version) {
  391 + fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);
  392 + }
  393 +
  394 + if (show_help || show_version) {
  395 + exit(0);
  396 + }
  397 +
  398 + if (!config_file) {
  399 + fprintf(stderr, "config file not specified, see help: %s -h\n", argv[0]);
  400 + return ERROR_SYSTEM_CONFIG_INVALID;
  401 + }
  402 +
  403 + SrsConfDirective root;
  404 + root.name = "root";
  405 +
  406 + if ((ret = root.parse(config_file)) != ERROR_SUCCESS) {
  407 + return ret;
  408 + }
  409 +
  410 + return ret;
  411 +}
  412 +
  413 +int Config::parse_argv(int& i, char** argv)
  414 +{
  415 + int ret = ERROR_SUCCESS;
  416 +
  417 + char* p = argv[i];
  418 +
  419 + if (*p++ != '-') {
  420 + fprintf(stderr, "invalid options(index=%d, value=%s), "
  421 + "must starts with -, see help: %s -h\n", i, argv[i], argv[0]);
  422 + return ERROR_SYSTEM_CONFIG_INVALID;
  423 + }
  424 +
  425 + while (*p) {
  426 + switch (*p++) {
  427 + case '?':
  428 + case 'h':
  429 + show_help = true;
  430 + break;
  431 + case 'v':
  432 + case 'V':
  433 + show_version = true;
  434 + break;
  435 + case 'c':
  436 + if (*p) {
  437 + config_file = p;
  438 + return ret;
  439 + }
  440 + if (argv[++i]) {
  441 + config_file = argv[i];
  442 + return ret;
  443 + }
  444 + fprintf(stderr, "option \"-c\" requires parameter\n");
  445 + return ERROR_SYSTEM_CONFIG_INVALID;
  446 + default:
  447 + fprintf(stderr, "invalid option: \"%c\", see help: %s -h\n", *(p - 1), argv[0]);
  448 + return ERROR_SYSTEM_CONFIG_INVALID;
  449 + }
  450 + }
  451 +
  452 + return ret;
  453 +}
  454 +
  455 +void Config::print_help(char** argv)
  456 +{
  457 + fprintf(stderr, RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION
  458 + " Copyright (c) 2013 winlin\n"
  459 + "Usage: %s [-h?vV] [-c <filename>]\n"
  460 + "\n"
  461 + "Options:\n"
  462 + " -?-h : show help\n"
  463 + " -v-V : show version and exit\n"
  464 + " -c filename : set configuration file\n"
  465 + "\n"
  466 + RTMP_SIG_SRS_WEB"\n"
  467 + RTMP_SIG_SRS_URL"\n"
  468 + "Email: "RTMP_SIG_SRS_EMAIL"\n",
  469 + argv[0]);
  470 +}
  471 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_CONIFG_HPP
  25 +#define SRS_CORE_CONIFG_HPP
  26 +
  27 +/*
  28 +#include <srs_core_config.hpp>
  29 +*/
  30 +#include <srs_core.hpp>
  31 +
  32 +#include <vector>
  33 +#include <string>
  34 +
  35 +/**
  36 +* the config parser.
  37 +*/
  38 +class Config
  39 +{
  40 +private:
  41 + bool show_help;
  42 + bool show_version;
  43 + char* config_file;
  44 +public:
  45 + Config();
  46 + virtual ~Config();
  47 +public:
  48 + virtual int parse_options(int argc, char** argv);
  49 +private:
  50 + virtual int parse_argv(int& i, char** argv);
  51 + virtual void print_help(char** argv);
  52 +};
  53 +
  54 +class SrsFileBuffer
  55 +{
  56 +public:
  57 + int fd;
  58 + int line;
  59 + // start of buffer.
  60 + char* start;
  61 + // end of buffer.
  62 + char* end;
  63 + // current consumed position.
  64 + char* pos;
  65 + // last available position.
  66 + char* last;
  67 +
  68 + SrsFileBuffer();
  69 + virtual ~SrsFileBuffer();
  70 + virtual int open(const char* filename);
  71 +};
  72 +
  73 +class SrsConfDirective
  74 +{
  75 +public:
  76 + std::string name;
  77 + std::vector<std::string> args;
  78 + std::vector<SrsConfDirective*> directives;
  79 +public:
  80 + SrsConfDirective();
  81 + virtual ~SrsConfDirective();
  82 + SrsConfDirective* at(int index);
  83 +public:
  84 + virtual int parse(const char* filename);
  85 +public:
  86 + enum SrsDirectiveType{parse_file, parse_block};
  87 + virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
  88 + virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
  89 + virtual int refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s_quoted, int startline, char*& pstart);
  90 +};
  91 +
  92 +#endif
@@ -71,6 +71,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -71,6 +71,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71 #define ERROR_SYSTEM_CLIENT_INVALID 402 71 #define ERROR_SYSTEM_CLIENT_INVALID 402
72 #define ERROR_SYSTEM_ASSERT_FAILED 403 72 #define ERROR_SYSTEM_ASSERT_FAILED 403
73 #define ERROR_SYSTEM_SIZE_NEGATIVE 404 73 #define ERROR_SYSTEM_SIZE_NEGATIVE 404
  74 +#define ERROR_SYSTEM_CONFIG_INVALID 405
  75 +#define ERROR_SYSTEM_CONFIG_DIRECTIVE 406
  76 +#define ERROR_SYSTEM_CONFIG_BLOCK_START 407
  77 +#define ERROR_SYSTEM_CONFIG_BLOCK_END 408
  78 +#define ERROR_SYSTEM_CONFIG_EOF 409
74 79
75 // see librtmp. 80 // see librtmp.
76 // failed when open ssl create the dh 81 // failed when open ssl create the dh
@@ -24,26 +24,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -24,26 +24,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <srs_core_log.hpp> 24 #include <srs_core_log.hpp>
25 #include <srs_core_error.hpp> 25 #include <srs_core_error.hpp>
26 #include <srs_core_server.hpp> 26 #include <srs_core_server.hpp>
  27 +#include <srs_core_config.hpp>
27 28
28 #include <stdlib.h> 29 #include <stdlib.h>
29 30
30 int main(int argc, char** argv){ 31 int main(int argc, char** argv){
31 int ret = ERROR_SUCCESS; 32 int ret = ERROR_SUCCESS;
32 33
33 - if (argc <= 1) {  
34 - printf(RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION  
35 - " Copyright (c) 2013 winlin\n"  
36 - "Usage: %s <listen_port>\n"  
37 - "\n"  
38 - RTMP_SIG_SRS_WEB"\n"  
39 - RTMP_SIG_SRS_URL"\n"  
40 - "Email: "RTMP_SIG_SRS_EMAIL"\n",  
41 - argv[0]);  
42 - exit(1);  
43 - } 34 + Config config;
44 35
45 - int listen_port = ::atoi(argv[1]);  
46 - srs_trace("listen_port=%d", listen_port); 36 + if ((ret = config.parse_options(argc, argv)) != ERROR_SUCCESS) {
  37 + return ret;
  38 + }
47 39
48 SrsServer server; 40 SrsServer server;
49 41
@@ -51,7 +43,7 @@ int main(int argc, char** argv){ @@ -51,7 +43,7 @@ int main(int argc, char** argv){
51 return ret; 43 return ret;
52 } 44 }
53 45
54 - if ((ret = server.listen(listen_port)) != ERROR_SUCCESS) { 46 + if ((ret = server.listen(1935)) != ERROR_SUCCESS) {
55 return ret; 47 return ret;
56 } 48 }
57 49
@@ -10,6 +10,8 @@ file @@ -10,6 +10,8 @@ file
10 ..\core\srs_core_auto_free.cpp, 10 ..\core\srs_core_auto_free.cpp,
11 ..\core\srs_core_server.hpp, 11 ..\core\srs_core_server.hpp,
12 ..\core\srs_core_server.cpp, 12 ..\core\srs_core_server.cpp,
  13 + ..\core\srs_core_config.hpp,
  14 + ..\core\srs_core_config.cpp,
13 ..\core\srs_core_conn.hpp, 15 ..\core\srs_core_conn.hpp,
14 ..\core\srs_core_conn.cpp, 16 ..\core\srs_core_conn.cpp,
15 ..\core\srs_core_client.hpp, 17 ..\core\srs_core_client.hpp,