This commit is contained in:
地平线
2015-09-16 20:36:05 +08:00
parent 029a277eaa
commit 39635d0386
11 changed files with 325 additions and 12 deletions

View File

@@ -408,11 +408,11 @@ public final class Application {
try {
//Thread ctd = Thread.currentThread();
//ctd.setContextClassLoader(new URLClassLoader(new URL[0], ctd.getContextClassLoader()));
final String protocol = serconf.getValue("protocol", "").replaceFirst("\\..+", "");
final String protocol = serconf.getValue("protocol", "").replaceFirst("\\..+", "").toUpperCase();
NodeServer server = null;
if ("SNCP".equalsIgnoreCase(protocol)) {
if ("SNCP".equals(protocol)) {
server = new NodeSncpServer(Application.this, serconf);
} else if ("HTTP".equalsIgnoreCase(protocol) || "HTTPS".equalsIgnoreCase(protocol)) {
} else if ("HTTP".equals(protocol) || "HTTPS".equals(protocol)) {
server = new NodeHttpServer(Application.this, serconf);
} else {
if (!inited.get()) {
@@ -426,7 +426,8 @@ public final class Application {
final Class<? extends NodeServer> type = entry.getType();
NodeProtocol pros = type.getAnnotation(NodeProtocol.class);
for (String p : pros.value()) {
if (p.equalsIgnoreCase("SNCP") || p.equalsIgnoreCase("HTTP") || p.equalsIgnoreCase("HTTPS")) continue;
p = p.toUpperCase();
if ("SNCP".equals(p) || "HTTP".equals(p) || "HTTPS".equals(p)) continue;
final Class<? extends NodeServer> old = nodeClasses.get(p);
if (old != null && old != type) throw new RuntimeException("Protocol(" + p + ") had NodeServer-Class(" + old.getName() + ") but repeat NodeServer-Class(" + type.getName() + ")");
nodeClasses.put(p, type);

View File

@@ -32,7 +32,7 @@ public class IcepRequest extends Request {
if (buffer.remaining() < 20) return -1;
this.requestid = buffer.getShort();
char bodysize = buffer.getChar();
byte[] bytes = new byte[16];
byte[] bytes = new byte[16];
buffer.get(bytes);
StunHeader header = new StunHeader(this.requestid, bytes);
this.stunPacket = new StunPacket(header);
@@ -49,12 +49,13 @@ public class IcepRequest extends Request {
@Override
protected void prepare() {
}
@Override
protected void recycle() {
this.requestid = 0;
this.stunPacket = null;
super.recycle();
}
public short getRequestid() {

View File

@@ -40,7 +40,7 @@ public final class IcepServer extends Server {
final int port = this.address.getPort();
AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Buffer.creatCounter");
AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Buffer.cycleCounter");
int rcapacity = Math.max(this.capacity, 16 * 1024 + 8); //兼容 HTTP 2.0
int rcapacity = Math.max(this.capacity, 8 * 1024);
ObjectPool<ByteBuffer> bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize,
(Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> {
if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false;
@@ -50,9 +50,9 @@ public final class IcepServer extends Server {
AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Response.creatCounter");
AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("ICEP_" + port + ".Response.cycleCounter");
ObjectPool<Response> responsePool = IcepResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
IcepContext icepcontext = new IcepContext(this.serverStartTime, this.logger, executor, bufferPool, responsePool,
IcepContext localcontext = new IcepContext(this.serverStartTime, this.logger, executor, bufferPool, responsePool,
this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond);
responsePool.setCreator((Object... params) -> new IcepResponse(icepcontext, new IcepRequest(icepcontext)));
return icepcontext;
responsePool.setCreator((Object... params) -> new IcepResponse(localcontext, new IcepRequest(localcontext)));
return localcontext;
}
}

View File

@@ -14,7 +14,7 @@ import com.wentch.redkale.util.*;
*/
public abstract class IcepServlet implements Servlet<IcepRequest, IcepResponse> {
AnyValue conf; //当前HttpServlet的配置
AnyValue conf; //当前Servlet的配置
public abstract short getRequestid();

View File

@@ -0,0 +1,73 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.boot.ClassFilter.FilterEntry;
import com.wentch.redkale.boot.*;
import static com.wentch.redkale.boot.NodeServer.LINE_SEPARATOR;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
import com.wentch.redkale.util.AnyValue.DefaultAnyValue;
import java.lang.reflect.*;
import java.net.*;
import java.util.logging.*;
/**
*
* @author zhangjx
*/
@NodeProtocol({"SOCKS"})
public class NodeSocksServer extends NodeServer {
private final SocksServer socksServer;
public NodeSocksServer(Application application, AnyValue serconf) {
super(application, application.getResourceFactory().createChild(), createServer(application, serconf));
this.socksServer = (SocksServer) server;
}
private static Server createServer(Application application, AnyValue serconf) {
return new SocksServer(application.getStartTime(), application.getWatchFactory());
}
@Override
public InetSocketAddress getSocketAddress() {
return socksServer == null ? null : socksServer.getSocketAddress();
}
@Override
protected ClassFilter<Servlet> createServletClassFilter() {
return createClassFilter(null, null, SocksServlet.class, null, "servlets", "servlet");
}
@Override
protected void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception {
if (socksServer != null) loadSocksServlet(this.nodeConf.getAnyValue("servlets"), servletFilter);
}
protected void loadSocksServlet(final AnyValue conf, ClassFilter<? extends Servlet> filter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
for (FilterEntry<? extends Servlet> en : filter.getFilterEntrys()) {
Class<SocksServlet> clazz = (Class<SocksServlet>) en.getType();
if (Modifier.isAbstract(clazz.getModifiers())) continue;
final SocksServlet servlet = clazz.newInstance();
factory.inject(servlet);
DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty();
this.socksServer.addSocksServlet(servlet, servletConf);
if (sb != null) sb.append(threadName).append(" Loaded ").append(clazz.getName()).append(" --> ").append(format(servlet.getRequestid())).append(LINE_SEPARATOR);
}
if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString());
}
private static String format(short value) {
String str = Integer.toHexString(value);
if (str.length() == 1) return "0x000" + str;
if (str.length() == 2) return "0x00" + str;
if (str.length() == 3) return "0x0" + str;
return "0x" + str;
}
}

View File

@@ -0,0 +1,29 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
import com.wentch.redkale.watch.*;
import java.net.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.concurrent.*;
import java.util.logging.*;
/**
*
* @author zhangjx
*/
public class SocksContext extends Context {
public SocksContext(long serverStartTime, Logger logger, ExecutorService executor, ObjectPool<ByteBuffer> bufferPool,
ObjectPool<Response> responsePool, int maxbody, Charset charset, InetSocketAddress address, PrepareServlet prepare,
WatchFactory watch, int readTimeoutSecond, int writeTimeoutSecond) {
super(serverStartTime, logger, executor, bufferPool, responsePool, maxbody, charset,
address, prepare, watch, readTimeoutSecond, writeTimeoutSecond);
}
}

View File

@@ -0,0 +1,45 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
import java.io.*;
import java.util.*;
/**
*
* @author zhangjx
*/
public class SocksPrepareServlet extends PrepareServlet<SocksRequest, SocksResponse> {
private final HashMap<Short, SocksServlet> servletmaps = new HashMap<>();
public SocksPrepareServlet() {
}
@Override
public void init(Context context, AnyValue config) {
}
public void addSocksServlet(SocksServlet servlet, AnyValue conf) {
servlet.conf = conf;
this.servletmaps.put(servlet.getRequestid(), servlet);
}
// 28.[00,03,00,08, 21,12,a4,42,45,6f,4e,77,4e,47,71,55,32,37,77,39, 00,19,00,04,11,00,00,00]
@Override
public void execute(SocksRequest request, SocksResponse response) throws IOException {
SocksServlet servlet = servletmaps.get(request.getRequestid());
if (servlet != null) {
servlet.execute(request, response);
} else {
response.finish();
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import java.nio.*;
/**
*
* @author zhangjx
*/
public class SocksRequest extends Request {
private short requestid;
protected SocksRequest(SocksContext context) {
super(context);
}
@Override
protected int readHeader(ByteBuffer buffer) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
protected void readBody(ByteBuffer buffer) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
protected void prepare() {
}
@Override
protected void recycle() {
super.recycle();
}
public short getRequestid() {
return requestid;
}
public void setRequestid(short requestid) {
this.requestid = requestid;
}
}

View File

@@ -0,0 +1,26 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
import java.util.concurrent.atomic.*;
/**
*
* @author zhangjx
*/
public class SocksResponse extends Response<SocksRequest> {
protected SocksResponse(Context context, SocksRequest request) {
super(context, request);
}
public static ObjectPool<Response> createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator<Response> creator) {
return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((SocksResponse) x).prepare(), (x) -> ((SocksResponse) x).recycle());
}
}

View File

@@ -0,0 +1,58 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
import com.wentch.redkale.watch.*;
import java.nio.*;
import java.util.concurrent.atomic.*;
/**
*
* @author zhangjx
*/
public final class SocksServer extends Server {
public SocksServer() {
this(System.currentTimeMillis(), null);
}
public SocksServer(long serverStartTime, final WatchFactory watch) {
super(serverStartTime, "TCP", new SocksPrepareServlet(), watch);
}
@Override
public void init(AnyValue config) throws Exception {
super.init(config);
}
public void addSocksServlet(SocksServlet servlet, AnyValue conf) {
((SocksPrepareServlet) this.prepare).addSocksServlet(servlet, conf);
}
@Override
@SuppressWarnings("unchecked")
protected Context createContext() {
final int port = this.address.getPort();
AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Buffer.creatCounter");
AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Buffer.cycleCounter");
int rcapacity = Math.max(this.capacity, 8 * 1024);
ObjectPool<ByteBuffer> bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize,
(Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> {
if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false;
e.clear();
return true;
});
AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Response.creatCounter");
AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Response.cycleCounter");
ObjectPool<Response> responsePool = SocksResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
SocksContext localcontext = new SocksContext(this.serverStartTime, this.logger, executor, bufferPool, responsePool,
this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond);
responsePool.setCreator((Object... params) -> new SocksResponse(localcontext, new SocksRequest(localcontext)));
return localcontext;
}
}

View File

@@ -0,0 +1,30 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.wentch.redkale.net.socks;
import com.wentch.redkale.net.*;
import com.wentch.redkale.util.*;
/**
*
* @author zhangjx
*/
public abstract class SocksServlet implements Servlet<SocksRequest, SocksResponse> {
AnyValue conf; //当前Servlet的配置
public abstract short getRequestid();
@Override
public final boolean equals(Object obj) {
return obj != null && obj.getClass() == this.getClass();
}
@Override
public final int hashCode() {
return this.getClass().hashCode();
}
}