mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
client: fix '401 Unauthorized' error with some Hikvision cameras
when automatically switching protocol
This commit is contained in:
19
client.go
19
client.go
@@ -206,6 +206,7 @@ type Client struct {
|
|||||||
sender *auth.Sender
|
sender *auth.Sender
|
||||||
cseq int
|
cseq int
|
||||||
useGetParameter bool
|
useGetParameter bool
|
||||||
|
lastDescribeURL *base.URL
|
||||||
streamBaseURL *base.URL
|
streamBaseURL *base.URL
|
||||||
protocol *Transport
|
protocol *Transport
|
||||||
tracks map[int]clientTrack
|
tracks map[int]clientTrack
|
||||||
@@ -657,6 +658,12 @@ func (c *Client) trySwitchingProtocol() error {
|
|||||||
c.scheme = prevBaseURL.Scheme
|
c.scheme = prevBaseURL.Scheme
|
||||||
c.host = prevBaseURL.Host
|
c.host = prevBaseURL.Host
|
||||||
|
|
||||||
|
// some Hikvision cameras require a describe before a setup
|
||||||
|
_, _, _, err := c.doDescribe(c.lastDescribeURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, track := range prevTracks {
|
for _, track := range prevTracks {
|
||||||
_, err := c.doSetup(true, track.track, prevBaseURL, 0, 0)
|
_, err := c.doSetup(true, track.track, prevBaseURL, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -664,7 +671,7 @@ func (c *Client) trySwitchingProtocol() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := c.doPlay(c.lastRange, true)
|
_, err = c.doPlay(c.lastRange, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -905,15 +912,15 @@ func (c *Client) do(req *base.Request, skipResponse bool) (*base.Response, error
|
|||||||
req.Header["Session"] = base.HeaderValue{c.session}
|
req.Header["Session"] = base.HeaderValue{c.session}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.sender != nil {
|
|
||||||
c.sender.AddAuthorization(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.cseq++
|
c.cseq++
|
||||||
req.Header["CSeq"] = base.HeaderValue{strconv.FormatInt(int64(c.cseq), 10)}
|
req.Header["CSeq"] = base.HeaderValue{strconv.FormatInt(int64(c.cseq), 10)}
|
||||||
|
|
||||||
req.Header["User-Agent"] = base.HeaderValue{"gortsplib"}
|
req.Header["User-Agent"] = base.HeaderValue{"gortsplib"}
|
||||||
|
|
||||||
|
if c.sender != nil {
|
||||||
|
c.sender.AddAuthorization(req)
|
||||||
|
}
|
||||||
|
|
||||||
if c.OnRequest != nil {
|
if c.OnRequest != nil {
|
||||||
c.OnRequest(req)
|
c.OnRequest(req)
|
||||||
}
|
}
|
||||||
@@ -1136,6 +1143,8 @@ func (c *Client) doDescribe(u *base.URL) (Tracks, *base.URL, *base.Response, err
|
|||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.lastDescribeURL = u
|
||||||
|
|
||||||
return tracks, baseURL, res, nil
|
return tracks, baseURL, res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1249,6 +1249,21 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
br = bufio.NewReader(conn)
|
br = bufio.NewReader(conn)
|
||||||
|
|
||||||
|
req, err = readRequest(br)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
|
base.Response{
|
||||||
|
StatusCode: base.StatusOK,
|
||||||
|
Header: base.Header{
|
||||||
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
|
"Content-Base": base.HeaderValue{"rtsp://localhost:8554/teststream/"},
|
||||||
|
},
|
||||||
|
Body: tracks.Write(false),
|
||||||
|
}.Write(&bb)
|
||||||
|
_, err = conn.Write(bb.Bytes())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
req, err = readRequest(br)
|
req, err = readRequest(br)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Setup, req.Method)
|
require.Equal(t, base.Setup, req.Method)
|
||||||
|
Reference in New Issue
Block a user