/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.common.filter;

import com.yami.shop.common.xss.XssWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * `XssFilter`类实现了`Filter`接口，是一个用于进行简单安全过滤的过滤器类，主要针对跨站脚本攻击（XSS，Cross-Site Scripting）进行防范。
 * 在Web应用中，用户输入的数据可能包含恶意的脚本代码，如果不加以过滤处理，这些代码可能会在浏览器端被执行，从而导致安全问题，比如窃取用户信息、篡改页面内容等。
 * 此类通过将请求包装在`XssWrapper`中，对请求中的数据进行过滤处理，以达到防范XSS攻击的目的，并且作为一个Spring组件，可以方便地被Spring容器管理和配置到Web应用的过滤器链中。
 *
 * @author lgh
 */
@Component // 表明这个类是一个Spring组件，会被Spring容器扫描并实例化，方便进行依赖注入等相关操作以及在Web应用中作为过滤器被正确管理和使用。
public class XssFilter implements Filter {
    // 创建一个日志记录器，用于记录过滤器执行过程中的相关信息，比如记录请求的URI等情况，方便后续查看过滤器的执行情况以及排查可能出现的问题。
    Logger logger = LoggerFactory.getLogger(getClass().getName());

    /**
     * `init`方法是`Filter`接口中定义的初始化方法，在过滤器被创建并加载到Web容器时调用一次，用于进行一些初始化的配置操作。
     * 在这里，当前的实现为空方法体，意味着没有额外的初始化逻辑需要执行，如果后续有需要，比如读取配置文件中的过滤规则等操作，可以在此方法中添加相应的代码。
     *
     * @param filterConfig 包含了过滤器的配置信息，通过这个参数可以获取到在Web应用配置文件中为该过滤器设置的初始化参数等内容，不过目前没有使用到。
     * @throws ServletException 如果在初始化过程中出现错误，例如读取配置文件出错等情况，可以抛出这个异常，由Web容器进行相应的处理。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * `doFilter`方法是`Filter`接口中最核心的方法，用于实现具体的过滤逻辑。每次有请求经过这个过滤器时，都会执行这个方法。
     * 其主要逻辑如下：
     * 1. 首先将传入的`ServletRequest`和`ServletResponse`对象强制转换为`HttpServletRequest`和`HttpServletResponse`类型，
     *    因为在Web应用中，通常处理的是基于HTTP协议的请求和响应，这样后续可以方便地使用HTTP相关的方法和属性进行操作。
     * 2. 通过日志记录器记录当前请求的URI（统一资源标识符），方便后续查看哪些请求经过了这个过滤器，对于调试和监控请求情况很有帮助。
     * 3. 进行XSS过滤操作，将原始的`HttpServletRequest`对象包装在`XssWrapper`对象中，`XssWrapper`类应该是实现了对请求数据进行XSS过滤的逻辑，
     *    然后将包装后的请求对象传递给过滤器链的下一个环节（通过`chain.doFilter`方法），这样后续的过滤器或者请求处理的Servlet等就能接收到经过XSS过滤后的请求数据，
     *    从而避免了恶意脚本代码通过请求进入到应用内部并造成安全风险。
     *
     * @param request 表示客户端发来的请求对象，包含了请求的各种信息，如请求头、请求参数等内容，在这里会被转换为`HttpServletRequest`类型来进一步处理。
     * @param response 表示服务器端要返回给客户端的响应对象，包含了响应的相关信息，如响应头、响应体等内容，在这里会被转换为`HttpServletResponse`类型来进行相关操作。
     * @param chain 过滤器链对象，代表了整个Web应用中过滤器的执行顺序链条，通过调用`chain.doFilter`方法可以将请求传递到下一个过滤器或者最终的请求处理Servlet中继续处理。
     * @throws IOException 如果在处理请求或响应的过程中出现输入输出相关的错误，例如读取请求数据出错、向客户端写响应数据出错等情况，会抛出这个异常，由Web容器进行相应的处理。
     * @throws ServletException 如果在过滤器执行过程中出现与Servlet相关的错误，例如请求对象转换失败、过滤器链执行异常等情况，会抛出这个异常，由Web容器进行相应的处理。
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        logger.info("uri:{}", req.getRequestURI());
        // xss 过滤，将原始的HttpServletRequest包装在XssWrapper中，XssWrapper类应该实现了对请求参数等数据进行XSS过滤的逻辑，
        // 然后把包装后的请求对象传递给过滤器链的下一个环节，使得后续的处理流程接收到的是经过XSS过滤后的请求数据。
        chain.doFilter(new XssWrapper(req), resp);
    }

    /**
     * `destroy`方法是`Filter`接口中定义的销毁方法，在过滤器从Web容器中被移除时调用，用于释放过滤器占用的资源，比如关闭打开的文件流、释放数据库连接等操作。
     * 在这里，当前的实现为空方法体，意味着没有额外的资源释放逻辑需要执行，如果后续过滤器在运行过程中有占用相关资源的情况，可以在此方法中添加相应的代码来进行资源的清理工作。
     */
    @Override
    public void destroy() {

    }
}