Skip to content

Commit 31fa676

Browse files
benoit-pierreFrenzie
authored andcommitted
ffi/downloader: improve fetch implementation
Use new HTTP response headers callback to abort early in case of error. Additionally, simplify check for range request support: only check the status code, instead of headers (since Cloudflare response doesn't include the expected "Accept-range" header).
1 parent 48f9870 commit 31fa676

1 file changed

Lines changed: 23 additions & 33 deletions

File tree

ffi/downloader.lua

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,58 +24,48 @@ end
2424

2525
function Downloader:fetch(url, callback, ranges, etag)
2626
assert(not (ranges and etag))
27-
self.status_code = nil
28-
self.etag = nil
29-
local ok
3027
local sink = function(s)
3128
return s and callback(ffi.cast("uint8_t *", s), #s)
3229
end
33-
local body, status_code, resp_headers, status_line
30+
local abort
31+
local response_headers = function(status_code, resp_headers, status_line)
32+
if ranges then
33+
abort = status_code ~= 206
34+
else
35+
abort = status_code ~= 200 and status_code ~= 304
36+
end
37+
return abort
38+
end
39+
local ok, status_code, resp_headers, status_line
3440
if ranges then
3541
ranges = merge_ranges(ranges)
36-
local range_support_checked = false
3742
local ranges_index = 1
3843
repeat
39-
body, status_code, resp_headers, status_line = http.request{
44+
ok, status_code, resp_headers, status_line = http.request{
4045
url = url,
4146
headers = { ["Range"] = string.format("bytes=%u-%u", ranges[ranges_index][1], ranges[ranges_index][2]) },
47+
response_headers = response_headers,
4248
sink = sink,
4349
}
44-
if not body then
45-
self.err = status_code
46-
return false
47-
end
48-
ok = status_code == 206
49-
if not ok then
50-
self.err = status_line
51-
return false
52-
end
53-
if not range_support_checked then
54-
if resp_headers["accept-ranges"] ~= "bytes" and not (resp_headers["content-range"] or ""):match("^bytes ") then
55-
self.err = "server does not support range requests!"
56-
return false
57-
end
58-
range_support_checked = true
59-
end
50+
ok = ok and not abort
6051
ranges_index = ranges_index + 1
61-
until ranges_index > #ranges
52+
until abort or not ok or ranges_index > #ranges
53+
if not ok and status_code == 200 then
54+
status_line = "server does not support range requests!"
55+
end
6256
else
63-
body, status_code, resp_headers, status_line = http.request{
57+
ok, status_code, resp_headers, status_line = http.request{
6458
url = url,
6559
headers = etag and { ["If-None-Match"] = etag },
60+
response_headers = response_headers,
6661
sink = sink,
6762
}
68-
if not body then
69-
self.err = status_code
70-
return false
71-
end
72-
self.etag = resp_headers['etag']
73-
ok = status_code == 200 or status_code == 304
74-
if not ok then
75-
self.err = status_line
76-
end
63+
ok = ok and not abort
7764
end
65+
self.headers = resp_headers
66+
self.etag = resp_headers['etag']
7867
self.status_code = status_code
68+
self.err = not ok and (status_line or status_code) or nil
7969
return ok
8070
end
8171

0 commit comments

Comments
 (0)