Skip to content

Commit 2feb0aa

Browse files
ossrs-aiwinlinvip
authored andcommitted
AI: HLS: Support query string in hls_key_url for JWT tokens. v7.0.120 (#4426)
1 parent 0c26a3c commit 2feb0aa

File tree

5 files changed

+71
-12
lines changed

5 files changed

+71
-12
lines changed

trunk/conf/full.conf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,8 +1540,11 @@ vhost hls.srs.com {
15401540
hls_key_file_path ./objs/nginx/html;
15411541
# the key root URL, use this can support https.
15421542
# @remark It's optional.
1543+
# @remark Supports query string for authentication tokens (e.g., JWT).
1544+
# Example: http://localhost:8080/?token=abc123&sig=xyz789
1545+
# Result in m3u8: http://localhost:8080/live/livestream-0.key?token=abc123&sig=xyz789
15431546
# Overwrite by env SRS_VHOST_HLS_HLS_KEY_URL for all vhosts.
1544-
hls_key_url https://localhost:8080;
1547+
hls_key_url http://localhost:8080/;
15451548

15461549
# Special control controls.
15471550
###########################################
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Test config for HLS encryption with query string in hls_key_url
2+
# This tests the fix for issue #4426
3+
4+
listen 1935;
5+
max_connections 1000;
6+
daemon off;
7+
srs_log_tank console;
8+
9+
http_server {
10+
enabled on;
11+
listen 8080;
12+
dir ./objs/nginx/html;
13+
}
14+
15+
vhost __defaultVhost__ {
16+
hls {
17+
enabled on;
18+
hls_fragment 10;
19+
hls_window 60;
20+
hls_path ./objs/nginx/html;
21+
hls_m3u8_file [app]/[stream].m3u8;
22+
hls_ts_file [app]/[stream]-[seq].ts;
23+
24+
# Enable AES-128 encryption
25+
hls_keys on;
26+
hls_fragments_per_key 5;
27+
hls_key_file [app]/[stream]-[seq].key;
28+
hls_key_file_path ./objs/nginx/html;
29+
30+
# Test with query string - this should now work correctly
31+
# Expected result in m3u8: http://localhost:8080/live/livestream-0.key?token=abc123&sig=xyz789
32+
hls_key_url http://localhost:8080/?token=abc123&sig=xyz789;
33+
}
34+
}
35+

trunk/doc/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The changelog for SRS.
77
<a name="v7-changes"></a>
88

99
## SRS 7.0 Changelog
10+
* v7.0, 2025-11-07, AI: HLS: Support query string in hls_key_url for JWT tokens. v7.0.120 (#4426)
1011
* v7.0, 2025-11-07, AI: RTC: Support keep_original_ssrc to preserve SSRC and timestamps. v7.0.119 (#3850)
1112
* v7.0, 2025-11-05, AI: WebRTC: Report video/audio codec info and frame stats in HTTP API. v7.0.118 (#4554)
1213
* v7.0, 2025-11-04, AI: SRT: Report video/audio codec info and frame stats in HTTP API. v7.0.117 (#4554)

trunk/src/app/srs_app_hls.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ using namespace std;
3333
#include <srs_kernel_utility.hpp>
3434
#include <srs_protocol_amf0.hpp>
3535
#include <srs_protocol_format.hpp>
36+
#include <srs_protocol_http_stack.hpp>
3637
#include <srs_protocol_rtmp_stack.hpp>
3738
#include <srs_protocol_stream.hpp>
3839

@@ -45,6 +46,33 @@ using namespace std;
4546
// reset the piece id when deviation overflow this.
4647
#define SRS_JUMP_WHEN_PIECE_DEVIATION 20
4748

49+
// Build the full key URL by appending key_file to hls_key_url with proper query string handling.
50+
// If hls_key_url contains query string like "http://localhost:8080/?token=abc",
51+
// the result will be "http://localhost:8080/live/livestream-0.key?token=abc"
52+
// @param hls_key_url The base URL which may contain query string
53+
// @param key_file The key file path like "live/livestream-0.key"
54+
// @return The full key URL with query string properly appended
55+
string srs_hls_build_key_url(const string &hls_key_url, const string &key_file)
56+
{
57+
if (hls_key_url.empty()) {
58+
return key_file;
59+
}
60+
61+
// Find the query string separator
62+
size_t pos = hls_key_url.find("?");
63+
if (pos != string::npos) {
64+
// URL contains query string, split and rebuild
65+
// Example: "http://localhost:8080/?token=abc" + "live/livestream-0.key"
66+
// Result: "http://localhost:8080/live/livestream-0.key?token=abc"
67+
string base_url = hls_key_url.substr(0, pos);
68+
string query_string = hls_key_url.substr(pos); // Include the '?'
69+
return base_url + key_file + query_string;
70+
}
71+
72+
// No query string, simple concatenation
73+
return hls_key_url + key_file;
74+
}
75+
4876
SrsHlsSegment::SrsHlsSegment(SrsTsContext *c, SrsAudioCodecId ac, SrsVideoCodecId vc, ISrsFileWriter *w)
4977
{
5078
sequence_no_ = 0;
@@ -1107,11 +1135,7 @@ srs_error_t SrsHlsFmp4Muxer::do_refresh_m3u8_segment(SrsHlsM4sSegment *segment,
11071135
string key_file = srs_path_build_stream(hls_key_file_, req_->vhost_, req_->app_, req_->stream_);
11081136
key_file = srs_strings_replace(key_file, "[seq]", srs_strconv_format_int(segment->sequence_no_));
11091137

1110-
string key_path = key_file;
1111-
// if key_url is not set,only use the file name
1112-
if (!hls_key_url_.empty()) {
1113-
key_path = hls_key_url_ + key_file;
1114-
}
1138+
string key_path = srs_hls_build_key_url(hls_key_url_, key_file);
11151139

11161140
ss << "#EXT-X-KEY:METHOD=SAMPLE-AES,URI=" << "\"" << key_path << "\",IV=0x" << hexiv << SRS_CONSTS_LF;
11171141
}
@@ -2040,11 +2064,7 @@ srs_error_t SrsHlsMuxer::do_refresh_m3u8_segment(SrsHlsSegment *segment, std::st
20402064
string key_file = srs_path_build_stream(hls_key_file_, req_->vhost_, req_->app_, req_->stream_);
20412065
key_file = srs_strings_replace(key_file, "[seq]", srs_strconv_format_int(segment->sequence_no_));
20422066

2043-
string key_path = key_file;
2044-
// if key_url is not set,only use the file name
2045-
if (!hls_key_url_.empty()) {
2046-
key_path = hls_key_url_ + key_file;
2047-
}
2067+
string key_path = srs_hls_build_key_url(hls_key_url_, key_file);
20482068

20492069
ss << "#EXT-X-KEY:METHOD=AES-128,URI=" << "\"" << key_path << "\",IV=0x" << hexiv << SRS_CONSTS_LF;
20502070
}

trunk/src/core/srs_core_version7.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 7
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 119
12+
#define VERSION_REVISION 120
1313

1414
#endif

0 commit comments

Comments
 (0)