ProxyServletConfig.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package com.genersoft.iot.vmp.conf;
  2. import com.genersoft.iot.vmp.media.bean.MediaServer;
  3. import com.genersoft.iot.vmp.media.service.IMediaServerService;
  4. import org.apache.http.HttpHost;
  5. import org.apache.http.HttpRequest;
  6. import org.apache.http.HttpResponse;
  7. import org.springframework.core.annotation.Order;
  8. import org.mitre.dsmiley.httpproxy.ProxyServlet;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.beans.factory.annotation.Value;
  13. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  14. import org.springframework.context.annotation.Bean;
  15. import org.springframework.context.annotation.Configuration;
  16. import org.springframework.util.ObjectUtils;
  17. import javax.servlet.ServletException;
  18. import javax.servlet.http.HttpServletRequest;
  19. import javax.servlet.http.HttpServletResponse;
  20. import java.io.IOException;
  21. import java.net.ConnectException;
  22. /**
  23. * @author lin
  24. */
  25. @SuppressWarnings(value = {"rawtypes", "unchecked"})
  26. @Configuration
  27. @Order(1)
  28. public class ProxyServletConfig {
  29. private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);
  30. @Autowired
  31. private IMediaServerService mediaServerService;
  32. @Value("${server.port}")
  33. private int serverPort;
  34. @Bean
  35. public ServletRegistrationBean zlmServletRegistrationBean(){
  36. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZlmProxyServlet(),"/zlm/*");
  37. servletRegistrationBean.setName("zlm_Proxy");
  38. servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:6080");
  39. servletRegistrationBean.addUrlMappings();
  40. if (logger.isDebugEnabled()) {
  41. servletRegistrationBean.addInitParameter("log", "true");
  42. }
  43. return servletRegistrationBean;
  44. }
  45. class ZlmProxyServlet extends ProxyServlet{
  46. @Override
  47. protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
  48. String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
  49. MediaServer mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
  50. if (mediaInfo != null) {
  51. if (!ObjectUtils.isEmpty(queryStr)) {
  52. queryStr += "&secret=" + mediaInfo.getSecret();
  53. }else {
  54. queryStr = "secret=" + mediaInfo.getSecret();
  55. }
  56. }
  57. return queryStr;
  58. }
  59. @Override
  60. protected HttpResponse doExecute(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
  61. HttpRequest proxyRequest) throws IOException {
  62. HttpResponse response = super.doExecute(servletRequest, servletResponse, proxyRequest);
  63. response.removeHeaders("Access-Control-Allow-Origin");
  64. response.setHeader("Access-Control-Allow-Credentials","true");
  65. response.removeHeaders("Access-Control-Allow-Credentials");
  66. return response;
  67. }
  68. /**
  69. * 异常处理
  70. */
  71. @Override
  72. protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){
  73. try {
  74. super.handleRequestException(proxyRequest, proxyResonse, e);
  75. } catch (ServletException servletException) {
  76. logger.error("zlm 代理失败: ", e);
  77. } catch (IOException ioException) {
  78. if (ioException instanceof ConnectException) {
  79. logger.error("zlm 连接失败");
  80. } else {
  81. logger.error("zlm 代理失败: ", e);
  82. }
  83. } catch (RuntimeException exception){
  84. logger.error("zlm 代理失败: ", e);
  85. }
  86. }
  87. /**
  88. * 对于为按照格式请求的可以直接返回404
  89. */
  90. @Override
  91. protected String getTargetUri(HttpServletRequest servletRequest) {
  92. String requestURI = servletRequest.getRequestURI();
  93. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  94. String uri = null;
  95. if (mediaInfo != null) {
  96. // String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
  97. uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());
  98. }else {
  99. uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以
  100. }
  101. return uri;
  102. }
  103. /**
  104. * 动态替换请求目标
  105. */
  106. @Override
  107. protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
  108. String requestURI = servletRequest.getRequestURI();
  109. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  110. HttpHost host;
  111. if (mediaInfo != null) {
  112. host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());
  113. }else {
  114. host = new HttpHost("127.0.0.1", serverPort);
  115. }
  116. return host;
  117. }
  118. /**
  119. * 根据uri获取流媒体信息
  120. */
  121. MediaServer getMediaInfoByUri(String uri){
  122. String[] split = uri.split("/");
  123. String mediaServerId = split[2];
  124. if ("default".equalsIgnoreCase(mediaServerId)) {
  125. return mediaServerService.getDefaultMediaServer();
  126. }else {
  127. return mediaServerService.getOne(mediaServerId);
  128. }
  129. }
  130. /**
  131. * 去掉url中的标志信息
  132. */
  133. @Override
  134. protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
  135. String requestURI = servletRequest.getRequestURI();
  136. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  137. String url = super.rewriteUrlFromRequest(servletRequest);
  138. if (mediaInfo == null) {
  139. logger.error("[ZLM服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);
  140. return url;
  141. }
  142. if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
  143. url = url.replace(mediaInfo.getId() + "/", "");
  144. }
  145. return url.replace("default/", "");
  146. }
  147. }
  148. @Bean
  149. public ServletRegistrationBean recordServletRegistrationBean(){
  150. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new RecordProxyServlet(),"/record_proxy/*");
  151. servletRegistrationBean.setName("record_proxy");
  152. servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:18081");
  153. servletRegistrationBean.addUrlMappings();
  154. if (logger.isDebugEnabled()) {
  155. servletRegistrationBean.addInitParameter("log", "true");
  156. }
  157. return servletRegistrationBean;
  158. }
  159. class RecordProxyServlet extends ProxyServlet{
  160. @Override
  161. protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
  162. String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
  163. MediaServer mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
  164. if (mediaInfo == null) {
  165. return null;
  166. }
  167. String remoteHost = String.format("http://%s:%s", mediaInfo.getStreamIp(), mediaInfo.getRecordAssistPort());
  168. if (!ObjectUtils.isEmpty(queryStr)) {
  169. queryStr += "&remoteHost=" + remoteHost;
  170. }else {
  171. queryStr = "remoteHost=" + remoteHost;
  172. }
  173. return queryStr;
  174. }
  175. @Override
  176. protected HttpResponse doExecute(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
  177. HttpRequest proxyRequest) throws IOException {
  178. HttpResponse response = super.doExecute(servletRequest, servletResponse, proxyRequest);
  179. String origin = servletRequest.getHeader("origin");
  180. response.setHeader("Access-Control-Allow-Origin",origin);
  181. response.setHeader("Access-Control-Allow-Credentials","true");
  182. return response;
  183. }
  184. /**
  185. * 异常处理
  186. */
  187. @Override
  188. protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResponse, Exception e){
  189. try {
  190. super.handleRequestException(proxyRequest, proxyResponse, e);
  191. } catch (ServletException servletException) {
  192. logger.error("录像服务 代理失败: ", e);
  193. } catch (IOException ioException) {
  194. if (ioException instanceof ConnectException) {
  195. logger.error("录像服务 连接失败");
  196. // }else if (ioException instanceof ClientAbortException) {
  197. // /**
  198. // * TODO 使用这个代理库实现代理在遇到代理视频文件时,如果是206结果,会遇到报错蛋市目前功能正常,
  199. // * TODO 暂时去除异常处理。后续使用其他代理框架修改测试
  200. // */
  201. }else {
  202. logger.error("录像服务 代理失败: ", e);
  203. }
  204. } catch (RuntimeException exception){
  205. logger.error("录像服务 代理失败: ", e);
  206. }
  207. }
  208. /**
  209. * 对于为按照格式请求的可以直接返回404
  210. */
  211. @Override
  212. protected String getTargetUri(HttpServletRequest servletRequest) {
  213. String requestURI = servletRequest.getRequestURI();
  214. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  215. String uri = null;
  216. if (mediaInfo != null) {
  217. // String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
  218. uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getRecordAssistPort());
  219. }else {
  220. uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以
  221. }
  222. return uri;
  223. }
  224. /**
  225. * 动态替换请求目标
  226. */
  227. @Override
  228. protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
  229. String requestURI = servletRequest.getRequestURI();
  230. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  231. HttpHost host;
  232. if (mediaInfo != null) {
  233. host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort());
  234. }else {
  235. host = new HttpHost("127.0.0.1", serverPort);
  236. }
  237. return host;
  238. }
  239. /**
  240. * 根据uri获取流媒体信息
  241. */
  242. MediaServer getMediaInfoByUri(String uri){
  243. String[] split = uri.split("/");
  244. String mediaServerId = split[2];
  245. if ("default".equalsIgnoreCase(mediaServerId)) {
  246. return mediaServerService.getDefaultMediaServer();
  247. }else {
  248. return mediaServerService.getOne(mediaServerId);
  249. }
  250. }
  251. /**
  252. * 去掉url中的标志信息
  253. */
  254. @Override
  255. protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
  256. String requestURI = servletRequest.getRequestURI();
  257. MediaServer mediaInfo = getMediaInfoByUri(requestURI);
  258. String url = super.rewriteUrlFromRequest(servletRequest);
  259. if (mediaInfo == null) {
  260. logger.error("[录像服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);
  261. return url;
  262. }
  263. if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
  264. url = url.replace(mediaInfo.getId() + "/", "");
  265. }
  266. return url.replace("default/", "");
  267. }
  268. }
  269. }