diff --git a/hyde.rb b/hyde.rb
index f09478f..046ab50 100644
--- a/hyde.rb
+++ b/hyde.rb
@@ -1,6 +1,23 @@
require 'mime-types'
+require 'webrick'
module Hyde
+ # 404 text
+ def default404(filepath)
+ return "
+
+
File not found
+
+ File not found
+ #{filepath}
+
+
+ Hyde on WEBrick/#{WEBrick::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})
+
+
+ "
+ end
+ module_function :default404
# Interchangeable pattern matching
module PatternMatching
def prep_path(path,safe_regex: true)
@@ -47,50 +64,54 @@ module Hyde
end
# Methods to control requests, accessible from within blocks
- module PublicRequestControlMethods
+ module PublicContextControlMethods
def redirect(url)
puts "Unimplemented method 'redirect' called"
return
end
end
- # Request control class
- class Request
+ # Request wrapper class
+ class Context
def initialize(path,request,response)
@path = path
@filepath = ""
@request = request
@response = response
+ @handles = {}
end
attr_reader :request
attr_reader :response
attr_accessor :filepath
attr_accessor :path
+ attr_accessor :handles
end
- # Request object with safe path encapsulation
- class ProtectedRequest < Request
+ # Context object with safe path encapsulation
+ class ProtectedContext < Context
def initialize(request)
@path = request.path
@filepath = request.filepath
@request = request.request
@response = request.response
+ @handles = request.handles
end
undef :path=
undef :filepath=
+ undef :handles=
end
# Handler classes
class Probe
include Hyde::PatternMatching
- include Hyde::PublicRequestControlMethods
+ include Hyde::PublicContextControlMethods
def initialize (path, safe_regex: true, &block_optional)
prep_path path, safe_regex: safe_regex
@block = block_optional
end
def match(request)
if @block and (match? request.path) then
- @current_request = Hyde::ProtectedRequest.new(request)
+ @current_request = Hyde::ProtectedContext.new(request)
@lock_methods = true
return_later = self.instance_exec @current_request, &@block
@lock_methods = false
@@ -105,10 +126,21 @@ module Hyde
if match? request.path then
match_path = normalize_input(request.path).match(@path)[0]
filepath = request.filepath+match_path
- mimetype = MIME::Types.type_for(filepath)
- file = File.new filepath, "r"
- data = file.read()
- # TODO: Finish this
+ begin
+ mimetype = MIME::Types.type_for(filepath)
+ file = File.new filepath, "r"
+ data = file.read()
+ request.response.body = data
+ request.response["Content-Type"] = mimetype
+ rescue Errno::ENOENT
+ if request.handles.include? 404 then
+ request.response.body = request.handles[404].call filepath
+ request.response["Content-Type"] = "text/html"
+ else
+ request.response.body = Hyde::default404 filepath
+ end
+ end
+ end
end
end
@@ -124,7 +156,8 @@ module Hyde
module Handlers
{
probe: Hyde::Probe,
- printProbe: Hyde::PrintProbe
+ printProbe: Hyde::PrintProbe,
+ serve: Hyde::Serve
}.each_pair { |name, newclass|
define_method name do |path, *a, **b, &block|
if path.kind_of? Array then
@@ -144,6 +177,7 @@ module Hyde
def initialize (path, root_path: nil, safe_regex: true, &block)
prep_path path, safe_regex: safe_regex
@chain = []
+ @handles = {}
@root_override = root_path
@remap = false
@lock_methods = true
@@ -170,6 +204,9 @@ module Hyde
@lock_methods = true
@remap = true
end
+ def handle(code, &block)
+ @handles[code] = block
+ end
def match(request)
raise Exception, "Not permitted" if @lock_methods
if match? request.path then
@@ -183,8 +220,19 @@ module Hyde
else
request.filepath = request.filepath+next_path+"/"
end
+ @handles.each_pair { |k,v| request.handles[k] = v }
next_pathspec = @chain.find { |x| x.match? cut_path }
next_pathspec.match request if next_pathspec
+ unless next_pathspec then
+ if request.handles.include? 404
+ request.response.body = request.handles[404].call(
+ request.filepath+"/"+cut_path
+ )
+ else
+ request.response.body = Hyde::default404(request.filepath+cut_path)
+ end
+ request.response["Content-Type"] = 'text/html'
+ end
end
end
end
diff --git a/test_combined.rb b/test_combined.rb
new file mode 100644
index 0000000..04bab29
--- /dev/null
+++ b/test_combined.rb
@@ -0,0 +1,26 @@
+require 'webrick'
+require_relative 'hyde'
+
+server = WEBrick::HTTPServer.new :Port => 8000
+trap 'INT' do server.shutdown end
+server.mount_proc '/' do |req,res|
+ Hyde::Pathspec.new '/' do
+ serve "index.html" do |ctx|
+ ctx.response.body = "This is a test of webrick+hyde combination
+If you're seeing this, this means it's a success"
+ ctx.response["Content-Type"] = "text/plain"
+ end
+ path "about" do
+ serve "webrick" do |ctx|
+ ctx.response.body = "WEBrick is weird and pretty undocumented"
+ ctx.response["Content-Type"] = "text/plain"
+ end
+ serve "hyde" do |ctx|
+ ctx.response.body = "Hyde was born because i thought Sinatra is cool, but nested paths are even cooler"
+ ctx.response["Content-Type"] = "text/plain"
+ end
+ end
+ end.match(Hyde::Context.new(req.path, req, res))
+end
+server.start
+