Skip to content

Instantly share code, notes, and snippets.

@rennex
Created February 1, 2018 00:44
Show Gist options
  • Save rennex/f788645096fa29e1d27d3e9e20bccdd9 to your computer and use it in GitHub Desktop.
Save rennex/f788645096fa29e1d27d3e9e20bccdd9 to your computer and use it in GitHub Desktop.
Roda plugin to easily support (and prefer) trailing slashes in certain paths.
# frozen-string-literal: true
class Roda
module RodaPlugins
# Treats any string matchers with a trailing slash ("/") almost like
# the slash wasn't there, but GET requests to that path without the
# slash are redirected to the path with a trailing slash.
#
# Example:
#
# route do |r|
# r.is "a/" do
# "path is #{r.path}"
# end
# end
#
# # with redirect_to_slash:
# # GET /a => browser gets redirected to /a/
# # GET /a/ => browser gets the response "path is /a/"
# # POST /a => browser gets the response "path is /a"
# # POST /a/ => browser gets the response "path is /a/"
module RedirectToSlash
module RequestMethods
private
def match(str)
if String === str
# trailing slash?
if str[-1] == "/"
# try the normal matcher without the slash
return false unless _match_string(str.chop)
# let's say the matcher was "a/", we accept both "/a" and "/a/"
if @remaining_path == "/"
# consume the trailing slash from the path so that TERM can match
@remaining_path = ""
elsif @remaining_path == "" && is_get?
# but if the path ends with "/a" and it's a GET request,
# redirect to "/a/"
redirect(path + "/")
end
return true
end
# no trailing slash, call the normal matcher
_match_string(str)
else
super(str)
end
end
end
end
register_plugin(:redirect_to_slash, RedirectToSlash)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment