yifan-c commented on code in PR #35:
URL: https://github.com/apache/cassandra-sidecar/pull/35#discussion_r939431531
##########
src/main/java/org/apache/cassandra/sidecar/models/Range.java:
##########
@@ -31,132 +31,116 @@
* Accepted Range formats are start-end, start-, -suffix_length
* start-end (start = start index of the range, end = end index of the range,
both inclusive)
* start- (start = start index of the range, end = end of file)
- * -suffix-length (Requested length from end of file)
+ * -suffix-length (Requested length from end of file. The length should be
positive)
*/
public class Range
{
- private static final Pattern START_END =
Pattern.compile("^(\\d+)-(\\d+)$");
- private static final Pattern PARTIAL =
Pattern.compile("^((\\d+)-)$|^(-(\\d+))$");
private static final String RANGE_UNIT = "bytes";
+ // matches a. bytes=1-2, b. bytes=1-, c. bytes=-2, d. bytes=-. Need to do
another valid for case d.
+ private static final Pattern RANGE_HEADER = Pattern.compile("^" +
RANGE_UNIT + "=(\\d*)-(\\d*)$");
private final long start;
private final long end;
private final long length;
- private Range(final long start, final long end)
+ /**
+ * Accepted RangeHeader formats are bytes=start-end, bytes=start-,
bytes=-suffix_length
+ */
+ public static Range parseHeader(final String header, final long fileSize)
{
- this.start = start;
- this.end = end;
- this.length = length(start, end);
+ if (header == null)
+ {
+ return new Range(0, fileSize - 1);
+ }
+ if (!header.startsWith(RANGE_UNIT + "="))
+ {
+ throw invalidRangeHeaderException(header);
+ }
+ return Range.parse(header, fileSize);
}
- public Range(final long start, final long end, final long length)
+ public static Range of(final long start, final long end)
{
- this.start = start;
- this.end = end;
- this.length = length;
+ return new Range(start, end);
}
- private long length(final long start, final long end)
+ /**
+ * Accepted string formats "bytes=1453-3563", "bytes=-22344", "bytes=5346-"
+ * Sample invalid string formats "bytes=8-3", "bytes=-", "bytes=-0",
"bytes=a-b"
+ *
+ * @param fileSize - passed in to convert partial range into absolute range
+ */
+ private static Range parse(@NotNull String rangeHeader, final long
fileSize)
{
- if (start == 0 && end == Long.MAX_VALUE) // avoid overflow (extra byte)
+ Matcher m = RANGE_HEADER.matcher(rangeHeader);
+ if (!m.matches())
{
- return Long.MAX_VALUE;
+ throw invalidRangeHeaderException(rangeHeader);
}
- return end - start + 1;
- }
- public long start()
- {
- return this.start;
- }
+ long left = m.group(1).isEmpty()? -1L : Long.parseLong(m.group(1));
+ long right = m.group(2).isEmpty()? -1L : Long.parseLong(m.group(2));
- public long end()
- {
- return this.end;
+ if (left == -1L && right == -1L) // matching "bytes=-"
+ {
+ throw invalidRangeHeaderException(rangeHeader);
+ }
+ else if (left == -1L) // matching "bytes=-1"
+ {
+ long len = Math.min(right, fileSize); // correct the range if it
exceeds file size.
Review Comment:
This is a change of behavior. I feel handling an over-sized range gracefully
helps to reduce the number of request/retry. Client will need to (and _should_)
read data according to content-length header.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]