WebSocketProxyFilter.java 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package com.datasophon.api.configuration;
  2. import com.netflix.zuul.ZuulFilter;
  3. import com.netflix.zuul.context.RequestContext;
  4. import com.netflix.zuul.exception.ZuulException;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.springframework.stereotype.Component;
  8. import javax.servlet.http.HttpServletRequest;
  9. import java.util.Map;
  10. import java.util.Objects;
  11. import java.util.concurrent.ConcurrentHashMap;
  12. /**
  13. *
  14. * Zuul 支持 websocket 的代理
  15. *
  16. * <pre>
  17. *
  18. * Created by zhenqin.
  19. * User: zhenqin
  20. * Date: 2023/3/17
  21. * Time: 上午11:32
  22. * Vendor: yiidata.com
  23. *
  24. * </pre>
  25. *
  26. * @author zhenqin
  27. */
  28. @Component
  29. @Slf4j
  30. public class WebSocketProxyFilter extends ZuulFilter {
  31. /**
  32. * 所有 websocket 的特殊处理
  33. */
  34. final static Map<String, ApiRoute> WEBSOCKET_ACTION_MAPPING = new ConcurrentHashMap<>();
  35. /**
  36. * 添加 WebSocket 地址
  37. * @param path
  38. * @param route
  39. */
  40. public static void addWebSocketRouter(String path, ApiRoute route) {
  41. WEBSOCKET_ACTION_MAPPING.put(path, route);
  42. }
  43. /**
  44. * 过滤器类型
  45. * pre 前置
  46. * routing
  47. * post 后置
  48. * error
  49. *
  50. * @return
  51. */
  52. @Override
  53. public String filterType() {
  54. return "pre";
  55. }
  56. /**
  57. * 执行顺序
  58. * 数值越小,优先级越高
  59. *
  60. * @return
  61. */
  62. @Override
  63. public int filterOrder() {
  64. return 0;
  65. }
  66. /**
  67. * 执行条件
  68. * true 开启, 执行 run 的特殊处理
  69. * false 关闭,否则不需要特殊处理,直接代理
  70. *
  71. * @return
  72. */
  73. @Override
  74. public boolean shouldFilter() {
  75. RequestContext rc = RequestContext.getCurrentContext();
  76. HttpServletRequest request = rc.getRequest();
  77. if(request == null) {
  78. return false;
  79. }
  80. final String path = request.getServletPath();
  81. final String connectionHeader = request.getHeader("Connection");
  82. final String upgradeHeader = request.getHeader("Upgrade");
  83. // 检验是不是 websocket 的链接, websocket 连接 Connection: Upgrade, Upgrade: websocket, Websocket, WebSocket
  84. return StringUtils.equals("Upgrade", connectionHeader) && StringUtils.equalsIgnoreCase("websocket", upgradeHeader) && WEBSOCKET_ACTION_MAPPING.get(path) != null;
  85. }
  86. /**
  87. * 动作(具体操作)
  88. * 具体逻辑
  89. *
  90. * @return
  91. * @throws ZuulException
  92. */
  93. @Override
  94. public Object run() throws ZuulException {
  95. RequestContext rc = RequestContext.getCurrentContext();
  96. HttpServletRequest request = rc.getRequest();
  97. final String path = request.getServletPath();
  98. rc.addZuulRequestHeader("Connection", request.getHeader("Connection"));
  99. rc.addZuulRequestHeader("Upgrade", request.getHeader("Upgrade"));
  100. //过滤该请求,不进行路由
  101. rc.setSendZuulResponse(false);
  102. //返回对应http status状态码
  103. rc.setResponseStatusCode(401);
  104. //设置返回的内容
  105. rc.setResponseBody("{'error':'token is empty'}");
  106. final ApiRoute apiRoute = WEBSOCKET_ACTION_MAPPING.get(path);
  107. log.info(path);
  108. try {
  109. Thread.sleep(10000);
  110. } catch (InterruptedException e) {
  111. e.printStackTrace();
  112. }
  113. return apiRoute;
  114. }
  115. }