-
-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathcurl.lua
More file actions
148 lines (128 loc) · 3.61 KB
/
curl.lua
File metadata and controls
148 lines (128 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
local async = require('plenary.async')
local curl = require('plenary.curl')
local log = require('plenary.log')
local utils = require('CopilotChat.utils')
local M = {}
M.args = {
timeout = 30000,
raw = {
'--retry',
'2',
'--retry-delay',
'1',
'--keepalive-time',
'60',
'--no-compressed',
'--connect-timeout',
'10',
'--tcp-nodelay',
'--no-buffer',
},
}
--- Store curl global arguments
---@param args table The arguments
---@return table
function M.store_args(args)
M.args = vim.tbl_deep_extend('force', M.args, args)
return M.args
end
--- Send curl get request
---@param url string The url
---@param opts table? The options
---@async
M.get = async.wrap(function(url, opts, callback)
log.debug('GET request:', url, opts)
local args = {
on_error = function(err)
log.debug('GET error:', err)
callback(nil, err and err.stderr or err)
end,
}
args = vim.tbl_deep_extend('force', M.args, args)
args = vim.tbl_deep_extend('force', args, opts or {})
args.callback = function(response)
log.debug('GET response:', response)
-- HTTP status codes: 1xx (informational), 2xx (success)
-- Status 100 (Continue) is common with streaming responses
local status_str = tostring(response.status)
if response and not vim.startswith(status_str, '1') and not vim.startswith(status_str, '20') then
callback(response, response.body)
return
end
if not args.json_response then
callback(response)
return
end
local body, err = utils.json_decode(tostring(response.body))
if err then
callback(response, err)
else
response.body = body
callback(response)
end
end
curl.get(url, args)
end, 3)
--- Send curl post request
---@param url string The url
---@param opts table? The options
---@async
M.post = async.wrap(function(url, opts, callback)
log.debug('POST request:', url, opts)
local args = {
on_error = function(err)
log.debug('POST error:', err)
callback(nil, err and err.stderr or err)
end,
}
args = vim.tbl_deep_extend('force', M.args, args)
args = vim.tbl_deep_extend('force', args, opts or {})
local temp_file_path = nil
args.callback = function(response)
log.debug('POST response:', url, response)
if temp_file_path then
local ok, err = pcall(os.remove, temp_file_path)
if not ok then
log.debug('Failed to remove temp file:', temp_file_path, err)
end
end
-- HTTP status codes: 1xx (informational), 2xx (success)
-- Status 100 (Continue) is common with streaming responses
local status_str = tostring(response.status)
if response and not vim.startswith(status_str, '1') and not vim.startswith(status_str, '20') then
callback(response, response.body)
return
end
if not args.json_response then
callback(response)
return
end
local body, err = utils.json_decode(tostring(response.body))
if err then
callback(response, err)
else
response.body = body
callback(response)
end
end
if args.json_response then
args.headers = vim.tbl_deep_extend('force', args.headers or {}, {
Accept = 'application/json',
})
end
if args.json_request then
args.headers = vim.tbl_deep_extend('force', args.headers or {}, {
['Content-Type'] = 'application/json',
})
temp_file_path = os.tmpname()
local f = io.open(temp_file_path, 'w+')
if f == nil then
error('Could not open file: ' .. temp_file_path)
end
f:write(vim.json.encode(args.body))
f:close()
args.body = temp_file_path
end
curl.post(url, args)
end, 3)
return M