nanoserve 0.1.0 → 0.2.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 +4 -4
- data/lib/nanoserve.rb +47 -12
- data/test/test_nanoserve.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36d89ee5855668e13996733662f4ef7c00a1cc56
|
4
|
+
data.tar.gz: 06c20ca6aeeaf09554954832c1241f82da2fc9a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98b1070c92caf9a53c8372ee688b6436be393f70d360635429690bd4e054bca84942d494f336fc9abdd37bc9165120a235faa755fd59e54968ecc71b95b11733
|
7
|
+
data.tar.gz: edaf2f744b271f6134561cd42ee9f841dd8a2059d0734b48e18900fa449e136e9689e66cfd17daf4ae91b7887177c74f53b71bbfb82ebaf1e6bc2df1efdcfbaf
|
data/lib/nanoserve.rb
CHANGED
@@ -11,14 +11,15 @@ module NanoServe
|
|
11
11
|
@port = port
|
12
12
|
@block = block
|
13
13
|
@thr = nil
|
14
|
+
@srv = nil
|
14
15
|
end
|
15
16
|
|
16
17
|
def start(y)
|
17
|
-
|
18
|
+
@srv = TCPServer.new(@port)
|
18
19
|
|
19
20
|
@thr = Thread.new do
|
20
21
|
Thread.abort_on_exception = true
|
21
|
-
conn =
|
22
|
+
conn = @srv.accept
|
22
23
|
port, host = conn.peeraddr[1, 2]
|
23
24
|
client = "#{host}:#{port}"
|
24
25
|
logger.debug "#{client}: connected"
|
@@ -27,8 +28,9 @@ module NanoServe
|
|
27
28
|
@block.call(conn, y)
|
28
29
|
rescue EOFError
|
29
30
|
logger.debug "#{client}: disconnected"
|
30
|
-
|
31
|
+
else
|
31
32
|
logger.debug "#{client}: closed"
|
33
|
+
ensure
|
32
34
|
conn.close
|
33
35
|
end
|
34
36
|
end
|
@@ -38,18 +40,22 @@ module NanoServe
|
|
38
40
|
yield
|
39
41
|
|
40
42
|
@thr.join
|
41
|
-
server.close
|
42
43
|
|
43
44
|
y
|
44
45
|
end
|
45
46
|
|
46
47
|
def stop
|
48
|
+
@srv.close
|
47
49
|
@thr.kill
|
48
50
|
end
|
49
51
|
|
50
52
|
def logger
|
51
53
|
@logger ||= Logger.new(STDOUT).tap { |l| l.level = Logger::INFO }
|
52
54
|
end
|
55
|
+
|
56
|
+
def logger=(logger)
|
57
|
+
@logger = logger
|
58
|
+
end
|
53
59
|
end
|
54
60
|
|
55
61
|
class HTTPResponder < TCPResponder
|
@@ -59,11 +65,18 @@ module NanoServe
|
|
59
65
|
buf = +''
|
60
66
|
loop do
|
61
67
|
line = conn.readline
|
62
|
-
break if line.chomp == ''
|
63
68
|
req << line
|
64
|
-
buf << line
|
69
|
+
buf << line if logger.debug?
|
70
|
+
break if req.headers?
|
65
71
|
end
|
66
72
|
logger.debug "request:\n" + buf.gsub(/^/, ' ')
|
73
|
+
length = 0
|
74
|
+
while req.content_length? && length < req.content_length
|
75
|
+
data = conn.readpartial(1024)
|
76
|
+
length += data.size
|
77
|
+
req << data
|
78
|
+
end
|
79
|
+
logger.debug "request body: #{length} bytes read"
|
67
80
|
|
68
81
|
res = Response.new
|
69
82
|
logger.debug 'calling'
|
@@ -82,6 +95,7 @@ module NanoServe
|
|
82
95
|
@http_version = nil
|
83
96
|
@sep = nil
|
84
97
|
@headers = {}
|
98
|
+
@body = +''.encode('ASCII-8BIT')
|
85
99
|
end
|
86
100
|
|
87
101
|
def params
|
@@ -94,10 +108,24 @@ module NanoServe
|
|
94
108
|
elsif @sep.nil?
|
95
109
|
parse_header(line.chomp)
|
96
110
|
else
|
97
|
-
|
111
|
+
parse_body(line)
|
98
112
|
end
|
99
113
|
end
|
100
114
|
|
115
|
+
def headers?
|
116
|
+
@sep
|
117
|
+
end
|
118
|
+
|
119
|
+
def content_length
|
120
|
+
@headers['content-length'].to_i
|
121
|
+
end
|
122
|
+
|
123
|
+
def content_length?
|
124
|
+
@headers.key?('content-length')
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
101
129
|
REQ_RE = %r{(?<method>[A-Z]+)\s+(?<path>\S+)\s+(?<version>HTTP/\d+.\d+)$}
|
102
130
|
|
103
131
|
def parse_request(str)
|
@@ -123,13 +151,20 @@ module NanoServe
|
|
123
151
|
end
|
124
152
|
|
125
153
|
def parse_header(str)
|
126
|
-
|
154
|
+
if str == ''
|
155
|
+
@sep = true
|
156
|
+
return
|
157
|
+
end
|
127
158
|
|
128
|
-
unless (m = str.match(/(?<header>[A-
|
159
|
+
unless (m = str.match(/(?<header>[A-Za-z][-A-Za-z]*):\s+(?<value>.+)$/))
|
129
160
|
raise RequestError, "cannot parse header: '#{str}'"
|
130
161
|
end
|
131
162
|
|
132
|
-
@headers[m[:header]] = m[:value]
|
163
|
+
@headers[m[:header].downcase] = m[:value]
|
164
|
+
end
|
165
|
+
|
166
|
+
def parse_body(line)
|
167
|
+
@body << line
|
133
168
|
end
|
134
169
|
end
|
135
170
|
|
@@ -151,7 +186,7 @@ module NanoServe
|
|
151
186
|
end
|
152
187
|
|
153
188
|
def body=(value)
|
154
|
-
@body = value.tap { @content_length =
|
189
|
+
@body = value.tap { @content_length = value.bytes.count.to_s }
|
155
190
|
end
|
156
191
|
|
157
192
|
def to_s
|
@@ -181,7 +216,7 @@ module NanoServe
|
|
181
216
|
end
|
182
217
|
|
183
218
|
def content_length
|
184
|
-
@content_length
|
219
|
+
@content_length || '0'
|
185
220
|
end
|
186
221
|
|
187
222
|
def content_type
|
data/test/test_nanoserve.rb
CHANGED
@@ -24,6 +24,8 @@ class TestNanoServe < MiniTest::Test
|
|
24
24
|
s.close
|
25
25
|
end
|
26
26
|
|
27
|
+
r.stop
|
28
|
+
|
27
29
|
assert_equal(uuid, buf)
|
28
30
|
end
|
29
31
|
|
@@ -50,6 +52,8 @@ class TestNanoServe < MiniTest::Test
|
|
50
52
|
Net::HTTP.get(uri + "test?uuid=#{uuid}")
|
51
53
|
end
|
52
54
|
|
55
|
+
r.stop
|
56
|
+
|
53
57
|
assert_equal(uuid, req.first.params['uuid'])
|
54
58
|
end
|
55
59
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoserve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loic Nageleisen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|