mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 16:35:45 +01:00
Postpone writing to output stream in diff command
Without this, the gzip filter would write the first bytes to the response output stream, before the diff command is triggered and potential exceptions may be thrown. When exceptions are thrown too late, filters like the GZip filter may already have sent bytes to the response stream. Afterwards this cannot be undone and the response created by an exception mapper may not be valid anymore.
This commit is contained in:
@@ -4,6 +4,7 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
@@ -20,6 +21,7 @@ import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.StreamingOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DiffRootResource {
|
||||
|
||||
@@ -55,20 +57,17 @@ public class DiffRootResource {
|
||||
@ResponseCode(code = 404, condition = "not found, no revision with the specified param for the repository available or repository not found"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision , @Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") @QueryParam("format") String format ){
|
||||
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision , @Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") @QueryParam("format") String format ) throws IOException {
|
||||
HttpUtil.checkForCRLFInjection(revision);
|
||||
DiffFormat diffFormat = DiffFormat.valueOf(format);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
StreamingOutput responseEntry = output -> {
|
||||
repositoryService.getDiffCommand()
|
||||
.setRevision(revision)
|
||||
.setFormat(diffFormat)
|
||||
.retrieveContent(output);
|
||||
};
|
||||
return Response.ok(responseEntry)
|
||||
DiffCommandBuilder.OutputStreamConsumer outputStreamConsumer = repositoryService.getDiffCommand()
|
||||
.setRevision(revision)
|
||||
.setFormat(diffFormat)
|
||||
.retrieveContent();
|
||||
return Response.ok((StreamingOutput) outputStreamConsumer::accept)
|
||||
.header(HEADER_CONTENT_DISPOSITION, HttpUtil.createContentDispositionAttachmentHeader(String.format("%s-%s.diff", name, revision)))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||
import sonia.scm.repository.api.DiffFormat;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
@@ -138,14 +139,13 @@ public class IncomingRootResource {
|
||||
HttpUtil.checkForCRLFInjection(target);
|
||||
DiffFormat diffFormat = DiffFormat.valueOf(format);
|
||||
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||
StreamingOutput responseEntry = output ->
|
||||
repositoryService.getDiffCommand()
|
||||
.setRevision(source)
|
||||
.setAncestorChangeset(target)
|
||||
.setFormat(diffFormat)
|
||||
.retrieveContent(output);
|
||||
DiffCommandBuilder.OutputStreamConsumer outputStreamConsumer = repositoryService.getDiffCommand()
|
||||
.setRevision(source)
|
||||
.setAncestorChangeset(target)
|
||||
.setFormat(diffFormat)
|
||||
.retrieveContent();
|
||||
|
||||
return Response.ok(responseEntry)
|
||||
return Response.ok((StreamingOutput) outputStreamConsumer::accept)
|
||||
.header(HEADER_CONTENT_DISPOSITION, HttpUtil.createContentDispositionAttachmentHeader(String.format("%s-%s.diff", name, source)))
|
||||
.build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user