ByteTreeNode

This commit is contained in:
redkale
2024-10-05 19:04:50 +08:00
parent d2b8ef4471
commit a0a12bc709
6 changed files with 49 additions and 22 deletions

View File

@@ -65,8 +65,8 @@ public class DeMemberInfo {
protected static class DeMemberNode extends ByteTreeNode<DeMember> {
@Override
public void put(String key, DeMember value) {
super.put(key, value);
public ByteTreeNode<DeMember> put(String key, DeMember value) {
return super.put(key, value);
}
}
}

View File

@@ -71,12 +71,12 @@ public class HttpContext extends Context {
random.setSeed(Math.abs(System.nanoTime()));
}
ByteTreeNode<String> getUriPathNode() {
UriPathNode getUriPathNode() {
return uriPathNode;
}
void addUriPath(final String path) {
this.uriPathNode.put(path, path);
void addUriPath(final String path, HttpServlet servlet) {
this.uriPathNode.put(path, path, servlet);
byte[] bs = path.getBytes(StandardCharsets.UTF_8);
int index = bs.length >= uriPathCaches.length ? 0 : bs.length;
Map<ByteArray, String> map = uriPathCaches[index];
@@ -260,18 +260,31 @@ public class HttpContext extends Context {
protected static class UriPathNode extends ByteTreeNode<String> {
public UriPathNode() {
protected HttpServlet servlet;
protected UriPathNode() {
super();
}
@Override
protected void put(String key, String value) {
super.put(key, value);
protected UriPathNode(ByteTreeNode<String> parent, int index) {
super(parent, index);
}
protected ByteTreeNode<String> put(String key, String value, HttpServlet servlet) {
UriPathNode n = (UriPathNode) super.put(key, value);
n.servlet = servlet;
return n;
}
@Override
protected String subNodeValue(ByteTreeNode<String> node, String key, int subLen) {
return key.substring(0, subLen);
protected ByteTreeNode<String> createNode(ByteTreeNode<String> parent, int index, String key, int subLen) {
UriPathNode n = new UriPathNode(parent, index);
n.value = key.substring(0, subLen);
return n;
}
public HttpServlet getServlet() {
return servlet;
}
}

View File

@@ -322,7 +322,9 @@ public class HttpDispatcherServlet
response.finish(100, response.getHttpCode(100));
return;
}
if (request.isWebSocket()) {
if (request.pathServlet != null) {
servlet = request.pathServlet;
} else if (request.isWebSocket()) {
servlet = wsMappings.get(uri);
if (servlet == null && this.regexWsArray != null) {
for (MappingEntry en : regexWsArray) {
@@ -510,7 +512,7 @@ public class HttpDispatcherServlet
getServlets().forEach(s -> {
s.postStart(context, getServletConf(s));
});
forEachMappingKey((k, s) -> context.addUriPath(k));
forEachMappingKey(context::addUriPath);
}
public HttpServlet findServletByTopic(String topic) {

View File

@@ -20,6 +20,7 @@ import org.redkale.annotation.Comment;
import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.Request;
import org.redkale.net.http.HttpContext.UriPathNode;
import org.redkale.util.*;
import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty;
@@ -171,6 +172,8 @@ public class HttpRequest extends Request<HttpContext> {
protected String locale;
HttpServlet pathServlet;
// 主要给chunked和unzip用的
private ByteArray array;
@@ -761,6 +764,7 @@ public class HttpRequest extends Request<HttpContext> {
if (qst >= 0) { // 带?参数
if (pathNode != null) {
this.requestPath = pathNode.getValue();
this.pathServlet = ((UriPathNode) pathNode).getServlet();
} else if (decodeable) { // 需要转义
this.requestPath = toDecodeString(bytes, 0, qst, charset);
} else {
@@ -778,6 +782,7 @@ public class HttpRequest extends Request<HttpContext> {
} else { // 没有带?参数
if (pathNode != null) {
this.requestPath = pathNode.getValue();
this.pathServlet = ((UriPathNode) pathNode).getServlet();
} else if (decodeable) { // 需要转义
this.requestPath = toDecodeString(bytes, 0, bytes.length(), charset);
} else {
@@ -1303,6 +1308,7 @@ public class HttpRequest extends Request<HttpContext> {
this.respConvertType = null;
this.headers.clear();
// 其他
this.pathServlet = null;
this.newSessionid = null;
this.method = null;
this.getmethod = false;

View File

@@ -27,7 +27,7 @@ public class ByteTreeNode<T> {
this(null, 0);
}
private ByteTreeNode(ByteTreeNode<T> parent, int index) {
protected ByteTreeNode(ByteTreeNode<T> parent, int index) {
this.parent = parent;
if (index < 0 || index >= nodes.length) {
throw new RedkaleException(index + " is illegal");
@@ -70,7 +70,7 @@ public class ByteTreeNode<T> {
return n.value;
}
protected void put(String key, T value) {
protected ByteTreeNode<T> put(String key, T value) {
ByteTreeNode<T> n = this;
int i = 0;
for (char ch : key.toCharArray()) {
@@ -80,17 +80,17 @@ public class ByteTreeNode<T> {
i++;
ByteTreeNode<T> s = n.nodes[ch];
if (s == null) {
s = new ByteTreeNode(n, ch);
s.value = subNodeValue(s, key, i);
s = createNode(n, ch, key, i);
n.nodes[ch] = s;
}
n = s;
}
n.value = value;
return n;
}
protected T subNodeValue(ByteTreeNode<T> node, String key, int subLen) {
return null;
protected ByteTreeNode<T> createNode(ByteTreeNode<T> parent, int index, String key, int subLen) {
return new ByteTreeNode(parent, index);
}
@Override

View File

@@ -4,11 +4,13 @@
*/
package org.redkale.test.httpparser;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import org.junit.jupiter.api.*;
import org.redkale.net.http.HttpContext;
import org.redkale.net.http.HttpRequest;
import org.redkale.net.http.HttpServlet;
/**
*
@@ -116,11 +118,12 @@ public class HttpRequestTest {
httpConfig.sameHeader = true;
httpConfig.maxHeader = 16 * 1024;
httpConfig.maxBody = 64 * 1024;
HttpServlet servlet = new HttpServlet();
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.invoke(context, "/test/sleep200");
method.invoke(context, "/test/aaa");
method.invoke(context, "/test/sleep200", servlet);
method.invoke(context, "/test/aaa", servlet);
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";
@@ -139,6 +142,9 @@ public class HttpRequestTest {
r1 = req.readHeader(ByteBuffer.wrap(text.getBytes()), 0);
Assertions.assertEquals(0, r1);
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);
text = "GET /test/sleep201 HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n";