From a0a12bc7094c04c7663ba49722acc3f262c6b072 Mon Sep 17 00:00:00 2001 From: redkale Date: Sat, 5 Oct 2024 19:04:50 +0800 Subject: [PATCH] ByteTreeNode --- .../org/redkale/convert/DeMemberInfo.java | 4 +-- .../org/redkale/net/http/HttpContext.java | 31 +++++++++++++------ .../net/http/HttpDispatcherServlet.java | 6 ++-- .../org/redkale/net/http/HttpRequest.java | 6 ++++ .../java/org/redkale/util/ByteTreeNode.java | 12 +++---- .../test/httpparser/HttpRequestTest.java | 12 +++++-- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/redkale/convert/DeMemberInfo.java b/src/main/java/org/redkale/convert/DeMemberInfo.java index 3c138005b..57fc7dc71 100644 --- a/src/main/java/org/redkale/convert/DeMemberInfo.java +++ b/src/main/java/org/redkale/convert/DeMemberInfo.java @@ -65,8 +65,8 @@ public class DeMemberInfo { protected static class DeMemberNode extends ByteTreeNode { @Override - public void put(String key, DeMember value) { - super.put(key, value); + public ByteTreeNode put(String key, DeMember value) { + return super.put(key, value); } } } diff --git a/src/main/java/org/redkale/net/http/HttpContext.java b/src/main/java/org/redkale/net/http/HttpContext.java index b48c2dafa..ca740708a 100644 --- a/src/main/java/org/redkale/net/http/HttpContext.java +++ b/src/main/java/org/redkale/net/http/HttpContext.java @@ -71,12 +71,12 @@ public class HttpContext extends Context { random.setSeed(Math.abs(System.nanoTime())); } - ByteTreeNode 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 map = uriPathCaches[index]; @@ -260,18 +260,31 @@ public class HttpContext extends Context { protected static class UriPathNode extends ByteTreeNode { - public UriPathNode() { + protected HttpServlet servlet; + + protected UriPathNode() { super(); } - @Override - protected void put(String key, String value) { - super.put(key, value); + protected UriPathNode(ByteTreeNode parent, int index) { + super(parent, index); + } + + protected ByteTreeNode put(String key, String value, HttpServlet servlet) { + UriPathNode n = (UriPathNode) super.put(key, value); + n.servlet = servlet; + return n; } @Override - protected String subNodeValue(ByteTreeNode node, String key, int subLen) { - return key.substring(0, subLen); + protected ByteTreeNode createNode(ByteTreeNode 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; } } diff --git a/src/main/java/org/redkale/net/http/HttpDispatcherServlet.java b/src/main/java/org/redkale/net/http/HttpDispatcherServlet.java index a5f138cc9..18af2503d 100644 --- a/src/main/java/org/redkale/net/http/HttpDispatcherServlet.java +++ b/src/main/java/org/redkale/net/http/HttpDispatcherServlet.java @@ -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) { diff --git a/src/main/java/org/redkale/net/http/HttpRequest.java b/src/main/java/org/redkale/net/http/HttpRequest.java index 328f8b3de..bfa5fc212 100644 --- a/src/main/java/org/redkale/net/http/HttpRequest.java +++ b/src/main/java/org/redkale/net/http/HttpRequest.java @@ -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 { protected String locale; + HttpServlet pathServlet; + // 主要给chunked和unzip用的 private ByteArray array; @@ -761,6 +764,7 @@ public class HttpRequest extends Request { 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 { } 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 { this.respConvertType = null; this.headers.clear(); // 其他 + this.pathServlet = null; this.newSessionid = null; this.method = null; this.getmethod = false; diff --git a/src/main/java/org/redkale/util/ByteTreeNode.java b/src/main/java/org/redkale/util/ByteTreeNode.java index 005d4f543..cd430b838 100644 --- a/src/main/java/org/redkale/util/ByteTreeNode.java +++ b/src/main/java/org/redkale/util/ByteTreeNode.java @@ -27,7 +27,7 @@ public class ByteTreeNode { this(null, 0); } - private ByteTreeNode(ByteTreeNode parent, int index) { + protected ByteTreeNode(ByteTreeNode 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 { return n.value; } - protected void put(String key, T value) { + protected ByteTreeNode put(String key, T value) { ByteTreeNode n = this; int i = 0; for (char ch : key.toCharArray()) { @@ -80,17 +80,17 @@ public class ByteTreeNode { i++; ByteTreeNode 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 node, String key, int subLen) { - return null; + protected ByteTreeNode createNode(ByteTreeNode parent, int index, String key, int subLen) { + return new ByteTreeNode(parent, index); } @Override diff --git a/src/test/java/org/redkale/test/httpparser/HttpRequestTest.java b/src/test/java/org/redkale/test/httpparser/HttpRequestTest.java index 51ae7e43a..b1f556a1e 100644 --- a/src/test/java/org/redkale/test/httpparser/HttpRequestTest.java +++ b/src/test/java/org/redkale/test/httpparser/HttpRequestTest.java @@ -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";