nanoserve 0.1.0 → 0.2.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
  SHA1:
3
- metadata.gz: '019575a37a4493c4816afbe726f0c2a0495049ea'
4
- data.tar.gz: bf54d9e145418838ce211764c5555ffaa68ae97d
3
+ metadata.gz: 36d89ee5855668e13996733662f4ef7c00a1cc56
4
+ data.tar.gz: 06c20ca6aeeaf09554954832c1241f82da2fc9a9
5
5
  SHA512:
6
- metadata.gz: 5576fec9ea2afa3d053996248045c8df2d418a8eab235354727b983b7457f2aaebe0f88a847f745b5534c499bc58c081d3c1689283df38fb4118c7cf66a0b06f
7
- data.tar.gz: 18c903426feae6ec6eb8c1d27e693f8cda25553635cff9087da1d71908245116e3d9573b21bba04d277264729accf8bddb4d4f3e660f2d410eba28b71f791741
6
+ metadata.gz: 98b1070c92caf9a53c8372ee688b6436be393f70d360635429690bd4e054bca84942d494f336fc9abdd37bc9165120a235faa755fd59e54968ecc71b95b11733
7
+ data.tar.gz: edaf2f744b271f6134561cd42ee9f841dd8a2059d0734b48e18900fa449e136e9689e66cfd17daf4ae91b7887177c74f53b71bbfb82ebaf1e6bc2df1efdcfbaf
@@ -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
- server = TCPServer.new(@port)
18
+ @srv = TCPServer.new(@port)
18
19
 
19
20
  @thr = Thread.new do
20
21
  Thread.abort_on_exception = true
21
- conn = server.accept
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
- ensure
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
- @body << line
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
- (@sep = '' && return) if str == ''
154
+ if str == ''
155
+ @sep = true
156
+ return
157
+ end
127
158
 
128
- unless (m = str.match(/(?<header>[A-Z][-A-Za-z]*):\s+(?<value>.+)$/))
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 = body.bytes.count.to_s }
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 ||= body.bytes.count.to_s
219
+ @content_length || '0'
185
220
  end
186
221
 
187
222
  def content_type
@@ -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.1.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-18 00:00:00.000000000 Z
11
+ date: 2017-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest