From fd6578671b530d791aeef8ff486735055f84d16f Mon Sep 17 00:00:00 2001 From: Reuh Date: Sun, 11 Dec 2016 17:38:21 +0100 Subject: [PATCH] Added syntax selection Also, the file is now 257 lines longs, including the final empty line. It's empty anyway, so it doesn't count ? Right ? --- changelog.txt | 3 ++- config.default.lua | 4 ++++ vrel.lua | 33 ++++++++++++++++----------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9d52c0a..d81cae8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,8 @@ vrel 0.1.5 (wip): - Doubled the default maximum lifetime (3 months -> 6 months). - Added an optional configuration file. - - Added syntax setting per-paste (wip). + - Added syntax setting per-paste. + - Sender IP storing should work with proxies. - Various luacheck cleaning (a few potential bugs are fixed). It's still complaining about legit things tho. vrel 0.1.4: - Now stores the sender's IP diff --git a/config.default.lua b/config.default.lua index dff759a..38d67f8 100644 --- a/config.default.lua +++ b/config.default.lua @@ -17,6 +17,10 @@ return { defaultLifetime = 86400, -- 1 day -- Maximal size of a request/paste requestMaxDataSize = 15728640, -- 15MB + -- Pygments style name + pygmentsStyle = "monokai", + -- Extra CSS applied to syntax-highlighted blocks (with and without Pygments) + extraStyle = "*{color:#F8F8F2;background-color:#272822;margin:0px;}pre{color:#8D8D8A;}", -- Request timeout timeout = 1, -- 1 second -- Debug mode diff --git a/vrel.lua b/vrel.lua index 5022272..ab0af0d 100644 --- a/vrel.lua +++ b/vrel.lua @@ -1,7 +1,7 @@ #!/bin/lua --- vrel v0.1.5: online paste service, in 256 lines of Lua (max line lenght = 256 but we shouldn't go this far if not needed). --- This module requires LuaSocket 2.0.2, and debug mode requires LuaFileSystem 1.6.3. Install pygmentize for the optional syntax highlighting. --- If you want persistance for paste storage, install lsqlite3. vrel should work with Lua 5.1 to 5.3. +-- This module requires LuaSocket 2.0.2, and debug mode requires LuaFileSystem 1.6.3. Install pygmentize for the optional syntax highlighting. If you want persistance for paste storage, install lsqlite3. vrel should work with Lua 5.1 to 5.3. +math.randomseed(os.time()) local hasConfigFile, config = pcall(dofile, "config.lua") if not hasConfigFile then config = {} end -- Basic HTTP server -- local httpd, requestMaxDataSize = nil, config.requestMaxDataSize or 15728640 -- max post/paste data size (bytes) (15MB) @@ -28,9 +28,8 @@ httpd = { post = {}, -- POST args {argName=argValue,...} (strings) get = {} -- GET args {argName=argValue,...} (strings) } - -- Get headers data from socket - local lines = {} - repeat + local lines = {} -- Headers + repeat -- Get headers data from socket local message = client:receive("*l") table.insert(lines, message) until not message or #message == 0 @@ -174,6 +173,7 @@ local function generateName(size) -- generate a paste name. If size ~= nil, will until (not size and not (data[name] or forbiddenName[name])) or (#name >= (size or math.huge)) return name end +local function getClientId(request) return request.headers["X-Forwarded-For"] or request.client:getpeername() end -- returns some identifier for the client who sent the request local lastClean, cleanInterval = os.time(), config.cleanInterval or 1800 -- last clean time (all time are stored in seconds) and clean interval (30min) local maxLifetime, defaultLifetime = config.maxLifetime or 15552000, config.defaultLifetime or 86400 -- maximum lifetime of a paste (6 month) and default (1 day) local function clean() -- clean the database each cleanInterval @@ -187,7 +187,7 @@ local function get(name, request) clean() -- get a paste (returns nil if non-exi if data[name] then local d = data[name] if d.expire < os.time() then data[name] = nil return end - if request.client:getpeername() ~= d.senderId and d.burnOnRead then data[name] = nil end -- burn on read (except if retrieved by original poster) + if getClientId(request) ~= d.senderId and d.burnOnRead then data[name] = nil end -- burn on read (except if retrieved by original poster) return d end end @@ -196,13 +196,13 @@ local function post(paste, request) clean() -- add a paste, will check data and if paste.lifetime then paste.expire = os.time() + (tonumber(paste.lifetime) or defaultLifetime) end paste.expire = math.min(tonumber(paste.expire) or os.time()+defaultLifetime, os.time()+maxLifetime) paste.burnOnRead = paste.burnOnRead == true - paste.senderId = paste.senderId or request.client:getpeername() or "0.0.0.0" + paste.senderId = paste.senderId or getClientId(request) or "unknown" paste.syntax = (paste.syntax or "text"):lower():match("[a-z]*") paste.data = tostring(paste.data) data[name] = paste return name, data[name] end -local pygmentsStyle, extraStyle = "monokai", "*{color:#F8F8F2;background-color:#272822;margin:0px;}pre{color:#8D8D8A;}" -- pygments style name, extra css for highlighted blocks (also aply if no pygments) +local pygmentsStyle, extraStyle = config.pygmentsStyle or "monokai", config.extraStyle or "*{color:#F8F8F2;background-color:#272822;margin:0px;}pre{color:#8D8D8A;}" -- pygments style name, extra css for highlighted blocks (also aply if no pygments) local function highlight(paste, forceLexer) -- Syntax highlighting; should returns the code block, style and everything included local source = assert(io.open("pygmentize.tmp", "w")) -- Lua can't at the same time write an read from a command, so we need to put one in a file source:write(paste.data) source:close() @@ -220,11 +220,10 @@ httpd.start(config.address or "*", config.port or 8155, { -- Pages ["/([^/]*)"] = function(request, name) if forbiddenName[name] then return end if request.method == "POST" and request.post.data then - name = post({ lifetime = (tonumber(request.post.lifetime) or defaultLifetime/3600)*3600, burnOnRead = request.post.burnOnRead == "on", data = request.post.data }, request) + name = post({ lifetime = (tonumber(request.post.lifetime) or defaultLifetime/3600)*3600, burnOnRead = request.post.burnOnRead == "on", syntax = request.post.syntax, data = request.post.data }, request) return { "303 See Other", {["Location"] = "/"..name}, "" } end - return { "200 OK", {["Content-Type"] = "text/html"}, [[ -vrel + return { "200 OK", {["Content-Type"] = "text/html"}, [[vrel ]]..(#name == 0 and [[
expires in hours (burn on read) vrel
- -
]] or highlight(get(name:match("^[^.]+"), request) or {data="paste not found"}, name:lower():match("%.([a-z]+)$")))..[[ + [["/> hours (burn on read) vrel + + ]] or highlight(get(name:match("^[^.]+"), request) or {data="paste not found",syntax="text"}, name:lower():match("%.([a-z]+)$")))..[[ ]] } end, ["/g/(.+)"] = function(request, name) local d = get(name, request) return d and { "200 OK", {["Content-Type"] = "text"}, d.data } or nil end, ["/p"] = function(request) if request.method == "POST" and request.post.data then - local name, paste = post({ lifetime = tonumber(request.post.lifetime) or defaultLifetime, burnOnRead = request.post.burnOnRead == "on", data = request.post.data }, request) + local name, paste = post({ lifetime = tonumber(request.post.lifetime) or defaultLifetime, burnOnRead = request.post.burnOnRead == "on", syntax = request.post.syntax, data = request.post.data }, request) return { "200 OK", {["Content-Type"] = "text/json"}, "{\"name\":\""..name.."\",\"lifetime\":"..paste.expire-os.time()..",\"burnOnRead\":"..tostring(paste.burnOnRead).."}\n" } end end