Compare commits

...

2 Commits

11 changed files with 70 additions and 23 deletions

View File

@ -13,9 +13,9 @@ app = Hyde::Server.new do
postprocess do |request, response| postprocess do |request, response|
puts "Request: #{request}, response: #{response}" puts "Request: #{request}, response: #{response}"
end end
index ["index"] index ["index.html"]
root "#{ENV['PWD']}/assets" root "#{ENV['PWD']}/assets"
serve "*.(html|css|js)" serve "/**/*.(html|css|js)"
get "/wormhole/:test/*" do |suffix, test: nil| get "/wormhole/:test/*" do |suffix, test: nil|
<<~RESPONSE <<~RESPONSE
You tried accessing #{suffix} at named param #{test} You tried accessing #{suffix} at named param #{test}

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title> Cleverly done, mr. freeman </title>
</head>
<body>
<h1>Cleverly done, mr. freeman</h1>
<hr/>
<p>But you are not supposed to be here</p>
<p><b>Get back where you belong.</b></p>
</body>
</html>

View File

@ -21,16 +21,13 @@ module Hyde
# Set root path (appends matched part of the path). # Set root path (appends matched part of the path).
# @param path [String # @param path [String
def root(path) def root(path)
raise StandardError, "path should be a String" unless path.is_a? String
@origin.root = path @origin.root = path
end end
# Set root path (without appending matched part). # Set root path (without appending matched part).
# @param path [String # @param path [String
def remap(path) def remap(path)
root(path) @origin.remap = path
@origin.remap = true
end end
# Add a preprocessor to the path. # Add a preprocessor to the path.

View File

@ -9,12 +9,29 @@ module Hyde
# @abstract # @abstract
class Node class Node
# @param path [Object] # @param path [Object]
def initialize(path) def initialize(path, parent:)
@pattern = Pattern.new(path).freeze @pattern = Pattern.new(path).freeze
@properties = Hyde::Util::Lookup.new(parent&.properties)
@root = nil @root = nil
@remap = false @remap = false
end end
# Set Node file root (like root in Nginx)
# @param path [String]
def root=(path)
raise StandardError, "path should be a String" unless path.is_a? String
@properties["path"] = File.expand_path(path)
@root = File.expand_path(path)
end
# Set Node absolute file path (like alias in Nginx)
# @param path [String]
def remap=(path)
self.root = path
@remap = true
end
# Try to navigate the path. Run method callback in response. # Try to navigate the path. Run method callback in response.
# @param [Hyde::Request] # @param [Hyde::Request]
# @return [Boolean] # @return [Boolean]
@ -49,7 +66,7 @@ module Hyde
true true
end end
attr_accessor :remap, :root attr_reader :remap, :root
private private

View File

@ -25,11 +25,9 @@ module Hyde
# @param parent [Hyde::Node] Parent object to inherit properties to # @param parent [Hyde::Node] Parent object to inherit properties to
# @param setup [#call] Setup block # @param setup [#call] Setup block
def initialize(path, parent:, &setup) def initialize(path, parent:, &setup)
super(path) super(path, parent: parent)
# Child nodes array # Child nodes array
@children = [] @children = []
# Inherited properties array
@properties = Hyde::Util::Lookup.new(parent&.properties)
# Arrays of preprocessors, postprocessors and filters # Arrays of preprocessors, postprocessors and filters
@preprocessors = [] @preprocessors = []
@postprocessors = [] @postprocessors = []

View File

@ -100,11 +100,12 @@ module Hyde
private private
# i shall name thee Norxondor Glorbulon
# Regexp pattern to match glob tokens # Regexp pattern to match glob tokens
TOKENS = / TOKENS = /
( # Glob-specific tokens ( # Glob-specific tokens
\/\*\*\/ | # Freestanding globstar (?<=(?:\/|^))\*\*(?:\/|$) | # Freestanding globstar
\*\* | # Attached globstar
\* | # Regular glob \* | # Regular glob
\[!?\w-\w\]\+ | # Character group \[!?\w-\w\]\+ | # Character group
(?<=\/):[\w_]+(?=(?:\/|$)) | # Named glob (?<=\/):[\w_]+(?=(?:\/|$)) | # Named glob
@ -153,8 +154,7 @@ module Hyde
def build_regexp(tokens) def build_regexp(tokens)
Regexp.new(tokens.map do |filter| Regexp.new(tokens.map do |filter|
case filter case filter
when "/**/" then "/(?:(.*)\/|)" # FIXME: this may return nil when /(\/|^)\*\*(\/|$)/ then "(?:(.*)/|)" # FIXME: this may return nil
when "**" then "(.*)"
when "*" then "([^/]*)" when "*" then "([^/]*)"
when /^\([\w\/|_-]+\)$/ then filter.sub('-', '\\-') when /^\([\w\/|_-]+\)$/ then filter.sub('-', '\\-')
when /^\[!?\w-\w\]\+$/ then filter.sub('!', '^') when /^\[!?\w-\w\]\+$/ then filter.sub('!', '^')

View File

@ -21,8 +21,7 @@ module Hyde
# @param path [Object] # @param path [Object]
# @param parent [Hyde::Node] # @param parent [Hyde::Node]
def initialize(path, parent:) def initialize(path, parent:)
super(path) super(path, parent: parent)
@properties = Hyde::Util::Lookup.new(parent&.properties)
end end
attr_reader :properties attr_reader :properties

View File

@ -20,7 +20,10 @@ module Hyde
# @param request [Hyde::Request] # @param request [Hyde::Request]
# @return [Boolean] true if file was found # @return [Boolean] true if file was found
def process(request) def process(request)
File.open(request.filepath.delete_suffix("/")) path = File.expand_path(request.filepath)
return unless path.start_with? @properties["path"]
File.open(path.delete_suffix("/"))
rescue StandardError rescue StandardError
false false
end end

View File

@ -15,7 +15,7 @@ module Hyde
@param = {} @param = {}
@splat = [] @splat = []
# Traversal route. Public and writable. # Traversal route. Public and writable.
@path = env["PATH_INFO"].dup @path = URI.decode_www_form_component(env["PATH_INFO"].dup)
# File serving path. Public and writable. # File serving path. Public and writable.
@filepath = "/" @filepath = "/"
# Encapsulates all rack variables. Should not be public. # Encapsulates all rack variables. Should not be public.

View File

@ -28,10 +28,9 @@ module Hyde
"content-type": "text/html" "content-type": "text/html"
} }
[headers, page] [headers, page]
end end,
}.each do |k, v| "path" => "/"
@properties[k] = v unless @properties[k] }.each { |k, v| @properties[k] = v unless @properties[k] }
end
end end
# Rack ingress point. # Rack ingress point.

View File

@ -69,6 +69,27 @@ class TestGlob < Test::Unit::TestCase
puts("Testing: #{test}") puts("Testing: #{test}")
assert_equal(result, unit.match?(test)) assert_equal(result, unit.match?(test))
end end
unit = Glob.new("**/*.php")
[
"archive.php", true,
"assets/thing.js", false,
"assetsthing.js", false,
"parts/thing.php", true,
"partsthing.php", true,
".php", true,
"parts/extra/test.php", true,
"archive.php", true,
"assets/thing.js", false,
"assetsthing.js", false,
"parts/thing.php", true,
"partsthing.php", true,
".php", true,
"parts/extra/test.php", true,
"parts/extra/test.php/literally/anything/here", true
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
puts "Test group: char ranges" puts "Test group: char ranges"
unit = Glob.new("/test/[9-z]+") unit = Glob.new("/test/[9-z]+")
[ [