@ -3,25 +3,29 @@ package httpopera
@@ -3,25 +3,29 @@ package httpopera
import (
"encoding/json"
"fmt"
"io"
"log"
"net"
"net/http"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/rtmp"
"github.com/gwuhaolin/livego/protocol/rtmp/rtmprelay"
"livego/av"
"livego/configure"
"livego/protocol/rtmp"
"livego/protocol/rtmp/rtmprelay"
jwtmiddleware "github.com/auth0/go-jwt-middleware"
"github.com/dgrijalva/jwt-go"
)
type Response struct {
w http . ResponseWriter
Status int ` json:"status" `
Message string ` json:"message "`
w http . ResponseWriter
Status int ` json:"status" `
Data interface { } ` json:"data "`
}
func ( r * Response ) SendJson ( ) ( int , error ) {
resp , _ := json . Marshal ( r )
r . w . Header ( ) . Set ( "Content-Type" , "application/json" )
r . w . WriteHeader ( r . Status )
return r . w . Write ( resp )
}
@ -58,10 +62,38 @@ func NewServer(h av.Handler, rtmpAddr string) *Server {
@@ -58,10 +62,38 @@ func NewServer(h av.Handler, rtmpAddr string) *Server {
}
}
func JWTMiddleware ( next http . Handler ) http . Handler {
return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if len ( configure . RtmpServercfg . JWTCfg . Secret ) > 0 {
var algorithm jwt . SigningMethod
if len ( configure . RtmpServercfg . JWTCfg . Algorithm ) > 0 {
algorithm = jwt . GetSigningMethod ( configure . RtmpServercfg . JWTCfg . Algorithm )
}
if algorithm == nil {
algorithm = jwt . SigningMethodHS256
}
jwtMiddleware := jwtmiddleware . New ( jwtmiddleware . Options {
Extractor : jwtmiddleware . FromFirst ( jwtmiddleware . FromAuthHeader , jwtmiddleware . FromParameter ( "jwt" ) ) ,
ValidationKeyGetter : func ( token * jwt . Token ) ( interface { } , error ) {
return [ ] byte ( configure . RtmpServercfg . Secret ) , nil
} ,
SigningMethod : algorithm ,
} )
jwtMiddleware . HandlerWithNext ( w , r , next . ServeHTTP )
return
}
next . ServeHTTP ( w , r )
} )
}
func ( s * Server ) Serve ( l net . Listener ) error {
mux := http . NewServeMux ( )
mux . Handle ( "/statics" , http . FileServer ( http . Dir ( "statics" ) ) )
mux . Handle ( "/statics/" , http . StripPrefix ( "/statics/ " , http . FileServer ( http . Dir ( "statics" ) ) ) )
mux . HandleFunc ( "/control/push" , func ( w http . ResponseWriter , r * http . Request ) {
s . handlePush ( w , r )
@ -69,21 +101,30 @@ func (s *Server) Serve(l net.Listener) error {
@@ -69,21 +101,30 @@ func (s *Server) Serve(l net.Listener) error {
mux . HandleFunc ( "/control/pull" , func ( w http . ResponseWriter , r * http . Request ) {
s . handlePull ( w , r )
} )
mux . HandleFunc ( "/control/get" , func ( w http . ResponseWriter , r * http . Request ) {
s . handleGet ( w , r )
} )
mux . HandleFunc ( "/control/reset" , func ( w http . ResponseWriter , r * http . Request ) {
s . handleReset ( w , r )
} )
mux . HandleFunc ( "/control/delete" , func ( w http . ResponseWriter , r * http . Request ) {
s . handleDelete ( w , r )
} )
mux . HandleFunc ( "/stat/livestat" , func ( w http . ResponseWriter , r * http . Request ) {
s . GetLiveStatics ( w , r )
} )
http . Serve ( l , mux )
http . Serve ( l , JWTMiddleware ( mux ) )
return nil
}
type stream struct {
Key string ` json:"key" `
Url string ` json:"U rl" `
StreamId uint32 ` json:"StreamI d" `
VideoTotalBytes uint64 ` json:123456 `
VideoSpeed uint64 ` json:123456 `
AudioTotalBytes uint64 ` json:123456 `
AudioSpeed uint64 ` json:123456 `
Url string ` json:"u rl" `
StreamId uint32 ` json:"stream_i d" `
VideoTotalBytes uint64 ` json:"video_total_bytes" `
VideoSpeed uint64 ` json:"video_speed" `
AudioTotalBytes uint64 ` json:"audio_total_bytes" `
AudioSpeed uint64 ` json:"audio_speed" `
}
type streams struct {
@ -93,9 +134,18 @@ type streams struct {
@@ -93,9 +134,18 @@ type streams struct {
//http://127.0.0.1:8090/stat/livestat
func ( server * Server ) GetLiveStatics ( w http . ResponseWriter , req * http . Request ) {
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
rtmpStream := server . handler . ( * rtmp . RtmpStream )
if rtmpStream == nil {
io . WriteString ( w , "<h1>Get rtmp stream information error</h1>" )
res . Status = 500
res . Data = "Get rtmp stream information error"
return
}
@ -130,17 +180,29 @@ func (server *Server) GetLiveStatics(w http.ResponseWriter, req *http.Request) {
@@ -130,17 +180,29 @@ func (server *Server) GetLiveStatics(w http.ResponseWriter, req *http.Request) {
}
}
}
resp , _ := json . Marshal ( msgs )
w . Header ( ) . Set ( "Content-Type" , "application/json" )
w . Write ( resp )
res . Data = resp
}
//http://127.0.0.1:8090/control/push ?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456
//http://127.0.0.1:8090/control/pull ?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456
func ( s * Server ) handlePull ( w http . ResponseWriter , req * http . Request ) {
var retString string
var err error
req . ParseForm ( )
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
if req . ParseForm ( ) != nil {
res . Status = 400
res . Data = "url: /control/pull?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456"
return
}
oper := req . Form [ "oper" ]
app := req . Form [ "app" ]
@ -149,7 +211,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
@@ -149,7 +211,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
log . Printf ( "control pull: oper=%v, app=%v, name=%v, url=%v" , oper , app , name , url )
if ( len ( app ) <= 0 ) || ( len ( name ) <= 0 ) || ( len ( url ) <= 0 ) {
io . WriteString ( w , "control push parameter error, please check them.</br>" )
res . Status = 400
res . Data = "control push parameter error, please check them."
return
}
@ -162,7 +225,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
@@ -162,7 +225,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
if ! found {
retString = fmt . Sprintf ( "session key[%s] not exist, please check it again." , keyString )
io . WriteString ( w , retString )
res . Status = 400
res . Data = retString
return
}
log . Printf ( "rtmprelay stop push %s from %s" , remoteurl , localurl )
@ -170,7 +234,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
@@ -170,7 +234,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
delete ( s . session , keyString )
retString = fmt . Sprintf ( "<h1>push url stop %s ok</h1></br>" , url [ 0 ] )
io . WriteString ( w , retString )
res . Status = 400
res . Data = retString
log . Printf ( "pull stop return %s" , retString )
} else {
pullRtmprelay := rtmprelay . NewRtmpRelay ( & localurl , & remoteurl )
@ -182,7 +247,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
@@ -182,7 +247,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
s . session [ keyString ] = pullRtmprelay
retString = fmt . Sprintf ( "<h1>push url start %s ok</h1></br>" , url [ 0 ] )
}
io . WriteString ( w , retString )
res . Status = 400
res . Data = retString
log . Printf ( "pull start return %s" , retString )
}
}
@ -192,7 +258,18 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
@@ -192,7 +258,18 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
var retString string
var err error
req . ParseForm ( )
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
if req . ParseForm ( ) != nil {
res . Data = "url: /control/push?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456"
return
}
oper := req . Form [ "oper" ]
app := req . Form [ "app" ]
@ -201,7 +278,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
@@ -201,7 +278,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
log . Printf ( "control push: oper=%v, app=%v, name=%v, url=%v" , oper , app , name , url )
if ( len ( app ) <= 0 ) || ( len ( name ) <= 0 ) || ( len ( url ) <= 0 ) {
io . WriteString ( w , "control push parameter error, please check them.</br>" )
res . Data = "control push parameter error, please check them."
return
}
@ -213,7 +290,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
@@ -213,7 +290,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
pushRtmprelay , found := s . session [ keyString ]
if ! found {
retString = fmt . Sprintf ( "<h1>session key[%s] not exist, please check it again.</h1>" , keyString )
io . WriteString ( w , retString )
res . Data = retString
return
}
log . Printf ( "rtmprelay stop push %s from %s" , remoteurl , localurl )
@ -221,7 +298,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
@@ -221,7 +298,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
delete ( s . session , keyString )
retString = fmt . Sprintf ( "<h1>push url stop %s ok</h1></br>" , url [ 0 ] )
io . WriteString ( w , retString )
res . Data = retString
log . Printf ( "push stop return %s" , retString )
} else {
pushRtmprelay := rtmprelay . NewRtmpRelay ( & localurl , & remoteurl )
@ -234,7 +311,101 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
@@ -234,7 +311,101 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
s . session [ keyString ] = pushRtmprelay
}
io . WriteString ( w , retString )
res . Data = retString
log . Printf ( "push start return %s" , retString )
}
}
//http://127.0.0.1:8090/control/reset?room=ROOM_NAME
func ( s * Server ) handleReset ( w http . ResponseWriter , r * http . Request ) {
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
if err := r . ParseForm ( ) ; err != nil {
res . Status = 400
res . Data = "url: /control/reset?room=ROOM_NAME"
return
}
room := r . Form . Get ( "room" )
if len ( room ) == 0 {
res . Status = 400
res . Data = "url: /control/get?room=ROOM_NAME"
return
}
msg , err := configure . RoomKeys . SetKey ( room )
if err != nil {
msg = err . Error ( )
res . Status = 400
}
res . Data = msg
}
//http://127.0.0.1:8090/control/get?room=ROOM_NAME
func ( s * Server ) handleGet ( w http . ResponseWriter , r * http . Request ) {
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
if err := r . ParseForm ( ) ; err != nil {
res . Status = 400
res . Data = "url: /control/get?room=ROOM_NAME"
return
}
room := r . Form . Get ( "room" )
if len ( room ) == 0 {
res . Status = 400
res . Data = "url: /control/get?room=ROOM_NAME"
return
}
msg , err := configure . RoomKeys . GetKey ( room )
if err != nil {
msg = err . Error ( )
res . Status = 400
}
res . Data = msg
}
//http://127.0.0.1:8090/control/delete?room=ROOM_NAME
func ( s * Server ) handleDelete ( w http . ResponseWriter , r * http . Request ) {
res := & Response {
w : w ,
Data : nil ,
Status : 200 ,
}
defer res . SendJson ( )
if err := r . ParseForm ( ) ; err != nil {
res . Status = 400
res . Data = "url: /control/delete?room=ROOM_NAME"
return
}
room := r . Form . Get ( "room" )
if len ( room ) == 0 {
res . Status = 400
res . Data = "url: /control/get?room=ROOM_NAME"
return
}
if configure . RoomKeys . DeleteChannel ( room ) {
res . Data = "Ok"
return
}
res . Status = 404
res . Data = "Room not found"
}