server.rb 0.3.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c1f5315cd2fe6ceaa25725d372a53dbf52f61477cf0798c15fd20a348b28b4d
4
- data.tar.gz: 35df8a5fb406a8445cbb3c3bd151740dea62635c2c24e167c19bf81dce35fa1d
3
+ metadata.gz: d6f5a23f88fe1b283e2b5004394f493a588060e653a28f72840ff5a194108d41
4
+ data.tar.gz: 479b0da5bf427fd73ef5ade931b713f342dc5be8d0e5409d12041b323e3c3c43
5
5
  SHA512:
6
- metadata.gz: 93f99747c53464ebd6781d75a99945b0e2f90e1614a5e2627e1cb08450bf92f0f7984156ae5ee4773200d191eb2da1e50c55fae3ea7b5cc406001320eb7a4574
7
- data.tar.gz: ab565ff1c8c9e3c9fe9f6be21134582835d8c87b434012d584829618c005fba27b38ad5ae288849fe189ad9076aa356c5c4707005b9a089e4d0c1acf34d0e7df
6
+ metadata.gz: 213694f2d265096664eaee7e7eab3f75f95fa361155e7c2671118dd02768f41bd9d1dab1d77eb320deb9c584c904207ee57025b7446bf8657bbde68f596c1620
7
+ data.tar.gz: c2182a37c1af04a2cac3e9826e3d70a145810dd9f2fb8d76a6a52a5b1ecdfcae2c9f4d87ee72bf39aa3284a3fb9c9d09ed47cf9f8b60b377b2daf7fa39b426de
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # {Server::IndexResolver Server::IndexResolver} is a
5
+ # middleware that serves the contents of index.html
6
+ # from a given directory
7
+ class Server::IndexResolver
8
+ def initialize(app, options = {})
9
+ @app = app
10
+ @root = options.fetch(:root)
11
+ end
12
+
13
+ def call(env)
14
+ index = File.join(root, File.expand_path(env["PATH_INFO"]), "index.html")
15
+ if File.exist?(index)
16
+ Rack::Response[
17
+ 200,
18
+ {"content-type" => "text/html"},
19
+ File.read(index).each_line
20
+ ].finish
21
+ else
22
+ @app.call(env)
23
+ end
24
+ end
25
+
26
+ private
27
+ attr_reader :root
28
+ end
@@ -1,3 +1,3 @@
1
1
  class Server
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/server.rb CHANGED
@@ -3,22 +3,20 @@
3
3
  class Server
4
4
  require "rack"
5
5
  require_relative "server/puma"
6
- require_relative "server/gzip"
7
- require_relative "server/etag"
8
- require_relative "server/dir"
6
+ require_relative "server/index_resolver"
9
7
 
10
8
  ##
11
- # @param [String] path
9
+ # @param [String] root
12
10
  # The path to a directory
13
11
  # @return [Rack::Builder]
14
12
  # Returns a Rack app
15
- def self.app(path)
13
+ def self.app(root)
16
14
  Rack::Builder.app do
17
- use Server::ETag
18
- run Server::Dir.new(path)
15
+ use IndexResolver, {root:}
16
+ use Rack::Deflater
17
+ run Rack::Files.new(root)
19
18
  end
20
19
  end
21
- private_class_method :app
22
20
 
23
21
  ##
24
22
  # @param [String] path
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: server.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - '0x1eef'
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-02 00:00:00.000000000 Z
11
+ date: 2024-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: puma
@@ -88,9 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - lib/server.rb
91
- - lib/server/dir.rb
92
- - lib/server/etag.rb
93
- - lib/server/gzip.rb
91
+ - lib/server/index_resolver.rb
94
92
  - lib/server/puma.rb
95
93
  - lib/server/version.rb
96
94
  homepage: https://github.com/0x1eef/server.rb#readme
data/lib/server/dir.rb DELETED
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ##
4
- # {Server::Dir Server::Dir} provides a rack application that
5
- # serves the contents of a directory
6
- class Server::Dir
7
- prepend Server::Gzip
8
-
9
- def initialize(root)
10
- @root = File.realpath(root)
11
- @mime_types = {".ttf" => "font/ttf"}.freeze
12
- end
13
-
14
- def call(env)
15
- catch(:redirect) { finish Rack::Request.new(env) }
16
- rescue Errno::EPERM, Errno::EACCES
17
- body = "Permission denied"
18
- [403, {"content-length" => body.bytesize, "content-type" => "text/plain"}, [body]]
19
- rescue Errno::ENOENT
20
- body = "The requested URL was not found"
21
- [404, {"content-length" => body.bytesize, "content-type" => "text/plain"}, [body]]
22
- rescue => ex
23
- body = "Internal server error (#{ex.class})"
24
- [500, {"content-length" => body.bytesize, "content-type" => "text/plain"}, [body]]
25
- end
26
-
27
- def finish(req)
28
- path = resolve_path(req)
29
- body = File.binread(path)
30
- extn = File.extname(path)
31
- [
32
- 200,
33
- {"content-type" => mime_types[extn] || Rack::Mime.mime_type(extn),
34
- "content-length" => body.bytesize},
35
- body.each_line.to_a
36
- ]
37
- end
38
-
39
- private
40
-
41
- attr_reader :root, :mime_types
42
-
43
- def resolve_path(req)
44
- path = File.join root, File.expand_path(req.path)
45
- return path unless File.directory?(path)
46
- if req.path.end_with?("/")
47
- File.join(path, "index.html")
48
- else
49
- throw(:redirect, [301, {"Location" => "#{req.path}/"}, [""]])
50
- end
51
- end
52
- end
data/lib/server/etag.rb DELETED
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ##
4
- # A middleware that adds ETag support.
5
- class Server::ETag < Rack::ETag
6
- ETAGS = {}
7
-
8
- ##
9
- # @param [#call] app
10
- # A rack app.
11
- #
12
- # @return [Server::ETag]
13
- # Reurns an instance of {Server::ETag Server::ETag}.
14
- def initialize(app)
15
- @app = app
16
- end
17
-
18
- ##
19
- # @param [Hash] env
20
- # An environment hash.
21
- #
22
- # @return [Array<Number, Hash, #each>]
23
- def call(env)
24
- status, headers, body = super(env)
25
- if headers["etag"] && headers["etag"] == env["HTTP_IF_NONE_MATCH"]
26
- [304, headers, [""]]
27
- else
28
- [status, headers, body]
29
- end
30
- end
31
- end
data/lib/server/gzip.rb DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ##
4
- # A mixin that serves a compressed copy of a file.
5
- # Similar to the nginx module
6
- # [gzip_static](http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html).
7
- module Server::Gzip
8
- def finish(request)
9
- path = gzip_path(request)
10
- if path
11
- body = File.binread(path)
12
- extn = File.extname(path[0..-4])
13
- [
14
- 200,
15
- {"content-type" => mime_types[extn] || Rack::Mime.mime_type(extn),
16
- "content-encoding" => "gzip",
17
- "content-length" => body.bytesize},
18
- body.each_line
19
- ]
20
- else
21
- super
22
- end
23
- end
24
-
25
- private
26
-
27
- def gzip_path(request)
28
- return unless request.get_header("accept-encoding")
29
- &.include?("gzip")
30
- path = "#{find_path(request)}.gz"
31
- File.exist?(path) ? path : nil
32
- end
33
- end