module Roda::RodaPlugins::HmacPaths::InstanceMethods

def hmac_path(path, opts=OPTS)

:until :: Make the given path valid until the given Time.
:seconds :: Make the given path valid for the given integer number of seconds.
the top level of the routing tree.
to the empty string, which will returns paths valid for r.hmac_path at
the already matched path of the routing tree using r.hmac_path. Defaults
:root :: Should be an empty string or string starting with +/+. This will be
limits the returned path to only be valid for that exact query string.
:params :: Includes parameters in the query string of the returned path, and
namespace when there is a default namespace, pass a nil value.
provided, the default namespace is used. To explicitly not use a
:namespace :: Make the HMAC value depend on the given namespace. If this is not
:method :: Limits the returned path to only be valid for the given request method.

valid paths. The given path should be a string starting with +/+. Options:
(directly or indirectly). This can prevent users of a site from enumerating
users can only request paths that they have been provided by the application
Return a path with an HMAC. Designed to be used with r.hmac_path, to make sure
def hmac_path(path, opts=OPTS)
  unless path.is_a?(String) && path.getbyte(0) == 47
    raise RodaError, "path must be a string starting with /"
  end
  root = opts[:root] || ''
  unless root.is_a?(String) && ((root_byte = root.getbyte(0)) == 47 || root_byte == nil)
    raise RodaError, "root must be empty string or string starting with /"
  end
  if valid_until = opts[:until]
    valid_until = valid_until.to_i
  elsif seconds = opts[:seconds]
    valid_until = Time.now.to_i + seconds
  end
  flags = String.new
  path = path.dup
  if method = opts[:method]
    flags << 'm'
  end
  if params = opts[:params]
    flags << 'p'
    path << '?' << Rack::Utils.build_query(params)
  end
  if hmac_path_namespace(opts)
    flags << 'n'
  end
  if valid_until
    flags << 't'
    path = "/#{valid_until}#{path}"
  end
  flags << '0' if flags.empty?
  
  hmac_path = if method
    "#{method.to_s.upcase}:/#{flags}#{path}"
  else
    "/#{flags}#{path}"
  end
  "#{root}/#{hmac_path_hmac(root, hmac_path, opts)}/#{flags}#{path}"
end