@@ -565,6 +565,123 @@ def build_request_validation(
565565 }
566566
567567
568+ @dataclass
569+ class HeadersConfig :
570+ add : Dict [str , str ]
571+ set : Dict [str , str ]
572+ remove : List [str ]
573+
574+
575+ def build_response_rewrite_validation (
576+ status_code : int ,
577+ body : str ,
578+ vars : Optional [str ],
579+ body_base64 : bool = False ,
580+ headers : Optional [HeadersConfig ] = None ,
581+ ) -> Dict [str , str ]:
582+ """generate response-rewrite plugin config
583+
584+ Args:
585+ status_code (int): 修改上游返回状态码,默认保留原始响应代码。
586+ body (str):
587+ - 修改上游返回的 body 内容,如果设置了新内容,header 里面的 content-length 字段也会被去掉。
588+ - 注意,这个字段只允许对插件配置中传递的主体进行解码,并不对上游响应进行解码。
589+ vars (str, Optional):
590+ - vars 是一个表达式列表,只有满足条件的请求和响应才会修改 body 和 header 信息,来自 lua-resty-expr。
591+ - 如果 vars 字段为空,那么所有的重写动作都会被无条件的执行。
592+ body_base64 (bool, Optional): 当设置时,在写给客户端之前,在body中传递的主体将被解码,这在一些图像和 Protobuffer 场景中使用。
593+ headers (HeadersConfig, optional):
594+ - add (Dict[str, str]): 添加新的响应头。格式为 {"name": "value", ...}。这个值能够以 $var 的格式包含 NGINX 变量。
595+ - set (Dict[str, str]): 改写响应头。格式为 {"name": "value", ...}。这个值能够以 $var 的格式包含 NGINX 变量。
596+ - remove (List[str]): 移除响应头。格式为 ["name", ...]。
597+
598+ Raises:
599+ ValueError: status_code must be between 200 and 598
600+ ValueError: key {} can not contain ':'
601+
602+ Returns:
603+ {
604+ "type": "response-rewrite",
605+ "yaml": "body: ''\n body_base64: false\n headers:\n add:\n - key: key1:value1\n remove:\n - key: key1\n set:\n - key: key1\n value: value1\n status_code: 200\n vars: ''\n "
606+ }
607+ """
608+
609+ if not (200 <= status_code <= 598 ):
610+ raise ValueError ("status_code must be between 200 and 598" )
611+
612+ if vars :
613+ _check_vars (vars , "response_rewrite" )
614+
615+ add_data = []
616+ for k , v in headers .add .items ():
617+ if ":" in k :
618+ raise ValueError (f"key { k } can not contain ':'" )
619+ add_data .append ({"key" : "{}:{}" .format (k , v )})
620+
621+ set_data = []
622+ for k , v in headers .set .items ():
623+ if ":" in k :
624+ raise ValueError (f"key { k } can not contain ':'" )
625+ set_data .append ({"key" : k , "value" : v })
626+
627+ remove_data = []
628+ for k in headers .remove :
629+ if ":" in k :
630+ raise ValueError (f"key { k } can not contain ':'" )
631+ remove_data .append ({"key" : k })
632+
633+ return {
634+ "type" : "response-rewrite" ,
635+ "yaml" : yaml_dump (
636+ {
637+ "status_code" : status_code ,
638+ "body_base64" : body_base64 ,
639+ "body" : body ,
640+ "vars" : vars ,
641+ "headers" : {
642+ "add" : add_data ,
643+ "set" : set_data ,
644+ "remove" : remove_data ,
645+ }
646+ }
647+ ),
648+ }
649+
650+
651+ def build_redirect_validation (
652+ uri : str ,
653+ ret_code : int = 302 ,
654+ ) -> Dict [str , str ]:
655+ """generate redirect plugin config
656+
657+ Args:
658+ uri (str): 要重定向到的 URI,可以包含 NGINX 变量。
659+ ret_code (int, Optional): HTTP 响应码。
660+
661+ Raises:
662+ ValueError: ret_code cannot be less than 200
663+
664+ Returns:
665+ {
666+ "type": "redirect",
667+ "yaml": "ret_code: 200\n uri: ''\n "
668+ }
669+ """
670+
671+ if ret_code and ret_code < 200 :
672+ raise ValueError ("ret_code cannot be less than 200" )
673+
674+ return {
675+ "type" : "redirect" ,
676+ "yaml" : yaml_dump (
677+ {
678+ "uri" : uri ,
679+ "ret_code" : ret_code ,
680+ }
681+ ),
682+ }
683+
684+
568685def _check_percentage (percentage : int , location : str ):
569686 if percentage and not (0 < percentage <= 100 ):
570687 raise ValueError (f"The percentage of { location } must be greater than 0 and less than or equal to 100" )
0 commit comments