SRS之配置的解析

1. 框架

1.1 SrsConfig 类

/**
* the config service provider.
* for the config supports reload, so never keep the reference cross st-thread,
* that is, never save the SrsConfDirective* get by any api of config,
* for it maybe free in the reload st-thread cycle.
* you can keep it before st-thread switch, or simply never keep it.
*/
class SrsConfig
{
// user command
private:
    /**
     * whether srs is run in dolphin mode.
     * @see https://github.com/ossrs/srs-dolphin
     */
    bool dolphin;
    std::string dolphin_rtmp_port;
    std::string dolphin_http_port;
    /**
    * whether show help and exit.
    */
    bool show_help;
    /**
    * whether test config file and exit.
    */
    bool test_conf;
    /**
    * whether show SRS version and exit.
    */
    bool show_version;
// global env variables.
private:
    /**
    * the user parameters, the argc and argv.
    * the argv is " ".join(argv), where argv is from main(argc, argv).
    */
    std::string _argv;
    /**
    * current working directory.
    */
    std::string _cwd;
// config section
private:
    /**
    * the last parsed config file.
    * if reload, reload the config file.
    */
    std::string config_file;
    /**
    * the directive root.
    */
    SrsConfDirective* root;
// reload section
private:
    /**
    * the reload subscribers, when reload, callback all handlers.
    */
    std::vector<ISrsReloadHandler*> subscribes;
public:
    SrsConfig();
    virtual ~SrsConfig();
// dolphin
public:
    /**
     * whether srs is in dolphin mode.
     */
    virtual bool is_dolphin();
private:
    virtual void set_config_directive(SrsConfDirective* parent, std::string dir, std::string value);
// reload
public:
    /**
    * for reload handler to register itself,
    * when config service do the reload, callback the handler.
    */
    virtual void subscribe(ISrsReloadHandler* handler);
    /**
    * for reload handler to unregister itself.
    */
    virtual void unsubscribe(ISrsReloadHandler* handler);
    /**
    * reload the config file.
    * @remark, user can test the config before reload it.
    */
    virtual int reload();
private:
    /**
    * reload the vhost section of config.
    */
    virtual int reload_vhost(SrsConfDirective* old_root);
protected:
    /**
    * reload from the config.
    * @remark, use protected for the utest to override with mock.
    */
    virtual int reload_conf(SrsConfig* conf);
private:
    /**
    * reload the http_api section of config.
    */
    virtual int reload_http_api(SrsConfDirective* old_root);
    /**
    * reload the http_stream section of config.
    */
    virtual int reload_http_stream(SrsConfDirective* old_root);
    /**
    * reload the transcode section of vhost of config.
    */
    virtual int reload_transcode(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost);
    /**
    * reload the ingest section of vhost of config.
    */
    virtual int reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost);
// parse options and file
public:
    /**
    * parse the cli, the main(argc,argv) function.
    */
    virtual int parse_options(int argc, char** argv);
    /**
     * initialize the cwd for server,
     * because we may change the workdir.
     */
    virtual int initialize_cwd();
    /**
    * get the config file path.
    */
    virtual std::string config();
private:
    /**
    * parse each argv.
    */
    virtual int parse_argv(int& i, char** argv);
    /**
    * print help and exit.
    */
    virtual void print_help(char** argv);
public:
    /**
    * parse the config file, which is specified by cli.
    */
    virtual int parse_file(const char* filename);
    /**
    * check the parsed config.
    */
    virtual int check_config();
protected:
    /**
    * parse config from the buffer.
    * @param buffer, the config buffer, user must delete it.
    * @remark, use protected for the utest to override with mock.
    */
    virtual int parse_buffer(_srs_internal::SrsConfigBuffer* buffer);
// global env
public:
    /**
    * get the current work directory.
    */
    virtual std::string         cwd();
    /**
    * get the cli, the main(argc,argv), program start command.
    */
    virtual std::string         argv();
// global section
public:
    /**
    * get the directive root, corresponding to the config file.
    * the root directive, no name and args, contains directives.
    * all directive parsed can retrieve from root.
    */
    virtual SrsConfDirective*   get_root();
    /**
    * get the deamon config.
    * if true, SRS will run in deamon mode, fork and fork to reap the
    * grand-child process to init process.
    */
    virtual bool                get_deamon();
    /**
    * get the max connections limit of system.
    * if exceed the max connection, SRS will disconnect the connection.
    * @remark, linux will limit the connections of each process,
    *       for example, when you need SRS to service 10000+ connections,
    *       user must use "ulimit -HSn 10000" and config the max connections
    *       of SRS.
    */
    virtual int                 get_max_connections();
    /**
    * get the listen port of SRS.
    * user can specifies multiple listen ports,
    * each args of directive is a listen port.
    */
    virtual std::vector<std::string>        get_listens();
    /**
    * get the pid file path.
    * the pid file is used to save the pid of SRS,
    * use file lock to prevent multiple SRS starting.
    * @remark, if user need to run multiple SRS instance,
    *       for example, to start multiple SRS for multiple CPUs,
    *       user can use different pid file for each process.
    */
    virtual std::string         get_pid_file();
    /**
    * get pithy print pulse ms,
    * for example, all rtmp connections only print one message
    * every this interval in ms.
    */
    virtual int                 get_pithy_print_ms();
    /**
     * whether use utc-time to format the time.
     */
    virtual bool                get_utc_time();
    /**
     * get the configed work dir.
     * ignore if empty string.
     */
    virtual std::string         get_work_dir();
    // whether use asprocess mode.
    virtual bool                get_asprocess();
// stream_caster section
public:
    /**
    * get all stream_caster in config file.
    */
    virtual std::vector<SrsConfDirective*>  get_stream_casters();
    /**
    * get whether the specified stream_caster is enabled.
    */
    virtual bool                get_stream_caster_enabled(SrsConfDirective* sc);
    /**
    * get the engine of stream_caster, the caster config.
    */
    virtual std::string         get_stream_caster_engine(SrsConfDirective* sc);
    /**
    * get the output rtmp url of stream_caster, the output config.
    */
    virtual std::string         get_stream_caster_output(SrsConfDirective* sc);
    /**
    * get the listen port of stream caster.
    */
    virtual int                 get_stream_caster_listen(SrsConfDirective* sc);
    /**
    * get the min udp port for rtp of stream caster rtsp.
    */
    virtual int                 get_stream_caster_rtp_port_min(SrsConfDirective* sc);
    /**
    * get the max udp port for rtp of stream caster rtsp.
    */
    virtual int                 get_stream_caster_rtp_port_max(SrsConfDirective* sc);
// vhost specified section
public:
    /**
    * get the vhost directive by vhost name.
    * @param vhost, the name of vhost to get.
    */
    virtual SrsConfDirective*   get_vhost(std::string vhost);
    /**
    * get all vhosts in config file.
    */
    virtual void get_vhosts(std::vector<SrsConfDirective*>& vhosts);
    /**
    * whether vhost is enabled
    * @param vhost, the vhost name.
    * @return true when vhost is ok; otherwise, false.
    */
    virtual bool                get_vhost_enabled(std::string vhost);
    /**
    * whether vhost is enabled
    * @param vhost, the vhost directive.
    * @return true when vhost is ok; otherwise, false.
    */
    virtual bool                get_vhost_enabled(SrsConfDirective* vhost);
    /**
    * whether gop_cache is enabled of vhost.
    * gop_cache used to cache last gop, for client to fast startup.
    * @return true when gop_cache is ok; otherwise, false.
    * @remark, default true.
    */
    virtual bool                get_gop_cache(std::string vhost);
    /**
    * whether debug_srs_upnode is enabled of vhost.
    * debug_srs_upnode is very important feature for tracable log,
    * but some server, for instance, flussonic donot support it.
    * @see https://github.com/ossrs/srs/issues/160
    * @return true when debug_srs_upnode is ok; otherwise, false.
    * @remark, default true.
    */
    virtual bool                get_debug_srs_upnode(std::string vhost);
    /**
    * whether atc is enabled of vhost.
    * atc always use encoder timestamp, SRS never adjust the time.
    * @return true when atc is ok; otherwise, false.
    * @remark, default false.
    */
    virtual bool                get_atc(std::string vhost);
    /**
    * whether atc_auto is enabled of vhost.
    * atc_auto used to auto enable atc, when metadata specified the bravo_atc.
    * @return true when atc_auto is ok; otherwise, false.
    * @remark, default true.
    */
    virtual bool                get_atc_auto(std::string vhost);
    /**
    * get the time_jitter algorithm.
    * @return the time_jitter algorithm, defined in SrsRtmpJitterAlgorithm.
    * @remark, default full.
    */
    virtual int                 get_time_jitter(std::string vhost);
    /**
     * whether use mix correct algorithm to ensure the timestamp
     * monotonically increase.
     */
    virtual bool                get_mix_correct(std::string vhost);
    /**
    * get the cache queue length, in seconds.
    * when exceed the queue length, drop packet util I frame.
    * @remark, default 10.
    */
    virtual double              get_queue_length(std::string vhost);
    /**
    * get the refer antisuck directive.
    * each args of directive is a refer config.
    * when the client refer(pageUrl) not match the refer config,
    * SRS will reject the connection.
    * @remark, default NULL.
    */
    virtual SrsConfDirective*   get_refer(std::string vhost);
    /**
    * get the play refer, refer for play clients.
    * @remark, default NULL.
    */
    virtual SrsConfDirective*   get_refer_play(std::string vhost);
    /**
    * get the publish refer, refer for publish clients.
    * @remark, default NULL.
    */
    virtual SrsConfDirective*   get_refer_publish(std::string vhost);
    /**
    * get the chunk size of vhost.
    * @param vhost, the vhost to get the chunk size. use global if not specified.
    *       empty string to get the global.
    * @remark, default 60000.
    */
    virtual int                 get_chunk_size(std::string vhost);
    /**
     * whether parse the sps when publish stream to SRS.
     */
    virtual bool                get_parse_sps(std::string vhost);
    /**
    * whether mr is enabled for vhost.
    * @param vhost, the vhost to get the mr.
    */
    virtual bool                get_mr_enabled(std::string vhost);
    /**
    * get the mr sleep time in ms for vhost.
    * @param vhost, the vhost to get the mr sleep time.
    */
    // TODO: FIXME: add utest for mr config.
    virtual int                 get_mr_sleep_ms(std::string vhost);
    /**
    * get the mw sleep time in ms for vhost.
    * @param vhost, the vhost to get the mw sleep time.
    */
    // TODO: FIXME: add utest for mw config.
    virtual int                 get_mw_sleep_ms(std::string vhost);
    /**
    * whether min latency mode enabled.
    * @param vhost, the vhost to get the min_latency.
    */
    // TODO: FIXME: add utest for min_latency.
    virtual bool                get_realtime_enabled(std::string vhost);
    /**
     * whether enable tcp nodelay for all clients of vhost.
     */
    virtual bool                get_tcp_nodelay(std::string vhost);
    /**
     * the minimal send interval in ms.
     */
    virtual double              get_send_min_interval(std::string vhost);
    /**
     * whether reduce the sequence header.
     */
    virtual bool                get_reduce_sequence_header(std::string vhost);
    /**
     * the 1st packet timeout in ms for encoder.
     */
    virtual int                 get_publish_1stpkt_timeout(std::string vhost);
    /**
     * the normal packet timeout in ms for encoder.
     */
    virtual int                 get_publish_normal_timeout(std::string vhost);
private:
    /**
    * get the global chunk size.
    */
    virtual int                 get_global_chunk_size();
// forward section
public:
    /**
    * get the forward directive of vhost.
    */
    virtual SrsConfDirective*   get_forward(std::string vhost);
// http_hooks section
private:
    /**
    * get the http_hooks directive of vhost.
    */
    virtual SrsConfDirective*   get_vhost_http_hooks(std::string vhost);
public:
    /**
    * whether vhost http-hooks enabled.
    * @remark, if not enabled, donot callback all http hooks.
    */
    virtual bool                get_vhost_http_hooks_enabled(std::string vhost);
    /**
    * get the on_connect callbacks of vhost.
    * @return the on_connect callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_connect(std::string vhost);
    /**
    * get the on_close callbacks of vhost.
    * @return the on_close callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_close(std::string vhost);
    /**
    * get the on_publish callbacks of vhost.
    * @return the on_publish callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_publish(std::string vhost);
    /**
    * get the on_unpublish callbacks of vhost.
    * @return the on_unpublish callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_unpublish(std::string vhost);
    /**
    * get the on_play callbacks of vhost.
    * @return the on_play callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_play(std::string vhost);
    /**
    * get the on_stop callbacks of vhost.
    * @return the on_stop callback directive, the args is the url to callback.
    */
    virtual SrsConfDirective*   get_vhost_on_stop(std::string vhost);
    /**
     * get the on_dvr callbacks of vhost.
     * @return the on_dvr callback directive, the args is the url to callback.
     */
    virtual SrsConfDirective*   get_vhost_on_dvr(std::string vhost);
    /**
     * get the on_hls callbacks of vhost.
     * @return the on_hls callback directive, the args is the url to callback.
     */
    virtual SrsConfDirective*   get_vhost_on_hls(std::string vhost);
    /**
     * get the on_hls_notify callbacks of vhost.
     * @return the on_hls_notify callback directive, the args is the url to callback.
     */
    virtual SrsConfDirective*   get_vhost_on_hls_notify(std::string vhost);
// bwct(bandwidth check tool) section
public:
    /**
    * whether bw check enabled for vhost.
    * if enabled, serve all clients with bandwidth check services.
    * oterwise, serve all cleints with stream.
    */
    virtual bool                get_bw_check_enabled(std::string vhost);
    /**
    * the key of server, if client key mot match, reject.
    */
    virtual std::string         get_bw_check_key(std::string vhost);
    /**
    * the check interval, in ms.
    * if the client request check in very short time(in the interval),
    * SRS will reject client.
    * @remark this is used to prevent the bandwidth check attack.
    */
    virtual int                 get_bw_check_interval_ms(std::string vhost);
    /**
    * the max kbps that user can test,
    * if exceed the kbps, server will slowdown the send-recv.
    * @remark this is used to protect the service bandwidth.
    */
    virtual int                 get_bw_check_limit_kbps(std::string vhost);
// vhost edge section
public:
    /**
    * whether vhost is edge mode.
    * for edge, publish client will be proxyed to upnode,
    * for edge, play client will share a connection to get stream from upnode.
    */
    virtual bool                get_vhost_is_edge(std::string vhost);
    /**
    * whether vhost is edge mode.
    * for edge, publish client will be proxyed to upnode,
    * for edge, play client will share a connection to get stream from upnode.
    */
    virtual bool                get_vhost_is_edge(SrsConfDirective* vhost);
    /**
    * get the origin config of edge,
    * specifies the origin ip address, port.
    */
    virtual SrsConfDirective*   get_vhost_edge_origin(std::string vhost);
    /**
    * whether edge token tranverse is enabled,
    * if true, edge will send connect origin to verfy the token of client.
    * for example, we verify all clients on the origin FMS by server-side as,
    * all clients connected to edge must be tranverse to origin to verify.
    */
    virtual bool                get_vhost_edge_token_traverse(std::string vhost);
    /**
     * get the transformed vhost for edge,
     * @see https://github.com/ossrs/srs/issues/372
     */
    virtual std::string         get_vhost_edge_transform_vhost(std::string vhost);
// vhost security section
public:
    /**
    * whether the secrity of vhost enabled.
    */
    virtual bool                get_security_enabled(std::string vhost);
    /**
    * get the security rules.
    */
    virtual SrsConfDirective*   get_security_rules(std::string vhost);
// vhost transcode section
public:
    /**
    * get the transcode directive of vhost in specified scope.
    * @param vhost, the vhost name to get the transcode directive.
    * @param scope, the scope, empty to get all. for example, user can transcode
    *       the app scope stream, by config with app:
    *                   transcode live {...}
    *       when the scope is "live", this directive is matched.
    *       the scope can be: empty for all, app, app/stream.
    * @remark, please see the samples of full.conf, the app.transcode.srs.com
    *       and stream.transcode.srs.com.
    */
    virtual SrsConfDirective*   get_transcode(std::string vhost, std::string scope);
    /**
    * whether the transcode directive is enabled.
    */
    virtual bool                get_transcode_enabled(SrsConfDirective* transcode);
    /**
    * get the ffmpeg tool path of transcode.
    */
    virtual std::string         get_transcode_ffmpeg(SrsConfDirective* transcode);
    /**
    * get the engines of transcode.
    */
    virtual std::vector<SrsConfDirective*>      get_transcode_engines(SrsConfDirective* transcode);
    /**
    * whether the engine is enabled.
    */
    virtual bool                get_engine_enabled(SrsConfDirective* engine);
    /**
    * get the iformat of engine
    */
    virtual std::string         get_engine_iformat(SrsConfDirective* engine);
    /**
    * get the vfilter of engine,
    * the video filter set before the vcodec of FFMPEG.
    */
    virtual std::vector<std::string> get_engine_vfilter(SrsConfDirective* engine);
    /**
    * get the vcodec of engine,
    * the codec of video, can be vn, copy or libx264
    */
    virtual std::string         get_engine_vcodec(SrsConfDirective* engine);
    /**
    * get the vbitrate of engine,
    * the bitrate in kbps of video, for example, 800kbps
    */
    virtual int                 get_engine_vbitrate(SrsConfDirective* engine);
    /**
    * get the vfps of engine.
    * the video fps, for example, 25fps
    */
    virtual double              get_engine_vfps(SrsConfDirective* engine);
    /**
    * get the vwidth of engine,
    * the video width, for example, 1024
    */
    virtual int                 get_engine_vwidth(SrsConfDirective* engine);
    /**
    * get the vheight of engine,
    * the video height, for example, 576
    */
    virtual int                 get_engine_vheight(SrsConfDirective* engine);
    /**
    * get the vthreads of engine,
    * the video transcode libx264 threads, for instance, 8
    */
    virtual int                 get_engine_vthreads(SrsConfDirective* engine);
    /**
    * get the vprofile of engine,
    * the libx264 profile, can be high,main,baseline
    */
    virtual std::string         get_engine_vprofile(SrsConfDirective* engine);
    /**
    * get the vpreset of engine,
    * the libx264 preset, can be ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo
    */
    virtual std::string         get_engine_vpreset(SrsConfDirective* engine);
    /**
    * get the additional video params.
    */
    virtual std::vector<std::string> get_engine_vparams(SrsConfDirective* engine);
    /**
    * get the acodec of engine,
    * the audio codec can be an, copy or libfdk_aac
    */
    virtual std::string         get_engine_acodec(SrsConfDirective* engine);
    /**
    * get the abitrate of engine,
    * the audio bitrate in kbps, for instance, 64kbps.
    */
    virtual int                 get_engine_abitrate(SrsConfDirective* engine);
    /**
    * get the asample_rate of engine,
    * the audio sample_rate, for instance, 44100HZ
    */
    virtual int                 get_engine_asample_rate(SrsConfDirective* engine);
    /**
    * get the achannels of engine,
    * the audio channel, for instance, 1 for mono, 2 for stereo.
    */
    virtual int                 get_engine_achannels(SrsConfDirective* engine);
    /**
    * get the aparams of engine,
    * the audio additional params.
    */
    virtual std::vector<std::string> get_engine_aparams(SrsConfDirective* engine);
    /**
    * get the oformat of engine
    */
    virtual std::string         get_engine_oformat(SrsConfDirective* engine);
    /**
    * get the output of engine, for example, rtmp://localhost/live/livestream,
    * @remark, we will use some variable, for instance, [vhost] to substitude with vhost.
    */
    virtual std::string         get_engine_output(SrsConfDirective* engine);
// vhost ingest section
public:
    /**
    * get the ingest directives of vhost.
    */
    virtual std::vector<SrsConfDirective*> get_ingesters(std::string vhost);
    /**
    * get specified ingest.
    */
    virtual SrsConfDirective*   get_ingest_by_id(std::string vhost, std::string ingest_id);
    /**
    * whether ingest is enalbed.
    */
    virtual bool                get_ingest_enabled(SrsConfDirective* ingest);
    /**
    * get the ingest ffmpeg tool
    */
    virtual std::string         get_ingest_ffmpeg(SrsConfDirective* ingest);
    /**
    * get the ingest input type, file or stream.
    */
    virtual std::string         get_ingest_input_type(SrsConfDirective* ingest);
    /**
    * get the ingest input url.
    */
    virtual std::string         get_ingest_input_url(SrsConfDirective* ingest);
// log section
public:
    /**
    * whether log to file.
    */
    virtual bool                get_log_tank_file();
    /**
    * get the log level.
    */
    virtual std::string         get_log_level();
    /**
    * get the log file path.
    */
    virtual std::string         get_log_file();
    /**
    * whether ffmpeg log enabled
    */
    virtual bool                get_ffmpeg_log_enabled();
    /**
    * the ffmpeg log dir.
    * @remark, /dev/null to disable it.
    */
    virtual std::string         get_ffmpeg_log_dir();
// hls section
private:
    /**
    * get the hls directive of vhost.
    */
    virtual SrsConfDirective*   get_hls(std::string vhost);
public:
    /**
    * whether HLS is enabled.
    */
    virtual bool                get_hls_enabled(std::string vhost);
    /**
    * get the HLS m3u8 list ts segment entry prefix info.
    */
    virtual std::string         get_hls_entry_prefix(std::string vhost);
    /**
     * get the HLS ts/m3u8 file store path.
     */
    virtual std::string         get_hls_path(std::string vhost);
    /**
     * get the HLS m3u8 file path template.
     */
    virtual std::string         get_hls_m3u8_file(std::string vhost);
    /**
     * get the HLS ts file path template.
     */
    virtual std::string         get_hls_ts_file(std::string vhost);
    /**
     * whether enable the floor(timestamp/hls_fragment) for variable timestamp.
     */
    virtual bool                get_hls_ts_floor(std::string vhost);
    /**
    * get the hls fragment time, in seconds.
    */
    virtual double              get_hls_fragment(std::string vhost);
    /**
    * get the hls td(target duration) ratio.
    */
    virtual double              get_hls_td_ratio(std::string vhost);
    /**
     * get the hls aof(audio overflow) ratio.
     */
    virtual double              get_hls_aof_ratio(std::string vhost);
    /**
    * get the hls window time, in seconds.
    * a window is a set of ts, the ts collection in m3u8.
    * @remark SRS will delete the ts exceed the window.
    */
    virtual double              get_hls_window(std::string vhost);
    /**
    * get the hls hls_on_error config.
    * the ignore will ignore error and disable hls.
    * the disconnect will disconnect publish connection.
    * @see https://github.com/ossrs/srs/issues/264
    */
    virtual std::string         get_hls_on_error(std::string vhost);
    /**
    * get the HLS default audio codec.
    */
    virtual std::string         get_hls_acodec(std::string vhost);
    /**
    * get the HLS default video codec.
    */
    virtual std::string         get_hls_vcodec(std::string vhost);
    /**
     * whether cleanup the old ts files.
     */
    virtual bool                get_hls_cleanup(std::string vhost);
    /**
     * the timeout to dispose the hls.
     */
    virtual int                 get_hls_dispose(std::string vhost);
    /**
     * whether reap the ts when got keyframe.
     */
    virtual bool                get_hls_wait_keyframe(std::string vhost);
    /**
     * get the size of bytes to read from cdn network, for the on_hls_notify callback,
     * that is, to read max bytes of the bytes from the callback, or timeout or error.
     */
    virtual int                 get_vhost_hls_nb_notify(std::string vhost);
// hds section
private:
    /**
    * get the hds directive of vhost.
    */
    virtual SrsConfDirective*   get_hds(const std::string &vhost);
public:
    /**
    * whether HDS is enabled.
    */
    virtual bool                get_hds_enabled(const std::string &vhost);
    /**
    * get the HDS file store path.
    */
    virtual std::string         get_hds_path(const std::string &vhost);
    /**
    * get the hds fragment time, in seconds.
    */
    virtual double              get_hds_fragment(const std::string &vhost);
    /**
    * get the hds window time, in seconds.
    * a window is a set of hds fragments.
    */
    virtual double              get_hds_window(const std::string &vhost);

// dvr section
private:
    /**
    * get the dvr directive.
    */
    virtual SrsConfDirective*   get_dvr(std::string vhost);
public:
    /**
    * whether dvr is enabled.
    */
    virtual bool                get_dvr_enabled(std::string vhost);
    /**
    * get the dvr path, the flv file to save in.
    */
    virtual std::string         get_dvr_path(std::string vhost);
    /**
    * get the plan of dvr, how to reap the flv file.
    */
    virtual std::string         get_dvr_plan(std::string vhost);
    /**
    * get the duration of dvr flv.
    */
    virtual int                 get_dvr_duration(std::string vhost);
    /**
    * whether wait keyframe to reap segment.
    */
    virtual bool                get_dvr_wait_keyframe(std::string vhost);
    /**
    * get the time_jitter algorithm for dvr.
    */
    virtual int                 get_dvr_time_jitter(std::string vhost);
// http api section
private:
    /**
    * get the http api directive.
    */
    virtual SrsConfDirective*   get_http_api();
    /**
    * whether http api enabled
    */
    virtual bool                get_http_api_enabled(SrsConfDirective* conf);
public:
    /**
    * whether http api enabled.
    */
    virtual bool                get_http_api_enabled();
    /**
    * get the http api listen port.
    */
    virtual std::string         get_http_api_listen();
    /**
    * whether enable crossdomain for http api.
    */
    virtual bool                get_http_api_crossdomain();
// http stream section
private:
    /**
    * get the http stream directive.
    */
    virtual SrsConfDirective*   get_http_stream();
    /**
    * whether http stream enabled.
    */
    virtual bool                get_http_stream_enabled(SrsConfDirective* conf);
public:
    /**
    * whether http stream enabled.
    */
    virtual bool                get_http_stream_enabled();
    /**
    * get the http stream listen port.
    */
    virtual std::string         get_http_stream_listen();
    /**
    * get the http stream root dir.
    */
    virtual std::string         get_http_stream_dir();
public:
    /**
    * get whether vhost enabled http stream
    */
    virtual bool                get_vhost_http_enabled(std::string vhost);
    /**
    * get the http mount point for vhost.
    * for example, http://vhost/live/livestream
    */
    virtual std::string         get_vhost_http_mount(std::string vhost);
    /**
    * get the http dir for vhost.
    * the path on disk for mount root of http vhost.
    */
    virtual std::string         get_vhost_http_dir(std::string vhost);
// flv live streaming section
public:
    /**
    * get whether vhost enabled http flv live stream
    */
    virtual bool                get_vhost_http_remux_enabled(std::string vhost);
    /**
    * get the fast cache duration for http audio live stream.
    */
    virtual double              get_vhost_http_remux_fast_cache(std::string vhost);
    /**
    * get the http flv live stream mount point for vhost.
    * used to generate the flv stream mount path.
    */
    virtual std::string         get_vhost_http_remux_mount(std::string vhost);
    /**
    * get whether the hstrs(http stream trigger rtmp source) enabled.
    */
    virtual bool                get_vhost_http_remux_hstrs(std::string vhost);
// http heartbeart section
private:
    /**
    * get the heartbeat directive.
    */
    virtual SrsConfDirective*   get_heartbeart();
public:
    /**
    * whether heartbeat enabled.
    */
    virtual bool                get_heartbeat_enabled();
    /**
    * get the heartbeat interval, in ms.
    */
    virtual int64_t             get_heartbeat_interval();
    /**
    * get the heartbeat report url.
    */
    virtual std::string         get_heartbeat_url();
    /**
    * get the device id of heartbeat, to report to server.
    */
    virtual std::string         get_heartbeat_device_id();
    /**
    * whether report with summaries of http api: /api/v1/summaries.
    */
    virtual bool                get_heartbeat_summaries();
// stats section
private:
    /**
    * get the stats directive.
    */
    virtual SrsConfDirective*   get_stats();
public:
    /**
    * get the network device index, used to retrieve the ip of device,
    * for heartbeat to report to server, or to get the local ip.
    * for example, 0 means the eth0 maybe.
    */
    virtual int                 get_stats_network();
    /**
    * get the disk stat device name list.
    * the device name configed in args of directive.
    * @return the disk device name to stat. NULL if not configed.
    */
    virtual SrsConfDirective*   get_stats_disk_device();
};

1.2 SrsConfDirective 类

/**
* the config directive.
* the config file is a group of directives,
* all directive has name, args and child-directives.
* for example, the following config text:
        vhost vhost.ossrs.net {
            enabled         on;
            ingest livestream {
                enabled      on;
                ffmpeg       /bin/ffmpeg;
            }
        }
* will be parsed to:
*       SrsConfDirective: name="vhost", arg0="vhost.ossrs.net", child-directives=[
*           SrsConfDirective: name="enabled", arg0="on", child-directives=[]
*           SrsConfDirective: name="ingest", arg0="livestream", child-directives=[
*               SrsConfDirective: name="enabled", arg0="on", child-directives=[]
*               SrsConfDirective: name="ffmpeg", arg0="/bin/ffmpeg", child-directives=[]
*           ]
*       ]
* @remark, allow empty directive, for example: "dir0 {}"
* @remark, don‘t allow empty name, for example: ";" or "{dir0 arg0;}
*/
class SrsConfDirective
{
public:
    /**
    * the line of config file in which the directive from
    */
    int conf_line;
    /**
    * the name of directive, for example, the following config text:
    *       enabled     on;
    * will be parsed to a directive, its name is "enalbed"
    */
    std::string name;
    /**
    * the args of directive, for example, the following config text:
    *       listen      1935 1936;
    * will be parsed to a directive, its args is ["1935", "1936"].
    */
    std::vector<std::string> args;
    /**
    * the child directives, for example, the following config text:
    *       vhost vhost.ossrs.net {
    *           enabled         on;
    *       }
    * will be parsed to a directive, its directives is a vector contains
    * a directive, which is:
    *       name:"enalbed", args:["on"], directives:[]
    *
    * @remark, the directives can contains directives.
    */
    std::vector<SrsConfDirective*> directives;
public:
    SrsConfDirective();
    virtual ~SrsConfDirective();
// args
public:
    /**
    * get the args0,1,2, if user want to get more args,
    * directly use the args.at(index).
    */
    virtual std::string arg0();
    virtual std::string arg1();
    virtual std::string arg2();
// directives
public:
    /**
    * get the directive by index.
    * @remark, assert the index<directives.size().
    */
    virtual SrsConfDirective* at(int index);
    /**
    * get the directive by name, return the first match.
    */
    virtual SrsConfDirective* get(std::string _name);
    /**
    * get the directive by name and its arg0, return the first match.
    */
    virtual SrsConfDirective* get(std::string _name, std::string _arg0);
// help utilities
public:
    /**
    * whether current directive is vhost.
    */
    virtual bool is_vhost();
    /**
    * whether current directive is stream_caster.
    */
    virtual bool is_stream_caster();
// parse utilities
public:
    /**
    * parse config directive from file buffer.
    */
    virtual int parse(_srs_internal::SrsConfigBuffer* buffer);
// private parse.
private:
    /**
    * the directive parsing type.
    */
    enum SrsDirectiveType {
        /**
        * the root directives, parsing file.
        */
        parse_file,
        /**
        * for each direcitve, parsing text block.
        */
        parse_block
    };
    /**
    * parse the conf from buffer. the work flow:
    * 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 int parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDirectiveType type);
    /**
    * 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.
    * @param line_start, the actual start line of directive.
    * @return, an error code indicates error or has child-directives.
    */
    virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector<std::string>& args, int& line_start);
};

1.3 SrsConfigBuffer

namespace _srs_internal
{
    class SrsConfigBuffer;
}

namespace _srs_internal
{
    /**
    * the buffer of config content.
    */
    class SrsConfigBuffer
    {
    protected:
        // last available position.
        char* last;
        // end of buffer.
        char* end;
        // start of buffer.
        char* start;
    public:
        // current consumed position.
        char* pos;
        // current parsed line.
        int line;
    public:
        SrsConfigBuffer();
        virtual ~SrsConfigBuffer();
    public:
        /**
        * fullfill the buffer with content of file specified by filename.
        */
        virtual int fullfill(const char* filename);
        /**
        * whether buffer is empty.
        */
        virtual bool empty();
    };
};

2. 函数实现

2.1 SrsConfig::parse_options

// see: ngx_get_options
int SrsConfig::parse_options(int argc, char** argv)
{
    int ret = ERROR_SUCCESS;

    // argv: 将 argv 中的数据拷贝到 _argv 中,多个字符串之间以 " " 间隔
    for (int i = 0; i < argc; i++) {
        _argv.append(argv[i]);

        if (i < argc - 1) {
            _argv.append(" ");
        }
    }

    // config: 解析通过命令行传入的参数
    show_help = true;
    for (int i = 1; i < argc; i++) {
        if ((ret = parse_argv(i, argv)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    if (show_help) {
        print_help(argv);
        exit(0);
    }

    if (show_version) {
        fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);
        exit(0);
    }

    // first hello message.
    srs_trace(_srs_version);

    if (config_file.empty()) {
        ret = ERROR_SYSTEM_CONFIG_INVALID;
        srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret);
        return ret;
    }

    // 解析配置文件
    ret = parse_file(config_file.c_str());

    if (test_conf) {
        // the parse_file never check the config,
        // we check it when user requires check config file.
        if (ret == ERROR_SUCCESS) {
            ret = check_ocnfig();
        }

        if (ret == ERROR_SUCCESS) {
            srs_trace("config file is ok");
            exit(0);
        } else {
            srs_error("config file is invalid");
            exit(ret);
        }
    }

    ////////////////////////////////////////////////////////////////////////
    // check log name and level
    ////////////////////////////////////////////////////////////////////////
    if (true) {
        /* 从 root 指令中获取"srs_log_file"指令指定的log文件路径,若没有找到,
         * 则使用默认log文件: "./objs/srs.log" */
        std::string log_filename = this->get_log_file();
        if (get_log_tank_file() && log_filename.empty()) {
            ret = ERROR_SYSTEM_CONFIG_INVALID;
            srs_error("must specifies the file to write log to. ret=%d", ret);
            return ret;
        }
        // 将日志保存到文件中
        if (get_log_tank_file()) {
            srs_trace("write log to file %s", log_filename.c_str());
            srs_trace("you can: tailf %s", log_filename.c_str());
            srs_trace("@see: %s", SRS_WIKI_URL_LOG);
        } else { // 否则,将日志打印到 console 中
            srs_trace("write log to console");
        }
    }
}

2.2 SrsConfig::parse_argv

int SrsConfig::parse_argv(int& i, char** argv)
{
    int ret = ERROR_SUCCESS;

    char* p = argv[i];

    if (*p++ != ‘-‘) {
        show_help = true;
        return ret;
    }

    while (*p) {
        switch (*p++) {
            case ‘?‘:
            case ‘h‘:
                show_help = true;
                break;
            case ‘t‘:
                show_help = false;
                test_conf = true;
                break;
            case ‘p‘:
                dolphin = true;
                if (*p) {
                    dolphin_rtmp_port = p;
                    continue;
                }
                if (argv[++i]) {
                    dolphin_rtmp_port = argv[i];
                    continue;
                }
                ret = ERROR_SYSTEM_CONFIG_INVALID;
                srs_error("option \"-p\" requires params, ret=%d", ret);
                return ret;
            case ‘x‘:
                dolphin = true;
                if (*p) {
                    dolphin_http_port = p;
                    continue;
                }
                if (argv[++i]) {
                    dolphin_http_port = argv[i];
                    continue;
                }
                ret = ERROR_SYSTEM_CONFIG_INVALID;
                srs_error("option \"-x\" requires params, ret=%d", ret);
                return ret;
            case ‘v‘:
            case ‘V‘:
                show_help = false;
                show_version = true;
                break;
            case ‘c‘:
                show_help = false;
                if (*p) {
                    config_file = p;
                    continue;
                }
                if (argv[++i]) {
                    config_file = argv[i];
                    continue;
                }
                ret = ERROR_SYSTEM_CONFIG_INVALID;
                srs_error("option \"-c\" requires parameter, ret=%d", ret);
                return ret;
            default:
                ret = ERROR_SYSTEM_CONFIG_INVALID;
                srs_error("invalid option: \"%c\", see help: %s -h, ret=%d", *(p - 1), argv[0], ret);
                return ret;
        }
    }

    return ret;
}

2.3 SrsConfig::parse_file

int SrsConfig::parse_file(const char *filename)
{
    int ret = ERROR_SUCCESS;

    config_file = filename;

    if (config_file.empty()) {
        return ERROR_SYSTEM_CONFIG_INVALID;
    }

    // 构造一个 SrsConfigBuffer 类的变量,用于存放配置文件的内容
    SrsConfigBuffer buffer;

    // 将配置文件的内容填充到 buffer 缓存中
    if ((ret = buffer.fullfill(config_file.c_str())) != ERROR_SUCCESS) {
        return ret;
    }

    // 解析 buffer 中的配置项
    return parse_buffer(&buffer);
}

2.4 namespace _srs_internal

namespace _srs_internal
{
    SrsConfigBuffer::SrsConfigBuffer()
    {
        line = 1;

        pos = last = start = NULL;
        end = start;
    }

    SrsConfigBuffer::~SrsConfigBuffer()
    {
        srs_freepa(start);
    }

    int SrsConfigBuffer::fullfill(const char *filename)
    {
        int ret = ERROR_SUCCESS;

        SrsFileReader reader;

        // open file reader.
        if ((ret = reader.open(filename)) != ERROR_SUCCESS) {
            srs_error("open conf file error. ret=%d", ret);
            return ret;
        }

        // read all.
        int filesize = (int)reader.filesize();

        // create buffer
        srs_freepa(start);
        pos = last = start = new char[filesize];
        end = start + filesize;

        // read total content from file.
        ssize_t nread = 0;
        if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) {
            srs_error("read file read error. expect %d, actual %d bytes, ret=%d",
                filesize, nread, ret);
            return ret;
        }

        return ret;
    }

    bool SrsConfigBuffer::empty()
    {
        return pos >= end;
    }
}

2.5 SrsConfig::parse_buffer

int SrsConfig::parse_buffer(SrsConfigBuffer* buffer)
{
    int ret = ERROR_SUCCESS;

    /* 解析 buffer 中的配置,解析出来的配置值保存在 root 指令中,
     * root 构建了一个指令树,保存着配置文件中所有指令 */
    if ((ret = root->parse(buffer)) != ERROR_SUCCESS) {
        return ret;
    }

    // mock by dolphin mode.
    // for the dolphin will start srs with specified params.
    if (dolphin) {
        // for RTMP.
        set_config_directive(root, "listen", dolphin_rtmp_port);

        // for HTTP.
        set_config_directive(root, "http_server", "");
        SrsConfDirective* http_server = root->get("http_server");
        set_config_directive(http_server, "enabled", "on");
        set_config_directive(http_server, "listen", dolphin_http_port);

        // others.
        set_config_directive(root, "daemon", "off");
        set_config_directive(root, "srs_log_tank", "console");
    }

    return ret;
}

2.5.1 SrsConfig::set_config_directive

void SrsConfig::set_config_directive(SrsConfDirective* parent, string dir, string value)
{
    // 尝试从 parent 中获取该 dir 指令
    SrsConfDirective* d = parent->get(dir);

    // 若 parent 指令中没有该 dir 子指令,则创建一个新指令
    if (!d) {
        d = new SrsConfDirective();
        if (!dir.empty()) {
            d->name = dir;
        }
        parent->directive.push_back(d);
    }

    // 清空该指令的参数
    d->args.clear();

    if (!value.empty) {
        d->args.push_back(value);
    }
}

2.6 SrsConfDirective::parse

int SrsConfDirective::parse(SrsConfigBuffer* buffer)
{
    // parse_file 表示当前开始解析配置文件
    return parse_conf(buffer, parse_file);
}

2.7 SrsConfDirective::parse_conf

// see: ngx_conf_parse
int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type)
{
    int ret = ERROR_SUCCESS;

    while (true) {
        std::vector<string> args;
        int line_start = 0;
        // 读取一行内容
        ret = read_token(buffer, args, line_start);

        /**
         * ret maybe:
         * ERROR_SYSTEM_CONFIG_INVALID           error.
         * ERROR_SYSTEM_CONFIG_DIRECTIVE         directive terminated by ‘;‘ found
         * ERROR_SYSTEM_CONFIG_BLOCK_START       token terminated by ‘{‘ found
         * ERROR_SYSTEM_CONFIG_BLOCK_END         the ‘}‘ found
         * ERROR_SYSTEM_CONFIG_EOF               the config file is done
         */
        if (ret == ERROR_SYSTEM_CONFIG_INVALID) {
            return ret;
        }
        if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
            if (type != parse_block) {
                srs_error("line: %d: unexpected \"}\", ret=%d", buffer->line, ret);
                return ret;
            }
            return ERROR_SUCCESS;
        }
        if (ret == ERROR_SYSTEM_CONFIG_EOF) {
            if (type == parse_block) {
                srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line, ret);
                return ret;
            }
            return ERROR_SUCCESS;
        }

        // 若没有读取到任何数据,则表示出错了
        if (args.empty()) {
            ret = ERROR_SYSTEM_CONFIG_INVALID;
            srs_error("line %d: empty directive. ret=%d", conf_line, ret);
            return ret;
        }

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

        directive->conf_line = line_start;
        directive->name = args[0];
        // 将 args[0] 从 args vector 容器中删除
        args.erase(args.begin());
        /* 将 args 中的全部数据和 directive->args 中的数据进行交换,
         * 即相等于将 args 中的数据拷贝给 directive->args */
        directive->args.swap(args);

        // 将该新解析的指令放入到 vector 类的 directives 容器中
        directives.push_back(directive);

        // 若为一个配置块的开始,则递归调用 parse_conf
        if (ret == ERROR_SYSTEM_CONFIG_BLOCK_START) {
            if ((ret = directive->parse_conf(buffer, parse_block) != ERROR_SUCCESS) {
                return ret;
            }
        }
    }

    return ret;
}

2.8 SrsConfDirective::read_token

// see: ngx_conf_read_token
int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector<string>& args, int& line_start)
{
    int ret = ERROR_SUCCESS;

    char* pstart = buffer->pos;

    // 若为 true,表示当前行是注释
    bool sharp_comment = false;

    // 若为 true,表示当前字符是 双引号 "
    bool d_quoted = false;
    // 若为 true,表示当前字符是 单引号 ‘
    bool s_quoted = false;

    // 若为 true,表示下一个的字符必须是空格
    bool need_space = false;
    // 若为 true,表示当前字符是最后一个空格,即下一个字符不是空格了
    bool last_space = true;

    while (true) {
        if (buffer->empty()) {
            ret = ERROR_SYSTEM_CONFIG_EOF;

            if (!args.empty() || !last_space) {
                srs_error("line %d: unexpected end of file, expecting ; or \"}\"", buffer->line);
                return ERROR_SYSTEM_CONFIG_INVALID;
            }
            srs_trace("config parse complete");

            return ret;
        }

        char ch = *buffer->pos++;

        // 若当前字符为 换行符,则表示当前行结束
        if (ch == SRS_LF) {
            buffer->line++;
            sharp_comment = false;
        }

        // 表示遇到注释了
        if (sharp_comment) {
            continue;
        }

        if (need_space) {
            if (is_common_space(ch)) {
                last_space = true;
                need_space = false;
                continue;
            }
            if (ch == ‘;‘) {
                return ERROR_SYSTEM_CONFIG_DIRECTIVE;
            }
            if (ch == ‘{‘) {
                return ERROR_SYSTEM_CONFIG_BLOCK_START;
            }
            srs_error("line %d: unexpected ‘%c‘", buffer->line, ch);
            return ERROR_SYSTEM_CONFIG_INVALID;
        }

        // last charecter is space.
        if (last_space) {
            // 若当前字符是空格,则继续取下一个字符
            if (is_common_space(ch)) {
                continue;
            }
            pstart = buffer->pos - 1;
            switch (ch) {
                case ‘;‘:
                    if (args.size() == 0) {
                        srs_error("line %d: unexpected ‘;‘", buffer->line);
                        return ERROR_SYSTEM_CONFIG_INVALID;
                    }
                    return ERROR_SYSTEM_CONFIG_DIRECTIVE;
                case ‘{‘:
                    if (args.size() == 0) {
                        srs_error("line %d: unexpected ‘{‘", buffer->line);
                        return ERROR_SYSTEM_CONFIG_INVALID;
                    }
                    return ERROR_SYSTEM_CONFIG_BLOCK_START;
                case ‘}‘:
                    if (args.size() != 0) {
                        srs_error("line %d: unexpected ‘}‘", buffer->line);
                        return ERROR_SYSTEM_CONFIG_INVALID;
                    }
                    return ERROR_SYSTEM_CONFIG_BLOCK_END;
                case ‘#‘:
                    sharp_comment = 1;
                    continue;
                case ‘"‘:
                    pstart++;
                    d_quoted = true;
                    last_space = 0;
                    continue;
                case ‘\‘‘:
                    pstart++;
                    s_quoted = true;
                    last_space = 0;
                    continue;
                default:
                    last_space = 0;
                    continue;
            }
        } else {
            // last charecter is not space
            if (line_start == 0) {
                line_start = buffer->line;
            }

            bool found = false;
            if (d_quoted) {
                if (ch == ‘"‘) {
                    d_quoted = false;
                    need_space = true;
                    found = true;
                }
            } else if (s_quoted) {
                if (ch == ‘\‘‘) {
                    s_quoted = false;
                    need_space = true;
                    found = true;
                }
            // 若当前字符是空格 或 ; 或 {,则置位 found
            } else if (is_common_space(ch) || ch == ‘;‘ || ch == ‘{‘) {
                last_space = true;
                found = 1;
            }

            if (found) {
                int len = (int)(buffer->pos - pstart);
                char* aword = new char[len];
                memcpy(aword, pstart, len);
                aword[len - 1] = 0;

                // 将其放入到 vector 类型的 args 容器中
                string word_str = aword;
                if (!word_str.empty()) {
                    args.push_back(word_str);
                }
                srs_freepa(aword);

                if (ch == ‘;‘) {
                    return ERROR_SYSTEM_CONFIG_DIRECTIVE;
                }
                if (ch == ‘{‘) {
                    return ERROR_SYSTEM_CONFIG_BLOCK_START;
                }
            }
        }
    }

    return ret;
}

原文地址:https://www.cnblogs.com/jimodetiantang/p/9013794.html

时间: 2024-10-29 13:03:03

SRS之配置的解析的相关文章

MHA大杀器——mysql主、从双击热备配置安装解析

MHA的主要作用: 在mysql的主从复制中,当master崩溃了,利用mha实现backup顶替崩溃的master自动切换为master继续工作,从而实现高可用. 下面介绍本次实验的环境: MHA分为manager管理节点和node节点,一般来讲最少是三台服务器,两台node节点,一台manager节点,但本次环境限制,只能使用两台,所以把manager也装在一台node节点上. 两台服务器,两个网口: IP: 10.2.16.253     10.0.0.1  node1 10.2.16.2

DNS各种基本配置(正向解析区域、反向解析区域;主/从;子域;基本安全控制)

DNS服务器所提供的服务是完成将主机名和转换为IP地址的工作.为什么需要将主机名转换为IP地址的工作呢?这是因为,当网络上的一台客户机访问某一服务器上的资源时,用户在浏览器地址栏中输入的是人类便于识记的主机名和域名.而网络上的计算机之间实现连接却是通过每台计算机在网络中拥有的惟一的IP地址来完成的,这样就需要在用户容易记忆的地址和计算机能够识别的地址之间有一个解析,DNS服务器便充当了地址解析的重要角色. 域名严格意义上的称呼为FQDN(Full Qualified Domain Name).域

Maven之——插件配置与解析

Maven之--插件配置与解析 插件配置就是为绑定插件指定其预定义的参数值.来进一步调整插件目标所执行的任务.可以通过命令行和POM中插件全局配置的形式来配置.不是所有的插件配置都可以通过命令行配置的. 1.    命令行插件配置 如maven-surefire-plugin插件提供一个maven.test.skip参数.当值为true时会跳过执行测试.命令行执行方式: mvninstall –Dmaven.test.skip=true mvn install 可以对比两者在控制台的输出就发现.

Storm 配置图文解析

Storm 配置图文解析 参考阅读:http://www.xiaofateng.com/?p=959 ============================== | sample-topology | | ------------------------ | Task 1 Task 2 Task 3 | | Worker Process 1 | | T1 T2 T3 | | +--------+ | | Spout => Bolt => Bolt | | +------+ | +----+

SpringMVC中用于绑定请求数据的注解以及配置视图解析器

SpringMVC中用于绑定请求数据的注解 在上一篇文章中我们简单介绍了@RequestMapping与@RequestParam注解,知道了如何去配置地址映射,本篇则介绍一些用于处理request数据的注解. [email protected]注解,该注解用于处理request中的header部分,也就是http请求头的部分,它可以把header部分的值绑定到方法的参数上,示例: package org.zero01.test; import org.springframework.stere

SpringMVC__配置视图解析以及服务端重定向和服务端跳转简单代码

applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.spri

apache虚拟主机配置及解析

Apache虚拟主机配置及解析 1.修改httpd-vhosts.conf 打开apache(Apache24)/conf/extra/httpd-vhosts.conf文件,添加虚拟主机信息,可以这只不同的域名指向不同的文件目录 <VirtualHost *:80> ServerAdmin [email protected]163.com # 服务管理员邮箱地址,出问题时发送邮件到这个邮箱 DocumentRoot "D:/AppServ/www/wx" # apache

Spring MVC一些配置信息解析

springMVC框架请求响应步骤 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找Handler 可以根据xml配置.注解进行查找 第三步:处理器映射器HandlerMapping向前端控制器返回Handler 第四步:前端控制器调用处理器适配器(HandlerAdapter)去执行Handler 第五步:处理器适配器去处理Handler 第六步:Handler处理完给适配器返回ModelAndView 第七步:处理器适

LAMP搭建4:配置PHP解析

搭建完成LAMP之后,访问服务器(IP:192.168.147.131)若返回如下结果即证明LAMP已搭建成功. 这个页面的源文件index.html所在目录在apache的主配置文件httpd.conf中定义: [[email protected] php-5.4.36]# vim /usr/local/apache2/conf/httpd.conf DocumentRoot "/usr/local/apache2/htdocs" 进入该目录就可以看到index.html页面文件,该