server.rb 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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