From dc8739c69228de86006cae6e60a34173cd02a369 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 19 Sep 2017 15:34:02 +0200 Subject: [PATCH 1/5] Normalize request method verb --- lib/nanoserve.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nanoserve.rb b/lib/nanoserve.rb index 0b761eb..29c32dc 100644 --- a/lib/nanoserve.rb +++ b/lib/nanoserve.rb @@ -139,7 +139,7 @@ module NanoServe end def parse_method(str) - str + str.upcase end def parse_path(str) From dd5001cb7c32bcbda4b5e083c73fc74aa264b36b Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 19 Sep 2017 15:35:55 +0200 Subject: [PATCH 2/5] Implement request body and normalized headers access --- lib/nanoserve.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/nanoserve.rb b/lib/nanoserve.rb index 29c32dc..5ab4559 100644 --- a/lib/nanoserve.rb +++ b/lib/nanoserve.rb @@ -102,6 +102,14 @@ module NanoServe Hash[*@uri.query.split('&').map { |kv| kv.split('=') }.flatten] end + def body + @body + end + + def [](key) + @headers[key.downcase] + end + def <<(line) if @method.nil? parse_request(line.chomp) From 66a2a206634a496e3bba4173df97624a9fbc92f9 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 19 Sep 2017 15:36:16 +0200 Subject: [PATCH 3/5] Implement request host, path and content_type access --- lib/nanoserve.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/nanoserve.rb b/lib/nanoserve.rb index 5ab4559..36b3dbc 100644 --- a/lib/nanoserve.rb +++ b/lib/nanoserve.rb @@ -98,6 +98,14 @@ module NanoServe @body = +''.encode('ASCII-8BIT') end + def host + @headers['host'] + end + + def path + @uri.path + end + def params Hash[*@uri.query.split('&').map { |kv| kv.split('=') }.flatten] end @@ -132,6 +140,10 @@ module NanoServe @headers.key?('content-length') end + def content_type + @headers['content-type'] + end + private REQ_RE = %r{(?[A-Z]+)\s+(?\S+)\s+(?HTTP/\d+.\d+)$} From 8a5c956a2431ebcb51b51a0c22535137e123b518 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 19 Sep 2017 15:46:02 +0200 Subject: [PATCH 4/5] Implement form-urlencoded support Query and form return a Hash, folding duplicates with last-key-wins strategy. *_array methods provide the seldom-used duplicate-preserving counterparts. Keep query and form separate, but provide params, which handles both, with form having precedence over query. --- lib/nanoserve.rb | 22 ++++++++++++++++++++- test/test_nanoserve.rb | 44 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/nanoserve.rb b/lib/nanoserve.rb index 36b3dbc..d6573fa 100644 --- a/lib/nanoserve.rb +++ b/lib/nanoserve.rb @@ -106,8 +106,28 @@ module NanoServe @uri.path end + def query_array + URI.decode_www_form(@uri.query || '') + end + + def form_array + form? ? URI.decode_www_form(body) : [] + end + + def query + Hash[*query_array.flatten] + end + + def form + Hash[*form_array.flatten] + end + def params - Hash[*@uri.query.split('&').map { |kv| kv.split('=') }.flatten] + query.merge(form) + end + + def form? + content_type == 'application/x-www-form-urlencoded' end def body diff --git a/test/test_nanoserve.rb b/test/test_nanoserve.rb index 9bbded2..29dd919 100644 --- a/test/test_nanoserve.rb +++ b/test/test_nanoserve.rb @@ -29,7 +29,7 @@ class TestNanoServe < MiniTest::Test assert_equal(uuid, buf) end - def test_http_responder + def test_http_responder_get uuid = SecureRandom.uuid.encode('UTF-8') uri = URI('http://localhost:2000') @@ -56,4 +56,46 @@ class TestNanoServe < MiniTest::Test assert_equal(uuid, req.first.params['uuid']) end + + def test_http_responder_post + uuid = SecureRandom.uuid.encode('UTF-8') + uri = URI('http://localhost:2000') + + r = NanoServe::HTTPResponder.new(uri.host, uri.port) do |res, req, y| + y << req + + res.body = <<-EOS.gsub(/^ {8}/, '') + + + An Example Page + + + Hello World, this is a very simple HTML document. + + + EOS + end + + req = r.start([]) do + Net::HTTP.post_form( + uri + "test?uuid=#{uuid}&p=query", + 'p' => 'form', + 'f' => 'foo', + ) + end + + r.stop + + assert_equal(uuid, req.first.params['uuid']) + assert_equal(uuid, req.first.query['uuid']) + assert_nil(req.first.form['uuid']) + + assert_equal('foo', req.first.params['f']) + assert_nil(req.first.query['f']) + assert_equal('foo', req.first.form['f']) + + assert_equal('form', req.first.params['p']) + assert_equal('query', req.first.query['p']) + assert_equal('form', req.first.form['p']) + end end From 2edc861a06538d5703a480744f20c8f201722c18 Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Tue, 19 Sep 2017 15:47:44 +0200 Subject: [PATCH 5/5] Release v0.3.0 --- nanoserve.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nanoserve.gemspec b/nanoserve.gemspec index 04d67f1..81c28a2 100644 --- a/nanoserve.gemspec +++ b/nanoserve.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = 'nanoserve' - s.version = '0.2.0' + s.version = '0.3.0' s.licenses = ['3BSD'] s.summary = 'Listen to one-shot connections' s.authors = ['Loic Nageleisen']