removed the crippling cocaine addiction from regexp pattern matching

This commit is contained in:
Yessiest 2023-04-19 11:30:24 +04:00
parent 6dcf46f40a
commit 3b8632f8a7
8 changed files with 110 additions and 14 deletions

63
hyde.rb
View File

@ -2,6 +2,12 @@ require 'mime-types'
require 'webrick' require 'webrick'
module Hyde module Hyde
# Branding and version
VERSION = "0.1"
attr_reader :VERSION
VLINE = "<ADDRESS>\n Hyde/#{Hyde::VERSION} on WEBrick/#{WEBrick::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n </ADDRESS>"
attr_reader :VLINE
class Server < WEBrick::HTTPServer class Server < WEBrick::HTTPServer
def initialize(config={},&setup) def initialize(config={},&setup)
super(config) super(config)
@ -11,6 +17,7 @@ module Hyde
end end
end end
end end
module ErrorPages module ErrorPages
# 404 text # 404 text
def error404(request, filepath) def error404(request, filepath)
@ -20,17 +27,18 @@ module Hyde
filepath filepath
) )
else else
request.response.body = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n<HTML>\n <HEAD><TITLE>File not found</TITLE></HEAD>\n <BODY>\n <H1>File not found</H1>\n #{filepath}\n <HR>\n <ADDRESS>\n Hyde on WEBrick/#{WEBrick::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n </ADDRESS>\n </BODY>\n</HTML>" request.response.body = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n<HTML>\n <HEAD><TITLE>File not found</TITLE></HEAD>\n <BODY>\n <H1>File not found</H1>\n #{filepath}\n <HR>\n #{Hyde::VLINE}\n </BODY>\n</HTML>"
end end
request.response["Content-Type"] = 'text/html' request.response["Content-Type"] = 'text/html'
end end
module_function :error404 module_function :error404
end end
# Interchangeable pattern matching
# Interchangeable glob/regex/string pattern matching
module PatternMatching module PatternMatching
def prep_path(path,safe_regex: true) def prep_path(path,safe_regexp: true)
raise Exception, "Not permitted" if @lock_methods raise Exception, "Not permitted" if @lock_methods
@safe_regex = safe_regex @safe_regexp = safe_regexp
@path = normalize(path) if path.kind_of? String @path = normalize(path) if path.kind_of? String
@path = path if path.kind_of? Regexp @path = path if path.kind_of? Regexp
end end
@ -40,9 +48,18 @@ module Hyde
return true if @path == "" return true if @path == ""
split_path = path.split("/").filter { |x| x != "" } split_path = path.split("/").filter { |x| x != "" }
if @path.kind_of? Regexp then if @path.kind_of? Regexp then
# "safe" as in "will not result in path matching anomalies" # this chunk of fuck is needed to force regexp into 3 rules:
return @path.match normalize_input(path) unless @safe_regex # 1) unsafe regexp means match the whole (remaining) line.
return Regexp.new("^"+@path.to_s+"$").match split_path[0] # 3) safe regexp means match only the part before the next slash
# 2) a .match? only returns when there are no leftovers
# this forces the matching to work somewhat consistently
test = @path.match normalize_input(path) unless @safe_regexp
test = @path.match split_path[0] if @safe_regexp
if test and (test.pre_match == "") and (test.post_match == "") then
return true
else
return false
end
else else
# algorithm to match path segments until no more left in @path # algorithm to match path segments until no more left in @path
@path.split("/").filter { |x| x != "" } @path.split("/").filter { |x| x != "" }
@ -91,12 +108,14 @@ module Hyde
@request = request @request = request
@response = response @response = response
@handles = {} @handles = {}
@indexlist = []
end end
attr_reader :request attr_reader :request
attr_reader :response attr_reader :response
attr_accessor :filepath attr_accessor :filepath
attr_accessor :path attr_accessor :path
attr_accessor :handles attr_accessor :handles
attr_accessor :indexlist
end end
# Context object with safe path encapsulation # Context object with safe path encapsulation
@ -111,14 +130,15 @@ module Hyde
undef :path= undef :path=
undef :filepath= undef :filepath=
undef :handles= undef :handles=
undef :indexlist=
end end
# Handler classes # Handler classes
class Probe class Probe
include Hyde::PatternMatching include Hyde::PatternMatching
include Hyde::PublicContextControlMethods include Hyde::PublicContextControlMethods
def initialize (path, safe_regex: true, &block_optional) def initialize (path, safe_regexp: true, &block_optional)
prep_path path, safe_regex: safe_regex prep_path path, safe_regexp: safe_regexp
@block = block_optional @block = block_optional
end end
def match(request) def match(request)
@ -145,7 +165,7 @@ module Hyde
request.response.body = data request.response.body = data
request.response["Content-Type"] = mimetype request.response["Content-Type"] = mimetype
rescue Errno::ENOENT rescue Errno::ENOENT
Hyde::ErrorPages::error404 filepath Hyde::ErrorPages::error404 request, request.request.path
end end
end end
end end
@ -181,8 +201,8 @@ module Hyde
class Pathspec class Pathspec
include Hyde::PatternMatching include Hyde::PatternMatching
include Hyde::Handlers include Hyde::Handlers
def initialize (path, root_path: nil, safe_regex: true, &block) def initialize (path, root_path: nil, safe_regexp: true, &block)
prep_path path, safe_regex: safe_regex prep_path path, safe_regexp: safe_regexp
@chain = [] @chain = []
@handles = {} @handles = {}
@root_override = root_path @root_override = root_path
@ -211,6 +231,9 @@ module Hyde
@lock_methods = true @lock_methods = true
@remap = true @remap = true
end end
def index(list)
@indexlist = list if list.kind_of? Array
end
def handle(code, &block) def handle(code, &block)
@handles[code] = block @handles[code] = block
end end
@ -228,13 +251,25 @@ module Hyde
else else
request.filepath = request.filepath+next_path+"/" request.filepath = request.filepath+next_path+"/"
end end
# error handle overlaying # parameter overrides overlaying
@handles.each_pair { |k,v| request.handles[k] = v } @handles.each_pair { |k,v| request.handles[k] = v }
request.indexlist = @indexlist if @indexlist
# do directory indexing
if cut_path.match /^\/?$/ then
request.indexlist.each do |x|
try_index = @chain.find { |y| y.match? x }
if try_index then
request.path = x
return try_index.match request
end
end
end
# passthrough to the next path object # passthrough to the next path object
next_pathspec = @chain.find { |x| x.match? cut_path } next_pathspec = @chain.find { |x| x.match? cut_path }
puts next_pathspec.inspect
next_pathspec.match request if next_pathspec next_pathspec.match request if next_pathspec
# throw 404 if nowhere to go
unless next_pathspec then unless next_pathspec then
# throw 404 if nowhere to go
Hyde::ErrorPages::error404 request, request.request.path Hyde::ErrorPages::error404 request, request.request.path
end end
end end

10
index.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<title> Unforseen consequences </title>
</head>
<body>
<p> Cleverly done, mister Freeman, but you are not supposed to be here </p>
<p> <b> Get back where you <a href="/index.html">belong</a> </b> </p>
</body>
</html>

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title> test </title>
</head>
<body>
<h1> This is a test </h1>
<hr>
<address> yes </address>
</body>
</html>

View File

@ -0,0 +1,7 @@
# Welcome to the INFINITE HYPERNET
---
- THE HYPE IS REAL
- SCENE IS DEAD
- BLOOD OF LAMERS IS FUEL

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title> very test </title>
</head>
<body>
<h1> This is a very test </h1>
<hr>
<address> yes 2 </address>
</body>
</html>

View File

@ -0,0 +1 @@
# YES

15
test/uploads/index.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD><TITLE>File listing</TITLE></HEAD>
<BODY>
<H1>File listing:</H1>
<ul>
<li><a href="/uploads/01-blog/test.md">this</a></li>
<li><a href="/uploads/02-rules/megafuck.md">that</a></li>
</ul>
<HR>
<ADDRESS>
welcum to this crap
</ADDRESS>
</BODY>
</HTML>

View File

@ -3,6 +3,7 @@ require_relative 'hyde'
server = Hyde::Server.new Port: 8000 do server = Hyde::Server.new Port: 8000 do
root "/home/yessiest/hyde/test/" root "/home/yessiest/hyde/test/"
serve "index.html" serve "index.html"
index ["index.html"]
path "about" do path "about" do
serve "webrick" do |ctx| serve "webrick" do |ctx|
ctx.response.body = "WEBrick is a modular http server stack" ctx.response.body = "WEBrick is a modular http server stack"
@ -13,6 +14,11 @@ server = Hyde::Server.new Port: 8000 do
ctx.response['Content-Type'] = "text/plain" ctx.response['Content-Type'] = "text/plain"
end end
end end
path "uploads" do
index ["index.html"]
serve "**/*.md", safe_regex: false
serve ["*.html","**/*.html"], safe_regex: false
end
end end
server.start server.start