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<Map> 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<String, Object> 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[^>]*>((?!table).)*</table>", "");
|
result = result.replaceAll("<a[^>]*>(ArcGIS JavaScript|ArcGIS Online map viewer|Google Earth|ArcMap|ArcGIS Explorer|ArcGIS.com Map)</a>", "");
|
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"));
|
}
|
|
|
}
|