in stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java [847:964]
public Response executeStreamGet( @Context UriInfo ui, @PathParam("entityId") PathSegment entityId,
@HeaderParam("range") String rangeHeader,
@HeaderParam("if-modified-since") String modifiedSince ) throws Exception {
if(logger.isTraceEnabled()){
logger.trace( "ServiceResource.executeStreamGet" );
}
// needed for testing
this.binaryStore = binaryStoreFactory.getBinaryStore( properties.getProperty(PROPERTIES_USERGRID_BINARY_UPLOADER) );
ApiResponse response = createApiResponse();
response.setAction( "get" );
response.setApplication( services.getApplication() );
response.setParams( ui.getQueryParameters() );
ServiceResults serviceResults = executeServiceRequest( ui, response, ServiceAction.GET, null );
Entity entity = serviceResults.getEntity();
if(logger.isTraceEnabled()){
logger.trace( "In ServiceResource.executeStreamGet with id: {}, range: {}, modifiedSince: {}",
entityId, rangeHeader, modifiedSince );
}
Map<String, Object> fileMetadata = AssetUtils.getFileMetadata( entity );
// return a 302 if not modified
Date modified = AssetUtils.fromIfModifiedSince( modifiedSince );
if ( modified != null ) {
Long lastModified = ( Long ) fileMetadata.get( AssetUtils.LAST_MODIFIED );
if ( lastModified - modified.getTime() < 0 ) {
return Response.status( Response.Status.NOT_MODIFIED ).build();
}
}
boolean range = StringUtils.isNotBlank( rangeHeader );
long start = 0, end = 0, contentLength = 0;
InputStream inputStream;
if ( range ) { // honor range request, calculate start & end
String rangeValue = rangeHeader.trim().substring( "bytes=".length() );
contentLength = ( Long ) fileMetadata.get( AssetUtils.CONTENT_LENGTH );
end = contentLength - 1;
if ( rangeValue.startsWith( "-" ) ) {
start = contentLength - 1 - Long.parseLong( rangeValue.substring( "-".length() ) );
}
else {
String[] startEnd = rangeValue.split( "-" );
long parsedStart = Long.parseLong( startEnd[0] );
if ( parsedStart > start && parsedStart < end ) {
start = parsedStart;
}
if ( startEnd.length > 1 ) {
long parsedEnd = Long.parseLong( startEnd[1] );
if ( parsedEnd > start && parsedEnd < end ) {
end = parsedEnd;
}
}
}
try {
inputStream = binaryStore.read( getApplicationId(), entity, start, end - start );
}catch(AwsPropertiesNotFoundException apnfe){
logger.error( "Amazon Property needed for this operation not found",apnfe );
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}catch(RuntimeException re){
logger.error(re.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
else { // no range
try {
inputStream = binaryStore.read( getApplicationId(), entity );
}catch(AwsPropertiesNotFoundException apnfe){
logger.error( "Amazon Property needed for this operation not found",apnfe );
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
catch(AmazonServiceException ase){
if( ase.getStatusCode() > 499 ){
logger.error(ase.getMessage());
}else if(logger.isDebugEnabled()){
logger.debug(ase.getMessage());
}
return Response.status(ase.getStatusCode()).build();
}
catch (StorageException se){
if( se.getCode() > 499 ){
logger.error(se.getMessage());
}else if(logger.isDebugEnabled()){
logger.debug(se.getMessage());
}
return Response.status(se.getCode()).build();
}
catch(RuntimeException re){
logger.error(re.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
// return 404 if not found
if ( inputStream == null ) {
return Response.status( Response.Status.NOT_FOUND ).build();
}
Long lastModified = ( Long ) fileMetadata.get( AssetUtils.LAST_MODIFIED );
Response.ResponseBuilder responseBuilder =
Response.ok( inputStream ).type( ( String ) fileMetadata.get( AssetUtils.CONTENT_TYPE ) )
.lastModified( new Date( lastModified ) );
if ( fileMetadata.get( AssetUtils.E_TAG ) != null ) {
responseBuilder.tag( ( String ) fileMetadata.get( AssetUtils.E_TAG ) );
}
if ( range ) {
responseBuilder.header( "Content-Range", "bytes " + start + "-" + end + "/" + contentLength );
}
return responseBuilder.build();
}