landline 0.10.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@
3
3
  require 'uri'
4
4
  require_relative 'util/query'
5
5
  require_relative 'util/cookie'
6
+ require_relative 'sandbox'
6
7
 
7
8
  module Landline
8
9
  # Request wrapper for Rack protocol
@@ -21,32 +22,38 @@ module Landline
21
22
  @param = {}
22
23
  @splat = []
23
24
  # Traversal route. Public and writable.
24
- @path = URI.decode_www_form_component(env["PATH_INFO"].dup)
25
+ @path = URI.decode_www_form_component(env["PATH_INFO"])
25
26
  # File serving path. Public and writable.
26
27
  @filepath = "/"
27
- # Encapsulates all rack variables. Should not be public.
28
+ # Encapsulates all rack variables. Is no longer private, but usually should not be used directly
28
29
  @rack = init_rack_vars(env)
29
30
  # Internal navigation states. Private.
30
31
  @states = []
31
32
  # Postprocessors for current request
32
33
  @postprocessors = []
34
+ # Execution context
35
+ @context = init_context
33
36
  end
34
37
 
35
38
  # Run postprocessors
36
39
  # @param response [Landline::Response]
37
40
  def run_postprocessors(response)
38
- @postprocessors.each do |postproc|
39
- postproc.call(self, response)
41
+ @context.origin.properties.lookup = {}
42
+ @postprocessors.reverse_each do |postproc|
43
+ @context.instance_exec(self, response, &postproc)
40
44
  end
45
+ @postprocessors = []
41
46
  end
42
47
 
43
48
  # Returns request body (if POST data exists)
49
+ # @note reads data from rack.input, which is not rewindable. .body data is memoized.
44
50
  # @return [nil, String]
45
51
  def body
46
52
  @body ||= @rack.input&.read
47
53
  end
48
54
 
49
55
  # Returns raw Rack input object
56
+ # @note Rack IO is not always rewindable - if it is read once, the data is gone (i.e. request.body will return nothing).
50
57
  # @return [IO] (May not entirely be compatible with IO, see Rack/SPEC.rdoc)
51
58
  def input
52
59
  @rack.input
@@ -62,13 +69,42 @@ module Landline
62
69
  @path, @param, @splat, @filepath = @states.pop
63
70
  end
64
71
 
72
+ # Checks if response stream can be partially hijacked
73
+ def hijack?
74
+ @_original_env['rack.hijack?']
75
+ end
76
+
77
+ # Returns full hijack callback
78
+ def hijack
79
+ @_original_env['rack.hijack']
80
+ end
81
+
82
+ # Reconstructs rack env after modification
83
+ def env
84
+ path = @path
85
+ @_original_env.merge(reconstruct_headers)
86
+ .merge({
87
+ 'PATH_INFO' => path,
88
+ 'REQUEST_PATH' => path,
89
+ 'QUERY_STRING' => query.query,
90
+ 'REQUEST_URI' => "#{path}?#{query.query}"
91
+ })
92
+ .merge(reconstruct_cookie)
93
+ end
94
+
65
95
  attr_reader :request_method, :script_name, :path_info, :server_name,
66
96
  :server_port, :server_protocol, :headers, :param, :splat,
67
- :postprocessors, :query, :cookies
68
- attr_accessor :path, :filepath
97
+ :postprocessors, :cookies, :rack, :context
98
+ attr_accessor :path, :filepath, :query
69
99
 
70
100
  private
71
101
 
102
+ # Initialize execution context
103
+ def init_context
104
+ origin = Landline::ProcessorOrigin.new(self, {})
105
+ Landline::ProcessorContext.new(origin)
106
+ end
107
+
72
108
  # Initialize basic rack request parameters
73
109
  # @param env [Hash]
74
110
  def init_request_params(env)
@@ -117,7 +153,7 @@ module Landline
117
153
  .freeze
118
154
  end
119
155
 
120
- # Iniitalize headers hash
156
+ # Initialize headers hash
121
157
  # @param env [Hash]
122
158
  # @return Hash
123
159
  def init_headers(env)
@@ -131,5 +167,30 @@ module Landline
131
167
  x.downcase.gsub("_", "-") if x.is_a? String
132
168
  end.freeze
133
169
  end
170
+
171
+ # Reconstruct headers
172
+ def reconstruct_headers
173
+ @headers.filter_map do |k, v|
174
+ next unless v
175
+
176
+ if !['content-type', 'content-length',
177
+ 'remote-addr'].include?(k) && (k.is_a? String)
178
+ k = "http_#{k}"
179
+ end
180
+ k = k.upcase.gsub("-", "_")
181
+ [k, v]
182
+ end.to_h
183
+ end
184
+
185
+ # Reconstruct cookie string
186
+ def reconstruct_cookie
187
+ return {} if @cookies.empty?
188
+
189
+ {
190
+ "HTTP_COOKIE" => @cookies.map do |_, v|
191
+ v.finalize_short
192
+ end.join(";")
193
+ }
194
+ end
134
195
  end
135
196
  end
@@ -96,7 +96,7 @@ module Landline
96
96
  end
97
97
  end
98
98
 
99
- attr_accessor :status, :headers, :body
99
+ attr_accessor :status, :headers, :body, :cookies
100
100
 
101
101
  # Ensure response correctness
102
102
  # @param obj [String, Array, Landline::Response]
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dsl/methods_common'
4
+ require_relative 'dsl/methods_probe'
5
+ require_relative 'dsl/constructors_probe'
6
+ require_relative 'util/lookup'
7
+
8
+ module Landline
9
+ # Execution context for filters and preprocessors.
10
+ class ProcessorContext
11
+ include Landline::DSL::CommonMethods
12
+ include Landline::DSL::ProbeMethods
13
+ include Landline::DSL::ProbeConstructors
14
+
15
+ def initialize(path)
16
+ @origin = path
17
+ end
18
+
19
+ attr_reader :origin
20
+ end
21
+
22
+ # Ephemeral proxy class to which callback execution binds
23
+ class ProcessorOrigin
24
+ def initialize(request, properties)
25
+ @request = request
26
+ @properties = Landline::Util::LookupROProxy.new(properties)
27
+ end
28
+
29
+ attr_accessor :response
30
+ attr_reader :request, :properties
31
+ end
32
+ end
@@ -11,39 +11,64 @@ module Landline
11
11
  # A specialized path that can be used directly as a Rack application.
12
12
  class Server < Landline::Path
13
13
  Context = ServerContext
14
-
15
14
  # @param parent [Landline::Node, nil] Parent object to inherit properties to
16
15
  # @param setup [#call] Setup block
17
- def initialize(parent: nil, **args, &setup)
18
- super("", parent: nil, **args, &setup)
16
+ def initialize(passthrough = nil, parent: nil, **opts, &setup)
17
+ super("", parent: parent, **opts, &setup)
19
18
  return if parent
20
19
 
20
+ @passthrough = passthrough
21
+ setup_properties(parent: nil, **opts)
22
+ end
23
+
24
+ # Rack ingress point.
25
+ # @param env [Hash]
26
+ # @return [Array(Integer,Hash,Array)]
27
+ def call(env)
28
+ request = Landline::Request.new(env)
29
+
30
+ response = handle_jumps(request)
31
+ request.run_postprocessors(response)
32
+ resp = response.finalize
33
+ if resp[1][:"x-cascade"] and resp[0] == 404 and @passthrough
34
+ @passthrough.call(request.env)
35
+ else
36
+ resp
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # Catch internal jumps
43
+ def handle_jumps(request)
44
+ response = Response.convert(catch(:finish) do
45
+ go(request)
46
+ end)
47
+ while response and
48
+ response.status == 307 and
49
+ response.headers.include? :"x-internal-jump"
50
+ response = Response.convert(catch(:finish) do
51
+ go(request)
52
+ end)
53
+ end
54
+ response
55
+ end
56
+
57
+ # Inititalization block for property setup
58
+ def setup_properties(*_args, **_opts)
21
59
  {
22
60
  "index" => [],
23
61
  "handle.default" => proc do |code, backtrace: nil|
24
62
  page = Landline::Util.default_error_page(code, backtrace)
25
63
  headers = {
26
64
  "content-length": page.bytesize,
27
- "content-type": "text/html"
65
+ "content-type": "text/html",
66
+ "x-cascade": true
28
67
  }
29
68
  [headers, page]
30
69
  end,
31
70
  "path" => "/"
32
71
  }.each { |k, v| @properties[k] = v unless @properties[k] }
33
72
  end
34
-
35
- # Rack ingress point.
36
- # This should not be called under any circumstances twice in the same application,
37
- # although server nesting for the purpose of creating virtual hosts is allowed.
38
- # @param env [Hash]
39
- # @return [Array(Integer,Hash,Array)]
40
- def call(env)
41
- request = Landline::Request.new(env)
42
- response = catch(:finish) do
43
- go(request)
44
- end
45
- request.run_postprocessors(response)
46
- Response.convert(response).finalize
47
- end
48
73
  end
49
74
  end
@@ -4,9 +4,16 @@ require_relative 'parseutils'
4
4
  require_relative 'errors'
5
5
  require 'date'
6
6
  require 'openssl'
7
+ require 'base64'
7
8
  HeaderRegexp = Landline::Util::HeaderRegexp
8
9
  ParserCommon = Landline::Util::ParserCommon
9
10
 
11
+ if RUBY_ENGINE == 'jruby' # fix for JRuby
12
+ OpenSSL::HMAC.define_singleton_method(:base64digest) do |*args|
13
+ Base64.strict_encode64(OpenSSL::HMAC.digest(*args)).strip
14
+ end
15
+ end
16
+
10
17
  module Landline
11
18
  # Utility class for handling cookies
12
19
  class Cookie
@@ -22,11 +29,11 @@ module Landline
22
29
  # @option params [String, Date] "expires"
23
30
  # @raise Landline::ParsingError invalid cookie parameters
24
31
  def initialize(key, value, params = {})
25
- unless key.match? HeaderRegexp::COOKIE_NAME
32
+ unless key.match?(/\A#{HeaderRegexp::COOKIE_NAME}\z/o)
26
33
  raise Landline::ParsingError, "invalid cookie key: #{key}"
27
34
  end
28
35
 
29
- unless value.match? HeaderRegexp::COOKIE_VALUE
36
+ unless value.match?(/\A#{HeaderRegexp::COOKIE_VALUE}\z/o)
30
37
  raise Landline::ParsingError, "invalid cookie value: #{value}"
31
38
  end
32
39
 
@@ -81,7 +88,7 @@ module Landline
81
88
  # @param sep [String] Hash separator
82
89
  # @return [Boolean] whether value is signed and valid
83
90
  def verify(key, algorithm: "sha256", sep: "&")
84
- val, sig = @value.match(/\A(.*)#{sep}([A-Za-z0-9+\/=]+)\Z/).to_a[1..]
91
+ val, sig = @value.match(/\A(.*)#{sep}([A-Za-z0-9+\/=]+)\z/).to_a[1..]
85
92
  return false unless val and sig
86
93
 
87
94
  sig == ::OpenSSL::HMAC.base64digest(algorithm, key, val)
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+ require 'json'
5
+ require 'base64'
6
+
7
+ if RUBY_ENGINE == 'jruby' # fix for JRuby
8
+ OpenSSL::HMAC.define_singleton_method(:base64digest) do |*args|
9
+ Base64.strict_encode64(OpenSSL::HMAC.digest(*args)).strip
10
+ end
11
+ end
12
+
13
+ module Landline
14
+ module Util
15
+ # JSON Web Token construction class
16
+ class JWT
17
+ ALGO = {
18
+ "HS256" => proc do |data, secret|
19
+ Base64.urlsafe_encode64(
20
+ OpenSSL::HMAC.digest("SHA256", secret, data)
21
+ ).gsub('=', '')
22
+ end,
23
+ "HS384" => proc do |data, secret|
24
+ Base64.urlsafe_encode64(
25
+ OpenSSL::HMAC.digest("SHA384", secret, data)
26
+ ).gsub('=', '')
27
+ end,
28
+ "HS512" => proc do |data, secret|
29
+ Base64.urlsafe_encode64(
30
+ OpenSSL::HMAC.digest("SHA512", secret, data)
31
+ ).gsub('=', '')
32
+ end
33
+ }.freeze
34
+
35
+ # Create a new JWT token wrapper
36
+ # @param data [Hash, Array] JSON-formattable data
37
+ # @param halgo [String] Name of the hash algorithm to use
38
+ def initialize(data, halgo = "HS256")
39
+ unless ALGO.include? halgo
40
+ raise StandardError, "hash algorithm #{halgo} not supported"
41
+ end
42
+
43
+ @halgo = halgo
44
+ @data = data
45
+ end
46
+
47
+ # Construct a string representation of the current token
48
+ # @param key [String]
49
+ # @return [String]
50
+ def make(key)
51
+ jsonheader = {
52
+ "alg": @halgo,
53
+ "typ": "JWT"
54
+ }.to_json
55
+ jsondata = @data.to_json
56
+ data = "#{base64(jsonheader)}.#{base64(jsondata)}"
57
+ "#{data}.#{ALGO[@halgo].call(data, key)}"
58
+ end
59
+
60
+ # Construct an object from string
61
+ # @param input [String]
62
+ # @param key [String]
63
+ # @return [JWT, nil] returns nil if verification couldn't complete
64
+ def self.from_string(input, key)
65
+ halgoj, dataj, sig = input.split(".")
66
+ halgo = JSON.parse(Base64.urlsafe_decode64(halgoj))["alg"]
67
+ return nil unless ALGO.include? halgo
68
+ return nil if ALGO[halgo].call("#{halgoj}.#{dataj}", key) != sig
69
+
70
+ new(JSON.parse(Base64.urlsafe_decode64(dataj)), halgo)
71
+ end
72
+
73
+ attr_accessor :data
74
+
75
+ private
76
+
77
+ def base64(data)
78
+ Base64.urlsafe_encode64(data).gsub("=", "")
79
+ end
80
+ end
81
+ end
82
+ end
@@ -33,5 +33,21 @@ module Landline
33
33
 
34
34
  attr_accessor :parent
35
35
  end
36
+
37
+ # Read-only lookup proxy
38
+ class LookupROProxy
39
+ def initialize(lookup)
40
+ @lookup = lookup
41
+ end
42
+
43
+ # Get a value by key
44
+ # @param key [#hash] key for value
45
+ # @return [Object,nil]
46
+ def [](key)
47
+ @lookup.[](key)
48
+ end
49
+
50
+ attr_accessor :lookup
51
+ end
36
52
  end
37
53
  end
@@ -1267,6 +1267,7 @@ module Landline
1267
1267
  }.freeze
1268
1268
 
1269
1269
  # Get MIME type by file extension
1270
+ # @note This function does no checks on the file - simply renaming the file to a different extension will yield an invalid result. Do not use this to check uploaded files - preferably, use libmagic or proper mime type tools for Ruby.
1270
1271
  # @param file [String] filename
1271
1272
  # @return [String] MIME type, defaults to "application/octet-stream"
1272
1273
  def self.get_mime_type(file)
@@ -8,28 +8,28 @@ module Landline
8
8
  # (not exactly precise) Regular expressions for some RFC definitions
9
9
  module HeaderRegexp
10
10
  # Matches the RFC2616 definiton of token
11
- TOKEN = /[!-~&&[^()<>@,;:\\"\/\[\]?={}\t]]+/.freeze
11
+ TOKEN = /[!-~&&[^()<>@,;:\\"\/\[\]?={}\t]]+/
12
12
  # Matches the RFC2616 definition of quoted-string
13
- QUOTED = /"[\x0-\x7E&&[^\x1-\x8\xb-\x1f]]*(?<!\\)"/.freeze
13
+ QUOTED = /"[\x0-\x7E&&[^\x1-\x8\xb-\x1f]]*(?<!\\)"/
14
14
  # Matches any CHAR except CTLs
15
- PRINTCHAR = /[\x2-\x7E]/.freeze
15
+ PRINTCHAR = /[\x2-\x7E]/
16
16
  # Matches 1 or more CHARs excluding CTLs
17
- PRINTABLE = /#{PRINTCHAR}+/o.freeze
17
+ PRINTABLE = /#{PRINTCHAR}+/o
18
18
  # Matches the RFC6265 definition of a cookie-octet
19
- COOKIE_OCTET = /[\x21-\x7E&&[^",;\\]]*/.freeze
20
- COOKIE_VALUE = /(?:#{QUOTED}|#{COOKIE_OCTET})/o.freeze
19
+ COOKIE_OCTET = /[\x21-\x7E&&[^",;\\]]*/
20
+ COOKIE_VALUE = /(?:#{QUOTED}|#{COOKIE_OCTET})/o
21
21
  COOKIE_NAME = TOKEN
22
22
  # Matches the RFC6265 definition of cookie-pair.
23
23
  # Captures name (1) and value (2).
24
- COOKIE_PAIR = /\A(#{COOKIE_NAME})=(#{COOKIE_VALUE})\Z/o.freeze
24
+ COOKIE_PAIR = /\A(#{COOKIE_NAME})=(#{COOKIE_VALUE})\z/o
25
25
  # Matches a very abstract definition of a quoted header paramter.
26
26
  # Captures name (1) and value (2).
27
- PARAM_QUOTED = /\A(#{TOKEN})=?(#{QUOTED}|#{PRINTCHAR}*)\Z/o.freeze
27
+ PARAM_QUOTED = /\A(#{TOKEN})=?(#{QUOTED}|#{PRINTCHAR}*)\z/o
28
28
  # Matches a very abstract definition of a header parameter.
29
29
  # Captures name (1) and value (2).
30
- PARAM = /\A(#{TOKEN})=?(#{PRINTCHAR}*)\Z/o.freeze
30
+ PARAM = /\A(#{TOKEN})=?(#{PRINTCHAR}*)\z/o
31
31
  # Specifically matches cookie parameters
32
- COOKIE_PARAM = /\A(#{TOKEN})=?(#{QUOTED}|#{COOKIE_OCTET})\Z/o.freeze
32
+ COOKIE_PARAM = /\A(#{TOKEN})=?(#{QUOTED}|#{COOKIE_OCTET})\z/o
33
33
  end
34
34
 
35
35
  # Module for all things related to parsing HTTP and related syntax.
@@ -48,7 +48,9 @@ module Landline
48
48
  # @param regexp [Regexp,nil] override param matching regexp
49
49
  # @return [Array(String, Hash)]
50
50
  def self.parse_value(input, sep: ";", unquote: false, regexp: nil)
51
- parts = input.split(sep).map { |x| URI.decode_uri_component(x).strip }
51
+ parts = input.split(sep).map do |x|
52
+ URI.decode_www_form_component(x).strip
53
+ end
52
54
  base = parts.shift
53
55
  opts = parts.map do |raw|
54
56
  key, value = raw.match(if regexp
@@ -8,6 +8,8 @@ module Landline
8
8
  # Query string parser
9
9
  class Query
10
10
  include Landline::Util::ParserSorting
11
+ attr_reader :query
12
+
11
13
  # @param query [String]
12
14
  def initialize(query)
13
15
  @query = query
data/lib/landline.rb CHANGED
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'landline/util/jwt'
3
4
  require_relative 'landline/server'
4
5
  require_relative 'landline/path'
5
6
  require_relative 'landline/probe'
6
7
  require_relative 'landline/request'
7
8
  require_relative 'landline/response'
8
9
  require_relative 'landline/template'
10
+ require_relative 'landline/app'
9
11
 
10
- # Landline is a hideously simple ruby web framework
12
+ # Landline is a backend framework born as a by-product of experimentation
11
13
  module Landline
12
14
  # Landline version
13
- VERSION = '0.10 "Node graph out of date. Rebuilding..." (beta)'
15
+ VERSION = '0.12.1 "Concrete and Gold" (pre-alpha)'
14
16
 
15
17
  # Landline branding and version
16
18
  VLINE = "Landline/#{Landline::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n".freeze
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: landline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yessiest
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-21 00:00:00.000000000 Z
11
+ date: 2024-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Landline is a no-hard-dependencies HTTP routing DSL that was made entirely for fun.
@@ -19,21 +19,22 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files:
21
21
  - HACKING.md
22
- - LAYOUT.md
23
22
  - LICENSE.md
24
23
  - README.md
25
24
  files:
26
25
  - HACKING.md
27
- - LAYOUT.md
28
26
  - LICENSE.md
29
27
  - README.md
30
28
  - lib/landline.rb
29
+ - lib/landline/app.rb
31
30
  - lib/landline/dsl/constructors_path.rb
32
31
  - lib/landline/dsl/constructors_probe.rb
33
32
  - lib/landline/dsl/methods_common.rb
34
33
  - lib/landline/dsl/methods_path.rb
35
34
  - lib/landline/dsl/methods_probe.rb
36
35
  - lib/landline/dsl/methods_template.rb
36
+ - lib/landline/extensions/session.rb
37
+ - lib/landline/extensions/websocket.rb
37
38
  - lib/landline/node.rb
38
39
  - lib/landline/path.rb
39
40
  - lib/landline/pattern_matching.rb
@@ -41,11 +42,13 @@ files:
41
42
  - lib/landline/pattern_matching/rematch.rb
42
43
  - lib/landline/pattern_matching/util.rb
43
44
  - lib/landline/probe.rb
45
+ - lib/landline/probe/crosscall_handler.rb
44
46
  - lib/landline/probe/handler.rb
45
47
  - lib/landline/probe/http_method.rb
46
48
  - lib/landline/probe/serve_handler.rb
47
49
  - lib/landline/request.rb
48
50
  - lib/landline/response.rb
51
+ - lib/landline/sandbox.rb
49
52
  - lib/landline/server.rb
50
53
  - lib/landline/template.rb
51
54
  - lib/landline/template/erb.rb
@@ -53,6 +56,7 @@ files:
53
56
  - lib/landline/util/cookie.rb
54
57
  - lib/landline/util/errors.rb
55
58
  - lib/landline/util/html.rb
59
+ - lib/landline/util/jwt.rb
56
60
  - lib/landline/util/lookup.rb
57
61
  - lib/landline/util/mime.rb
58
62
  - lib/landline/util/multipart.rb
@@ -61,7 +65,7 @@ files:
61
65
  - lib/landline/util/query.rb
62
66
  homepage: https://adastra7.net/git/Yessiest/landline
63
67
  licenses:
64
- - AGPL-3.0
68
+ - AGPL-3.0-or-later
65
69
  metadata: {}
66
70
  post_install_message:
67
71
  rdoc_options: []
@@ -78,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
82
  - !ruby/object:Gem::Version
79
83
  version: '0'
80
84
  requirements: []
81
- rubygems_version: 3.3.25
85
+ rubygems_version: 3.5.6
82
86
  signing_key:
83
87
  specification_version: 4
84
88
  summary: Elegant HTTP DSL
data/LAYOUT.md DELETED
@@ -1,86 +0,0 @@
1
- # Internal structure of Landline lib
2
-
3
- Note: If you want to start hacking on Landline and extending it, follow this
4
- layout as closely as possible.
5
-
6
- ## Core classes
7
-
8
- These are core classes of Landline and they are loaded as soon as the library is loaded.
9
-
10
- - Landline::Path [path.rb]
11
- - Landline::PathContext [path.rb]
12
- - Landline::Probe [probe.rb]
13
- - Landline::ProbeContext [probe.rb]
14
- - Landline::Node (parent of Path and Probe) [node.rb]
15
- - Landline::Server (Rack application interface) [server.rb]
16
- - Landline::ServerContext [server.rb]
17
- - Landline::Request (Rack request wrapper) [request.rb]
18
- - Landline::Response (Rack response wrapper) [response.rb]
19
- - Landline::Pattern [pattern\_matching.rb]
20
- - Landline::TemplateContext [tempalte.rb]
21
- - Landline::Template (template engine interface) [template.rb]
22
-
23
- ## Patterns
24
-
25
- These are classes that Landline::Pattern can interface with to create Patterns.
26
-
27
- - Landline::PatternMatching::ReMatch [pattern\_matching/rematch.rb]
28
- - Landline::PatternMatching::Glob [pattern\_matching/glob.rb]
29
-
30
- ## DSL Method mixins
31
-
32
- These are module mixins that add common methods to DSL bindings.
33
-
34
- - Landline::DSL::PathConstructors [dsl/constructors\_path.rb]
35
- - Landline::DSL::ProbeConstructures [dsl/constructors\_probe.rb]
36
- - Landline::DSL::CommonMethods [dsl/methods\_common.rb]
37
- - Landline::DSL::PathMethods [dsl/methods\_path.rb]
38
- - Landline::DSL::ProbeMethods [dsl/methods\_probe.rb]
39
- - Landline::DSL::TemplateMethods [dsl/methods\_template.rb]
40
-
41
- ## Utilities
42
-
43
- These are self-contained classes and methods that add extra functionality to Landline.
44
-
45
- - Landline::Util::Lookup [util/lookup.rb]
46
- - Landline::PatternMatching [pattern\_matching/util.rb]
47
- - Landline::Cookie (class) [util/cookie.rb]
48
- - Landline::Error (class) [util/errors.rb]
49
- - Landline::ParsingError (class) [util/errors.rb]
50
- - Landline::Util (html/http utilities) [util/html.rb]
51
- - Landline::MIME (MIME extension to type association) [util/mime.rb]
52
- - Landline::Util::ParserSorting (functions for sorting form/query hashes) [util/parsesorting.rb]
53
- - Landline::Util::Query (query class) [util/query.rb]
54
- - Landline::Util::FormPart (formparser struct) [util/multipart.rb]
55
- - Landline::Util::MultipartParser (multipart form parser) [util/multipart.rb]
56
- - Landline::Util::HeaderRegexp (helper regexps for headers) [util/parseutils.rb]
57
- - Landline::Util (parser methods) [util/parseutils.rb]
58
-
59
- ## Probe subclasses
60
-
61
- These are reactive request handlers with their own semantics, if needed.
62
-
63
- - Landline::Handlers::Handler [probe/handler.rb]
64
- - Landline::Handlers::GETHandler [probe/http\_method.rb]
65
- - Landline::Handlers::POSTHandler [probe/http\_method.rb]
66
- - Landline::Handlers::HEADHandler [probe/http\_method.rb]
67
- - Landline::Handlers::PUTHandler [probe/http\_method.rb]
68
- - Landline::Handlers::DELETEHandler [probe/http\_method.rb]
69
- - Landline::Handlers::CONNECTHandler [probe/http\_method.rb]
70
- - Landline::Handlers::OPTIONSHandler [probe/http\_method.rb]
71
- - Landline::Handlers::TRACEHandler [probe/http\_method.rb]
72
- - Landline::Handlers::PATCHHandler [probe/http\_method.rb]
73
- - Landline::Handlers::Serve
74
-
75
- ## Path subclasses
76
-
77
- These are navigation handlers with their own semantics.
78
-
79
- (currently none)
80
-
81
- ## Template engine interfaces
82
-
83
- These are uniform interfaces for various templating engines.
84
-
85
- - Landline::Templates::ERB [template/erb.rb]
86
- - Landline::Templates::Erubi [template/erubi.rb]