|
24 | 24 |
|
25 | 25 | function Downloader:fetch(url, callback, ranges, etag) |
26 | 26 | assert(not (ranges and etag)) |
27 | | - self.status_code = nil |
28 | | - self.etag = nil |
29 | | - local ok |
30 | 27 | local sink = function(s) |
31 | 28 | return s and callback(ffi.cast("uint8_t *", s), #s) |
32 | 29 | 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 |
34 | 40 | if ranges then |
35 | 41 | ranges = merge_ranges(ranges) |
36 | | - local range_support_checked = false |
37 | 42 | local ranges_index = 1 |
38 | 43 | repeat |
39 | | - body, status_code, resp_headers, status_line = http.request{ |
| 44 | + ok, status_code, resp_headers, status_line = http.request{ |
40 | 45 | url = url, |
41 | 46 | headers = { ["Range"] = string.format("bytes=%u-%u", ranges[ranges_index][1], ranges[ranges_index][2]) }, |
| 47 | + response_headers = response_headers, |
42 | 48 | sink = sink, |
43 | 49 | } |
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 |
60 | 51 | 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 |
62 | 56 | else |
63 | | - body, status_code, resp_headers, status_line = http.request{ |
| 57 | + ok, status_code, resp_headers, status_line = http.request{ |
64 | 58 | url = url, |
65 | 59 | headers = etag and { ["If-None-Match"] = etag }, |
| 60 | + response_headers = response_headers, |
66 | 61 | sink = sink, |
67 | 62 | } |
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 |
77 | 64 | end |
| 65 | + self.headers = resp_headers |
| 66 | + self.etag = resp_headers['etag'] |
78 | 67 | self.status_code = status_code |
| 68 | + self.err = not ok and (status_line or status_code) or nil |
79 | 69 | return ok |
80 | 70 | end |
81 | 71 |
|
|
0 commit comments