public-inbox.git  about / heads / tags
an "archives first" approach to mailing lists
blob a267d1c88464b4d8b5cbf9bcd96b9a8701509bf6 2368 bytes (raw)
$ git show ci-WIP:examples/cgit-wwwhighlight-filter.lua	# shows this blob on the CLI

  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
 
-- Copyright (C) 2019 all contributors <meta@public-inbox.org>
-- License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
--
-- This filter accesses the PublicInbox::WwwHighlight PSGI endpoint
-- (see examples/highlight.psgi)
--
-- Dependencies: lua-http
--
-- disclaimer: written by someone who does not know Lua.
--
-- This requires cgit linked with Lua
-- Usage (in your cgitrc(5) config file):
--
--   source-filter=lua:/path/to/this/script.lua
--   about-filter=lua:/path/to/this/script.lua
--
local wwwhighlight_url = 'http://127.0.0.1:9090/'
local req_timeout = 10
local too_big = false

-- match $PublicInbox::HTTP::MAX_REQUEST_BUFFER
local max_len = 10 * 1024 * 1024

-- about-filter needs surrounding <pre> tags if all we do is
-- highlight and linkify
local pre = true

function filter_open(...)
	req_body = ""

	-- detect when we're used in an about-filter
	local repo_url = os.getenv('CGIT_REPO_URL')
	if repo_url then
		local path_info = os.getenv('PATH_INFO')
		rurl = path_info:match("^/(.+)/about/?$")
		pre = rurl == repo_url
	end

	-- hand filename off for language detection
	local fn = select(1, ...)
	if fn then
		local http_util = require 'http.util'
		wwwhighlight_url = wwwhighlight_url .. http_util.encodeURI(fn)
	end
end

-- try to buffer the entire source in memory
function filter_write(str)
	if too_big then
		html(str)
	elseif (req_body:len() + str:len()) > max_len then
		too_big = true
		req_body = ""
		html(req_body)
		html(str)
	else
		req_body = req_body .. str
	end
end

function fail(err)
	io.stderr:write(tostring(err), "\n")
	if pre then
		html("<pre>")
	end
	html_txt(req_body)
	if pre then
		html("</pre>")
	end
	return 1
end

function filter_close()
	if too_big then
		return 0
	end
	local request = require 'http.request'
	local req = request.new_from_uri(wwwhighlight_url)
	req.headers:upsert(':method', 'PUT')
	req:set_body(req_body)

	-- don't wait for 100-Continue message from the PSGI app
	req.headers:delete('expect')

	local headers, stream = req:go(req_timeout)
	if headers == nil then
		return fail(stream)
	end
	local status = headers:get(':status')
	if status ~= '200' then
		return fail('status ' .. status)
	end
	local body, err = stream:get_body_as_string()
	if not body and err then
		return fail(err)
	end
	if pre then
		html("<pre>")
	end
	html(body)
	if pre then
		html("</pre>")
	end
	return 0
end

git clone https://public-inbox.org/public-inbox.git
git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git