package com.terra.proxy.servlet; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.terra.proxy.bean.VistorBean; import com.terra.proxy.proxy.SolrProxyServletConfiguration; import com.terra.proxy.service.Impl.ServerRegisterServiceImpl; import com.terra.proxy.util.HttpContextUtils; import com.terra.proxy.util.JedisUtils; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.utils.URIUtils; import org.apache.http.entity.BasicHttpEntity; import org.mitre.dsmiley.httpproxy.ProxyServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import redis.clients.jedis.Jedis; import javax.annotation.PostConstruct; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URI; import java.util.*; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class RerequestServlet2 extends ProxyServlet { private Logger log = LoggerFactory.getLogger(RerequestServlet2.class); @Autowired JedisUtils jedisUtils; ServerRegisterServiceImpl service; @PostConstruct public void init() { try { super.init(); } catch (ServletException e) { // TODO Auto-generated catch block e.printStackTrace(); } WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); service = wac.getBean(ServerRegisterServiceImpl.class); } public static boolean isdigit(String str) { return str.matches("[0-9]+"); } protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { URI errorurl = URI.create("http://" + "localhost" + ":" + servletRequest.getServerPort() + "/404.html"); StringBuilder uri = new StringBuilder(1000); StringBuilder queryString2 = new StringBuilder(1000); System.out.print(servletRequest.getHeader("Content-Length") + servletRequest.getHeader("Transfer-Encoding")); // Handle the path given to the servlet if (servletRequest.getPathInfo() != null) {// ex: /my/path.html System.out.println(servletRequest.getPathInfo()); uri.append(encodeUriQuery(servletRequest.getPathInfo())); } // Handle the query string & fragment String queryString = servletRequest.getQueryString();// ex:(following String fragment = null; // 根据zyid和suffix后缀查询对应的真实服务地址,判断是否公开, 公开不需要token拼接参数返回 List serverlist = new ArrayList<>(); String zyid = ""; String path = servletRequest.getPathInfo(); String[] splitpath = path.split("/"); zyid = splitpath[1]; String suffix = null; if (splitpath.length > 3 && splitpath[3] != null) { suffix = isdigit(splitpath[2]) ? splitpath[2] : null; } String fromsys = ""; if (queryString != null) { String pathpar[] = queryString.split("&"); for (int i = 0; i < pathpar.length; i++) { String a = pathpar[i].split("=")[0]; String v = pathpar[i].split("=")[1]; if ("fromsys".equals(a)) { fromsys = v; break; } } } Map param = new HashMap(); if (!isInteger(zyid)) { servletRequest.setAttribute(ATTR_TARGET_HOST, URIUtils.extractHost(errorurl)); return "http://" + "localhost" + ":" + servletRequest.getServerPort() + "/404.html"; } param.put("resourceid", Integer.valueOf(zyid)); param.put("suffix", suffix != null ? Integer.valueOf(suffix) : null); param.put("fromsys", fromsys); serverlist = service.queryServer(param); param.put("SERVERURL", serverlist.get(0).get("SERVERURL").toString()); serverlist.add(param); System.out.print(serverlist.toString()); String url = serverlist.get(0).get("SERVERURL").toString(); Integer ispublic = Integer.valueOf(serverlist.get(0).get("ISPUBLIC").toString()); URI hostpath = URI.create(url); servletRequest.setAttribute(ATTR_TARGET_HOST, URIUtils.extractHost(hostpath)); VistorBean vb = new VistorBean(); vb.setRequestip(servletRequest.getRemoteAddr()); vb.setResourceid(Integer.valueOf(zyid)); vb.setVisitfromsys("ZJZT"); vb.setServerurl(serverlist.get(0).get("SERVERURL").toString()); // split off fragment from queryString, updating queryString if found if (queryString != null) { // 针对请求地址的参数做操作 // 判断是否带了token if (queryString.indexOf("token") == -1 && ispublic != 1) { servletRequest.setAttribute(ATTR_TARGET_HOST, URIUtils.extractHost(errorurl)); vb.setResult("fail"); visitlogsaveinredis(vb); return "http://" + "localhost" + ":" + servletRequest.getLocalPort() + "/500.html"; } String par[] = queryString.split("&"); for (int i = 0; i < par.length; i++) { String a = par[i].split("=")[0]; String v = par[i].split("=")[1]; if ("token".equals(a)) { // 判断内存里有咩有匹配的token,咩有去redis库里查询,库里没有,则在内存和库中存储,库里有,存入内存 if (!SolrProxyServletConfiguration.tokens.contains(v)) { Jedis jedis = null; try { jedis = JedisUtils.getJedis(); if (!jedis.exists(v)) { // jedis.sadd("token", v); servletRequest.setAttribute(ATTR_TARGET_HOST, URIUtils.extractHost(errorurl)); vb.setResult("fail"); visitlogsaveinredis(vb); return "http://" + "localhost" + ":" + servletRequest.getLocalPort() + "/tokenerror.html"; } } catch (Exception e) { e.printStackTrace(); } finally { jedis.close(); } } } else { queryString2.append("&").append(par[i]); } } int fragIdx = queryString.indexOf('#'); if (fragIdx >= 0) { fragment = queryString.substring(fragIdx + 1); queryString = queryString.substring(0, fragIdx); } } else { if (ispublic != 1) { servletRequest.setAttribute(ATTR_TARGET_HOST, URIUtils.extractHost(errorurl)); vb.setResult("fail"); visitlogsaveinredis(vb); return "http://" + "localhost" + ":" + servletRequest.getLocalPort() + "/500.html"; } } if (!serverlist.isEmpty()) { System.out.print(serverlist.get(0).get("SERVERURL").toString()); StringBuilder returnuri = new StringBuilder(serverlist.get(0).get("SERVERURL").toString()); String externstr = uri.substring(uri.lastIndexOf("Server") + 6, uri.length()); System.out.println(externstr); returnuri.append(externstr); if (queryString2 != null && queryString2.length() > 0) { if (!(returnuri.indexOf("?") > -1)) { returnuri.append('?'); } returnuri.append(encodeUriQuery(queryString2)); } if (doSendUrlFragment && fragment != null) { returnuri.append('#'); returnuri.append(encodeUriQuery(fragment)); } vb.setResult("success"); visitlogsaveinredis(vb); return returnuri.toString(); } return null; } public static boolean isInteger(String str) { Pattern pattern = Pattern.compile("^[1-9]\\d*|0$"); return pattern.matcher(str).matches(); } protected void copyResponseEntity(HttpResponse proxyResponse, HttpServletResponse servletResponse) throws IOException { HttpEntity entity = proxyResponse.getEntity(); BufferedReader reader; InputStream is = entity.getContent(); servletResponse.setCharacterEncoding("UTF-8"); if (isgzip(entity)) { reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(is))); StringBuffer sb = new StringBuffer(); String s = null; while ((s = reader.readLine()) != null) { log.info(s); sb.append(s); } String result = sb.toString(); result = result.replaceAll("]*>((?!table).)*", ""); result = result.replaceAll("]*>(ArcGIS JavaScript|ArcGIS Online map viewer|Google Earth|ArcMap|ArcGIS Explorer|ArcGIS.com Map)", ""); result = result.replaceAll("(http|https)://[^/]+/", "/"); result = result.replaceAll("/arcgis/rest/services", ""); HttpServletRequest hsr = HttpContextUtils.getHttpServletRequest(); BasicHttpEntity entity2 = new BasicHttpEntity(); byte[] bt; bt = compress(result); ByteArrayInputStream btinput = new ByteArrayInputStream(bt); entity2.setContent(btinput); entity2.setContentEncoding("gzip"); entity2.setContentType(entity.getContentType()); entity2.setChunked(false); if (entity2 != null) { servletResponse.addHeader("Content-Length", String.valueOf(bt.length)); OutputStream servletOutputStream = servletResponse.getOutputStream(); entity2.writeTo(servletOutputStream); } } else { if (entity != null) { OutputStream servletOutputStream = servletResponse.getOutputStream(); entity.writeTo(servletOutputStream); } } } /* * 统计不同ip调用服务次数,并将其存入入redis */ private void visitlogsaveinredis(VistorBean vb) { String fromip = vb.getRequestip(); vb.setDate(new Date()); Jedis jedis = null; int count = 0; try { jedis = JedisUtils.getJedis(); jedis.sadd("visitlog", JSONObject.toJSONStringWithDateFormat(vb, "yyyy-MM-dd HH:mm:ss", SerializerFeature.PrettyFormat)); } catch (Exception e) { // TODO: handle exception log.error("redis包错"); } finally { jedis.close(); } } public static byte[] compress(String str) { ByteArrayOutputStream out = new ByteArrayOutputStream(); GZIPOutputStream gzip = null; try { gzip = new GZIPOutputStream(out); gzip.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if (gzip != null) { try { gzip.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } } return out.toByteArray(); } public boolean isgzip(HttpEntity entity) { return entity.getContentEncoding() != null && "Content-Encoding: gzip".equals(entity.getContentEncoding().toString()) ? true : false; } public boolean ishtml(HttpEntity entity) { String temp = entity.getContentType().toString(); return temp.contains("text/html") ? true : false; } private void setXForwardedForHeader(HttpServletRequest servletRequest, HttpRequest proxyRequest) { String headerName = "X-Forwarded-For"; if (this.doForwardIP) { String newHeader = servletRequest.getRemoteAddr(); String existingHeader = servletRequest.getHeader(headerName); if (existingHeader != null) { newHeader = existingHeader + ", " + newHeader; } proxyRequest.setHeader(headerName, newHeader); } } protected void copyResponseHeaders(HttpResponse proxyResponse, HttpServletRequest servletRequest, HttpServletResponse servletResponse) { for (Header header : proxyResponse.getAllHeaders()) { if (!hopByHopHeaders.containsHeader(header.getName())) { if ((header.getName().equalsIgnoreCase("Set-Cookie")) || (header.getName().equalsIgnoreCase("Set-Cookie2"))) { copyProxyCookie(servletRequest, servletResponse, header); } else { servletResponse.addHeader(header.getName(), header.getValue()); System.out.print(header.getName() + header.getValue()); } } } System.out.print(servletResponse.containsHeader("Content-Length")); } }