ByteTreeNode
This commit is contained in:
@@ -65,8 +65,8 @@ public class DeMemberInfo {
|
|||||||
protected static class DeMemberNode extends ByteTreeNode<DeMember> {
|
protected static class DeMemberNode extends ByteTreeNode<DeMember> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(String key, DeMember value) {
|
public ByteTreeNode<DeMember> put(String key, DeMember value) {
|
||||||
super.put(key, value);
|
return super.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ public class HttpContext extends Context {
|
|||||||
random.setSeed(Math.abs(System.nanoTime()));
|
random.setSeed(Math.abs(System.nanoTime()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteTreeNode<String> getUriPathNode() {
|
UriPathNode getUriPathNode() {
|
||||||
return uriPathNode;
|
return uriPathNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addUriPath(final String path) {
|
void addUriPath(final String path, HttpServlet servlet) {
|
||||||
this.uriPathNode.put(path, path);
|
this.uriPathNode.put(path, path, servlet);
|
||||||
byte[] bs = path.getBytes(StandardCharsets.UTF_8);
|
byte[] bs = path.getBytes(StandardCharsets.UTF_8);
|
||||||
int index = bs.length >= uriPathCaches.length ? 0 : bs.length;
|
int index = bs.length >= uriPathCaches.length ? 0 : bs.length;
|
||||||
Map<ByteArray, String> map = uriPathCaches[index];
|
Map<ByteArray, String> map = uriPathCaches[index];
|
||||||
@@ -260,18 +260,31 @@ public class HttpContext extends Context {
|
|||||||
|
|
||||||
protected static class UriPathNode extends ByteTreeNode<String> {
|
protected static class UriPathNode extends ByteTreeNode<String> {
|
||||||
|
|
||||||
public UriPathNode() {
|
protected HttpServlet servlet;
|
||||||
|
|
||||||
|
protected UriPathNode() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected UriPathNode(ByteTreeNode<String> parent, int index) {
|
||||||
protected void put(String key, String value) {
|
super(parent, index);
|
||||||
super.put(key, value);
|
}
|
||||||
|
|
||||||
|
protected ByteTreeNode<String> put(String key, String value, HttpServlet servlet) {
|
||||||
|
UriPathNode n = (UriPathNode) super.put(key, value);
|
||||||
|
n.servlet = servlet;
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String subNodeValue(ByteTreeNode<String> node, String key, int subLen) {
|
protected ByteTreeNode<String> createNode(ByteTreeNode<String> parent, int index, String key, int subLen) {
|
||||||
return key.substring(0, subLen);
|
UriPathNode n = new UriPathNode(parent, index);
|
||||||
|
n.value = key.substring(0, subLen);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpServlet getServlet() {
|
||||||
|
return servlet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -322,7 +322,9 @@ public class HttpDispatcherServlet
|
|||||||
response.finish(100, response.getHttpCode(100));
|
response.finish(100, response.getHttpCode(100));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (request.isWebSocket()) {
|
if (request.pathServlet != null) {
|
||||||
|
servlet = request.pathServlet;
|
||||||
|
} else if (request.isWebSocket()) {
|
||||||
servlet = wsMappings.get(uri);
|
servlet = wsMappings.get(uri);
|
||||||
if (servlet == null && this.regexWsArray != null) {
|
if (servlet == null && this.regexWsArray != null) {
|
||||||
for (MappingEntry en : regexWsArray) {
|
for (MappingEntry en : regexWsArray) {
|
||||||
@@ -510,7 +512,7 @@ public class HttpDispatcherServlet
|
|||||||
getServlets().forEach(s -> {
|
getServlets().forEach(s -> {
|
||||||
s.postStart(context, getServletConf(s));
|
s.postStart(context, getServletConf(s));
|
||||||
});
|
});
|
||||||
forEachMappingKey((k, s) -> context.addUriPath(k));
|
forEachMappingKey(context::addUriPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpServlet findServletByTopic(String topic) {
|
public HttpServlet findServletByTopic(String topic) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.redkale.annotation.Comment;
|
|||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
import org.redkale.convert.json.JsonConvert;
|
||||||
import org.redkale.net.Request;
|
import org.redkale.net.Request;
|
||||||
|
import org.redkale.net.http.HttpContext.UriPathNode;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
import static org.redkale.util.Utility.isEmpty;
|
import static org.redkale.util.Utility.isEmpty;
|
||||||
import static org.redkale.util.Utility.isNotEmpty;
|
import static org.redkale.util.Utility.isNotEmpty;
|
||||||
@@ -171,6 +172,8 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
|
|
||||||
protected String locale;
|
protected String locale;
|
||||||
|
|
||||||
|
HttpServlet pathServlet;
|
||||||
|
|
||||||
// 主要给chunked和unzip用的
|
// 主要给chunked和unzip用的
|
||||||
private ByteArray array;
|
private ByteArray array;
|
||||||
|
|
||||||
@@ -761,6 +764,7 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
if (qst >= 0) { // 带?参数
|
if (qst >= 0) { // 带?参数
|
||||||
if (pathNode != null) {
|
if (pathNode != null) {
|
||||||
this.requestPath = pathNode.getValue();
|
this.requestPath = pathNode.getValue();
|
||||||
|
this.pathServlet = ((UriPathNode) pathNode).getServlet();
|
||||||
} else if (decodeable) { // 需要转义
|
} else if (decodeable) { // 需要转义
|
||||||
this.requestPath = toDecodeString(bytes, 0, qst, charset);
|
this.requestPath = toDecodeString(bytes, 0, qst, charset);
|
||||||
} else {
|
} else {
|
||||||
@@ -778,6 +782,7 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
} else { // 没有带?参数
|
} else { // 没有带?参数
|
||||||
if (pathNode != null) {
|
if (pathNode != null) {
|
||||||
this.requestPath = pathNode.getValue();
|
this.requestPath = pathNode.getValue();
|
||||||
|
this.pathServlet = ((UriPathNode) pathNode).getServlet();
|
||||||
} else if (decodeable) { // 需要转义
|
} else if (decodeable) { // 需要转义
|
||||||
this.requestPath = toDecodeString(bytes, 0, bytes.length(), charset);
|
this.requestPath = toDecodeString(bytes, 0, bytes.length(), charset);
|
||||||
} else {
|
} else {
|
||||||
@@ -1303,6 +1308,7 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
this.respConvertType = null;
|
this.respConvertType = null;
|
||||||
this.headers.clear();
|
this.headers.clear();
|
||||||
// 其他
|
// 其他
|
||||||
|
this.pathServlet = null;
|
||||||
this.newSessionid = null;
|
this.newSessionid = null;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
this.getmethod = false;
|
this.getmethod = false;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class ByteTreeNode<T> {
|
|||||||
this(null, 0);
|
this(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteTreeNode(ByteTreeNode<T> parent, int index) {
|
protected ByteTreeNode(ByteTreeNode<T> parent, int index) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if (index < 0 || index >= nodes.length) {
|
if (index < 0 || index >= nodes.length) {
|
||||||
throw new RedkaleException(index + " is illegal");
|
throw new RedkaleException(index + " is illegal");
|
||||||
@@ -70,7 +70,7 @@ public class ByteTreeNode<T> {
|
|||||||
return n.value;
|
return n.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void put(String key, T value) {
|
protected ByteTreeNode<T> put(String key, T value) {
|
||||||
ByteTreeNode<T> n = this;
|
ByteTreeNode<T> n = this;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (char ch : key.toCharArray()) {
|
for (char ch : key.toCharArray()) {
|
||||||
@@ -80,17 +80,17 @@ public class ByteTreeNode<T> {
|
|||||||
i++;
|
i++;
|
||||||
ByteTreeNode<T> s = n.nodes[ch];
|
ByteTreeNode<T> s = n.nodes[ch];
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
s = new ByteTreeNode(n, ch);
|
s = createNode(n, ch, key, i);
|
||||||
s.value = subNodeValue(s, key, i);
|
|
||||||
n.nodes[ch] = s;
|
n.nodes[ch] = s;
|
||||||
}
|
}
|
||||||
n = s;
|
n = s;
|
||||||
}
|
}
|
||||||
n.value = value;
|
n.value = value;
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected T subNodeValue(ByteTreeNode<T> node, String key, int subLen) {
|
protected ByteTreeNode<T> createNode(ByteTreeNode<T> parent, int index, String key, int subLen) {
|
||||||
return null;
|
return new ByteTreeNode(parent, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.test.httpparser;
|
package org.redkale.test.httpparser;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.redkale.net.http.HttpContext;
|
import org.redkale.net.http.HttpContext;
|
||||||
import org.redkale.net.http.HttpRequest;
|
import org.redkale.net.http.HttpRequest;
|
||||||
|
import org.redkale.net.http.HttpServlet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -116,11 +118,12 @@ public class HttpRequestTest {
|
|||||||
httpConfig.sameHeader = true;
|
httpConfig.sameHeader = true;
|
||||||
httpConfig.maxHeader = 16 * 1024;
|
httpConfig.maxHeader = 16 * 1024;
|
||||||
httpConfig.maxBody = 64 * 1024;
|
httpConfig.maxBody = 64 * 1024;
|
||||||
|
HttpServlet servlet = new HttpServlet();
|
||||||
HttpContext context = new HttpContext(httpConfig);
|
HttpContext context = new HttpContext(httpConfig);
|
||||||
Method method = HttpContext.class.getDeclaredMethod("addUriPath", String.class);
|
Method method = HttpContext.class.getDeclaredMethod("addUriPath", String.class, HttpServlet.class);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
method.invoke(context, "/test/sleep200");
|
method.invoke(context, "/test/sleep200", servlet);
|
||||||
method.invoke(context, "/test/aaa");
|
method.invoke(context, "/test/aaa", servlet);
|
||||||
|
|
||||||
HttpRequestX req = new HttpRequestX(context);
|
HttpRequestX req = new HttpRequestX(context);
|
||||||
String text = "GET /test/azzzz HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n";
|
String text = "GET /test/azzzz HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n";
|
||||||
@@ -139,6 +142,9 @@ public class HttpRequestTest {
|
|||||||
r1 = req.readHeader(ByteBuffer.wrap(text.getBytes()), 0);
|
r1 = req.readHeader(ByteBuffer.wrap(text.getBytes()), 0);
|
||||||
Assertions.assertEquals(0, r1);
|
Assertions.assertEquals(0, r1);
|
||||||
Assertions.assertEquals("/test/sleep200", req.getRequestPath());
|
Assertions.assertEquals("/test/sleep200", req.getRequestPath());
|
||||||
|
Field serField = HttpRequest.class.getDeclaredField("pathServlet");
|
||||||
|
serField.setAccessible(true);
|
||||||
|
Assertions.assertEquals(servlet, serField.get(req));
|
||||||
|
|
||||||
req = new HttpRequestX(context);
|
req = new HttpRequestX(context);
|
||||||
text = "GET /test/sleep201 HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n";
|
text = "GET /test/sleep201 HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user