mirror of
https://github.com/aler9/gortsplib
synced 2025-10-16 12:10:48 +08:00
126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package gortsplib
|
|
|
|
import (
|
|
"bufio"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// ConnClientConf allows to configure a ConnClient.
|
|
type ConnClientConf struct {
|
|
// pre-existing TCP connection that will be wrapped
|
|
NConn net.Conn
|
|
|
|
// (optional) timeout for read requests.
|
|
// It defaults to 5 seconds
|
|
ReadTimeout time.Duration
|
|
|
|
// (optional) timeout for write requests.
|
|
// It defaults to 5 seconds
|
|
WriteTimeout time.Duration
|
|
|
|
// (optional) size of the read buffer.
|
|
// It defaults to 4096 bytes
|
|
ReadBufferSize int
|
|
|
|
// (optional) size of the write buffer.
|
|
// It defaults to 4096 bytes
|
|
WriteBufferSize int
|
|
}
|
|
|
|
// ConnClient is a client-side RTSP connection.
|
|
type ConnClient struct {
|
|
conf ConnClientConf
|
|
br *bufio.Reader
|
|
bw *bufio.Writer
|
|
session string
|
|
curCSeq int
|
|
auth *AuthClient
|
|
}
|
|
|
|
// NewConnClient allocates a ConnClient. See ConnClientConf for the options.
|
|
func NewConnClient(conf ConnClientConf) *ConnClient {
|
|
if conf.ReadTimeout == time.Duration(0) {
|
|
conf.ReadTimeout = 5 * time.Second
|
|
}
|
|
if conf.WriteTimeout == time.Duration(0) {
|
|
conf.WriteTimeout = 5 * time.Second
|
|
}
|
|
if conf.ReadBufferSize == 0 {
|
|
conf.ReadBufferSize = 4096
|
|
}
|
|
if conf.WriteBufferSize == 0 {
|
|
conf.WriteBufferSize = 4096
|
|
}
|
|
|
|
return &ConnClient{
|
|
conf: conf,
|
|
br: bufio.NewReaderSize(conf.NConn, conf.ReadBufferSize),
|
|
bw: bufio.NewWriterSize(conf.NConn, conf.WriteBufferSize),
|
|
}
|
|
}
|
|
|
|
// NetConn returns the underlying net.Conn.
|
|
func (c *ConnClient) NetConn() net.Conn {
|
|
return c.conf.NConn
|
|
}
|
|
|
|
// SetSession sets a Session header that is automatically inserted into every outgoing request.
|
|
func (c *ConnClient) SetSession(v string) {
|
|
c.session = v
|
|
}
|
|
|
|
// SetCredentials allows to automatically insert the Authenticate header into every outgoing request.
|
|
// The content of the header is computed with the given user, password, realm and nonce.
|
|
func (c *ConnClient) SetCredentials(wwwAuthenticateHeader []string, user string, pass string) error {
|
|
var err error
|
|
c.auth, err = NewAuthClient(wwwAuthenticateHeader, user, pass)
|
|
return err
|
|
}
|
|
|
|
// WriteRequest writes a request and reads a response.
|
|
func (c *ConnClient) WriteRequest(req *Request) (*Response, error) {
|
|
if c.session != "" {
|
|
if req.Header == nil {
|
|
req.Header = make(Header)
|
|
}
|
|
req.Header["Session"] = []string{c.session}
|
|
}
|
|
|
|
if c.auth != nil {
|
|
if req.Header == nil {
|
|
req.Header = make(Header)
|
|
}
|
|
req.Header["Authorization"] = c.auth.GenerateHeader(req.Method, req.Url)
|
|
}
|
|
|
|
// automatically insert CSeq
|
|
if req.Header == nil {
|
|
req.Header = make(Header)
|
|
}
|
|
c.curCSeq += 1
|
|
req.Header["CSeq"] = []string{strconv.FormatInt(int64(c.curCSeq), 10)}
|
|
|
|
c.conf.NConn.SetWriteDeadline(time.Now().Add(c.conf.WriteTimeout))
|
|
err := req.write(c.bw)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
|
|
return readResponse(c.br)
|
|
}
|
|
|
|
// ReadInterleavedFrame reads an InterleavedFrame.
|
|
func (c *ConnClient) ReadInterleavedFrame() (*InterleavedFrame, error) {
|
|
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
|
|
return readInterleavedFrame(c.br)
|
|
}
|
|
|
|
// WriteInterleavedFrame writes an InterleavedFrame.
|
|
func (c *ConnClient) WriteInterleavedFrame(frame *InterleavedFrame) error {
|
|
c.conf.NConn.SetWriteDeadline(time.Now().Add(c.conf.WriteTimeout))
|
|
return frame.write(c.bw)
|
|
}
|