proof of concept
This commit is contained in:
parent
f50ea11b17
commit
8593315b95
66
hyde.rb
66
hyde.rb
|
@ -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
|
||||
begin
|
||||
mimetype = MIME::Types.type_for(filepath)
|
||||
file = File.new filepath, "r"
|
||||
data = file.read()
|
||||
# TODO: Finish this
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue