Repository: bluenviron/gortsplib
Pull request #619 (2024-09-15 18:09:12)

server: fix compatibility with rtspclientsink and query parameters (bluenviron/mediamtx#3295)
Fixes bluenviron/mediamtx#3295

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/bluenviron/gortsplib/pull/619?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) Report
Attention: Patch coverage is `87.50000%` with `4 lines` in your changes missing coverage. Please review.
> Project coverage is 81.86%. Comparing base [(`2023bf1`)](https://app.codecov.io/gh/bluenviron/gortsplib/commit/2023bf1b0028d6d74504f83a63be13e546117d96?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) to head [(`08b0e45`)](https://app.codecov.io/gh/bluenviron/gortsplib/commit/08b0e45f7d883f3cda569b0b014b406103e0e7b6?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).

| [Files with missing lines](https://app.codecov.io/gh/bluenviron/gortsplib/pull/619?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) | Patch % | Lines |
|---|---|---|
| [server\_session.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/619?src=pr&el=tree&filepath=server_session.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-c2VydmVyX3Nlc3Npb24uZ28=) | 87.50% | [3 Missing and 1 partial :warning: ](https://app.codecov.io/gh/bluenviron/gortsplib/pull/619?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #619      +/-   ##
==========================================
- Coverage   81.88%   81.86%   -0.02%     
==========================================
  Files         115      115              
  Lines       11625    11637      +12     
==========================================
+ Hits         9519     9527       +8     
- Misses       1703     1706       +3     
- Partials      403      404       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/bluenviron/gortsplib/pull/619?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).


Patch:
diff --git a/server_session.go b/server_session.go
index c8760388..08793061 100644
--- a/server_session.go
+++ b/server_session.go
@@ -56,28 +56,45 @@ func serverParseURLForPlay(u *base.URL) (string, string, string, error) {
 	return path, query, trackID, nil
 }
 
-func recordBaseURL(u *base.URL, path string, query string) *base.URL {
-	baseURL := &base.URL{
-		Scheme:   u.Scheme,
-		Host:     u.Host,
-		Path:     path,
-		RawQuery: query,
-	}
-
-	if baseURL.RawQuery != "" {
-		baseURL.RawQuery += "/"
-	} else {
-		baseURL.Path += "/"
-	}
-
-	return baseURL
-}
-
-func findMediaByURL(medias []*description.Media, baseURL *base.URL, u *base.URL) *description.Media {
+func findMediaByURL(
+	medias []*description.Media,
+	path string,
+	query string,
+	u *base.URL,
+) *description.Media {
 	for _, media := range medias {
-		u1, err := media.URL(baseURL)
-		if err == nil && u1.String() == u.String() {
-			return media
+		if strings.HasPrefix(media.Control, "rtsp://") ||
+			strings.HasPrefix(media.Control, "rtsps://") {
+			if media.Control == u.String() {
+				return media
+			}
+		} else {
+			// FFmpeg format
+			u1 := &base.URL{
+				Scheme:   u.Scheme,
+				Host:     u.Host,
+				Path:     path,
+				RawQuery: query,
+			}
+			if query != "" {
+				u1.RawQuery += "/" + media.Control
+			} else {
+				u1.Path += "/" + media.Control
+			}
+			if u1.String() == u.String() {
+				return media
+			}
+
+			// GStreamer format
+			u2 := &base.URL{
+				Scheme:   u.Scheme,
+				Host:     u.Host,
+				Path:     path + "/" + media.Control,
+				RawQuery: query,
+			}
+			if u2.String() == u.String() {
+				return media
+			}
 		}
 	}
 
@@ -775,7 +792,7 @@ func (ss *ServerSession) handleRequestInner(sc *ServerConn, req *base.Request) (
 		case ServerSessionStateInitial, ServerSessionStatePrePlay: // play
 			medi = findMediaByTrackID(stream.desc.Medias, trackID)
 		default: // record
-			medi = findMediaByURL(ss.announcedDesc.Medias, recordBaseURL(req.URL, path, query), req.URL)
+			medi = findMediaByURL(ss.announcedDesc.Medias, path, query, req.URL)
 		}
 
 		if medi == nil {


Test patch:
diff --git a/server_record_test.go b/server_record_test.go
index 9cc5acd6..683f127d 100644
--- a/server_record_test.go
+++ b/server_record_test.go
@@ -298,13 +298,21 @@ func TestServerRecordPath(t *testing.T) {
 			"",
 		},
 		{
-			"subpath and query",
+			"subpath and query, ffmpeg format",
 			"fff=ggg",
 			"rtsp://localhost:8554/test/stream?testing=0",
 			"rtsp://localhost:8554/test/stream?testing=0/fff=ggg",
 			"/test/stream",
 			"testing=0",
 		},
+		{
+			"subpath and query, gstreamer format",
+			"fff=ggg",
+			"rtsp://localhost:8554/test/stream?testing=0",
+			"rtsp://localhost:8554/test/stream/fff=ggg?testing=0",
+			"/test/stream",
+			"testing=0",
+		},
 		{
 			"no path",
 			"streamid=1",