-- resty-gitweb@app.lua -- Entry point for git HTTP site implementation -- Copyright (c) 2020 Joshua 'joshuas3' Stockin -- -- This software is licensed under the MIT License. local puremagic = require("puremagic") local utils = require("utils/utils") local git = require("git/git") local parse_uri = require("utils/parse_uri") local parsed_uri = parse_uri() local view local content -- TODO: Rewrite app script completely if parsed_uri.repo == nil then content = require("pages/index")(CONFIG) else -- repo found local repo for _,r in pairs(CONFIG) do if parsed_uri.repo == r.name then repo = r break end end if repo then repo.loc = repo.location.dev local success, repo_libgit2_object = git.repo.open(repo.loc) if not success then error("Failed to open repository at "..repo.loc) end repo.obj = repo_libgit2_object view = parsed_uri.parts[2] or "tree" local branch local res, status = pcall(function() -- if branch is real branch = git.find_rev(repo.obj, parsed_uri.parts[3]) -- if parts[3] is nil, defaults to "HEAD" end) if res then local res, status = pcall(function() -- effectively catch any errors, 404 if any if view == "tree" then -- directory display (with automatic README rendering) local path = parsed_uri.parts table.remove(path, 3) -- branch table.remove(path, 2) -- "tree" table.remove(path, 1) -- repo if #path > 0 then path = table.concat(path, "/").."/" else path = "" end content = require("pages/tree")(repo, repo.loc, branch, path) elseif view == "blob" then local path = parsed_uri.parts table.remove(path, 3) -- branch table.remove(path, 2) -- "tree" table.remove(path, 1) -- repo if #path > 0 then path = table.concat(path, "/") else path = "" end content = require("pages/blob")(repo, repo.loc, branch, path) elseif view == "raw" then local path = parsed_uri.parts table.remove(path, 3) -- branch table.remove(path, 2) -- "tree" table.remove(path, 1) -- repo if #path > 0 then path = table.concat(path, "/") else path = "" end content, is_binary = require("pages/raw")(repo, repo.loc, branch, path) if content then if is_binary then mimetype = puremagic.via_content(content.body, path) content.type = mimetype else content.type = "text/plain" end end elseif view == "log" then content = require("pages/log")(repo, repo.loc, branch, ngx.var.arg_n, ngx.var.arg_skip) elseif view == "refs" then content = require("pages/refs")(repo, repo.loc, branch) elseif view == "download" then content = require("pages/download")(repo, repo.loc, branch) elseif view == "commit" then -- /repo/commit/[COMMIT HASH] else error("bad view "..view) end end) -- pcall if res ~= true then if not PRODUCTION then ngx.say(res) ngx.say(status) end ngx.exit(ngx.HTTP_NOT_FOUND) return end elseif not PRODUCTION then -- branch doesn't exist, show an error in non-prod environments ngx.say(res) ngx.say(status) ngx.exit(ngx.HTTP_NOT_FOUND) end git.repo.free(repo.obj) end end if content ~= nil then -- TODO: HTML templates from files, static serving if view ~= "raw" then ngx.header.content_type = "text/html" ngx.say([[]]) ngx.say([[]]) ngx.say( [[]]) ngx.say("") if parsed_uri.repo then local arrow_left_circle = [[]] ngx.say(""..arrow_left_circle.."Index") end ngx.print(content:build()) ngx.say("") else ngx.header.content_type = content.type ngx.print(content:build()) end ngx.exit(ngx.HTTP_OK) return else ngx.exit(ngx.HTTP_NOT_FOUND) -- default behavior return end