net.lua 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. local M = {}
  2. --- Makes an HTTP GET request to the given URL (asynchronous).
  3. ---
  4. --- This function operates in one mode:
  5. --- - Asynchronous (non-blocking): Returns immediately and passes the response object to the
  6. --- provided `on_response` handler on completetion.
  7. ---
  8. --- @param url string The URL for the request.
  9. --- @param opts? table Optional parameters:
  10. --- - `verbose` (boolean|nil): Enables verbose output.
  11. --- - `retry` (integer|nil): Number of retries on transient failures (default: 3).
  12. --- - `outpath` (string|nil): File path to save the response body to. If set, the `body` value in the Response Object will be `true` instead of the response body.
  13. --- @param on_response fun(err?: string, response?: { body: string|boolean }) Callback invoked on request
  14. --- completetion. The `body` field in the response object contains the raw response data (text or binary).
  15. --- Called with (err, nil) on failure, or (nil, { body = string|boolean }) on success.
  16. function M.request(url, opts, on_response)
  17. vim.validate({
  18. url = { url, 'string' },
  19. opts = { opts, 'table', true },
  20. on_response = { on_response, 'function' },
  21. })
  22. opts = opts or {}
  23. local retry = opts.retry or 3
  24. -- Build curl command
  25. local args = { 'curl' }
  26. if opts.verbose then
  27. table.insert(args, '--verbose')
  28. else
  29. vim.list_extend(args, { '--silent', '--show-error', '--fail' })
  30. end
  31. vim.list_extend(args, { '--location', '--retry', tostring(retry) })
  32. if opts.outpath then
  33. vim.list_extend(args, { '--output', opts.outpath })
  34. end
  35. table.insert(args, url)
  36. local function on_exit(res)
  37. local s = 'Request failed with exit code %d'
  38. local err_msg = res.code ~= 0
  39. and ((res.stderr ~= '' and res.stderr) or string.format(s, res.code))
  40. or nil
  41. local response = res.code == 0 and { body = opts.outpath and true or res.stdout } or nil
  42. if on_response then
  43. on_response(err_msg, response)
  44. end
  45. end
  46. vim.system(args, {}, on_exit)
  47. end
  48. return M