Skip to content

Instantly share code, notes, and snippets.

@fnordfish
Last active January 14, 2022 11:11
Show Gist options
  • Save fnordfish/9b5f98dab60254e3ef60a624019fe69e to your computer and use it in GitHub Desktop.
Save fnordfish/9b5f98dab60254e3ef60a624019fe69e to your computer and use it in GitHub Desktop.
Dead simple static file server using Ruby Rack, implementing Apaches RewriteMap feature using a plain-text mapping file.
# frozen_string_literal: true
# Dead simple static file server using Ruby Rack implementing
# Apaches RewriteMap feature using a plain-text mapping file.
# See: https://httpd.apache.org/docs/current/rewrite/rewritemap.html#txt
#
# Deliberately does not use any caching, so keep the size of your redirects.txt
# in mind.
#
# Usage:
# $ cat /var/www/redirects.txt
# /foo/old%20path /foo/new-path/
#
# $ RACK_ROOT=/var/www rackup config.ru
# $stdout.sync = true
PUBLIC_ROOT = ENV["RACK_ROOT"]
REDIRECTS_FILE = File.join(PUBLIC_ROOT, "redirects.txt")
INDEX = "index.html"
INDEX_PATH_SUFFIX = "/#{INDEX}".freeze
use Rack::CommonLogger
use Rack::Static, urls: [""], root: PUBLIC_ROOT, index: INDEX, cascade: true
run ->(env) do
path_info = env["PATH_INFO"].delete_suffix(INDEX_PATH_SUFFIX)
query_string = env["QUERY_STRING"]
requested_url = "#{path_info}#{"?#{query_string}" unless query_string.empty?}"
requested_slash_url = "#{File.join(path_info, '/')}#{"?#{query_string}" unless query_string.empty?}"
redirect = nil
File.open(REDIRECTS_FILE).each_line(chomp: true) { |line|
orig, mapped = line.split(" ", 2)
next unless [requested_url, requested_slash_url, path_info].include?(orig)
redirect = mapped
redirect << "?#{query_string}" if !query_string.empty? && !orig.include?("?")
break
}
if redirect
[301, { "Location" => redirect }, [""]]
elsif File.directory?(File.join(PUBLIC_ROOT, path_info))
[301, { "Location" => requested_slash_url }, [""]]
else
[404, {}, ["Not Found"]]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment