first commit
This commit is contained in:
97
httpdl/conditional_test.go
Normal file
97
httpdl/conditional_test.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package httpdl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hanbok/got/download"
|
||||
)
|
||||
|
||||
// TestConditionalGet304 checks that --conditional-get sends If-Modified-Since
|
||||
// for an existing local file and treats a 304 as success without rewriting the
|
||||
// file.
|
||||
func TestConditionalGet304(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
out := filepath.Join(dir, "file.bin")
|
||||
const existing = "already here"
|
||||
if err := os.WriteFile(out, []byte(existing), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gotIfModSince := false
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("If-Modified-Since") != "" {
|
||||
gotIfModSince = true
|
||||
}
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
d := New([]string{srv.URL + "/file.bin"}, Config{
|
||||
Dir: dir,
|
||||
Out: "file.bin",
|
||||
MaxConnPerServer: 1,
|
||||
ConditionalGet: true,
|
||||
AllowOverwrite: true,
|
||||
UserAgent: "got-test",
|
||||
})
|
||||
if err := d.Run(context.Background()); err != nil {
|
||||
t.Fatalf("conditional-get 304 should succeed, got %v", err)
|
||||
}
|
||||
if !gotIfModSince {
|
||||
t.Fatal("expected an If-Modified-Since header on the request")
|
||||
}
|
||||
if d.Stat().Status != download.Complete {
|
||||
t.Fatalf("status = %v, want Complete", d.Stat().Status)
|
||||
}
|
||||
// The file must be untouched: 304 means "up to date".
|
||||
b, err := os.ReadFile(out)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(b) != existing {
|
||||
t.Fatalf("file was rewritten: %q, want %q", b, existing)
|
||||
}
|
||||
}
|
||||
|
||||
// TestConditionalGetSkippedWithControlFile verifies the rule that
|
||||
// --conditional-get is ignored when a .got control file exists, so an
|
||||
// in-progress resume is never short-circuited by a 304.
|
||||
func TestConditionalGetSkippedWithControlFile(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
out := filepath.Join(dir, "file.bin")
|
||||
if err := os.WriteFile(out, []byte("partial"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// A control file present means a resume is in flight.
|
||||
if err := os.WriteFile(controlPath(out), []byte("{}"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sawIfModSince := false
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("If-Modified-Since") != "" {
|
||||
sawIfModSince = true
|
||||
}
|
||||
// Serve a small body so the run can complete.
|
||||
http.Error(w, "no range", http.StatusOK)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
d := New([]string{srv.URL + "/file.bin"}, Config{
|
||||
Dir: dir,
|
||||
Out: "file.bin",
|
||||
MaxConnPerServer: 1,
|
||||
ConditionalGet: true,
|
||||
AllowOverwrite: true,
|
||||
UserAgent: "got-test",
|
||||
})
|
||||
_ = d.Run(context.Background())
|
||||
if sawIfModSince {
|
||||
t.Fatal("If-Modified-Since must not be sent when a control file exists")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user