-- vim: set ts=2 expandtab: require 'apache2' require 'os' local unix = require "socket.unix" local SOCKET_PATH = "/var/container_share/redis-accessproxy.sock" local TIMEOUT = 0.1 function query_access_controller(r, client_ip) local sock = unix() sock:settimeout(TIMEOUT) local ok, err = sock:connect(SOCKET_PATH) if not ok then return nil, err end sock:send("GET /access-check?client_ip=" .. client_ip .. " HTTP/1.0\r\nHost: localhost\r\n\r\n") local response, recv_err = sock:receive("*a") sock:close() if not response then return nil, recv_err end local code = tonumber(response:match("HTTP/%d%.%d (%d+)")) r:debug("copper: ip=" .. client_ip .. " code=" .. tostring(code)) local headers = {} headers['block-reason'] = response:match("[Bb]lock%-[Rr]eason:%s*(.-)%s*\r?\n") return code, headers end function distributed_traffic(r) -- Let bots do *some* botty things if r.uri == "/robots.txt" then return apache2.DECLINED end -- `success` denotes whether the call to query_access_controller() succeeded or not -- `response` is the return code from query_access_controller() if it did succeed local success, response, headers = pcall(query_access_controller, r, r.useragent_ip) if success == false then -- Tell Apache that we've decided to not handle the request return apache2.DECLINED elseif response == 429 then -- return `Too Many Requests` r.err_headers_out['copper-block-reason'] = headers['block-reason'] r.err_headers_out['Retry-After'] = "300" return 429 end -- Fallback return apache2.DECLINED end