v2writable: done: force synchronous awaitpid
[public-inbox.git] / examples / cgit-wwwhighlight-filter.lua
bloba622e9f80338f7da08c632437d73cf8cd88f3f20
1 -- Copyright (C) 2019-2021 all contributors <meta@public-inbox.org>
2 -- License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
3 --
4 -- This filter accesses the PublicInbox::WwwHighlight PSGI endpoint
5 -- (see examples/highlight.psgi)
6 --
7 -- Dependencies: lua-http
8 --
9 -- disclaimer: written by someone who does not know Lua.
11 -- This requires cgit linked with Lua
12 -- Usage (in your cgitrc(5) config file):
14 -- source-filter=lua:/path/to/this/script.lua
15 -- about-filter=lua:/path/to/this/script.lua
17 local wwwhighlight_url = 'http://127.0.0.1:9090/'
18 local req_timeout = 10
19 local too_big = false
21 -- match $PublicInbox::HTTP::MAX_REQUEST_BUFFER
22 local max_len = 10 * 1024 * 1024
24 -- about-filter needs surrounding <pre> tags if all we do is
25 -- highlight and linkify
26 local pre = true
28 function filter_open(...)
29 req_body = ""
31 -- detect when we're used in an about-filter
32 local repo_url = os.getenv('CGIT_REPO_URL')
33 if repo_url then
34 local path_info = os.getenv('PATH_INFO')
35 rurl = path_info:match("^/(.+)/about/?$")
36 pre = rurl == repo_url
37 end
39 -- hand filename off for language detection
40 local fn = select(1, ...)
41 if fn then
42 local http_util = require 'http.util'
43 wwwhighlight_url = wwwhighlight_url .. http_util.encodeURI(fn)
44 end
45 end
47 -- try to buffer the entire source in memory
48 function filter_write(str)
49 if too_big then
50 html(str)
51 elseif (req_body:len() + str:len()) > max_len then
52 too_big = true
53 req_body = ""
54 html(req_body)
55 html(str)
56 else
57 req_body = req_body .. str
58 end
59 end
61 function fail(err)
62 io.stderr:write(tostring(err), "\n")
63 if pre then
64 html("<pre>")
65 end
66 html_txt(req_body)
67 if pre then
68 html("</pre>")
69 end
70 return 1
71 end
73 function filter_close()
74 if too_big then
75 return 0
76 end
77 local request = require 'http.request'
78 local req = request.new_from_uri(wwwhighlight_url)
79 req.headers:upsert(':method', 'PUT')
80 req:set_body(req_body)
82 -- don't wait for 100-Continue message from the PSGI app
83 req.headers:delete('expect')
85 local headers, stream = req:go(req_timeout)
86 if headers == nil then
87 return fail(stream)
88 end
89 local status = headers:get(':status')
90 if status ~= '200' then
91 return fail('status ' .. status)
92 end
93 local body, err = stream:get_body_as_string()
94 if not body and err then
95 return fail(err)
96 end
97 if pre then
98 html("<pre>")
99 end
100 html(body)
101 if pre then
102 html("</pre>")
104 return 0