* master: HTTP: cookie file stores expiration in seconds Update Orbit to S20210223232630 LFS: handle invalid pointers better Fix errorprone configuration for maven-compiler-plugin with javac Change-Id: Ib76e754bd36789de0a3c6b85a4814aa1fe9cb401tags/v5.11.0.202103031150-rc1
</executions> | </executions> | ||||
</plugin> | </plugin> | ||||
<plugin> | <plugin> | ||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | <artifactId>maven-compiler-plugin</artifactId> | ||||
<version>3.8.1</version> | |||||
<configuration> | <configuration> | ||||
<compilerVersion>${javac.target}</compilerVersion> | |||||
<source>${javac.target}</source> | |||||
<target>${javac.target}</target> | |||||
<encoding>UTF-8</encoding> | |||||
<source>1.8</source> | |||||
<target>1.8</target> | |||||
<generatedSourcesDirectory>.apt_generated</generatedSourcesDirectory> | <generatedSourcesDirectory>.apt_generated</generatedSourcesDirectory> | ||||
</configuration> | </configuration> | ||||
<executions> | |||||
<execution> | |||||
<id>compile-with-errorprone</id> | |||||
<phase>compile</phase> | |||||
<goals> | |||||
<goal>compile</goal> | |||||
</goals> | |||||
<configuration> | |||||
<compilerId>javac-with-errorprone</compilerId> | |||||
<forceJavacCompilerUse>true</forceJavacCompilerUse> | |||||
</configuration> | |||||
</execution> | |||||
</executions> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.codehaus.plexus</groupId> | |||||
<artifactId>plexus-compiler-javac</artifactId> | |||||
<version>2.8.5</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.codehaus.plexus</groupId> | |||||
<artifactId>plexus-compiler-javac-errorprone</artifactId> | |||||
<version>2.8.5</version> | |||||
</dependency> | |||||
<!-- override plexus-compiler-javac-errorprone's dependency on | |||||
Error Prone with the latest version --> | |||||
<dependency> | |||||
<groupId>com.google.errorprone</groupId> | |||||
<artifactId>error_prone_core</artifactId> | |||||
<version>2.3.4</version> | |||||
</dependency> | |||||
</dependencies> | |||||
</plugin> | </plugin> | ||||
<plugin> | <plugin> | ||||
<groupId>org.apache.maven.plugins</groupId> | <groupId>org.apache.maven.plugins</groupId> |
Bundle-Vendor: %Bundle-Vendor | Bundle-Vendor: %Bundle-Vendor | ||||
Bundle-Localization: plugin | Bundle-Localization: plugin | ||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.11.0,5.12.0)", | |||||
Import-Package: org.eclipse.jgit.api;version="[5.11.0,5.12.0)", | |||||
org.eclipse.jgit.attributes;version="[5.11.0,5.12.0)", | |||||
org.eclipse.jgit.internal.storage.dfs;version="[5.11.0,5.12.0)", | |||||
org.eclipse.jgit.junit;version="[5.11.0,5.12.0)", | org.eclipse.jgit.junit;version="[5.11.0,5.12.0)", | ||||
org.eclipse.jgit.lfs;version="[5.11.0,5.12.0)", | org.eclipse.jgit.lfs;version="[5.11.0,5.12.0)", | ||||
org.eclipse.jgit.lfs.errors;version="[5.11.0,5.12.0)", | org.eclipse.jgit.lfs.errors;version="[5.11.0,5.12.0)", |
/* | |||||
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others | |||||
* | |||||
* This program and the accompanying materials are made available under the | |||||
* terms of the Eclipse Distribution License v. 1.0 which is available at | |||||
* https://www.eclipse.org/org/documents/edl-v10.php. | |||||
* | |||||
* SPDX-License-Identifier: BSD-3-Clause | |||||
*/ | |||||
package org.eclipse.jgit.lfs; | |||||
import static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertTrue; | |||||
import java.io.File; | |||||
import java.nio.charset.StandardCharsets; | |||||
import java.nio.file.Files; | |||||
import org.eclipse.jgit.api.Git; | |||||
import org.eclipse.jgit.api.ResetCommand.ResetType; | |||||
import org.eclipse.jgit.attributes.FilterCommandRegistry; | |||||
import org.eclipse.jgit.junit.RepositoryTestCase; | |||||
import org.eclipse.jgit.lfs.lib.Constants; | |||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.junit.AfterClass; | |||||
import org.junit.Before; | |||||
import org.junit.BeforeClass; | |||||
import org.junit.Test; | |||||
public class LfsGitTest extends RepositoryTestCase { | |||||
private static final String SMUDGE_NAME = org.eclipse.jgit.lib.Constants.BUILTIN_FILTER_PREFIX | |||||
+ Constants.ATTR_FILTER_DRIVER_PREFIX | |||||
+ org.eclipse.jgit.lib.Constants.ATTR_FILTER_TYPE_SMUDGE; | |||||
private static final String CLEAN_NAME = org.eclipse.jgit.lib.Constants.BUILTIN_FILTER_PREFIX | |||||
+ Constants.ATTR_FILTER_DRIVER_PREFIX | |||||
+ org.eclipse.jgit.lib.Constants.ATTR_FILTER_TYPE_CLEAN; | |||||
@BeforeClass | |||||
public static void installLfs() { | |||||
FilterCommandRegistry.register(SMUDGE_NAME, SmudgeFilter.FACTORY); | |||||
FilterCommandRegistry.register(CLEAN_NAME, CleanFilter.FACTORY); | |||||
} | |||||
@AfterClass | |||||
public static void removeLfs() { | |||||
FilterCommandRegistry.unregister(SMUDGE_NAME); | |||||
FilterCommandRegistry.unregister(CLEAN_NAME); | |||||
} | |||||
private Git git; | |||||
@Override | |||||
@Before | |||||
public void setUp() throws Exception { | |||||
super.setUp(); | |||||
git = new Git(db); | |||||
// commit something | |||||
writeTrashFile("Test.txt", "Hello world"); | |||||
git.add().addFilepattern("Test.txt").call(); | |||||
git.commit().setMessage("Initial commit").call(); | |||||
// prepare the config for LFS | |||||
StoredConfig config = git.getRepository().getConfig(); | |||||
config.setString("filter", "lfs", "clean", CLEAN_NAME); | |||||
config.setString("filter", "lfs", "smudge", SMUDGE_NAME); | |||||
config.save(); | |||||
} | |||||
@Test | |||||
public void checkoutNonLfsPointer() throws Exception { | |||||
String content = "size_t\nsome_function(void* ptr);\n"; | |||||
File smallFile = writeTrashFile("Test.txt", content); | |||||
StringBuilder largeContent = new StringBuilder( | |||||
LfsPointer.SIZE_THRESHOLD * 4); | |||||
while (largeContent.length() < LfsPointer.SIZE_THRESHOLD * 4) { | |||||
largeContent.append(content); | |||||
} | |||||
File largeFile = writeTrashFile("large.txt", largeContent.toString()); | |||||
fsTick(largeFile); | |||||
git.add().addFilepattern("Test.txt").addFilepattern("large.txt").call(); | |||||
git.commit().setMessage("Text files").call(); | |||||
writeTrashFile(".gitattributes", "*.txt filter=lfs"); | |||||
git.add().addFilepattern(".gitattributes").call(); | |||||
git.commit().setMessage("attributes").call(); | |||||
assertTrue(smallFile.delete()); | |||||
assertTrue(largeFile.delete()); | |||||
// This reset will run the two text files through the smudge filter | |||||
git.reset().setMode(ResetType.HARD).call(); | |||||
assertTrue(smallFile.exists()); | |||||
assertTrue(largeFile.exists()); | |||||
checkFile(smallFile, content); | |||||
checkFile(largeFile, largeContent.toString()); | |||||
// Modify the large file | |||||
largeContent.append(content); | |||||
writeTrashFile("large.txt", largeContent.toString()); | |||||
// This should convert largeFile to an LFS pointer | |||||
git.add().addFilepattern("large.txt").call(); | |||||
git.commit().setMessage("Large modified").call(); | |||||
String lfsPtr = "version https://git-lfs.github.com/spec/v1\n" | |||||
+ "oid sha256:d041ab19bd7edd899b3c0450d0f61819f96672f0b22d26c9753abc62e1261614\n" | |||||
+ "size 858\n"; | |||||
assertEquals("[.gitattributes, mode:100644, content:*.txt filter=lfs]" | |||||
+ "[Test.txt, mode:100644, content:" + content + ']' | |||||
+ "[large.txt, mode:100644, content:" + lfsPtr + ']', | |||||
indexState(CONTENT)); | |||||
// Verify the file has been saved | |||||
File savedFile = new File(db.getDirectory(), "lfs"); | |||||
savedFile = new File(savedFile, "objects"); | |||||
savedFile = new File(savedFile, "d0"); | |||||
savedFile = new File(savedFile, "41"); | |||||
savedFile = new File(savedFile, | |||||
"d041ab19bd7edd899b3c0450d0f61819f96672f0b22d26c9753abc62e1261614"); | |||||
String saved = new String(Files.readAllBytes(savedFile.toPath()), | |||||
StandardCharsets.UTF_8); | |||||
assertEquals(saved, largeContent.toString()); | |||||
assertTrue(smallFile.delete()); | |||||
assertTrue(largeFile.delete()); | |||||
git.reset().setMode(ResetType.HARD).call(); | |||||
assertTrue(smallFile.exists()); | |||||
assertTrue(largeFile.exists()); | |||||
checkFile(smallFile, content); | |||||
checkFile(largeFile, largeContent.toString()); | |||||
assertEquals("[.gitattributes, mode:100644, content:*.txt filter=lfs]" | |||||
+ "[Test.txt, mode:100644, content:" + content + ']' | |||||
+ "[large.txt, mode:100644, content:" + lfsPtr + ']', | |||||
indexState(CONTENT)); | |||||
git.add().addFilepattern("Test.txt").call(); | |||||
git.commit().setMessage("Small committed again").call(); | |||||
String lfsPtrSmall = "version https://git-lfs.github.com/spec/v1\n" | |||||
+ "oid sha256:9110463275fb0e2f0e9fdeaf84e598e62915666161145cf08927079119cc7814\n" | |||||
+ "size 33\n"; | |||||
assertEquals("[.gitattributes, mode:100644, content:*.txt filter=lfs]" | |||||
+ "[Test.txt, mode:100644, content:" + lfsPtrSmall + ']' | |||||
+ "[large.txt, mode:100644, content:" + lfsPtr + ']', | |||||
indexState(CONTENT)); | |||||
assertTrue(git.status().call().isClean()); | |||||
} | |||||
} |
/* | /* | ||||
* Copyright (C) 2017, Markus Duft <markus.duft@ssi-schaefer.com> and others | |||||
* Copyright (C) 2017, 2021 Markus Duft <markus.duft@ssi-schaefer.com> and others | |||||
* | * | ||||
* This program and the accompanying materials are made available under the | * This program and the accompanying materials are made available under the | ||||
* terms of the Eclipse Distribution License v. 1.0 which is available at | * terms of the Eclipse Distribution License v. 1.0 which is available at | ||||
*/ | */ | ||||
public static ObjectLoader smudgeLfsBlob(Repository db, ObjectLoader loader) | public static ObjectLoader smudgeLfsBlob(Repository db, ObjectLoader loader) | ||||
throws IOException { | throws IOException { | ||||
if (loader.getSize() > LfsPointer.SIZE_THRESHOLD) { | |||||
if (loader.getSize() > LfsPointer.FULL_SIZE_THRESHOLD) { | |||||
return loader; | return loader; | ||||
} | } | ||||
import static java.nio.charset.StandardCharsets.UTF_8; | import static java.nio.charset.StandardCharsets.UTF_8; | ||||
import java.io.BufferedInputStream; | |||||
import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
import java.io.ByteArrayInputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
import org.eclipse.jgit.lfs.lib.AnyLongObjectId; | import org.eclipse.jgit.lfs.lib.AnyLongObjectId; | ||||
import org.eclipse.jgit.lfs.lib.Constants; | import org.eclipse.jgit.lfs.lib.Constants; | ||||
import org.eclipse.jgit.lfs.lib.LongObjectId; | import org.eclipse.jgit.lfs.lib.LongObjectId; | ||||
import org.eclipse.jgit.util.IO; | |||||
/** | /** | ||||
* Represents an LFS pointer file | * Represents an LFS pointer file | ||||
public static final String HASH_FUNCTION_NAME = Constants.LONG_HASH_FUNCTION | public static final String HASH_FUNCTION_NAME = Constants.LONG_HASH_FUNCTION | ||||
.toLowerCase(Locale.ROOT).replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$ | .toLowerCase(Locale.ROOT).replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$ | ||||
/** | |||||
* {@link #SIZE_THRESHOLD} is too low; with lfs extensions a LFS pointer can | |||||
* be larger. But 8kB should be more than enough. | |||||
*/ | |||||
static final int FULL_SIZE_THRESHOLD = 8 * 1024; | |||||
private final AnyLongObjectId oid; | private final AnyLongObjectId oid; | ||||
private final long size; | private final long size; | ||||
/** | /** | ||||
* Try to parse the data provided by an InputStream to the format defined by | * Try to parse the data provided by an InputStream to the format defined by | ||||
* {@link #VERSION} | |||||
* {@link #VERSION}. If the given stream supports mark and reset as | |||||
* indicated by {@link InputStream#markSupported()}, its input position will | |||||
* be reset if the stream content is not actually a LFS pointer (i.e., when | |||||
* {@code null} is returned). If the stream content is an invalid LFS | |||||
* pointer or the given stream does not support mark/reset, the input | |||||
* position may not be reset. | |||||
* | * | ||||
* @param in | * @param in | ||||
* the {@link java.io.InputStream} from where to read the data | * the {@link java.io.InputStream} from where to read the data | ||||
* @return an {@link org.eclipse.jgit.lfs.LfsPointer} or <code>null</code> | |||||
* if the stream was not parseable as LfsPointer | |||||
* @return an {@link org.eclipse.jgit.lfs.LfsPointer} or {@code null} if the | |||||
* stream was not parseable as LfsPointer | |||||
* @throws java.io.IOException | * @throws java.io.IOException | ||||
*/ | */ | ||||
@Nullable | @Nullable | ||||
public static LfsPointer parseLfsPointer(InputStream in) | public static LfsPointer parseLfsPointer(InputStream in) | ||||
throws IOException { | throws IOException { | ||||
if (in.markSupported()) { | |||||
return parse(in); | |||||
} | |||||
// Fallback; note that while parse() resets its input stream, that won't | |||||
// reset "in". | |||||
return parse(new BufferedInputStream(in)); | |||||
} | |||||
@Nullable | |||||
private static LfsPointer parse(InputStream in) | |||||
throws IOException { | |||||
if (!in.markSupported()) { | |||||
// No translation; internal error | |||||
throw new IllegalArgumentException( | |||||
"LFS pointer parsing needs InputStream.markSupported() == true"); //$NON-NLS-1$ | |||||
} | |||||
// Try reading only a short block first. | |||||
in.mark(SIZE_THRESHOLD); | |||||
byte[] preamble = new byte[SIZE_THRESHOLD]; | |||||
int length = IO.readFully(in, preamble, 0); | |||||
if (length < preamble.length || in.read() < 0) { | |||||
// We have the whole file. Try to parse a pointer from it. | |||||
try (BufferedReader r = new BufferedReader(new InputStreamReader( | |||||
new ByteArrayInputStream(preamble, 0, length), UTF_8))) { | |||||
LfsPointer ptr = parse(r); | |||||
if (ptr == null) { | |||||
in.reset(); | |||||
} | |||||
return ptr; | |||||
} | |||||
} | |||||
// Longer than SIZE_THRESHOLD: expect "version" to be the first line. | |||||
boolean hasVersion = checkVersion(preamble); | |||||
in.reset(); | |||||
if (!hasVersion) { | |||||
return null; | |||||
} | |||||
in.mark(FULL_SIZE_THRESHOLD); | |||||
byte[] fullPointer = new byte[FULL_SIZE_THRESHOLD]; | |||||
length = IO.readFully(in, fullPointer, 0); | |||||
if (length == fullPointer.length && in.read() >= 0) { | |||||
in.reset(); | |||||
return null; // Too long. | |||||
} | |||||
try (BufferedReader r = new BufferedReader(new InputStreamReader( | |||||
new ByteArrayInputStream(fullPointer, 0, length), UTF_8))) { | |||||
LfsPointer ptr = parse(r); | |||||
if (ptr == null) { | |||||
in.reset(); | |||||
} | |||||
return ptr; | |||||
} | |||||
} | |||||
private static LfsPointer parse(BufferedReader r) throws IOException { | |||||
boolean versionLine = false; | boolean versionLine = false; | ||||
LongObjectId id = null; | LongObjectId id = null; | ||||
long sz = -1; | long sz = -1; | ||||
// This parsing is a bit too general if we go by the spec at | // This parsing is a bit too general if we go by the spec at | ||||
// https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md | // https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md | ||||
// Comment lines are not mentioned in the spec, and the "version" line | |||||
// MUST be the first. | |||||
try (BufferedReader br = new BufferedReader( | |||||
new InputStreamReader(in, UTF_8))) { | |||||
for (String s = br.readLine(); s != null; s = br.readLine()) { | |||||
if (s.startsWith("#") || s.length() == 0) { //$NON-NLS-1$ | |||||
continue; | |||||
} else if (s.startsWith("version")) { //$NON-NLS-1$ | |||||
if (versionLine || s.length() < 8 || s.charAt(7) != ' ') { | |||||
return null; // Not a LFS pointer | |||||
} | |||||
String rest = s.substring(8).trim(); | |||||
versionLine = VERSION.equals(rest) | |||||
|| VERSION_LEGACY.equals(rest); | |||||
if (!versionLine) { | |||||
return null; // Not a LFS pointer | |||||
} | |||||
} else { | |||||
try { | |||||
if (s.startsWith("oid sha256:")) { //$NON-NLS-1$ | |||||
if (id != null) { | |||||
return null; // Not a LFS pointer | |||||
} | |||||
id = LongObjectId | |||||
.fromString(s.substring(11).trim()); | |||||
} else if (s.startsWith("size")) { //$NON-NLS-1$ | |||||
if (sz > 0 || s.length() < 5 | |||||
|| s.charAt(4) != ' ') { | |||||
return null; // Not a LFS pointer | |||||
} | |||||
sz = Long.parseLong(s.substring(5).trim()); | |||||
// Comment lines are not mentioned in the spec, the "version" line | |||||
// MUST be the first, and keys are ordered alphabetically. | |||||
for (String s = r.readLine(); s != null; s = r.readLine()) { | |||||
if (s.startsWith("#") || s.length() == 0) { //$NON-NLS-1$ | |||||
continue; | |||||
} else if (s.startsWith("version")) { //$NON-NLS-1$ | |||||
if (versionLine || !checkVersionLine(s)) { | |||||
return null; // Not a LFS pointer | |||||
} | |||||
versionLine = true; | |||||
} else { | |||||
try { | |||||
if (s.startsWith("oid sha256:")) { //$NON-NLS-1$ | |||||
if (id != null) { | |||||
return null; // Not a LFS pointer | |||||
} | } | ||||
} catch (RuntimeException e) { | |||||
// We could not parse the line. If we have a version | |||||
// already, this is a corrupt LFS pointer. Otherwise it | |||||
// is just not an LFS pointer. | |||||
if (versionLine) { | |||||
throw e; | |||||
id = LongObjectId.fromString(s.substring(11).trim()); | |||||
} else if (s.startsWith("size")) { //$NON-NLS-1$ | |||||
if (sz > 0 || s.length() < 5 || s.charAt(4) != ' ') { | |||||
return null; // Not a LFS pointer | |||||
} | } | ||||
return null; | |||||
sz = Long.parseLong(s.substring(5).trim()); | |||||
} | } | ||||
} catch (RuntimeException e) { | |||||
// We could not parse the line. If we have a version | |||||
// already, this is a corrupt LFS pointer. Otherwise it | |||||
// is just not an LFS pointer. | |||||
if (versionLine) { | |||||
throw e; | |||||
} | |||||
return null; | |||||
} | } | ||||
} | } | ||||
if (versionLine && id != null && sz > -1) { | if (versionLine && id != null && sz > -1) { | ||||
return null; | return null; | ||||
} | } | ||||
private static boolean checkVersion(byte[] data) { | |||||
// According to the spec at | |||||
// https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md | |||||
// it MUST always be the first line. | |||||
try (BufferedReader r = new BufferedReader( | |||||
new InputStreamReader(new ByteArrayInputStream(data), UTF_8))) { | |||||
String s = r.readLine(); | |||||
if (s != null && s.startsWith("version")) { //$NON-NLS-1$ | |||||
return checkVersionLine(s); | |||||
} | |||||
} catch (IOException e) { | |||||
// Doesn't occur, we're reading from a byte array! | |||||
} | |||||
return false; | |||||
} | |||||
private static boolean checkVersionLine(String s) { | |||||
if (s.length() < 8 || s.charAt(7) != ' ') { | |||||
return false; // Not a valid LFS pointer version line | |||||
} | |||||
String rest = s.substring(8).trim(); | |||||
return VERSION.equals(rest) || VERSION_LEGACY.equals(rest); | |||||
} | |||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
public String toString() { | public String toString() { |
/* | /* | ||||
* Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.com> and others | |||||
* Copyright (C) 2016, 2021 Christian Halstrick <christian.halstrick@sap.com> and others | |||||
* | * | ||||
* This program and the accompanying materials are made available under the | * This program and the accompanying materials are made available under the | ||||
* terms of the Eclipse Distribution License v. 1.0 which is available at | * terms of the Eclipse Distribution License v. 1.0 which is available at | ||||
import static java.nio.charset.StandardCharsets.UTF_8; | import static java.nio.charset.StandardCharsets.UTF_8; | ||||
import java.io.BufferedInputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
*/ | */ | ||||
public SmudgeFilter(Repository db, InputStream in, OutputStream out) | public SmudgeFilter(Repository db, InputStream in, OutputStream out) | ||||
throws IOException { | throws IOException { | ||||
this(in.markSupported() ? in : new BufferedInputStream(in), out, db); | |||||
} | |||||
private SmudgeFilter(InputStream in, OutputStream out, Repository db) | |||||
throws IOException { | |||||
super(in, out); | super(in, out); | ||||
InputStream from = in; | |||||
try { | try { | ||||
Lfs lfs = new Lfs(db); | |||||
LfsPointer res = LfsPointer.parseLfsPointer(in); | |||||
LfsPointer res = LfsPointer.parseLfsPointer(from); | |||||
if (res != null) { | if (res != null) { | ||||
AnyLongObjectId oid = res.getOid(); | AnyLongObjectId oid = res.getOid(); | ||||
Lfs lfs = new Lfs(db); | |||||
Path mediaFile = lfs.getMediaFile(oid); | Path mediaFile = lfs.getMediaFile(oid); | ||||
if (!Files.exists(mediaFile)) { | if (!Files.exists(mediaFile)) { | ||||
downloadLfsResource(lfs, db, res); | downloadLfsResource(lfs, db, res); | ||||
} | } | ||||
this.in = Files.newInputStream(mediaFile); | this.in = Files.newInputStream(mediaFile); | ||||
} else { | |||||
// Not swapped; stream was reset, don't close! | |||||
from = null; | |||||
} | } | ||||
} finally { | } finally { | ||||
in.close(); // make sure the swapped stream is closed properly. | |||||
if (from != null) { | |||||
from.close(); // Close the swapped-out stream | |||||
} | |||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Copyright (C) 2015, 2017, Dariusz Luksza <dariusz@luksza.org> and others | |||||
* Copyright (C) 2015, 2021 Dariusz Luksza <dariusz@luksza.org> and others | |||||
* | * | ||||
* This program and the accompanying materials are made available under the | * This program and the accompanying materials are made available under the | ||||
* terms of the Eclipse Distribution License v. 1.0 which is available at | * terms of the Eclipse Distribution License v. 1.0 which is available at | ||||
try (ObjectStream stream = object.openStream()) { | try (ObjectStream stream = object.openStream()) { | ||||
pointer = LfsPointer.parseLfsPointer(stream); | pointer = LfsPointer.parseLfsPointer(stream); | ||||
return pointer != null; | return pointer != null; | ||||
} catch (RuntimeException e) { | |||||
return false; | |||||
} | } | ||||
} | } | ||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.10" sequenceNumber="1613861945"> | |||||
<target name="jgit-4.10" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.10" with source configurePhase | target "jgit-4.10" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2018-12/" { | location "https://download.eclipse.org/releases/2018-12/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.11" sequenceNumber="1613862033"> | |||||
<target name="jgit-4.11" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.11" with source configurePhase | target "jgit-4.11" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2019-03/" { | location "https://download.eclipse.org/releases/2019-03/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.12" sequenceNumber="1613862033"> | |||||
<target name="jgit-4.12" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.12" with source configurePhase | target "jgit-4.12" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2019-06/" { | location "https://download.eclipse.org/releases/2019-06/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.13" sequenceNumber="1613862034"> | |||||
<target name="jgit-4.13" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.13" with source configurePhase | target "jgit-4.13" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2019-09/" { | location "https://download.eclipse.org/releases/2019-09/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.14" sequenceNumber="1613862030"> | |||||
<target name="jgit-4.14" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.14" with source configurePhase | target "jgit-4.14" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2019-12/201912181000/" { | location "https://download.eclipse.org/releases/2019-12/201912181000/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.15" sequenceNumber="1613862030"> | |||||
<target name="jgit-4.15" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.15" with source configurePhase | target "jgit-4.15" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2020-03/202003181000/" { | location "https://download.eclipse.org/releases/2020-03/202003181000/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.16" sequenceNumber="1613862033"> | |||||
<target name="jgit-4.16" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.16" with source configurePhase | target "jgit-4.16" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2020-06/" { | location "https://download.eclipse.org/releases/2020-06/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.17" sequenceNumber="1613862034"> | |||||
<target name="jgit-4.17" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.17" with source configurePhase | target "jgit-4.17" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2020-09/" { | location "https://download.eclipse.org/releases/2020-09/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.18" sequenceNumber="1613862034"> | |||||
<target name="jgit-4.18" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.18" with source configurePhase | target "jgit-4.18" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2020-12/" { | location "https://download.eclipse.org/releases/2020-12/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.19-staging" sequenceNumber="1613862034"> | |||||
<target name="jgit-4.19-staging" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.19-staging" with source configurePhase | target "jgit-4.19-staging" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/staging/2021-03/" { | location "https://download.eclipse.org/staging/2021-03/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.6" sequenceNumber="1613862049"> | |||||
<target name="jgit-4.6" sequenceNumber="1614632988"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.6" with source configurePhase | target "jgit-4.6" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/neon/" { | location "https://download.eclipse.org/releases/neon/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.7" sequenceNumber="1613862039"> | |||||
<target name="jgit-4.7" sequenceNumber="1614632978"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.7" with source configurePhase | target "jgit-4.7" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/oxygen/" { | location "https://download.eclipse.org/releases/oxygen/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.8" sequenceNumber="1613862034"> | |||||
<target name="jgit-4.8" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.8" with source configurePhase | target "jgit-4.8" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/photon/" { | location "https://download.eclipse.org/releases/photon/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.9" sequenceNumber="1613862033"> | |||||
<target name="jgit-4.9" sequenceNumber="1614632975"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> | ||||
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> | ||||
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> | ||||
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> | ||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/> | |||||
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository"/> | |||||
</location> | </location> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.osgi" version="0.0.0"/> | <unit id="org.eclipse.osgi" version="0.0.0"/> |
target "jgit-4.9" with source configurePhase | target "jgit-4.9" with source configurePhase | ||||
include "projects/jetty-9.4.x.tpd" | include "projects/jetty-9.4.x.tpd" | ||||
include "orbit/S20210216215844.tpd" | |||||
include "orbit/S20210223232630.tpd" | |||||
location "https://download.eclipse.org/releases/2018-09/" { | location "https://download.eclipse.org/releases/2018-09/" { | ||||
org.eclipse.osgi lazy | org.eclipse.osgi lazy |
target "S20210216215844" with source configurePhase | |||||
target "S20210223232630" with source configurePhase | |||||
// see https://download.eclipse.org/tools/orbit/downloads/ | // see https://download.eclipse.org/tools/orbit/downloads/ | ||||
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository" { | |||||
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210223232630/repository" { | |||||
com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | ||||
com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626] | ||||
com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] | com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] |
some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple1 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200000 key2 valueFromSimple1 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200 key1 valueFromSimple1 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200 key2 valueFromSimple1 |
some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple2 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200000 key3 valueFromSimple2 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200 key1 valueFromSimple2 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200 key3 valueFromSimple2 |
some-domain1 TRUE /some/path1 FALSE 0 key1 value1 | some-domain1 TRUE /some/path1 FALSE 0 key1 value1 | ||||
# expires date is 01/01/2030 @ 12:00am (UTC) | # expires date is 01/01/2030 @ 12:00am (UTC) | ||||
#HttpOnly_.some-domain2 TRUE /some/path2 TRUE 1893499200000 key2 value2 | |||||
#HttpOnly_.some-domain2 TRUE /some/path2 TRUE 1893499200 key2 value2 | |||||
some-domain3 TRUE /some/path3 FALSE 1893499200000 key3 value3 | |||||
some-domain3 TRUE /some/path3 FALSE 1893499200 key3 value3 |
some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple1 | |||||
some-domain1 TRUE /some/path1 FALSE 1893499200 key2 valueFromSimple1 |
import java.nio.file.Files; | import java.nio.file.Files; | ||||
import java.nio.file.Path; | import java.nio.file.Path; | ||||
import java.nio.file.StandardCopyOption; | import java.nio.file.StandardCopyOption; | ||||
import java.time.Duration; | |||||
import java.time.Instant; | import java.time.Instant; | ||||
import java.time.temporal.ChronoUnit; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Date; | |||||
import java.util.LinkedHashSet; | import java.util.LinkedHashSet; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.regex.Pattern; | |||||
import org.eclipse.jgit.internal.storage.file.LockFile; | import org.eclipse.jgit.internal.storage.file.LockFile; | ||||
import org.eclipse.jgit.util.http.HttpCookiesMatcher; | import org.eclipse.jgit.util.http.HttpCookiesMatcher; | ||||
private URL baseUrl; | private URL baseUrl; | ||||
/** | /** | ||||
* This is the expiration date that is used in the test cookie files | |||||
* This is the expiration date that is used in the test cookie files. | |||||
*/ | */ | ||||
private static long JAN_01_2030_NOON = Instant | |||||
.parse("2030-01-01T12:00:00.000Z").toEpochMilli(); | |||||
private static final Instant TEST_EXPIRY_DATE = Instant | |||||
.parse("2030-01-01T12:00:00.000Z"); | |||||
/** Earlier than TEST_EXPIRY_DATE. */ | |||||
private static final Instant TEST_DATE = TEST_EXPIRY_DATE.minus(180, | |||||
ChronoUnit.DAYS); | |||||
@Before | @Before | ||||
public void setUp() throws IOException { | public void setUp() throws IOException { | ||||
cookie.setPath("/"); | cookie.setPath("/"); | ||||
cookie.setMaxAge(1000); | cookie.setMaxAge(1000); | ||||
cookies.add(cookie); | cookies.add(cookie); | ||||
Date creationDate = new Date(); | |||||
try (Writer writer = Files.newBufferedWriter(tmpFile, | try (Writer writer = Files.newBufferedWriter(tmpFile, | ||||
StandardCharsets.US_ASCII)) { | StandardCharsets.US_ASCII)) { | ||||
NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); | |||||
NetscapeCookieFile.write(writer, cookies, baseUrl, TEST_DATE); | |||||
} | } | ||||
String expectedExpiration = String | String expectedExpiration = String | ||||
.valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); | |||||
.valueOf(TEST_DATE.getEpochSecond() + cookie.getMaxAge()); | |||||
assertThat(Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), | assertThat(Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), | ||||
CoreMatchers | CoreMatchers | ||||
HttpCookie cookie = new HttpCookie("key2", "value2"); | HttpCookie cookie = new HttpCookie("key2", "value2"); | ||||
cookie.setMaxAge(1000); | cookie.setMaxAge(1000); | ||||
cookies.add(cookie); | cookies.add(cookie); | ||||
Date creationDate = new Date(); | |||||
try (Writer writer = Files.newBufferedWriter(tmpFile, | try (Writer writer = Files.newBufferedWriter(tmpFile, | ||||
StandardCharsets.US_ASCII)) { | StandardCharsets.US_ASCII)) { | ||||
NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); | |||||
NetscapeCookieFile.write(writer, cookies, baseUrl, TEST_DATE); | |||||
} | } | ||||
String expectedExpiration = String | String expectedExpiration = String | ||||
.valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); | |||||
.valueOf(TEST_DATE.getEpochSecond() + cookie.getMaxAge()); | |||||
assertThat(Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), | assertThat(Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), | ||||
CoreMatchers.equalTo( | CoreMatchers.equalTo( | ||||
} | } | ||||
} | } | ||||
@Test | |||||
public void testReadCookieFileWithMilliseconds() throws IOException { | |||||
try (InputStream input = this.getClass() | |||||
.getResourceAsStream("cookies-with-milliseconds.txt")) { | |||||
Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | |||||
} | |||||
NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile, | |||||
TEST_DATE); | |||||
long expectedMaxAge = Duration.between(TEST_DATE, TEST_EXPIRY_DATE) | |||||
.getSeconds(); | |||||
for (HttpCookie cookie : cookieFile.getCookies(true)) { | |||||
assertEquals(expectedMaxAge, cookie.getMaxAge()); | |||||
} | |||||
} | |||||
@Test | @Test | ||||
public void testWriteAfterAnotherJgitProcessModifiedTheFile() | public void testWriteAfterAnotherJgitProcessModifiedTheFile() | ||||
throws IOException, InterruptedException { | throws IOException, InterruptedException { | ||||
.getResourceAsStream("cookies-simple1.txt")) { | .getResourceAsStream("cookies-simple1.txt")) { | ||||
Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | ||||
} | } | ||||
NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile); | |||||
NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile, | |||||
TEST_DATE); | |||||
cookieFile.getCookies(true); | cookieFile.getCookies(true); | ||||
// now modify file externally | // now modify file externally | ||||
try (InputStream input = this.getClass() | try (InputStream input = this.getClass() | ||||
// now try to write | // now try to write | ||||
cookieFile.write(baseUrl); | cookieFile.write(baseUrl); | ||||
// validate that the external changes are there as well | |||||
// due to rounding errors (conversion from ms to sec to ms) | |||||
// the expiration date might not be exact | |||||
List<String> lines = Files.readAllLines(tmpFile, | List<String> lines = Files.readAllLines(tmpFile, | ||||
StandardCharsets.US_ASCII); | StandardCharsets.US_ASCII); | ||||
assertEquals("Expected 3 lines", 3, lines.size()); | assertEquals("Expected 3 lines", 3, lines.size()); | ||||
assertStringMatchesPatternWithInexactNumber(lines.get(0), | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey1\tvalueFromSimple2", | |||||
JAN_01_2030_NOON, 1000); | |||||
assertStringMatchesPatternWithInexactNumber(lines.get(1), | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey3\tvalueFromSimple2", | |||||
JAN_01_2030_NOON, 1000); | |||||
assertStringMatchesPatternWithInexactNumber(lines.get(2), | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey2\tvalueFromSimple1", | |||||
JAN_01_2030_NOON, 1000); | |||||
} | |||||
@SuppressWarnings("boxing") | |||||
private static final void assertStringMatchesPatternWithInexactNumber( | |||||
String string, String pattern, long expectedNumericValue, | |||||
long delta) { | |||||
java.util.regex.Matcher matcher = Pattern.compile(pattern) | |||||
.matcher(string); | |||||
assertTrue("Given string '" + string + "' does not match '" + pattern | |||||
+ "'", matcher.matches()); | |||||
// extract numeric value | |||||
Long actualNumericValue = Long.decode(matcher.group(1)); | |||||
assertTrue( | |||||
"Value is supposed to be close to " + expectedNumericValue | |||||
+ " but is " + actualNumericValue + ".", | |||||
Math.abs(expectedNumericValue - actualNumericValue) <= delta); | |||||
assertEquals( | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t1893499200\tkey1\tvalueFromSimple2", | |||||
lines.get(0)); | |||||
assertEquals( | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t1893499200\tkey3\tvalueFromSimple2", | |||||
lines.get(1)); | |||||
assertEquals( | |||||
"some-domain1\tTRUE\t/some/path1\tFALSE\t1893499200\tkey2\tvalueFromSimple1", | |||||
lines.get(2)); | |||||
} | } | ||||
@Test | @Test | ||||
cookie.setHttpOnly(true); | cookie.setHttpOnly(true); | ||||
cookies.add(cookie); | cookies.add(cookie); | ||||
Date creationDate = new Date(); | |||||
try (Writer writer = Files.newBufferedWriter(tmpFile, | try (Writer writer = Files.newBufferedWriter(tmpFile, | ||||
StandardCharsets.US_ASCII)) { | StandardCharsets.US_ASCII)) { | ||||
NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); | |||||
NetscapeCookieFile.write(writer, cookies, baseUrl, TEST_DATE); | |||||
} | } | ||||
Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, | Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, | ||||
creationDate).getCookies(true); | |||||
TEST_DATE) | |||||
.getCookies(true); | |||||
assertThat(actualCookies, HttpCookiesMatcher.containsInOrder(cookies)); | assertThat(actualCookies, HttpCookiesMatcher.containsInOrder(cookies)); | ||||
} | } | ||||
.getResourceAsStream("cookies-simple1.txt")) { | .getResourceAsStream("cookies-simple1.txt")) { | ||||
Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | ||||
} | } | ||||
// round up to the next second (to prevent rounding errors) | |||||
Date creationDate = new Date( | |||||
(System.currentTimeMillis() / 1000) * 1000); | |||||
Set<HttpCookie> cookies = new NetscapeCookieFile(tmpFile, creationDate) | |||||
Set<HttpCookie> cookies = new NetscapeCookieFile(tmpFile, TEST_DATE) | |||||
.getCookies(true); | .getCookies(true); | ||||
Path tmpFile2 = folder.newFile().toPath(); | Path tmpFile2 = folder.newFile().toPath(); | ||||
try (Writer writer = Files.newBufferedWriter(tmpFile2, | try (Writer writer = Files.newBufferedWriter(tmpFile2, | ||||
StandardCharsets.US_ASCII)) { | StandardCharsets.US_ASCII)) { | ||||
NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); | |||||
NetscapeCookieFile.write(writer, cookies, baseUrl, TEST_DATE); | |||||
} | } | ||||
// compare original file with newly written one, they should not differ | // compare original file with newly written one, they should not differ | ||||
assertEquals(Files.readAllLines(tmpFile), Files.readAllLines(tmpFile2)); | assertEquals(Files.readAllLines(tmpFile), Files.readAllLines(tmpFile2)); | ||||
Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | ||||
} | } | ||||
Date creationDate = new Date(); | |||||
Set<HttpCookie> cookies = new LinkedHashSet<>(); | Set<HttpCookie> cookies = new LinkedHashSet<>(); | ||||
HttpCookie cookie = new HttpCookie("key2", "value2"); | HttpCookie cookie = new HttpCookie("key2", "value2"); | ||||
cookie.setDomain("some-domain2"); | cookie.setDomain("some-domain2"); | ||||
cookie.setPath("/some/path2"); | cookie.setPath("/some/path2"); | ||||
cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); | |||||
cookie.setMaxAge( | |||||
Duration.between(TEST_DATE, TEST_EXPIRY_DATE).getSeconds()); | |||||
cookie.setSecure(true); | cookie.setSecure(true); | ||||
cookie.setHttpOnly(true); | cookie.setHttpOnly(true); | ||||
cookies.add(cookie); | cookies.add(cookie); | ||||
cookie = new HttpCookie("key3", "value3"); | cookie = new HttpCookie("key3", "value3"); | ||||
cookie.setDomain("some-domain3"); | cookie.setDomain("some-domain3"); | ||||
cookie.setPath("/some/path3"); | cookie.setPath("/some/path3"); | ||||
cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); | |||||
cookie.setMaxAge( | |||||
Duration.between(TEST_DATE, TEST_EXPIRY_DATE).getSeconds()); | |||||
cookies.add(cookie); | cookies.add(cookie); | ||||
Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, creationDate) | |||||
.getCookies(true); | |||||
Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, | |||||
TEST_DATE).getCookies(true); | |||||
assertThat(actualCookies, HttpCookiesMatcher.containsInOrder(cookies)); | assertThat(actualCookies, HttpCookiesMatcher.containsInOrder(cookies)); | ||||
} | } | ||||
Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); | ||||
} | } | ||||
new NetscapeCookieFile(tmpFile) | |||||
.getCookies(true); | |||||
assertTrue(new NetscapeCookieFile(tmpFile, TEST_DATE).getCookies(true) | |||||
.isEmpty()); | |||||
} | } | ||||
} | } |
import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||
import java.nio.file.Path; | import java.nio.file.Path; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
import java.time.Instant; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Date; | |||||
import java.util.LinkedHashSet; | import java.util.LinkedHashSet; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.concurrent.TimeUnit; | |||||
import org.eclipse.jgit.annotations.NonNull; | import org.eclipse.jgit.annotations.NonNull; | ||||
import org.eclipse.jgit.annotations.Nullable; | import org.eclipse.jgit.annotations.Nullable; | ||||
* In general this class is not thread-safe. So any consumer needs to take care | * In general this class is not thread-safe. So any consumer needs to take care | ||||
* of synchronization! | * of synchronization! | ||||
* | * | ||||
* @see <a href="https://curl.se/docs/http-cookies.html">Cookie file format</a> | |||||
* @see <a href="http://www.cookiecentral.com/faq/#3.5">Netscape Cookie File | * @see <a href="http://www.cookiecentral.com/faq/#3.5">Netscape Cookie File | ||||
* Format</a> | * Format</a> | ||||
* @see <a href= | * @see <a href= | ||||
private byte[] hash; | private byte[] hash; | ||||
final Date creationDate; | |||||
private final Instant createdAt; | |||||
private Set<HttpCookie> cookies = null; | private Set<HttpCookie> cookies = null; | ||||
* where to find the cookie file | * where to find the cookie file | ||||
*/ | */ | ||||
public NetscapeCookieFile(Path path) { | public NetscapeCookieFile(Path path) { | ||||
this(path, new Date()); | |||||
this(path, Instant.now()); | |||||
} | } | ||||
NetscapeCookieFile(Path path, Date creationDate) { | |||||
NetscapeCookieFile(Path path, Instant createdAt) { | |||||
this.path = path; | this.path = path; | ||||
this.snapshot = FileSnapshot.DIRTY; | this.snapshot = FileSnapshot.DIRTY; | ||||
this.creationDate = creationDate; | |||||
this.createdAt = createdAt; | |||||
} | } | ||||
/** | /** | ||||
if (cookies == null || refresh) { | if (cookies == null || refresh) { | ||||
try { | try { | ||||
byte[] in = getFileContentIfModified(); | byte[] in = getFileContentIfModified(); | ||||
Set<HttpCookie> newCookies = parseCookieFile(in, creationDate); | |||||
Set<HttpCookie> newCookies = parseCookieFile(in, createdAt); | |||||
if (cookies != null) { | if (cookies != null) { | ||||
cookies = mergeCookies(newCookies, cookies); | cookies = mergeCookies(newCookies, cookies); | ||||
} else { | } else { | ||||
* | * | ||||
* @param input | * @param input | ||||
* the file content to parse | * the file content to parse | ||||
* @param creationDate | |||||
* the date for the creation of the cookies (used to calculate | |||||
* the maxAge based on the expiration date given within the file) | |||||
* @param createdAt | |||||
* cookie creation time; used to calculate the maxAge based on | |||||
* the expiration date given within the file | |||||
* @return the set of parsed cookies from the given file (even expired | * @return the set of parsed cookies from the given file (even expired | ||||
* ones). If there is more than one cookie with the same name in | * ones). If there is more than one cookie with the same name in | ||||
* this file the last one overwrites the first one! | * this file the last one overwrites the first one! | ||||
* if the given file does not have a proper format | * if the given file does not have a proper format | ||||
*/ | */ | ||||
private static Set<HttpCookie> parseCookieFile(@NonNull byte[] input, | private static Set<HttpCookie> parseCookieFile(@NonNull byte[] input, | ||||
@NonNull Date creationDate) | |||||
@NonNull Instant createdAt) | |||||
throws IOException, IllegalArgumentException { | throws IOException, IllegalArgumentException { | ||||
String decoded = RawParseUtils.decode(StandardCharsets.US_ASCII, input); | String decoded = RawParseUtils.decode(StandardCharsets.US_ASCII, input); | ||||
new StringReader(decoded))) { | new StringReader(decoded))) { | ||||
String line; | String line; | ||||
while ((line = reader.readLine()) != null) { | while ((line = reader.readLine()) != null) { | ||||
HttpCookie cookie = parseLine(line, creationDate); | |||||
HttpCookie cookie = parseLine(line, createdAt); | |||||
if (cookie != null) { | if (cookie != null) { | ||||
cookies.add(cookie); | cookies.add(cookie); | ||||
} | } | ||||
} | } | ||||
private static HttpCookie parseLine(@NonNull String line, | private static HttpCookie parseLine(@NonNull String line, | ||||
@NonNull Date creationDate) { | |||||
@NonNull Instant createdAt) { | |||||
if (line.isEmpty() || (line.startsWith("#") //$NON-NLS-1$ | if (line.isEmpty() || (line.startsWith("#") //$NON-NLS-1$ | ||||
&& !line.startsWith(HTTP_ONLY_PREAMBLE))) { | && !line.startsWith(HTTP_ONLY_PREAMBLE))) { | ||||
return null; | return null; | ||||
cookie.setSecure(Boolean.parseBoolean(cookieLineParts[3])); | cookie.setSecure(Boolean.parseBoolean(cookieLineParts[3])); | ||||
long expires = Long.parseLong(cookieLineParts[4]); | long expires = Long.parseLong(cookieLineParts[4]); | ||||
long maxAge = (expires - creationDate.getTime()) / 1000; | |||||
// Older versions stored milliseconds. This heuristic to detect that | |||||
// will cause trouble in the year 33658. :-) | |||||
if (cookieLineParts[4].length() == 13) { | |||||
expires = TimeUnit.MILLISECONDS.toSeconds(expires); | |||||
} | |||||
long maxAge = expires - createdAt.getEpochSecond(); | |||||
if (maxAge <= 0) { | if (maxAge <= 0) { | ||||
return null; // skip expired cookies | return null; // skip expired cookies | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Read the underying file and return its content but only in case it has | |||||
* Read the underlying file and return its content but only in case it has | |||||
* been modified since the last access. | * been modified since the last access. | ||||
* <p> | * <p> | ||||
* Internally calculates the hash and maintains {@link FileSnapshot}s to | * Internally calculates the hash and maintains {@link FileSnapshot}s to | ||||
path); | path); | ||||
// reread new changes if necessary | // reread new changes if necessary | ||||
Set<HttpCookie> cookiesFromFile = NetscapeCookieFile | Set<HttpCookie> cookiesFromFile = NetscapeCookieFile | ||||
.parseCookieFile(cookieFileContent, creationDate); | |||||
.parseCookieFile(cookieFileContent, createdAt); | |||||
this.cookies = mergeCookies(cookiesFromFile, cookies); | this.cookies = mergeCookies(cookiesFromFile, cookies); | ||||
} | } | ||||
} catch (FileNotFoundException e) { | } catch (FileNotFoundException e) { | ||||
ByteArrayOutputStream output = new ByteArrayOutputStream(); | ByteArrayOutputStream output = new ByteArrayOutputStream(); | ||||
try (Writer writer = new OutputStreamWriter(output, | try (Writer writer = new OutputStreamWriter(output, | ||||
StandardCharsets.US_ASCII)) { | StandardCharsets.US_ASCII)) { | ||||
write(writer, cookies, url, creationDate); | |||||
write(writer, cookies, url, createdAt); | |||||
} | } | ||||
LockFile lockFile = new LockFile(path.toFile()); | LockFile lockFile = new LockFile(path.toFile()); | ||||
for (int retryCount = 0; retryCount < LOCK_ACQUIRE_MAX_RETRY_COUNT; retryCount++) { | for (int retryCount = 0; retryCount < LOCK_ACQUIRE_MAX_RETRY_COUNT; retryCount++) { | ||||
* @param url | * @param url | ||||
* the url for which to write the cookie (to derive the default | * the url for which to write the cookie (to derive the default | ||||
* values for certain cookie attributes) | * values for certain cookie attributes) | ||||
* @param creationDate | |||||
* the date when the cookie has been created. Important for | |||||
* calculation the cookie expiration time (calculated from | |||||
* cookie's maxAge and this creation time) | |||||
* @param createdAt | |||||
* cookie creation time; used to calculate a cookie's expiration | |||||
* time | |||||
* @throws IOException | * @throws IOException | ||||
* if an I/O error occurs | * if an I/O error occurs | ||||
*/ | */ | ||||
static void write(@NonNull Writer writer, | static void write(@NonNull Writer writer, | ||||
@NonNull Collection<HttpCookie> cookies, @NonNull URL url, | @NonNull Collection<HttpCookie> cookies, @NonNull URL url, | ||||
@NonNull Date creationDate) throws IOException { | |||||
@NonNull Instant createdAt) throws IOException { | |||||
for (HttpCookie cookie : cookies) { | for (HttpCookie cookie : cookies) { | ||||
writeCookie(writer, cookie, url, creationDate); | |||||
writeCookie(writer, cookie, url, createdAt); | |||||
} | } | ||||
} | } | ||||
private static void writeCookie(@NonNull Writer writer, | private static void writeCookie(@NonNull Writer writer, | ||||
@NonNull HttpCookie cookie, @NonNull URL url, | @NonNull HttpCookie cookie, @NonNull URL url, | ||||
@NonNull Date creationDate) throws IOException { | |||||
@NonNull Instant createdAt) throws IOException { | |||||
if (cookie.getMaxAge() <= 0) { | if (cookie.getMaxAge() <= 0) { | ||||
return; // skip expired cookies | return; // skip expired cookies | ||||
} | } | ||||
final String expirationDate; | final String expirationDate; | ||||
// whenCreated field is not accessible in HttpCookie | // whenCreated field is not accessible in HttpCookie | ||||
expirationDate = String | expirationDate = String | ||||
.valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); | |||||
.valueOf(createdAt.getEpochSecond() + cookie.getMaxAge()); | |||||
writer.write(expirationDate); | writer.write(expirationDate); | ||||
writer.write(COLUMN_SEPARATOR); | writer.write(COLUMN_SEPARATOR); | ||||
writer.write(cookie.getName()); | writer.write(cookie.getName()); |
<encoding>UTF-8</encoding> | <encoding>UTF-8</encoding> | ||||
<source>1.8</source> | <source>1.8</source> | ||||
<target>1.8</target> | <target>1.8</target> | ||||
<compilerArgs> | |||||
<arg>-XDcompilePolicy=simple</arg> | |||||
<arg>-Xplugin:ErrorProne</arg> | |||||
</compilerArgs> | |||||
<annotationProcessorPaths> | |||||
<path> | |||||
<groupId>com.google.errorprone</groupId> | |||||
<artifactId>error_prone_core</artifactId> | |||||
<version>2.4.0</version> | |||||
</path> | |||||
</annotationProcessorPaths> | |||||
</configuration> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</profile> | |||||
<profile> | |||||
<id>jdk8</id> | |||||
<activation> | |||||
<jdk>1.8</jdk> | |||||
</activation> | |||||
<properties> | |||||
<javac.version>9+181-r4173-1</javac.version> | |||||
</properties> | |||||
<build> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.apache.maven.plugins</groupId> | |||||
<artifactId>maven-compiler-plugin</artifactId> | |||||
<configuration> | |||||
<fork>true</fork> | |||||
<compilerArgs combine.children="append"> | |||||
<arg>-J-Xbootclasspath/p:${settings.localRepository}/com/google/errorprone/javac/${javac.version}/javac-${javac.version}.jar</arg> | |||||
</compilerArgs> | |||||
</configuration> | </configuration> | ||||
<executions> | |||||
<execution> | |||||
<id>default-compile</id> | |||||
<phase>compile</phase> | |||||
<goals> | |||||
<goal>compile</goal> | |||||
</goals> | |||||
<configuration> | |||||
<includes> | |||||
<include>org/eclipse/jgit/transport/InsecureCipherFactory.java</include> | |||||
</includes> | |||||
</configuration> | |||||
</execution> | |||||
<execution> | |||||
<id>compile-with-errorprone</id> | |||||
<phase>compile</phase> | |||||
<goals> | |||||
<goal>compile</goal> | |||||
</goals> | |||||
<configuration> | |||||
<compilerId>javac-with-errorprone</compilerId> | |||||
<forceJavacCompilerUse>true</forceJavacCompilerUse> | |||||
<excludes> | |||||
<exclude>org/eclipse/jgit/transport/InsecureCipherFactory.java</exclude> | |||||
</excludes> | |||||
</configuration> | |||||
</execution> | |||||
</executions> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.codehaus.plexus</groupId> | |||||
<artifactId>plexus-compiler-javac</artifactId> | |||||
<version>${plexus-compiler-version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.codehaus.plexus</groupId> | |||||
<artifactId>plexus-compiler-javac-errorprone</artifactId> | |||||
<version>${plexus-compiler-version}</version> | |||||
</dependency> | |||||
<!-- override plexus-compiler-javac-errorprone's dependency on | |||||
Error Prone with the latest version --> | |||||
<dependency> | |||||
<groupId>com.google.errorprone</groupId> | |||||
<artifactId>error_prone_core</artifactId> | |||||
<version>2.3.4</version> | |||||
</dependency> | |||||
</dependencies> | |||||
</plugin> | </plugin> | ||||
</plugins> | </plugins> | ||||
</build> | </build> |