Skip to content

[JENKINS-72469] Tool downloads repeatedly if HTTP server does not send last-modified HTTP header #18838

Description

@jenkins-infra-bot

Users reported in community.jenkins.io that they were seeing repeated downloads of the Azul JDK.

The content delivery network of Azul Systems (provider of JDK implementations) stopped providing the last-modified header recently. The Jenkins FilePath implementation depends on the HTTP last-modified header even though the MDN description says that it is less accurate that the ETag header.

The Groovy console code that I used to confirm the behavior of the FilePath.installIfNecessaryFrom method is:

URL archive = new URL("https://cdn.azul.com/zulu/bin/zulu17.46.19-ca-fx-jdk17.0.9-linux_x64.tar.gz")
println("URL of archive is " + archive)
TaskListener listener = TaskListener.NULL
File jdk17Dir = new File("/tmp/jdk17.0.9")
println("Java 17 dir is " + jdk17Dir + " and " + (jdk17Dir.exists() ? "exists" : "does not exist"))
File timestamp = new File("/tmp/jdk17.0.9/.timestamp")
if (timestamp.exists()) {
	println("Timestamp file " + timestamp + " exists and has a last modified date of " + timestamp.lastModified())
} else {
	println("Timestamp file " + timestamp + " does not exist")
}
FilePath jdk17FilePath = new FilePath(jdk17Dir)
println("Java 17 FilePath is " + jdk17FilePath + " and " + (jdk17FilePath.exists() ? "exists" : "does not exist"))
boolean result = jdk17FilePath.installIfNecessaryFrom(archive, listener, "Installing JDK 17 into " + jdk17Dir)
println("Result of installIfNecessaryFrom is " + result)

When that code is run the first time, it downloads JDK 17.0.9 from the Azul Systems CDN. When that code is run the second time, it report that the timestamp of the file is 0 (the epoch) and downloads JDK 17.0.9 again.

The FilePath implementation should be extended to support the ETag header, since that is considered more accurate than the last-modified header.


Originally reported by markewaite, imported from: Tool downloads repeatedly if HTTP server does not send last-modified HTTP header
  • assignee: markewaite
  • status: Closed
  • priority: Minor
  • component(s): core
  • label(s): 2.426.3-fixed
  • resolution: Fixed
  • resolved: 2024-01-02T03:12:26+00:00
  • votes: 0
  • watchers: 1
  • imported: 2025-11-24
Raw content of original issue

Users reported in community.jenkins.io that they were seeing repeated downloads of the Azul JDK.

The content delivery network of Azul Systems (provider of JDK implementations) stopped providing the last-modified header recently. The Jenkins FilePath implementation depends on the HTTP last-modified header even though the MDN description says that it is less accurate that the ETag header.

The Groovy console code that I used to confirm the behavior of the FilePath.installIfNecessaryFrom method is:

URL archive = new URL("https://cdn.azul.com/zulu/bin/zulu17.46.19-ca-fx-jdk17.0.9-linux_x64.tar.gz")
println("URL of archive is " + archive)
TaskListener listener = TaskListener.NULL
File jdk17Dir = new File("/tmp/jdk17.0.9")
println("Java 17 dir is " + jdk17Dir + " and " + (jdk17Dir.exists() ? "exists" : "does not exist"))
File timestamp = new File("/tmp/jdk17.0.9/.timestamp")
if (timestamp.exists()) {
	println("Timestamp file " + timestamp + " exists and has a last modified date of " + timestamp.lastModified())
} else {
	println("Timestamp file " + timestamp + " does not exist")
}
FilePath jdk17FilePath = new FilePath(jdk17Dir)
println("Java 17 FilePath is " + jdk17FilePath + " and " + (jdk17FilePath.exists() ? "exists" : "does not exist"))
boolean result = jdk17FilePath.installIfNecessaryFrom(archive, listener, "Installing JDK 17 into " + jdk17Dir)
println("Result of installIfNecessaryFrom is " + result)

When that code is run the first time, it downloads JDK 17.0.9 from the Azul Systems CDN. When that code is run the second time, it report that the timestamp of the file is 0 (the epoch) and downloads JDK 17.0.9 again.

The FilePath implementation should be extended to support the ETag header, since that is considered more accurate than the last-modified header.

  • environment: Jenkins 2.426.2 and Jenkins 2.438 (and much, much older)

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions