Skip to content

Commit 2e7dca9

Browse files
authored
Merge pull request #2657 from adobe/4.10.0-maintenance
4.10.0
2 parents bee04bf + 6b7fc78 commit 2e7dca9

File tree

5 files changed

+84
-15
lines changed

5 files changed

+84
-15
lines changed

CHANGELOG.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Whenever a 3rd party library is updated, S3Mock will update it's MINOR version.
99
* [Planned changes](#planned-changes)
1010
* [CURRENT - 4.x - THIS VERSION IS UNDER ACTIVE DEVELOPMENT](#current---4x---this-version-is-under-active-development)
1111
* [4.11.0 - PLANNED](#4110---planned)
12-
* [4.10.0 - PLANNED](#4100---planned)
12+
* [4.10.0](#4100)
1313
* [4.9.1](#491)
1414
* [4.9.0](#490)
1515
* [4.8.0](#480)
@@ -155,7 +155,7 @@ Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Jav
155155
## 4.11.0 - PLANNED
156156
Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Java integration.
157157

158-
**This is the last currently planned minor release of 4.x.**
158+
**This is currently the last planned minor release of 4.x.**
159159

160160
* Features and fixes
161161
* TBD
@@ -164,23 +164,42 @@ Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Jav
164164
* Version updates (deliverable dependencies)
165165
* Update to Spring Boot 3.5.8
166166
* Planned release November 20th 2025
167-
* TBD: link to milestone
167+
* https://github.com/spring-projects/spring-boot/milestone/401
168168
* Version updates (build dependencies)
169169
* TBD
170170

171-
## 4.10.0 - PLANNED
171+
## 4.10.0
172172
Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Java integration.
173173

174174
* Features and fixes
175-
* TBD
175+
* Return correct error body on invalid ranges (fixes #2732)
176+
* Accept unquoted etags in if-match/if-none-match headers (fixes #2665)
176177
* Refactorings
177-
* TBD
178+
* Drop commons-lang3 dependency and replace its usages with core Java (fixes #2735)
178179
* Version updates (deliverable dependencies)
179-
* Update to Spring Boot 3.5.7
180-
* Planned release October 23rd 2025
181-
* https://github.com/spring-projects/spring-boot/milestone/399
180+
* Bump spring-boot.version from 3.5.6 to 3.5.7
181+
* Bump aws-v2.version from 2.33.12 to 2.37.2
182+
* Bump aws.version from 1.12.791 to 1.12.793
183+
* Bump alpine from 3.22.1 to 3.22.2 in /docker
184+
* Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0
182185
* Version updates (build dependencies)
183-
* TBD
186+
* Bump kotlin.version from 2.2.20 to 2.2.21
187+
* Bump aws.sdk.kotlin:s3-jvm from 1.5.41 to 1.5.73
188+
* Bump digital.pragmatech.testing:spring-test-profiler from 0.0.12 to 0.0.13
189+
* Bump org.mockito.kotlin:mockito-kotlin from 6.0.0 to 6.1.0
190+
* Bump org.xmlunit:xmlunit-assertj3 from 2.10.4 to 2.11.0
191+
* Bump org.codehaus.mojo:exec-maven-plugin from 3.5.1 to 3.6.2
192+
* Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0
193+
* Bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1
194+
* Bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0
195+
* Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2
196+
* Bump com.puppycrawl.tools:checkstyle from 11.0.1 to 12.1.1
197+
* Bump org.jacoco:jacoco-maven-plugin from 0.8.13 to 0.8.14
198+
* Bump github/codeql-action from 3.30.3 to 4.31.2
199+
* Bump actions/dependency-review-action from 4.7.3 to 4.8.1
200+
* Bump ossf/scorecard-action from 2.4.2 to 2.4.3
201+
* Bump actions/stale from 10.0.0 to 10.1.0
202+
* Bump actions/upload-artifact from 4.6.2 to 5.0.0
184203

185204
## 4.9.1
186205
Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Java integration.

integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/GetPutDeleteObjectIT.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,23 @@ internal class GetPutDeleteObjectIT : S3TestBase() {
13361336
}
13371337
}
13381338

1339+
@Test
1340+
@S3VerifiedTodo
1341+
fun `GET object succeeds with unquoted if-match=true`(testInfo: TestInfo) {
1342+
val (bucketName, putObjectResponse) = givenBucketAndObject(testInfo, UPLOAD_FILE_NAME)
1343+
val matchingEtag = putObjectResponse.eTag()
1344+
val unquotedEtag = matchingEtag.substring(1, matchingEtag.length - 1)
1345+
s3Client
1346+
.getObject {
1347+
it.bucket(bucketName)
1348+
it.key(UPLOAD_FILE_NAME)
1349+
it.ifMatch(unquotedEtag)
1350+
}.use {
1351+
assertThat(it.response().eTag()).isEqualTo(matchingEtag)
1352+
assertThat(it.response().contentLength()).isEqualTo(UPLOAD_FILE_LENGTH)
1353+
}
1354+
}
1355+
13391356
@Test
13401357
@S3VerifiedSuccess(year = 2025)
13411358
fun `GET object succeeds with if-match=true and if-unmodified-since=false`(testInfo: TestInfo) {
@@ -1407,6 +1424,23 @@ internal class GetPutDeleteObjectIT : S3TestBase() {
14071424
.hasMessageContaining("Service: S3, Status Code: 304")
14081425
}
14091426

1427+
@Test
1428+
@S3VerifiedTodo
1429+
fun `GET object fails with unquoted if-none-match=false`(testInfo: TestInfo) {
1430+
val (bucketName, putObjectResponse) = givenBucketAndObject(testInfo, UPLOAD_FILE_NAME)
1431+
val matchingEtag = putObjectResponse.eTag()
1432+
val unquotedEtag = matchingEtag.substring(1, matchingEtag.length - 1)
1433+
1434+
assertThatThrownBy {
1435+
s3Client.getObject {
1436+
it.bucket(bucketName)
1437+
it.key(UPLOAD_FILE_NAME)
1438+
it.ifNoneMatch(unquotedEtag)
1439+
}
1440+
}.isInstanceOf(S3Exception::class.java)
1441+
.hasMessageContaining("Service: S3, Status Code: 304")
1442+
}
1443+
14101444
@Test
14111445
@S3VerifiedSuccess(year = 2025)
14121446
fun `GET object succeeds with if-modified-since=true`(testInfo: TestInfo) {

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
<kotlin.compiler.languageVersion>2.2</kotlin.compiler.languageVersion>
8484
<kotlin-coroutines.version>1.10.2</kotlin-coroutines.version>
8585

86-
<aws-v2.version>2.33.12</aws-v2.version>
86+
<aws-v2.version>2.37.2</aws-v2.version>
8787

8888
<aws.version>1.12.793</aws.version>
8989

server/src/main/java/com/adobe/testing/s3mock/service/ObjectService.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,16 @@ public void verifyObjectMatching(
368368

369369
var setMatch = match != null && !match.isEmpty();
370370
if (setMatch) {
371-
if (match.contains(WILDCARD_ETAG) || match.contains(WILDCARD) || match.contains(etag)) {
371+
var unquotedEtag = etag.replace("\"", "");
372+
if (match.contains(WILDCARD_ETAG)
373+
|| match.contains(WILDCARD)
374+
|| match.contains(etag)
375+
|| match.contains(unquotedEtag)
376+
) {
372377
// request cares only that the object exists or that the etag matches.
373378
LOG.debug("Object {} exists", s3ObjectMetadata.key());
374379
return;
375-
} else if (!match.contains(etag)) {
380+
} else if (!match.contains(unquotedEtag) && !match.contains(etag)) {
376381
LOG.debug("Object {} does not match etag {}", s3ObjectMetadata.key(), etag);
377382
throw PRECONDITION_FAILED;
378383
}
@@ -388,7 +393,12 @@ public void verifyObjectMatching(
388393

389394
var setNoneMatch = noneMatch != null && !noneMatch.isEmpty();
390395
if (setNoneMatch) {
391-
if (noneMatch.contains(WILDCARD_ETAG) || noneMatch.contains(WILDCARD) || noneMatch.contains(etag)) {
396+
var unquotedEtag = etag.replace("\"", "");
397+
if (noneMatch.contains(WILDCARD_ETAG)
398+
|| noneMatch.contains(WILDCARD)
399+
|| noneMatch.contains(etag)
400+
|| noneMatch.contains(unquotedEtag)
401+
) {
392402
// request cares only that the object etag does not match.
393403
LOG.debug("Object {} has an ETag {} that matches one of the 'noneMatch' values", s3ObjectMetadata.key(), etag);
394404
throw NOT_MODIFIED;

server/src/test/kotlin/com/adobe/testing/s3mock/ChecksumTestUtil.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import software.amazon.awssdk.http.auth.aws.internal.signer.chunkedencoding.Trai
2828
import software.amazon.awssdk.http.auth.aws.internal.signer.io.ChecksumInputStream
2929
import software.amazon.awssdk.http.auth.aws.internal.signer.util.ChecksumUtil
3030
import software.amazon.awssdk.http.auth.aws.internal.signer.util.SignerUtils
31+
import software.amazon.awssdk.http.auth.spi.signer.PayloadChecksumStore
3132
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity
3233
import java.io.File
3334
import java.io.InputStream
@@ -85,7 +86,12 @@ object ChecksumTestUtil {
8586
mutableSetOf(sdkChecksum)
8687
)
8788

88-
val checksumTrailer: TrailerProvider = ChecksumTrailerProvider(sdkChecksum, checksumHeaderName)
89+
val checksumTrailer: TrailerProvider = ChecksumTrailerProvider(
90+
sdkChecksum,
91+
checksumHeaderName,
92+
checksumAlgorithm,
93+
PayloadChecksumStore.create()
94+
)
8995

9096
builder.inputStream(checksumInputStream).addTrailer(checksumTrailer)
9197
}

0 commit comments

Comments
 (0)