Merge pull request #1 from winlinvip/develop
merge origin
正在显示
29 个修改的文件
包含
1232 行增加
和
360 行删除
| @@ -468,6 +468,13 @@ Supported operating systems and hardware: | @@ -468,6 +468,13 @@ Supported operating systems and hardware: | ||
| 468 | [EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_SrsLibrtmp#publish-audio-raw-stream) | 468 | [EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_SrsLibrtmp#publish-audio-raw-stream) |
| 469 | ) by srs-librtmp. | 469 | ) by srs-librtmp. |
| 470 | 1. Support 0.1s+ latency, read [#257](https://github.com/winlinvip/simple-rtmp-server/issues/257). | 470 | 1. Support 0.1s+ latency, read [#257](https://github.com/winlinvip/simple-rtmp-server/issues/257). |
| 471 | +1. Support allow/deny publish/play for all or specified ip( | ||
| 472 | +[CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_Security), | ||
| 473 | +[EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_Security) | ||
| 474 | +). | ||
| 475 | +1. Support custom dvr path and http callback, read | ||
| 476 | +[#179](https://github.com/winlinvip/simple-rtmp-server/issues/179) and | ||
| 477 | +[274](https://github.com/winlinvip/simple-rtmp-server/issues/274). | ||
| 471 | 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). | 478 | 1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech). |
| 472 | 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). | 479 | 1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92). |
| 473 | 1. [no-plan] Support multiple processes, for both origin and edge | 480 | 1. [no-plan] Support multiple processes, for both origin and edge |
| @@ -501,6 +508,10 @@ Supported operating systems and hardware: | @@ -501,6 +508,10 @@ Supported operating systems and hardware: | ||
| 501 | * 2013-10-17, Created.<br/> | 508 | * 2013-10-17, Created.<br/> |
| 502 | 509 | ||
| 503 | ## History | 510 | ## History |
| 511 | +* v2.0, 2015-01-03, fix [#274](https://github.com/winlinvip/simple-rtmp-server/issues/274), http-callback support on_dvr when reap a dvr file. 2.0.89 | ||
| 512 | +* v2.0, 2015-01-03, hotfix to remove the pageUrl for http callback. 2.0.88 | ||
| 513 | +* v2.0, 2015-01-03, fix [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), dvr support custom filepath by variables. 2.0.87 | ||
| 514 | +* v2.0, 2015-01-02, fix [#211](https://github.com/winlinvip/simple-rtmp-server/issues/211), support security allow/deny publish/play all/ip. 2.0.86 | ||
| 504 | * v2.0, 2015-01-02, hotfix [#207](https://github.com/winlinvip/simple-rtmp-server/issues/207), trim the last 0 of log. 2.0.85 | 515 | * v2.0, 2015-01-02, hotfix [#207](https://github.com/winlinvip/simple-rtmp-server/issues/207), trim the last 0 of log. 2.0.85 |
| 505 | * v2.0, 2014-01-02, fix [#158](https://github.com/winlinvip/simple-rtmp-server/issues/158), http-callback check http status code ok(200). 2.0.84 | 516 | * v2.0, 2014-01-02, fix [#158](https://github.com/winlinvip/simple-rtmp-server/issues/158), http-callback check http status code ok(200). 2.0.84 |
| 506 | * v2.0, 2015-01-02, hotfix [#216](https://github.com/winlinvip/simple-rtmp-server/issues/216), http-callback post in application/json content-type. 2.0.83 | 517 | * v2.0, 2015-01-02, hotfix [#216](https://github.com/winlinvip/simple-rtmp-server/issues/216), http-callback post in application/json content-type. 2.0.83 |
| @@ -550,6 +561,7 @@ Supported operating systems and hardware: | @@ -550,6 +561,7 @@ Supported operating systems and hardware: | ||
| 550 | * v2.0, 2014-10-18, remove supports for OSX(darwin). 2.0.1. | 561 | * v2.0, 2014-10-18, remove supports for OSX(darwin). 2.0.1. |
| 551 | * v2.0, 2014-10-16, revert github srs README to English. 2.0.0. | 562 | * v2.0, 2014-10-16, revert github srs README to English. 2.0.0. |
| 552 | 563 | ||
| 564 | +* v1.0, 2015-01-03, hotfix to remove the pageUrl for http callback. 1.0.19 | ||
| 553 | * v1.0, 2015-01-02, hotfix [#207](https://github.com/winlinvip/simple-rtmp-server/issues/207), trim the last 0 of log. 1.0.18 | 565 | * v1.0, 2015-01-02, hotfix [#207](https://github.com/winlinvip/simple-rtmp-server/issues/207), trim the last 0 of log. 1.0.18 |
| 554 | * v1.0, 2015-01-02, hotfix [#216](https://github.com/winlinvip/simple-rtmp-server/issues/216), http-callback post in application/json content-type. 1.0.17 | 566 | * v1.0, 2015-01-02, hotfix [#216](https://github.com/winlinvip/simple-rtmp-server/issues/216), http-callback post in application/json content-type. 1.0.17 |
| 555 | * v1.0, 2015-01-01, hotfix [#270](https://github.com/winlinvip/simple-rtmp-server/issues/270), memory leak for http client post. 1.0.16 | 567 | * v1.0, 2015-01-01, hotfix [#270](https://github.com/winlinvip/simple-rtmp-server/issues/270), memory leak for http client post. 1.0.16 |
trunk/conf/dvr.path.conf
0 → 100644
| 1 | +# the config for srs to dvr in custom path. | ||
| 2 | +# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path | ||
| 3 | +# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path | ||
| 4 | +# @see full.conf for detail config. | ||
| 5 | + | ||
| 6 | +listen 1935; | ||
| 7 | +max_connections 1000; | ||
| 8 | +vhost __defaultVhost__ { | ||
| 9 | + dvr { | ||
| 10 | + enabled on; | ||
| 11 | + dvr_path ./objs/nginx/html/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv; | ||
| 12 | + dvr_plan segment; | ||
| 13 | + dvr_duration 30; | ||
| 14 | + dvr_wait_keyframe on; | ||
| 15 | + } | ||
| 16 | +} |
trunk/conf/full.conf
100755 → 100644
| @@ -142,6 +142,35 @@ http_stream { | @@ -142,6 +142,35 @@ http_stream { | ||
| 142 | vhost __defaultVhost__ { | 142 | vhost __defaultVhost__ { |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | +# the security to allow or deny clients. | ||
| 146 | +vhost security.srs.com { | ||
| 147 | + # security for host to allow or deny clients. | ||
| 148 | + # @see https://github.com/winlinvip/simple-rtmp-server/issues/211 | ||
| 149 | + security { | ||
| 150 | + # whether enable the security for vhost. | ||
| 151 | + # default: off | ||
| 152 | + enabled on; | ||
| 153 | + # the security list, each item format as: | ||
| 154 | + # allow|deny publish|play all|<ip> | ||
| 155 | + # for example: | ||
| 156 | + # allow publish all; | ||
| 157 | + # deny publish all; | ||
| 158 | + # allow publish 127.0.0.1; | ||
| 159 | + # deny publish 127.0.0.1; | ||
| 160 | + # allow play all; | ||
| 161 | + # deny play all; | ||
| 162 | + # allow play 127.0.0.1; | ||
| 163 | + # deny play 127.0.0.1; | ||
| 164 | + # SRS apply the following simple strategies one by one: | ||
| 165 | + # 1. allow all if security disabled. | ||
| 166 | + # 2. default to deny all when security enabled. | ||
| 167 | + # 3. allow if matches allow strategy. | ||
| 168 | + # 4. deny if matches deny strategy. | ||
| 169 | + allow play all; | ||
| 170 | + allow publish all; | ||
| 171 | + } | ||
| 172 | +} | ||
| 173 | + | ||
| 145 | # the MR(merged-read) setting for publisher. | 174 | # the MR(merged-read) setting for publisher. |
| 146 | # the MW(merged-write) settings for player. | 175 | # the MW(merged-write) settings for player. |
| 147 | vhost mrw.srs.com { | 176 | vhost mrw.srs.com { |
| @@ -207,15 +236,38 @@ vhost dvr.srs.com { | @@ -207,15 +236,38 @@ vhost dvr.srs.com { | ||
| 207 | # default: off | 236 | # default: off |
| 208 | enabled on; | 237 | enabled on; |
| 209 | # the dvr output path. | 238 | # the dvr output path. |
| 210 | - # the app dir is auto created under the dvr_path. | ||
| 211 | - # for example, for rtmp stream: | ||
| 212 | - # rtmp://127.0.0.1/live/livestream | ||
| 213 | - # http://127.0.0.1/live/livestream.m3u8 | ||
| 214 | - # where dvr_path is /dvr, srs will create the following files: | ||
| 215 | - # /dvr/live the app dir for all streams. | ||
| 216 | - # /dvr/live/livestream.{time}.flv the dvr flv file. | ||
| 217 | - # @remark, the time use system timestamp in ms, user can use http callback to rename it. | ||
| 218 | - # in a word, the dvr_path is for vhost. | 239 | + # we supports some variables to generate the filename. |
| 240 | + # [vhost], the vhost of stream. | ||
| 241 | + # [app], the app of stream. | ||
| 242 | + # [stream], the stream name of stream. | ||
| 243 | + # [2006], replace this const to current year. | ||
| 244 | + # [01], replace this const to current month. | ||
| 245 | + # [02], replace this const to current date. | ||
| 246 | + # [15], replace this const to current hour. | ||
| 247 | + # [04], repleace this const to current minute. | ||
| 248 | + # [05], repleace this const to current second. | ||
| 249 | + # [999], repleace this const to current millisecond. | ||
| 250 | + # [timestamp],replace this const to current UNIX timestamp in ms. | ||
| 251 | + # @remark we use golang time format "2006-01-02 15:04:05.999" | ||
| 252 | + # for example, for url rtmp://ossrs.net/live/livestream and time 2015-01-03 10:57:30.776 | ||
| 253 | + # 1. No variables, the rule of SRS1.0(auto add [stream].[timestamp].flv as filename): | ||
| 254 | + # dvr_path ./objs/nginx/html; | ||
| 255 | + # => | ||
| 256 | + # dvr_path ./objs/nginx/html/live/livestream.1420254068776.flv; | ||
| 257 | + # 2. Use stream and date as dir name, time as filename: | ||
| 258 | + # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv; | ||
| 259 | + # => | ||
| 260 | + # dvr_path /data/ossrs.net/live/livestream/2015/01/03/10.57.30.776.flv; | ||
| 261 | + # 3. Use stream and year/month as dir name, date and time as filename: | ||
| 262 | + # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]-[15].[04].[05].[999].flv; | ||
| 263 | + # => | ||
| 264 | + # dvr_path /data/ossrs.net/live/livestream/2015/01/03-10.57.30.776.flv; | ||
| 265 | + # 4. Use vhost/app and year/month as dir name, stream/date/time as filename: | ||
| 266 | + # dvr_path /data/[vhost]/[app]/[2006]/[01]/[stream]-[02]-[15].[04].[05].[999].flv; | ||
| 267 | + # => | ||
| 268 | + # dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv; | ||
| 269 | + # @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path | ||
| 270 | + # @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path | ||
| 219 | # default: ./objs/nginx/html | 271 | # default: ./objs/nginx/html |
| 220 | dvr_path ./objs/nginx/html; | 272 | dvr_path ./objs/nginx/html; |
| 221 | # the dvr plan. canbe: | 273 | # the dvr plan. canbe: |
| @@ -244,6 +296,11 @@ vhost dvr.srs.com { | @@ -244,6 +296,11 @@ vhost dvr.srs.com { | ||
| 244 | # 3. off, disable the time jitter algorithm, like atc. | 296 | # 3. off, disable the time jitter algorithm, like atc. |
| 245 | # default: full | 297 | # default: full |
| 246 | time_jitter full; | 298 | time_jitter full; |
| 299 | + | ||
| 300 | + # on_dvr | ||
| 301 | + # for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com | ||
| 302 | + # @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#http-callback | ||
| 303 | + # @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#http-callback | ||
| 247 | } | 304 | } |
| 248 | } | 305 | } |
| 249 | 306 | ||
| @@ -286,7 +343,7 @@ vhost ingest.srs.com { | @@ -286,7 +343,7 @@ vhost ingest.srs.com { | ||
| 286 | } | 343 | } |
| 287 | } | 344 | } |
| 288 | 345 | ||
| 289 | -# vhost for http | 346 | +# vhost for http server config in each vhost. |
| 290 | vhost http.srs.com { | 347 | vhost http.srs.com { |
| 291 | # http vhost specified config | 348 | # http vhost specified config |
| 292 | http { | 349 | http { |
| @@ -438,6 +495,20 @@ vhost hooks.callback.srs.com { | @@ -438,6 +495,20 @@ vhost hooks.callback.srs.com { | ||
| 438 | # support multiple api hooks, format: | 495 | # support multiple api hooks, format: |
| 439 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN | 496 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN |
| 440 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; | 497 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; |
| 498 | + # when srs reap a dvr file, call the hook, | ||
| 499 | + # the request in the POST data string is a object encode by json: | ||
| 500 | + # { | ||
| 501 | + # "action": "on_dvr", | ||
| 502 | + # "client_id": 1985, | ||
| 503 | + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 504 | + # "stream": "livestream", | ||
| 505 | + # "cwd": "/usr/local/srs", | ||
| 506 | + # "file": "./objs/nginx/html/live/livestream.1420254068776.flv" | ||
| 507 | + # } | ||
| 508 | + # if valid, the hook must return HTTP code 200(Stauts OK) and response | ||
| 509 | + # an int value specifies the error code(0 corresponding to success): | ||
| 510 | + # 0 | ||
| 511 | + on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs; | ||
| 441 | } | 512 | } |
| 442 | } | 513 | } |
| 443 | 514 | ||
| @@ -501,11 +572,105 @@ vhost same.vhost.forward.srs.com { | @@ -501,11 +572,105 @@ vhost same.vhost.forward.srs.com { | ||
| 501 | # this used to split/forward the current stream for cluster active-standby, | 572 | # this used to split/forward the current stream for cluster active-standby, |
| 502 | # active-active for cdn to build high available fault tolerance system. | 573 | # active-active for cdn to build high available fault tolerance system. |
| 503 | # format: {ip}:{port} {ip_N}:{port_N} | 574 | # format: {ip}:{port} {ip_N}:{port_N} |
| 504 | - # or specify the vhost by params, @see: change.vhost.forward.srs.com | ||
| 505 | - # if vhost not specified, use the request vhost instead. | ||
| 506 | forward 127.0.0.1:1936 127.0.0.1:1937; | 575 | forward 127.0.0.1:1936 127.0.0.1:1937; |
| 507 | } | 576 | } |
| 508 | 577 | ||
| 578 | +# the main comments for transcode | ||
| 579 | +vhost example.transcode.srs.com { | ||
| 580 | + # the streaming transcode configs. | ||
| 581 | + transcode { | ||
| 582 | + # whether the transcode enabled. | ||
| 583 | + # if off, donot transcode. | ||
| 584 | + # default: off. | ||
| 585 | + enabled on; | ||
| 586 | + # the ffmpeg | ||
| 587 | + ffmpeg ./objs/ffmpeg/bin/ffmpeg; | ||
| 588 | + # the transcode engine for matched stream. | ||
| 589 | + # all matched stream will transcoded to the following stream. | ||
| 590 | + # the transcode set name(ie. hd) is optional and not used. | ||
| 591 | + engine example { | ||
| 592 | + # whether the engine is enabled | ||
| 593 | + # default: off. | ||
| 594 | + enabled on; | ||
| 595 | + # input format, can be: | ||
| 596 | + # off, do not specifies the format, ffmpeg will guess it. | ||
| 597 | + # flv, for flv or RTMP stream. | ||
| 598 | + # other format, for example, mp4/aac whatever. | ||
| 599 | + # default: flv | ||
| 600 | + iformat flv; | ||
| 601 | + # ffmpeg filters, follows the main input. | ||
| 602 | + vfilter { | ||
| 603 | + # the logo input file. | ||
| 604 | + i ./doc/ffmpeg-logo.png; | ||
| 605 | + # the ffmpeg complex filter. | ||
| 606 | + # for filters, @see: http://ffmpeg.org/ffmpeg-filters.html | ||
| 607 | + filter_complex 'overlay=10:10'; | ||
| 608 | + } | ||
| 609 | + # video encoder name. can be: | ||
| 610 | + # libx264: use h.264(libx264) video encoder. | ||
| 611 | + # copy: donot encoder the video stream, copy it. | ||
| 612 | + # vn: disable video output. | ||
| 613 | + vcodec libx264; | ||
| 614 | + # video bitrate, in kbps | ||
| 615 | + vbitrate 1500; | ||
| 616 | + # video framerate. | ||
| 617 | + vfps 25; | ||
| 618 | + # video width, must be even numbers. | ||
| 619 | + vwidth 768; | ||
| 620 | + # video height, must be even numbers. | ||
| 621 | + vheight 320; | ||
| 622 | + # the max threads for ffmpeg to used. | ||
| 623 | + vthreads 12; | ||
| 624 | + # x264 profile, @see x264 -help, can be: | ||
| 625 | + # high,main,baseline | ||
| 626 | + vprofile main; | ||
| 627 | + # x264 preset, @see x264 -help, can be: | ||
| 628 | + # ultrafast,superfast,veryfast,faster,fast | ||
| 629 | + # medium,slow,slower,veryslow,placebo | ||
| 630 | + vpreset medium; | ||
| 631 | + # other x264 or ffmpeg video params | ||
| 632 | + vparams { | ||
| 633 | + # ffmpeg options, @see: http://ffmpeg.org/ffmpeg.html | ||
| 634 | + t 100; | ||
| 635 | + # 264 params, @see: http://ffmpeg.org/ffmpeg-codecs.html#libx264 | ||
| 636 | + coder 1; | ||
| 637 | + b_strategy 2; | ||
| 638 | + bf 3; | ||
| 639 | + refs 10; | ||
| 640 | + } | ||
| 641 | + # audio encoder name. can be: | ||
| 642 | + # libaacplus: use aac(libaacplus) audio encoder. | ||
| 643 | + # copy: donot encoder the audio stream, copy it. | ||
| 644 | + # an: disable audio output. | ||
| 645 | + acodec libaacplus; | ||
| 646 | + # audio bitrate, in kbps. [16, 72] for libaacplus. | ||
| 647 | + abitrate 70; | ||
| 648 | + # audio sample rate. for flv/rtmp, it must be: | ||
| 649 | + # 44100,22050,11025,5512 | ||
| 650 | + asample_rate 44100; | ||
| 651 | + # audio channel, 1 for mono, 2 for stereo. | ||
| 652 | + achannels 2; | ||
| 653 | + # other ffmpeg audio params | ||
| 654 | + aparams { | ||
| 655 | + # audio params, @see: http://ffmpeg.org/ffmpeg-codecs.html#Audio-Encoders | ||
| 656 | + profile:a aac_low; | ||
| 657 | + } | ||
| 658 | + # output format, can be: | ||
| 659 | + # off, do not specifies the format, ffmpeg will guess it. | ||
| 660 | + # flv, for flv or RTMP stream. | ||
| 661 | + # other format, for example, mp4/aac whatever. | ||
| 662 | + # default: flv | ||
| 663 | + oformat flv; | ||
| 664 | + # output stream. variables: | ||
| 665 | + # [vhost] the input stream vhost. | ||
| 666 | + # [port] the intput stream port. | ||
| 667 | + # [app] the input stream app. | ||
| 668 | + # [stream] the input stream name. | ||
| 669 | + # [engine] the tanscode engine name. | ||
| 670 | + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | ||
| 671 | + } | ||
| 672 | + } | ||
| 673 | +} | ||
| 509 | # the mirror filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#Filtering-Introduction | 674 | # the mirror filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#Filtering-Introduction |
| 510 | vhost mirror.transcode.srs.com { | 675 | vhost mirror.transcode.srs.com { |
| 511 | transcode { | 676 | transcode { |
| @@ -536,10 +701,8 @@ vhost mirror.transcode.srs.com { | @@ -536,10 +701,8 @@ vhost mirror.transcode.srs.com { | ||
| 536 | } | 701 | } |
| 537 | } | 702 | } |
| 538 | } | 703 | } |
| 539 | -# | ||
| 540 | # the drawtext filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#drawtext-1 | 704 | # the drawtext filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#drawtext-1 |
| 541 | # remark: we remove the libfreetype which always cause build failed, you must add it manual if needed. | 705 | # remark: we remove the libfreetype which always cause build failed, you must add it manual if needed. |
| 542 | -# | ||
| 543 | ####################################################################################################### | 706 | ####################################################################################################### |
| 544 | # the crop filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#crop | 707 | # the crop filter of ffmpeg, @see: http://ffmpeg.org/ffmpeg-filters.html#crop |
| 545 | vhost crop.transcode.srs.com { | 708 | vhost crop.transcode.srs.com { |
| @@ -656,97 +819,41 @@ vhost copy.transcode.srs.com { | @@ -656,97 +819,41 @@ vhost copy.transcode.srs.com { | ||
| 656 | } | 819 | } |
| 657 | } | 820 | } |
| 658 | # transcode all app and stream of vhost | 821 | # transcode all app and stream of vhost |
| 822 | +# the comments, read example.transcode.srs.com | ||
| 659 | vhost all.transcode.srs.com { | 823 | vhost all.transcode.srs.com { |
| 660 | - # the streaming transcode configs. | ||
| 661 | transcode { | 824 | transcode { |
| 662 | - # whether the transcode enabled. | ||
| 663 | - # if off, donot transcode. | ||
| 664 | - # default: off. | ||
| 665 | enabled on; | 825 | enabled on; |
| 666 | - # the ffmpeg | ||
| 667 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; | 826 | ffmpeg ./objs/ffmpeg/bin/ffmpeg; |
| 668 | - # the transcode engine for matched stream. | ||
| 669 | - # all matched stream will transcoded to the following stream. | ||
| 670 | - # the transcode set name(ie. hd) is optional and not used. | ||
| 671 | engine ffsuper { | 827 | engine ffsuper { |
| 672 | - # whether the engine is enabled | ||
| 673 | - # default: off. | ||
| 674 | enabled on; | 828 | enabled on; |
| 675 | - # input format, can be: | ||
| 676 | - # off, do not specifies the format, ffmpeg will guess it. | ||
| 677 | - # flv, for flv or RTMP stream. | ||
| 678 | - # other format, for example, mp4/aac whatever. | ||
| 679 | - # default: flv | ||
| 680 | iformat flv; | 829 | iformat flv; |
| 681 | - # ffmpeg filters, follows the main input. | ||
| 682 | vfilter { | 830 | vfilter { |
| 683 | - # the logo input file. | ||
| 684 | i ./doc/ffmpeg-logo.png; | 831 | i ./doc/ffmpeg-logo.png; |
| 685 | - # the ffmpeg complex filter. | ||
| 686 | - # for filters, @see: http://ffmpeg.org/ffmpeg-filters.html | ||
| 687 | filter_complex 'overlay=10:10'; | 832 | filter_complex 'overlay=10:10'; |
| 688 | } | 833 | } |
| 689 | - # video encoder name. can be: | ||
| 690 | - # libx264: use h.264(libx264) video encoder. | ||
| 691 | - # copy: donot encoder the video stream, copy it. | ||
| 692 | - # vn: disable video output. | ||
| 693 | vcodec libx264; | 834 | vcodec libx264; |
| 694 | - # video bitrate, in kbps | ||
| 695 | vbitrate 1500; | 835 | vbitrate 1500; |
| 696 | - # video framerate. | ||
| 697 | vfps 25; | 836 | vfps 25; |
| 698 | - # video width, must be even numbers. | ||
| 699 | vwidth 768; | 837 | vwidth 768; |
| 700 | - # video height, must be even numbers. | ||
| 701 | vheight 320; | 838 | vheight 320; |
| 702 | - # the max threads for ffmpeg to used. | ||
| 703 | vthreads 12; | 839 | vthreads 12; |
| 704 | - # x264 profile, @see x264 -help, can be: | ||
| 705 | - # high,main,baseline | ||
| 706 | vprofile main; | 840 | vprofile main; |
| 707 | - # x264 preset, @see x264 -help, can be: | ||
| 708 | - # ultrafast,superfast,veryfast,faster,fast | ||
| 709 | - # medium,slow,slower,veryslow,placebo | ||
| 710 | vpreset medium; | 841 | vpreset medium; |
| 711 | - # other x264 or ffmpeg video params | ||
| 712 | vparams { | 842 | vparams { |
| 713 | - # ffmpeg options, @see: http://ffmpeg.org/ffmpeg.html | ||
| 714 | t 100; | 843 | t 100; |
| 715 | - # 264 params, @see: http://ffmpeg.org/ffmpeg-codecs.html#libx264 | ||
| 716 | coder 1; | 844 | coder 1; |
| 717 | b_strategy 2; | 845 | b_strategy 2; |
| 718 | bf 3; | 846 | bf 3; |
| 719 | refs 10; | 847 | refs 10; |
| 720 | } | 848 | } |
| 721 | - # audio encoder name. can be: | ||
| 722 | - # libaacplus: use aac(libaacplus) audio encoder. | ||
| 723 | - # copy: donot encoder the audio stream, copy it. | ||
| 724 | - # an: disable audio output. | ||
| 725 | acodec libaacplus; | 849 | acodec libaacplus; |
| 726 | - # audio bitrate, in kbps. [16, 72] for libaacplus. | ||
| 727 | abitrate 70; | 850 | abitrate 70; |
| 728 | - # audio sample rate. for flv/rtmp, it must be: | ||
| 729 | - # 44100,22050,11025,5512 | ||
| 730 | asample_rate 44100; | 851 | asample_rate 44100; |
| 731 | - # audio channel, 1 for mono, 2 for stereo. | ||
| 732 | achannels 2; | 852 | achannels 2; |
| 733 | - # other ffmpeg audio params | ||
| 734 | aparams { | 853 | aparams { |
| 735 | - # audio params, @see: http://ffmpeg.org/ffmpeg-codecs.html#Audio-Encoders | ||
| 736 | profile:a aac_low; | 854 | profile:a aac_low; |
| 737 | } | 855 | } |
| 738 | - # output format, can be: | ||
| 739 | - # off, do not specifies the format, ffmpeg will guess it. | ||
| 740 | - # flv, for flv or RTMP stream. | ||
| 741 | - # other format, for example, mp4/aac whatever. | ||
| 742 | - # default: flv | ||
| 743 | oformat flv; | 856 | oformat flv; |
| 744 | - # output stream. variables: | ||
| 745 | - # [vhost] the input stream vhost. | ||
| 746 | - # [port] the intput stream port. | ||
| 747 | - # [app] the input stream app. | ||
| 748 | - # [stream] the input stream name. | ||
| 749 | - # [engine] the tanscode engine name. | ||
| 750 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; | 857 | output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine]; |
| 751 | } | 858 | } |
| 752 | engine ffhd { | 859 | engine ffhd { |
trunk/conf/realtime.conf
100755 → 100644
trunk/conf/security.deny.publish.conf
0 → 100644
| 1 | +# security config for srs, allow play and deny publish. | ||
| 2 | +# @see https://github.com/winlinvip/simple-rtmp-server/issues/211#issuecomment-68507035 | ||
| 3 | +# @see full.conf for detail config. | ||
| 4 | + | ||
| 5 | +listen 1935; | ||
| 6 | +max_connections 1000; | ||
| 7 | +vhost __defaultVhost__ { | ||
| 8 | + security { | ||
| 9 | + enabled on; | ||
| 10 | + deny publish all; | ||
| 11 | + allow play all; | ||
| 12 | + } | ||
| 13 | +} |
| @@ -389,7 +389,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | @@ -389,7 +389,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | ||
| 389 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" | 389 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" |
| 390 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" | 390 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" |
| 391 | "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac" | 391 | "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac" |
| 392 | - "srs_app_recv_thread" "srs_app_statistic") | 392 | + "srs_app_recv_thread" "srs_app_security" "srs_app_statistic") |
| 393 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh | 393 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh |
| 394 | APP_OBJS="${MODULE_OBJS[@]}" | 394 | APP_OBJS="${MODULE_OBJS[@]}" |
| 395 | fi | 395 | fi |
| @@ -241,6 +241,74 @@ class RESTStreams(object): | @@ -241,6 +241,74 @@ class RESTStreams(object): | ||
| 241 | return code | 241 | return code |
| 242 | 242 | ||
| 243 | ''' | 243 | ''' |
| 244 | +handle the dvrs requests: dvr stream. | ||
| 245 | +''' | ||
| 246 | +class RESTDvrs(object): | ||
| 247 | + exposed = True | ||
| 248 | + | ||
| 249 | + def GET(self): | ||
| 250 | + enable_crossdomain() | ||
| 251 | + | ||
| 252 | + dvrs = {} | ||
| 253 | + return json.dumps(dvrs) | ||
| 254 | + | ||
| 255 | + ''' | ||
| 256 | + for SRS hook: on_dvr | ||
| 257 | + on_dvr: | ||
| 258 | + when srs reap a dvr file, call the hook, | ||
| 259 | + the request in the POST data string is a object encode by json: | ||
| 260 | + { | ||
| 261 | + "action": "on_dvr", | ||
| 262 | + "client_id": 1985, | ||
| 263 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 264 | + "stream": "livestream", | ||
| 265 | + "cwd": "/usr/local/srs", | ||
| 266 | + "file": "./objs/nginx/html/live/livestream.1420254068776.flv" | ||
| 267 | + } | ||
| 268 | + if valid, the hook must return HTTP code 200(Stauts OK) and response | ||
| 269 | + an int value specifies the error code(0 corresponding to success): | ||
| 270 | + 0 | ||
| 271 | + ''' | ||
| 272 | + def POST(self): | ||
| 273 | + enable_crossdomain() | ||
| 274 | + | ||
| 275 | + # return the error code in str | ||
| 276 | + code = Error.success | ||
| 277 | + | ||
| 278 | + req = cherrypy.request.body.read() | ||
| 279 | + trace("post to dvrs, req=%s"%(req)) | ||
| 280 | + try: | ||
| 281 | + json_req = json.loads(req) | ||
| 282 | + except Exception, ex: | ||
| 283 | + code = Error.system_parse_json | ||
| 284 | + trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code)) | ||
| 285 | + return str(code) | ||
| 286 | + | ||
| 287 | + action = json_req["action"] | ||
| 288 | + if action == "on_dvr": | ||
| 289 | + code = self.__on_dvr(json_req) | ||
| 290 | + else: | ||
| 291 | + trace("invalid request action: %s"%(json_req["action"])) | ||
| 292 | + code = Error.request_invalid_action | ||
| 293 | + | ||
| 294 | + return str(code) | ||
| 295 | + | ||
| 296 | + def OPTIONS(self, *args, **kwargs): | ||
| 297 | + enable_crossdomain() | ||
| 298 | + | ||
| 299 | + def __on_dvr(self, req): | ||
| 300 | + code = Error.success | ||
| 301 | + | ||
| 302 | + trace("srs %s: client id=%s, ip=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s"%( | ||
| 303 | + req["action"], req["client_id"], req["ip"], req["vhost"], req["app"], req["stream"], | ||
| 304 | + req["cwd"], req["file"] | ||
| 305 | + )) | ||
| 306 | + | ||
| 307 | + # TODO: process the on_dvr event | ||
| 308 | + | ||
| 309 | + return code | ||
| 310 | + | ||
| 311 | +''' | ||
| 244 | handle the sessions requests: client play/stop stream | 312 | handle the sessions requests: client play/stop stream |
| 245 | ''' | 313 | ''' |
| 246 | class RESTSessions(object): | 314 | class RESTSessions(object): |
| @@ -1039,6 +1107,7 @@ class V1(object): | @@ -1039,6 +1107,7 @@ class V1(object): | ||
| 1039 | self.clients = RESTClients() | 1107 | self.clients = RESTClients() |
| 1040 | self.streams = RESTStreams() | 1108 | self.streams = RESTStreams() |
| 1041 | self.sessions = RESTSessions() | 1109 | self.sessions = RESTSessions() |
| 1110 | + self.dvrs = RESTDvrs() | ||
| 1042 | self.chats = RESTChats() | 1111 | self.chats = RESTChats() |
| 1043 | self.servers = RESTServers() | 1112 | self.servers = RESTServers() |
| 1044 | self.nodes = RESTNodes() | 1113 | self.nodes = RESTNodes() |
| @@ -1048,6 +1117,7 @@ class V1(object): | @@ -1048,6 +1117,7 @@ class V1(object): | ||
| 1048 | "clients": "for srs http callback, to handle the clients requests: connect/disconnect vhost/app.", | 1117 | "clients": "for srs http callback, to handle the clients requests: connect/disconnect vhost/app.", |
| 1049 | "streams": "for srs http callback, to handle the streams requests: publish/unpublish stream.", | 1118 | "streams": "for srs http callback, to handle the streams requests: publish/unpublish stream.", |
| 1050 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", | 1119 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", |
| 1120 | + "dvrs": "for srs http callback, to handle the dvr requests: dvr stream.", | ||
| 1051 | "chats": "for srs demo meeting, the chat streams, public chat room.", | 1121 | "chats": "for srs demo meeting, the chat streams, public chat room.", |
| 1052 | "nodes": { | 1122 | "nodes": { |
| 1053 | "summary": "for srs cdn node", | 1123 | "summary": "for srs cdn node", |
| @@ -15,7 +15,7 @@ ret=$?; if [[ 0 -ne $ret ]]; then | @@ -15,7 +15,7 @@ ret=$?; if [[ 0 -ne $ret ]]; then | ||
| 15 | exit $ret | 15 | exit $ret |
| 16 | fi | 16 | fi |
| 17 | 17 | ||
| 18 | -files=`git status|egrep "(modified|new file)"|awk -F ':' '{print $2}'|awk '{print $1}'|egrep "(.hpp$|.cpp$|.cc$|.h$|.c$|.txt$|.sh$)"`; | 18 | +files=`git status|egrep "(modified|new file)"|awk -F ':' '{print $2}'|awk '{print $1}'|egrep "(.hpp$|.cpp$|.cc$|.h$|.c$|.txt$|.sh|.conf$)"`; |
| 19 | for file in $files; do | 19 | for file in $files; do |
| 20 | dos2unix $file; | 20 | dos2unix $file; |
| 21 | echo $file|grep ".sh$" >/dev/null 2>&1; EOF_SH=$? | 21 | echo $file|grep ".sh$" >/dev/null 2>&1; EOF_SH=$? |
| @@ -434,7 +434,8 @@ int SrsConfig::reload_conf(SrsConfig* conf) | @@ -434,7 +434,8 @@ int SrsConfig::reload_conf(SrsConfig* conf) | ||
| 434 | // always support reload without additional code: | 434 | // always support reload without additional code: |
| 435 | // chunk_size, ff_log_dir, max_connections, | 435 | // chunk_size, ff_log_dir, max_connections, |
| 436 | // bandcheck, http_hooks, heartbeat, | 436 | // bandcheck, http_hooks, heartbeat, |
| 437 | - // token_traverse, debug_srs_upnode | 437 | + // token_traverse, debug_srs_upnode, |
| 438 | + // security | ||
| 438 | 439 | ||
| 439 | // merge config: listen | 440 | // merge config: listen |
| 440 | if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) { | 441 | if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) { |
| @@ -1363,6 +1364,7 @@ int SrsConfig::check_config() | @@ -1363,6 +1364,7 @@ int SrsConfig::check_config() | ||
| 1363 | && n != "atc" && n != "atc_auto" | 1364 | && n != "atc" && n != "atc_auto" |
| 1364 | && n != "debug_srs_upnode" | 1365 | && n != "debug_srs_upnode" |
| 1365 | && n != "mr" && n != "mw_latency" && n != "min_latency" | 1366 | && n != "mr" && n != "mw_latency" && n != "min_latency" |
| 1367 | + && n != "security" | ||
| 1366 | ) { | 1368 | ) { |
| 1367 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1369 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1368 | srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret); | 1370 | srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret); |
| @@ -1424,6 +1426,7 @@ int SrsConfig::check_config() | @@ -1424,6 +1426,7 @@ int SrsConfig::check_config() | ||
| 1424 | string m = conf->at(j)->name.c_str(); | 1426 | string m = conf->at(j)->name.c_str(); |
| 1425 | if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish" | 1427 | if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish" |
| 1426 | && m != "on_unpublish" && m != "on_play" && m != "on_stop" | 1428 | && m != "on_unpublish" && m != "on_play" && m != "on_stop" |
| 1429 | + && m != "on_dvr" | ||
| 1427 | ) { | 1430 | ) { |
| 1428 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1431 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1429 | srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret); | 1432 | srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret); |
| @@ -1440,6 +1443,16 @@ int SrsConfig::check_config() | @@ -1440,6 +1443,16 @@ int SrsConfig::check_config() | ||
| 1440 | return ret; | 1443 | return ret; |
| 1441 | } | 1444 | } |
| 1442 | }*/ | 1445 | }*/ |
| 1446 | + } else if (n == "security") { | ||
| 1447 | + for (int j = 0; j < (int)conf->directives.size(); j++) { | ||
| 1448 | + SrsConfDirective* security = conf->at(j); | ||
| 1449 | + string m = security->name.c_str(); | ||
| 1450 | + if (m != "enabled" && m != "deny" && m != "allow") { | ||
| 1451 | + ret = ERROR_SYSTEM_CONFIG_INVALID; | ||
| 1452 | + srs_error("unsupported vhost security directive %s, ret=%d", m.c_str(), ret); | ||
| 1453 | + return ret; | ||
| 1454 | + } | ||
| 1455 | + } | ||
| 1443 | } else if (n == "transcode") { | 1456 | } else if (n == "transcode") { |
| 1444 | for (int j = 0; j < (int)conf->directives.size(); j++) { | 1457 | for (int j = 0; j < (int)conf->directives.size(); j++) { |
| 1445 | SrsConfDirective* trans = conf->at(j); | 1458 | SrsConfDirective* trans = conf->at(j); |
| @@ -2323,6 +2336,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) | @@ -2323,6 +2336,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) | ||
| 2323 | return conf->get("on_stop"); | 2336 | return conf->get("on_stop"); |
| 2324 | } | 2337 | } |
| 2325 | 2338 | ||
| 2339 | +SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost) | ||
| 2340 | +{ | ||
| 2341 | + SrsConfDirective* conf = get_vhost_http_hooks(vhost); | ||
| 2342 | + | ||
| 2343 | + if (!conf) { | ||
| 2344 | + return NULL; | ||
| 2345 | + } | ||
| 2346 | + | ||
| 2347 | + return conf->get("on_dvr"); | ||
| 2348 | +} | ||
| 2349 | + | ||
| 2326 | bool SrsConfig::get_bw_check_enabled(string vhost) | 2350 | bool SrsConfig::get_bw_check_enabled(string vhost) |
| 2327 | { | 2351 | { |
| 2328 | SrsConfDirective* conf = get_vhost(vhost); | 2352 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -2456,6 +2480,43 @@ bool SrsConfig::get_vhost_edge_token_traverse(string vhost) | @@ -2456,6 +2480,43 @@ bool SrsConfig::get_vhost_edge_token_traverse(string vhost) | ||
| 2456 | return true; | 2480 | return true; |
| 2457 | } | 2481 | } |
| 2458 | 2482 | ||
| 2483 | +bool SrsConfig::get_security_enabled(string vhost) | ||
| 2484 | +{ | ||
| 2485 | + SrsConfDirective* conf = get_vhost(vhost); | ||
| 2486 | + | ||
| 2487 | + if (!conf) { | ||
| 2488 | + return SRS_CONF_DEFAULT_SECURITY_ENABLED; | ||
| 2489 | + } | ||
| 2490 | + | ||
| 2491 | + SrsConfDirective* security = conf->get("security"); | ||
| 2492 | + if (!security) { | ||
| 2493 | + return SRS_CONF_DEFAULT_SECURITY_ENABLED; | ||
| 2494 | + } | ||
| 2495 | + | ||
| 2496 | + conf = security->get("enabled"); | ||
| 2497 | + if (!conf || conf->arg0() != "on") { | ||
| 2498 | + return SRS_CONF_DEFAULT_SECURITY_ENABLED; | ||
| 2499 | + } | ||
| 2500 | + | ||
| 2501 | + return true; | ||
| 2502 | +} | ||
| 2503 | + | ||
| 2504 | +SrsConfDirective* SrsConfig::get_security_rules(string vhost) | ||
| 2505 | +{ | ||
| 2506 | + SrsConfDirective* conf = get_vhost(vhost); | ||
| 2507 | + | ||
| 2508 | + if (!conf) { | ||
| 2509 | + return NULL; | ||
| 2510 | + } | ||
| 2511 | + | ||
| 2512 | + SrsConfDirective* security = conf->get("security"); | ||
| 2513 | + if (!security) { | ||
| 2514 | + return NULL; | ||
| 2515 | + } | ||
| 2516 | + | ||
| 2517 | + return security; | ||
| 2518 | +} | ||
| 2519 | + | ||
| 2459 | SrsConfDirective* SrsConfig::get_transcode(string vhost, string scope) | 2520 | SrsConfDirective* SrsConfig::get_transcode(string vhost, string scope) |
| 2460 | { | 2521 | { |
| 2461 | SrsConfDirective* conf = get_vhost(vhost); | 2522 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -76,6 +76,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -76,6 +76,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 76 | #define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL "http://"SRS_CONSTS_LOCALHOST":8085/api/v1/servers" | 76 | #define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL "http://"SRS_CONSTS_LOCALHOST":8085/api/v1/servers" |
| 77 | #define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_SUMMARIES false | 77 | #define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_SUMMARIES false |
| 78 | 78 | ||
| 79 | +#define SRS_CONF_DEFAULT_SECURITY_ENABLED false | ||
| 80 | + | ||
| 79 | #define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0 | 81 | #define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0 |
| 80 | 82 | ||
| 81 | #define SRS_CONF_DEFAULT_STAGE_PLAY_USER_INTERVAL_MS 10000 | 83 | #define SRS_CONF_DEFAULT_STAGE_PLAY_USER_INTERVAL_MS 10000 |
| @@ -608,6 +610,11 @@ public: | @@ -608,6 +610,11 @@ public: | ||
| 608 | * @return the on_stop callback directive, the args is the url to callback. | 610 | * @return the on_stop callback directive, the args is the url to callback. |
| 609 | */ | 611 | */ |
| 610 | virtual SrsConfDirective* get_vhost_on_stop(std::string vhost); | 612 | virtual SrsConfDirective* get_vhost_on_stop(std::string vhost); |
| 613 | + /** | ||
| 614 | + * get the on_dvr callbacks of vhost. | ||
| 615 | + * @return the on_dvr callback directive, the args is the url to callback. | ||
| 616 | + */ | ||
| 617 | + virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost); | ||
| 611 | // bwct(bandwidth check tool) section | 618 | // bwct(bandwidth check tool) section |
| 612 | public: | 619 | public: |
| 613 | /** | 620 | /** |
| @@ -659,6 +666,16 @@ public: | @@ -659,6 +666,16 @@ public: | ||
| 659 | * all clients connected to edge must be tranverse to origin to verify. | 666 | * all clients connected to edge must be tranverse to origin to verify. |
| 660 | */ | 667 | */ |
| 661 | virtual bool get_vhost_edge_token_traverse(std::string vhost); | 668 | virtual bool get_vhost_edge_token_traverse(std::string vhost); |
| 669 | +// vhost security section | ||
| 670 | +public: | ||
| 671 | + /** | ||
| 672 | + * whether the secrity of vhost enabled. | ||
| 673 | + */ | ||
| 674 | + virtual bool get_security_enabled(std::string vhost); | ||
| 675 | + /** | ||
| 676 | + * get the security rules. | ||
| 677 | + */ | ||
| 678 | + virtual SrsConfDirective* get_security_rules(std::string vhost); | ||
| 662 | // vhost transcode section | 679 | // vhost transcode section |
| 663 | public: | 680 | public: |
| 664 | /** | 681 | /** |
| @@ -776,7 +793,7 @@ public: | @@ -776,7 +793,7 @@ public: | ||
| 776 | * @remark, we will use some variable, for instance, [vhost] to substitude with vhost. | 793 | * @remark, we will use some variable, for instance, [vhost] to substitude with vhost. |
| 777 | */ | 794 | */ |
| 778 | virtual std::string get_engine_output(SrsConfDirective* engine); | 795 | virtual std::string get_engine_output(SrsConfDirective* engine); |
| 779 | -// ingest section | 796 | +// vhost ingest section |
| 780 | public: | 797 | public: |
| 781 | /** | 798 | /** |
| 782 | * get the ingest directives of vhost. | 799 | * get the ingest directives of vhost. |
| @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 27 | 27 | ||
| 28 | #include <fcntl.h> | 28 | #include <fcntl.h> |
| 29 | #include <sstream> | 29 | #include <sstream> |
| 30 | +#include <sys/time.h> | ||
| 30 | using namespace std; | 31 | using namespace std; |
| 31 | 32 | ||
| 32 | #include <srs_app_config.hpp> | 33 | #include <srs_app_config.hpp> |
| @@ -136,14 +137,97 @@ int SrsDvrPlan::open_new_segment() | @@ -136,14 +137,97 @@ int SrsDvrPlan::open_new_segment() | ||
| 136 | 137 | ||
| 137 | SrsRequest* req = _req; | 138 | SrsRequest* req = _req; |
| 138 | 139 | ||
| 139 | - // new flv file | ||
| 140 | - std::stringstream path; | 140 | + // the path in config, for example, |
| 141 | + // /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv | ||
| 142 | + std::string path_config = _srs_config->get_dvr_path(req->vhost); | ||
| 141 | 143 | ||
| 142 | - path << _srs_config->get_dvr_path(req->vhost) | ||
| 143 | - << "/" << req->app << "/" | ||
| 144 | - << req->stream << "." << srs_get_system_time_ms() << ".flv"; | 144 | + // add [stream].[timestamp].flv as filename for dir |
| 145 | + if (path_config.find(".flv") != path_config.length() - 4) { | ||
| 146 | + path_config += "/[stream].[timestamp].flv"; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + // the flv file path | ||
| 150 | + std::string path = path_config; | ||
| 151 | + | ||
| 152 | + // variable [vhost] | ||
| 153 | + path = srs_string_replace(path, "[vhost]", req->vhost); | ||
| 154 | + // variable [app] | ||
| 155 | + path = srs_string_replace(path, "[app]", req->app); | ||
| 156 | + // variable [stream] | ||
| 157 | + path = srs_string_replace(path, "[stream]", req->stream); | ||
| 158 | + | ||
| 159 | + // date and time substitude | ||
| 160 | + // clock time | ||
| 161 | + timeval tv; | ||
| 162 | + if (gettimeofday(&tv, NULL) == -1) { | ||
| 163 | + return ERROR_SYSTEM_TIME; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + // to calendar time | ||
| 167 | + struct tm* tm; | ||
| 168 | + if ((tm = localtime(&tv.tv_sec)) == NULL) { | ||
| 169 | + return ERROR_SYSTEM_TIME; | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + // the buffer to format the date and time. | ||
| 173 | + char buf[64]; | ||
| 174 | + | ||
| 175 | + // [2006], replace with current year. | ||
| 176 | + if (true) { | ||
| 177 | + snprintf(buf, sizeof(buf), "%d", 1900 + tm->tm_year); | ||
| 178 | + path = srs_string_replace(path, "[2006]", buf); | ||
| 179 | + } | ||
| 180 | + // [2006], replace with current year. | ||
| 181 | + if (true) { | ||
| 182 | + snprintf(buf, sizeof(buf), "%d", 1900 + tm->tm_year); | ||
| 183 | + path = srs_string_replace(path, "[2006]", buf); | ||
| 184 | + } | ||
| 185 | + // [01], replace this const to current month. | ||
| 186 | + if (true) { | ||
| 187 | + snprintf(buf, sizeof(buf), "%d", 1 + tm->tm_mon); | ||
| 188 | + path = srs_string_replace(path, "[01]", buf); | ||
| 189 | + } | ||
| 190 | + // [02], replace this const to current date. | ||
| 191 | + if (true) { | ||
| 192 | + snprintf(buf, sizeof(buf), "%d", tm->tm_mday); | ||
| 193 | + path = srs_string_replace(path, "[02]", buf); | ||
| 194 | + } | ||
| 195 | + // [15], replace this const to current hour. | ||
| 196 | + if (true) { | ||
| 197 | + snprintf(buf, sizeof(buf), "%d", tm->tm_hour); | ||
| 198 | + path = srs_string_replace(path, "[15]", buf); | ||
| 199 | + } | ||
| 200 | + // [04], repleace this const to current minute. | ||
| 201 | + if (true) { | ||
| 202 | + snprintf(buf, sizeof(buf), "%d", tm->tm_min); | ||
| 203 | + path = srs_string_replace(path, "[04]", buf); | ||
| 204 | + } | ||
| 205 | + // [05], repleace this const to current second. | ||
| 206 | + if (true) { | ||
| 207 | + snprintf(buf, sizeof(buf), "%d", tm->tm_sec); | ||
| 208 | + path = srs_string_replace(path, "[05]", buf); | ||
| 209 | + } | ||
| 210 | + // [999], repleace this const to current millisecond. | ||
| 211 | + if (true) { | ||
| 212 | + snprintf(buf, sizeof(buf), "%03d", (int)(tv.tv_usec / 1000)); | ||
| 213 | + path = srs_string_replace(path, "[999]", buf); | ||
| 214 | + } | ||
| 215 | + // [timestamp],replace this const to current UNIX timestamp in ms. | ||
| 216 | + if (true) { | ||
| 217 | + int64_t now_us = ((int64_t)tv.tv_sec) * 1000 * 1000 + (int64_t)tv.tv_usec; | ||
| 218 | + snprintf(buf, sizeof(buf), "%"PRId64, now_us / 1000); | ||
| 219 | + path = srs_string_replace(path, "[timestamp]", buf); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + // create dir first. | ||
| 223 | + std::string dir = path.substr(0, path.rfind("/")); | ||
| 224 | + if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) { | ||
| 225 | + srs_error("create dir=%s failed. ret=%d", dir.c_str(), ret); | ||
| 226 | + return ret; | ||
| 227 | + } | ||
| 228 | + srs_info("create dir=%s ok", dir.c_str()); | ||
| 145 | 229 | ||
| 146 | - if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) { | 230 | + if ((ret = flv_open(req->get_stream_url(), path)) != ERROR_SUCCESS) { |
| 147 | return ret; | 231 | return ret; |
| 148 | } | 232 | } |
| 149 | dvr_enabled = true; | 233 | dvr_enabled = true; |
| @@ -320,6 +404,30 @@ int SrsDvrPlan::flv_close() | @@ -320,6 +404,30 @@ int SrsDvrPlan::flv_close() | ||
| 320 | return ret; | 404 | return ret; |
| 321 | } | 405 | } |
| 322 | 406 | ||
| 407 | +#ifdef SRS_AUTO_HTTP_CALLBACK | ||
| 408 | + SrsRequest* req = _req; | ||
| 409 | + if (_srs_config->get_vhost_http_hooks_enabled(req->vhost)) { | ||
| 410 | + // HTTP: on_dvr | ||
| 411 | + SrsConfDirective* on_dvr = _srs_config->get_vhost_on_dvr(req->vhost); | ||
| 412 | + if (!on_dvr) { | ||
| 413 | + srs_info("ignore the empty http callback: on_dvr"); | ||
| 414 | + return ret; | ||
| 415 | + } | ||
| 416 | + | ||
| 417 | + int connection_id = _srs_context->get_id(); | ||
| 418 | + std::string ip = req->ip; | ||
| 419 | + std::string cwd = _srs_config->cwd(); | ||
| 420 | + std::string file = segment->path; | ||
| 421 | + for (int i = 0; i < (int)on_dvr->args.size(); i++) { | ||
| 422 | + std::string url = on_dvr->args.at(i); | ||
| 423 | + if ((ret = SrsHttpHooks::on_dvr(url, connection_id, ip, req, cwd, file)) != ERROR_SUCCESS) { | ||
| 424 | + srs_error("hook client on_dvr failed. url=%s, ret=%d", url.c_str(), ret); | ||
| 425 | + return ret; | ||
| 426 | + } | ||
| 427 | + } | ||
| 428 | + } | ||
| 429 | +#endif | ||
| 430 | + | ||
| 323 | return ret; | 431 | return ret; |
| 324 | } | 432 | } |
| 325 | 433 |
| @@ -951,16 +951,12 @@ int SrsHlsMuxer::create_dir() | @@ -951,16 +951,12 @@ int SrsHlsMuxer::create_dir() | ||
| 951 | app_dir += app; | 951 | app_dir += app; |
| 952 | 952 | ||
| 953 | // TODO: cleanup the dir when startup. | 953 | // TODO: cleanup the dir when startup. |
| 954 | - | ||
| 955 | - mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH; | ||
| 956 | - if (::mkdir(app_dir.c_str(), mode) < 0) { | ||
| 957 | - if (errno != EEXIST) { | ||
| 958 | - ret = ERROR_HLS_CREATE_DIR; | ||
| 959 | - srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret); | ||
| 960 | - return ret; | ||
| 961 | - } | 954 | + |
| 955 | + if ((ret = srs_create_dir_recursively(app_dir)) != ERROR_SUCCESS) { | ||
| 956 | + srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret); | ||
| 957 | + return ret; | ||
| 962 | } | 958 | } |
| 963 | - srs_info("create app dir %s success.", app_dir.c_str()); | 959 | + srs_info("create app dir %s ok", app_dir.c_str()); |
| 964 | 960 | ||
| 965 | return ret; | 961 | return ret; |
| 966 | } | 962 | } |
| @@ -26,7 +26,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -26,7 +26,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 26 | #ifdef SRS_AUTO_HTTP_API | 26 | #ifdef SRS_AUTO_HTTP_API |
| 27 | 27 | ||
| 28 | #include <sstream> | 28 | #include <sstream> |
| 29 | -#include <set> | ||
| 30 | using namespace std; | 29 | using namespace std; |
| 31 | 30 | ||
| 32 | #include <srs_kernel_log.hpp> | 31 | #include <srs_kernel_log.hpp> |
| @@ -153,8 +152,8 @@ int SrsApiV1::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) | @@ -153,8 +152,8 @@ int SrsApiV1::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) | ||
| 153 | << __SRS_JFIELD_STR("meminfos", "the meminfo of system") << __SRS_JFIELD_CONT | 152 | << __SRS_JFIELD_STR("meminfos", "the meminfo of system") << __SRS_JFIELD_CONT |
| 154 | << __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT | 153 | << __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT |
| 155 | << __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT | 154 | << __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT |
| 156 | - << __SRS_JFIELD_STR("vhosts", "list all vhosts") << __SRS_JFIELD_CONT | ||
| 157 | - << __SRS_JFIELD_STR("streams", "list streams that match the name or vhost") | 155 | + << __SRS_JFIELD_STR("vhosts", "dumps vhost to json") << __SRS_JFIELD_CONT |
| 156 | + << __SRS_JFIELD_STR("streams", "dumps streams to json") | ||
| 158 | << __SRS_JOBJECT_END | 157 | << __SRS_JOBJECT_END |
| 159 | << __SRS_JOBJECT_END; | 158 | << __SRS_JOBJECT_END; |
| 160 | 159 | ||
| @@ -522,30 +521,19 @@ bool SrsApiVhosts::can_handle(const char* path, int length, const char** /*pchil | @@ -522,30 +521,19 @@ bool SrsApiVhosts::can_handle(const char* path, int length, const char** /*pchil | ||
| 522 | 521 | ||
| 523 | int SrsApiVhosts::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) | 522 | int SrsApiVhosts::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) |
| 524 | { | 523 | { |
| 524 | + std::stringstream data; | ||
| 525 | + SrsStatistic* stat = SrsStatistic::instance(); | ||
| 526 | + int ret = stat->dumps_vhosts(data); | ||
| 527 | + | ||
| 525 | std::stringstream ss; | 528 | std::stringstream ss; |
| 526 | 529 | ||
| 527 | - std::set<std::string> vhost_set; | ||
| 528 | - SrsStreamInfoMap* pool = SrsStatistic::instance()->get_pool(); | ||
| 529 | - SrsStreamInfoMap::iterator it; | ||
| 530 | - for (it = pool->begin(); it != pool->end(); it++) { | ||
| 531 | - if (it->second->_req == NULL) | ||
| 532 | - continue; | ||
| 533 | - vhost_set.insert(it->second->_req->vhost); | ||
| 534 | - } | ||
| 535 | - | ||
| 536 | - ss << __SRS_JARRAY_START; | ||
| 537 | - bool first = true; | ||
| 538 | - std::set<std::string>::iterator it_set; | ||
| 539 | - for (it_set = vhost_set.begin(); it_set != vhost_set.end(); it_set++) { | ||
| 540 | - if (first) { | ||
| 541 | - first = false; | ||
| 542 | - } else { | ||
| 543 | - ss << __SRS_JFIELD_CONT; | ||
| 544 | - } | ||
| 545 | - | ||
| 546 | - ss << "\"" << (*it_set) << "\""; | ||
| 547 | - } | ||
| 548 | - ss << __SRS_JARRAY_END; | 530 | + ss << __SRS_JOBJECT_START |
| 531 | + << __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT | ||
| 532 | + << __SRS_JFIELD_ORG("server", stat->server_id()) << __SRS_JFIELD_CONT | ||
| 533 | + << __SRS_JFIELD_ORG("vhosts", __SRS_JARRAY_START) | ||
| 534 | + << data.str() | ||
| 535 | + << __SRS_JARRAY_END | ||
| 536 | + << __SRS_JOBJECT_END; | ||
| 549 | 537 | ||
| 550 | return res_json(skt, req, ss.str()); | 538 | return res_json(skt, req, ss.str()); |
| 551 | } | 539 | } |
| @@ -565,41 +553,19 @@ bool SrsApiStreams::can_handle(const char* path, int length, const char** /*pchi | @@ -565,41 +553,19 @@ bool SrsApiStreams::can_handle(const char* path, int length, const char** /*pchi | ||
| 565 | 553 | ||
| 566 | int SrsApiStreams::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) | 554 | int SrsApiStreams::do_process_request(SrsStSocket* skt, SrsHttpMessage* req) |
| 567 | { | 555 | { |
| 556 | + std::stringstream data; | ||
| 557 | + SrsStatistic* stat = SrsStatistic::instance(); | ||
| 558 | + int ret = stat->dumps_streams(data); | ||
| 559 | + | ||
| 568 | std::stringstream ss; | 560 | std::stringstream ss; |
| 569 | 561 | ||
| 570 | - std::string query_name = req->query_get("name"); | ||
| 571 | - std::string query_vhost = req->query_get("vhost"); | ||
| 572 | - if (query_name.size() > 0 || query_vhost.size() > 0) { | ||
| 573 | - ss << __SRS_JARRAY_START; | ||
| 574 | - bool first = true; | ||
| 575 | - SrsStreamInfoMap* pool = SrsStatistic::instance()->get_pool(); | ||
| 576 | - SrsStreamInfoMap::iterator it; | ||
| 577 | - for (it = pool->begin(); it != pool->end(); it++) { | ||
| 578 | - SrsRequest* reqinfo = it->second->_req; | ||
| 579 | - if (reqinfo == NULL) | ||
| 580 | - continue; | ||
| 581 | - | ||
| 582 | - if (reqinfo->stream == query_name || reqinfo->vhost == query_vhost) { | ||
| 583 | - if (first) { | ||
| 584 | - first = false; | ||
| 585 | - } else { | ||
| 586 | - ss << __SRS_JFIELD_CONT; | ||
| 587 | - } | ||
| 588 | - | ||
| 589 | - ss << __SRS_JOBJECT_START | ||
| 590 | - << __SRS_JFIELD_STR("name", reqinfo->stream) << __SRS_JFIELD_CONT | ||
| 591 | - << __SRS_JFIELD_STR("url", reqinfo->tcUrl) << __SRS_JFIELD_CONT | ||
| 592 | - << __SRS_JFIELD_ORG("clients", 0) << __SRS_JFIELD_CONT | ||
| 593 | - << __SRS_JFIELD_STR("status", "idle") << __SRS_JFIELD_CONT | ||
| 594 | - << __SRS_JFIELD_STR("type", "") << __SRS_JFIELD_CONT | ||
| 595 | - << __SRS_JFIELD_STR("codec", "") | ||
| 596 | - << __SRS_JOBJECT_END; | ||
| 597 | - } | ||
| 598 | - } | ||
| 599 | - ss << __SRS_JARRAY_END; | ||
| 600 | - } else { | ||
| 601 | - return res_error(skt, req, 400, "Bad Request", "unknown query"); | ||
| 602 | - } | 562 | + ss << __SRS_JOBJECT_START |
| 563 | + << __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT | ||
| 564 | + << __SRS_JFIELD_ORG("server", stat->server_id()) << __SRS_JFIELD_CONT | ||
| 565 | + << __SRS_JFIELD_ORG("streams", __SRS_JARRAY_START) | ||
| 566 | + << data.str() | ||
| 567 | + << __SRS_JARRAY_END | ||
| 568 | + << __SRS_JOBJECT_END; | ||
| 603 | 569 | ||
| 604 | return res_json(skt, req, ss.str()); | 570 | return res_json(skt, req, ss.str()); |
| 605 | } | 571 | } |
| @@ -122,8 +122,7 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re | @@ -122,8 +122,7 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re | ||
| 122 | << __SRS_JFIELD_ORG("client_id", client_id) << __SRS_JFIELD_CONT | 122 | << __SRS_JFIELD_ORG("client_id", client_id) << __SRS_JFIELD_CONT |
| 123 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | 123 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT |
| 124 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | 124 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT |
| 125 | - << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | ||
| 126 | - << __SRS_JFIELD_STR("pageUrl", req->pageUrl) | 125 | + << __SRS_JFIELD_STR("app", req->app) |
| 127 | << __SRS_JOBJECT_END; | 126 | << __SRS_JOBJECT_END; |
| 128 | std::string data = ss.str(); | 127 | std::string data = ss.str(); |
| 129 | std::string res; | 128 | std::string res; |
| @@ -178,7 +177,6 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r | @@ -178,7 +177,6 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r | ||
| 178 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | 177 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT |
| 179 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | 178 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT |
| 180 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | 179 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT |
| 181 | - << __SRS_JFIELD_STR("pageUrl", req->pageUrl) << __SRS_JFIELD_CONT | ||
| 182 | << __SRS_JFIELD_STR("stream", req->stream) | 180 | << __SRS_JFIELD_STR("stream", req->stream) |
| 183 | << __SRS_JOBJECT_END; | 181 | << __SRS_JOBJECT_END; |
| 184 | std::string data = ss.str(); | 182 | std::string data = ss.str(); |
| @@ -234,7 +232,6 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest | @@ -234,7 +232,6 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest | ||
| 234 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | 232 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT |
| 235 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | 233 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT |
| 236 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | 234 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT |
| 237 | - << __SRS_JFIELD_STR("pageUrl", req->pageUrl) << __SRS_JFIELD_CONT | ||
| 238 | << __SRS_JFIELD_STR("stream", req->stream) | 235 | << __SRS_JFIELD_STR("stream", req->stream) |
| 239 | << __SRS_JOBJECT_END; | 236 | << __SRS_JOBJECT_END; |
| 240 | std::string data = ss.str(); | 237 | std::string data = ss.str(); |
| @@ -290,7 +287,6 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req) | @@ -290,7 +287,6 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req) | ||
| 290 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | 287 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT |
| 291 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | 288 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT |
| 292 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | 289 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT |
| 293 | - << __SRS_JFIELD_STR("pageUrl", req->pageUrl) << __SRS_JFIELD_CONT | ||
| 294 | << __SRS_JFIELD_STR("stream", req->stream) | 290 | << __SRS_JFIELD_STR("stream", req->stream) |
| 295 | << __SRS_JOBJECT_END; | 291 | << __SRS_JOBJECT_END; |
| 296 | std::string data = ss.str(); | 292 | std::string data = ss.str(); |
| @@ -346,7 +342,6 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | @@ -346,7 +342,6 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | ||
| 346 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | 342 | << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT |
| 347 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | 343 | << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT |
| 348 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | 344 | << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT |
| 349 | - << __SRS_JFIELD_STR("pageUrl", req->pageUrl) << __SRS_JFIELD_CONT | ||
| 350 | << __SRS_JFIELD_STR("stream", req->stream) | 345 | << __SRS_JFIELD_STR("stream", req->stream) |
| 351 | << __SRS_JOBJECT_END; | 346 | << __SRS_JOBJECT_END; |
| 352 | std::string data = ss.str(); | 347 | std::string data = ss.str(); |
| @@ -384,5 +379,61 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | @@ -384,5 +379,61 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | ||
| 384 | return; | 379 | return; |
| 385 | } | 380 | } |
| 386 | 381 | ||
| 387 | -#endif | 382 | +int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req, string cwd, string file) |
| 383 | +{ | ||
| 384 | + int ret = ERROR_SUCCESS; | ||
| 385 | + | ||
| 386 | + SrsHttpUri uri; | ||
| 387 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 388 | + srs_error("http uri parse on_dvr url failed, ignored. " | ||
| 389 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 390 | + return ret; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + std::stringstream ss; | ||
| 394 | + ss << __SRS_JOBJECT_START | ||
| 395 | + << __SRS_JFIELD_STR("action", "on_dvr") << __SRS_JFIELD_CONT | ||
| 396 | + << __SRS_JFIELD_ORG("client_id", client_id) << __SRS_JFIELD_CONT | ||
| 397 | + << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | ||
| 398 | + << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | ||
| 399 | + << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | ||
| 400 | + << __SRS_JFIELD_STR("stream", req->stream) << __SRS_JFIELD_CONT | ||
| 401 | + << __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT | ||
| 402 | + << __SRS_JFIELD_STR("file", file) | ||
| 403 | + << __SRS_JOBJECT_END; | ||
| 404 | + std::string data = ss.str(); | ||
| 405 | + std::string res; | ||
| 406 | + int status_code; | ||
| 407 | + | ||
| 408 | + SrsHttpClient http; | ||
| 409 | + if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) { | ||
| 410 | + srs_error("http post on_dvr uri failed, ignored. " | ||
| 411 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 412 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 413 | + return ret; | ||
| 414 | + } | ||
| 415 | + | ||
| 416 | + // ensure the http status is ok. | ||
| 417 | + // https://github.com/winlinvip/simple-rtmp-server/issues/158 | ||
| 418 | + if (status_code != SRS_CONSTS_HTTP_OK) { | ||
| 419 | + ret = ERROR_HTTP_STATUS_INVLIAD; | ||
| 420 | + srs_error("http hook on_dvr status failed. " | ||
| 421 | + "client_id=%d, code=%d, ret=%d", client_id, status_code, ret); | ||
| 422 | + return ret; | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 426 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 427 | + srs_warn("http hook on_dvr validate failed, ignored. " | ||
| 428 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 429 | + return ret; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + srs_trace("http hook on_dvr success. " | ||
| 433 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 434 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 435 | + | ||
| 436 | + return ret; | ||
| 437 | +} | ||
| 388 | 438 | ||
| 439 | +#endif |
| @@ -58,7 +58,6 @@ public: | @@ -58,7 +58,6 @@ public: | ||
| 58 | * @param client_id the id of client on server. | 58 | * @param client_id the id of client on server. |
| 59 | * @param url the api server url, to valid the client. | 59 | * @param url the api server url, to valid the client. |
| 60 | * ignore if empty. | 60 | * ignore if empty. |
| 61 | - * @return valid failed or connect to the url failed. | ||
| 62 | */ | 61 | */ |
| 63 | static int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); | 62 | static int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 64 | /** | 63 | /** |
| @@ -73,7 +72,6 @@ public: | @@ -73,7 +72,6 @@ public: | ||
| 73 | * @param client_id the id of client on server. | 72 | * @param client_id the id of client on server. |
| 74 | * @param url the api server url, to valid the client. | 73 | * @param url the api server url, to valid the client. |
| 75 | * ignore if empty. | 74 | * ignore if empty. |
| 76 | - * @return valid failed or connect to the url failed. | ||
| 77 | */ | 75 | */ |
| 78 | static int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); | 76 | static int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 79 | /** | 77 | /** |
| @@ -88,7 +86,6 @@ public: | @@ -88,7 +86,6 @@ public: | ||
| 88 | * @param client_id the id of client on server. | 86 | * @param client_id the id of client on server. |
| 89 | * @param url the api server url, to valid the client. | 87 | * @param url the api server url, to valid the client. |
| 90 | * ignore if empty. | 88 | * ignore if empty. |
| 91 | - * @return valid failed or connect to the url failed. | ||
| 92 | */ | 89 | */ |
| 93 | static int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); | 90 | static int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 94 | /** | 91 | /** |
| @@ -98,6 +95,15 @@ public: | @@ -98,6 +95,15 @@ public: | ||
| 98 | * ignore if empty. | 95 | * ignore if empty. |
| 99 | */ | 96 | */ |
| 100 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); | 97 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 98 | + /** | ||
| 99 | + * on_dvr hook, when reap a dvr file. | ||
| 100 | + * @param client_id the id of client on server. | ||
| 101 | + * @param url the api server url, to process the event. | ||
| 102 | + * ignore if empty. | ||
| 103 | + * @param cwd the current work directory, used to resolve the reltive file path. | ||
| 104 | + * @param file the file path, can be relative or absolute path. | ||
| 105 | + */ | ||
| 106 | + static int on_dvr(std::string url, int client_id, std::string ip, SrsRequest* req, std::string cwd, std::string file); | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | #endif | 109 | #endif |
| @@ -51,6 +51,7 @@ using namespace std; | @@ -51,6 +51,7 @@ using namespace std; | ||
| 51 | #include <srs_app_recv_thread.hpp> | 51 | #include <srs_app_recv_thread.hpp> |
| 52 | #include <srs_core_performance.hpp> | 52 | #include <srs_core_performance.hpp> |
| 53 | #include <srs_kernel_utility.hpp> | 53 | #include <srs_kernel_utility.hpp> |
| 54 | +#include <srs_app_security.hpp> | ||
| 54 | #include <srs_app_statistic.hpp> | 55 | #include <srs_app_statistic.hpp> |
| 55 | 56 | ||
| 56 | // when stream is busy, for example, streaming is already | 57 | // when stream is busy, for example, streaming is already |
| @@ -82,6 +83,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd) | @@ -82,6 +83,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd) | ||
| 82 | rtmp = new SrsRtmpServer(skt); | 83 | rtmp = new SrsRtmpServer(skt); |
| 83 | refer = new SrsRefer(); | 84 | refer = new SrsRefer(); |
| 84 | bandwidth = new SrsBandwidth(); | 85 | bandwidth = new SrsBandwidth(); |
| 86 | + security = new SrsSecurity(); | ||
| 85 | duration = 0; | 87 | duration = 0; |
| 86 | kbps = new SrsKbps(); | 88 | kbps = new SrsKbps(); |
| 87 | kbps->set_io(skt, skt); | 89 | kbps->set_io(skt, skt); |
| @@ -103,6 +105,7 @@ SrsRtmpConn::~SrsRtmpConn() | @@ -103,6 +105,7 @@ SrsRtmpConn::~SrsRtmpConn() | ||
| 103 | srs_freep(skt); | 105 | srs_freep(skt); |
| 104 | srs_freep(refer); | 106 | srs_freep(refer); |
| 105 | srs_freep(bandwidth); | 107 | srs_freep(bandwidth); |
| 108 | + srs_freep(security); | ||
| 106 | srs_freep(kbps); | 109 | srs_freep(kbps); |
| 107 | } | 110 | } |
| 108 | 111 | ||
| @@ -133,6 +136,9 @@ int SrsRtmpConn::do_cycle() | @@ -133,6 +136,9 @@ int SrsRtmpConn::do_cycle() | ||
| 133 | } | 136 | } |
| 134 | srs_verbose("rtmp connect app success"); | 137 | srs_verbose("rtmp connect app success"); |
| 135 | 138 | ||
| 139 | + // set client ip to request. | ||
| 140 | + req->ip = ip; | ||
| 141 | + | ||
| 136 | // discovery vhost, resolve the vhost from config | 142 | // discovery vhost, resolve the vhost from config |
| 137 | SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost); | 143 | SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost); |
| 138 | if (parsed_vhost) { | 144 | if (parsed_vhost) { |
| @@ -361,6 +367,13 @@ int SrsRtmpConn::stream_service_cycle() | @@ -361,6 +367,13 @@ int SrsRtmpConn::stream_service_cycle() | ||
| 361 | req->strip(); | 367 | req->strip(); |
| 362 | srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f", | 368 | srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f", |
| 363 | srs_client_type_string(type).c_str(), req->stream.c_str(), req->duration); | 369 | srs_client_type_string(type).c_str(), req->stream.c_str(), req->duration); |
| 370 | + | ||
| 371 | + // security check | ||
| 372 | + if ((ret = security->check(type, ip, req)) != ERROR_SUCCESS) { | ||
| 373 | + srs_error("security check failed. ret=%d", ret); | ||
| 374 | + return ret; | ||
| 375 | + } | ||
| 376 | + srs_info("security check ok"); | ||
| 364 | 377 | ||
| 365 | // client is identified, set the timeout to service timeout. | 378 | // client is identified, set the timeout to service timeout. |
| 366 | rtmp->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US); | 379 | rtmp->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US); |
| @@ -383,7 +396,12 @@ int SrsRtmpConn::stream_service_cycle() | @@ -383,7 +396,12 @@ int SrsRtmpConn::stream_service_cycle() | ||
| 383 | } | 396 | } |
| 384 | srs_assert(source != NULL); | 397 | srs_assert(source != NULL); |
| 385 | 398 | ||
| 386 | - SrsStatistic::instance()->add_request_info(source, req); | 399 | + // update the statistic when source disconveried. |
| 400 | + SrsStatistic* stat = SrsStatistic::instance(); | ||
| 401 | + if ((ret = stat->on_client(_srs_context->get_id(), req)) != ERROR_SUCCESS) { | ||
| 402 | + srs_error("stat client failed. ret=%d", ret); | ||
| 403 | + return ret; | ||
| 404 | + } | ||
| 387 | 405 | ||
| 388 | // check ASAP, to fail it faster if invalid. | 406 | // check ASAP, to fail it faster if invalid. |
| 389 | if (type != SrsRtmpConnPlay && !vhost_is_edge) { | 407 | if (type != SrsRtmpConnPlay && !vhost_is_edge) { |
| @@ -51,6 +51,7 @@ class SrsRtmpClient; | @@ -51,6 +51,7 @@ class SrsRtmpClient; | ||
| 51 | class SrsSharedPtrMessage; | 51 | class SrsSharedPtrMessage; |
| 52 | class SrsQueueRecvThread; | 52 | class SrsQueueRecvThread; |
| 53 | class SrsPublishRecvThread; | 53 | class SrsPublishRecvThread; |
| 54 | +class SrsSecurity; | ||
| 54 | 55 | ||
| 55 | /** | 56 | /** |
| 56 | * the client provides the main logic control for RTMP clients. | 57 | * the client provides the main logic control for RTMP clients. |
| @@ -66,6 +67,7 @@ private: | @@ -66,6 +67,7 @@ private: | ||
| 66 | SrsRtmpServer* rtmp; | 67 | SrsRtmpServer* rtmp; |
| 67 | SrsRefer* refer; | 68 | SrsRefer* refer; |
| 68 | SrsBandwidth* bandwidth; | 69 | SrsBandwidth* bandwidth; |
| 70 | + SrsSecurity* security; | ||
| 69 | // elapse duration in ms | 71 | // elapse duration in ms |
| 70 | // for live play duration, for instance, rtmpdump to record. | 72 | // for live play duration, for instance, rtmpdump to record. |
| 71 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/47 | 73 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/47 |
trunk/src/app/srs_app_security.cpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2015 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_app_security.hpp> | ||
| 25 | + | ||
| 26 | +#include <srs_kernel_error.hpp> | ||
| 27 | +#include <srs_app_config.hpp> | ||
| 28 | + | ||
| 29 | +using namespace std; | ||
| 30 | + | ||
| 31 | +SrsSecurity::SrsSecurity() | ||
| 32 | +{ | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +SrsSecurity::~SrsSecurity() | ||
| 36 | +{ | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +int SrsSecurity::check(SrsRtmpConnType type, string ip, SrsRequest* req) | ||
| 40 | +{ | ||
| 41 | + int ret = ERROR_SUCCESS; | ||
| 42 | + | ||
| 43 | + // allow all if security disabled. | ||
| 44 | + if (!_srs_config->get_security_enabled(req->vhost)) { | ||
| 45 | + return ret; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + // default to deny all when security enabled. | ||
| 49 | + ret = ERROR_SYSTEM_SECURITY; | ||
| 50 | + | ||
| 51 | + // rules to apply | ||
| 52 | + SrsConfDirective* rules = _srs_config->get_security_rules(req->vhost); | ||
| 53 | + if (!rules) { | ||
| 54 | + return ret; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + // allow if matches allow strategy. | ||
| 58 | + if (allow_check(rules, type, ip) == ERROR_SYSTEM_SECURITY_ALLOW) { | ||
| 59 | + ret = ERROR_SUCCESS; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + // deny if matches deny strategy. | ||
| 63 | + if (deny_check(rules, type, ip) == ERROR_SYSTEM_SECURITY_DENY) { | ||
| 64 | + ret = ERROR_SYSTEM_SECURITY_DENY; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + return ret; | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip) | ||
| 71 | +{ | ||
| 72 | + int ret = ERROR_SUCCESS; | ||
| 73 | + | ||
| 74 | + for (int i = 0; i < (int)rules->directives.size(); i++) { | ||
| 75 | + SrsConfDirective* rule = rules->at(i); | ||
| 76 | + | ||
| 77 | + if (rule->name != "allow") { | ||
| 78 | + continue; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + switch (type) { | ||
| 82 | + case SrsRtmpConnPlay: | ||
| 83 | + if (rule->arg0() != "play") { | ||
| 84 | + break; | ||
| 85 | + } | ||
| 86 | + if (rule->arg1() == "all" || rule->arg1() == ip) { | ||
| 87 | + ret = ERROR_SYSTEM_SECURITY_ALLOW; | ||
| 88 | + break; | ||
| 89 | + } | ||
| 90 | + break; | ||
| 91 | + case SrsRtmpConnFMLEPublish: | ||
| 92 | + case SrsRtmpConnFlashPublish: | ||
| 93 | + if (rule->arg0() != "publish") { | ||
| 94 | + break; | ||
| 95 | + } | ||
| 96 | + if (rule->arg1() == "all" || rule->arg1() == ip) { | ||
| 97 | + ret = ERROR_SYSTEM_SECURITY_ALLOW; | ||
| 98 | + break; | ||
| 99 | + } | ||
| 100 | + break; | ||
| 101 | + case SrsRtmpConnUnknown: | ||
| 102 | + default: | ||
| 103 | + break; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + // when matched, donot search more. | ||
| 107 | + if (ret == ERROR_SYSTEM_SECURITY_ALLOW) { | ||
| 108 | + break; | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + return ret; | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip) | ||
| 116 | +{ | ||
| 117 | + int ret = ERROR_SUCCESS; | ||
| 118 | + | ||
| 119 | + for (int i = 0; i < (int)rules->directives.size(); i++) { | ||
| 120 | + SrsConfDirective* rule = rules->at(i); | ||
| 121 | + | ||
| 122 | + if (rule->name != "deny") { | ||
| 123 | + continue; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + switch (type) { | ||
| 127 | + case SrsRtmpConnPlay: | ||
| 128 | + if (rule->arg0() != "play") { | ||
| 129 | + break; | ||
| 130 | + } | ||
| 131 | + if (rule->arg1() == "all" || rule->arg1() == ip) { | ||
| 132 | + ret = ERROR_SYSTEM_SECURITY_DENY; | ||
| 133 | + break; | ||
| 134 | + } | ||
| 135 | + break; | ||
| 136 | + case SrsRtmpConnFMLEPublish: | ||
| 137 | + case SrsRtmpConnFlashPublish: | ||
| 138 | + if (rule->arg0() != "publish") { | ||
| 139 | + break; | ||
| 140 | + } | ||
| 141 | + if (rule->arg1() == "all" || rule->arg1() == ip) { | ||
| 142 | + ret = ERROR_SYSTEM_SECURITY_DENY; | ||
| 143 | + break; | ||
| 144 | + } | ||
| 145 | + break; | ||
| 146 | + case SrsRtmpConnUnknown: | ||
| 147 | + default: | ||
| 148 | + break; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + // when matched, donot search more. | ||
| 152 | + if (ret == ERROR_SYSTEM_SECURITY_DENY) { | ||
| 153 | + break; | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + return ret; | ||
| 158 | +} | ||
| 159 | + |
trunk/src/app/srs_app_security.hpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2015 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_APP_SECURITY_HPP | ||
| 25 | +#define SRS_APP_SECURITY_HPP | ||
| 26 | + | ||
| 27 | +/* | ||
| 28 | +#include <srs_app_security.hpp> | ||
| 29 | +*/ | ||
| 30 | + | ||
| 31 | +#include <srs_core.hpp> | ||
| 32 | + | ||
| 33 | +#include <string> | ||
| 34 | + | ||
| 35 | +#include <srs_protocol_rtmp.hpp> | ||
| 36 | + | ||
| 37 | +class SrsConfDirective; | ||
| 38 | + | ||
| 39 | +/** | ||
| 40 | +* the security apply on vhost. | ||
| 41 | +* @see https://github.com/winlinvip/simple-rtmp-server/issues/211 | ||
| 42 | +*/ | ||
| 43 | +class SrsSecurity | ||
| 44 | +{ | ||
| 45 | +public: | ||
| 46 | + SrsSecurity(); | ||
| 47 | + virtual ~SrsSecurity(); | ||
| 48 | +public: | ||
| 49 | + /** | ||
| 50 | + * security check the client apply by vhost security strategy | ||
| 51 | + * @param type the client type, publish or play. | ||
| 52 | + * @param ip the ip address of client. | ||
| 53 | + * @param req the request object of client. | ||
| 54 | + */ | ||
| 55 | + virtual int check(SrsRtmpConnType type, std::string ip, SrsRequest* req); | ||
| 56 | +private: | ||
| 57 | + /** | ||
| 58 | + * security check the allow, | ||
| 59 | + * @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW. | ||
| 60 | + */ | ||
| 61 | + virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); | ||
| 62 | + /** | ||
| 63 | + * security check the deny, | ||
| 64 | + * @return, if denied, ERROR_SYSTEM_SECURITY_DENY. | ||
| 65 | + */ | ||
| 66 | + virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); | ||
| 67 | +}; | ||
| 68 | + | ||
| 69 | +#endif | ||
| 70 | + |
| @@ -23,53 +23,142 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,53 +23,142 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_app_statistic.hpp> | 24 | #include <srs_app_statistic.hpp> |
| 25 | 25 | ||
| 26 | +#include <unistd.h> | ||
| 27 | +#include <sstream> | ||
| 28 | +using namespace std; | ||
| 29 | + | ||
| 26 | #include <srs_protocol_rtmp.hpp> | 30 | #include <srs_protocol_rtmp.hpp> |
| 31 | +#include <srs_app_json.hpp> | ||
| 32 | + | ||
| 33 | +int64_t __srs_gvid = getpid(); | ||
| 27 | 34 | ||
| 28 | -SrsStreamInfo::SrsStreamInfo() | 35 | +int64_t __srs_generate_id() |
| 29 | { | 36 | { |
| 30 | - _req = NULL; | 37 | + return __srs_gvid++; |
| 31 | } | 38 | } |
| 32 | 39 | ||
| 33 | -SrsStreamInfo::~SrsStreamInfo() | 40 | +SrsStatisticVhost::SrsStatisticVhost() |
| 34 | { | 41 | { |
| 35 | - if (_req != NULL) | ||
| 36 | - delete _req; | 42 | + id = __srs_generate_id(); |
| 37 | } | 43 | } |
| 38 | 44 | ||
| 39 | -SrsStatistic *SrsStatistic::_instance = NULL; | 45 | +SrsStatisticVhost::~SrsStatisticVhost() |
| 46 | +{ | ||
| 47 | +} | ||
| 40 | 48 | ||
| 41 | -SrsStatistic::SrsStatistic() | 49 | +SrsStatisticStream::SrsStatisticStream() |
| 42 | { | 50 | { |
| 51 | + id = __srs_generate_id(); | ||
| 52 | + vhost = NULL; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +SrsStatisticStream::~SrsStatisticStream() | ||
| 56 | +{ | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +SrsStatistic* SrsStatistic::_instance = new SrsStatistic(); | ||
| 43 | 60 | ||
| 61 | +SrsStatistic::SrsStatistic() | ||
| 62 | +{ | ||
| 63 | + _server_id = __srs_generate_id(); | ||
| 44 | } | 64 | } |
| 45 | 65 | ||
| 46 | SrsStatistic::~SrsStatistic() | 66 | SrsStatistic::~SrsStatistic() |
| 47 | { | 67 | { |
| 48 | - SrsStreamInfoMap::iterator it; | ||
| 49 | - for (it = pool.begin(); it != pool.end(); it++) { | ||
| 50 | - delete it->second; | ||
| 51 | - } | 68 | + if (true) { |
| 69 | + std::map<std::string, SrsStatisticVhost*>::iterator it; | ||
| 70 | + for (it = vhosts.begin(); it != vhosts.end(); it++) { | ||
| 71 | + SrsStatisticVhost* vhost = it->second; | ||
| 72 | + srs_freep(vhost); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + if (true) { | ||
| 76 | + std::map<std::string, SrsStatisticStream*>::iterator it; | ||
| 77 | + for (it = streams.begin(); it != streams.end(); it++) { | ||
| 78 | + SrsStatisticStream* stream = it->second; | ||
| 79 | + srs_freep(stream); | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + if (true) { | ||
| 83 | + std::map<int, SrsStatisticClient*>::iterator it; | ||
| 84 | + for (it = clients.begin(); it != clients.end(); it++) { | ||
| 85 | + SrsStatisticClient* client = it->second; | ||
| 86 | + srs_freep(client); | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +SrsStatistic* SrsStatistic::instance() | ||
| 92 | +{ | ||
| 93 | + return _instance; | ||
| 52 | } | 94 | } |
| 53 | 95 | ||
| 54 | -SrsStreamInfoMap* SrsStatistic::get_pool() | 96 | +int SrsStatistic::on_client(int id, SrsRequest* req) |
| 55 | { | 97 | { |
| 56 | - return &pool; | 98 | + int ret = ERROR_SUCCESS; |
| 99 | + | ||
| 100 | + // create vhost if not exists. | ||
| 101 | + SrsStatisticVhost* vhost = NULL; | ||
| 102 | + if (vhosts.find(req->vhost) == vhosts.end()) { | ||
| 103 | + vhost = new SrsStatisticVhost(); | ||
| 104 | + vhost->vhost = req->vhost; | ||
| 105 | + vhosts[req->vhost] = vhost; | ||
| 106 | + } else { | ||
| 107 | + vhost = vhosts[req->vhost]; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + // the url to identify the stream. | ||
| 111 | + std::string url = req->get_stream_url(); | ||
| 112 | + | ||
| 113 | + // create stream if not exists. | ||
| 114 | + SrsStatisticStream* stream = NULL; | ||
| 115 | + if (streams.find(url) == streams.end()) { | ||
| 116 | + stream = new SrsStatisticStream(); | ||
| 117 | + stream->vhost = vhost; | ||
| 118 | + stream->stream = req->stream; | ||
| 119 | + stream->url = url; | ||
| 120 | + streams[url] = stream; | ||
| 121 | + } else { | ||
| 122 | + stream = streams[url]; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + return ret; | ||
| 57 | } | 126 | } |
| 58 | 127 | ||
| 59 | -SrsStreamInfo* SrsStatistic::get(void *p) | 128 | +int64_t SrsStatistic::server_id() |
| 60 | { | 129 | { |
| 61 | - SrsStreamInfoMap::iterator it = pool.find(p); | ||
| 62 | - if (it == pool.end()) { | ||
| 63 | - pool[p] = new SrsStreamInfo(); | ||
| 64 | - return pool[p]; | ||
| 65 | - } else { | ||
| 66 | - return it->second; | ||
| 67 | - } | 130 | + return _server_id; |
| 68 | } | 131 | } |
| 69 | 132 | ||
| 70 | -void SrsStatistic::add_request_info(void *p, SrsRequest *req) | 133 | +int SrsStatistic::dumps_vhosts(stringstream& ss) |
| 71 | { | 134 | { |
| 72 | - SrsStreamInfo *info = get(p); | ||
| 73 | - if (info->_req == NULL) | ||
| 74 | - info->_req = req->copy(); | ||
| 75 | -} | ||
| 135 | + int ret = ERROR_SUCCESS; | ||
| 136 | + | ||
| 137 | + std::map<std::string, SrsStatisticVhost*>::iterator it; | ||
| 138 | + for (it = vhosts.begin(); it != vhosts.end(); it++) { | ||
| 139 | + SrsStatisticVhost* vhost = it->second; | ||
| 140 | + ss << __SRS_JOBJECT_START | ||
| 141 | + << __SRS_JFIELD_ORG("id", vhost->id) << __SRS_JFIELD_CONT | ||
| 142 | + << __SRS_JFIELD_STR("name", vhost->vhost) | ||
| 143 | + << __SRS_JOBJECT_END; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + return ret; | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +int SrsStatistic::dumps_streams(stringstream& ss) | ||
| 150 | +{ | ||
| 151 | + int ret = ERROR_SUCCESS; | ||
| 152 | + | ||
| 153 | + std::map<std::string, SrsStatisticStream*>::iterator it; | ||
| 154 | + for (it = streams.begin(); it != streams.end(); it++) { | ||
| 155 | + SrsStatisticStream* stream = it->second; | ||
| 156 | + ss << __SRS_JOBJECT_START | ||
| 157 | + << __SRS_JFIELD_ORG("id", stream->id) << __SRS_JFIELD_CONT | ||
| 158 | + << __SRS_JFIELD_STR("name", stream->stream) << __SRS_JFIELD_CONT | ||
| 159 | + << __SRS_JFIELD_ORG("vhost", stream->vhost->id) | ||
| 160 | + << __SRS_JOBJECT_END; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + return ret; | ||
| 164 | +} |
| @@ -31,40 +31,78 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,40 +31,78 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | #include <srs_core.hpp> | 31 | #include <srs_core.hpp> |
| 32 | 32 | ||
| 33 | #include <map> | 33 | #include <map> |
| 34 | +#include <string> | ||
| 34 | 35 | ||
| 35 | class SrsRequest; | 36 | class SrsRequest; |
| 36 | 37 | ||
| 37 | -class SrsStreamInfo | 38 | +struct SrsStatisticVhost |
| 38 | { | 39 | { |
| 39 | public: | 40 | public: |
| 40 | - SrsStreamInfo(); | ||
| 41 | - virtual ~SrsStreamInfo(); | ||
| 42 | - | ||
| 43 | - SrsRequest *_req; | 41 | + int64_t id; |
| 42 | + std::string vhost; | ||
| 43 | +public: | ||
| 44 | + SrsStatisticVhost(); | ||
| 45 | + virtual ~SrsStatisticVhost(); | ||
| 44 | }; | 46 | }; |
| 45 | -typedef std::map<void*, SrsStreamInfo*> SrsStreamInfoMap; | ||
| 46 | 47 | ||
| 47 | -class SrsStatistic | 48 | +struct SrsStatisticStream |
| 48 | { | 49 | { |
| 49 | public: | 50 | public: |
| 50 | - static SrsStatistic *instance() | ||
| 51 | - { | ||
| 52 | - if (_instance == NULL) { | ||
| 53 | - _instance = new SrsStatistic(); | ||
| 54 | - } | ||
| 55 | - return _instance; | ||
| 56 | - } | 51 | + int64_t id; |
| 52 | + SrsStatisticVhost* vhost; | ||
| 53 | + std::string app; | ||
| 54 | + std::string stream; | ||
| 55 | + std::string url; | ||
| 56 | +public: | ||
| 57 | + SrsStatisticStream(); | ||
| 58 | + virtual ~SrsStatisticStream(); | ||
| 59 | +}; | ||
| 57 | 60 | ||
| 58 | - virtual SrsStreamInfoMap* get_pool(); | 61 | +struct SrsStatisticClient |
| 62 | +{ | ||
| 63 | +public: | ||
| 64 | + SrsStatisticStream* stream; | ||
| 65 | + int id; | ||
| 66 | +}; | ||
| 59 | 67 | ||
| 60 | - virtual void add_request_info(void *p, SrsRequest *req); | ||
| 61 | - | 68 | +class SrsStatistic |
| 69 | +{ | ||
| 70 | +private: | ||
| 71 | + static SrsStatistic *_instance; | ||
| 72 | + // the id to identify the sever. | ||
| 73 | + int64_t _server_id; | ||
| 74 | + // key: vhost name, value: vhost object. | ||
| 75 | + std::map<std::string, SrsStatisticVhost*> vhosts; | ||
| 76 | + // key: stream name, value: stream object. | ||
| 77 | + std::map<std::string, SrsStatisticStream*> streams; | ||
| 78 | + // key: client id, value: stream object. | ||
| 79 | + std::map<int, SrsStatisticClient*> clients; | ||
| 62 | private: | 80 | private: |
| 63 | SrsStatistic(); | 81 | SrsStatistic(); |
| 64 | virtual ~SrsStatistic(); | 82 | virtual ~SrsStatistic(); |
| 65 | - static SrsStatistic *_instance; | ||
| 66 | - SrsStreamInfoMap pool; | ||
| 67 | - virtual SrsStreamInfo *get(void *p); | 83 | +public: |
| 84 | + static SrsStatistic* instance(); | ||
| 85 | +public: | ||
| 86 | + /** | ||
| 87 | + * when got a client to publish/play stream, | ||
| 88 | + * @param id, the client srs id. | ||
| 89 | + * @param req, the client request object. | ||
| 90 | + */ | ||
| 91 | + virtual int on_client(int id, SrsRequest* req); | ||
| 92 | +public: | ||
| 93 | + /** | ||
| 94 | + * get the server id, used to identify the server. | ||
| 95 | + * for example, when restart, the server id must changed. | ||
| 96 | + */ | ||
| 97 | + virtual int64_t server_id(); | ||
| 98 | + /** | ||
| 99 | + * dumps the vhosts to sstream in json. | ||
| 100 | + */ | ||
| 101 | + virtual int dumps_vhosts(std::stringstream& ss); | ||
| 102 | + /** | ||
| 103 | + * dumps the streams to sstream in json. | ||
| 104 | + */ | ||
| 105 | + virtual int dumps_streams(std::stringstream& ss); | ||
| 68 | }; | 106 | }; |
| 69 | 107 | ||
| 70 | -#endif | ||
| 108 | +#endif |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 85 | 34 | +#define VERSION_REVISION 89 |
| 35 | // server info. | 35 | // server info. |
| 36 | #define RTMP_SIG_SRS_KEY "SRS" | 36 | #define RTMP_SIG_SRS_KEY "SRS" |
| 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" | 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" |
| @@ -90,6 +90,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -90,6 +90,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 90 | #define ERROR_SYSTEM_FILE_SEEK 1049 | 90 | #define ERROR_SYSTEM_FILE_SEEK 1049 |
| 91 | #define ERROR_SYSTEM_IO_INVALID 1050 | 91 | #define ERROR_SYSTEM_IO_INVALID 1050 |
| 92 | #define ERROR_ST_EXCEED_THREADS 1051 | 92 | #define ERROR_ST_EXCEED_THREADS 1051 |
| 93 | +#define ERROR_SYSTEM_SECURITY 1052 | ||
| 94 | +#define ERROR_SYSTEM_SECURITY_DENY 1053 | ||
| 95 | +#define ERROR_SYSTEM_SECURITY_ALLOW 1054 | ||
| 96 | +#define ERROR_SYSTEM_TIME 1055 | ||
| 97 | +#define ERROR_SYSTEM_DIR_EXISTS 1056 | ||
| 98 | +#define ERROR_SYSTEM_CREATE_DIR 1057 | ||
| 93 | 99 | ||
| 94 | /////////////////////////////////////////////////////// | 100 | /////////////////////////////////////////////////////// |
| 95 | // RTMP protocol error. | 101 | // RTMP protocol error. |
| @@ -149,7 +155,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -149,7 +155,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 149 | /////////////////////////////////////////////////////// | 155 | /////////////////////////////////////////////////////// |
| 150 | #define ERROR_HLS_METADATA 3000 | 156 | #define ERROR_HLS_METADATA 3000 |
| 151 | #define ERROR_HLS_DECODE_ERROR 3001 | 157 | #define ERROR_HLS_DECODE_ERROR 3001 |
| 152 | -#define ERROR_HLS_CREATE_DIR 3002 | 158 | +//#define ERROR_HLS_CREATE_DIR 3002 |
| 153 | #define ERROR_HLS_OPEN_FAILED 3003 | 159 | #define ERROR_HLS_OPEN_FAILED 3003 |
| 154 | #define ERROR_HLS_WRITE_FAILED 3004 | 160 | #define ERROR_HLS_WRITE_FAILED 3004 |
| 155 | #define ERROR_HLS_AAC_FRAME_LENGTH 3005 | 161 | #define ERROR_HLS_AAC_FRAME_LENGTH 3005 |
| @@ -32,10 +32,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -32,10 +32,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #include <string.h> | 34 | #include <string.h> |
| 35 | +#include <sys/stat.h> | ||
| 36 | +#include <fcntl.h> | ||
| 35 | 37 | ||
| 36 | using namespace std; | 38 | using namespace std; |
| 37 | 39 | ||
| 38 | #include <srs_kernel_log.hpp> | 40 | #include <srs_kernel_log.hpp> |
| 41 | +#include <srs_kernel_error.hpp> | ||
| 39 | 42 | ||
| 40 | // this value must: | 43 | // this value must: |
| 41 | // equals to (SRS_SYS_CYCLE_INTERVAL*SRS_SYS_TIME_RESOLUTION_MS_TIMES)*1000 | 44 | // equals to (SRS_SYS_CYCLE_INTERVAL*SRS_SYS_TIME_RESOLUTION_MS_TIMES)*1000 |
| @@ -222,3 +225,56 @@ bool srs_string_ends_with(string str, string flag) | @@ -222,3 +225,56 @@ bool srs_string_ends_with(string str, string flag) | ||
| 222 | return str.rfind(flag) == str.length() - flag.length(); | 225 | return str.rfind(flag) == str.length() - flag.length(); |
| 223 | } | 226 | } |
| 224 | 227 | ||
| 228 | +int __srs_create_dir_recursively(string dir) | ||
| 229 | +{ | ||
| 230 | + int ret = ERROR_SUCCESS; | ||
| 231 | + | ||
| 232 | + struct stat st; | ||
| 233 | + | ||
| 234 | + // stat current dir, if exists, return error. | ||
| 235 | + if (stat(dir.c_str(), &st) == 0) { | ||
| 236 | + return ERROR_SYSTEM_DIR_EXISTS; | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + // create parent first. | ||
| 240 | + size_t pos; | ||
| 241 | + if ((pos = dir.rfind("/")) != std::string::npos) { | ||
| 242 | + std::string parent = dir.substr(0, pos); | ||
| 243 | + ret = __srs_create_dir_recursively(parent); | ||
| 244 | + // return for error. | ||
| 245 | + if (ret != ERROR_SUCCESS && ret != ERROR_SYSTEM_DIR_EXISTS) { | ||
| 246 | + return ret; | ||
| 247 | + } | ||
| 248 | + // parent exists, set to ok. | ||
| 249 | + ret = ERROR_SUCCESS; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + // create curren dir. | ||
| 253 | + mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH; | ||
| 254 | + if (::mkdir(dir.c_str(), mode) < 0) { | ||
| 255 | + if (errno == EEXIST) { | ||
| 256 | + return ERROR_SYSTEM_DIR_EXISTS; | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + ret = ERROR_SYSTEM_CREATE_DIR; | ||
| 260 | + srs_error("create dir %s failed. ret=%d", dir.c_str(), ret); | ||
| 261 | + return ret; | ||
| 262 | + } | ||
| 263 | + srs_info("create dir %s success.", dir.c_str()); | ||
| 264 | + | ||
| 265 | + return ret; | ||
| 266 | +} | ||
| 267 | + | ||
| 268 | +int srs_create_dir_recursively(string dir) | ||
| 269 | +{ | ||
| 270 | + int ret = ERROR_SUCCESS; | ||
| 271 | + | ||
| 272 | + ret = __srs_create_dir_recursively(dir); | ||
| 273 | + | ||
| 274 | + if (ret == ERROR_SYSTEM_DIR_EXISTS) { | ||
| 275 | + return ERROR_SUCCESS; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + return ret; | ||
| 279 | +} | ||
| 280 | + |
| @@ -59,5 +59,8 @@ extern std::string srs_string_remove(std::string str, std::string remove_chars); | @@ -59,5 +59,8 @@ extern std::string srs_string_remove(std::string str, std::string remove_chars); | ||
| 59 | // whether string end with | 59 | // whether string end with |
| 60 | extern bool srs_string_ends_with(std::string str, std::string flag); | 60 | extern bool srs_string_ends_with(std::string str, std::string flag); |
| 61 | 61 | ||
| 62 | +// create dir recursively | ||
| 63 | +extern int srs_create_dir_recursively(std::string dir); | ||
| 64 | + | ||
| 62 | #endif | 65 | #endif |
| 63 | 66 |
| @@ -91,6 +91,7 @@ SrsRequest* SrsRequest::copy() | @@ -91,6 +91,7 @@ SrsRequest* SrsRequest::copy() | ||
| 91 | { | 91 | { |
| 92 | SrsRequest* cp = new SrsRequest(); | 92 | SrsRequest* cp = new SrsRequest(); |
| 93 | 93 | ||
| 94 | + cp->ip = ip; | ||
| 94 | cp->app = app; | 95 | cp->app = app; |
| 95 | cp->objectEncoding = objectEncoding; | 96 | cp->objectEncoding = objectEncoding; |
| 96 | cp->pageUrl = pageUrl; | 97 | cp->pageUrl = pageUrl; |
| @@ -54,6 +54,9 @@ class IMergeReadHandler; | @@ -54,6 +54,9 @@ class IMergeReadHandler; | ||
| 54 | class SrsRequest | 54 | class SrsRequest |
| 55 | { | 55 | { |
| 56 | public: | 56 | public: |
| 57 | + // client ip. | ||
| 58 | + std::string ip; | ||
| 59 | +public: | ||
| 57 | /** | 60 | /** |
| 58 | * tcUrl: rtmp://request_vhost:port/app/stream | 61 | * tcUrl: rtmp://request_vhost:port/app/stream |
| 59 | * support pass vhost in query string, such as: | 62 | * support pass vhost in query string, such as: |
| 1 | file | 1 | file |
| 2 | - main readonly separator, | ||
| 3 | - ..\main\srs_main_server.cpp, | ||
| 4 | - auto readonly separator, | ||
| 5 | - ..\..\objs\srs_auto_headers.hpp, | ||
| 6 | - libs readonly separator, | ||
| 7 | - ..\libs\srs_librtmp.hpp, | ||
| 8 | - ..\libs\srs_librtmp.cpp, | ||
| 9 | - ..\libs\srs_lib_bandwidth.hpp, | ||
| 10 | - ..\libs\srs_lib_bandwidth.cpp, | ||
| 11 | - ..\libs\srs_lib_simple_socket.hpp, | ||
| 12 | - ..\libs\srs_lib_simple_socket.cpp, | ||
| 13 | - core readonly separator, | ||
| 14 | - ..\core\srs_core.hpp, | ||
| 15 | - ..\core\srs_core.cpp, | ||
| 16 | - ..\core\srs_core_autofree.hpp, | ||
| 17 | - ..\core\srs_core_autofree.cpp, | ||
| 18 | - ..\core\srs_core_performance.hpp, | ||
| 19 | - ..\core\srs_core_performance.cpp, | ||
| 20 | - kernel readonly separator, | ||
| 21 | - ..\kernel\srs_kernel_codec.hpp, | ||
| 22 | - ..\kernel\srs_kernel_codec.cpp, | ||
| 23 | - ..\kernel\srs_kernel_consts.hpp, | ||
| 24 | - ..\kernel\srs_kernel_consts.cpp, | ||
| 25 | - ..\kernel\srs_kernel_error.hpp, | ||
| 26 | - ..\kernel\srs_kernel_error.cpp, | ||
| 27 | - ..\kernel\srs_kernel_file.hpp, | ||
| 28 | - ..\kernel\srs_kernel_file.cpp, | ||
| 29 | - ..\kernel\srs_kernel_flv.hpp, | ||
| 30 | - ..\kernel\srs_kernel_flv.cpp, | ||
| 31 | - ..\kernel\srs_kernel_log.hpp, | ||
| 32 | - ..\kernel\srs_kernel_log.cpp, | ||
| 33 | - ..\kernel\srs_kernel_stream.hpp, | ||
| 34 | - ..\kernel\srs_kernel_stream.cpp, | ||
| 35 | - ..\kernel\srs_kernel_utility.hpp, | ||
| 36 | - ..\kernel\srs_kernel_utility.cpp, | ||
| 37 | - rtmp-protocol readonly separator, | ||
| 38 | - ..\rtmp\srs_protocol_amf0.hpp, | ||
| 39 | - ..\rtmp\srs_protocol_amf0.cpp, | ||
| 40 | - ..\rtmp\srs_protocol_buffer.hpp, | ||
| 41 | - ..\rtmp\srs_protocol_buffer.cpp, | ||
| 42 | - ..\rtmp\srs_protocol_handshake.hpp, | ||
| 43 | - ..\rtmp\srs_protocol_handshake.cpp, | ||
| 44 | - ..\rtmp\srs_protocol_io.hpp, | ||
| 45 | - ..\rtmp\srs_protocol_io.cpp, | ||
| 46 | - ..\rtmp\srs_protocol_msg_array.hpp, | ||
| 47 | - ..\rtmp\srs_protocol_msg_array.cpp, | ||
| 48 | - ..\rtmp\srs_protocol_rtmp.hpp, | ||
| 49 | - ..\rtmp\srs_protocol_rtmp.cpp, | ||
| 50 | - ..\rtmp\srs_protocol_stack.hpp, | ||
| 51 | - ..\rtmp\srs_protocol_stack.cpp, | ||
| 52 | - ..\rtmp\srs_protocol_utility.hpp, | ||
| 53 | - ..\rtmp\srs_protocol_utility.cpp, | ||
| 54 | - app readonly separator, | ||
| 55 | - ..\app\srs_app_avc_aac.hpp, | ||
| 56 | - ..\app\srs_app_avc_aac.cpp, | ||
| 57 | - ..\app\srs_app_bandwidth.hpp, | ||
| 58 | - ..\app\srs_app_bandwidth.cpp, | ||
| 59 | - ..\app\srs_app_conn.hpp, | ||
| 60 | - ..\app\srs_app_conn.cpp, | ||
| 61 | - ..\app\srs_app_config.hpp, | ||
| 62 | - ..\app\srs_app_config.cpp, | ||
| 63 | - ..\app\srs_app_dvr.hpp, | ||
| 64 | - ..\app\srs_app_dvr.cpp, | ||
| 65 | - ..\app\srs_app_edge.hpp, | ||
| 66 | - ..\app\srs_app_edge.cpp, | ||
| 67 | - ..\app\srs_app_empty.hpp, | ||
| 68 | - ..\app\srs_app_empty.cpp, | ||
| 69 | - ..\app\srs_app_encoder.hpp, | ||
| 70 | - ..\app\srs_app_encoder.cpp, | ||
| 71 | - ..\app\srs_app_ffmpeg.hpp, | ||
| 72 | - ..\app\srs_app_ffmpeg.cpp, | ||
| 73 | - ..\app\srs_app_forward.hpp, | ||
| 74 | - ..\app\srs_app_forward.cpp, | ||
| 75 | - ..\app\srs_app_heartbeat.hpp, | ||
| 76 | - ..\app\srs_app_heartbeat.cpp, | ||
| 77 | - ..\app\srs_app_hls.hpp, | ||
| 78 | - ..\app\srs_app_hls.cpp, | ||
| 79 | - ..\app\srs_app_http.hpp, | ||
| 80 | - ..\app\srs_app_http.cpp, | ||
| 81 | - ..\app\srs_app_http_api.hpp, | ||
| 82 | - ..\app\srs_app_http_api.cpp, | ||
| 83 | - ..\app\srs_app_http_client.hpp, | ||
| 84 | - ..\app\srs_app_http_client.cpp, | ||
| 85 | - ..\app\srs_app_http_conn.hpp, | ||
| 86 | - ..\app\srs_app_http_conn.cpp, | ||
| 87 | - ..\app\srs_app_http_hooks.hpp, | ||
| 88 | - ..\app\srs_app_http_hooks.cpp, | ||
| 89 | - ..\app\srs_app_ingest.hpp, | ||
| 90 | - ..\app\srs_app_ingest.cpp, | ||
| 91 | - ..\app\srs_app_json.hpp, | ||
| 92 | - ..\app\srs_app_json.cpp, | ||
| 93 | - ..\app\srs_app_kbps.hpp, | ||
| 94 | - ..\app\srs_app_kbps.cpp, | ||
| 95 | - ..\app\srs_app_log.hpp, | ||
| 96 | - ..\app\srs_app_log.cpp, | ||
| 97 | - ..\app\srs_app_recv_thread.hpp, | ||
| 98 | - ..\app\srs_app_recv_thread.cpp, | ||
| 99 | - ..\app\srs_app_refer.hpp, | ||
| 100 | - ..\app\srs_app_refer.cpp, | ||
| 101 | - ..\app\srs_app_reload.hpp, | ||
| 102 | - ..\app\srs_app_reload.cpp, | ||
| 103 | - ..\app\srs_app_rtmp_conn.hpp, | ||
| 104 | - ..\app\srs_app_rtmp_conn.cpp, | ||
| 105 | - ..\app\srs_app_pithy_print.hpp, | ||
| 106 | - ..\app\srs_app_pithy_print.cpp, | ||
| 107 | - ..\app\srs_app_server.hpp, | ||
| 108 | - ..\app\srs_app_server.cpp, | ||
| 109 | - ..\app\srs_app_st.hpp, | ||
| 110 | - ..\app\srs_app_st.cpp, | ||
| 111 | - ..\app\srs_app_st_socket.hpp, | ||
| 112 | - ..\app\srs_app_st_socket.cpp, | ||
| 113 | - ..\app\srs_app_source.hpp, | ||
| 114 | - ..\app\srs_app_source.cpp, | ||
| 115 | - ..\app\srs_app_thread.hpp, | ||
| 116 | - ..\app\srs_app_thread.cpp, | ||
| 117 | - ..\app\srs_app_utility.hpp, | ||
| 118 | - ..\app\srs_app_utility.cpp, | ||
| 119 | - utest readonly separator, | ||
| 120 | - ..\utest\srs_utest.hpp, | ||
| 121 | - ..\utest\srs_utest.cpp, | ||
| 122 | - ..\utest\srs_utest_amf0.hpp, | ||
| 123 | - ..\utest\srs_utest_amf0.cpp, | ||
| 124 | - ..\utest\srs_utest_config.hpp, | ||
| 125 | - ..\utest\srs_utest_config.cpp, | ||
| 126 | - ..\utest\srs_utest_core.hpp, | ||
| 127 | - ..\utest\srs_utest_core.cpp, | ||
| 128 | - ..\utest\srs_utest_kernel.hpp, | ||
| 129 | - ..\utest\srs_utest_kernel.cpp, | ||
| 130 | - ..\utest\srs_utest_protocol.hpp, | ||
| 131 | - ..\utest\srs_utest_protocol.cpp, | ||
| 132 | - ..\utest\srs_utest_reload.hpp, | ||
| 133 | - ..\utest\srs_utest_reload.cpp, | ||
| 134 | - research readonly separator, | ||
| 135 | - ..\..\research\librtmp\srs_aac_raw_publish.c, | ||
| 136 | - ..\..\research\librtmp\srs_audio_raw_publish.c, | ||
| 137 | - ..\..\research\librtmp\srs_bandwidth_check.c, | ||
| 138 | - ..\..\research\librtmp\srs_detect_rtmp.c, | ||
| 139 | - ..\..\research\librtmp\srs_flv_injecter.c, | ||
| 140 | - ..\..\research\librtmp\srs_flv_parser.c, | ||
| 141 | - ..\..\research\librtmp\srs_h264_raw_publish.c, | ||
| 142 | - ..\..\research\librtmp\srs_ingest_flv.c, | ||
| 143 | - ..\..\research\librtmp\srs_ingest_rtmp.c, | ||
| 144 | - ..\..\research\librtmp\srs_play.c, | ||
| 145 | - ..\..\research\librtmp\srs_publish.c, | ||
| 146 | - ..\..\research\librtmp\srs_rtmp_dump.c, | ||
| 147 | - ..\..\research\hls\ts_info.cc; | 2 | + main readonly separator, |
| 3 | + ..\main\srs_main_server.cpp, | ||
| 4 | + auto readonly separator, | ||
| 5 | + ..\..\objs\srs_auto_headers.hpp, | ||
| 6 | + libs readonly separator, | ||
| 7 | + ..\libs\srs_librtmp.hpp, | ||
| 8 | + ..\libs\srs_librtmp.cpp, | ||
| 9 | + ..\libs\srs_lib_bandwidth.hpp, | ||
| 10 | + ..\libs\srs_lib_bandwidth.cpp, | ||
| 11 | + ..\libs\srs_lib_simple_socket.hpp, | ||
| 12 | + ..\libs\srs_lib_simple_socket.cpp, | ||
| 13 | + core readonly separator, | ||
| 14 | + ..\core\srs_core.hpp, | ||
| 15 | + ..\core\srs_core.cpp, | ||
| 16 | + ..\core\srs_core_autofree.hpp, | ||
| 17 | + ..\core\srs_core_autofree.cpp, | ||
| 18 | + ..\core\srs_core_performance.hpp, | ||
| 19 | + ..\core\srs_core_performance.cpp, | ||
| 20 | + kernel readonly separator, | ||
| 21 | + ..\kernel\srs_kernel_codec.hpp, | ||
| 22 | + ..\kernel\srs_kernel_codec.cpp, | ||
| 23 | + ..\kernel\srs_kernel_consts.hpp, | ||
| 24 | + ..\kernel\srs_kernel_consts.cpp, | ||
| 25 | + ..\kernel\srs_kernel_error.hpp, | ||
| 26 | + ..\kernel\srs_kernel_error.cpp, | ||
| 27 | + ..\kernel\srs_kernel_file.hpp, | ||
| 28 | + ..\kernel\srs_kernel_file.cpp, | ||
| 29 | + ..\kernel\srs_kernel_flv.hpp, | ||
| 30 | + ..\kernel\srs_kernel_flv.cpp, | ||
| 31 | + ..\kernel\srs_kernel_log.hpp, | ||
| 32 | + ..\kernel\srs_kernel_log.cpp, | ||
| 33 | + ..\kernel\srs_kernel_stream.hpp, | ||
| 34 | + ..\kernel\srs_kernel_stream.cpp, | ||
| 35 | + ..\kernel\srs_kernel_utility.hpp, | ||
| 36 | + ..\kernel\srs_kernel_utility.cpp, | ||
| 37 | + rtmp-protocol readonly separator, | ||
| 38 | + ..\rtmp\srs_protocol_amf0.hpp, | ||
| 39 | + ..\rtmp\srs_protocol_amf0.cpp, | ||
| 40 | + ..\rtmp\srs_protocol_buffer.hpp, | ||
| 41 | + ..\rtmp\srs_protocol_buffer.cpp, | ||
| 42 | + ..\rtmp\srs_protocol_handshake.hpp, | ||
| 43 | + ..\rtmp\srs_protocol_handshake.cpp, | ||
| 44 | + ..\rtmp\srs_protocol_io.hpp, | ||
| 45 | + ..\rtmp\srs_protocol_io.cpp, | ||
| 46 | + ..\rtmp\srs_protocol_msg_array.hpp, | ||
| 47 | + ..\rtmp\srs_protocol_msg_array.cpp, | ||
| 48 | + ..\rtmp\srs_protocol_rtmp.hpp, | ||
| 49 | + ..\rtmp\srs_protocol_rtmp.cpp, | ||
| 50 | + ..\rtmp\srs_protocol_stack.hpp, | ||
| 51 | + ..\rtmp\srs_protocol_stack.cpp, | ||
| 52 | + ..\rtmp\srs_protocol_utility.hpp, | ||
| 53 | + ..\rtmp\srs_protocol_utility.cpp, | ||
| 54 | + app readonly separator, | ||
| 55 | + ..\app\srs_app_avc_aac.hpp, | ||
| 56 | + ..\app\srs_app_avc_aac.cpp, | ||
| 57 | + ..\app\srs_app_bandwidth.hpp, | ||
| 58 | + ..\app\srs_app_bandwidth.cpp, | ||
| 59 | + ..\app\srs_app_conn.hpp, | ||
| 60 | + ..\app\srs_app_conn.cpp, | ||
| 61 | + ..\app\srs_app_config.hpp, | ||
| 62 | + ..\app\srs_app_config.cpp, | ||
| 63 | + ..\app\srs_app_dvr.hpp, | ||
| 64 | + ..\app\srs_app_dvr.cpp, | ||
| 65 | + ..\app\srs_app_edge.hpp, | ||
| 66 | + ..\app\srs_app_edge.cpp, | ||
| 67 | + ..\app\srs_app_empty.hpp, | ||
| 68 | + ..\app\srs_app_empty.cpp, | ||
| 69 | + ..\app\srs_app_encoder.hpp, | ||
| 70 | + ..\app\srs_app_encoder.cpp, | ||
| 71 | + ..\app\srs_app_ffmpeg.hpp, | ||
| 72 | + ..\app\srs_app_ffmpeg.cpp, | ||
| 73 | + ..\app\srs_app_forward.hpp, | ||
| 74 | + ..\app\srs_app_forward.cpp, | ||
| 75 | + ..\app\srs_app_heartbeat.hpp, | ||
| 76 | + ..\app\srs_app_heartbeat.cpp, | ||
| 77 | + ..\app\srs_app_hls.hpp, | ||
| 78 | + ..\app\srs_app_hls.cpp, | ||
| 79 | + ..\app\srs_app_http.hpp, | ||
| 80 | + ..\app\srs_app_http.cpp, | ||
| 81 | + ..\app\srs_app_http_api.hpp, | ||
| 82 | + ..\app\srs_app_http_api.cpp, | ||
| 83 | + ..\app\srs_app_http_client.hpp, | ||
| 84 | + ..\app\srs_app_http_client.cpp, | ||
| 85 | + ..\app\srs_app_http_conn.hpp, | ||
| 86 | + ..\app\srs_app_http_conn.cpp, | ||
| 87 | + ..\app\srs_app_http_hooks.hpp, | ||
| 88 | + ..\app\srs_app_http_hooks.cpp, | ||
| 89 | + ..\app\srs_app_ingest.hpp, | ||
| 90 | + ..\app\srs_app_ingest.cpp, | ||
| 91 | + ..\app\srs_app_json.hpp, | ||
| 92 | + ..\app\srs_app_json.cpp, | ||
| 93 | + ..\app\srs_app_kbps.hpp, | ||
| 94 | + ..\app\srs_app_kbps.cpp, | ||
| 95 | + ..\app\srs_app_log.hpp, | ||
| 96 | + ..\app\srs_app_log.cpp, | ||
| 97 | + ..\app\srs_app_recv_thread.hpp, | ||
| 98 | + ..\app\srs_app_recv_thread.cpp, | ||
| 99 | + ..\app\srs_app_refer.hpp, | ||
| 100 | + ..\app\srs_app_refer.cpp, | ||
| 101 | + ..\app\srs_app_reload.hpp, | ||
| 102 | + ..\app\srs_app_reload.cpp, | ||
| 103 | + ..\app\srs_app_rtmp_conn.hpp, | ||
| 104 | + ..\app\srs_app_rtmp_conn.cpp, | ||
| 105 | + ..\app\srs_app_pithy_print.hpp, | ||
| 106 | + ..\app\srs_app_pithy_print.cpp, | ||
| 107 | + ..\app\srs_app_security.hpp, | ||
| 108 | + ..\app\srs_app_security.cpp, | ||
| 109 | + ..\app\srs_app_server.hpp, | ||
| 110 | + ..\app\srs_app_server.cpp, | ||
| 111 | + ..\app\srs_app_st.hpp, | ||
| 112 | + ..\app\srs_app_st.cpp, | ||
| 113 | + ..\app\srs_app_st_socket.hpp, | ||
| 114 | + ..\app\srs_app_st_socket.cpp, | ||
| 115 | + ..\app\srs_app_statistic.hpp, | ||
| 116 | + ..\app\srs_app_statistic.cpp, | ||
| 117 | + ..\app\srs_app_source.hpp, | ||
| 118 | + ..\app\srs_app_source.cpp, | ||
| 119 | + ..\app\srs_app_thread.hpp, | ||
| 120 | + ..\app\srs_app_thread.cpp, | ||
| 121 | + ..\app\srs_app_utility.hpp, | ||
| 122 | + ..\app\srs_app_utility.cpp, | ||
| 123 | + utest readonly separator, | ||
| 124 | + ..\utest\srs_utest.hpp, | ||
| 125 | + ..\utest\srs_utest.cpp, | ||
| 126 | + ..\utest\srs_utest_amf0.hpp, | ||
| 127 | + ..\utest\srs_utest_amf0.cpp, | ||
| 128 | + ..\utest\srs_utest_config.hpp, | ||
| 129 | + ..\utest\srs_utest_config.cpp, | ||
| 130 | + ..\utest\srs_utest_core.hpp, | ||
| 131 | + ..\utest\srs_utest_core.cpp, | ||
| 132 | + ..\utest\srs_utest_kernel.hpp, | ||
| 133 | + ..\utest\srs_utest_kernel.cpp, | ||
| 134 | + ..\utest\srs_utest_protocol.hpp, | ||
| 135 | + ..\utest\srs_utest_protocol.cpp, | ||
| 136 | + ..\utest\srs_utest_reload.hpp, | ||
| 137 | + ..\utest\srs_utest_reload.cpp, | ||
| 138 | + research readonly separator, | ||
| 139 | + ..\..\research\librtmp\srs_aac_raw_publish.c, | ||
| 140 | + ..\..\research\librtmp\srs_audio_raw_publish.c, | ||
| 141 | + ..\..\research\librtmp\srs_bandwidth_check.c, | ||
| 142 | + ..\..\research\librtmp\srs_detect_rtmp.c, | ||
| 143 | + ..\..\research\librtmp\srs_flv_injecter.c, | ||
| 144 | + ..\..\research\librtmp\srs_flv_parser.c, | ||
| 145 | + ..\..\research\librtmp\srs_h264_raw_publish.c, | ||
| 146 | + ..\..\research\librtmp\srs_ingest_flv.c, | ||
| 147 | + ..\..\research\librtmp\srs_ingest_rtmp.c, | ||
| 148 | + ..\..\research\librtmp\srs_play.c, | ||
| 149 | + ..\..\research\librtmp\srs_publish.c, | ||
| 150 | + ..\..\research\librtmp\srs_rtmp_dump.c, | ||
| 151 | + ..\..\research\hls\ts_info.cc; | ||
| 148 | 152 | ||
| 149 | mainconfig | 153 | mainconfig |
| 150 | - "" = "MAIN"; | 154 | + "" = "MAIN"; |
| 151 | 155 |
| @@ -1206,12 +1206,12 @@ VOID TEST(KernelStreamTest, StreamRead8Bytes) | @@ -1206,12 +1206,12 @@ VOID TEST(KernelStreamTest, StreamRead8Bytes) | ||
| 1206 | data[18] = 0x13; | 1206 | data[18] = 0x13; |
| 1207 | data[19] = 0x14; | 1207 | data[19] = 0x14; |
| 1208 | 1208 | ||
| 1209 | - EXPECT_EQ(0x0102030405060708, s.read_8bytes()); | ||
| 1210 | - EXPECT_EQ(0x090a0b0c0d0e0f10, s.read_8bytes()); | 1209 | + EXPECT_EQ(0x0102030405060708LL, s.read_8bytes()); |
| 1210 | + EXPECT_EQ(0x090a0b0c0d0e0f10LL, s.read_8bytes()); | ||
| 1211 | 1211 | ||
| 1212 | s.skip(-1 * s.pos()); | 1212 | s.skip(-1 * s.pos()); |
| 1213 | s.skip(5); | 1213 | s.skip(5); |
| 1214 | - EXPECT_EQ(0x060708090a0b0c0d, s.read_8bytes()); | 1214 | + EXPECT_EQ(0x060708090a0b0c0dLL, s.read_8bytes()); |
| 1215 | } | 1215 | } |
| 1216 | 1216 | ||
| 1217 | /** | 1217 | /** |
| @@ -1364,8 +1364,8 @@ VOID TEST(KernelStreamTest, StreamWrite8Bytes) | @@ -1364,8 +1364,8 @@ VOID TEST(KernelStreamTest, StreamWrite8Bytes) | ||
| 1364 | 1364 | ||
| 1365 | EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); | 1365 | EXPECT_TRUE(ERROR_SUCCESS == s.initialize(data, 1024)); |
| 1366 | 1366 | ||
| 1367 | - s.write_8bytes(0x1011121314151617); | ||
| 1368 | - s.write_8bytes(0x1819202122232425); | 1367 | + s.write_8bytes(0x1011121314151617LL); |
| 1368 | + s.write_8bytes(0x1819202122232425LL); | ||
| 1369 | 1369 | ||
| 1370 | s.skip(-1 * s.pos()); | 1370 | s.skip(-1 * s.pos()); |
| 1371 | EXPECT_EQ(0x10, s.read_1bytes()); | 1371 | EXPECT_EQ(0x10, s.read_1bytes()); |
-
请 注册 或 登录 后发表评论