@Test public void buildGetBlobOptionsTest() throws RestServiceException { doBuildGetBlobOptionsTest(null, null, true, true); doBuildGetBlobOptionsTest("bytes=0-7", ByteRanges.fromOffsetRange(0, 7), true, false, true); doBuildGetBlobOptionsTest("bytes=234-56679090", ByteRanges.fromOffsetRange(234, 56679090), true, false, true); doBuildGetBlobOptionsTest("bytes=1-", ByteRanges.fromStartOffset(1), true, false, true); doBuildGetBlobOptionsTest("bytes=12345678-", ByteRanges.fromStartOffset(12345678), true, false, true); doBuildGetBlobOptionsTest("bytes=-8", ByteRanges.fromLastNBytes(8), true, false, true); doBuildGetBlobOptionsTest("bytes=-123456789", ByteRanges.fromLastNBytes(123456789), true, false, true); String[] badRanges = {"bytes=0-abcd", "bytes=0as23-44444444", "bytes=22-7777777777777777777777777777777777777777777", "bytes=22--53", "bytes=223-34", "bytes=-34ab", "bytes=--12", "bytes=-12-", "bytes=12ab-", "bytes=---", "btes=3-5", "bytes=345", "bytes=3.14-22", "bytes=3-6.2", "bytes=", "bytes=-", "bytes= -"}; for (String badRange : badRanges) { doBuildGetBlobOptionsTest(badRange, null, false, false); } }
public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException { String rangeHeaderValue = getHeader(args, Headers.RANGE, false); if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) { throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs); } boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false); return new GetBlobOptionsBuilder().operationType( subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo) .getOption(getOption) .blobSegment(blobSegmentIdx) .range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null) .resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob) .build(); }
RestUtils { public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException { String rangeHeaderValue = getHeader(args, Headers.RANGE, false); if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) { throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs); } boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false); return new GetBlobOptionsBuilder().operationType( subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo) .getOption(getOption) .blobSegment(blobSegmentIdx) .range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null) .resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob) .build(); } }
RestUtils { public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException { String rangeHeaderValue = getHeader(args, Headers.RANGE, false); if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) { throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs); } boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false); return new GetBlobOptionsBuilder().operationType( subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo) .getOption(getOption) .blobSegment(blobSegmentIdx) .range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null) .resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob) .build(); }  }
RestUtils { public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException { String rangeHeaderValue = getHeader(args, Headers.RANGE, false); if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) { throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs); } boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false); return new GetBlobOptionsBuilder().operationType( subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo) .getOption(getOption) .blobSegment(blobSegmentIdx) .range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null) .resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob) .build(); }  static BlobProperties buildBlobProperties(Map<String, Object> args); static byte[] buildUserMetadata(Map<String, Object> args); static Map<String, String> buildUserMetadata(byte[] userMetadata); static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource,
      GetOption getOption, int blobSegmentIdx); static Pair<String, Long> buildContentRangeAndLength(ByteRange range, long blobSize,
      boolean resolveRangeOnEmptyBlob); static RequestPath getRequestPath(RestRequest restRequest); static Long getTimeFromDateString(String dateString); static long toSecondsPrecisionInMs(long ms); static GetOption getGetOption(RestRequest restRequest, GetOption defaultGetOption); static boolean isPrivate(Map<String, Object> args); static boolean isChunkUpload(Map<String, Object> args); static void ensureRequiredHeadersOrThrow(RestRequest restRequest, Set<String> requiredHeaders); static String getHeader(Map<String, ?> args, String header, boolean required); static Long getLongHeader(Map<String, ?> args, String header, boolean required); static T getNumericalHeader(Map<String, ?> args, String header, boolean required,
      Function<String, T> converter); static boolean getBooleanHeader(Map<String, Object> args, String header, boolean required); static Account getAccountFromArgs(Map<String, Object> args); static Container getContainerFromArgs(Map<String, Object> args); static void accountAndContainerNamePreconditionCheck(RestRequest restRequest); static boolean setUserMetadataHeaders(byte[] userMetadata, RestResponseChannel restResponseChannel); }
RestUtils { public static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException { String rangeHeaderValue = getHeader(args, Headers.RANGE, false); if (subResource != null && !subResource.equals(SubResource.Segment) && rangeHeaderValue != null) { throw new RestServiceException("Ranges not supported for sub-resources that aren't Segment.", RestServiceErrorCode.InvalidArgs); } boolean resolveRangeOnEmptyBlob = getBooleanHeader(args, Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, false); return new GetBlobOptionsBuilder().operationType( subResource == null || subResource == SubResource.Segment ? GetBlobOptions.OperationType.All : GetBlobOptions.OperationType.BlobInfo) .getOption(getOption) .blobSegment(blobSegmentIdx) .range(rangeHeaderValue != null ? RestUtils.buildByteRange(rangeHeaderValue) : null) .resolveRangeOnEmptyBlob(resolveRangeOnEmptyBlob) .build(); }  static BlobProperties buildBlobProperties(Map<String, Object> args); static byte[] buildUserMetadata(Map<String, Object> args); static Map<String, String> buildUserMetadata(byte[] userMetadata); static GetBlobOptions buildGetBlobOptions(Map<String, Object> args, SubResource subResource,
      GetOption getOption, int blobSegmentIdx); static Pair<String, Long> buildContentRangeAndLength(ByteRange range, long blobSize,
      boolean resolveRangeOnEmptyBlob); static RequestPath getRequestPath(RestRequest restRequest); static Long getTimeFromDateString(String dateString); static long toSecondsPrecisionInMs(long ms); static GetOption getGetOption(RestRequest restRequest, GetOption defaultGetOption); static boolean isPrivate(Map<String, Object> args); static boolean isChunkUpload(Map<String, Object> args); static void ensureRequiredHeadersOrThrow(RestRequest restRequest, Set<String> requiredHeaders); static String getHeader(Map<String, ?> args, String header, boolean required); static Long getLongHeader(Map<String, ?> args, String header, boolean required); static T getNumericalHeader(Map<String, ?> args, String header, boolean required,
      Function<String, T> converter); static boolean getBooleanHeader(Map<String, Object> args, String header, boolean required); static Account getAccountFromArgs(Map<String, Object> args); static Container getContainerFromArgs(Map<String, Object> args); static void accountAndContainerNamePreconditionCheck(RestRequest restRequest); static boolean setUserMetadataHeaders(byte[] userMetadata, RestResponseChannel restResponseChannel); static final String HTTP_DATE_FORMAT; static final String BYTE_RANGE_UNITS; static final String SIGNED_ID_PREFIX; static final String JSON_CONTENT_TYPE; }