From cc5b5f4e13dafbad9c9b6e1a8781b61da6978830 Mon Sep 17 00:00:00 2001 From: Jonas Widen Date: Sun, 16 Mar 2025 18:37:14 +0100 Subject: [PATCH] Fixed crash --- lua/gemini/api.lua | 137 +++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 74 deletions(-) diff --git a/lua/gemini/api.lua b/lua/gemini/api.lua index c3d2c76..1c7bada 100644 --- a/lua/gemini/api.lua +++ b/lua/gemini/api.lua @@ -12,98 +12,87 @@ end -- Async HTTP request function local function async_request(url, payload, callback) - -- Parse URL properly - local host = url:match("^https://([^/]+)") - local path = url:match("^https://[^/]+(.*)$") + -- Create a temporary file for the response + local temp_file = vim.fn.tempname() - if not host or not path then + -- Construct curl command + local curl_cmd = string.format( + 'curl -s -X POST -H "Content-Type: application/json" -d %s %s', + vim.fn.shellescape(payload), + vim.fn.shellescape(url) + ) + + -- Create job + local stdout = vim.loop.new_pipe() + local stderr = vim.loop.new_pipe() + + local handle + handle = vim.loop.spawn('curl', { + args = { + '-s', + '-X', 'POST', + '-H', 'Content-Type: application/json', + '-d', payload, + url + }, + stdio = {nil, stdout, stderr} + }, function(code) + stdout:close() + stderr:close() + handle:close() + end) + + if not handle then vim.schedule(function() - callback(nil, "Invalid URL format") + callback(nil, "Failed to start curl") end) return end - -- Resolve hostname to IP - vim.loop.getaddrinfo(host, "443", { - family = "inet", - socktype = "stream", - protocol = "tcp" - }, function(err, res) + local response = "" + local error_msg = "" + + stdout:read_start(function(err, chunk) if err then vim.schedule(function() - callback(nil, "DNS resolution error: " .. err) + callback(nil, "Read error: " .. err) end) return end + if chunk then + response = response .. chunk + end + end) - if not res or #res == 0 then + stderr:read_start(function(err, chunk) + if err then vim.schedule(function() - callback(nil, "Could not resolve hostname") + callback(nil, "Error reading stderr: " .. err) + end) + return + end + if chunk then + error_msg = error_msg .. chunk + end + end) + + -- When everything is done + handle:on('exit', function(code) + if code ~= 0 then + vim.schedule(function() + callback(nil, "Curl failed: " .. error_msg) end) return end - local client = vim.loop.new_tcp() - - client:connect(res[1].addr, res[1].port, function(err) - if err then - vim.schedule(function() - callback(nil, "Connection error: " .. err) - end) - return + -- Try to parse the response + local success, decoded = pcall(vim.json.decode, response) + vim.schedule(function() + if success then + callback(decoded) + else + callback(nil, "JSON decode error: " .. response) end - - -- Create TLS wrapper - local tls_client = vim.loop.new_tls_wrap(client) - - local request = string.format( - "POST %s HTTP/1.1\r\n" .. - "Host: %s\r\n" .. - "Content-Type: application/json\r\n" .. - "Content-Length: %d\r\n" .. - "\r\n" .. - "%s", - path, host, #payload, payload - ) - - local response = "" - - tls_client:write(request, function(err) - if err then - vim.schedule(function() - callback(nil, "Write error: " .. err) - end) - return - end - - tls_client:read_start(function(err, chunk) - if err then - vim.schedule(function() - callback(nil, "Read error: " .. err) - end) - return - end - - if chunk then - response = response .. chunk - else - -- Connection closed, process response - local body = response:match("\r\n\r\n(.+)$") - local success, decoded = pcall(vim.json.decode, body) - - vim.schedule(function() - if success then - callback(decoded) - else - callback(nil, "JSON decode error: " .. body) - end - end) - - tls_client:close() - client:close() - end - end) - end) end) end) end