mirror of
https://github.com/NewFuture/DDNS.git
synced 2026-10-20 19:23:33 +00:00
* feat(mcp): add Streamable HTTP transport Add a modern MCP 2026-07-28 HTTP endpoint for standalone and Web modes, with shared listener configuration, authentication, schema, tests, and bilingual documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): support Python 2 HTTP assertions Normalize response header names and call handler methods through their underlying functions so the HTTP tests behave consistently on Python 2.7 and Python 3. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): harden HTTP request handling Validate mirrored request IDs, align Config Studio listener checks, bound socket reads, and accept the binary wrapper's documented SIGINT exit status. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): align HTTP negotiation validation Reject unavailable Accept media types by quality and keep schema host validation consistent with runtime listener checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): validate host schema behavior Assert accepted and rejected host samples instead of comparing Unicode escape representations that differ on Python 2.7. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): avoid cross-engine schema regex Keep the schema pattern contract without executing its ECMA-262 Unicode escape through Python 2's incompatible regex engine. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate HTTP request boundaries Reject empty tokens and malformed JSON-RPC request shapes, and keep Config Studio bracket validation aligned with runtime listener handling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): tighten HTTP input validation Reject legacy notifications, nested host brackets, and document the required JSON content type so validation remains consistent across runtime, schema, and Config Studio. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate Origin before method errors Apply the existing Origin policy to non-POST MCP requests and return CORS headers for configured allowed origins. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(mcp): clarify proxy Origin allowlist Explain that browser clients behind TLS termination must allowlist the public HTTPS origin even when the public page appears same-origin. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(mcp): add standalone server guide Move MCP client setup, transports, tools, security, and protocol limits into dedicated Chinese and English pages with matching navigation and index links. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): reject duplicate routing headers Reject repeated MCP protocol, method, and name headers before body consistency checks across Python 2 and Python 3. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate named request headers Validate Mcp-Name for tools/call, prompts/get, and resources/read before dispatching unsupported methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
# -*- coding:utf-8 -*-
|
|
"""
|
|
Configuration loader for DDNS environment variables.
|
|
@author: NewFuture
|
|
"""
|
|
|
|
from ast import literal_eval
|
|
from os import environ
|
|
from sys import stderr
|
|
|
|
__all__ = ["load_config"]
|
|
|
|
|
|
def _try_parse_array(value, key=None):
|
|
# type: (str, str|None) -> Any
|
|
"""解析数组值[], 非数组返回元素字符串(去除前后空格)"""
|
|
if not value:
|
|
return value
|
|
|
|
value = value.strip()
|
|
# 尝试解析 JSON
|
|
# if (value.startswith("{'") and value.endswith("'}")) or (value.startswith('{"') and value.endswith('"}')):
|
|
# try:
|
|
# return json_decode(value)
|
|
# except Exception:
|
|
# logging.warning("Failed to parse JSON from value: %s", value)
|
|
if value.startswith("[") and value.endswith("]"):
|
|
# or (value.startswith("{") and value.endswith("}"))
|
|
try:
|
|
return literal_eval(value)
|
|
except Exception:
|
|
stderr.write("Failed to parse JSON array from value: {}={}\n".format(key, value))
|
|
pass
|
|
# 返回去除前后空格的字符串
|
|
return value
|
|
|
|
|
|
def load_config(prefix="DDNS_"):
|
|
# type: (str) -> dict
|
|
"""
|
|
从环境变量加载配置并返回配置字典。
|
|
|
|
支持以下转换:
|
|
1. 对于特定的数组参数(index4, index6, ipv4, ipv6, proxy),转换为数组
|
|
2. 对于 JSON 格式的数组 [item1,item2],转换为数组
|
|
3. 键名转换:点号转下划线,支持大小写变体
|
|
4. 自动检测标准 Python 环境变量:
|
|
- SSL 验证:PYTHONHTTPSVERIFY
|
|
5. 支持 extra 字段:DDNS_EXTRA_XXX 会被转换为 extra_xxx
|
|
6. 其他所有值保持原始字符串格式,去除前后空格
|
|
|
|
Args:
|
|
prefix (str): 环境变量前缀,默认为 "DDNS_"
|
|
|
|
Returns:
|
|
dict: 从环境变量解析的配置字典
|
|
"""
|
|
env_vars = {} # type: dict[str, str | list]
|
|
|
|
# 标准环境变量映射
|
|
alias_mappings = {"pythonhttpsverify": "ssl"}
|
|
|
|
for key, value in environ.items():
|
|
lower_key = key.lower()
|
|
config_key = None
|
|
|
|
if lower_key in alias_mappings:
|
|
config_key = alias_mappings[lower_key]
|
|
if config_key in env_vars:
|
|
continue # DDNS变量优先级更高
|
|
elif lower_key.startswith(prefix.lower()):
|
|
config_key = lower_key[len(prefix) :].replace(".", "_") # noqa: E203
|
|
|
|
if config_key:
|
|
env_vars[config_key] = (
|
|
value.strip() if config_key in ("token", "http_token") else _try_parse_array(value, key=key)
|
|
)
|
|
|
|
return env_vars
|