BogdanovKirill / RtspClientSharp

Pure C# RTSP client for .NET Standard without external dependencies and with true async nature. I welcome contributions.
MIT License
713 stars 286 forks source link

BadRequest answer when sending RTSP SETUP request to camera #110

Open perkasthor opened 3 years ago

perkasthor commented 3 years ago

Description When trying to connect a recently updated Vivotek camera, I get a "Bad Request" answer from the camera. After downloading and debugging the code, I saw that this happened during the RTSP SETUP request. Using Wireshark, I compared the requests from RtspClientSharp and "ONVIF Device Manager" software, and indeed, the requests are different. It appears that RtspClientSharp does not support URIs containing queries when appending track name:

I've modified the code to support appending track name to either the URI path or query, see my modification below. File: RtspRequestMessageFactory.cs Code modification (end of file)

private Uri GetTrackUri(string trackName)
{
    Uri trackUri;

    if (!Uri.IsWellFormedUriString(trackName, UriKind.Absolute))
    {
        var uriBuilder = new UriBuilder(GetContentBasedUri());

        // old
        //bool trackNameStartsWithSlash = trackName.StartsWith("/");
        //if (uriBuilder.Path.EndsWith("/"))
        //    uriBuilder.Path += trackNameStartsWithSlash ? trackName.Substring(1) : trackName;
        //else
        //    uriBuilder.Path += trackNameStartsWithSlash ? trackName : "/" + trackName;

        // new
        if (string.IsNullOrWhiteSpace(uriBuilder.Query))
            uriBuilder.Path = AppendTrackToUri(uriBuilder.Path, trackName);
        else
            uriBuilder.Query = AppendTrackToUri(uriBuilder.Query, trackName);

        trackUri = uriBuilder.Uri;
    }
    else
        trackUri = new Uri(trackName, UriKind.Absolute);

    return trackUri;
}

private static string AppendTrackToUri(string uriPart, string trackName)
{
    bool trackNameStartsWithSlash = trackName.StartsWith("/");

    if (uriPart.EndsWith("/"))
        return uriPart + (trackNameStartsWithSlash ? trackName.Substring(1) : trackName);
    return uriPart + (trackNameStartsWithSlash ? trackName : "/" + trackName);
}

Fell free to integrate this change in the source code. I'm new to GitHub and don't want to mess with this depot ;)