@ -218,23 +218,18 @@ func (c *serverClient) writeResDeadline(res *gortsplib.Response) {
@@ -218,23 +218,18 @@ func (c *serverClient) writeResDeadline(res *gortsplib.Response) {
c . conn . WriteResponse ( res )
}
func ( c * serverClient ) writeResError ( req * gortsplib . Request , err error ) {
func ( c * serverClient ) writeResError ( req * gortsplib . Request , code gortsplib . StatusCode , err error ) {
c . log ( "ERR: %s" , err )
header := gortsplib . Header { }
if cseq , ok := req . Header [ "CSeq" ] ; ok && len ( cseq ) == 1 {
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 400 ,
Status : "Bad Request" ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
} )
} else {
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 400 ,
Status : "Bad Request" ,
} )
header [ "CSeq" ] = [ ] string { cseq [ 0 ] }
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : code ,
Header : header ,
} )
}
func ( c * serverClient ) handleRequest ( req * gortsplib . Request ) bool {
@ -242,13 +237,13 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -242,13 +237,13 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
cseq , ok := req . Header [ "CSeq" ]
if ! ok || len ( cseq ) != 1 {
c . writeResError ( req , fmt . Errorf ( "cseq missing" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "cseq missing" ) )
return false
}
ur , err := url . Parse ( req . Url )
if err != nil {
c . writeResError ( req , fmt . Errorf ( "unable to parse path '%s'" , req . Url ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "unable to parse path '%s'" , req . Url ) )
return false
}
@ -274,8 +269,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -274,8 +269,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
// in any state
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Public" : [ ] string { strings . Join ( [ ] string {
@ -293,7 +287,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -293,7 +287,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
case "DESCRIBE" :
if c . state != _CLIENT_STATE_STARTING {
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
@ -309,13 +303,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -309,13 +303,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return pub . streamSdpText , nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Content-Base" : [ ] string { req . Url } ,
@ -327,7 +320,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -327,7 +320,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
case "ANNOUNCE" :
if c . state != _CLIENT_STATE_STARTING {
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
@ -345,8 +338,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -345,8 +338,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 401 ,
Status : "Unauthorized" ,
StatusCode : gortsplib . StatusUnauthorized ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"WWW-Authenticate" : c . as . GenerateHeader ( ) ,
@ -363,18 +355,18 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -363,18 +355,18 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
ct , ok := req . Header [ "Content-Type" ]
if ! ok || len ( ct ) != 1 {
c . writeResError ( req , fmt . Errorf ( "Content-Type header missing" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "Content-Type header missing" ) )
return false
}
if ct [ 0 ] != "application/sdp" {
c . writeResError ( req , fmt . Errorf ( "unsupported Content-Type '%s'" , ct ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "unsupported Content-Type '%s'" , ct ) )
return false
}
sdpParsed , err := sdpParse ( req . Content )
if err != nil {
c . writeResError ( req , fmt . Errorf ( "invalid SDP: %s" , err ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "invalid SDP: %s" , err ) )
return false
}
@ -397,13 +389,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -397,13 +389,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
@ -413,14 +404,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -413,14 +404,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
case "SETUP" :
tsRaw , ok := req . Header [ "Transport" ]
if ! ok || len ( tsRaw ) != 1 {
c . writeResError ( req , fmt . Errorf ( "transport header missing" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header missing" ) )
return false
}
th := gortsplib . ReadHeaderTransport ( tsRaw [ 0 ] )
if _ , ok := th [ "unicast" ] ; ! ok {
c . writeResError ( req , fmt . Errorf ( "transport header does not contain unicast" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not contain unicast" ) )
return false
}
@ -440,25 +431,18 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -440,25 +431,18 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return false
} ( ) {
if _ , ok := c . p . protocols [ _STREAM_PROTOCOL_UDP ] ; ! ok {
c . log ( "ERR: udp streaming is disabled" )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 461 ,
Status : "Unsupported Transport" ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
} )
c . writeResError ( req , gortsplib . StatusUnsupportedTransport , fmt . Errorf ( "UDP streaming is disabled" ) )
return false
}
rtpPort , rtcpPort := th . GetPorts ( "client_port" )
if rtpPort == 0 || rtcpPort == 0 {
c . writeResError ( req , fmt . Errorf ( "transport header does not have valid client ports (%s)" , tsRaw [ 0 ] ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not have valid client ports (%s)" , tsRaw [ 0 ] ) )
return false
}
if c . path != "" && path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -490,13 +474,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -490,13 +474,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Transport" : [ ] string { strings . Join ( [ ] string {
@ -513,19 +496,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -513,19 +496,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
// play via TCP
} else if _ , ok := th [ "RTP/AVP/TCP" ] ; ok {
if _ , ok := c . p . protocols [ _STREAM_PROTOCOL_TCP ] ; ! ok {
c . log ( "ERR: tcp streaming is disabled" )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 461 ,
Status : "Unsupported Transport" ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
} )
c . writeResError ( req , gortsplib . StatusUnsupportedTransport , fmt . Errorf ( "TCP streaming is disabled" ) )
return false
}
if c . path != "" && path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -557,15 +533,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -557,15 +533,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
interleaved := fmt . Sprintf ( "%d-%d" , ( ( len ( c . streamTracks ) - 1 ) * 2 ) , ( ( len ( c . streamTracks ) - 1 ) * 2 ) + 1 )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Transport" : [ ] string { strings . Join ( [ ] string {
@ -579,19 +554,19 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -579,19 +554,19 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return true
} else {
c . writeResError ( req , fmt . Errorf ( "transport header does not contain a valid protocol (RTP/AVP, RTP/AVP/UDP or RTP/AVP/TCP) (%s)" , tsRaw [ 0 ] ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not contain a valid protocol (RTP/AVP, RTP/AVP/UDP or RTP/AVP/TCP) (%s)" , tsRaw [ 0 ] ) )
return false
}
// record
case _CLIENT_STATE_ANNOUNCE , _CLIENT_STATE_PRE_RECORD :
if _ , ok := th [ "mode=record" ] ; ! ok {
c . writeResError ( req , fmt . Errorf ( "transport header does not contain mode=record" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not contain mode=record" ) )
return false
}
if path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -608,20 +583,13 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -608,20 +583,13 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return false
} ( ) {
if _ , ok := c . p . protocols [ _STREAM_PROTOCOL_UDP ] ; ! ok {
c . log ( "ERR: udp streaming is disabled" )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 461 ,
Status : "Unsupported Transport" ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
} )
c . writeResError ( req , gortsplib . StatusUnsupportedTransport , fmt . Errorf ( "UDP streaming is disabled" ) )
return false
}
rtpPort , rtcpPort := th . GetPorts ( "client_port" )
if rtpPort == 0 || rtcpPort == 0 {
c . writeResError ( req , fmt . Errorf ( "transport header does not have valid client ports (%s)" , tsRaw [ 0 ] ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not have valid client ports (%s)" , tsRaw [ 0 ] ) )
return false
}
@ -647,13 +615,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -647,13 +615,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Transport" : [ ] string { strings . Join ( [ ] string {
@ -670,14 +637,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -670,14 +637,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
// record via TCP
} else if _ , ok := th [ "RTP/AVP/TCP" ] ; ok {
if _ , ok := c . p . protocols [ _STREAM_PROTOCOL_TCP ] ; ! ok {
c . log ( "ERR: tcp streaming is disabled" )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 461 ,
Status : "Unsupported Transport" ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
} ,
} )
c . writeResError ( req , gortsplib . StatusUnsupportedTransport , fmt . Errorf ( "TCP streaming is disabled" ) )
return false
}
@ -714,13 +674,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -714,13 +674,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Transport" : [ ] string { strings . Join ( [ ] string {
@ -734,23 +693,23 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -734,23 +693,23 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return true
} else {
c . writeResError ( req , fmt . Errorf ( "transport header does not contain a valid protocol (RTP/AVP, RTP/AVP/UDP or RTP/AVP/TCP) (%s)" , tsRaw [ 0 ] ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "transport header does not contain a valid protocol (RTP/AVP, RTP/AVP/UDP or RTP/AVP/TCP) (%s)" , tsRaw [ 0 ] ) )
return false
}
default :
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
case "PLAY" :
if c . state != _CLIENT_STATE_PRE_PLAY {
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
if path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -770,7 +729,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -770,7 +729,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
@ -778,8 +737,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -778,8 +737,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
// otherwise, in case of TCP connections, RTP packets could be written
// before the response
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Session" : [ ] string { "12345678" } ,
@ -826,12 +784,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -826,12 +784,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
case "PAUSE" :
if c . state != _CLIENT_STATE_PLAY {
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
if path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -842,8 +800,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -842,8 +800,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
c . p . mutex . Unlock ( )
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Session" : [ ] string { "12345678" } ,
@ -853,12 +810,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -853,12 +810,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
case "RECORD" :
if c . state != _CLIENT_STATE_PRE_RECORD {
c . writeResError ( req , fmt . Errorf ( "client is in state '%d'" , c . state ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "client is in state '%d'" , c . state ) )
return false
}
if path != c . path {
c . writeResError ( req , fmt . Errorf ( "path has changed" ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "path has changed" ) )
return false
}
@ -873,13 +830,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -873,13 +830,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return nil
} ( )
if err != nil {
c . writeResError ( req , err )
c . writeResError ( req , gortsplib . StatusBadRequest , err )
return false
}
c . writeResDeadline ( & gortsplib . Response {
StatusCode : 200 ,
Status : "OK" ,
StatusCode : gortsplib . StatusOK ,
Header : gortsplib . Header {
"CSeq" : [ ] string { cseq [ 0 ] } ,
"Session" : [ ] string { "12345678" } ,
@ -928,7 +884,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -928,7 +884,7 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
return false
default :
c . writeResError ( req , fmt . Errorf ( "unhandled method '%s'" , req . Method ) )
c . writeResError ( req , gortsplib . StatusBadRequest , fmt . Errorf ( "unhandled method '%s'" , req . Method ) )
return false
}
}