proof of concept

This commit is contained in:
Yessiest 2023-04-17 00:45:49 +04:00
parent f50ea11b17
commit 8593315b95
2 changed files with 86 additions and 12 deletions

72
hyde.rb
View File

@ -1,6 +1,23 @@
require 'mime-types'
require 'webrick'
module Hyde
# 404 text
def default404(filepath)
return "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">
<HTML>
<HEAD><TITLE>File not found</TITLE></HEAD>
<BODY>
<H1>File not found</H1>
#{filepath}
<HR>
<ADDRESS>
Hyde on WEBrick/#{WEBrick::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})
</ADDRESS>
</BODY>
</HTML>"
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

26
test_combined.rb Normal file
View File

@ -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