Skip to content

Commit

Permalink
yegor256#45: Range should work
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Bugayenko committed Mar 18, 2013
1 parent b08796e commit e65bbf4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
3 changes: 2 additions & 1 deletion s3auth-hosts/src/main/java/com/s3auth/hosts/DefaultHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ public Resource fetch(@NotNull final URI uri, @NotNull final Range range)
this.bucket.name(),
name.get()
).withRange(range.first(), range.last())
)
),
range
);
break;
} catch (com.amazonaws.AmazonClientException ex) {
Expand Down
24 changes: 23 additions & 1 deletion s3auth-hosts/src/main/java/com/s3auth/hosts/DefaultResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,20 @@ final class DefaultResource implements Resource {
*/
private final transient S3Object object;

/**
* The range.
*/
private final transient Range range;

/**
* Public ctor.
* @param obj S3 object
* @param rng Range served
*/
public DefaultResource(@NotNull final S3Object obj) {
public DefaultResource(@NotNull final S3Object obj,
@NotNull final Range rng) {
this.object = obj;
this.range = rng;
}

/**
Expand Down Expand Up @@ -138,6 +146,20 @@ public Collection<String> headers() {
)
);
}
headers.add(DefaultResource.header("Accept-Ranges", "bytes"));
if (!this.range.equals(Range.ENTIRE)) {
headers.add(
DefaultResource.header(
"Content-Range",
String.format(
"bytes %d-%d/%d",
this.range.first(),
this.range.last(),
this.object.getObjectMetadata().getContentLength()
)
)
);
}
return headers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void getsHeadersFromAmazonObject() throws Exception {
final ObjectMetadata meta = Mockito.mock(ObjectMetadata.class);
Mockito.doReturn(meta).when(object).getObjectMetadata();
Mockito.doReturn(1L).when(meta).getContentLength();
final Resource res = new DefaultResource(object);
final Resource res = new DefaultResource(object, Range.ENTIRE);
MatcherAssert.assertThat(
res.headers(),
Matchers.hasItem("Content-Length: 1")
Expand All @@ -77,7 +77,7 @@ public void writesFromAmazonObjectToOutputStream() throws Exception {
final S3Object object = Mockito.mock(S3Object.class);
Mockito.doReturn(stream).when(object).getObjectContent();
MatcherAssert.assertThat(
ResourceMocker.toString(new DefaultResource(object)),
ResourceMocker.toString(new DefaultResource(object, Range.ENTIRE)),
Matchers.equalTo("")
);
}
Expand All @@ -101,7 +101,9 @@ public void writesInputToOutputStream() throws Exception {
final S3Object object = Mockito.mock(S3Object.class);
Mockito.doReturn(stream).when(object).getObjectContent();
MatcherAssert.assertThat(
ResourceMocker.toByteArray(new DefaultResource(object)),
ResourceMocker.toByteArray(
new DefaultResource(object, Range.ENTIRE)
),
Matchers.equalTo(data)
);
}
Expand All @@ -119,7 +121,7 @@ public void throwsWhenFailedToRead() throws Exception {
final S3Object object = Mockito.mock(S3Object.class);
Mockito.doReturn(stream).when(object).getObjectContent();
MatcherAssert.assertThat(
ResourceMocker.toString(new DefaultResource(object)),
ResourceMocker.toString(new DefaultResource(object, Range.ENTIRE)),
Matchers.equalTo("")
);
}
Expand Down
42 changes: 40 additions & 2 deletions s3auth-relay/src/main/java/com/s3auth/relay/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
@Loggable(Loggable.DEBUG)
final class HttpRequest {

/**
* Range HTTP header.
* @see <a href="HTTP headers">http://en.wikipedia.org/wiki/List_of_HTTP_header_fields</a>
*/
private static final String RANGE_HEADER = "Range";

/**
* Range header matching pattern.
*/
private static final Pattern RANGE_PATTERN =
Pattern.compile("bytes=(\\d+)-(\\d+)");

/**
* TOP line pattern.
*/
Expand Down Expand Up @@ -160,9 +172,35 @@ public URI requestUri() {
/**
* Get range requested.
* @return The URI
* @throws HttpException If something is wrong
* @see <a href="http://en.wikipedia.org/wiki/Byte_serving">Byte Serving</a>
*/
public Range range() {
return Range.ENTIRE;
public Range range() throws HttpException {
Range range;
if (this.hdrs.containsKey(HttpRequest.RANGE_HEADER)) {
final Matcher matcher = HttpRequest.RANGE_PATTERN.matcher(
this.hdrs.get(HttpRequest.RANGE_HEADER).iterator().next()
);
if (matcher.matches()) {
throw new HttpException(
HttpURLConnection.HTTP_BAD_REQUEST,
"invalid Range header format"
);
}
range = new Range() {
@Override
public long first() {
return Long.parseLong(matcher.group(1));
}
@Override
public long last() {
return Long.parseLong(matcher.group(2));
}
};
} else {
range = Range.ENTIRE;
}
return range;
}

/**
Expand Down

0 comments on commit e65bbf4

Please sign in to comment.