summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-05 11:02:14 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-05 11:02:14 +0000
commit25d58ff9f19c7af2eff8e90f97aa64d180151152 (patch)
tree0808469ee8bef5d983d6dedc49ab0fc56c1f5cde
parent9a9fa3cc8150a93cd47e631d7c4c11d74cfcb6ff (diff)
downloadgitano-25d58ff9f19c7af2eff8e90f97aa64d180151152.tar.bz2
Change the http interface to use cURL
-rw-r--r--README4
-rw-r--r--lib/gitano/actions.lua89
2 files changed, 44 insertions, 49 deletions
diff --git a/README b/README
index 10fe364..2ff7eef 100644
--- a/README
+++ b/README
@@ -22,3 +22,7 @@ Gitano depends on [lua-scrypt], [Luxio], [Lace], [Supple], [Gall] and [Clod].
In addition, Gitano depends on the Lua PCRE package lrexlib which can typically
be found in lua-rex-pcre or liblua5.1-rex-pcre0 in Debian or Ubuntu.
+
+If you wish to use the http access capability in post-recive hooks then you
+will need to ensure cURL is installed and the `curl` binary itself is present
+on your PATH.
diff --git a/lib/gitano/actions.lua b/lib/gitano/actions.lua
index 30f93de..06b5af7 100644
--- a/lib/gitano/actions.lua
+++ b/lib/gitano/actions.lua
@@ -10,6 +10,7 @@ local gall = require "gall"
local config = require "gitano.config"
local sio = require 'luxio.simple'
local supple = require 'gitano.supple'
+local subprocess = require 'luxio.subprocess'
local function update_actions(conf, repo, tags)
@@ -41,54 +42,43 @@ local function update_actions(conf, repo, tags)
return true
end
-local function http_txn(method, host, path, headers, body)
- log.ddebug("Attempting to fetch",host,":", path)
- log.ddebug("Connect...")
- local port = "http"
- if host:match(":") then
- host, port = host:match("^(.-):([^:]+)$")
+local function curl_txn(url, headers, body, content_type)
+ local method = (body and body ~= "") and "POST" or "GET"
+ local args = { "curl", "--max-filesize", tostring(1024*1024),
+ "--insecure", "-X", method, "-D-", "-s" }
+ if type(url) ~= "string" then
+ return "500", "url must be a string", {}, ""
end
- local sock, err = sio.connect(host, port)
- if not sock then
- return "500", err, {}, ""
+ if url:sub(1,7) ~= "http://" and url:sub(1,8) ~= "https://" then
+ return "500", "url must be http:// or https://", {}, ""
end
- local req_lines = {
- method .. " " .. path .. " HTTP/1.0",
- "Host: " .. host,
- }
- for k, v in pairs(headers) do
- req_lines[#req_lines+1] = ("%s: %s"):format(k,v)
+ headers = headers or {}
+ if type(headers) ~= "table" then
+ return "500", "headers must be a table if provided", {} , ""
end
- req_lines[#req_lines+1] = "Connection: Close"
- req_lines[#req_lines+1] = ""
- req_lines[#req_lines+1] = ""
- local req = table.concat(req_lines, "\r\n")
- log.ddebug("Write request")
- log.ddebug(req)
- local ok, msg = sock:write(req)
- if not ok then
- sock:close()
- return "500", msg, {}, ""
+ if method == "POST" then
+ headers["Content-Type"] = content_type or application/octet-stream
+ headers["Content-Length"] = tostring(#body)
+ args[#args+1] = "--data-binary"
+ args[#args+1] = "@-"
end
- if body and body ~= "" then
- log.ddebug("Writing body of request:")
- log.ddebug(body)
- ok, msg = sock:write(body)
- if not ok then
- sock:close()
- return "500", msg, {}, ""
- end
+ for k, v in pairs(headers) do
+ args[#args+1] = "-H"
+ args[#args+1] = tostring(k) .. ": " .. tostring(v)
end
- log.ddebug("Read response")
- ok, msg = sock:read "*a"
- if not ok then
- sock:close()
- return "500", msg, {}, ""
+ args[#args+1] = url
+ args.stdin = body or ""
+ args.stdout = subprocess.PIPE
+ args.stderr = subprocess.PIPE
+ local proc = subprocess.spawn_simple(args)
+ local response = proc.stdout:read("*a")
+ local err = proc.stderr:read("*a")
+ proc.stdout:close()
+ proc.stderr:close()
+ local how, why = proc:wait()
+ if (how ~= "exit" or why ~= 0) then
+ return "500", err, {}, ""
end
- local response = ok
-
- sock:close()
-
local code, msg, _headers, content = response:match("^HTTP/1.[01] (...) ?([^\r\n]+)\r?\n(.-)\r?\n\r?\n(.*)$")
local headers = {}
for k, v in _headers:gmatch("([^:\r\n]+): *([^\r\n]+)") do
@@ -100,16 +90,15 @@ local function http_txn(method, host, path, headers, body)
return code, msg, headers, content
end
+
local function http_get(host, path)
- return http_txn("GET", host, path, {}, "")
+ log.warn("Hook using legacy http_get or http.get, please update to use new fetch() interface")
+ return curl_txn("http://" .. host .. path)
end
local function http_post(host, path, content_type, body)
- return http_txn("POST", host, path,
- {
- ["Content-Type"] = content_type,
- ["Content-Length"] = tostring(#body),
- }, body)
+ log.warn("Hook using legacy http.post, please update to use new fetch() interface")
+ return curl_txn("http://" .. host .. path, body, content_type)
end
local function set_supple_globals(action)
@@ -124,7 +113,9 @@ local function set_supple_globals(action)
globs["log"] = logcopy
if action == "post-receive" then
globs["http_get"] = http_get -- Legacy name for this, use http.get
- globs["http"] = { get = http_get, post = http_post }
+ local http_tab = { get = http_get, post = http_post } -- Moar legacy for now
+ globs["http"] = http_tab
+ globs["fetch"] = curl_txn
end
supple.set_globals(globs)
end