Skip to content

Commit a12e44f

Browse files
committed
feat(subscription): add response_headers field and method to format subscription response headers
1 parent 4c737b9 commit a12e44f

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

app/models/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ class Subscription(BaseModel):
262262
# only supported by v2RayTun and Happ apps
263263
announce: str = Field(default="", max_length=128)
264264
announce_url: str = Field(default="")
265+
response_headers: dict[str, Any] = Field(default_factory=dict)
265266
# Rules To Seperate Clients And Send Config As Needed
266267
rules: list[SubRule]
267268
manual_sub_request: SubFormatEnable = Field(default_factory=SubFormatEnable)

app/operation/subscription.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,30 @@ def _format_rule_response_headers(
204204

205205
return headers
206206

207+
@classmethod
208+
def _format_subscription_response_headers(
209+
cls, sub_settings: SubSettings, format_variables: dict[str, str | int | float]
210+
) -> dict[str, str]:
211+
if not sub_settings.response_headers:
212+
return {}
213+
214+
headers: dict[str, str] = {}
215+
for raw_name, raw_value in sub_settings.response_headers.items():
216+
header_name = str(raw_name).strip()
217+
if not header_name or raw_value is None:
218+
continue
219+
220+
formatted_value = cls._stringify_rule_header_value(raw_value, format_variables)
221+
if not formatted_value:
222+
continue
223+
224+
if header_name.lower() in cls._ENCODED_RULE_RESPONSE_HEADERS:
225+
formatted_value = encode_title(formatted_value)
226+
227+
headers[header_name] = formatted_value
228+
229+
return headers
230+
207231
@staticmethod
208232
def _stringify_rule_header_value(value: Any, format_variables: dict[str, str | int | float]) -> str:
209233
if isinstance(value, str):
@@ -362,6 +386,11 @@ async def user_subscription(
362386
extra_headers={},
363387
)
364388
try:
389+
response_headers.update(
390+
self._format_subscription_response_headers(
391+
sub_settings, await self._get_rule_response_header_variables(user, client_type)
392+
)
393+
)
365394
response_headers.update(
366395
self._format_rule_response_headers(
367396
matched_rule, await self._get_rule_response_header_variables(user, client_type)
@@ -424,6 +453,11 @@ async def user_subscription_with_client_type(
424453
user, request_url, sub_settings, extension=client_config.get(client_type, {}).get("extension", "")
425454
)
426455
try:
456+
response_headers.update(
457+
self._format_subscription_response_headers(
458+
sub_settings, await self._get_rule_response_header_variables(user, client_type)
459+
)
460+
)
427461
response_headers = self.sanitize_response_headers(response_headers)
428462
except ValueError as exc:
429463
await self.raise_error(message=str(exc), code=400)
@@ -495,6 +529,11 @@ async def user_subscription_raw(
495529
formatted_announce = self._format_announce(sub_settings, format_variables)
496530
response_headers = self.create_response_headers(user, request_url, sub_settings)
497531
try:
532+
response_headers.update(
533+
self._format_subscription_response_headers(
534+
sub_settings, await self._get_rule_response_header_variables(user, ConfigFormat.links)
535+
)
536+
)
498537
response_headers = self.sanitize_response_headers(response_headers)
499538
except ValueError as exc:
500539
await self.raise_error(message=str(exc), code=400)
@@ -527,6 +566,11 @@ async def user_subscription_by_user(
527566
user, request_url, sub_settings, extension=client_config.get(client_type, {}).get("extension", "")
528567
)
529568
try:
569+
response_headers.update(
570+
self._format_subscription_response_headers(
571+
sub_settings, await self._get_rule_response_header_variables(user, client_type)
572+
)
573+
)
530574
response_headers = self.sanitize_response_headers(response_headers)
531575
except ValueError as exc:
532576
await self.raise_error(message=str(exc), code=400)

0 commit comments

Comments
 (0)