mirror of
https://github.com/containers/skopeo.git
synced 2026-02-02 15:29:34 +00:00
Apply Last-Modified time as mtime when saving URLs
When saving the contents of a URL to a local file, attempt to set mtime based on the response's Last-Modified header, if there is one. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com> Closes: #58 Approved by: nalind
This commit is contained in:
committed by
Atomic Bot
parent
c72d2db65d
commit
19a7165783
@@ -11,4 +11,4 @@ before_install:
|
||||
- sudo apt-get -qq install bats btrfs-tools libdevmapper-dev libgpgme11-dev
|
||||
script:
|
||||
- make
|
||||
- cd tests; sudo ./test_runner.sh
|
||||
- cd tests; sudo PATH="$PATH" ./test_runner.sh
|
||||
|
||||
14
add.go
14
add.go
@@ -9,6 +9,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
@@ -29,12 +30,23 @@ func addUrl(destination, srcurl string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating %q: %v", destination, err)
|
||||
}
|
||||
if last := resp.Header.Get("Last-Modified"); last != "" {
|
||||
if mtime, err := time.Parse(time.RFC1123, last); err != nil {
|
||||
logrus.Debugf("error parsing Last-Modified time %q: %v", last, err)
|
||||
} else {
|
||||
defer func() {
|
||||
if err := os.Chtimes(destination, time.Now(), mtime); err != nil {
|
||||
logrus.Debugf("error setting mtime to Last-Modified time %q: %v", last, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
defer f.Close()
|
||||
n, err := io.Copy(f, resp.Body)
|
||||
if resp.ContentLength >= 0 && n != resp.ContentLength {
|
||||
return fmt.Errorf("error reading contents for %q: wrong length (%d != %d)", destination, n, resp.ContentLength)
|
||||
}
|
||||
if err := f.Chmod(0755); err != nil {
|
||||
if err := f.Chmod(0600); err != nil {
|
||||
return fmt.Errorf("error setting permissions on %q: %v", destination, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -86,3 +86,21 @@ load helpers
|
||||
cmp ${TESTDIR}/randomfile $root/randomsubdir/randomfile
|
||||
buildah rm $cid
|
||||
}
|
||||
|
||||
@test "copy-url-mtime" {
|
||||
createrandom ${TESTDIR}/randomfile
|
||||
|
||||
cid=$(buildah from --signature-policy ${TESTSDIR}/policy.json scratch)
|
||||
buildah config --workingdir / $cid
|
||||
starthttpd ${TESTDIR}
|
||||
buildah copy $cid http://0.0.0.0:${HTTP_SERVER_PORT}/randomfile /urlfile
|
||||
stophttpd
|
||||
root=$(buildah mount $cid)
|
||||
test -s $root/urlfile
|
||||
cmp ${TESTDIR}/randomfile $root/urlfile
|
||||
run test -nt ${TESTDIR}/randomfile $root/urlfile
|
||||
[ "$status" -ne 0 ]
|
||||
run test -ot ${TESTDIR}/randomfile $root/urlfile
|
||||
[ "$status" -ne 0 ]
|
||||
buildah rm $cid
|
||||
}
|
||||
|
||||
@@ -11,7 +11,27 @@ function setup() {
|
||||
REPO=${TESTDIR}/root
|
||||
}
|
||||
|
||||
function starthttpd() {
|
||||
pushd ${2:-${BATS_TMPDIR}} > /dev/null
|
||||
cp ${TESTSDIR}/serve.go .
|
||||
go build serve.go
|
||||
HTTP_SERVER_PORT=$((RANDOM+32768))
|
||||
./serve ${HTTP_SERVER_PORT} ${1:-${BATS_TMPDIR}} &
|
||||
HTTP_SERVER_PID=$!
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function stophttpd() {
|
||||
if test -n "$HTTP_SERVER_PID" ; then
|
||||
kill -HUP ${HTTP_SERVER_PID}
|
||||
unset HTTP_SERVER_PID
|
||||
unset HTTP_SERVER_PORT
|
||||
fi
|
||||
true
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
stophttpd
|
||||
rm -fr ${TESTDIR}
|
||||
}
|
||||
|
||||
|
||||
40
tests/serve.go
Normal file
40
tests/serve.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func sendThatFile(basepath string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
filename := filepath.Join(basepath, filepath.Clean(string([]rune{filepath.Separator})+r.URL.Path))
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
http.Error(w, "whoops", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
finfo, err := f.Stat()
|
||||
if err != nil {
|
||||
http.Error(w, "whoops", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.ServeContent(w, r, filename, finfo.ModTime(), f)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
args := os.Args
|
||||
if len(args) < 3 {
|
||||
log.Fatal("requires listening port and subdirectory path")
|
||||
}
|
||||
port := args[1]
|
||||
basedir := args[2]
|
||||
http.HandleFunc("/", sendThatFile(basedir))
|
||||
log.Fatal(http.ListenAndServe(":"+port, nil))
|
||||
}
|
||||
Reference in New Issue
Block a user