初始化提交
1.请求支持postBody、post、get三种方式 2.支持网络速率、延迟、流量统计
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=UTF-8
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.7
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
version=1
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.wezoz.nat</groupId>
|
||||||
|
<artifactId>wezoz-nat-client</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>wezoz-nat-client</name>
|
||||||
|
<url>https://www.wezoz.com</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.socket</groupId>
|
||||||
|
<artifactId>socket.io-client</artifactId>
|
||||||
|
<version>0.8.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.24</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.17</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>4.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.wezoz.nat;
|
||||||
|
|
||||||
|
public interface CallListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态改变
|
||||||
|
*
|
||||||
|
* @param info
|
||||||
|
*/
|
||||||
|
public void statusCall(String info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件回调
|
||||||
|
*
|
||||||
|
* @param info
|
||||||
|
*/
|
||||||
|
public void eventCall(String info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流量统计
|
||||||
|
*
|
||||||
|
* @param traffic
|
||||||
|
*/
|
||||||
|
public void trafficCall(long traffic);
|
||||||
|
|
||||||
|
public void speedCall(long speed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭
|
||||||
|
*/
|
||||||
|
public void onClose();
|
||||||
|
|
||||||
|
public void ping(long ms);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,318 @@
|
|||||||
|
package com.wezoz.nat;
|
||||||
|
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.wezoz.nat.form.MainForm;
|
||||||
|
import com.wezoz.nat.utils.HttpClientUtils;
|
||||||
|
|
||||||
|
import io.socket.client.IO;
|
||||||
|
import io.socket.client.IO.Options;
|
||||||
|
import io.socket.client.Socket;
|
||||||
|
|
||||||
|
public class LocalServer {
|
||||||
|
|
||||||
|
private static final String HTTP_REQUEST = "httpRequest";
|
||||||
|
|
||||||
|
private static final String HTTP_RESPONSE = "httpResponse";
|
||||||
|
|
||||||
|
private static final String BIND_DOMAIN = "bindDomain";
|
||||||
|
|
||||||
|
private static final String BIND_DOMAIN_NOTICE = "bindDomainNotice";
|
||||||
|
|
||||||
|
private static final String PING = "clientPing";
|
||||||
|
|
||||||
|
private static final String PING_NOTICE = "clientPingNotice";
|
||||||
|
|
||||||
|
private Logger logger = Logger.getLogger(getClass());
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
|
||||||
|
private String server;
|
||||||
|
|
||||||
|
private String forward;
|
||||||
|
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
private long traffic = 0;// 流量统计
|
||||||
|
|
||||||
|
private long speed = 0;// 实时网速统计
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForward(String forward) {
|
||||||
|
this.forward = forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServer(String server) {
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CallListener callListener;
|
||||||
|
|
||||||
|
public void setCallListener(CallListener callListener) {
|
||||||
|
this.callListener = callListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ping() {
|
||||||
|
if (socket == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket.emit(PING, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindDomain() {
|
||||||
|
|
||||||
|
socket.emit(BIND_DOMAIN, domain);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws Exception {
|
||||||
|
|
||||||
|
Options opts = new Options();
|
||||||
|
opts.transports = new String[] { "websocket", "polling" };
|
||||||
|
socket = IO.socket(server, opts);
|
||||||
|
|
||||||
|
Map<String, String> eventMapper = new HashMap<String, String>();
|
||||||
|
|
||||||
|
eventMapper.put(Socket.EVENT_DISCONNECT, "断开连接");
|
||||||
|
eventMapper.put(Socket.EVENT_ERROR, "断开错误");
|
||||||
|
eventMapper.put(Socket.EVENT_CONNECTING, "正在连接服务器");
|
||||||
|
eventMapper.put(Socket.EVENT_CONNECT_TIMEOUT, "连接服务器超时");
|
||||||
|
eventMapper.put(Socket.EVENT_RECONNECTING, "自动重连服务器");
|
||||||
|
eventMapper.put(Socket.EVENT_RECONNECT, "准备重连服务器");
|
||||||
|
eventMapper.put(Socket.EVENT_CONNECT, "连接服务器成功");
|
||||||
|
eventMapper.put(HTTP_REQUEST, null);
|
||||||
|
eventMapper.put(BIND_DOMAIN_NOTICE, null);
|
||||||
|
eventMapper.put(PING_NOTICE, null);
|
||||||
|
Set<String> keys = eventMapper.keySet();
|
||||||
|
// 注册事件和提示信息
|
||||||
|
for (String k : keys) {
|
||||||
|
SocketListener socketListener = new SocketListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventCall(String eventName, String message, Object... args) {
|
||||||
|
if (null != message) {
|
||||||
|
callListener.eventCall("[" + eventName + "]:" + message);
|
||||||
|
}
|
||||||
|
switch (eventName) {
|
||||||
|
case Socket.EVENT_CONNECT:
|
||||||
|
callListener.statusCall("连接服务器成功");
|
||||||
|
LocalServer.this.bindDomain();
|
||||||
|
LocalServer.this.ping();
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST:
|
||||||
|
handlerRequest(args);
|
||||||
|
break;
|
||||||
|
case BIND_DOMAIN_NOTICE:
|
||||||
|
handlerBindDomain(args);
|
||||||
|
break;
|
||||||
|
case PING_NOTICE:
|
||||||
|
handlerPing(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
socketListener.setEventName(k);
|
||||||
|
socketListener.setMessage(eventMapper.get(k));
|
||||||
|
socket.on(k, socketListener);
|
||||||
|
}
|
||||||
|
socket.connect();
|
||||||
|
|
||||||
|
// 注册回调事件,实时统计网络速率
|
||||||
|
|
||||||
|
TimerTask task = new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long temp = speed;
|
||||||
|
speed = 0;
|
||||||
|
callListener.speedCall(temp);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Timer timer = new Timer();
|
||||||
|
timer.scheduleAtFixedRate(task, 0, 1000);
|
||||||
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ping();
|
||||||
|
}
|
||||||
|
}, 0, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlerPing(Object[] args) {
|
||||||
|
long time = (long) args[0];
|
||||||
|
long ms = System.currentTimeMillis() - time;
|
||||||
|
callListener.ping(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlerBindDomain(Object... args) {
|
||||||
|
try {
|
||||||
|
org.json.JSONObject jsonObject = (org.json.JSONObject) args[0];
|
||||||
|
int code = jsonObject.getInt("code");
|
||||||
|
String msg = jsonObject.getString("msg");
|
||||||
|
if (code == 1000) {
|
||||||
|
// 弹出地址
|
||||||
|
} else {
|
||||||
|
// 断开链接
|
||||||
|
socket.close();
|
||||||
|
callListener.onClose();
|
||||||
|
}
|
||||||
|
callListener.eventCall("[绑定域名]:" + msg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理远程的http请求
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
private void handlerRequest(Object... args) {
|
||||||
|
org.json.JSONObject object = (org.json.JSONObject) args[0];
|
||||||
|
JSONObject request = JSON.parseObject(object.toString());
|
||||||
|
String url = request.getString("url");
|
||||||
|
Map<String, Object> headers = request.getJSONObject("headers");
|
||||||
|
headers.remove("content-length");
|
||||||
|
String method = request.getString("method");
|
||||||
|
String eventName = request.getString("eventName");
|
||||||
|
|
||||||
|
Map<String, Object> params = request.getJSONObject("params");
|
||||||
|
|
||||||
|
String reqUrl = forward + url;
|
||||||
|
logger.info("收到请求: methon=" + method + " url=" + reqUrl);
|
||||||
|
if (callListener != null) {
|
||||||
|
callListener.eventCall("[远程请求]: methon=" + method + " url=" + reqUrl + " params:" + params + " headers:" + headers);
|
||||||
|
}
|
||||||
|
Response response = null;
|
||||||
|
// 发送请求
|
||||||
|
// 替换host
|
||||||
|
Set<String> keys = headers.keySet();
|
||||||
|
if ("POST".equals(method.toUpperCase())) {
|
||||||
|
|
||||||
|
// 查看是否是json或者xml请求一类
|
||||||
|
String encoding = "utf-8";
|
||||||
|
String contentType = null;
|
||||||
|
if (headers.get("content-type") != null) {
|
||||||
|
contentType = headers.get("content-type").toString();
|
||||||
|
String[] array = contentType.split(";");
|
||||||
|
contentType = array[0];
|
||||||
|
if (array.length > 1) {
|
||||||
|
String[] charsets = array[1].split("=");
|
||||||
|
if (charsets.length > 1) {
|
||||||
|
encoding = charsets[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HttpPost post = new HttpPost(reqUrl);
|
||||||
|
for (String k : keys) {
|
||||||
|
post.addHeader(k, String.valueOf(headers.get(k)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 默认类型application/x-www-form-urlencoded
|
||||||
|
if (contentType == null) {
|
||||||
|
contentType = "application/x-www-form-urlencoded";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容普通post和json/xml post
|
||||||
|
if (contentType.equals("application/x-www-form-urlencoded")) {
|
||||||
|
response = HttpClientUtils.post(post, params);
|
||||||
|
}else {
|
||||||
|
//其他的全部postBody
|
||||||
|
response = HttpClientUtils.postBody(post, request.getString("params"), encoding);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
response = new Response();
|
||||||
|
response.setStatusCode(500);
|
||||||
|
response.setStatusMessage("本地服务器报错:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ("GET".equals(method.toUpperCase())) {
|
||||||
|
HttpGet get = new HttpGet(reqUrl);
|
||||||
|
for (String k : keys) {
|
||||||
|
get.addHeader(k, String.valueOf(headers.get(k)));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
response = HttpClientUtils.get(get);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response = new Response();
|
||||||
|
response.setStatusCode(500);
|
||||||
|
response.setStatusMessage("本地服务器报错:" + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 提示请求不支持
|
||||||
|
response = new Response();
|
||||||
|
response.setStatusCode(500);
|
||||||
|
response.setEncoding("utf-8");
|
||||||
|
response.setStatusMessage(method + "请求类型暂时不支持!");
|
||||||
|
}
|
||||||
|
org.json.JSONObject jsonObject = new org.json.JSONObject();
|
||||||
|
try {
|
||||||
|
|
||||||
|
// 处理重定向
|
||||||
|
if (response.getStatusCode() == 302 || response.getStatusCode() == 307 || response.getStatusCode() == 303) {
|
||||||
|
// 处理地址
|
||||||
|
String localtion = response.getHeaders().get("Location");
|
||||||
|
localtion.replace(server, domain);
|
||||||
|
response.getHeaders().put("Location", localtion);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bytes = (byte[]) response.getBody();
|
||||||
|
long length = bytes.length;
|
||||||
|
this.traffic += length;
|
||||||
|
this.speed += length;
|
||||||
|
jsonObject.put("body", response.getBody());
|
||||||
|
jsonObject.put("headers", response.getHeaders());
|
||||||
|
jsonObject.put("statusCode", response.getStatusCode());
|
||||||
|
jsonObject.put("encoding", response.getEncoding());
|
||||||
|
jsonObject.put("statusMessage", response.getStatusMessage());
|
||||||
|
jsonObject.put("eventName", eventName);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
logger.info("请求响应:" + response);
|
||||||
|
if (callListener != null) {
|
||||||
|
callListener.eventCall("[目标响应]:" + response);
|
||||||
|
}
|
||||||
|
if (socket == null) {
|
||||||
|
callListener.eventCall("[服务关闭] The service has been closed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket.emit(HTTP_RESPONSE, jsonObject);
|
||||||
|
// 通知界面显示流量
|
||||||
|
callListener.trafficCall(this.traffic);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (socket != null) {
|
||||||
|
socket.close();
|
||||||
|
socket = null;
|
||||||
|
}
|
||||||
|
callListener.ping(0l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
new MainForm().setVisible(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.wezoz.nat;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Response implements Serializable{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5431808741731247591L;
|
||||||
|
|
||||||
|
private int statusCode = 200;// 状态码
|
||||||
|
|
||||||
|
private String statusMessage = "ok";// 状态消息
|
||||||
|
|
||||||
|
private Map<String, String> headers;// 请求头
|
||||||
|
|
||||||
|
private String encoding;// 编码
|
||||||
|
|
||||||
|
private Object body;// 响应内容
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCode(int statusCode) {
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatusMessage() {
|
||||||
|
return statusMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusMessage(String statusMessage) {
|
||||||
|
this.statusMessage = statusMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(Map<String, String> headers) {
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncoding() {
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoding(String encoding) {
|
||||||
|
this.encoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(Object body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Response [statusCode=" + statusCode + ", statusMessage=" + statusMessage + ", headers=" + headers + ", encoding=" + encoding + ", body={}]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.wezoz.nat;
|
||||||
|
|
||||||
|
import io.socket.emitter.Emitter.Listener;
|
||||||
|
|
||||||
|
public abstract class SocketListener implements Listener {
|
||||||
|
|
||||||
|
private String eventName;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventName(String eventName) {
|
||||||
|
this.eventName = eventName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventName() {
|
||||||
|
return eventName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(Object... args) {
|
||||||
|
this.eventCall(this.getEventName(),this.getMessage(), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调事件
|
||||||
|
*
|
||||||
|
* @param eventName
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public abstract void eventCall(String eventName,String message, Object... args);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.wezoz.nat.form;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
|
public class BaseForm extends JFrame {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8446051052250946428L;
|
||||||
|
|
||||||
|
public BaseForm() {
|
||||||
|
getContentPane().setLayout(null);
|
||||||
|
getContentPane().setBackground(new Color(248, 251, 253));
|
||||||
|
this.addWindowListener(new WindowAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
System.exit(0);
|
||||||
|
super.windowClosing(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ImageIcon imageIcon = new ImageIcon(getClass().getResource("/logo.png"));
|
||||||
|
|
||||||
|
this.setIconImage(imageIcon.getImage());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.wezoz.nat.form;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
|
public class LoginForm extends BaseForm {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8577615925651575124L;
|
||||||
|
|
||||||
|
private JTextField txtUsername;
|
||||||
|
|
||||||
|
private JTextField txtPassword;
|
||||||
|
|
||||||
|
public LoginForm() {
|
||||||
|
setResizable(false);
|
||||||
|
|
||||||
|
|
||||||
|
txtUsername = new JTextField();
|
||||||
|
txtUsername.setForeground(new Color(104, 104, 104));
|
||||||
|
txtUsername.setBounds(69, 66, 235, 41);
|
||||||
|
|
||||||
|
getContentPane().add(txtUsername);
|
||||||
|
txtUsername.setColumns(10);
|
||||||
|
|
||||||
|
txtPassword = new JTextField();
|
||||||
|
txtPassword.setToolTipText("密码");
|
||||||
|
txtPassword.setColumns(10);
|
||||||
|
txtPassword.setForeground(new Color(104, 104, 104));
|
||||||
|
txtPassword.setBounds(69, 122, 235, 41);
|
||||||
|
getContentPane().add(txtPassword);
|
||||||
|
|
||||||
|
JButton btnLogin = new JButton("登录");
|
||||||
|
btnLogin.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
new MainForm().setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnLogin.setBounds(187, 185, 117, 47);
|
||||||
|
getContentPane().add(btnLogin);
|
||||||
|
|
||||||
|
JButton btnReg = new JButton("注册");
|
||||||
|
btnReg.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (java.awt.Desktop.isDesktopSupported()) {
|
||||||
|
try {
|
||||||
|
// 创建一个URI实例
|
||||||
|
URI uri = URI.create("https://www.wezoz.com/register/");
|
||||||
|
// 获取当前系统桌面扩展
|
||||||
|
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
|
||||||
|
// 判断系统桌面是否支持要执行的功能
|
||||||
|
if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||||
|
// 获取系统默认浏览器打开链接
|
||||||
|
dp.browse(uri);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e1) {
|
||||||
|
// 此为uri为空时抛出异常
|
||||||
|
} catch (IOException e2) {
|
||||||
|
// 此为无法获取系统默认浏览器
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnReg.setBounds(69, 185, 117, 47);
|
||||||
|
getContentPane().add(btnReg);
|
||||||
|
this.setSize(400, 300);
|
||||||
|
this.setLocationRelativeTo(null);
|
||||||
|
this.setTitle("Wezoz NAT 登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new LoginForm().setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
package com.wezoz.nat.form;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.border.EtchedBorder;
|
||||||
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
|
import com.wezoz.nat.CallListener;
|
||||||
|
import com.wezoz.nat.LocalServer;
|
||||||
|
|
||||||
|
public class MainForm extends BaseForm {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8577615925651575124L;
|
||||||
|
|
||||||
|
private JTextField txtHost;
|
||||||
|
|
||||||
|
private JTextArea txtConsole;
|
||||||
|
|
||||||
|
private JButton btnAction;
|
||||||
|
|
||||||
|
private JLabel lblStatus;
|
||||||
|
|
||||||
|
private LocalServer server;
|
||||||
|
|
||||||
|
private JPanel panelSetting;
|
||||||
|
|
||||||
|
private JScrollPane panelConsole;
|
||||||
|
|
||||||
|
private JLabel label_1;
|
||||||
|
|
||||||
|
private JTextField txtDomain;
|
||||||
|
|
||||||
|
private JLabel lblwezozcom;
|
||||||
|
|
||||||
|
private JLabel lablTraffic;
|
||||||
|
|
||||||
|
private JLabel label_3;
|
||||||
|
|
||||||
|
private JLabel lblSpeed;
|
||||||
|
private JLabel lblPing;
|
||||||
|
|
||||||
|
public MainForm() {
|
||||||
|
setTitle("Wezoz NAT");
|
||||||
|
this.setSize(546, 432);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
JLabel label = new JLabel("状态:");
|
||||||
|
label.setBounds(20, 27, 61, 16);
|
||||||
|
getContentPane().add(label);
|
||||||
|
|
||||||
|
lblStatus = new JLabel("服务停止");
|
||||||
|
lblStatus.setBounds(60, 27, 280, 16);
|
||||||
|
getContentPane().add(lblStatus);
|
||||||
|
|
||||||
|
btnAction = new JButton("启动服务");
|
||||||
|
btnAction.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (btnAction.getText().equals("启动服务")) {
|
||||||
|
try {
|
||||||
|
String host = txtHost.getText();
|
||||||
|
server = new LocalServer();
|
||||||
|
server.setServer("http://wezoz.com:3001");
|
||||||
|
server.setForward(host);
|
||||||
|
server.setDomain(txtDomain.getText());
|
||||||
|
server.setCallListener(new CallListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void statusCall(String info) {
|
||||||
|
lblStatus.setText(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventCall(String info) {
|
||||||
|
txtConsole.append(info + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
server.stop();
|
||||||
|
lblStatus.setText("服务停止");
|
||||||
|
btnAction.setText("启动服务");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trafficCall(long traffic) {
|
||||||
|
|
||||||
|
lablTraffic.setText(formatNumber(traffic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void speedCall(long speed) {
|
||||||
|
lblSpeed.setText(formatNumber(speed)+"/s");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ping(long ms) {
|
||||||
|
lblPing.setText(ms+"ms");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.start();
|
||||||
|
btnAction.setText("停止服务");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
lblStatus.setText("启动失败!请检查地址是否正确");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
server.stop();
|
||||||
|
lblStatus.setText("服务停止");
|
||||||
|
btnAction.setText("启动服务");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnAction.setBounds(339, 22, 117, 29);
|
||||||
|
getContentPane().add(btnAction);
|
||||||
|
|
||||||
|
panelSetting = new JPanel();
|
||||||
|
panelSetting.setBackground(new Color(248, 251, 253));
|
||||||
|
panelSetting.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "\u7F51\u7EDC\u53C2\u6570", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
|
||||||
|
panelSetting.setBounds(19, 55, 506, 119);
|
||||||
|
getContentPane().add(panelSetting);
|
||||||
|
panelSetting.setLayout(null);
|
||||||
|
|
||||||
|
JLabel lblip = new JLabel("转发地址:");
|
||||||
|
lblip.setBounds(18, 64, 65, 16);
|
||||||
|
panelSetting.add(lblip);
|
||||||
|
|
||||||
|
txtHost = new JTextField();
|
||||||
|
txtHost.setText("http://127.0.0.1:8080");
|
||||||
|
txtHost.setBounds(82, 59, 331, 26);
|
||||||
|
panelSetting.add(txtHost);
|
||||||
|
txtHost.setColumns(10);
|
||||||
|
|
||||||
|
label_1 = new JLabel("绑定域名:");
|
||||||
|
label_1.setBounds(18, 30, 65, 16);
|
||||||
|
panelSetting.add(label_1);
|
||||||
|
|
||||||
|
txtDomain = new JTextField();
|
||||||
|
txtDomain.setColumns(10);
|
||||||
|
txtDomain.setBounds(82, 25, 108, 26);
|
||||||
|
panelSetting.add(txtDomain);
|
||||||
|
|
||||||
|
lblwezozcom = new JLabel(".wezoz.com");
|
||||||
|
lblwezozcom.setBounds(189, 30, 90, 16);
|
||||||
|
panelSetting.add(lblwezozcom);
|
||||||
|
|
||||||
|
JLabel label_2 = new JLabel("流出流量:");
|
||||||
|
label_2.setBounds(18, 92, 65, 16);
|
||||||
|
panelSetting.add(label_2);
|
||||||
|
|
||||||
|
lablTraffic = new JLabel("0KB");
|
||||||
|
lablTraffic.setBounds(82, 92, 96, 16);
|
||||||
|
panelSetting.add(lablTraffic);
|
||||||
|
|
||||||
|
label_3 = new JLabel("速度:");
|
||||||
|
label_3.setBounds(162, 92, 39, 16);
|
||||||
|
panelSetting.add(label_3);
|
||||||
|
|
||||||
|
lblSpeed = new JLabel("0KB");
|
||||||
|
lblSpeed.setBounds(199, 92, 73, 16);
|
||||||
|
panelSetting.add(lblSpeed);
|
||||||
|
|
||||||
|
JLabel label_4 = new JLabel("延迟:");
|
||||||
|
label_4.setBounds(305, 92, 39, 16);
|
||||||
|
panelSetting.add(label_4);
|
||||||
|
|
||||||
|
lblPing = new JLabel("0ms");
|
||||||
|
lblPing.setBounds(342, 92, 123, 16);
|
||||||
|
panelSetting.add(lblPing);
|
||||||
|
|
||||||
|
txtConsole = new JTextArea() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 8749801166570350982L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(String str) {
|
||||||
|
this.setCaretPosition(this.getDocument().getLength());
|
||||||
|
str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + " - " + str;
|
||||||
|
if (this.getText().length() > 100000) {
|
||||||
|
this.setText("");
|
||||||
|
}
|
||||||
|
super.append(str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
txtConsole.setText("准备就绪\n");
|
||||||
|
txtConsole.setBounds(19, 181, 437, 129);
|
||||||
|
panelConsole = new JScrollPane(txtConsole, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||||
|
panelConsole.setLocation(20, 210);
|
||||||
|
panelConsole.setSize(431, 150);
|
||||||
|
|
||||||
|
getContentPane().add(panelConsole);
|
||||||
|
this.addComponentListener(new ComponentAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
change();
|
||||||
|
super.componentResized(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
change();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatNumber(long traffic) {
|
||||||
|
String text = null;
|
||||||
|
DecimalFormat format = new DecimalFormat("#.##");
|
||||||
|
Double value = traffic * 0.0001221d;
|
||||||
|
if (value <= 1024) {
|
||||||
|
text = format.format(value) + "KB";
|
||||||
|
} else if (value / 1024 > 1) {
|
||||||
|
text = format.format((value / 1024)) + "MB";
|
||||||
|
} else if (value / 1024 / 1024 > 1) {
|
||||||
|
text = format.format((value / 1024 / 1024)) + "GB";
|
||||||
|
} else if (value / 1024 / 1024 / 1024 > 1) {
|
||||||
|
text = format.format((value / 1024 / 1024 / 1024)) + "TB";
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void change() {
|
||||||
|
int width = MainForm.this.getWidth();
|
||||||
|
int height = MainForm.this.getHeight();
|
||||||
|
int wv = width - 40;
|
||||||
|
panelSetting.setSize(wv, panelSetting.getHeight());
|
||||||
|
panelConsole.setSize(wv, height - panelConsole.getY() - 40);
|
||||||
|
btnAction.setLocation(width - 20 - btnAction.getWidth(), btnAction.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new MainForm().setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,455 @@
|
|||||||
|
package com.wezoz.nat.utils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.SSLContextBuilder;
|
||||||
|
import org.apache.http.conn.ssl.TrustStrategy;
|
||||||
|
import org.apache.http.conn.ssl.X509HostnameVerifier;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.wezoz.nat.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http请求工具 httpclient4.5
|
||||||
|
*
|
||||||
|
* @author panjing
|
||||||
|
* @project wootop-common
|
||||||
|
* @date 2016年4月19日 上午11:20:43
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class HttpClientUtils {
|
||||||
|
|
||||||
|
private static Log log = LogFactory.getLog(HttpClientUtils.class);
|
||||||
|
|
||||||
|
|
||||||
|
public final static String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
|
||||||
|
public final static String CONTENT_TYPE = "Content-Type";
|
||||||
|
|
||||||
|
public final static String TEXT_HTML = "text/html";
|
||||||
|
|
||||||
|
public final static int STATUS_CODE_SUCCESS = 200;
|
||||||
|
|
||||||
|
private static CloseableHttpClient httpClient;
|
||||||
|
|
||||||
|
private static PoolingHttpClientConnectionManager connMgr;
|
||||||
|
|
||||||
|
private static RequestConfig requestConfig;
|
||||||
|
|
||||||
|
private static final int MAX_TIMEOUT = 7000;
|
||||||
|
|
||||||
|
static {
|
||||||
|
// 设置连接池
|
||||||
|
connMgr = new PoolingHttpClientConnectionManager();
|
||||||
|
// 设置连接池大小
|
||||||
|
connMgr.setMaxTotal(100);
|
||||||
|
connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
|
||||||
|
|
||||||
|
RequestConfig.Builder configBuilder = RequestConfig.custom();
|
||||||
|
// 设置连接超时
|
||||||
|
configBuilder.setConnectTimeout(MAX_TIMEOUT);
|
||||||
|
// 设置读取超时
|
||||||
|
configBuilder.setSocketTimeout(MAX_TIMEOUT);
|
||||||
|
// 设置从连接池获取连接实例的超时
|
||||||
|
configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
|
||||||
|
// 在提交请求之前 测试连接是否可用
|
||||||
|
configBuilder.setStaleConnectionCheckEnabled(true);
|
||||||
|
requestConfig = configBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CloseableHttpClient getClient() {
|
||||||
|
|
||||||
|
if (httpClient == null) {
|
||||||
|
//不重定向处理
|
||||||
|
RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).setConnectionRequestTimeout(100000).setSocketTimeout(100000).setRedirectsEnabled(false).build();
|
||||||
|
|
||||||
|
httpClient = HttpClients.custom().setDefaultRequestConfig(config).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get请求
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Response get(String url) {
|
||||||
|
|
||||||
|
HttpGet httpGet = new HttpGet(url);
|
||||||
|
return get(httpGet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get请求
|
||||||
|
*
|
||||||
|
* @param httpGet
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Response get(HttpGet httpGet) {
|
||||||
|
Response response = new Response();
|
||||||
|
try {
|
||||||
|
CloseableHttpResponse res = getClient().execute(httpGet);
|
||||||
|
response = getContent(res);
|
||||||
|
|
||||||
|
} catch (SocketTimeoutException e) {
|
||||||
|
log.error("Read timed out:" + httpGet.getURI());
|
||||||
|
response.setStatusCode(502);
|
||||||
|
response.setStatusMessage("读取超时");
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatusCode(500);
|
||||||
|
response.setStatusMessage("请求本地服务器出错");
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post请求
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Response post(String url, Map<String, Object> params) {
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
|
||||||
|
return post(httpPost, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response postSSL(String url, Map<String, Object> params) {
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
return postSSL(httpPost, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post请求
|
||||||
|
*
|
||||||
|
* @param httpPost
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Response post(HttpPost httpPost, Map<String, Object> params) {
|
||||||
|
Response res = null;
|
||||||
|
try {
|
||||||
|
if (params != null) {
|
||||||
|
List<BasicNameValuePair> basicNameValuePairs = new ArrayList<BasicNameValuePair>();
|
||||||
|
|
||||||
|
Set<String> keySet = params.keySet();
|
||||||
|
for (String key : keySet) {
|
||||||
|
Object obj = params.get(key);
|
||||||
|
String value = null;
|
||||||
|
if (obj != null) {
|
||||||
|
value = String.valueOf(obj);
|
||||||
|
}
|
||||||
|
basicNameValuePairs.add(new BasicNameValuePair(key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpEntity httpEntity = new UrlEncodedFormEntity(basicNameValuePairs, DEFAULT_ENCODING);
|
||||||
|
|
||||||
|
httpPost.setEntity(httpEntity);
|
||||||
|
}
|
||||||
|
CloseableHttpResponse response = getClient().execute(httpPost);
|
||||||
|
res = getContent(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response postBody(HttpPost httpPost, String body,String encoding) {
|
||||||
|
Response res = null;
|
||||||
|
try {
|
||||||
|
httpPost.setEntity(new StringEntity(body, encoding));
|
||||||
|
CloseableHttpResponse response = getClient().execute(httpPost);
|
||||||
|
res = getContent(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response gzipPost(String url, Map<String, Object> params) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
return gzipPost(httpPost, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response gzipPost(HttpPost httpPost, Map<String, Object> params) {
|
||||||
|
|
||||||
|
Response res = null;
|
||||||
|
try {
|
||||||
|
// httpPost.addHeader("User-Agent", DEFAULT_USER_AGENT);
|
||||||
|
httpPost.addHeader("Content-Encoding", "gzip");
|
||||||
|
if (params != null) {
|
||||||
|
List<BasicNameValuePair> basicNameValuePairs = new ArrayList<BasicNameValuePair>();
|
||||||
|
|
||||||
|
Set<String> keySet = params.keySet();
|
||||||
|
for (String key : keySet) {
|
||||||
|
Object obj = params.get(key);
|
||||||
|
String value = null;
|
||||||
|
if (obj != null) {
|
||||||
|
value = String.valueOf(obj);
|
||||||
|
}
|
||||||
|
basicNameValuePairs.add(new BasicNameValuePair(key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// HttpEntity httpEntity = new
|
||||||
|
// UrlEncodedFormEntity(basicNameValuePairs, DEFAULT_ENCODING);
|
||||||
|
String str = JSON.toJSONString(params);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
GZIPOutputStream gos = new GZIPOutputStream(baos);
|
||||||
|
gos.write(str.getBytes("utf-8"));
|
||||||
|
gos.flush();
|
||||||
|
|
||||||
|
byte[] bs = baos.toByteArray();
|
||||||
|
HttpEntity httpEntity = new ByteArrayEntity(bs);
|
||||||
|
|
||||||
|
httpPost.setEntity(httpEntity);
|
||||||
|
}
|
||||||
|
CloseableHttpResponse response = getClient().execute(httpPost);
|
||||||
|
res = getContent(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Response postSSL(HttpPost httpPost, Map<String, Object> params) {
|
||||||
|
|
||||||
|
Response res = null;
|
||||||
|
try {
|
||||||
|
// httpPost.addHeader("User-Agent", DEFAULT_USER_AGENT);
|
||||||
|
List<BasicNameValuePair> basicNameValuePairs = new ArrayList<BasicNameValuePair>();
|
||||||
|
|
||||||
|
Set<String> keySet = params.keySet();
|
||||||
|
for (String key : keySet) {
|
||||||
|
Object obj = params.get(key);
|
||||||
|
String value = null;
|
||||||
|
if (obj != null) {
|
||||||
|
value = String.valueOf(obj);
|
||||||
|
}
|
||||||
|
basicNameValuePairs.add(new BasicNameValuePair(key, value));
|
||||||
|
}
|
||||||
|
HttpEntity httpEntity = new UrlEncodedFormEntity(basicNameValuePairs, DEFAULT_ENCODING);
|
||||||
|
|
||||||
|
httpPost.setEntity(httpEntity);
|
||||||
|
URI uri = httpPost.getURI();
|
||||||
|
new SSLHttpClient().registerSSL(uri.getHost(), "https", uri.getPort(), uri.getScheme());
|
||||||
|
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
|
||||||
|
CloseableHttpResponse response = httpClient.execute(httpPost);
|
||||||
|
res = getContent(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
|
||||||
|
|
||||||
|
SSLConnectionSocketFactory sslsf = null;
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
|
||||||
|
|
||||||
|
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verify(String arg0, SSLSession arg1) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verify(String host, SSLSocket ssl) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verify(String host, X509Certificate cert) throws SSLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return sslsf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能: postBody形式发送数据
|
||||||
|
// @param urlPath 对方地址
|
||||||
|
// @param json 要传送的数据
|
||||||
|
// @return
|
||||||
|
// @throws Exception
|
||||||
|
public static String postBody(String urlPath, String data) throws Exception {
|
||||||
|
|
||||||
|
// Configure and open a connection to the site you will send the
|
||||||
|
// request
|
||||||
|
URL url = new URL(urlPath);
|
||||||
|
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||||
|
// 设置doOutput属性为true表示将使用此urlConnection写入数据
|
||||||
|
urlConnection.setDoOutput(true);
|
||||||
|
// 定义待写入数据的内容类型,我们设置为application/x-www-form-urlencoded类型
|
||||||
|
urlConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
|
||||||
|
// 得到请求的输出流对象
|
||||||
|
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
|
||||||
|
// 把数据写入请求的Body
|
||||||
|
out.write(data);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
// 从服务器读取响应
|
||||||
|
InputStream inputStream = urlConnection.getInputStream();
|
||||||
|
String encoding = urlConnection.getContentEncoding();
|
||||||
|
String body = IOUtils.toString(inputStream, encoding);
|
||||||
|
if (urlConnection.getResponseCode() != 200) {
|
||||||
|
throw new Exception(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEncoding(CloseableHttpResponse response) {
|
||||||
|
|
||||||
|
String encoding = null;
|
||||||
|
|
||||||
|
Header[] headers = response.getHeaders(CONTENT_TYPE);
|
||||||
|
if (headers != null && headers.length > 0) {
|
||||||
|
Header header = headers[0];
|
||||||
|
String value = header.getValue();
|
||||||
|
value = value.replaceAll(" ", "");
|
||||||
|
value = value.toLowerCase();
|
||||||
|
int index = 0;
|
||||||
|
if ((index = value.lastIndexOf("charset")) != -1) {
|
||||||
|
String[] array = value.substring(index).split("=");
|
||||||
|
if (array.length > 1) {
|
||||||
|
encoding = array[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取响应内容
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
* @throws ParseException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static Response getContent(CloseableHttpResponse response) throws ParseException, IOException {
|
||||||
|
|
||||||
|
Response res = new Response();
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
if (entity == null) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bytes = readBytes(entity.getContent());
|
||||||
|
String encoding = getEncoding(response);
|
||||||
|
if (encoding == null) {
|
||||||
|
encoding = "utf-8";
|
||||||
|
}
|
||||||
|
res.setBody(bytes);
|
||||||
|
res.setEncoding(encoding);
|
||||||
|
res.setStatusCode(response.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
Map<String, String> headersMap = new HashMap<String, String>();
|
||||||
|
Header[] headers = response.getAllHeaders();
|
||||||
|
for (Header header : headers) {
|
||||||
|
headersMap.put(header.getName(), header.getValue());
|
||||||
|
}
|
||||||
|
res.setHeaders(headersMap);
|
||||||
|
|
||||||
|
// content = new String(bytes, encoding);
|
||||||
|
EntityUtils.consume(response.getEntity());
|
||||||
|
response.close();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将流读取为字节数组
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static byte[] readBytes(InputStream in) throws IOException {
|
||||||
|
|
||||||
|
BufferedInputStream bufin = new BufferedInputStream(in);
|
||||||
|
int buffSize = 1024;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);
|
||||||
|
|
||||||
|
byte[] temp = new byte[buffSize];
|
||||||
|
int size = 0;
|
||||||
|
while ((size = bufin.read(temp)) != -1) {
|
||||||
|
out.write(temp, 0, size);
|
||||||
|
}
|
||||||
|
bufin.close();
|
||||||
|
|
||||||
|
byte[] content = out.toByteArray();
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(get("http://localhost:8080/wootop-doctor/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package com.wezoz.nat.utils;
|
||||||
|
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class SSLHttpClient {
|
||||||
|
/**
|
||||||
|
* 注册SSL连接
|
||||||
|
* @param hostname 请求的主机名(IP或者域名)
|
||||||
|
* @param protocol 请求协议名称(TLS-安全传输层协议)
|
||||||
|
* @param port 端口号
|
||||||
|
* @param scheme 协议名称
|
||||||
|
* @return HttpClient实例
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws KeyManagementException
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient registerSSL(String hostname,String protocol,int port,String scheme)throws NoSuchAlgorithmException, KeyManagementException {
|
||||||
|
//创建一个默认的HttpClient
|
||||||
|
CloseableHttpClient httpclient = HttpClients.createDefault();
|
||||||
|
//创建SSL上下文实例
|
||||||
|
SSLContext ctx = SSLContext.getInstance(protocol);
|
||||||
|
//服务端证书验证
|
||||||
|
X509TrustManager tm = new X509TrustManager() {
|
||||||
|
/**
|
||||||
|
* 验证客户端证书
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain,String authType)
|
||||||
|
throws java.security.cert.CertificateException {
|
||||||
|
//这里跳过客户端证书 验证
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证服务端证书
|
||||||
|
* @param chain 证书链
|
||||||
|
* @param authType 使用的密钥交换算法,当使用来自服务器的密钥时authType为RSA
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain,String authType)
|
||||||
|
throws java.security.cert.CertificateException {
|
||||||
|
if (chain == null || chain.length == 0)
|
||||||
|
throw new IllegalArgumentException("null or zero-length certificate chain");
|
||||||
|
if (authType == null || authType.length() == 0)
|
||||||
|
throw new IllegalArgumentException("null or zero-length authentication type");
|
||||||
|
|
||||||
|
boolean br = false;
|
||||||
|
Principal principal = null;
|
||||||
|
for (X509Certificate x509Certificate : chain) {
|
||||||
|
principal = x509Certificate.getSubjectX500Principal();
|
||||||
|
if (principal != null) {
|
||||||
|
br = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!br) {
|
||||||
|
throw new CertificateException("服务端证书验证失败!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回CA发行的证书
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//初始化SSL上下文
|
||||||
|
ctx.init(null, new TrustManager[]{tm}, new java.security.SecureRandom());
|
||||||
|
//创建SSL连接
|
||||||
|
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||||
|
Scheme sch = new Scheme(scheme, port, socketFactory);
|
||||||
|
//注册SSL连接
|
||||||
|
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
|
||||||
|
return httpclient;
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
log4j.rootLogger=INFO,ERROR
|
||||||
|
|
||||||
|
log4j.appender=org.apache.log4j.RollingFileAppender
|
||||||
|
log4j.appender.File=wezoz-nat.log
|
||||||
|
log4j.appender.MaxFileSize=10MB
|
||||||
|
log4j.appender.Threshold=ALL
|
||||||
|
log4j.appender.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.layout.ConversionPattern=-%t %d{yyyy-MM-dd HH\:mm\:ss,SSS} -%p -%l -%m %n
|
||||||
|
log4j.appender.BufferSize=8192
|
||||||
|
|
||||||
|
|
||||||
|
log4j.appender.INFO=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.INFO.Target=System.out
|
||||||
|
log4j.appender.INFO.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.INFO.layout.ConversionPattern=-%t %d{yyyy-MM-dd HH\:mm\:ss,SSS} -%p -%l -%m %n
|
||||||
|
|
||||||
|
log4j.appender.ERROR=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.ERROR.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.ERROR.Target=System.out
|
||||||
|
log4j.appender.ERROR.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.ERROR.layout.ConversionPattern=-%t %d{yyyy-MM-dd HH\:mm\:ss,SSS} -%p -%l -%m %n
|
||||||
|
|
||||||
|
#log4j.logger.org.apache.http=OFF
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 288 KiB |
Reference in New Issue
Block a user