Skip to content

Commit b74f55d

Browse files
committed
optimize(transport): optimize resumable transport initial request
1 parent 2600811 commit b74f55d

File tree

2 files changed

+43
-57
lines changed

2 files changed

+43
-57
lines changed

pkg/v1/remote/transport/resumable.go

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,43 +29,20 @@ type resumableTransport struct {
2929
}
3030

3131
func (rt *resumableTransport) RoundTrip(in *http.Request) (*http.Response, error) {
32-
if in.Method != http.MethodGet {
33-
return rt.inner.RoundTrip(in)
34-
}
35-
36-
req := in.Clone(in.Context())
37-
req.Header.Set("Range", "bytes=0-")
38-
resp, err := rt.inner.RoundTrip(req)
32+
resp, err := rt.inner.RoundTrip(in)
3933
if err != nil {
4034
return resp, err
4135
}
4236

43-
switch resp.StatusCode {
44-
case http.StatusPartialContent:
45-
case http.StatusRequestedRangeNotSatisfiable:
46-
// fallback to previous behavior
47-
resp.Body.Close()
48-
return rt.inner.RoundTrip(in)
49-
default:
37+
if in.Method != http.MethodGet || resp.StatusCode != http.StatusOK || resp.ContentLength <= 0 {
5038
return resp, nil
5139
}
5240

53-
var contentLength int64
54-
if _, _, contentLength, err = parseContentRange(resp.Header.Get("Content-Range")); err != nil || contentLength <= 0 {
55-
// fallback to previous behavior
56-
resp.Body.Close()
57-
return rt.inner.RoundTrip(in)
58-
}
59-
60-
// modify response status to 200, ensure caller error checking works
61-
resp.StatusCode = http.StatusOK
62-
resp.Status = "200 OK"
63-
resp.ContentLength = contentLength
6441
resp.Body = &resumableBody{
6542
rc: resp.Body,
6643
inner: rt.inner,
67-
req: req,
68-
total: contentLength,
44+
req: in,
45+
total: resp.ContentLength,
6946
transferred: 0,
7047
}
7148

pkg/v1/remote/transport/resumable_test.go

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,42 +31,46 @@ func handleResumableLayer(data []byte, w http.ResponseWriter, r *http.Request, t
3131
return
3232
}
3333

34+
var (
35+
contentLength, start, end int64
36+
statusCode = http.StatusOK
37+
err error
38+
)
39+
40+
contentLength = int64(len(data))
41+
end = contentLength - 1
3442
contentRange := r.Header.Get("Range")
35-
if contentRange == "" {
36-
w.WriteHeader(http.StatusBadRequest)
37-
return
38-
}
39-
40-
matches := rangeRe.FindStringSubmatch(contentRange)
41-
if len(matches) != 3 {
42-
w.WriteHeader(http.StatusBadRequest)
43-
return
44-
}
45-
46-
contentLength := int64(len(data))
47-
start, err := strconv.ParseInt(matches[1], 10, 64)
48-
if err != nil || start < 0 {
49-
w.WriteHeader(http.StatusBadRequest)
50-
return
51-
}
52-
53-
if start >= int64(contentLength) {
54-
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
55-
return
56-
}
43+
if contentRange != "" {
44+
matches := rangeRe.FindStringSubmatch(contentRange)
45+
if len(matches) != 3 {
46+
w.WriteHeader(http.StatusBadRequest)
47+
return
48+
}
5749

58-
var end = int64(contentLength) - 1
59-
if matches[2] != "" {
60-
end, err = strconv.ParseInt(matches[2], 10, 64)
61-
if err != nil || end < 0 {
50+
if start, err = strconv.ParseInt(matches[1], 10, 64); err != nil || start < 0 {
6251
w.WriteHeader(http.StatusBadRequest)
6352
return
6453
}
6554

66-
if end >= int64(contentLength) {
55+
if start >= int64(contentLength) {
6756
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
6857
return
6958
}
59+
60+
if matches[2] != "" {
61+
end, err = strconv.ParseInt(matches[2], 10, 64)
62+
if err != nil || end < 0 {
63+
w.WriteHeader(http.StatusBadRequest)
64+
return
65+
}
66+
67+
if end >= int64(contentLength) {
68+
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
69+
return
70+
}
71+
}
72+
73+
statusCode = http.StatusPartialContent
7074
}
7175

7276
var currentContentLength = end - start + 1
@@ -91,9 +95,14 @@ func handleResumableLayer(data []byte, w http.ResponseWriter, r *http.Request, t
9195

9296
end = start + currentContentLength - 1
9397

94-
w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, contentLength))
95-
w.Header().Set("Content-Length", strconv.FormatInt(currentContentLength, 10))
96-
w.WriteHeader(http.StatusPartialContent)
98+
if statusCode == http.StatusPartialContent {
99+
w.Header().Set("Content-Length", strconv.FormatInt(currentContentLength, 10))
100+
w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, contentLength))
101+
} else {
102+
w.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10))
103+
}
104+
105+
w.WriteHeader(statusCode)
97106
w.Write(data[start : end+1])
98107
time.Sleep(time.Second)
99108
}

0 commit comments

Comments
 (0)