From 8593315b95fb439c3b7ddf8ad4cffc5f2bd28566 Mon Sep 17 00:00:00 2001 From: Yessiest Date: Mon, 17 Apr 2023 00:45:49 +0400 Subject: [PATCH] proof of concept --- hyde.rb | 72 ++++++++++++++++++++++++++++++++++++++++-------- test_combined.rb | 26 +++++++++++++++++ 2 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 test_combined.rb 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 +