Skip to content

Commit 2a56889

Browse files
fix(live_streaming): fix Qiniu authentication to support dynamic hosts
Fixed authentication bug where the host was hardcoded instead of being dynamically determined based on the actual API call. The _get_auth_header() method now accepts url, body, and content_type parameters to properly sign requests for both base endpoint (mls.cn-east-1.qiniumiku.com) and bucket-specific endpoints (<bucket>.mls.cn-east-1.qiniumiku.com). Changes: - Modified _get_auth_header() to accept url, body, and content_type params - Updated all API methods to pass the actual request URL for signing - Added json import for proper request body serialization Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: callmefisher <[email protected]>
1 parent 2326c08 commit 2a56889

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

src/mcp_server/core/live_streaming/live_streaming.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import aiohttp
2+
import json
23
import logging
34
import qiniu
45

@@ -24,19 +25,24 @@ def __init__(self, cfg: config.Config = None):
2425
self.secret_key != "YOUR_QINIU_SECRET_KEY":
2526
self.auth = qiniu.Auth(self.access_key, self.secret_key)
2627

27-
def _get_auth_header(self) -> Dict[str, str]:
28+
def _get_auth_header(self, url: str = "", body: bytes = None, content_type: str = "application/x-www-form-urlencoded") -> Dict[str, str]:
2829
"""
2930
Generate authorization header
3031
Priority: QINIU_ACCESS_KEY/QINIU_SECRET_KEY > API KEY
32+
33+
Args:
34+
url: The request URL for signing (required for Qiniu Auth)
35+
body: The request body for signing
36+
content_type: The content type of the request
3137
"""
3238
# Priority 1: Use QINIU_ACCESS_KEY/QINIU_SECRET_KEY if configured
3339
if self.auth:
34-
# Generate Qiniu token for the request
35-
# For live streaming API, we use a simple token format
40+
# Generate Qiniu token for the request with the actual URL
41+
# This ensures proper authentication for dynamic hosts like <bucket>.mls.cn-east-1.qiniumiku.com
3642
token = self.auth.token_of_request(
37-
url="",
38-
body=None,
39-
content_type="application/x-www-form-urlencoded"
43+
url=url,
44+
body=body,
45+
content_type=content_type
4046
)
4147
return {
4248
"Authorization": f"Qiniu {token}"
@@ -91,7 +97,7 @@ async def create_bucket(self, bucket: str) -> Dict[str, Any]:
9197
Dict containing the response status and message
9298
"""
9399
url = self._build_bucket_url(bucket)
94-
headers = self._get_auth_header()
100+
headers = self._get_auth_header(url=url)
95101

96102
logger.info(f"Creating bucket: {bucket} at {url}")
97103

@@ -131,7 +137,7 @@ async def create_stream(self, bucket: str, stream: str) -> Dict[str, Any]:
131137
Dict containing the response status and message
132138
"""
133139
url = self._build_stream_url(bucket, stream)
134-
headers = self._get_auth_header()
140+
headers = self._get_auth_header(url=url)
135141

136142
logger.info(f"Creating stream: {stream} in bucket: {bucket} at {url}")
137143

@@ -174,14 +180,15 @@ async def bind_push_domain(self, bucket: str, domain: str, domain_type: str = "p
174180
Dict containing the response status and message
175181
"""
176182
url = f"{self._build_bucket_url(bucket)}/?pushDomain"
177-
headers = {
178-
**self._get_auth_header(),
179-
"Content-Type": "application/json"
180-
}
181183
data = {
182184
"domain": domain,
183185
"type": domain_type
184186
}
187+
body = json.dumps(data).encode('utf-8')
188+
headers = {
189+
**self._get_auth_header(url=url, body=body, content_type="application/json"),
190+
"Content-Type": "application/json"
191+
}
185192

186193
logger.info(f"Binding push domain: {domain} (type: {domain_type}) to bucket: {bucket}")
187194

@@ -224,14 +231,15 @@ async def bind_play_domain(self, bucket: str, domain: str, domain_type: str = "l
224231
Dict containing the response status and message
225232
"""
226233
url = f"{self._build_bucket_url(bucket)}/?domain"
227-
headers = {
228-
**self._get_auth_header(),
229-
"Content-Type": "application/json"
230-
}
231234
data = {
232235
"domain": domain,
233236
"type": domain_type
234237
}
238+
body = json.dumps(data).encode('utf-8')
239+
headers = {
240+
**self._get_auth_header(url=url, body=body, content_type="application/json"),
241+
"Content-Type": "application/json"
242+
}
235243

236244
logger.info(f"Binding playback domain: {domain} (type: {domain_type}) to bucket: {bucket}")
237245

@@ -344,7 +352,7 @@ async def query_live_traffic_stats(self, begin: str, end: str) -> Dict[str, Any]
344352

345353
url = f"http://{endpoint}/?trafficStats&begin={begin}&end={end}&g=5min&select=flow&flow=downflow"
346354
headers = {
347-
**self._get_auth_header(),
355+
**self._get_auth_header(url=url, content_type="application/json"),
348356
"Content-Type": "application/json"
349357
}
350358

@@ -393,7 +401,7 @@ async def list_buckets(self) -> Dict[str, Any]:
393401
endpoint = endpoint[8:]
394402

395403
url = f"https://{endpoint}/"
396-
headers = self._get_auth_header()
404+
headers = self._get_auth_header(url=url)
397405

398406
logger.info(f"Listing all live streaming buckets from {url}")
399407

@@ -439,7 +447,7 @@ async def list_streams(self, bucket_id: str) -> Dict[str, Any]:
439447
endpoint = endpoint[8:]
440448

441449
url = f"https://{endpoint}/?streamlist&bucketId={bucket_id}"
442-
headers = self._get_auth_header()
450+
headers = self._get_auth_header(url=url)
443451

444452
logger.info(f"Listing streams in bucket: {bucket_id}")
445453

0 commit comments

Comments
 (0)