final long accessTime = _timeMaster.currentTimeMillis();
final E entry = _entryConverter.entryFromStorable(rawEntry);
updateLastAccessedForGet(request, response, entry, accessTime);
Compression comp = entry.getCompression();
boolean skipCompression;
// Range to resolve, now that we know full length?
if (range != null) {
range = range.resolveWithTotalLength(entry.getActualUncompressedLength());
final long length = range.calculateLength();
// any bytes matching? If not, it's a failure
if (length <= 0L) {
return response.badRange(new GetErrorResponse<K>(key, "Invalid 'Range' HTTP Header (\""+range+"\")"));
}
// note: can not skip decompress if we have to give range...
skipCompression = false;
} else {
skipCompression = (comp != Compression.NONE) && comp.isAcceptable(acceptableEnc);
}
StreamingResponseContent output;
if (entry.hasExternalData()) { // need to stream from File
File f = entry.getRaw().getExternalFile(_fileManager);
output = new FileBackedResponseContentImpl(diag, _timeMaster, entryStore,
accessTime, f, skipCompression ? null : comp, range, entry);
} else { // inline
ByteContainer inlined = entry.getRaw().getInlinedData();
if (!skipCompression) {
try {
inlined = Compressors.uncompress(inlined, comp, (int) entry.getRaw().getOriginalLength());
} catch (IOException e) {
return internalGetError(response, e, key, "Failed to decompress inline data");
}
}
output = new SimpleStreamingResponseContent(diag, _timeMaster, inlined, range, inlined.byteLength());
}
// #21: provide content length header
long cl = output.getLength();
if (cl >= 0L) {
response = response.setContentLength(cl);
}
// one more thing; add header for range if necessary; also, response code differs
if (range == null) {
response = response.ok(output);
} else {
response = response.partialContent(output, range.asResponseHeader());
}
// Issue #6: Need to provide Etag, if content hash available
int contentHash = rawEntry.getContentHash();
if (contentHash != HashConstants.NO_CHECKSUM) {
StringBuilder sb = new StringBuilder();
sb.append('"');
sb.append(contentHash);
sb.append('"');
response = response.addHeader(ClusterMateConstants.HTTP_HEADER_ETAG, sb.toString());
}
// also need to let client know we left compression in there:
if (skipCompression) {
response = response.setBodyCompression(comp.asContentEncoding());
}
return response;
}