From 39f628e71a53bf1f4bfe2e4f861186991c4c9e69 Mon Sep 17 00:00:00 2001 From: Timi Date: Tue, 15 Jul 2025 11:44:27 +0800 Subject: [PATCH] add RequestRange --- .../java/com/imyeyu/spring/TimiSpring.java | 30 ++++++++++++++ .../com/imyeyu/spring/bean/RequestRange.java | 39 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/main/java/com/imyeyu/spring/bean/RequestRange.java diff --git a/src/main/java/com/imyeyu/spring/TimiSpring.java b/src/main/java/com/imyeyu/spring/TimiSpring.java index fc5c118..cc8a007 100644 --- a/src/main/java/com/imyeyu/spring/TimiSpring.java +++ b/src/main/java/com/imyeyu/spring/TimiSpring.java @@ -7,6 +7,7 @@ import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.java.bean.timi.TimiResponse; import com.imyeyu.java.ref.Ref; +import com.imyeyu.spring.bean.RequestRange; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -16,6 +17,7 @@ import org.slf4j.LoggerFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Locale; @@ -117,6 +119,12 @@ public class TimiSpring { return getRequest().getRequestURI(); } + public static String cutURIStartAt(String flag) { + int indexOf = getURI().indexOf(flag); + TimiException.requiredTrue(-1 < indexOf, "not found flag: %s".formatted(flag)); + return getURI().substring(indexOf + flag.length()); + } + /** * 获取 HttpServlet 回调 * @@ -357,4 +365,26 @@ public class TimiSpring { public static boolean isLocalIP() { return getRequestIP().startsWith("127"); } + + public static RequestRange requestRange(long fileLength) throws IOException { + HttpServletResponse resp = getResponse(); + + String range = getRequestAttrAsString("Range"); + if (range == null || !range.startsWith("bytes=")) { + return null; + } + // 处理 bytes=0-999 格式 + String rangeValue = range.substring("bytes=".length()); + String[] ranges = rangeValue.split("-"); + TimiException.requiredTrue(2 == ranges.length, "Invalid Range format"); + long start = Long.parseLong(ranges[0]); + long end = ranges[1].isEmpty() ? fileLength - 1 : Long.parseLong(ranges[1]); + // 验证范围有效性 + if (start < 0 || fileLength <= end || end < start) { + resp.setHeader("Content-Range", "bytes */" + fileLength); + resp.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + return new RequestRange(start, end); + } } diff --git a/src/main/java/com/imyeyu/spring/bean/RequestRange.java b/src/main/java/com/imyeyu/spring/bean/RequestRange.java new file mode 100644 index 0000000..7198a93 --- /dev/null +++ b/src/main/java/com/imyeyu/spring/bean/RequestRange.java @@ -0,0 +1,39 @@ +package com.imyeyu.spring.bean; + +/** + * @author 夜雨 + * @since 2025-07-14 17:09 + */ +public class RequestRange { + + private long start; + + private long end; + + private long length; + + public RequestRange(long start, long end) { + this.start = start; + this.end = end; + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getEnd() { + return end; + } + + public void setEnd(long end) { + this.end = end; + } + + public long getLength() { + return end - start + 1; + } +} \ No newline at end of file