StandardApiVersionDeprecationHandler generates nonconforming Sunset HTTP dates
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
- #37493 @SwatiKumari250 による — マージされずにクローズ
評価
調査の方向性
spring-web/src/main/java/org/springframework/web/accept/StandardApiVersionDeprecationHandler.java から始めてください。ここでは VersionInfo.withSunsetDate が DateTimeFormatter.RFC_1123_DATE_TIME を使って ZonedDateTime を整形しています。すでに二桁の日付で GMT を出力している HttpHeaders.setZonedDateTime と比較してください。既存の非推奨ハンドラーのテストの横に、GMT 以外のタイムゾーンで一桁の日を設定するテストを追加してください。Sunset ヘッダーが、Sun, 01 Nov 2026 03:11:11 GMT のように GMT で時刻を表示すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
Passing a non-GMT ZonedDateTime to VersionSpec.setSunsetDate() generates a Sunset header with a numeric timezone offset instead of GMT. Single-digit month days are also rendered without the two-digit IMF-fixdate day.
The class advertises RFC 8594 support. RFC 8594 section 3 specifies HTTP-date for the Sunset value; RFC 9110 section 5.6.7 requires senders to generate IMF-fixdate (GMT and a two-digit day). This is a header formatting issue, not a claim of a security vulnerability.
Versions and verification scope
Reproduced using official Spring Framework 7.0.9 Maven artifacts on Windows 11 / OpenJDK 21 / Maven 3.6.3. The same regressions were also executed against eleven relevant, byte-for-byte unmodified source files from main (7.1.0-SNAPSHOT), commit 4dea36c5872b3ad9ac9357a9cd8a077264f88a39, with 7.0.9 supporting dependencies.
The released-artifact project has no copied implementation sources. The current-source project compiles the original classes under review. These are isolated public-API regressions; no full upstream Gradle build, NullAway/checkstyle run, server deployment, or production validation is claimed.
Minimal reproduction
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.accept.ApiVersionParser;
import org.springframework.web.accept.StandardApiVersionDeprecationHandler;
import static org.assertj.core.api.Assertions.assertThat;
class SunsetHttpDateTests {
@Test
void sunsetMustUseGmtAndTwoDigitDay() {
ApiVersionParser<String> parser = version -> version;
StandardApiVersionDeprecationHandler handler =
new StandardApiVersionDeprecationHandler(parser);
handler.configureVersion("1").setSunsetDate(
ZonedDateTime.of(2026, 11, 1, 11, 11, 11, 0,
ZoneId.of("Asia/Shanghai")));
MockHttpServletResponse response = new MockHttpServletResponse();
handler.handleVersion("1", new Object(),
new MockHttpServletRequest(), response);
assertThat(response.getHeader("Sunset"))
.isEqualTo("Sun, 01 Nov 2026 03:11:11 GMT");
}
}
Expected and actual results
Expected, preserving the instant:
Sun, 01 Nov 2026 03:11:11 GMT
Actual:
Sun, 1 Nov 2026 11:11:11 +0800
The actual handler writes this value to the servlet response; this is not merely a standalone formatter comparison. A GMT date with a two-digit day (November 11) passes, matching the existing upstream test's shape. HTTP client compatibility was not measured.
Root-cause observation
VersionInfo.withSunsetDate uses DateTimeFormatter.RFC_1123_DATE_TIME on the supplied ZonedDateTime without normalizing the instant to GMT. That general formatter also permits a one-digit day.
Spring's existing HttpHeaders.setZonedDateTime() HTTP-date formatting preserves the instant and emits the expected GMT/two-digit form. An isolated candidate reusing this formatter passes both the regression and the original-shape GMT control; the upstream clone remains unchanged.
Related work and references
Searched existing issues/PRs for StandardApiVersionDeprecationHandler, Sunset/GMT, and Sunset timezone formatting; no matching report was found in those results.
- 主要言語
- Java
- スター
- 60.3k
- フォーク
- 38.7k
- 平均マージ
- 1日 9時間
- マージ済み PR(30日)
- 34
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
spring-projects/spring-framework のほかの issue
-
`YamlProcessor.getFlattenedMap` with `includeEmpty` returns a `null` key for an empty root mapping再び着手できるかも @erfannvb が 8 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンstatus: waiting-for-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
spring-projects/spring-framework#37522 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
`WebClient` with default codecs drops `ProblemDetail` extension members再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンstatus: waiting-for-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
spring-projects/spring-framework#37503 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
FastByteArrayOutputStream input stream rejects valid skip(long) arguments再び着手できるかも @hickey-ai が 11 日前に担当しましたが、オープン中のプルリクエストはありません。 オープンstatus: waiting-for-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
spring-projects/spring-framework#37471 · コメント 6 件 ·
メンテナーはふだん 1 日以内に返信
-
LinkedCaseInsensitiveMap.keySet().remove returns false after removing a null-valued entry再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンstatus: waiting-for-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
spring-projects/spring-framework#37470 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
ServerSentEventHttpMessageReader does not recognize data fields without a colon再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンin: web status: waiting-for-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
spring-projects/spring-framework#37461 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
spring-projects/spring-framework の issue をすべて見る
似ている issue
-
bug web-server
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
jooby-project/jooby#4035 ·
メンテナーはふだん 1 日以内に返信
-
L: javascript
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
dependabot/dependabot-core#16744 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
quarkiverse/quarkus-google-cloud-services#1187 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
locationtech/jts#1250 ·
-
type/improve
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100