Merge pull request #9256 from DSpace/backport-9248-to-dspace-7_x

[Port dspace-7_x] Return headers for HEAD request
This commit is contained in:
Alan Orth
2024-01-11 18:43:12 +03:00
committed by GitHub
3 changed files with 30 additions and 10 deletions

View File

@@ -138,6 +138,7 @@ public class BitstreamRestController {
.withBufferSize(BUFFER_SIZE) .withBufferSize(BUFFER_SIZE)
.withFileName(name) .withFileName(name)
.withChecksum(bit.getChecksum()) .withChecksum(bit.getChecksum())
.withLength(bit.getSizeBytes())
.withMimetype(mimetype) .withMimetype(mimetype)
.with(request) .with(request)
.with(response); .with(response);
@@ -167,6 +168,12 @@ public class BitstreamRestController {
//Send the data //Send the data
if (httpHeadersInitializer.isValid()) { if (httpHeadersInitializer.isValid()) {
HttpHeaders httpHeaders = httpHeadersInitializer.initialiseHeaders(); HttpHeaders httpHeaders = httpHeadersInitializer.initialiseHeaders();
if (RequestMethod.HEAD.name().equals(request.getMethod())) {
log.debug("HEAD request - no response body");
return ResponseEntity.ok().headers(httpHeaders).build();
}
return ResponseEntity.ok().headers(httpHeaders).body(bitstreamResource); return ResponseEntity.ok().headers(httpHeaders).body(bitstreamResource);
} }

View File

@@ -14,6 +14,7 @@ import static javax.mail.internet.MimeUtility.encodeText;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -33,7 +34,6 @@ public class HttpHeadersInitializer {
protected final Logger log = LoggerFactory.getLogger(this.getClass()); protected final Logger log = LoggerFactory.getLogger(this.getClass());
private static final String METHOD_HEAD = "HEAD";
private static final String MULTIPART_BOUNDARY = "MULTIPART_BYTERANGES"; private static final String MULTIPART_BOUNDARY = "MULTIPART_BYTERANGES";
private static final String CONTENT_TYPE_MULTITYPE_WITH_BOUNDARY = "multipart/byteranges; boundary=" + private static final String CONTENT_TYPE_MULTITYPE_WITH_BOUNDARY = "multipart/byteranges; boundary=" +
MULTIPART_BOUNDARY; MULTIPART_BOUNDARY;
@@ -144,6 +144,9 @@ public class HttpHeadersInitializer {
if (checksum != null) { if (checksum != null) {
httpHeaders.put(ETAG, Collections.singletonList(checksum)); httpHeaders.put(ETAG, Collections.singletonList(checksum));
} }
if (Objects.nonNull((Long.valueOf(this.length)))) {
httpHeaders.put(HttpHeaders.CONTENT_LENGTH, Collections.singletonList(String.valueOf(this.length)));
}
httpHeaders.put(LAST_MODIFIED, Collections.singletonList(FastHttpDateFormat.formatDate(lastModified))); httpHeaders.put(LAST_MODIFIED, Collections.singletonList(FastHttpDateFormat.formatDate(lastModified)));
httpHeaders.put(EXPIRES, Collections.singletonList(FastHttpDateFormat.formatDate( httpHeaders.put(EXPIRES, Collections.singletonList(FastHttpDateFormat.formatDate(
System.currentTimeMillis() + DEFAULT_EXPIRE_TIME))); System.currentTimeMillis() + DEFAULT_EXPIRE_TIME)));
@@ -165,16 +168,14 @@ public class HttpHeadersInitializer {
httpHeaders.put(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, httpHeaders.put(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
Collections.singletonList(HttpHeaders.ACCEPT_RANGES)); Collections.singletonList(HttpHeaders.ACCEPT_RANGES));
httpHeaders.put(CONTENT_DISPOSITION, Collections.singletonList(String.format(CONTENT_DISPOSITION_FORMAT,
disposition,
encodeText(fileName))));
log.debug("Content-Disposition : {}", disposition);
// Content phase // distposition may be null here if contentType is null
if (METHOD_HEAD.equals(request.getMethod())) { if (!isNullOrEmpty(disposition)) {
log.debug("HEAD request - skipping content"); httpHeaders.put(CONTENT_DISPOSITION, Collections.singletonList(String.format(CONTENT_DISPOSITION_FORMAT,
return null; disposition,
encodeText(fileName))));
} }
log.debug("Content-Disposition : {}", disposition);
return httpHeaders; return httpHeaders;

View File

@@ -205,6 +205,18 @@ public class BitstreamRestControllerIT extends AbstractControllerIntegrationTest
} }
context.restoreAuthSystemState(); context.restoreAuthSystemState();
//** WHEN **
// we want to know what we are downloading before we download it
getClient().perform(head("/api/core/bitstreams/" + bitstream.getID() + "/content"))
//** THEN **
.andExpect(status().isOk())
//The Content Length must match the full length
.andExpect(header().longValue("Content-Length", bitstreamContent.getBytes().length))
.andExpect(header().string("Content-Type", "text/plain;charset=UTF-8"))
.andExpect(header().string("ETag", "\"" + bitstream.getChecksum() + "\""))
.andExpect(content().bytes(new byte[] {}));
//** WHEN ** //** WHEN **
//We download the bitstream //We download the bitstream
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content")) getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
@@ -231,7 +243,7 @@ public class BitstreamRestControllerIT extends AbstractControllerIntegrationTest
.andExpect(status().isNotModified()); .andExpect(status().isNotModified());
//The download and head request should also be logged as a statistics record //The download and head request should also be logged as a statistics record
checkNumberOfStatsRecords(bitstream, 2); checkNumberOfStatsRecords(bitstream, 3);
} }
@Test @Test