mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
DVR: Support blackbox test based on hooks. v5.0.132 (#3365)
This commit is contained in:
parent
a27ce1d50f
commit
e655948e96
31 changed files with 4704 additions and 3925 deletions
43
.github/workflows/test.yml
vendored
43
.github/workflows/test.yml
vendored
|
@ -4,6 +4,7 @@ name: "Test"
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
# The dependency graph:
|
# The dependency graph:
|
||||||
|
# test(6m)
|
||||||
# multiple-arch-armv7(13m)
|
# multiple-arch-armv7(13m)
|
||||||
# multiple-arch-aarch64(7m)
|
# multiple-arch-aarch64(7m)
|
||||||
# cygwin64-cache(1m)
|
# cygwin64-cache(1m)
|
||||||
|
@ -16,9 +17,7 @@ on: [push, pull_request]
|
||||||
# build-cross-arm(3m)
|
# build-cross-arm(3m)
|
||||||
# build-cross-aarch64(3m)
|
# build-cross-aarch64(3m)
|
||||||
# multiple-arch-amd64(2m)
|
# multiple-arch-amd64(2m)
|
||||||
# utest(3m)
|
|
||||||
# coverage(3m)
|
# coverage(3m)
|
||||||
# blackbox(3m)
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cygwin64-cache:
|
cygwin64-cache:
|
||||||
|
@ -163,30 +162,8 @@ jobs:
|
||||||
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target ubuntu20-cross-aarch64 .
|
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target ubuntu20-cross-aarch64 .
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
utest:
|
test:
|
||||||
name: utest
|
name: utest-regression-blackbox-test
|
||||||
needs:
|
|
||||||
- fast
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
# Tests
|
|
||||||
- name: Build test image
|
|
||||||
run: docker build --tag srs:test --build-arg MAKEARGS='-j2' -f trunk/Dockerfile.test .
|
|
||||||
# For utest
|
|
||||||
- name: Run SRS utest
|
|
||||||
run: docker run --rm srs:test ./objs/srs_utest
|
|
||||||
# For regression-test
|
|
||||||
- name: Run SRS regression-test
|
|
||||||
run: |
|
|
||||||
docker run --rm srs:test bash -c './objs/srs -c conf/regression-test.conf && \
|
|
||||||
cd 3rdparty/srs-bench && ./objs/srs_test -test.v && ./objs/srs_gb28181_test -test.v'
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
|
|
||||||
blackbox:
|
|
||||||
name: blackbox
|
|
||||||
needs:
|
|
||||||
- fast
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
@ -196,10 +173,21 @@ jobs:
|
||||||
# For blackbox-test
|
# For blackbox-test
|
||||||
- name: Run SRS blackbox-test
|
- name: Run SRS blackbox-test
|
||||||
run: |
|
run: |
|
||||||
|
#docker run --rm -w /srs/trunk/3rdparty/srs-bench srs:test ./objs/srs_blackbox_test -test.v \
|
||||||
|
# -test.run 'TestFast_RtmpPublish_DvrFlv_Basic' -srs-log -srs-stdout srs-ffmpeg-stderr -srs-dvr-stderr \
|
||||||
|
# -srs-ffprobe-stdout
|
||||||
docker run --rm -w /srs/trunk/3rdparty/srs-bench srs:test \
|
docker run --rm -w /srs/trunk/3rdparty/srs-bench srs:test \
|
||||||
./objs/srs_blackbox_test -test.v -test.run '^TestFast' -test.parallel 64
|
./objs/srs_blackbox_test -test.v -test.run '^TestFast' -test.parallel 64
|
||||||
docker run --rm -w /srs/trunk/3rdparty/srs-bench srs:test \
|
docker run --rm -w /srs/trunk/3rdparty/srs-bench srs:test \
|
||||||
./objs/srs_blackbox_test -test.v -test.run '^TestSlow' -test.parallel 4
|
./objs/srs_blackbox_test -test.v -test.run '^TestSlow' -test.parallel 4
|
||||||
|
# For utest
|
||||||
|
- name: Run SRS utest
|
||||||
|
run: docker run --rm srs:test ./objs/srs_utest
|
||||||
|
# For regression-test
|
||||||
|
- name: Run SRS regression-test
|
||||||
|
run: |
|
||||||
|
docker run --rm srs:test bash -c './objs/srs -c conf/regression-test.conf && \
|
||||||
|
cd 3rdparty/srs-bench && ./objs/srs_test -test.v && ./objs/srs_gb28181_test -test.v'
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
|
@ -312,8 +300,7 @@ jobs:
|
||||||
needs:
|
needs:
|
||||||
- cygwin64
|
- cygwin64
|
||||||
- coverage
|
- coverage
|
||||||
- blackbox
|
- test
|
||||||
- utest
|
|
||||||
- build-centos7
|
- build-centos7
|
||||||
- build-ubuntu16
|
- build-ubuntu16
|
||||||
- build-ubuntu18
|
- build-ubuntu18
|
||||||
|
|
143
trunk/3rdparty/srs-bench/blackbox/dvr_test.go
vendored
Normal file
143
trunk/3rdparty/srs-bench/blackbox/dvr_test.go
vendored
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// # Copyright (c) 2023 Winlin
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
package blackbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ossrs/go-oryx-lib/errors"
|
||||||
|
"github.com/ossrs/go-oryx-lib/logger"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFast_RtmpPublish_DvrFlv_Basic(t *testing.T) {
|
||||||
|
// This case is run in parallel.
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// Setup the max timeout for this case.
|
||||||
|
ctx, cancel := context.WithTimeout(logger.WithContext(context.Background()), time.Duration(*srsTimeout)*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Check a set of errors.
|
||||||
|
var r0, r1, r2, r3, r4, r5, r6 error
|
||||||
|
defer func(ctx context.Context) {
|
||||||
|
if err := filterTestError(ctx.Err(), r0, r1, r2, r3, r4, r5, r6); err != nil {
|
||||||
|
t.Errorf("Fail for err %+v", err)
|
||||||
|
} else {
|
||||||
|
logger.Tf(ctx, "test done with err %+v", err)
|
||||||
|
}
|
||||||
|
}(ctx)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
defer wg.Wait()
|
||||||
|
|
||||||
|
// Start hooks service.
|
||||||
|
hooks := NewHooksService()
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
r6 = hooks.Run(ctx, cancel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Start SRS server and wait for it to be ready.
|
||||||
|
svr := NewSRSServer(func(v *srsServer) {
|
||||||
|
v.envs = []string{
|
||||||
|
"SRS_VHOST_DVR_ENABLED=on",
|
||||||
|
"SRS_VHOST_DVR_DVR_PLAN=session",
|
||||||
|
"SRS_VHOST_DVR_DVR_PATH=./objs/nginx/html/[app]/[stream].[timestamp].flv",
|
||||||
|
fmt.Sprintf("SRS_VHOST_DVR_DVR_DURATION=%v", *srsFFprobeDuration),
|
||||||
|
"SRS_VHOST_HTTP_HOOKS_ENABLED=on",
|
||||||
|
fmt.Sprintf("SRS_VHOST_HTTP_HOOKS_ON_DVR=http://localhost:%v/api/v1/dvrs", hooks.HooksAPI()),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
<-hooks.ReadyCtx().Done()
|
||||||
|
r0 = svr.Run(ctx, cancel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Start FFmpeg to publish stream.
|
||||||
|
duration := time.Duration(*srsFFprobeDuration) * time.Millisecond
|
||||||
|
streamID := fmt.Sprintf("stream-%v-%v", os.Getpid(), rand.Int())
|
||||||
|
streamURL := fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
|
||||||
|
ffmpeg := NewFFmpeg(func(v *ffmpegClient) {
|
||||||
|
// When process quit, still keep case to run.
|
||||||
|
v.cancelCaseWhenQuit, v.ffmpegDuration = false, duration
|
||||||
|
v.args = []string{
|
||||||
|
"-stream_loop", "-1", "-re", "-i", *srsPublishAvatar, "-c", "copy", "-f", "flv", streamURL,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
<-svr.ReadyCtx().Done()
|
||||||
|
r1 = ffmpeg.Run(ctx, cancel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Start FFprobe to detect and verify stream.
|
||||||
|
ffprobe := NewFFprobe(func(v *ffprobeClient) {
|
||||||
|
v.dvrByFFmpeg, v.streamURL = false, streamURL
|
||||||
|
v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
for evt := range hooks.HooksEvents() {
|
||||||
|
if onDvrEvt, ok := evt.(*HooksEventOnDvr); ok {
|
||||||
|
fp := path.Join(svr.WorkDir(), onDvrEvt.File)
|
||||||
|
logger.Tf(ctx, "FFprobe: Set the dvrFile=%v from callback", fp)
|
||||||
|
v.dvrFile = fp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
<-svr.ReadyCtx().Done()
|
||||||
|
r2 = ffprobe.Run(ctx, cancel)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Fast quit for probe done.
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
case <-ffprobe.ProbeDoneCtx().Done():
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
str, m := ffprobe.Result()
|
||||||
|
if len(m.Streams) != 2 {
|
||||||
|
r3 = errors.Errorf("invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ts := 90; m.Format.ProbeScore < ts {
|
||||||
|
r4 = errors.Errorf("low score=%v < %v, %v, %v", m.Format.ProbeScore, ts, m.String(), str)
|
||||||
|
}
|
||||||
|
if dv := m.Duration(); dv < duration/2 {
|
||||||
|
r5 = errors.Errorf("short duration=%v < %v, %v, %v", dv, duration/2, m.String(), str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
297
trunk/3rdparty/srs-bench/blackbox/util.go
vendored
297
trunk/3rdparty/srs-bench/blackbox/util.go
vendored
|
@ -27,6 +27,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ossrs/go-oryx-lib/errors"
|
"github.com/ossrs/go-oryx-lib/errors"
|
||||||
|
ohttp "github.com/ossrs/go-oryx-lib/http"
|
||||||
"github.com/ossrs/go-oryx-lib/logger"
|
"github.com/ossrs/go-oryx-lib/logger"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -200,6 +201,8 @@ type backendService struct {
|
||||||
name string
|
name string
|
||||||
args []string
|
args []string
|
||||||
env []string
|
env []string
|
||||||
|
// If timeout, kill the process.
|
||||||
|
duration time.Duration
|
||||||
|
|
||||||
// The process stdout and stderr.
|
// The process stdout and stderr.
|
||||||
stdout bytes.Buffer
|
stdout bytes.Buffer
|
||||||
|
@ -315,6 +318,22 @@ func (v *backendService) Run(ctx context.Context, cancel context.CancelFunc) err
|
||||||
// The context for SRS process.
|
// The context for SRS process.
|
||||||
processDone, processDoneCancel := context.WithCancel(context.Background())
|
processDone, processDoneCancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
// If exceed timeout, kill the process.
|
||||||
|
v.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer v.wg.Done()
|
||||||
|
if v.duration <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <- ctx.Done():
|
||||||
|
case <-time.After(v.duration):
|
||||||
|
logger.Tf(ctx, "Process killed duration=%v, pid=%v, name=%v, args=%v", v.duration, v.pid, v.name, v.args)
|
||||||
|
cmd.Process.Kill()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// If SRS process terminated, notify case to stop.
|
// If SRS process terminated, notify case to stop.
|
||||||
v.wg.Add(1)
|
v.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -327,12 +346,12 @@ func (v *backendService) Run(ctx context.Context, cancel context.CancelFunc) err
|
||||||
defer processDoneCancel()
|
defer processDoneCancel()
|
||||||
|
|
||||||
if err := cmd.Wait(); err != nil && !v.ignoreExitStatusError {
|
if err := cmd.Wait(); err != nil && !v.ignoreExitStatusError {
|
||||||
v.r0 = errors.Wrapf(err, "Process wait err, name=%v, args=%v", v.name, v.args)
|
v.r0 = errors.Wrapf(err, "Process wait err, pid=%v, name=%v, args=%v", v.pid, v.name, v.args)
|
||||||
}
|
}
|
||||||
if v.onStop != nil {
|
if v.onStop != nil {
|
||||||
if err := v.onStop(ctx, v, cmd, v.r0, &v.stdout, &v.stderr); err != nil {
|
if err := v.onStop(ctx, v, cmd, v.r0, &v.stdout, &v.stderr); err != nil {
|
||||||
if v.r0 == nil {
|
if v.r0 == nil {
|
||||||
v.r0 = errors.Wrapf(err, "Process onStop err, name=%v, args=%v", v.name, v.args)
|
v.r0 = errors.Wrapf(err, "Process onStop err, pid=%v, name=%v, args=%v", v.pid, v.name, v.args)
|
||||||
} else {
|
} else {
|
||||||
logger.Ef(ctx, "Process onStop err %v", err)
|
logger.Ef(ctx, "Process onStop err %v", err)
|
||||||
}
|
}
|
||||||
|
@ -435,7 +454,7 @@ type srsServer struct {
|
||||||
func NewSRSServer(opts ...func(v *srsServer)) SRSServer {
|
func NewSRSServer(opts ...func(v *srsServer)) SRSServer {
|
||||||
rid := fmt.Sprintf("%v-%v", os.Getpid(), rand.Int())
|
rid := fmt.Sprintf("%v-%v", os.Getpid(), rand.Int())
|
||||||
v := &srsServer{
|
v := &srsServer{
|
||||||
workDir: "./",
|
workDir: path.Join("objs", fmt.Sprintf("%v", rand.Int())),
|
||||||
srsID: fmt.Sprintf("srs-id-%v", rid),
|
srsID: fmt.Sprintf("srs-id-%v", rid),
|
||||||
process: newBackendService(),
|
process: newBackendService(),
|
||||||
}
|
}
|
||||||
|
@ -443,7 +462,7 @@ func NewSRSServer(opts ...func(v *srsServer)) SRSServer {
|
||||||
|
|
||||||
// If we run in GoLand, the current directory is in blackbox, so we use parent directory.
|
// If we run in GoLand, the current directory is in blackbox, so we use parent directory.
|
||||||
if _, err := os.Stat("objs"); err != nil {
|
if _, err := os.Stat("objs"); err != nil {
|
||||||
v.workDir = "../"
|
v.workDir = path.Join("..", "objs", fmt.Sprintf("%v", rand.Int()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do allocate resource.
|
// Do allocate resource.
|
||||||
|
@ -461,22 +480,12 @@ func NewSRSServer(opts ...func(v *srsServer)) SRSServer {
|
||||||
allocator.Free(v.httpListen)
|
allocator.Free(v.httpListen)
|
||||||
allocator.Free(v.srtListen)
|
allocator.Free(v.srtListen)
|
||||||
|
|
||||||
pidFile := path.Join(v.workDir, v.srsRelativePidFile)
|
if _, err := os.Stat(v.workDir); err == nil {
|
||||||
if _, err := os.Stat(pidFile); err == nil {
|
os.RemoveAll(v.workDir)
|
||||||
os.Remove(pidFile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
idFile := path.Join(v.workDir, v.srsRelativeIDFile)
|
logger.Tf(ctx, "SRS server is closed, id=%v, pid=%v, cleanup=%v r0=%v",
|
||||||
if _, err := os.Stat(idFile); err == nil {
|
v.srsID, bs.pid, v.workDir, bs.r0)
|
||||||
os.Remove(idFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
hlsFiles := path.Join(v.workDir, "objs", "live")
|
|
||||||
if _, err := os.Stat(hlsFiles); err == nil {
|
|
||||||
os.RemoveAll(hlsFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Tf(ctx, "SRS server is closed, id=%v, pid=%v, r0=%v", v.srsID, bs.pid, bs.r0)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,20 +521,39 @@ func (v *srsServer) Run(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
v.workDir, *srsBinary, v.srsID, v.srsRelativePidFile, v.rtmpListen,
|
v.workDir, *srsBinary, v.srsID, v.srsRelativePidFile, v.rtmpListen,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Create directories.
|
||||||
|
if err := os.MkdirAll(path.Join(v.workDir, "./objs/nginx/html"), os.FileMode(0755) | os.ModeDir); err != nil {
|
||||||
|
return errors.Wrapf(err, "SRS create directory %v", path.Join(v.workDir, "./objs/nginx/html"))
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the name and args of process.
|
// Setup the name and args of process.
|
||||||
v.process.name = *srsBinary
|
v.process.name = *srsBinary
|
||||||
v.process.args = []string{"-e"}
|
v.process.args = []string{"-e"}
|
||||||
|
|
||||||
// Setup the envrionment variables.
|
// Setup the constant values.
|
||||||
v.process.env = []string{
|
v.process.env = []string{
|
||||||
// SRS working directory.
|
|
||||||
fmt.Sprintf("SRS_WORK_DIR=%v", v.workDir),
|
|
||||||
// Run in frontend.
|
// Run in frontend.
|
||||||
"SRS_DAEMON=off",
|
"SRS_DAEMON=off",
|
||||||
// Write logs to stdout and stderr.
|
// Write logs to stdout and stderr.
|
||||||
"SRS_SRS_LOG_FILE=console",
|
"SRS_SRS_LOG_FILE=console",
|
||||||
// Disable warning for asan.
|
// Disable warning for asan.
|
||||||
"MallocNanoZone=0",
|
"MallocNanoZone=0",
|
||||||
|
// Avoid error for macOS, which ulimit to 256.
|
||||||
|
"SRS_MAX_CONNECTIONS=100",
|
||||||
|
}
|
||||||
|
// For directories.
|
||||||
|
v.process.env = append(v.process.env, []string{
|
||||||
|
// SRS working directory.
|
||||||
|
fmt.Sprintf("SRS_WORK_DIR=%v", v.workDir),
|
||||||
|
// Setup the default directory for HTTP server.
|
||||||
|
"SRS_HTTP_SERVER_DIR=./objs/nginx/html",
|
||||||
|
// Setup the default directory for HLS stream.
|
||||||
|
"SRS_VHOST_HLS_HLS_PATH=./objs/nginx/html",
|
||||||
|
"SRS_VHOST_HLS_HLS_M3U8_FILE=[app]/[stream].m3u8",
|
||||||
|
"SRS_VHOST_HLS_HLS_TS_FILE=[app]/[stream]-[seq].ts",
|
||||||
|
}...)
|
||||||
|
// For variables.
|
||||||
|
v.process.env = append(v.process.env, []string{
|
||||||
// SRS PID file.
|
// SRS PID file.
|
||||||
fmt.Sprintf("SRS_PID=%v", v.srsRelativePidFile),
|
fmt.Sprintf("SRS_PID=%v", v.srsRelativePidFile),
|
||||||
// SRS ID file.
|
// SRS ID file.
|
||||||
|
@ -533,19 +561,13 @@ func (v *srsServer) Run(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
// HTTP API to detect the service.
|
// HTTP API to detect the service.
|
||||||
fmt.Sprintf("SRS_HTTP_API_ENABLED=on"),
|
fmt.Sprintf("SRS_HTTP_API_ENABLED=on"),
|
||||||
fmt.Sprintf("SRS_HTTP_API_LISTEN=%v", v.apiListen),
|
fmt.Sprintf("SRS_HTTP_API_LISTEN=%v", v.apiListen),
|
||||||
// Avoid error for macOS, which ulimit to 256.
|
|
||||||
"SRS_MAX_CONNECTIONS=100",
|
|
||||||
// Setup the default directory for HTTP server.
|
|
||||||
"SRS_HTTP_SERVER_DIR=objs",
|
|
||||||
// Setup the default directory for HLS stream.
|
|
||||||
"SRS_VHOST_HLS_HLS_PATH=objs",
|
|
||||||
// Setup the RTMP listen port.
|
// Setup the RTMP listen port.
|
||||||
fmt.Sprintf("SRS_LISTEN=%v", v.rtmpListen),
|
fmt.Sprintf("SRS_LISTEN=%v", v.rtmpListen),
|
||||||
// Setup the HTTP sever listen port.
|
// Setup the HTTP sever listen port.
|
||||||
fmt.Sprintf("SRS_HTTP_SERVER_LISTEN=%v", v.httpListen),
|
fmt.Sprintf("SRS_HTTP_SERVER_LISTEN=%v", v.httpListen),
|
||||||
// Setup the SRT server listen port.
|
// Setup the SRT server listen port.
|
||||||
fmt.Sprintf("SRS_SRT_SERVER_LISTEN=%v", v.srtListen),
|
fmt.Sprintf("SRS_SRT_SERVER_LISTEN=%v", v.srtListen),
|
||||||
}
|
}...)
|
||||||
// Rewrite envs by case.
|
// Rewrite envs by case.
|
||||||
if v.envs != nil {
|
if v.envs != nil {
|
||||||
v.process.env = append(v.process.env, v.envs...)
|
v.process.env = append(v.process.env, v.envs...)
|
||||||
|
@ -588,8 +610,8 @@ func (v *srsServer) Run(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
|
|
||||||
// Hooks for process.
|
// Hooks for process.
|
||||||
v.process.onBeforeStart = func(ctx context.Context, bs *backendService, cmd *exec.Cmd) error {
|
v.process.onBeforeStart = func(ctx context.Context, bs *backendService, cmd *exec.Cmd) error {
|
||||||
logger.Tf(ctx, "SRS id=%v, env=%v, cmd is %v %v",
|
logger.Tf(ctx, "SRS id=%v, env %v %v %v",
|
||||||
v.srsID, cmd.Env, bs.name, strings.Join(bs.args, " "))
|
v.srsID, strings.Join(cmd.Env, " "), bs.name, strings.Join(bs.args, " "))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
v.process.onAfterStart = func(ctx context.Context, bs *backendService, cmd *exec.Cmd) error {
|
v.process.onAfterStart = func(ctx context.Context, bs *backendService, cmd *exec.Cmd) error {
|
||||||
|
@ -625,11 +647,16 @@ type ffmpegClient struct {
|
||||||
|
|
||||||
// FFmpeg cli args, without ffmpeg binary.
|
// FFmpeg cli args, without ffmpeg binary.
|
||||||
args []string
|
args []string
|
||||||
|
// Let the process quit, do not cancel the case.
|
||||||
|
cancelCaseWhenQuit bool
|
||||||
|
// When timeout, stop FFmpeg, sometimes the '-t' does not work.
|
||||||
|
ffmpegDuration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFFmpeg(opts ...func(v *ffmpegClient)) FFmpegClient {
|
func NewFFmpeg(opts ...func(v *ffmpegClient)) FFmpegClient {
|
||||||
v := &ffmpegClient{
|
v := &ffmpegClient{
|
||||||
process: newBackendService(),
|
process: newBackendService(),
|
||||||
|
cancelCaseWhenQuit: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do cleanup.
|
// Do cleanup.
|
||||||
|
@ -657,6 +684,7 @@ func (v *ffmpegClient) Run(ctx context.Context, cancel context.CancelFunc) error
|
||||||
v.process.name = *srsFFmpeg
|
v.process.name = *srsFFmpeg
|
||||||
v.process.args = v.args
|
v.process.args = v.args
|
||||||
v.process.env = os.Environ()
|
v.process.env = os.Environ()
|
||||||
|
v.process.duration = v.ffmpegDuration
|
||||||
|
|
||||||
v.process.onStop = func(ctx context.Context, bs *backendService, cmd *exec.Cmd, r0 error, stdout, stderr *bytes.Buffer) error {
|
v.process.onStop = func(ctx context.Context, bs *backendService, cmd *exec.Cmd, r0 error, stdout, stderr *bytes.Buffer) error {
|
||||||
logger.Tf(ctx, "FFmpeg process pid=%v exit, r0=%v, stdout=%v", bs.pid, r0, stdout.String())
|
logger.Tf(ctx, "FFmpeg process pid=%v exit, r0=%v, stdout=%v", bs.pid, r0, stdout.String())
|
||||||
|
@ -666,7 +694,20 @@ func (v *ffmpegClient) Run(ctx context.Context, cancel context.CancelFunc) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.process.Run(ctx, cancel)
|
// We might not want to cancel the case, for example, when check DVR by session, we just let the FFmpeg process to
|
||||||
|
// quit and we should check the callback and DVR file.
|
||||||
|
ffCtx, ffCancel := context.WithCancel(ctx)
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <- ctx.Done():
|
||||||
|
case <-ffCtx.Done():
|
||||||
|
if v.cancelCaseWhenQuit {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return v.process.Run(ffCtx, ffCancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
type FFprobeClient interface {
|
type FFprobeClient interface {
|
||||||
|
@ -678,16 +719,19 @@ type FFprobeClient interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ffprobeClient struct {
|
type ffprobeClient struct {
|
||||||
// The stream to probe.
|
// The DVR file for ffprobe. Stream should be DVR to file, then use ffprobe to detect it. If DVR by FFmpeg, we will
|
||||||
streamURL string
|
// start a FFmpeg process to do the DVR, or the DVR should be done by other tools.
|
||||||
|
|
||||||
// The DVR file for ffprobe. We DVR stream to file, then use ffprobe to detect it.
|
|
||||||
dvrFile string
|
dvrFile string
|
||||||
// The duration of video file for DVR.
|
|
||||||
duration time.Duration
|
|
||||||
// The timeout to wait for task to done.
|
// The timeout to wait for task to done.
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
|
||||||
|
// Whether do DVR by FFmpeg, if using SRS DVR, please set to false.
|
||||||
|
dvrByFFmpeg bool
|
||||||
|
// The stream to DVR for probing. Ignore if not DVR by ffmpeg
|
||||||
|
streamURL string
|
||||||
|
// The duration of video file for DVR and probing.
|
||||||
|
duration time.Duration
|
||||||
|
|
||||||
// When probe stream metadata object.
|
// When probe stream metadata object.
|
||||||
doneCtx context.Context
|
doneCtx context.Context
|
||||||
doneCancel context.CancelFunc
|
doneCancel context.CancelFunc
|
||||||
|
@ -700,6 +744,7 @@ type ffprobeClient struct {
|
||||||
func NewFFprobe(opts ...func(v *ffprobeClient)) FFprobeClient {
|
func NewFFprobe(opts ...func(v *ffprobeClient)) FFprobeClient {
|
||||||
v := &ffprobeClient{
|
v := &ffprobeClient{
|
||||||
metadata: &ffprobeObject{},
|
metadata: &ffprobeObject{},
|
||||||
|
dvrByFFmpeg: true,
|
||||||
}
|
}
|
||||||
v.doneCtx, v.doneCancel = context.WithCancel(context.Background())
|
v.doneCtx, v.doneCancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
@ -728,9 +773,12 @@ func (v *ffprobeClient) Run(ctxCase context.Context, cancelCase context.CancelFu
|
||||||
|
|
||||||
// Try to start a DVR process.
|
// Try to start a DVR process.
|
||||||
for ctx.Err() == nil {
|
for ctx.Err() == nil {
|
||||||
|
// If not DVR by FFmpeg, we just wait the DVR file to be ready, and it should be done by SRS or other tools.
|
||||||
|
if v.dvrByFFmpeg {
|
||||||
// If error, just ignore and retry, because the stream might not be ready. For example, for HLS, the DVR process
|
// If error, just ignore and retry, because the stream might not be ready. For example, for HLS, the DVR process
|
||||||
// might need to wait for a duration of segment, 10s as such.
|
// might need to wait for a duration of segment, 10s as such.
|
||||||
_ = v.doDVR(ctx)
|
_ = v.doDVR(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether DVR file is ok.
|
// Check whether DVR file is ok.
|
||||||
if fs, err := os.Stat(v.dvrFile); err == nil && fs.Size() > 1024 {
|
if fs, err := os.Stat(v.dvrFile); err == nil && fs.Size() > 1024 {
|
||||||
|
@ -738,9 +786,14 @@ func (v *ffprobeClient) Run(ctxCase context.Context, cancelCase context.CancelFu
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If not DVR by FFmpeg, must be by other tools, only need to wait.
|
||||||
|
if !v.dvrByFFmpeg {
|
||||||
|
logger.Tf(ctx, "Waiting stream=%v to be DVR", v.streamURL)
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for a while and retry. Use larger timeout for HLS.
|
// Wait for a while and retry. Use larger timeout for HLS.
|
||||||
retryTimeout := 1 * time.Second
|
retryTimeout := 1 * time.Second
|
||||||
if strings.Contains(v.streamURL, ".m3u8") {
|
if strings.Contains(v.streamURL, ".m3u8") || v.dvrFile == "" {
|
||||||
retryTimeout = 3 * time.Second
|
retryTimeout = 3 * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,6 +816,10 @@ func (v *ffprobeClient) Run(ctxCase context.Context, cancelCase context.CancelFu
|
||||||
func (v *ffprobeClient) doDVR(ctx context.Context) error {
|
func (v *ffprobeClient) doDVR(ctx context.Context) error {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
|
if !v.dvrByFFmpeg {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
process := newBackendService()
|
process := newBackendService()
|
||||||
process.name = *srsFFmpeg
|
process.name = *srsFFmpeg
|
||||||
process.args = []string{
|
process.args = []string{
|
||||||
|
@ -1070,3 +1127,167 @@ func (v *ffprobeObject) Audio() *ffprobeObjectMedia {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HooksEvent interface {
|
||||||
|
HookAction() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type HooksEventBase struct {
|
||||||
|
Action string `json:"action"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *HooksEventBase) HookAction() string {
|
||||||
|
return v.Action
|
||||||
|
}
|
||||||
|
|
||||||
|
type HooksEventOnDvr struct {
|
||||||
|
HooksEventBase
|
||||||
|
Stream string `json:"stream"`
|
||||||
|
StreamUrl string `json:"stream_url"`
|
||||||
|
StreamID string `json:"stream_id"`
|
||||||
|
CWD string `json:"cwd"`
|
||||||
|
File string `json:"file"`
|
||||||
|
TcUrl string `json:"tcUrl"`
|
||||||
|
App string `json:"app"`
|
||||||
|
Vhost string `json:"vhost"`
|
||||||
|
IP string `json:"ip"`
|
||||||
|
ClientIP string `json:"client_id"`
|
||||||
|
ServerID string `json:"server_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HooksService interface {
|
||||||
|
ServiceRunner
|
||||||
|
ServiceReadyQuerier
|
||||||
|
HooksAPI() int
|
||||||
|
HooksEvents() <-chan HooksEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
type hooksService struct {
|
||||||
|
readyCtx context.Context
|
||||||
|
readyCancel context.CancelFunc
|
||||||
|
|
||||||
|
httpPort int
|
||||||
|
dispose func()
|
||||||
|
|
||||||
|
r0 error
|
||||||
|
hooksOnDvr chan HooksEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHooksService(opts ...func(v *hooksService)) HooksService {
|
||||||
|
v := &hooksService{}
|
||||||
|
|
||||||
|
v.httpPort = allocator.Allocate()
|
||||||
|
v.dispose = func() {
|
||||||
|
allocator.Free(v.httpPort)
|
||||||
|
close(v.hooksOnDvr)
|
||||||
|
}
|
||||||
|
v.hooksOnDvr = make(chan HooksEvent, 64)
|
||||||
|
v.readyCtx, v.readyCancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *hooksService) ReadyCtx() context.Context {
|
||||||
|
return v.readyCtx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *hooksService) HooksAPI() int {
|
||||||
|
return v.httpPort
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *hooksService) HooksEvents() <-chan HooksEvent {
|
||||||
|
return v.hooksOnDvr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *hooksService) Run(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
|
defer func() {
|
||||||
|
v.readyCancel()
|
||||||
|
v.dispose()
|
||||||
|
}()
|
||||||
|
|
||||||
|
handler := http.ServeMux{}
|
||||||
|
handler.HandleFunc("/api/v1/ping", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ohttp.WriteData(ctx, w, r, "pong")
|
||||||
|
})
|
||||||
|
|
||||||
|
handler.HandleFunc("/api/v1/dvrs", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
ohttp.WriteError(ctx, w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
evt := HooksEventOnDvr{}
|
||||||
|
if err := json.Unmarshal(b, &evt); err != nil {
|
||||||
|
ohttp.WriteError(ctx, w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
case v.hooksOnDvr <- &evt:
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tf(ctx, "Callback: Got on_dvr request %v", string(b))
|
||||||
|
ohttp.WriteData(ctx, w, r, nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
server := &http.Server{Addr: fmt.Sprintf(":%v", v.httpPort), Handler: &handler}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
defer wg.Wait()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
logger.Tf(ctx, "Callback: Start hooks server, listen=%v", v.httpPort)
|
||||||
|
|
||||||
|
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
|
logger.Wf(ctx, "Callback: Service listen=%v, err %v", v.httpPort, err)
|
||||||
|
v.r0 = errors.Wrapf(err, "server listen=%v", v.httpPort)
|
||||||
|
cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Tf(ctx, "Callback: Hooks done, listen=%v", v.httpPort)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
<-ctx.Done()
|
||||||
|
|
||||||
|
go server.Shutdown(context.Background())
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
for ctx.Err() == nil {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
r := fmt.Sprintf("http://localhost:%v/api/v1/ping", v.httpPort)
|
||||||
|
res, err := http.Get(r)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tf(ctx, "Callback: API is ready, %v %v", r, string(b))
|
||||||
|
v.readyCancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
return v.r0
|
||||||
|
}
|
||||||
|
|
1
trunk/3rdparty/srs-bench/go.mod
vendored
1
trunk/3rdparty/srs-bench/go.mod
vendored
|
@ -12,6 +12,7 @@ require (
|
||||||
github.com/pion/sdp/v3 v3.0.4
|
github.com/pion/sdp/v3 v3.0.4
|
||||||
github.com/pion/transport v0.12.2
|
github.com/pion/transport v0.12.2
|
||||||
github.com/pion/webrtc/v3 v3.0.13
|
github.com/pion/webrtc/v3 v3.0.13
|
||||||
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/yapingcat/gomedia/codec v0.0.0-20220617074658-94762898dc25
|
github.com/yapingcat/gomedia/codec v0.0.0-20220617074658-94762898dc25
|
||||||
github.com/yapingcat/gomedia/mpeg2 v0.0.0-20220617074658-94762898dc25
|
github.com/yapingcat/gomedia/mpeg2 v0.0.0-20220617074658-94762898dc25
|
||||||
)
|
)
|
||||||
|
|
4
trunk/3rdparty/srs-bench/vendor/github.com/ghettovoice/gosip/sip/parser/error.go
generated
vendored
4
trunk/3rdparty/srs-bench/vendor/github.com/ghettovoice/gosip/sip/parser/error.go
generated
vendored
|
@ -11,9 +11,7 @@ type InvalidStartLineError string
|
||||||
func (err InvalidStartLineError) Syntax() bool { return true }
|
func (err InvalidStartLineError) Syntax() bool { return true }
|
||||||
func (err InvalidStartLineError) Malformed() bool { return false }
|
func (err InvalidStartLineError) Malformed() bool { return false }
|
||||||
func (err InvalidStartLineError) Broken() bool { return true }
|
func (err InvalidStartLineError) Broken() bool { return true }
|
||||||
func (err InvalidStartLineError) Error() string {
|
func (err InvalidStartLineError) Error() string { return "parser.InvalidStartLineError: " + string(err) }
|
||||||
return "parser.InvalidStartLineError: " + string(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidMessageFormat string
|
type InvalidMessageFormat string
|
||||||
|
|
||||||
|
|
87
trunk/3rdparty/srs-bench/vendor/github.com/ossrs/go-oryx-lib/http/api.go
generated
vendored
Normal file
87
trunk/3rdparty/srs-bench/vendor/github.com/ossrs/go-oryx-lib/http/api.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2017 Oryx(ossrs)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// The oryx http package, the response parse service.
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read http api by HTTP GET and parse the code/data.
|
||||||
|
func ApiRequest(url string) (code int, body []byte, err error) {
|
||||||
|
if body, err = apiGet(url); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if code, _, err = apiParse(url, body); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read http api by HTTP GET.
|
||||||
|
func apiGet(url string) (body []byte, err error) {
|
||||||
|
var resp *http.Response
|
||||||
|
if resp, err = http.Get(url); err != nil {
|
||||||
|
err = fmt.Errorf("api get failed, url=%v, err is %v", url, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if body, err = ioutil.ReadAll(resp.Body); err != nil {
|
||||||
|
err = fmt.Errorf("api read failed, url=%v, err is %v", url, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the standard response {code:int,data:object}.
|
||||||
|
func apiParse(url string, body []byte) (code int, data interface{}, err error) {
|
||||||
|
obj := make(map[string]interface{})
|
||||||
|
if err = json.Unmarshal(body, &obj); err != nil {
|
||||||
|
err = fmt.Errorf("api parse failed, url=%v, body=%v, err is %v", url, string(body), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if value, ok := obj["code"]; !ok {
|
||||||
|
err = fmt.Errorf("api no code, url=%v, body=%v", url, string(body))
|
||||||
|
return
|
||||||
|
} else if value, ok := value.(float64); !ok {
|
||||||
|
err = fmt.Errorf("api code not number, code=%v, url=%v, body=%v", value, url, string(body))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
code = int(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ = obj["data"]
|
||||||
|
if code != 0 {
|
||||||
|
err = fmt.Errorf("api error, code=%v, url=%v, body=%v, data=%v", code, url, string(body), data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
274
trunk/3rdparty/srs-bench/vendor/github.com/ossrs/go-oryx-lib/http/http.go
generated
vendored
Normal file
274
trunk/3rdparty/srs-bench/vendor/github.com/ossrs/go-oryx-lib/http/http.go
generated
vendored
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2017 Oryx(ossrs)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// The oryx http package provides standard request and response in json.
|
||||||
|
// Error, when error, use this handler.
|
||||||
|
// CplxError, for complex error, use this handler.
|
||||||
|
// Data, when no error, use this handler.
|
||||||
|
// SystemError, application level error code.
|
||||||
|
// SetHeader, for direclty response the raw stream.
|
||||||
|
// The standard server response:
|
||||||
|
// code, an int error code.
|
||||||
|
// data, specifies the data.
|
||||||
|
// The api for simple api:
|
||||||
|
// WriteVersion, to directly response the version.
|
||||||
|
// WriteData, to directly write the data in json.
|
||||||
|
// WriteError, to directly write the error.
|
||||||
|
// WriteCplxError, to directly write the complex error.
|
||||||
|
// The global variables:
|
||||||
|
// oh.Server, to set the response header["Server"].
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
ol "github.com/ossrs/go-oryx-lib/logger"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// header["Content-Type"] in response.
|
||||||
|
const (
|
||||||
|
HttpJson = "application/json"
|
||||||
|
HttpJavaScript = "application/javascript"
|
||||||
|
)
|
||||||
|
|
||||||
|
// header["Server"] in response.
|
||||||
|
var Server = "Oryx"
|
||||||
|
|
||||||
|
// system int error.
|
||||||
|
type SystemError int
|
||||||
|
|
||||||
|
func (v SystemError) Error() string {
|
||||||
|
return fmt.Sprintf("System error=%d", int(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// system conplex error.
|
||||||
|
type SystemComplexError struct {
|
||||||
|
// the system error code.
|
||||||
|
Code SystemError `json:"code"`
|
||||||
|
// the description for this error.
|
||||||
|
Message string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v SystemComplexError) Error() string {
|
||||||
|
return fmt.Sprintf("%v, %v", v.Code.Error(), v.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// application level, with code.
|
||||||
|
type AppError interface {
|
||||||
|
Code() int
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP Status Code
|
||||||
|
type HTTPStatus interface {
|
||||||
|
Status() int
|
||||||
|
}
|
||||||
|
|
||||||
|
// http standard error response.
|
||||||
|
// @remark for not SystemError, we will use logger.E to print it.
|
||||||
|
// @remark user can use WriteError() for simple api.
|
||||||
|
func Error(ctx ol.Context, err error) http.Handler {
|
||||||
|
// for complex error, use code instead.
|
||||||
|
if v, ok := err.(SystemComplexError); ok {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
jsonHandler(ctx, FilterCplxSystemError(ctx, w, r, v)).ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// for int error, use code instead.
|
||||||
|
if v, ok := err.(SystemError); ok {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
jsonHandler(ctx, FilterSystemError(ctx, w, r, v)).ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// for application error, use code instead.
|
||||||
|
if v, ok := err.(AppError); ok {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
jsonHandler(ctx, FilterAppError(ctx, w, r, v)).ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknown error, log and response detail
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
SetHeader(w)
|
||||||
|
w.Header().Set("Content-Type", HttpJson)
|
||||||
|
|
||||||
|
status := http.StatusInternalServerError
|
||||||
|
if v, ok := err.(HTTPStatus); ok {
|
||||||
|
status = v.Status()
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Error(w, FilterError(ctx, w, r, err), status)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for complex error use Error(ctx, SystemComplexError{})
|
||||||
|
// @remark user can use WriteCplxError() for simple api.
|
||||||
|
func CplxError(ctx ol.Context, code SystemError, message string) http.Handler {
|
||||||
|
return Error(ctx, SystemComplexError{code, message})
|
||||||
|
}
|
||||||
|
|
||||||
|
// http normal response.
|
||||||
|
// @remark user can use nil v to response success, which data is null.
|
||||||
|
// @remark user can use WriteData() for simple api.
|
||||||
|
func Data(ctx ol.Context, v interface{}) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
jsonHandler(ctx, FilterData(ctx, w, r, v)).ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// set http header, for directly use the w,
|
||||||
|
// for example, user want to directly write raw text.
|
||||||
|
func SetHeader(w http.ResponseWriter) {
|
||||||
|
w.Header().Set("Server", Server)
|
||||||
|
}
|
||||||
|
|
||||||
|
// response json directly.
|
||||||
|
func jsonHandler(ctx ol.Context, rv interface{}) http.Handler {
|
||||||
|
var err error
|
||||||
|
var b []byte
|
||||||
|
if b, err = json.Marshal(rv); err != nil {
|
||||||
|
return Error(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
status := http.StatusOK
|
||||||
|
if v, ok := rv.(HTTPStatus); ok {
|
||||||
|
status = v.Status()
|
||||||
|
}
|
||||||
|
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
SetHeader(w)
|
||||||
|
|
||||||
|
q := r.URL.Query()
|
||||||
|
if cb := q.Get("callback"); cb != "" {
|
||||||
|
w.Header().Set("Content-Type", HttpJavaScript)
|
||||||
|
if status != http.StatusOK {
|
||||||
|
w.WriteHeader(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle error.
|
||||||
|
fmt.Fprintf(w, "%s(%s)", cb, string(b))
|
||||||
|
} else {
|
||||||
|
w.Header().Set("Content-Type", HttpJson)
|
||||||
|
if status != http.StatusOK {
|
||||||
|
w.WriteHeader(status)
|
||||||
|
}
|
||||||
|
// TODO: Handle error.
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// response the standard version info:
|
||||||
|
// {code, server, data} where server is the server pid, and data is below object:
|
||||||
|
// {major, minor, revision, extra, version, signature}
|
||||||
|
// @param version in {major.minor.revision-extra}, where -extra is optional,
|
||||||
|
// for example: 1.0.0 or 1.0.0-0 or 1.0.0-1
|
||||||
|
func WriteVersion(w http.ResponseWriter, r *http.Request, version string) {
|
||||||
|
var major, minor, revision, extra int
|
||||||
|
|
||||||
|
versions := strings.Split(version, "-")
|
||||||
|
if len(versions) > 1 {
|
||||||
|
extra, _ = strconv.Atoi(versions[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
versions = strings.Split(versions[0], ".")
|
||||||
|
if len(versions) > 0 {
|
||||||
|
major, _ = strconv.Atoi(versions[0])
|
||||||
|
}
|
||||||
|
if len(versions) > 1 {
|
||||||
|
minor, _ = strconv.Atoi(versions[1])
|
||||||
|
}
|
||||||
|
if len(versions) > 2 {
|
||||||
|
revision, _ = strconv.Atoi(versions[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
Data(nil, map[string]interface{}{
|
||||||
|
"major": major,
|
||||||
|
"minor": minor,
|
||||||
|
"revision": revision,
|
||||||
|
"extra": extra,
|
||||||
|
"version": version,
|
||||||
|
"signature": Server,
|
||||||
|
}).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directly write json data, a wrapper for Data().
|
||||||
|
// @remark user can use Data() for group of complex apis.
|
||||||
|
func WriteData(ctx ol.Context, w http.ResponseWriter, r *http.Request, v interface{}) {
|
||||||
|
Data(ctx, v).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directly write success json response, same to WriteData(ctx, w, r, nil).
|
||||||
|
func Success(ctx ol.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
WriteData(ctx, w, r, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directly write error, a wrapper for Error().
|
||||||
|
// @remark user can use Error() for group of complex apis.
|
||||||
|
func WriteError(ctx ol.Context, w http.ResponseWriter, r *http.Request, err error) {
|
||||||
|
Error(ctx, err).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directly write complex error, a wrappter for CplxError().
|
||||||
|
// @remark user can use CplxError() for group of complex apis.
|
||||||
|
func WriteCplxError(ctx ol.Context, w http.ResponseWriter, r *http.Request, code SystemError, message string) {
|
||||||
|
CplxError(ctx, code, message).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for hijack to define the response structure.
|
||||||
|
// user can redefine these functions for special response.
|
||||||
|
var FilterCplxSystemError = func(ctx ol.Context, w http.ResponseWriter, r *http.Request, o SystemComplexError) interface{} {
|
||||||
|
ol.Ef(ctx, "Serve %v failed, err is %+v", r.URL, o)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
var FilterSystemError = func(ctx ol.Context, w http.ResponseWriter, r *http.Request, o SystemError) interface{} {
|
||||||
|
ol.Ef(ctx, "Serve %v failed, err is %+v", r.URL, o)
|
||||||
|
return map[string]int{"code": int(o)}
|
||||||
|
}
|
||||||
|
var FilterAppError = func(ctx ol.Context, w http.ResponseWriter, r *http.Request, err AppError) interface{} {
|
||||||
|
ol.Ef(ctx, "Serve %v failed, err is %+v", r.URL, err)
|
||||||
|
return map[string]interface{}{"code": err.Code(), "data": err.Error()}
|
||||||
|
}
|
||||||
|
var FilterError = func(ctx ol.Context, w http.ResponseWriter, r *http.Request, err error) string {
|
||||||
|
ol.Ef(ctx, "Serve %v failed, err is %+v", r.URL, err)
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
var FilterData = func(ctx ol.Context, w http.ResponseWriter, r *http.Request, o interface{}) interface{} {
|
||||||
|
rv := map[string]interface{}{
|
||||||
|
"code": 0,
|
||||||
|
"server": os.Getpid(),
|
||||||
|
"data": o,
|
||||||
|
}
|
||||||
|
|
||||||
|
// for string, directly use it without convert,
|
||||||
|
// for the type covert by golang maybe modify the content.
|
||||||
|
if v, ok := o.(string); ok {
|
||||||
|
rv["data"] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv
|
||||||
|
}
|
1
trunk/3rdparty/srs-bench/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
|
@ -10,3 +10,4 @@ func isTerminal(fd int) bool {
|
||||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
|
@ -10,3 +10,4 @@ func isTerminal(fd int) bool {
|
||||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mgutz/ansi"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/mgutz/ansi"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
2
trunk/3rdparty/srs-bench/vendor/modules.txt
vendored
2
trunk/3rdparty/srs-bench/vendor/modules.txt
vendored
|
@ -33,6 +33,7 @@ github.com/ossrs/go-oryx-lib/amf0
|
||||||
github.com/ossrs/go-oryx-lib/avc
|
github.com/ossrs/go-oryx-lib/avc
|
||||||
github.com/ossrs/go-oryx-lib/errors
|
github.com/ossrs/go-oryx-lib/errors
|
||||||
github.com/ossrs/go-oryx-lib/flv
|
github.com/ossrs/go-oryx-lib/flv
|
||||||
|
github.com/ossrs/go-oryx-lib/http
|
||||||
github.com/ossrs/go-oryx-lib/logger
|
github.com/ossrs/go-oryx-lib/logger
|
||||||
github.com/ossrs/go-oryx-lib/rtmp
|
github.com/ossrs/go-oryx-lib/rtmp
|
||||||
# github.com/pion/datachannel v1.4.21
|
# github.com/pion/datachannel v1.4.21
|
||||||
|
@ -116,6 +117,7 @@ github.com/pion/webrtc/v3/pkg/media/oggreader
|
||||||
github.com/pion/webrtc/v3/pkg/media/oggwriter
|
github.com/pion/webrtc/v3/pkg/media/oggwriter
|
||||||
github.com/pion/webrtc/v3/pkg/rtcerr
|
github.com/pion/webrtc/v3/pkg/rtcerr
|
||||||
# github.com/pkg/errors v0.9.1
|
# github.com/pkg/errors v0.9.1
|
||||||
|
## explicit
|
||||||
github.com/pkg/errors
|
github.com/pkg/errors
|
||||||
# github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
# github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
||||||
github.com/satori/go.uuid
|
github.com/satori/go.uuid
|
||||||
|
|
|
@ -1515,6 +1515,7 @@ vhost http.remux.srs.com {
|
||||||
vhost hooks.callback.srs.com {
|
vhost hooks.callback.srs.com {
|
||||||
http_hooks {
|
http_hooks {
|
||||||
# whether the http hooks enable.
|
# whether the http hooks enable.
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ENABLED for all vhosts.
|
||||||
# default off.
|
# default off.
|
||||||
enabled on;
|
enabled on;
|
||||||
# when client(encoder) publish to vhost/app/stream, call the hook,
|
# when client(encoder) publish to vhost/app/stream, call the hook,
|
||||||
|
@ -1533,6 +1534,7 @@ vhost hooks.callback.srs.com {
|
||||||
# on_publish http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
# on_publish http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
||||||
# @remark For SRS4, the HTTPS url is supported, for example:
|
# @remark For SRS4, the HTTPS url is supported, for example:
|
||||||
# on_publish https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
# on_publish https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_PUBLISH for all vhosts.
|
||||||
on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
|
on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
|
||||||
# when client(encoder) stop publish to vhost/app/stream, call the hook,
|
# when client(encoder) stop publish to vhost/app/stream, call the hook,
|
||||||
# the request in the POST data string is a object encode by json:
|
# the request in the POST data string is a object encode by json:
|
||||||
|
@ -1550,6 +1552,7 @@ vhost hooks.callback.srs.com {
|
||||||
# on_unpublish http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
# on_unpublish http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
||||||
# @remark For SRS4, the HTTPS url is supported, for example:
|
# @remark For SRS4, the HTTPS url is supported, for example:
|
||||||
# on_unpublish https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
# on_unpublish https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_UNPUBLISH for all vhosts.
|
||||||
on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
|
on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
|
||||||
# when client start to play vhost/app/stream, call the hook,
|
# when client start to play vhost/app/stream, call the hook,
|
||||||
# the request in the POST data string is a object encode by json:
|
# the request in the POST data string is a object encode by json:
|
||||||
|
@ -1568,6 +1571,7 @@ vhost hooks.callback.srs.com {
|
||||||
# on_play http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
# on_play http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
||||||
# @remark For SRS4, the HTTPS url is supported, for example:
|
# @remark For SRS4, the HTTPS url is supported, for example:
|
||||||
# on_play https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
# on_play https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_PLAY for all vhosts.
|
||||||
on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
|
on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
|
||||||
# when client stop to play vhost/app/stream, call the hook,
|
# when client stop to play vhost/app/stream, call the hook,
|
||||||
# the request in the POST data string is a object encode by json:
|
# the request in the POST data string is a object encode by json:
|
||||||
|
@ -1585,6 +1589,7 @@ vhost hooks.callback.srs.com {
|
||||||
# on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
# on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN
|
||||||
# @remark For SRS4, the HTTPS url is supported, for example:
|
# @remark For SRS4, the HTTPS url is supported, for example:
|
||||||
# on_stop https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
# on_stop https://xxx/api0 https://xxx/api1 https://xxx/apiN
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_STOP for all vhosts.
|
||||||
on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
|
on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
|
||||||
# when srs reap a dvr file, call the hook,
|
# when srs reap a dvr file, call the hook,
|
||||||
# the request in the POST data string is a object encode by json:
|
# the request in the POST data string is a object encode by json:
|
||||||
|
@ -1600,6 +1605,7 @@ vhost hooks.callback.srs.com {
|
||||||
# if valid, the hook must return HTTP code 200(Status OK) and response
|
# if valid, the hook must return HTTP code 200(Status OK) and response
|
||||||
# an int value specifies the error code(0 corresponding to success):
|
# an int value specifies the error code(0 corresponding to success):
|
||||||
# 0
|
# 0
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_DVR for all vhosts.
|
||||||
on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs;
|
on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs;
|
||||||
# when srs reap a ts file of hls, call the hook,
|
# when srs reap a ts file of hls, call the hook,
|
||||||
# the request in the POST data string is a object encode by json:
|
# the request in the POST data string is a object encode by json:
|
||||||
|
@ -1620,6 +1626,7 @@ vhost hooks.callback.srs.com {
|
||||||
# if valid, the hook must return HTTP code 200(Status OK) and response
|
# if valid, the hook must return HTTP code 200(Status OK) and response
|
||||||
# an int value specifies the error code(0 corresponding to success):
|
# an int value specifies the error code(0 corresponding to success):
|
||||||
# 0
|
# 0
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_HLS for all vhosts.
|
||||||
on_hls http://127.0.0.1:8085/api/v1/hls http://localhost:8085/api/v1/hls;
|
on_hls http://127.0.0.1:8085/api/v1/hls http://localhost:8085/api/v1/hls;
|
||||||
# when srs reap a ts file of hls, call this hook,
|
# when srs reap a ts file of hls, call this hook,
|
||||||
# used to push file to cdn network, by get the ts file from cdn network.
|
# used to push file to cdn network, by get the ts file from cdn network.
|
||||||
|
@ -1631,6 +1638,7 @@ vhost hooks.callback.srs.com {
|
||||||
# [ts_url], replace with the ts url.
|
# [ts_url], replace with the ts url.
|
||||||
# ignore any return data of server.
|
# ignore any return data of server.
|
||||||
# @remark random select a url to report, not report all.
|
# @remark random select a url to report, not report all.
|
||||||
|
# Overwrite by env SRS_VHOST_HTTP_HOOKS_ON_HLS_NOTIFY for all vhosts.
|
||||||
on_hls_notify http://127.0.0.1:8085/api/v1/hls/[server_id]/[app]/[stream]/[ts_url][param];
|
on_hls_notify http://127.0.0.1:8085/api/v1/hls/[server_id]/[app]/[stream]/[ts_url][param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 5.0 Changelog
|
## SRS 5.0 Changelog
|
||||||
|
|
||||||
* v5.0, 2023-01-05, FFmpeg: Support build with FFmpeg native opus. v5.0.131 (#3140)
|
* v5.0, 2023-01-06, DVR: Support blackbox test based on hooks. v5.0.132
|
||||||
|
* v5.0, 2023-01-06, FFmpeg: Support build with FFmpeg native opus. v5.0.131 (#3140)
|
||||||
* v5.0, 2023-01-05, CORS: Refine HTTP CORS headers. v5.0.130
|
* v5.0, 2023-01-05, CORS: Refine HTTP CORS headers. v5.0.130
|
||||||
* v5.0, 2023-01-03, Add blackbox test for HLS and MP3 codec. v5.0.129
|
* v5.0, 2023-01-03, Add blackbox test for HLS and MP3 codec. v5.0.129
|
||||||
* v5.0, 2023-01-02, Merge [#3355](https://github.com/ossrs/srs/pull/3355): Test: Support blackbox test by FFmpeg. v5.0.128
|
* v5.0, 2023-01-02, Merge [#3355](https://github.com/ossrs/srs/pull/3355): Test: Support blackbox test by FFmpeg. v5.0.128
|
||||||
|
|
|
@ -68,6 +68,16 @@ const char* _srs_version = "XCORE-" RTMP_SIG_SRS_SERVER;
|
||||||
#define SRS_OVERWRITE_BY_ENV_MILLISECONDS(key) if (!srs_getenv(key).empty()) return (srs_utime_t)(::atoi(srs_getenv(key).c_str()) * SRS_UTIME_MILLISECONDS)
|
#define SRS_OVERWRITE_BY_ENV_MILLISECONDS(key) if (!srs_getenv(key).empty()) return (srs_utime_t)(::atoi(srs_getenv(key).c_str()) * SRS_UTIME_MILLISECONDS)
|
||||||
#define SRS_OVERWRITE_BY_ENV_FLOAT_SECONDS(key) if (!srs_getenv(key).empty()) return srs_utime_t(::atof(srs_getenv(key).c_str()) * SRS_UTIME_SECONDS)
|
#define SRS_OVERWRITE_BY_ENV_FLOAT_SECONDS(key) if (!srs_getenv(key).empty()) return srs_utime_t(::atof(srs_getenv(key).c_str()) * SRS_UTIME_SECONDS)
|
||||||
#define SRS_OVERWRITE_BY_ENV_FLOAT_MILLISECONDS(key) if (!srs_getenv(key).empty()) return srs_utime_t(::atof(srs_getenv(key).c_str()) * SRS_UTIME_MILLISECONDS)
|
#define SRS_OVERWRITE_BY_ENV_FLOAT_MILLISECONDS(key) if (!srs_getenv(key).empty()) return srs_utime_t(::atof(srs_getenv(key).c_str()) * SRS_UTIME_MILLISECONDS)
|
||||||
|
#define SRS_OVERWRITE_BY_ENV_DIRECTIVE(key) { \
|
||||||
|
static SrsConfDirective* dir = NULL; \
|
||||||
|
if (!dir && !srs_getenv(key).empty()) { \
|
||||||
|
string v = srs_getenv(key); \
|
||||||
|
dir = new SrsConfDirective(); \
|
||||||
|
dir->name = key; \
|
||||||
|
dir->args.push_back(v); \
|
||||||
|
} \
|
||||||
|
if (dir) return dir; \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dumps the ingest/transcode-engine in @param dir to amf0 object @param engine.
|
* dumps the ingest/transcode-engine in @param dir to amf0 object @param engine.
|
||||||
|
@ -5359,6 +5369,8 @@ SrsConfDirective* SrsConfig::get_vhost_http_hooks(string vhost)
|
||||||
|
|
||||||
bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
|
bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_BOOL("srs.vhost.http_hooks.enabled"); // SRS_VHOST_HTTP_HOOKS_ENABLED
|
||||||
|
|
||||||
static bool DEFAULT = false;
|
static bool DEFAULT = false;
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
@ -5371,6 +5383,8 @@ bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
|
||||||
|
|
||||||
bool SrsConfig::get_vhost_http_hooks_enabled(SrsConfDirective* vhost)
|
bool SrsConfig::get_vhost_http_hooks_enabled(SrsConfDirective* vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_BOOL("srs.vhost.http_hooks.enabled"); // SRS_VHOST_HTTP_HOOKS_ENABLED
|
||||||
|
|
||||||
static bool DEFAULT = false;
|
static bool DEFAULT = false;
|
||||||
|
|
||||||
SrsConfDirective* conf = vhost->get("http_hooks");
|
SrsConfDirective* conf = vhost->get("http_hooks");
|
||||||
|
@ -5388,6 +5402,8 @@ bool SrsConfig::get_vhost_http_hooks_enabled(SrsConfDirective* vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_connect"); // SRS_VHOST_HTTP_HOOKS_ON_CONNECT
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5398,6 +5414,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_close"); // SRS_VHOST_HTTP_HOOKS_ON_CLOSE
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5408,6 +5426,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_publish"); // SRS_VHOST_HTTP_HOOKS_ON_PUBLISH
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5418,6 +5438,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_unpublish"); // SRS_VHOST_HTTP_HOOKS_ON_UNPUBLISH
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5428,6 +5450,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_play"); // SRS_VHOST_HTTP_HOOKS_ON_PLAY
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5438,6 +5462,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_stop"); // SRS_VHOST_HTTP_HOOKS_ON_STOP
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5448,6 +5474,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_dvr"); // SRS_VHOST_HTTP_HOOKS_ON_DVR
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5458,6 +5486,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_hls(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_hls(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_hls"); // SRS_VHOST_HTTP_HOOKS_ON_HLS
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5468,6 +5498,8 @@ SrsConfDirective* SrsConfig::get_vhost_on_hls(string vhost)
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost_on_hls_notify(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost_on_hls_notify(string vhost)
|
||||||
{
|
{
|
||||||
|
SRS_OVERWRITE_BY_ENV_DIRECTIVE("srs.vhost.http_hooks.on_hls_notify"); // SRS_VHOST_HTTP_HOOKS_ON_HLS_NOTIFY
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
SrsConfDirective* conf = get_vhost_http_hooks(vhost);
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 5
|
#define VERSION_MAJOR 5
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 131
|
#define VERSION_REVISION 132
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3937,8 +3937,6 @@ VOID TEST(ConfigMainTest, SrtServerTlpktDrop)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesGlobal)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesGlobal)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4035,8 +4033,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesGlobal)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesthreads)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesthreads)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4047,8 +4043,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesthreads)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesRtmp)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesRtmp)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4082,8 +4076,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesRtmp)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpApi)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpApi)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4126,8 +4118,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHttpApi)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpServer)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpServer)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4163,8 +4153,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHttpServer)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesSrtServer)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesSrtServer)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4220,8 +4208,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesSrtServer)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostSrt)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostSrt)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4235,8 +4221,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesVhostSrt)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesRtcServer)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesRtcServer)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4303,8 +4287,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesRtcServer)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostRtc)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostRtc)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4362,8 +4344,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesVhostRtc)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPlay)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPlay)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4433,8 +4413,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPlay)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPublish)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPublish)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4460,8 +4438,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesVhostPublish)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesCircuitBreaker)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesCircuitBreaker)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4490,8 +4466,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesCircuitBreaker)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudCls)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudCls)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4539,8 +4513,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudCls)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudApm)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudApm)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4566,8 +4538,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudApm)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesExporter)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesExporter)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4587,8 +4557,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesExporter)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHeartbeat)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHeartbeat)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4611,8 +4579,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHeartbeat)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesScope)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesScope)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4646,8 +4612,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesScope)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpStatic)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpStatic)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4664,8 +4628,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHttpStatic)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpRemux)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHttpRemux)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
|
@ -4722,8 +4684,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHttpRemux)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesDash)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesDash)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4776,8 +4736,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHds)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesDvr)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesDvr)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4806,8 +4764,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesDvr)
|
||||||
|
|
||||||
VOID TEST(ConfigEnvTest, CheckEnvValuesHls)
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHls)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
MockSrsConfig conf;
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
@ -4887,3 +4843,70 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHls)
|
||||||
EXPECT_FALSE(conf.get_vhost_hls_dts_directly("__defaultVhost__"));
|
EXPECT_FALSE(conf.get_vhost_hls_dts_directly("__defaultVhost__"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(ConfigEnvTest, CheckEnvValuesHooks)
|
||||||
|
{
|
||||||
|
MockSrsConfig conf;
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ENABLED", "on");
|
||||||
|
EXPECT_TRUE(conf.get_vhost_http_hooks_enabled("__defaultVhost__"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_PUBLISH", "http://server/api/publish");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_publish("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/publish", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_UNPUBLISH", "http://server/api/unpublish");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_unpublish("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/unpublish", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_PLAY", "http://server/api/play");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_play("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/play", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_STOP", "http://server/api/stop");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_stop("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/stop", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_DVR", "http://server/api/dvr");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_dvr("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/dvr", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_HLS", "http://server/api/hls");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_hls("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/hls", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsSetEnvConfig(hooks, "SRS_VHOST_HTTP_HOOKS_ON_HLS_NOTIFY", "http://server/api/hls_notify");
|
||||||
|
SrsConfDirective* dir = conf.get_vhost_on_hls_notify("__defaultVhost__");
|
||||||
|
ASSERT_TRUE(dir != NULL);
|
||||||
|
ASSERT_TRUE((int)dir->args.size() == 1);
|
||||||
|
ASSERT_STREQ("http://server/api/hls_notify", dir->arg0().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue