package com.terra.proxy.servlet;
|
|
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.XML;
|
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.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 redis.clients.jedis.Jedis;
|
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.*;
|
import java.net.URI;
|
import java.util.Date;
|
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPOutputStream;
|
|
public class ZjProxyServlet2 extends ProxyServlet {
|
|
private String layer = "";
|
private boolean flag = true;
|
|
|
private Logger log = LoggerFactory.getLogger(ZjProxyServlet2.class);
|
|
protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
|
//获取来源ip,统计调用次数
|
|
VistorBean vb = new VistorBean();
|
|
vb.setRequestip(servletRequest.getRemoteHost());
|
if (servletRequest.getRequestURI() != null) {
|
vb.setServerurl(servletRequest.getRequestURI());
|
}
|
URI errorurl = URI.create(
|
"http://" + "localhost" + ":" + servletRequest.getServerPort() + "/404.html");
|
StringBuilder queryString2 = new StringBuilder(1000);
|
StringBuilder uri = new StringBuilder(500);
|
if (getTargetUri(servletRequest) != null) {
|
uri.append(getTargetUri(servletRequest));
|
}
|
if (servletRequest.getPathInfo() != null) {
|
uri.append(encodeUriQuery(servletRequest.getPathInfo()));
|
}
|
String queryString = servletRequest.getQueryString();
|
|
|
if (queryString != null) {
|
// 针对请求地址的参数做操作
|
// 判断是否带了token
|
if (flag && queryString.indexOf("token") == -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("=").length >= 2 ? par[i].split("=")[1] : "";
|
if (a.equals("layers") && v.contains("mpt")) {
|
layer = v.replace(".", " ");
|
|
}
|
if ("token".equals(a)) {
|
// 判断内存里有咩有匹配的token,咩有去redis库里查询,库里没有,则在内存和库中存储,库里有,存入内存
|
if (flag) {
|
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]);
|
}
|
}
|
} else {
|
if (flag) {
|
vb.setResult("fail");
|
visitlogsaveinredis(vb);
|
return "http://" + "localhost" + ":" + servletRequest.getLocalPort() + "/500.html";
|
}
|
}
|
|
String fragment = null;
|
if (queryString != null) {
|
int fragIdx = queryString.indexOf('#');
|
if (fragIdx >= 0) {
|
fragment = queryString.substring(fragIdx + 1);
|
queryString = queryString.substring(0, fragIdx);
|
}
|
}
|
|
if ((queryString2 != null) && (queryString2.length() > 0)) {
|
uri.append('?');
|
uri.append(encodeUriQuery(queryString2));
|
}
|
if ((this.doSendUrlFragment) && (fragment != null)) {
|
uri.append('#');
|
uri.append(encodeUriQuery(fragment));
|
}
|
vb.setResult("ok");
|
visitlogsaveinredis(vb);
|
return uri.toString();
|
}
|
|
|
/*
|
* 统计不同ip调用服务次数,并将其存入入redis
|
*/
|
private void visitlogsaveinredis(VistorBean vb) {
|
String fromip = vb.getRequestip();
|
vb.setDate(new Date());
|
vb.setVisitfromsys("ZJZT");
|
Jedis jedis = null;
|
try {
|
jedis = JedisUtils.getJedis();
|
jedis.sadd("visitlog", JSONObject.toJSONStringWithDateFormat(vb, "yyyy-MM-dd HH:mm:ss", SerializerFeature.PrettyFormat));
|
} catch (Exception e) {
|
|
log.error("redis包错");
|
} finally {
|
jedis.close();
|
}
|
|
|
}
|
|
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) {
|
|
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 && "application/xml; charset=utf-8".equals(entity.getContentType().getValue())) {
|
reader = new BufferedReader(new InputStreamReader(is));
|
StringBuffer sb = new StringBuffer();
|
String s = null;
|
while ((s = reader.readLine()) != null) {
|
|
sb.append(s);
|
}
|
String result = sb.toString();
|
BasicHttpEntity entity2 = new BasicHttpEntity();
|
if (result.indexOf("mpt") > -1 && result.indexOf("SkylineGlobe Server") > -1) {
|
cn.hutool.json.JSONObject xmlobj = XML.toJSONObject(result);
|
cn.hutool.json.JSONObject caps = (cn.hutool.json.JSONObject) xmlobj.get("Capabilities");
|
JSONArray array = caps.getJSONArray("Contents");
|
for (int i = 0; i < array.size(); i++) {
|
cn.hutool.json.JSONObject temp = array.getJSONObject(i);
|
if (temp.get("ows:Title").toString().contains(layer)) {
|
array.remove(i);
|
}
|
}
|
result = XML.toXml(xmlobj);
|
|
} else {
|
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("/arcgis/rest/services", "");
|
result = result.replaceAll("(http|https)://[^/]+/", "/");
|
|
}
|
|
byte[] bt;
|
|
bt = result.getBytes();
|
|
ByteArrayInputStream btinput = new ByteArrayInputStream(bt);
|
entity2.setContent(btinput);
|
entity2.setContentType(entity.getContentType());
|
entity2.setChunked(false);
|
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);
|
}
|
}
|
}
|
}
|
|
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) {
|
|
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"));
|
}
|
|
}
|