Skip to content

Commit da60d33

Browse files
committed
Bump ioswmr and fix tee for hf
1 parent f40cfa3 commit da60d33

5 files changed

Lines changed: 61 additions & 58 deletions

File tree

cache.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ func (m *MirrorHandler) cacheResponse(w http.ResponseWriter, r *http.Request) {
234234
}
235235
}
236236

237-
defer tee.Close()
238237
tee.ServeHTTP(w, r)
239238
return
240239
}
@@ -278,7 +277,7 @@ func (m *MirrorHandler) cacheFile(ctx context.Context, sourceFile, cacheFile str
278277
}
279278

280279
func (m *MirrorHandler) cacheFileDirect(ctx context.Context, sourceFile, cacheFile string) error {
281-
resp, info, err := httpGet(ctx, m.client(), sourceFile)
280+
resp, info, err := httpGet(ctx, m.client(), sourceFile, false)
282281
if err != nil {
283282
return err
284283
}

fetch.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func httpHead(ctx context.Context, client *http.Client, p string) (fs.FileInfo,
4040
//
4141
// The caller is responsible for closing the returned io.ReadCloser.
4242
// Returns ErrNotOK if the response status is not 200 OK.
43-
func httpGet(ctx context.Context, client *http.Client, p string) (io.ReadCloser, *fileInfo, error) {
43+
func httpGet(ctx context.Context, client *http.Client, p string, teeHf bool) (io.ReadCloser, *fileInfo, error) {
4444
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p, nil)
4545
if err != nil {
4646
return nil, nil, err
@@ -56,7 +56,22 @@ func httpGet(ctx context.Context, client *http.Client, p string) (io.ReadCloser,
5656
return nil, nil, fmt.Errorf("%w: http status %d", ErrNotOK, resp.StatusCode)
5757
}
5858

59-
return resp.Body, &fileInfo{
59+
body := resp.Body
60+
// huggingface HEAD and GET headers may differ, so we perform a HEAD request to get accurate metadata for caching decisions.
61+
if teeHf && resp.ContentLength <= 0 {
62+
if _, ok := hfHosts[req.URL.Host]; ok {
63+
reqHead, err := http.NewRequestWithContext(ctx, http.MethodHead, p, nil)
64+
if err != nil {
65+
return nil, nil, err
66+
}
67+
resp, err = client.Do(reqHead)
68+
if err != nil {
69+
return nil, nil, err
70+
}
71+
}
72+
}
73+
74+
return body, &fileInfo{
6075
name: p,
6176
resp: resp,
6277
}, nil

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/OpenCIDN/cidn v0.0.108
77
github.com/spf13/pflag v1.0.10
88
github.com/wzshiming/httpseek v0.5.0
9-
github.com/wzshiming/ioswmr v0.0.0-20260228060639-c732d91a1feb
9+
github.com/wzshiming/ioswmr v0.0.0-20260302055634-59c8070e7d03
1010
github.com/wzshiming/sss v0.7.0
1111
golang.org/x/sync v0.19.0
1212
k8s.io/apimachinery v0.34.1

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ github.com/wzshiming/httpseek v0.5.0 h1:9pFLlTcebylAtLA4ni0Qo5xwXTgeQOo0iVQA3G1Q
8989
github.com/wzshiming/httpseek v0.5.0/go.mod h1:YoZhlLIwNjTBDXIT8NpK5zRjOgZouRXPaBfjVXdqMMs=
9090
github.com/wzshiming/ioswmr v0.0.0-20260228060639-c732d91a1feb h1:XvBxo2V5vkklUAdpC9IhTck8N8EAgrRfRhOwDsXaLcM=
9191
github.com/wzshiming/ioswmr v0.0.0-20260228060639-c732d91a1feb/go.mod h1:TwwDyS1wnJG3AvKliA+PPB0kliN3yEjsabtH4o7xySQ=
92+
github.com/wzshiming/ioswmr v0.0.0-20260302052319-c9316c655ea7 h1:9TstNh3ONYZgvJofkcb4IW5h47k1QqKQ2jZisw9S2n0=
93+
github.com/wzshiming/ioswmr v0.0.0-20260302052319-c9316c655ea7/go.mod h1:TwwDyS1wnJG3AvKliA+PPB0kliN3yEjsabtH4o7xySQ=
94+
github.com/wzshiming/ioswmr v0.0.0-20260302053347-fc8ba863812e h1:LvTADj966y6pJ8A42Yxxog8BtoMZlxgCdtK2rGHGWBI=
95+
github.com/wzshiming/ioswmr v0.0.0-20260302053347-fc8ba863812e/go.mod h1:TwwDyS1wnJG3AvKliA+PPB0kliN3yEjsabtH4o7xySQ=
96+
github.com/wzshiming/ioswmr v0.0.0-20260302055634-59c8070e7d03 h1:rOFrtfMWksCMFwE8IhbCAxkPeBGLy4mOtxrBlhrNhhI=
97+
github.com/wzshiming/ioswmr v0.0.0-20260302055634-59c8070e7d03/go.mod h1:TwwDyS1wnJG3AvKliA+PPB0kliN3yEjsabtH4o7xySQ=
9298
github.com/wzshiming/sss v0.7.0 h1:YNGJMJ+LBv9dhEUoWTRRl35tru8V2FoW816AR8fZtLg=
9399
github.com/wzshiming/sss v0.7.0/go.mod h1:4FNGdjjLOzcmZtcCOW+cpL4dmJvg4pMeek0UQy5/FCg=
94100
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=

tee_response.go

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,15 @@ import (
77
"io"
88
"io/fs"
99
"net/http"
10-
"os"
1110
"path"
12-
"sync"
1311

1412
"github.com/wzshiming/ioswmr"
1513
)
1614

1715
type teeResponse struct {
18-
fileInfo fs.FileInfo
19-
swmr ioswmr.SWMR
20-
tmp *os.File
21-
teeCache *sync.Map
22-
etag string
23-
cacheFile string
16+
fileInfo fs.FileInfo
17+
swmr ioswmr.SWMR
18+
etag string
2419
}
2520

2621
func (t *teeResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -31,91 +26,79 @@ func (t *teeResponse) ServeHTTP(w http.ResponseWriter, r *http.Request) {
3126
rs := t.swmr.NewReadSeeker(0, int(size))
3227
defer rs.Close()
3328
name := path.Base(r.URL.Path)
34-
w.Header().Set("ETag", t.etag)
29+
if t.etag != "" {
30+
w.Header().Set("ETag", t.etag)
31+
}
3532
w.Header().Set("Content-Type", "application/octet-stream")
36-
w.Header().Set("Content-Length", fmt.Sprint(size))
3733
http.ServeContent(w, r, name, t.fileInfo.ModTime(), rs)
3834
} else {
3935
rs := t.swmr.NewReader(0)
4036
defer rs.Close()
41-
w.Header().Set("ETag", t.etag)
42-
w.Header().Set("Content-Type", "application/octet-stream")
37+
if t.etag != "" {
38+
w.Header().Set("ETag", t.etag)
39+
}
4340
w.WriteHeader(http.StatusOK)
4441
if r.Method == http.MethodGet {
4542
_, _ = io.Copy(w, rs)
4643
}
4744
}
4845
}
4946

50-
func (t *teeResponse) Close() error {
51-
if !t.swmr.IsClosed() {
52-
return nil
53-
}
54-
if t.swmr.Using() != 0 {
55-
return nil
56-
}
57-
t.teeCache.Delete(t.cacheFile)
58-
err := t.tmp.Close()
59-
if err != nil {
60-
return err
61-
}
62-
_ = os.Remove(t.tmp.Name())
63-
return nil
64-
}
65-
6647
func (m *MirrorHandler) cacheFileTee(ctx context.Context, sourceFile, cacheFile string) (*teeResponse, error) {
67-
resp, info, err := httpGet(ctx, m.client(), sourceFile)
48+
body, info, err := httpGet(ctx, m.client(), sourceFile, true)
6849
if err != nil {
6950
return nil, err
7051
}
7152

72-
var body io.Reader = resp
73-
7453
contentLength := info.Size()
7554
if contentLength == 0 {
76-
_ = resp.Close()
55+
_ = body.Close()
7756
return nil, ErrNotOK
7857
}
7958

8059
if m.Logger != nil {
8160
m.Logger.Println("Tee Cache", cacheFile, contentLength)
8261
}
8362

84-
tmp, err := os.CreateTemp("", "mirror-tee-*")
85-
if err != nil {
86-
_ = resp.Close()
87-
return nil, err
88-
}
8963
fw, err := m.RemoteCache.Writer(ctx, cacheFile)
9064
if err != nil {
9165
if m.Logger != nil {
9266
m.Logger.Println("Cache writer error", cacheFile, contentLength, err)
9367
}
94-
_ = resp.Close()
95-
_ = tmp.Close()
96-
_ = os.Remove(tmp.Name())
68+
_ = body.Close()
9769
return nil, err
9870
}
9971

100-
swmr := ioswmr.NewSWMR(tmp)
72+
swmr := ioswmr.NewSWMR(
73+
ioswmr.NewMemoryOrTemporaryFileBuffer(nil, nil),
74+
ioswmr.WithAutoClose(),
75+
ioswmr.WithBeforeCloseFunc(func() {
76+
m.teeCache.Delete(cacheFile)
77+
if m.Logger != nil {
78+
m.Logger.Println("Tee Cache closed", cacheFile, err)
79+
}
80+
}),
81+
)
10182

10283
tee := &teeResponse{
103-
fileInfo: info,
104-
swmr: swmr,
105-
tmp: tmp,
106-
etag: info.ETag(),
107-
teeCache: &m.teeCache,
108-
cacheFile: cacheFile,
84+
fileInfo: info,
85+
swmr: swmr,
86+
etag: info.ETag(),
10987
}
88+
sw := swmr.Writer()
11089

11190
go func() {
112-
defer tee.Close()
113-
defer resp.Close()
114-
defer fw.Close()
115-
defer swmr.Close()
91+
defer body.Close()
92+
_, err := io.Copy(sw, body)
93+
_ = sw.CloseWithError(err)
94+
}()
11695

117-
w := io.MultiWriter(swmr, fw)
118-
n, err := io.Copy(w, body)
96+
go func() {
97+
r := swmr.NewReader(0)
98+
defer r.Close()
99+
100+
defer fw.Close()
101+
n, err := io.Copy(fw, r)
119102
if err != nil && !errors.Is(err, io.EOF) {
120103
if m.Logger != nil {
121104
m.Logger.Println("SWMR copy error", cacheFile, contentLength, n, err)

0 commit comments

Comments
 (0)