mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-08-31 13:59:05 +00:00
fix(parser): harden runtime resource handling
This commit is contained in:
@@ -17,16 +17,35 @@ import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class HttpResponseHelper {
|
||||
static Logger LOGGER = LoggerFactory.getLogger(HttpResponseHelper.class);
|
||||
private static final int MAX_RESPONSE_BODY_BYTES = 8 * 1024 * 1024;
|
||||
private static final int MAX_DECOMPRESSED_CHARS = 16 * 1024 * 1024;
|
||||
|
||||
// -------------------- 公共方法 --------------------
|
||||
public static String asText(HttpResponse<?> res) {
|
||||
String encoding = res.getHeader(HttpHeaders.CONTENT_ENCODING.toString());
|
||||
try {
|
||||
Buffer body = toBuffer(res);
|
||||
return asText(body, encoding);
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("asText: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String asText(Buffer body, String encoding) {
|
||||
try {
|
||||
if (body == null) {
|
||||
return "";
|
||||
}
|
||||
ensureBodyLimit(body);
|
||||
if (encoding == null || "identity".equalsIgnoreCase(encoding)) {
|
||||
return body.toString(StandardCharsets.UTF_8);
|
||||
}
|
||||
return decompress(body, encoding);
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("asText: {}", e.getMessage(), e);
|
||||
return null;
|
||||
@@ -36,6 +55,29 @@ public class HttpResponseHelper {
|
||||
public static JsonObject asJson(HttpResponse<?> res) {
|
||||
try {
|
||||
String text = asText(res);
|
||||
return parseJsonText(text);
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("asJson: {}", e.getMessage(), e);
|
||||
return JsonObject.of();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject asJson(Buffer body, String encoding) {
|
||||
try {
|
||||
String text = asText(body, encoding);
|
||||
return parseJsonText(text);
|
||||
} catch (IllegalArgumentException | UnsupportedOperationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("asJson: {}", e.getMessage(), e);
|
||||
return JsonObject.of();
|
||||
}
|
||||
}
|
||||
|
||||
private static JsonObject parseJsonText(String text) {
|
||||
try {
|
||||
if (text != null) {
|
||||
return new JsonObject(text);
|
||||
} else {
|
||||
@@ -53,13 +95,26 @@ public class HttpResponseHelper {
|
||||
return res.body() instanceof Buffer ? (Buffer) res.body() : Buffer.buffer(res.bodyAsString());
|
||||
}
|
||||
|
||||
private static void ensureBodyLimit(Buffer body) {
|
||||
if (body != null && body.length() > MAX_RESPONSE_BODY_BYTES) {
|
||||
throw new IllegalArgumentException("响应体过大: " + body.length() + " bytes");
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeLimited(StringWriter writer, char[] buffer, int len) throws IOException {
|
||||
if (writer.getBuffer().length() + len > MAX_DECOMPRESSED_CHARS) {
|
||||
throw new IOException("解压后响应体过大");
|
||||
}
|
||||
writer.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
// -------------------- 通用解压分发 --------------------
|
||||
private static String decompress(Buffer compressed, String encoding) throws IOException {
|
||||
return switch (encoding.toLowerCase()) {
|
||||
case "gzip" -> decompressGzip(compressed);
|
||||
case "deflate" -> decompressDeflate(compressed);
|
||||
case "br" -> decompressBrotli(compressed);
|
||||
case "zstd" -> compressed.toString(StandardCharsets.UTF_8); // 暂时返回原始内容
|
||||
case "zstd" -> throw new UnsupportedOperationException("不支持的 Content-Encoding: zstd");
|
||||
default -> throw new UnsupportedOperationException("不支持的 Content-Encoding: " + encoding);
|
||||
};
|
||||
}
|
||||
@@ -74,7 +129,7 @@ public class HttpResponseHelper {
|
||||
char[] buffer = new char[4096];
|
||||
int n;
|
||||
while ((n = isr.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, n);
|
||||
writeLimited(writer, buffer, n);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
@@ -99,7 +154,7 @@ public class HttpResponseHelper {
|
||||
char[] buffer = new char[4096];
|
||||
int n;
|
||||
while ((n = isr.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, n);
|
||||
writeLimited(writer, buffer, n);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
@@ -115,7 +170,7 @@ public class HttpResponseHelper {
|
||||
char[] buffer = new char[4096];
|
||||
int n;
|
||||
while ((n = isr.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, n);
|
||||
writeLimited(writer, buffer, n);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user