From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, WEIRD_PORT shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 55EA61F453; Thu, 25 Apr 2019 03:19:04 +0000 (UTC) Date: Thu, 25 Apr 2019 03:19:04 +0000 From: Eric Wong To: meta@public-inbox.org Subject: [PATCH v2] examples: cgit filter for use with WwwHighlight Message-ID: <20190425031904.GA31675@dcvr> References: <20190424230214.2378-1-e@80x24.org> <20190424230214.2378-5-e@80x24.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190424230214.2378-5-e@80x24.org> List-Id: I'm using this as the cgit about-filter and source-filter in https://80x24.org/public-inbox.git --- v2: * proper error handling and behavior w.r.t. large files * do not send Expect: header (and waiting for 100-continue) * correctly distinguish between about-filter and source-filter (v1 was creating nested
 when used as source-filter)

 interdiff:
 $ U=https://public-inbox.org/meta
 $ interdiff <(curl -s $U/dafb7a8/s/?b=x.lua) <(curl -s $U/a267d1c/s/?b=x.lua)

 MANIFEST                              |   1 +
 examples/cgit-wwwhighlight-filter.lua | 105 ++++++++++++++++++++++++++
 2 files changed, 106 insertions(+)
 create mode 100644 examples/cgit-wwwhighlight-filter.lua

diff --git a/MANIFEST b/MANIFEST
index 9858b9e..ed8ff49 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -39,6 +39,7 @@ examples/apache2_perl.conf
 examples/apache2_perl_old.conf
 examples/cgi-webrick.rb
 examples/cgit-commit-filter.lua
+examples/cgit-wwwhighlight-filter.lua
 examples/cgit.psgi
 examples/highlight.psgi
 examples/logrotate.conf
diff --git a/examples/cgit-wwwhighlight-filter.lua b/examples/cgit-wwwhighlight-filter.lua
new file mode 100644
index 0000000..a267d1c
--- /dev/null
+++ b/examples/cgit-wwwhighlight-filter.lua
@@ -0,0 +1,105 @@
+-- Copyright (C) 2019 all contributors 
+-- License: GPL-2.0+ 
+--
+-- 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 
 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("
")
+	end
+	html_txt(req_body)
+	if pre then
+		html("
") + 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("
")
+	end
+	html(body)
+	if pre then
+		html("
") + end + return 0 +end -- EW