mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-21 15:59:48 +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:
@@ -58,6 +58,7 @@ import org.eclipse.jgit.util.FS;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
import sonia.scm.ScmConstraintViolationException;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.GitUserAgentProvider;
|
||||
@@ -70,6 +71,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Optional.of;
|
||||
import static sonia.scm.ScmConstraintViolationException.Builder.doThrow;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
@@ -727,7 +729,11 @@ public final class GitUtil
|
||||
mergeBaseWalk.setRevFilter(RevFilter.MERGE_BASE);
|
||||
mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(revision1));
|
||||
mergeBaseWalk.markStart(mergeBaseWalk.parseCommit(revision2));
|
||||
return mergeBaseWalk.next().getId();
|
||||
RevCommit ancestor = mergeBaseWalk.next();
|
||||
doThrow()
|
||||
.violation("revisions " + revision1.name() + " and " + revision2.name() + " are not related and therefore do not have a common ancestor", "revisions")
|
||||
.when(ancestor == null);
|
||||
return ancestor.getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,15 +31,12 @@
|
||||
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import org.eclipse.jgit.diff.DiffEntry;
|
||||
import org.eclipse.jgit.diff.DiffFormatter;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -52,22 +49,25 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDiffResult(DiffCommandRequest request, OutputStream output) throws IOException {
|
||||
public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) throws IOException {
|
||||
@SuppressWarnings("squid:S2095") // repository will be closed with the RepositoryService
|
||||
org.eclipse.jgit.lib.Repository repository = open();
|
||||
try (DiffFormatter formatter = new DiffFormatter(new BufferedOutputStream(output))) {
|
||||
formatter.setRepository(repository);
|
||||
|
||||
Differ.Diff diff = Differ.diff(repository, request);
|
||||
Differ.Diff diff = Differ.diff(repository, request);
|
||||
|
||||
for (DiffEntry e : diff.getEntries()) {
|
||||
if (!e.getOldId().equals(e.getNewId())) {
|
||||
formatter.format(e);
|
||||
return output -> {
|
||||
try (DiffFormatter formatter = new DiffFormatter(output)) {
|
||||
formatter.setRepository(repository);
|
||||
|
||||
for (DiffEntry e : diff.getEntries()) {
|
||||
if (!e.getOldId().equals(e.getNewId())) {
|
||||
formatter.format(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatter.flush();
|
||||
}
|
||||
formatter.flush();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class GitDiffCommandTest extends AbstractGitCommandTestBase {
|
||||
DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
|
||||
diffCommandRequest.setRevision("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4");
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest, output);
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest);
|
||||
assertEquals(DIFF_FILE_A + DIFF_FILE_B, output.toString());
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class GitDiffCommandTest extends AbstractGitCommandTestBase {
|
||||
DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
|
||||
diffCommandRequest.setRevision("test-branch");
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest, output);
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest);
|
||||
assertEquals(DIFF_FILE_A + DIFF_FILE_B, output.toString());
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class GitDiffCommandTest extends AbstractGitCommandTestBase {
|
||||
diffCommandRequest.setRevision("test-branch");
|
||||
diffCommandRequest.setPath("a.txt");
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest, output);
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest);
|
||||
assertEquals(DIFF_FILE_A, output.toString());
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class GitDiffCommandTest extends AbstractGitCommandTestBase {
|
||||
diffCommandRequest.setRevision("master");
|
||||
diffCommandRequest.setAncestorChangeset("test-branch");
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest, output);
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest);
|
||||
assertEquals(DIFF_FILE_A_MULTIPLE_REVISIONS + DIFF_FILE_F_MULTIPLE_REVISIONS, output.toString());
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class GitDiffCommandTest extends AbstractGitCommandTestBase {
|
||||
diffCommandRequest.setAncestorChangeset("test-branch");
|
||||
diffCommandRequest.setPath("a.txt");
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest, output);
|
||||
gitDiffCommand.getDiffResult(diffCommandRequest);
|
||||
assertEquals(DIFF_FILE_A_MULTIPLE_REVISIONS, output.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user