Added directory bouncing, status code handlers and pipelining
This commit is contained in:
parent
55e87603e5
commit
447f51570a
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
|
||||
require 'landline'
|
||||
|
||||
app = Landline::Server.new do
|
||||
path "/hello" do
|
||||
bounce
|
||||
get "/world" do
|
||||
"Hello world!"
|
||||
end
|
||||
end
|
||||
get "/hello/user" do
|
||||
"Hello user!"
|
||||
end
|
||||
end
|
||||
|
||||
run app
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
|
||||
require 'landline'
|
||||
|
||||
app = Landline::Server.new do
|
||||
get "/hello" do
|
||||
header "content-type", "text/plain"
|
||||
"Hello World!"
|
||||
end
|
||||
get "/error" do
|
||||
raise StandardError, "I raised an error! (and that's very sad)"
|
||||
end
|
||||
handle do |status, backtrace: nil|
|
||||
page = ([Landline::Util::HTTP_STATUS[status]] +
|
||||
(backtrace || [""])).join("\n")
|
||||
[
|
||||
{
|
||||
"content-length": page.bytesize,
|
||||
"content-type": "text/plain"
|
||||
},
|
||||
page
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
run app
|
|
@ -0,0 +1,3 @@
|
|||
#
|
||||
# ~/.bash_logout
|
||||
#
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# ~/.bash_profile
|
||||
#
|
||||
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# ~/.bashrc
|
||||
#
|
||||
|
||||
# If not running interactively, don't do anything
|
||||
[[ $- != *i* ]] && return
|
||||
|
||||
# alias ls='ls --color=auto'
|
||||
# alias grep='grep --color=auto'
|
||||
# PS1='[\u@\h \W]\$ '
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
|
||||
require 'landline'
|
||||
|
||||
app = Landline::Server.new do
|
||||
root ENV["PWD"]
|
||||
index ["index.html"]
|
||||
post "/" do
|
||||
formdata = form if form?
|
||||
files = {}
|
||||
if formdata
|
||||
formdata["form_files"].each do |file|
|
||||
filename = file.filename.split("/").last
|
||||
`mv #{file.tempfile.path} $PWD/files/#{filename}`
|
||||
files[file.filename] = "<a href=\"files/#{filename}\">#{filename}</a>"
|
||||
end
|
||||
end
|
||||
erubi(file("index.rhtml"), { formdata: files }).run
|
||||
end
|
||||
serve "/files/*"
|
||||
get "/" do
|
||||
erubi(file("index.rhtml")).run
|
||||
end
|
||||
end
|
||||
|
||||
run app
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<title>Form upload test</title>
|
||||
<style>
|
||||
.form { display: flex; flex-direction: column }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>File uploader</h1>
|
||||
<hr/>
|
||||
<p> Add files here: <p>
|
||||
<form method="post"
|
||||
class="form"
|
||||
enctype="multipart/form-data">
|
||||
<input id="form_files" type="file" name="form_files[]" multiple>
|
||||
<label for="form_files">Attach file</label>
|
||||
<input type="submit" value="Send form">
|
||||
</form>
|
||||
<% if (defined? formdata) and formdata %>
|
||||
<hr>
|
||||
<ul>
|
||||
<% formdata.each do |key, part| %>
|
||||
<li><%= key %>: <%= part %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../lib
|
|
@ -0,0 +1 @@
|
|||
Example of handling forms in Landline
|
|
@ -5,6 +5,26 @@ module Landline
|
|||
module DSL
|
||||
# Common path methods
|
||||
module PathMethods
|
||||
# Bounce request if no handler found instead of issuing 404
|
||||
def bounce
|
||||
@origin.bounce = true
|
||||
end
|
||||
|
||||
# Create a status code handler on path.
|
||||
# Recursively applies to all paths unless overridden.
|
||||
# @param [Integer, nil] Specify a status code to handle
|
||||
def handle(code = "default", &block)
|
||||
@origin.properties["handle.#{code}"] = block
|
||||
end
|
||||
|
||||
# Insert a pass-through pipeline into request processing
|
||||
# (i.e. for error handling purposes).
|
||||
# Passed block should yield request (and return yielded data back).
|
||||
# @param block [#call] block that yields request
|
||||
def pipeline(&block)
|
||||
@origin.pipeline = block
|
||||
end
|
||||
|
||||
# Set path index
|
||||
# @param index [Array,String]
|
||||
def index(index)
|
||||
|
|
|
@ -5,12 +5,16 @@ require_relative 'node'
|
|||
require_relative 'dsl/constructors_path'
|
||||
require_relative 'dsl/methods_path'
|
||||
require_relative 'dsl/methods_common'
|
||||
require_relative 'dsl/methods_probe'
|
||||
require_relative 'dsl/constructors_probe'
|
||||
require_relative 'util/lookup'
|
||||
|
||||
module Landline
|
||||
# Execution context for filters and preprocessors.
|
||||
class ProcessorContext
|
||||
include Landline::DSL::CommonMethods
|
||||
include Landline::DSL::ProbeMethods
|
||||
include Landline::DSL::ProbeConstructors
|
||||
|
||||
def initialize(path)
|
||||
@origin = path
|
||||
|
@ -54,21 +58,11 @@ module Landline
|
|||
# @return [Boolean] true if further navigation will be done
|
||||
# @raise [UncaughtThrowError] by default throws :response if no matches found.
|
||||
def process(request)
|
||||
return false unless run_filters(request)
|
||||
|
||||
run_preprocessors(request)
|
||||
enqueue_postprocessors(request)
|
||||
@children.each do |x|
|
||||
if (value = x.go(request))
|
||||
return value
|
||||
end
|
||||
if @pipeline
|
||||
@pipeline.call(request) { |inner_req| process_wrapped(inner_req) }
|
||||
else
|
||||
process_wrapped(request)
|
||||
end
|
||||
value = index(request)
|
||||
return value if value
|
||||
|
||||
_die(404)
|
||||
rescue StandardError => e
|
||||
_die(500, backtrace: [e.to_s] + e.backtrace)
|
||||
end
|
||||
|
||||
# Add a preprocessor to the path.
|
||||
|
@ -95,7 +89,9 @@ module Landline
|
|||
@filters.append(block)
|
||||
end
|
||||
|
||||
attr_reader :children, :properties
|
||||
attr_reader :children, :properties, :request
|
||||
|
||||
attr_accessor :bounce, :pipeline
|
||||
|
||||
private
|
||||
|
||||
|
@ -123,6 +119,31 @@ module Landline
|
|||
request.postprocessors.append(*@postprocessors)
|
||||
end
|
||||
|
||||
# Method callback on successful request navigation.
|
||||
# Finds the next appropriate path to go to.
|
||||
# (inner pipeline-wrapped handler)
|
||||
# @return [Boolean] true if further navigation will be done
|
||||
# @raise [UncaughtThrowError] by default throws :response if no matches found.
|
||||
def process_wrapped(request)
|
||||
@request = request
|
||||
return false unless run_filters(request)
|
||||
|
||||
run_preprocessors(request)
|
||||
enqueue_postprocessors(request)
|
||||
@children.each do |x|
|
||||
value = x.go(request)
|
||||
return value if value
|
||||
end
|
||||
value = index(request)
|
||||
return value if value
|
||||
|
||||
@bounce ? false : _die(404)
|
||||
rescue StandardError => e
|
||||
_die(500, backtrace: [e.to_s] + e.backtrace)
|
||||
ensure
|
||||
@request = nil
|
||||
end
|
||||
|
||||
# Try to perform indexing on the path if possible
|
||||
# @param request [Landline::Request]
|
||||
# @return [Boolean] true if indexing succeeded
|
||||
|
@ -146,11 +167,12 @@ module Landline
|
|||
# @raise [UncaughtThrowError] throws :finish to stop processing
|
||||
def _die(errorcode, backtrace: nil)
|
||||
throw :finish, [errorcode].append(
|
||||
*(@properties["handle.#{errorcode}"] or
|
||||
@properties["handle.default"]).call(
|
||||
errorcode,
|
||||
backtrace: backtrace
|
||||
)
|
||||
*@proccontext.instance_exec(
|
||||
errorcode,
|
||||
backtrace: backtrace,
|
||||
&(@properties["handle.#{errorcode}"] or
|
||||
@properties["handle.default"])
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,10 +15,10 @@ module Landline
|
|||
@context = Landline::ProbeContext.new(self)
|
||||
@response = nil
|
||||
end
|
||||
|
||||
|
||||
attr_accessor :response
|
||||
attr_reader :request
|
||||
|
||||
|
||||
# Method callback on successful request navigation.
|
||||
# Runs block supplied with object initialization.
|
||||
# Request's #splat and #param are passed to block.
|
||||
|
|
|
@ -88,6 +88,8 @@ module Landline
|
|||
|
||||
# Import a template from within current template
|
||||
def import(filepath)
|
||||
filepath = filepath.is_a? File ? filepath : File.open(filepath)
|
||||
# @sg-ignore
|
||||
newtemp = self.class.new(filepath, {}, parent: @parent)
|
||||
newtemp.binding = @binding
|
||||
newtemp
|
||||
|
|
Loading…
Reference in New Issue