diamant 0.0.2 → 0.0.3
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/diamant.rb +19 -48
- data/lib/diamant/response.rb +52 -0
- data/lib/diamant/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c406e42cc1a01c8fd089f314e6e020bc7fcb94658f6d67fc20d3d77c3ba7f842
|
|
4
|
+
data.tar.gz: '08c40e5c6155396c1c9681146438bdfb68465853e3c51a71d2e112e0485f2840'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 184a94626fa34d1e117cac0ab8d8814b520a12eb904b8804aad5466f49eea638ed4e02082148da504dada15b619ef67684465acf709a1b07bb8de3ab936d9448
|
|
7
|
+
data.tar.gz: 2641c99a8f263c33bd93c67363be5209d424d2ace599d52abc58ca16056f9f9c786a411dab89b77d658e531b0f405385838e768f0a0b53b145215aeafd3e57e4
|
data/lib/diamant.rb
CHANGED
|
@@ -11,6 +11,7 @@ require 'uri/gemini'
|
|
|
11
11
|
|
|
12
12
|
require 'diamant/version'
|
|
13
13
|
require 'diamant/mimetype'
|
|
14
|
+
require 'diamant/response'
|
|
14
15
|
|
|
15
16
|
module Diamant
|
|
16
17
|
# Runs the server request/answer loop.
|
|
@@ -25,34 +26,32 @@ module Diamant
|
|
|
25
26
|
def start
|
|
26
27
|
tcp_serv = TCPServer.new @bind, @port
|
|
27
28
|
ssl_serv = OpenSSL::SSL::SSLServer.new tcp_serv, ssl_context
|
|
29
|
+
main_loop(ssl_serv)
|
|
30
|
+
ensure
|
|
31
|
+
ssl_serv&.shutdown
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
include Diamant::Response
|
|
37
|
+
|
|
38
|
+
def main_loop(ssl_serv)
|
|
28
39
|
loop do
|
|
29
40
|
Thread.new(ssl_serv.accept) do |client|
|
|
30
41
|
handle_client(client)
|
|
31
42
|
client.close
|
|
32
43
|
end
|
|
44
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
45
|
+
# Do not even try to answer anything as the socket cannot be
|
|
46
|
+
# built. This will abruptly interrupt the connection from a client
|
|
47
|
+
# point of view, which must deal with it. Only keep a trace for us.
|
|
48
|
+
@logger.error(
|
|
49
|
+
format('SSLError: %<cause>s',
|
|
50
|
+
cause: e.message.sub(/.*state=error: (.+)\Z/, '\1'))
|
|
51
|
+
)
|
|
33
52
|
rescue Interrupt
|
|
34
53
|
break
|
|
35
54
|
end
|
|
36
|
-
ensure
|
|
37
|
-
ssl_serv&.shutdown
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def reject_request?(sock, current_load)
|
|
43
|
-
# Accept only 10 thread with no restriction
|
|
44
|
-
return false if current_load < 11
|
|
45
|
-
# Seppuku
|
|
46
|
-
raise 'Server is under heavy load' if current_load > 1965
|
|
47
|
-
if current_load > 42
|
|
48
|
-
@logger.warn '41 - Too much threads...'
|
|
49
|
-
sock.puts "41 See you soon...\r\n"
|
|
50
|
-
return true
|
|
51
|
-
end
|
|
52
|
-
# Please wait a little
|
|
53
|
-
@logger.warn '44 5 - Too much threads...'
|
|
54
|
-
sock.puts "44 5\r\n"
|
|
55
|
-
true
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
def handle_client(client)
|
|
@@ -67,34 +66,6 @@ module Diamant
|
|
|
67
66
|
end
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
def read_file(client)
|
|
71
|
-
r = Net::GeminiRequest.read_new(client)
|
|
72
|
-
[r.uri, route(r.path)]
|
|
73
|
-
rescue Net::GeminiBadRequest
|
|
74
|
-
[nil, ["59\r\n"]]
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def build_response(route)
|
|
78
|
-
info = Diamant::MimeType.new(route)
|
|
79
|
-
answer = IO.readlines route, chomp: true
|
|
80
|
-
answer.prepend "20 #{info.content_type}"
|
|
81
|
-
rescue Diamant::MimeError
|
|
82
|
-
['50 Not a supported file!']
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def route(path)
|
|
86
|
-
# In any case, remove the / prefix
|
|
87
|
-
route = File.expand_path path.delete_prefix('/'), Dir.pwd
|
|
88
|
-
# We better should use some sort of chroot...
|
|
89
|
-
unless route.start_with?(Dir.pwd)
|
|
90
|
-
@logger.warn "Bad attempt to get something out of public_dir: #{route}"
|
|
91
|
-
return ['51 Not found!']
|
|
92
|
-
end
|
|
93
|
-
route << '/index.gmi' if File.directory?(route)
|
|
94
|
-
return ['51 Not found!'] unless File.exist?(route)
|
|
95
|
-
build_response route
|
|
96
|
-
end
|
|
97
|
-
|
|
98
69
|
def ssl_context
|
|
99
70
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
|
100
71
|
ssl_context.min_version = OpenSSL::SSL::TLS1_2_VERSION
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Diamant
|
|
4
|
+
# Methods to generate requests responses
|
|
5
|
+
module Response
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def reject_request?(sock, current_load)
|
|
9
|
+
# Accept only 10 thread with no restriction
|
|
10
|
+
return false if current_load < 11
|
|
11
|
+
# Seppuku
|
|
12
|
+
raise 'Server is under heavy load' if current_load > 1965
|
|
13
|
+
if current_load > 42
|
|
14
|
+
@logger.warn '41 - Too much threads...'
|
|
15
|
+
sock.puts "41 See you soon...\r\n"
|
|
16
|
+
return true
|
|
17
|
+
end
|
|
18
|
+
# Please wait a little
|
|
19
|
+
@logger.warn '44 5 - Too much threads...'
|
|
20
|
+
sock.puts "44 5\r\n"
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def read_file(client)
|
|
25
|
+
r = Net::GeminiRequest.read_new(client)
|
|
26
|
+
[r.uri, route(r.path)]
|
|
27
|
+
rescue Net::GeminiBadRequest
|
|
28
|
+
[nil, ["59\r\n"]]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def route(path)
|
|
32
|
+
# In any case, remove the / prefix
|
|
33
|
+
route = File.expand_path path.delete_prefix('/'), Dir.pwd
|
|
34
|
+
# We better should use some sort of chroot...
|
|
35
|
+
unless route.start_with?(Dir.pwd)
|
|
36
|
+
@logger.warn "Bad attempt to get something out of public_dir: #{route}"
|
|
37
|
+
return ['51 Not found!']
|
|
38
|
+
end
|
|
39
|
+
route << '/index.gmi' if File.directory?(route)
|
|
40
|
+
return ['51 Not found!'] unless File.exist?(route)
|
|
41
|
+
build_response route
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def build_response(route)
|
|
45
|
+
info = Diamant::MimeType.new(route)
|
|
46
|
+
answer = IO.readlines route, chomp: true
|
|
47
|
+
answer.prepend "20 #{info.content_type}"
|
|
48
|
+
rescue Diamant::MimeError
|
|
49
|
+
['50 Not a supported file!']
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/diamant/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: diamant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Étienne Deparis
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-12-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ruby-net-text
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.0.
|
|
19
|
+
version: 0.0.3
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.0.
|
|
26
|
+
version: 0.0.3
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: byebug
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -165,6 +165,7 @@ files:
|
|
|
165
165
|
- lib/diamant.rb
|
|
166
166
|
- lib/diamant/cert_generator.rb
|
|
167
167
|
- lib/diamant/mimetype.rb
|
|
168
|
+
- lib/diamant/response.rb
|
|
168
169
|
- lib/diamant/version.rb
|
|
169
170
|
homepage: https://git.umaneti.net/diamant/about/
|
|
170
171
|
licenses:
|