This commit is contained in:
Redkale
2018-05-04 08:50:17 +08:00
parent a5dd878c66
commit bfc6b04a30
6 changed files with 167 additions and 61 deletions

View File

@@ -79,6 +79,13 @@ public class Context {
//依赖注入工厂类
protected final ResourceFactory resourceFactory;
public Context(ContextConfig config) {
this(config.serverStartTime, config.logger, config.executor, config.sslContext,
config.bufferCapacity, config.bufferPool, config.responsePool, config.maxbody,
config.charset, config.address, config.resourceFactory, config.prepare,
config.aliveTimeoutSeconds, config.readTimeoutSeconds, config.writeTimeoutSeconds);
}
public Context(long serverStartTime, Logger logger, ThreadPoolExecutor executor, SSLContext sslContext,
int bufferCapacity, ObjectPool<ByteBuffer> bufferPool, ObjectPool<Response> responsePool,
final int maxbody, Charset charset, InetSocketAddress address, ResourceFactory resourceFactory,
@@ -188,4 +195,57 @@ public class Context {
public BsonConvert getBsonConvert() {
return bsonFactory.getConvert();
}
public static class ContextConfig {
//服务启动时间
public long serverStartTime;
//Server的线程池
public ThreadPoolExecutor executor;
//SSL
public SSLContext sslContext;
//ByteBuffer的容量默认8K
public int bufferCapacity;
//ByteBuffer对象池
public ObjectPool<ByteBuffer> bufferPool;
//Response对象池
public ObjectPool<Response> responsePool;
//服务的根Servlet
public PrepareServlet prepare;
//服务的监听地址
public InetSocketAddress address;
//字符集
public Charset charset;
//请求内容的大小上限, 默认64K
public int maxbody;
//keep alive IO读取的超时时间
public int aliveTimeoutSeconds;
//IO读取的超时时间
public int readTimeoutSeconds;
//IO写入的超时时间
public int writeTimeoutSeconds;
//日志Logger
public Logger logger;
//依赖注入工厂类
public ResourceFactory resourceFactory;
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
}

View File

@@ -6,14 +6,9 @@
package org.redkale.net.http;
import org.redkale.asm.MethodDebugVisitor;
import java.net.*;
import java.nio.*;
import java.nio.channels.CompletionHandler;
import java.nio.charset.*;
import java.security.*;
import java.util.concurrent.*;
import java.util.logging.*;
import javax.net.ssl.SSLContext;
import org.redkale.asm.*;
import static org.redkale.asm.Opcodes.*;
import org.redkale.net.*;
@@ -33,13 +28,8 @@ public class HttpContext extends Context {
protected final ConcurrentHashMap<Class, Creator> asyncHandlerCreators = new ConcurrentHashMap<>();
public HttpContext(long serverStartTime, Logger logger, ThreadPoolExecutor executor, SSLContext sslContext,
final int bufferCapacity, final ObjectPool<ByteBuffer> bufferPool, ObjectPool<Response> responsePool,
int maxbody, Charset charset, InetSocketAddress address, ResourceFactory resourceFactory,
PrepareServlet prepare, int aliveTimeoutSeconds, int readTimeoutSeconds, int writeTimeoutSeconds) {
super(serverStartTime, logger, executor, sslContext, bufferCapacity, bufferPool, responsePool,
maxbody, charset, address, resourceFactory, prepare, aliveTimeoutSeconds, readTimeoutSeconds, writeTimeoutSeconds);
public HttpContext(HttpContextConfig config) {
super(config);
random.setSeed(Math.abs(System.nanoTime()));
}
@@ -169,4 +159,8 @@ public class HttpContext extends Context {
}.loadClass(newDynName.replace('/', '.'), bytes);
return (Creator<H>) Creator.create(newHandlerClazz);
}
public static class HttpContextConfig extends ContextConfig {
}
}

View File

@@ -136,7 +136,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
private final Supplier<byte[]> dateSupplier;
private final HttpCookie defcookie;
private final HttpCookie defaultCookie;
private final List<HttpRender> renders;
@@ -148,21 +148,18 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((HttpResponse) x).prepare(), (x) -> ((HttpResponse) x).recycle());
}
public HttpResponse(HttpContext context, HttpRequest request,
String plainContentType, String jsonContentType,
String[][] defaultAddHeaders, String[][] defaultSetHeaders,
HttpCookie defcookie, boolean autoOptions, Supplier<byte[]> dateSupplier, List< HttpRender> renders) {
public HttpResponse(HttpContext context, HttpRequest request, HttpResponseConfig config) {
super(context, request);
this.plainContentType = plainContentType == null || plainContentType.isEmpty() ? "text/plain; charset=utf-8" : plainContentType;
this.jsonContentType = jsonContentType == null || jsonContentType.isEmpty() ? "application/json; charset=utf-8" : jsonContentType;
this.plainContentType = config.plainContentType == null || config.plainContentType.isEmpty() ? "text/plain; charset=utf-8" : config.plainContentType;
this.jsonContentType = config.jsonContentType == null || config.jsonContentType.isEmpty() ? "application/json; charset=utf-8" : config.jsonContentType;
this.plainContentTypeBytes = ("Content-Type: " + this.plainContentType + "\r\n").getBytes();
this.jsonContentTypeBytes = ("Content-Type: " + this.jsonContentType + "\r\n").getBytes();
this.defaultAddHeaders = defaultAddHeaders;
this.defaultSetHeaders = defaultSetHeaders;
this.defcookie = defcookie;
this.autoOptions = autoOptions;
this.dateSupplier = dateSupplier;
this.renders = renders;
this.defaultAddHeaders = config.defaultAddHeaders;
this.defaultSetHeaders = config.defaultSetHeaders;
this.defaultCookie = config.defaultCookie;
this.autoOptions = config.autoOptions;
this.dateSupplier = config.dateSupplier;
this.renders = config.renders;
this.hasRender = renders != null && !renders.isEmpty();
this.onlyoneHttpRender = renders != null && renders.size() == 1 ? renders.get(0) : null;
this.contentType = this.plainContentType;
@@ -907,13 +904,13 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
buffer.put((en.name + ": " + en.getValue() + "\r\n").getBytes());
}
if (request.newsessionid != null) {
String domain = defcookie == null ? null : defcookie.getDomain();
String domain = defaultCookie == null ? null : defaultCookie.getDomain();
if (domain == null) {
domain = "";
} else {
domain = "Domain=" + domain + "; ";
}
String path = defcookie == null ? null : defcookie.getPath();
String path = defaultCookie == null ? null : defaultCookie.getPath();
if (path == null || path.isEmpty()) path = "/";
if (request.newsessionid.isEmpty()) {
buffer.put(("Set-Cookie: " + HttpRequest.SESSIONID_NAME + "=; " + domain + "Path=" + path + "; Max-Age=0; HttpOnly\r\n").getBytes());
@@ -924,9 +921,9 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
if (this.cookies != null) {
for (HttpCookie cookie : this.cookies) {
if (cookie == null) continue;
if (defcookie != null) {
if (defcookie.getDomain() != null && cookie.getDomain() == null) cookie.setDomain(defcookie.getDomain());
if (defcookie.getPath() != null && cookie.getPath() == null) cookie.setPath(defcookie.getPath());
if (defaultCookie != null) {
if (defaultCookie.getDomain() != null && cookie.getDomain() == null) cookie.setDomain(defaultCookie.getDomain());
if (defaultCookie.getPath() != null && cookie.getPath() == null) cookie.setPath(defaultCookie.getPath());
}
buffer.put(("Set-Cookie: " + genString(cookie) + "\r\n").getBytes());
}
@@ -1173,4 +1170,28 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
}
}
public static class HttpResponseConfig {
public String plainContentType;
public String jsonContentType;
public String[][] defaultAddHeaders;
public String[][] defaultSetHeaders;
public HttpCookie defaultCookie;
public boolean autoOptions;
public Supplier<byte[]> dateSupplier;
public List< HttpRender> renders;
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
}

View File

@@ -17,6 +17,8 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import java.util.logging.Level;
import org.redkale.net.*;
import org.redkale.net.http.HttpContext.HttpContextConfig;
import org.redkale.net.http.HttpResponse.HttpResponseConfig;
import org.redkale.net.sncp.Sncp;
import org.redkale.service.Service;
import org.redkale.util.*;
@@ -391,15 +393,10 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
}
}
final String plainType = plainContentType;
final String jsonType = jsonContentType;
final String[][] addHeaders = defaultAddHeaders.isEmpty() ? null : defaultAddHeaders.toArray(new String[defaultAddHeaders.size()][]);
final String[][] setHeaders = defaultSetHeaders.isEmpty() ? null : defaultSetHeaders.toArray(new String[defaultSetHeaders.size()][]);
final boolean options = autoOptions;
Supplier<byte[]> dateSupplier0 = null;
Supplier<byte[]> dateSupplier = null;
if (datePeriod == 0) {
final ZoneId gmtZone = ZoneId.of("GMT");
dateSupplier0 = () -> ("Date: " + RFC_1123_DATE_TIME.format(java.time.ZonedDateTime.now(gmtZone)) + "\r\n").getBytes();
dateSupplier = () -> ("Date: " + RFC_1123_DATE_TIME.format(java.time.ZonedDateTime.now(gmtZone)) + "\r\n").getBytes();
} else if (datePeriod > 0) {
if (this.dateScheduler == null) {
this.dateScheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
@@ -413,21 +410,45 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
this.dateScheduler.scheduleAtFixedRate(() -> {
currDateBytes = ("Date: " + gmtDateFormat.format(new Date()) + "\r\n").getBytes();
}, 1000 - System.currentTimeMillis() % 1000, datePeriod, TimeUnit.MILLISECONDS);
dateSupplier0 = () -> currDateBytes;
dateSupplier = () -> currDateBytes;
}
}
final HttpCookie defCookie = defaultCookie;
final String addrHeader = remoteAddrHeader;
final Supplier<byte[]> dateSupplier = dateSupplier0;
final HttpResponseConfig respConfig = new HttpResponseConfig();
respConfig.plainContentType = plainContentType;
respConfig.jsonContentType = jsonContentType;
respConfig.defaultAddHeaders = defaultAddHeaders.isEmpty() ? null : defaultAddHeaders.toArray(new String[defaultAddHeaders.size()][]);
respConfig.defaultSetHeaders = defaultSetHeaders.isEmpty() ? null : defaultSetHeaders.toArray(new String[defaultSetHeaders.size()][]);
respConfig.defaultCookie = defaultCookie;
respConfig.autoOptions = autoOptions;
respConfig.dateSupplier = dateSupplier;
respConfig.renders = ((HttpPrepareServlet) prepare).renders;
AtomicLong createResponseCounter = new AtomicLong();
AtomicLong cycleResponseCounter = new AtomicLong();
ObjectPool<Response> responsePool = HttpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
HttpContext httpcontext = new HttpContext(this.serverStartTime, this.logger, executor, this.sslContext,
rcapacity, bufferPool, responsePool, this.maxbody, this.charset, this.address, this.resourceFactory,
this.prepare, this.aliveTimeoutSeconds, this.readTimeoutSeconds, this.writeTimeoutSeconds);
responsePool.setCreator((Object... params) -> new HttpResponse(httpcontext, new HttpRequest(httpcontext, addrHeader),
plainType, jsonType, addHeaders, setHeaders, defCookie, options, dateSupplier, ((HttpPrepareServlet) prepare).renders));
final HttpContextConfig contextConfig = new HttpContextConfig();
contextConfig.serverStartTime = this.serverStartTime;
contextConfig.logger = this.logger;
contextConfig.executor = this.executor;
contextConfig.sslContext = this.sslContext;
contextConfig.bufferCapacity = rcapacity;
contextConfig.bufferPool = bufferPool;
contextConfig.responsePool = responsePool;
contextConfig.maxbody = this.maxbody;
contextConfig.charset = this.charset;
contextConfig.address = this.address;
contextConfig.prepare = this.prepare;
contextConfig.resourceFactory = this.resourceFactory;
contextConfig.aliveTimeoutSeconds = this.aliveTimeoutSeconds;
contextConfig.readTimeoutSeconds = this.readTimeoutSeconds;
contextConfig.writeTimeoutSeconds = this.writeTimeoutSeconds;
HttpContext httpcontext = new HttpContext(contextConfig);
responsePool.setCreator((Object... params) -> new HttpResponse(httpcontext, new HttpRequest(httpcontext, addrHeader), respConfig));
return httpcontext;
}
}

View File

@@ -5,14 +5,7 @@
*/
package org.redkale.net.sncp;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import org.redkale.net.*;
import org.redkale.util.*;
/**
* <p>
@@ -22,11 +15,11 @@ import org.redkale.util.*;
*/
public class SncpContext extends Context {
public SncpContext(long serverStartTime, Logger logger, ThreadPoolExecutor executor, SSLContext sslContext,
int bufferCapacity, ObjectPool<ByteBuffer> bufferPool, ObjectPool<Response> responsePool,
int maxbody, Charset charset, InetSocketAddress address, ResourceFactory resourceFactory,
PrepareServlet prepare, int aliveTimeoutSeconds, int readTimeoutSeconds, int writeTimeoutSeconds) {
super(serverStartTime, logger, executor, sslContext, bufferCapacity, bufferPool, responsePool,
maxbody, charset, address, resourceFactory, prepare, aliveTimeoutSeconds, readTimeoutSeconds, writeTimeoutSeconds);
public SncpContext(SncpContextConfig config) {
super(config);
}
public static class SncpContextConfig extends ContextConfig {
}
}

View File

@@ -10,6 +10,7 @@ import java.util.*;
import java.util.concurrent.atomic.*;
import org.redkale.convert.bson.*;
import org.redkale.net.*;
import org.redkale.net.sncp.SncpContext.SncpContextConfig;
import org.redkale.service.Service;
import org.redkale.util.*;
@@ -106,9 +107,25 @@ public class SncpServer extends Server<DLong, SncpContext, SncpRequest, SncpResp
AtomicLong createResponseCounter = new AtomicLong();
AtomicLong cycleResponseCounter = new AtomicLong();
ObjectPool<Response> responsePool = SncpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
SncpContext sncpcontext = new SncpContext(this.serverStartTime, this.logger, executor, this.sslContext,
rcapacity, bufferPool, responsePool, this.maxbody, this.charset, this.address, this.resourceFactory,
this.prepare, this.aliveTimeoutSeconds, this.readTimeoutSeconds, this.writeTimeoutSeconds);
final SncpContextConfig contextConfig = new SncpContextConfig();
contextConfig.serverStartTime = this.serverStartTime;
contextConfig.logger = this.logger;
contextConfig.executor = this.executor;
contextConfig.sslContext = this.sslContext;
contextConfig.bufferCapacity = rcapacity;
contextConfig.bufferPool = bufferPool;
contextConfig.responsePool = responsePool;
contextConfig.maxbody = this.maxbody;
contextConfig.charset = this.charset;
contextConfig.address = this.address;
contextConfig.prepare = this.prepare;
contextConfig.resourceFactory = this.resourceFactory;
contextConfig.aliveTimeoutSeconds = this.aliveTimeoutSeconds;
contextConfig.readTimeoutSeconds = this.readTimeoutSeconds;
contextConfig.writeTimeoutSeconds = this.writeTimeoutSeconds;
SncpContext sncpcontext = new SncpContext(contextConfig);
responsePool.setCreator((Object... params) -> new SncpResponse(sncpcontext, new SncpRequest(sncpcontext)));
return sncpcontext;
}