lowloop 0.8.5 → 0.8.6
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.
- checksums.yaml +4 -4
- data/lib/lowloop.rb +1 -1
- data/lib/responses/file_response.rb +20 -5
- data/lib/responses/response_factory.rb +14 -2
- data/lib/servers/file_server.rb +9 -2
- data/lib/states/file_state.rb +3 -1
- data/lib/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a30797b16bfdc71adaec6a4879217a777d27662498ce0a7a7213578657a2c7fc
|
|
4
|
+
data.tar.gz: 7ec9f60a96218d13b33d2c2cec0ffa4666f6ec5c0d52773cd7f8277e92722efc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3006e7ec87770b925233c906827ae98d5e1db05e200e3614b98401d30f6f90475c6541e6e5fbf582da74382a99ce7e279a389472096ef4d0e9aff12980f859e7
|
|
7
|
+
data.tar.gz: 7538373e1451c78fbaafa9ba046e43ca6106382449262dc5d044a18c5f2ebaa4e2a2a05ce0f0cb39780522b4384633afee57b8fa7bde1778814f7c9f3425d6b0
|
data/lib/lowloop.rb
CHANGED
|
@@ -23,7 +23,7 @@ class LowLoop
|
|
|
23
23
|
@frame = LowFrame.new(renderer: (renderer if config.matrix_mode), fps: 10, show_output:)
|
|
24
24
|
|
|
25
25
|
Low::Events::RequestEvent.define do |observers|
|
|
26
|
-
observers << Low::FileServer.new(web_root: config.web_root, content_types: config.content_types)
|
|
26
|
+
observers << Low::FileServer.new(web_root: config.web_root, content_types: config.content_types, cache_control: config.cache_control)
|
|
27
27
|
observers << router if router
|
|
28
28
|
observers.push(self, action: :mirror) if config.mirror_mode
|
|
29
29
|
end
|
|
@@ -7,13 +7,28 @@ module Low
|
|
|
7
7
|
class << self
|
|
8
8
|
def request(event:)
|
|
9
9
|
file = event.file
|
|
10
|
+
return nil unless File.exist?(file.path)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
12
|
+
path = file.path
|
|
13
|
+
cache_control = file.cache_control
|
|
14
|
+
return respond(ResponseFactory.not_modified(path:, cache_control:)) if unchanged?(path, event.request)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
respond(ResponseFactory.file(path:, content_type: file.content_type, cache_control:))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def respond(response)
|
|
22
|
+
Events::ResponseEvent.new(response:).tap(&:branch)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def unchanged?(path, request)
|
|
26
|
+
since = request&.headers&.[]('if-modified-since')
|
|
27
|
+
return false unless since
|
|
28
|
+
|
|
29
|
+
File.mtime(path).to_i <= Time.httpdate(Array(since).first.to_s).to_i
|
|
30
|
+
rescue ArgumentError
|
|
31
|
+
false
|
|
17
32
|
end
|
|
18
33
|
end
|
|
19
34
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'cgi'
|
|
4
|
+
require 'time'
|
|
4
5
|
require 'protocol/http'
|
|
5
6
|
require 'protocol/http/body/file'
|
|
6
7
|
|
|
@@ -13,13 +14,24 @@ module Low
|
|
|
13
14
|
Protocol::HTTP::Response.new('HTTP/1.1', 200, headers, body)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
def file(path:, content_type:)
|
|
17
|
-
headers = Protocol::HTTP::Headers.new([['content-type', content_type]])
|
|
17
|
+
def file(path:, content_type:, cache_control: nil)
|
|
18
|
+
headers = Protocol::HTTP::Headers.new([['content-type', content_type], *cache_headers(path, cache_control)])
|
|
18
19
|
file = File.open(path, 'rb')
|
|
19
20
|
body = Protocol::HTTP::Body::File.new(file)
|
|
20
21
|
Protocol::HTTP::Response.new('HTTP/1.1', 200, headers, body)
|
|
21
22
|
end
|
|
22
23
|
|
|
24
|
+
def not_modified(path:, cache_control: nil)
|
|
25
|
+
headers = Protocol::HTTP::Headers.new(cache_headers(path, cache_control))
|
|
26
|
+
Protocol::HTTP::Response.new('HTTP/1.1', 304, headers, nil)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def cache_headers(path, cache_control)
|
|
30
|
+
headers = [['last-modified', File.mtime(path).httpdate]]
|
|
31
|
+
headers << ['cache-control', cache_control] if cache_control
|
|
32
|
+
headers
|
|
33
|
+
end
|
|
34
|
+
|
|
23
35
|
# Shows the error and where it happened in debug mode (or show a 500 status).
|
|
24
36
|
def error(error:, debug: false)
|
|
25
37
|
headers = Protocol::HTTP::Headers.new([['content-type', 'text/html']])
|
data/lib/servers/file_server.rb
CHANGED
|
@@ -11,9 +11,10 @@ module Low
|
|
|
11
11
|
include LowType
|
|
12
12
|
include Observers
|
|
13
13
|
|
|
14
|
-
def initialize(web_root:, content_types:)
|
|
14
|
+
def initialize(web_root:, content_types:, cache_control: nil)
|
|
15
15
|
@web_root = web_root
|
|
16
16
|
@content_types = content_types.transform_keys(&:to_s)
|
|
17
|
+
@cache_control = cache_control
|
|
17
18
|
|
|
18
19
|
observers(Events::FileEvent) << FileResponse
|
|
19
20
|
end
|
|
@@ -27,6 +28,12 @@ module Low
|
|
|
27
28
|
extension
|
|
28
29
|
end
|
|
29
30
|
|
|
31
|
+
def cache_control(extension)
|
|
32
|
+
return @cache_control unless @cache_control.is_a?(Hash)
|
|
33
|
+
|
|
34
|
+
@cache_control.transform_keys(&:to_s)[extension]
|
|
35
|
+
end
|
|
36
|
+
|
|
30
37
|
def request(event: Events::RequestEvent)
|
|
31
38
|
file_path = event.request.path
|
|
32
39
|
|
|
@@ -37,7 +44,7 @@ module Low
|
|
|
37
44
|
return nil if extension.nil?
|
|
38
45
|
|
|
39
46
|
file_path = url.local_path(@web_root)
|
|
40
|
-
file = States::FileState.new(path: file_path, content_type: @content_types[extension])
|
|
47
|
+
file = States::FileState.new(path: file_path, content_type: @content_types[extension], cache_control: cache_control(extension))
|
|
41
48
|
|
|
42
49
|
Events::FileEvent.take(file:, request: event.request)
|
|
43
50
|
end
|
data/lib/states/file_state.rb
CHANGED
data/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lowloop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-11-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: async
|
|
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
160
160
|
- !ruby/object:Gem::Version
|
|
161
161
|
version: '0'
|
|
162
162
|
requirements: []
|
|
163
|
-
rubygems_version:
|
|
163
|
+
rubygems_version: 3.6.2
|
|
164
164
|
specification_version: 4
|
|
165
165
|
summary: An event-driven event loop
|
|
166
166
|
test_files: []
|