|
51 | 51 | -- ── curl-based write helper ─────────────────────────────────────────────────── |
52 | 52 |
|
53 | 53 | local function curlRequest(url, method, payload, token) |
54 | | - logger.dbg("GithubBrowserAPI: curl " .. method .. " " .. url) |
| 54 | + logger.dbg("GithubBrowserAPI: " .. method .. " " .. url) |
55 | 55 |
|
56 | | - local cache_dir = DataStorage:getDataDir() .. "/cache" |
57 | | - os.execute("mkdir -p " .. cache_dir) |
58 | | - local tmp_payload = cache_dir .. "/githubbrowser_payload.json" |
59 | | - |
60 | | - if payload then |
61 | | - local fh = io.open(tmp_payload, "w") |
62 | | - if fh then |
63 | | - fh:write(payload) |
64 | | - fh:close() |
65 | | - end |
66 | | - end |
| 56 | + local headers = { |
| 57 | + ["User-Agent"] = "KOReader-GithubBrowser/1.0", |
| 58 | + ["Accept"] = "application/vnd.github.v3+json", |
| 59 | + ["Content-Type"] = "application/json", |
| 60 | + } |
67 | 61 |
|
68 | | - local cmd = string.format( |
69 | | - 'curl -s -S -X %s -H "User-Agent: KOReader-GithubBrowser/1.0" -H "Accept: application/vnd.github.v3+json" -H "Content-Type: application/json" --connect-timeout 30 --max-time 120', |
70 | | - method |
71 | | - ) |
72 | 62 | if token and token ~= "" then |
73 | | - cmd = cmd .. string.format(' -H "Authorization: token %s"', token) |
| 63 | + headers["Authorization"] = "token " .. token |
74 | 64 | end |
| 65 | + |
| 66 | + local source = nil |
75 | 67 | if payload then |
76 | | - cmd = cmd .. string.format(' -d @"%s"', tmp_payload) |
| 68 | + headers["Content-Length"] = tostring(#payload) |
| 69 | + source = ltn12.source.string(payload) |
| 70 | + else |
| 71 | + headers["Content-Length"] = "0" |
77 | 72 | end |
78 | | - cmd = cmd .. string.format(' "%s"', url) |
79 | 73 |
|
80 | | - local handle = io.popen(cmd .. " 2>&1") |
81 | | - local response = "" |
82 | | - if handle then |
83 | | - response = handle:read("*a") |
84 | | - handle:close() |
| 74 | + local response_body = {} |
| 75 | + |
| 76 | + socketutil:set_timeout(DEFAULT_TIMEOUT, DEFAULT_MAXTIME) |
| 77 | + local ok, code, _resp_headers, _status = socket_http.request { |
| 78 | + url = url, |
| 79 | + method = method, |
| 80 | + headers = headers, |
| 81 | + source = source, |
| 82 | + sink = ltn12.sink.table(response_body), |
| 83 | + redirect = true, |
| 84 | + } |
| 85 | + socketutil:reset_timeout() |
| 86 | + |
| 87 | + if not ok then |
| 88 | + return nil, "Network error: " .. tostring(code) |
85 | 89 | end |
86 | 90 |
|
87 | | - if payload then os.remove(tmp_payload) end |
| 91 | + local response = table.concat(response_body) |
88 | 92 |
|
89 | | - if response == "" then |
90 | | - return nil, "Empty response from GitHub API." |
| 93 | + if response == "" and (code == 200 or code == 201 or code == 204) then |
| 94 | + return { success = true }, nil |
| 95 | + elseif response == "" then |
| 96 | + return nil, "Empty response (HTTP " .. tostring(code) .. ")" |
91 | 97 | end |
92 | 98 |
|
93 | | - local ok, data = pcall(json.decode, response) |
94 | | - if not ok then |
95 | | - return nil, "Failed to parse response: " .. response:sub(1, 200) |
| 99 | + local ok2, data = pcall(json.decode, response) |
| 100 | + if not ok2 then |
| 101 | + return nil, "Failed to parse response (HTTP " .. tostring(code) .. "): " .. response:sub(1, 200) |
| 102 | + end |
| 103 | + |
| 104 | + if type(code) == "number" and code >= 400 then |
| 105 | + return nil, "API Error (HTTP " .. tostring(code) .. "): " .. (data.message or "?") |
96 | 106 | end |
97 | 107 |
|
98 | 108 | return data, nil |
|
0 commit comments