mirror of
https://github.com/aler9/gortsplib
synced 2025-10-09 00:50:24 +08:00
add automatic authentication
This commit is contained in:
@@ -13,6 +13,12 @@ type ConnClientConf struct {
|
|||||||
// pre-existing TCP connection that will be wrapped
|
// pre-existing TCP connection that will be wrapped
|
||||||
NConn net.Conn
|
NConn net.Conn
|
||||||
|
|
||||||
|
// (optional) a username to authenticate with the server
|
||||||
|
Username string
|
||||||
|
|
||||||
|
// (optional) a password to authenticate with the server
|
||||||
|
Password string
|
||||||
|
|
||||||
// (optional) timeout for read requests.
|
// (optional) timeout for read requests.
|
||||||
// It defaults to 5 seconds
|
// It defaults to 5 seconds
|
||||||
ReadTimeout time.Duration
|
ReadTimeout time.Duration
|
||||||
@@ -41,7 +47,7 @@ type ConnClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewConnClient allocates a ConnClient. See ConnClientConf for the options.
|
// NewConnClient allocates a ConnClient. See ConnClientConf for the options.
|
||||||
func NewConnClient(conf ConnClientConf) *ConnClient {
|
func NewConnClient(conf ConnClientConf) (*ConnClient, error) {
|
||||||
if conf.ReadTimeout == time.Duration(0) {
|
if conf.ReadTimeout == time.Duration(0) {
|
||||||
conf.ReadTimeout = 5 * time.Second
|
conf.ReadTimeout = 5 * time.Second
|
||||||
}
|
}
|
||||||
@@ -55,11 +61,16 @@ func NewConnClient(conf ConnClientConf) *ConnClient {
|
|||||||
conf.WriteBufferSize = 4096
|
conf.WriteBufferSize = 4096
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.Username != "" && conf.Password == "" ||
|
||||||
|
conf.Username == "" && conf.Password != "" {
|
||||||
|
return nil, fmt.Errorf("both username and password must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
return &ConnClient{
|
return &ConnClient{
|
||||||
conf: conf,
|
conf: conf,
|
||||||
br: bufio.NewReaderSize(conf.NConn, conf.ReadBufferSize),
|
br: bufio.NewReaderSize(conf.NConn, conf.ReadBufferSize),
|
||||||
bw: bufio.NewWriterSize(conf.NConn, conf.WriteBufferSize),
|
bw: bufio.NewWriterSize(conf.NConn, conf.WriteBufferSize),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetConn returns the underlying net.Conn.
|
// NetConn returns the underlying net.Conn.
|
||||||
@@ -67,14 +78,6 @@ func (c *ConnClient) NetConn() net.Conn {
|
|||||||
return c.conf.NConn
|
return c.conf.NConn
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
// WriteRequest writes a request and reads a response.
|
||||||
func (c *ConnClient) WriteRequest(req *Request) (*Response, error) {
|
func (c *ConnClient) WriteRequest(req *Request) (*Response, error) {
|
||||||
if req.Header == nil {
|
if req.Header == nil {
|
||||||
@@ -108,14 +111,24 @@ func (c *ConnClient) WriteRequest(req *Request) (*Response, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get session from response
|
// get session from response
|
||||||
if res.StatusCode == StatusOK {
|
if sxRaw, ok := res.Header["Session"]; ok && len(sxRaw) == 1 {
|
||||||
if sxRaw, ok := res.Header["Session"]; ok && len(sxRaw) == 1 {
|
sx, err := ReadHeaderSession(sxRaw[0])
|
||||||
sx, err := ReadHeaderSession(sxRaw[0])
|
if err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("unable to parse session header: %s", err)
|
||||||
return nil, fmt.Errorf("unable to parse session header: %s", err)
|
|
||||||
}
|
|
||||||
c.session = sx.Session
|
|
||||||
}
|
}
|
||||||
|
c.session = sx.Session
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup authentication
|
||||||
|
if res.StatusCode == StatusUnauthorized && c.conf.Username != "" && c.auth == nil {
|
||||||
|
auth, err := NewAuthClient(res.Header["WWW-Authenticate"], c.conf.Username, c.conf.Password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to setup authentication: %s", err)
|
||||||
|
}
|
||||||
|
c.auth = auth
|
||||||
|
|
||||||
|
// send request again
|
||||||
|
return c.WriteRequest(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
|
@@ -59,6 +59,9 @@ const (
|
|||||||
StatusProxyUnavailable StatusCode = 553
|
StatusProxyUnavailable StatusCode = 553
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// StatusMessages contains the status messages associated with each status code.
|
||||||
|
var StatusMessages = statusMessages
|
||||||
|
|
||||||
var statusMessages = map[StatusCode]string{
|
var statusMessages = map[StatusCode]string{
|
||||||
StatusContinue: "Continue",
|
StatusContinue: "Continue",
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user