diff --git a/src/main/java/org/redkale/net/http/HttpRequest.java b/src/main/java/org/redkale/net/http/HttpRequest.java index 65375594c..330470d38 100644 --- a/src/main/java/org/redkale/net/http/HttpRequest.java +++ b/src/main/java/org/redkale/net/http/HttpRequest.java @@ -500,6 +500,7 @@ public class HttpRequest extends Request { if (this.requestURI == null) { int qst = -1;//?的位置 boolean decodeable = false; + boolean latin1 = true; for (;;) { if (remain-- < 1) { buffer.clear(); @@ -513,12 +514,14 @@ public class HttpRequest extends Request { qst = bytes.length(); } else if (!decodeable && (b == '+' || b == '%')) { decodeable = true; + } else if (latin1 && (b < 0x20 || b >= 0x80)) { + latin1 = false; } bytes.put(b); } size = bytes.length(); if (qst > 0) { - this.requestURI = decodeable ? toDecodeString(bytes, 0, qst, charset) : bytes.toString(0, qst, charset); + this.requestURI = decodeable ? toDecodeString(bytes, 0, qst, charset) : bytes.toString(latin1, 0, qst, charset); this.queryBytes = bytes.getBytes(qst + 1, size - qst - 1); this.lastRequestURIString = null; this.lastRequestURIBytes = null; @@ -537,12 +540,12 @@ public class HttpRequest extends Request { if (lastURIBytes != null && lastURIBytes.length == size && bytes.equal(lastURIBytes)) { this.requestURI = this.lastRequestURIString; } else { - this.requestURI = bytes.toString(charset); + this.requestURI = bytes.toString(latin1, charset); this.lastRequestURIString = this.requestURI; this.lastRequestURIBytes = bytes.getBytes(); } } else { - this.requestURI = bytes.toString(charset); + this.requestURI = bytes.toString(latin1, charset); this.lastRequestURIString = null; this.lastRequestURIBytes = null; } @@ -608,6 +611,13 @@ public class HttpRequest extends Request { if (b1 == '\r' && b2 == '\n') { return 0; } + boolean latin1 = true; + if (latin1 && (b1 < 0x20 || b1 >= 0x80)) { + latin1 = false; + } + if (latin1 && (b2 < 0x20 || b2 >= 0x80)) { + latin1 = false; + } bytes.put(b1, b2); for (;;) { // name if (remain-- < 1) { @@ -618,10 +628,12 @@ public class HttpRequest extends Request { byte b = buffer.get(); if (b == ':') { break; + } else if (latin1 && (b < 0x20 || b >= 0x80)) { + latin1 = false; } bytes.put(b); } - String name = parseHeaderName(bytes, charset); + String name = parseHeaderName(latin1, bytes, charset); bytes.clear(); boolean first = true; int space = 0; @@ -672,12 +684,12 @@ public class HttpRequest extends Request { switch (name) { case "Content-Type": case "content-type": - value = bytes.toString(charset); + value = bytes.toString(true, charset); this.contentType = value; break; case "Content-Length": case "content-length": - value = bytes.toString(charset); + value = bytes.toString(true, charset); this.contentLength = Long.decode(value); break; case "Host": @@ -724,7 +736,7 @@ public class HttpRequest extends Request { break; case "Upgrade": case "upgrade": - value = bytes.toString(charset); + value = bytes.toString(true, charset); this.maybews = "websocket".equalsIgnoreCase(value); headers.put("Upgrade", value); break; @@ -733,7 +745,7 @@ public class HttpRequest extends Request { headers.put("User-Agent", value); break; case Rest.REST_HEADER_RPC: - value = bytes.toString(charset); + value = bytes.toString(true, charset); this.rpc = "true".equalsIgnoreCase(value); headers.put(name, value); break; @@ -744,18 +756,18 @@ public class HttpRequest extends Request { headers.put(name, value); break; case Rest.REST_HEADER_PARAM_FROM_BODY: - value = bytes.toString(charset); + value = bytes.toString(true, charset); this.frombody = "true".equalsIgnoreCase(value); headers.put(name, value); break; case Rest.REST_HEADER_REQ_CONVERT_TYPE: - value = bytes.toString(charset); + value = bytes.toString(true, charset); reqConvertType = ConvertType.valueOf(value); reqConvert = ConvertFactory.findConvert(reqConvertType); headers.put(name, value); break; case Rest.REST_HEADER_RESP_CONVERT_TYPE: - value = bytes.toString(charset); + value = bytes.toString(true, charset); respConvertType = ConvertType.valueOf(value); respConvert = ConvertFactory.findConvert(respConvertType); headers.put(name, value); @@ -783,7 +795,7 @@ public class HttpRequest extends Request { } } - static String parseHeaderName(ByteArray bytes, Charset charset) { + static String parseHeaderName(boolean latin1, ByteArray bytes, Charset charset) { final int size = bytes.length(); final byte[] bs = bytes.content(); final byte first = bs[0]; @@ -817,7 +829,7 @@ public class HttpRequest extends Request { } } } - return bytes.toString(charset); + return bytes.toString(latin1, charset); } @Override @@ -971,6 +983,13 @@ public class HttpRequest extends Request { protected static String toDecodeString(ByteArray array, int offset, int len, final Charset charset) { byte[] content = array.content(); + if (len == 1) { + return Character.toString(content[offset]); + } else if (len == 2 && content[offset] >= '0' && content[offset] <= '9') { + return new String(content, 0, offset, len); + } else if (len == 3 && content[offset + 1] >= '0' && content[offset + 1] <= '9') { + return new String(content, 0, offset, len); + } int start = offset; final int end = offset + len; boolean flag = false; //是否需要转义 diff --git a/src/main/java/org/redkale/net/http/HttpSimpleClient.java b/src/main/java/org/redkale/net/http/HttpSimpleClient.java index 2d2382b71..24c90fdca 100644 --- a/src/main/java/org/redkale/net/http/HttpSimpleClient.java +++ b/src/main/java/org/redkale/net/http/HttpSimpleClient.java @@ -282,6 +282,13 @@ public class HttpSimpleClient { if (b1 == '\r' && b2 == '\n') { return 0; } + boolean latin1 = true; + if (latin1 && (b1 < 0x20 || b1 >= 0x80)) { + latin1 = false; + } + if (latin1 && (b2 < 0x20 || b2 >= 0x80)) { + latin1 = false; + } bytes.put(b1, b2); for (;;) { // name if (remain-- < 1) { @@ -292,10 +299,12 @@ public class HttpSimpleClient { byte b = buffer.get(); if (b == ':') { break; + } else if (latin1 && (b < 0x20 || b >= 0x80)) { + latin1 = false; } bytes.put(b); } - String name = parseHeaderName(bytes, null); + String name = parseHeaderName(latin1, bytes, null); bytes.clear(); boolean first = true; int space = 0; @@ -345,7 +354,7 @@ public class HttpSimpleClient { switch (name) { case "Content-Length": case "content-length": - value = bytes.toString(null); + value = bytes.toString(true, null); this.contentLength = Integer.decode(value); result.header(name, value); break; diff --git a/src/main/java/org/redkale/util/ByteArray.java b/src/main/java/org/redkale/util/ByteArray.java index cd75b8cc1..882397b52 100644 --- a/src/main/java/org/redkale/util/ByteArray.java +++ b/src/main/java/org/redkale/util/ByteArray.java @@ -936,6 +936,21 @@ public final class ByteArray implements ByteTuple { return toString(0, count, charset); } + /** + * 按指定字符集转成字符串 + * + * @param latin1 是否LATIN1 + * @param charset 字符集 + * + * @return 字符串 + */ + public String toString(final boolean latin1, final Charset charset) { + if (latin1) { + return new String(content, 0, 0, count); + } + return new String(content, 0, count, charset == null ? StandardCharsets.UTF_8 : charset); + } + /** * 将指定的起始位置和长度按指定字符集转成字符串 * @@ -946,10 +961,24 @@ public final class ByteArray implements ByteTuple { * @return 字符串 */ public String toString(final int offset, int len, final Charset charset) { - if (charset == null) { - return new String(content, offset, len, StandardCharsets.UTF_8); + return new String(content, offset, len, charset == null ? StandardCharsets.UTF_8 : charset); + } + + /** + * 将指定的起始位置和长度按指定字符集转成字符串 + * + * @param latin1 是否LATIN1 + * @param offset 起始位置 + * @param len 长度 + * @param charset 字符集 + * + * @return 字符串 + */ + public String toString(final boolean latin1, int offset, int len, final Charset charset) { + if (latin1) { + return new String(content, 0, offset, len); } - return new String(content, offset, len, charset); + return new String(content, offset, len, charset == null ? StandardCharsets.UTF_8 : charset); } /**