优化HttpRequest

This commit is contained in:
Redkale
2023-01-06 12:21:21 +08:00
parent aa78b98ebf
commit a986becb70
3 changed files with 75 additions and 18 deletions

View File

@@ -500,6 +500,7 @@ public class HttpRequest extends Request<HttpContext> {
if (this.requestURI == null) { if (this.requestURI == null) {
int qst = -1;//?的位置 int qst = -1;//?的位置
boolean decodeable = false; boolean decodeable = false;
boolean latin1 = true;
for (;;) { for (;;) {
if (remain-- < 1) { if (remain-- < 1) {
buffer.clear(); buffer.clear();
@@ -513,12 +514,14 @@ public class HttpRequest extends Request<HttpContext> {
qst = bytes.length(); qst = bytes.length();
} else if (!decodeable && (b == '+' || b == '%')) { } else if (!decodeable && (b == '+' || b == '%')) {
decodeable = true; decodeable = true;
} else if (latin1 && (b < 0x20 || b >= 0x80)) {
latin1 = false;
} }
bytes.put(b); bytes.put(b);
} }
size = bytes.length(); size = bytes.length();
if (qst > 0) { 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.queryBytes = bytes.getBytes(qst + 1, size - qst - 1);
this.lastRequestURIString = null; this.lastRequestURIString = null;
this.lastRequestURIBytes = null; this.lastRequestURIBytes = null;
@@ -537,12 +540,12 @@ public class HttpRequest extends Request<HttpContext> {
if (lastURIBytes != null && lastURIBytes.length == size && bytes.equal(lastURIBytes)) { if (lastURIBytes != null && lastURIBytes.length == size && bytes.equal(lastURIBytes)) {
this.requestURI = this.lastRequestURIString; this.requestURI = this.lastRequestURIString;
} else { } else {
this.requestURI = bytes.toString(charset); this.requestURI = bytes.toString(latin1, charset);
this.lastRequestURIString = this.requestURI; this.lastRequestURIString = this.requestURI;
this.lastRequestURIBytes = bytes.getBytes(); this.lastRequestURIBytes = bytes.getBytes();
} }
} else { } else {
this.requestURI = bytes.toString(charset); this.requestURI = bytes.toString(latin1, charset);
this.lastRequestURIString = null; this.lastRequestURIString = null;
this.lastRequestURIBytes = null; this.lastRequestURIBytes = null;
} }
@@ -608,6 +611,13 @@ public class HttpRequest extends Request<HttpContext> {
if (b1 == '\r' && b2 == '\n') { if (b1 == '\r' && b2 == '\n') {
return 0; 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); bytes.put(b1, b2);
for (;;) { // name for (;;) { // name
if (remain-- < 1) { if (remain-- < 1) {
@@ -618,10 +628,12 @@ public class HttpRequest extends Request<HttpContext> {
byte b = buffer.get(); byte b = buffer.get();
if (b == ':') { if (b == ':') {
break; break;
} else if (latin1 && (b < 0x20 || b >= 0x80)) {
latin1 = false;
} }
bytes.put(b); bytes.put(b);
} }
String name = parseHeaderName(bytes, charset); String name = parseHeaderName(latin1, bytes, charset);
bytes.clear(); bytes.clear();
boolean first = true; boolean first = true;
int space = 0; int space = 0;
@@ -672,12 +684,12 @@ public class HttpRequest extends Request<HttpContext> {
switch (name) { switch (name) {
case "Content-Type": case "Content-Type":
case "content-type": case "content-type":
value = bytes.toString(charset); value = bytes.toString(true, charset);
this.contentType = value; this.contentType = value;
break; break;
case "Content-Length": case "Content-Length":
case "content-length": case "content-length":
value = bytes.toString(charset); value = bytes.toString(true, charset);
this.contentLength = Long.decode(value); this.contentLength = Long.decode(value);
break; break;
case "Host": case "Host":
@@ -724,7 +736,7 @@ public class HttpRequest extends Request<HttpContext> {
break; break;
case "Upgrade": case "Upgrade":
case "upgrade": case "upgrade":
value = bytes.toString(charset); value = bytes.toString(true, charset);
this.maybews = "websocket".equalsIgnoreCase(value); this.maybews = "websocket".equalsIgnoreCase(value);
headers.put("Upgrade", value); headers.put("Upgrade", value);
break; break;
@@ -733,7 +745,7 @@ public class HttpRequest extends Request<HttpContext> {
headers.put("User-Agent", value); headers.put("User-Agent", value);
break; break;
case Rest.REST_HEADER_RPC: case Rest.REST_HEADER_RPC:
value = bytes.toString(charset); value = bytes.toString(true, charset);
this.rpc = "true".equalsIgnoreCase(value); this.rpc = "true".equalsIgnoreCase(value);
headers.put(name, value); headers.put(name, value);
break; break;
@@ -744,18 +756,18 @@ public class HttpRequest extends Request<HttpContext> {
headers.put(name, value); headers.put(name, value);
break; break;
case Rest.REST_HEADER_PARAM_FROM_BODY: case Rest.REST_HEADER_PARAM_FROM_BODY:
value = bytes.toString(charset); value = bytes.toString(true, charset);
this.frombody = "true".equalsIgnoreCase(value); this.frombody = "true".equalsIgnoreCase(value);
headers.put(name, value); headers.put(name, value);
break; break;
case Rest.REST_HEADER_REQ_CONVERT_TYPE: case Rest.REST_HEADER_REQ_CONVERT_TYPE:
value = bytes.toString(charset); value = bytes.toString(true, charset);
reqConvertType = ConvertType.valueOf(value); reqConvertType = ConvertType.valueOf(value);
reqConvert = ConvertFactory.findConvert(reqConvertType); reqConvert = ConvertFactory.findConvert(reqConvertType);
headers.put(name, value); headers.put(name, value);
break; break;
case Rest.REST_HEADER_RESP_CONVERT_TYPE: case Rest.REST_HEADER_RESP_CONVERT_TYPE:
value = bytes.toString(charset); value = bytes.toString(true, charset);
respConvertType = ConvertType.valueOf(value); respConvertType = ConvertType.valueOf(value);
respConvert = ConvertFactory.findConvert(respConvertType); respConvert = ConvertFactory.findConvert(respConvertType);
headers.put(name, value); headers.put(name, value);
@@ -783,7 +795,7 @@ public class HttpRequest extends Request<HttpContext> {
} }
} }
static String parseHeaderName(ByteArray bytes, Charset charset) { static String parseHeaderName(boolean latin1, ByteArray bytes, Charset charset) {
final int size = bytes.length(); final int size = bytes.length();
final byte[] bs = bytes.content(); final byte[] bs = bytes.content();
final byte first = bs[0]; final byte first = bs[0];
@@ -817,7 +829,7 @@ public class HttpRequest extends Request<HttpContext> {
} }
} }
} }
return bytes.toString(charset); return bytes.toString(latin1, charset);
} }
@Override @Override
@@ -971,6 +983,13 @@ public class HttpRequest extends Request<HttpContext> {
protected static String toDecodeString(ByteArray array, int offset, int len, final Charset charset) { protected static String toDecodeString(ByteArray array, int offset, int len, final Charset charset) {
byte[] content = array.content(); 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; int start = offset;
final int end = offset + len; final int end = offset + len;
boolean flag = false; //是否需要转义 boolean flag = false; //是否需要转义

View File

@@ -282,6 +282,13 @@ public class HttpSimpleClient {
if (b1 == '\r' && b2 == '\n') { if (b1 == '\r' && b2 == '\n') {
return 0; 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); bytes.put(b1, b2);
for (;;) { // name for (;;) { // name
if (remain-- < 1) { if (remain-- < 1) {
@@ -292,10 +299,12 @@ public class HttpSimpleClient {
byte b = buffer.get(); byte b = buffer.get();
if (b == ':') { if (b == ':') {
break; break;
} else if (latin1 && (b < 0x20 || b >= 0x80)) {
latin1 = false;
} }
bytes.put(b); bytes.put(b);
} }
String name = parseHeaderName(bytes, null); String name = parseHeaderName(latin1, bytes, null);
bytes.clear(); bytes.clear();
boolean first = true; boolean first = true;
int space = 0; int space = 0;
@@ -345,7 +354,7 @@ public class HttpSimpleClient {
switch (name) { switch (name) {
case "Content-Length": case "Content-Length":
case "content-length": case "content-length":
value = bytes.toString(null); value = bytes.toString(true, null);
this.contentLength = Integer.decode(value); this.contentLength = Integer.decode(value);
result.header(name, value); result.header(name, value);
break; break;

View File

@@ -936,6 +936,21 @@ public final class ByteArray implements ByteTuple {
return toString(0, count, charset); 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 字符串 * @return 字符串
*/ */
public String toString(final int offset, int len, final Charset charset) { public String toString(final int offset, int len, final Charset charset) {
if (charset == null) { return new String(content, offset, len, charset == null ? StandardCharsets.UTF_8 : charset);
return new String(content, offset, len, StandardCharsets.UTF_8);
} }
return new String(content, offset, len, 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 == null ? StandardCharsets.UTF_8 : charset);
} }
/** /**