qeweney 0.10 → 0.14

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '048091b6174ddf88ab76f9676514db59d42a77d363db9be53d90e16235322ac7'
4
- data.tar.gz: 8b346882f337e3b48bd8dd17dc2345458df6fc01c74a9a96d9d94bae31f2d841
3
+ metadata.gz: 3f515f9637f0d993c9dfbea4d425695f76915871ad0c62e090cbb31a4a57b4a7
4
+ data.tar.gz: 80a6bf6da6a0d2b85771deff0cb24ad9bcf389e4af37042a6fd62c215617a657
5
5
  SHA512:
6
- metadata.gz: a1c9db7e7e6c494124f6306b3de4e43bd5d58d2148cef0bea8ef653598c2ba2e5fe3220b0009aa35d43085267572c0a0914db0cb568c2de93be89c66a97470af
7
- data.tar.gz: '09693533b8686a6aeddb8d409434c3e3dfd212e04ff1364adcc79feb1c74c65d2526f087107374df366e96a1dc3edaf71b5876e69f10ac5886e5d41d0aec6e93'
6
+ metadata.gz: d08170e772a3fad93d49a06bc8ee6c656e5057e5368d3dfba6687d1f838dff50e7cfb8895315480f3f85ea519d8ee0ae20a3a480ee26293bd86bfec2c4912918
7
+ data.tar.gz: a1918424e95a70891eb4f8fb1b163cdf62167bb3847c16192be9f8dffd95c77513cca4f0e6d4a759275b14bc7891d770585b3625b4601177195ade7a731f6814
data/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
- ## 0.10.0 2021-06-24
1
+ ## 0.14 2021-08-10
2
+
3
+ - Fix Request#on with paths containing slashes
4
+
5
+ ## 0.13.1 2021-08-03
6
+
7
+ - Fix `Request#read`
8
+
9
+ ## 0.13 2021-08-02
10
+
11
+ - Restore `Request#complete?` method
12
+ - Add buffered_only argument to `Request#next_chunk`
13
+
14
+ ## 0.12 2021-07-30
15
+
16
+ - Remove `Request#consume` method
17
+ - Remove `Request#complete?` and associated methods
18
+
19
+ ## 0.11 2021-07-26
20
+
21
+ - Fix rack env (digital-fabric/tipi#11)
22
+
23
+ ## 0.10 2021-06-24
2
24
 
3
25
  - Include file stat in `#serve_io` options as hint for adapter
4
26
  - Fix `MimeTypes#[]` for empty extension
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qeweney (0.10)
4
+ qeweney (0.14)
5
5
  escape_utils (~> 1.2.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Qeweney
1
+ # Qeweney - add water, makes its own sauce!
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/qeweney.svg)](http://rubygems.org/gems/qeweney)
4
+ [![Modulation Test](https://github.com/digital-fabric/qeweney/workflows/Tests/badge.svg)](https://github.com/digital-fabric/qeweney/actions?query=workflow%3ATests)
5
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/digital-fabric/qeweney/blob/master/LICENSE)
2
6
 
3
7
  ## Cross-library HTTP request / response API for servers
4
8
 
data/lib/qeweney/rack.rb CHANGED
@@ -67,12 +67,33 @@ module Qeweney
67
67
  end
68
68
  end
69
69
 
70
+ # TODO: integrate in env
71
+ # Implements a rack input stream:
72
+ # https://www.rubydoc.info/github/rack/rack/master/file/SPEC#label-The+Input+Stream
73
+ class InputStream
74
+ def initialize(request)
75
+ @request = request
76
+ end
77
+
78
+ def gets; end
79
+
80
+ def read(length = nil, outbuf = nil); end
81
+
82
+ def each(&block)
83
+ @request.each_chunk(&block)
84
+ end
85
+
86
+ def rewind; end
87
+ end
88
+
70
89
  def self.rack_env_from_request(request)
71
90
  Hash.new do |h, k|
72
- h[k] = env_value_from_request(request, k)
91
+ h[k] = rack_env_value_from_request(request, k)
73
92
  end
74
93
  end
75
94
 
95
+ # TODO: improve conformance to rack spec
96
+ # TODO: set values like port, scheme etc from actual connection
76
97
  RACK_ENV = {
77
98
  'SCRIPT_NAME' => '',
78
99
  'rack.version' => [1, 3],
@@ -90,9 +111,11 @@ module Qeweney
90
111
  'rack.multipar.tempfile_factory' => nil
91
112
  }
92
113
 
93
- def self.env_value_from_request(request, key)
114
+ HTTP_HEADER_RE = /^HTTP_(.+)$/.freeze
115
+
116
+ def self.rack_env_value_from_request(request, key)
94
117
  case key
95
- when 'REQUEST_METHOD' then request.method
118
+ when 'REQUEST_METHOD' then request.method.upcase
96
119
  when 'PATH_INFO' then request.path
97
120
  when 'QUERY_STRING' then request.query_string || ''
98
121
  when 'SERVER_NAME' then request.headers['host']
@@ -27,14 +27,16 @@ module Qeweney
27
27
  @buffered_body_chunks << chunk
28
28
  end
29
29
 
30
- def next_chunk
30
+ def next_chunk(buffered_only = false)
31
31
  if @buffered_body_chunks
32
32
  chunk = @buffered_body_chunks.shift
33
33
  @buffered_body_chunks = nil if @buffered_body_chunks.empty?
34
34
  return chunk
35
+ elsif buffered_only
36
+ return nil
35
37
  end
36
38
 
37
- @message_complete ? nil : @adapter.get_body_chunk(self)
39
+ @adapter.get_body_chunk(self, buffered_only)
38
40
  end
39
41
 
40
42
  def each_chunk
@@ -44,37 +46,28 @@ module Qeweney
44
46
  end
45
47
  @buffered_body_chunks = nil
46
48
  end
47
- while !@message_complete && (chunk = @adapter.get_body_chunk(self))
49
+ while (chunk = @adapter.get_body_chunk(self))
48
50
  yield chunk
49
51
  end
50
52
  end
51
53
 
52
- def complete!(keep_alive = nil)
53
- @message_complete = true
54
- @keep_alive = keep_alive
55
- end
56
-
57
- def complete?
58
- @message_complete
59
- end
60
-
61
- def consume
62
- @adapter.consume_request(self)
63
- end
64
-
65
- def keep_alive?
66
- @keep_alive
67
- end
68
-
69
54
  def read
70
- buf = @buffered_body_chunks ? @buffered_body_chunks.join : nil
71
- while (chunk = @adapter.get_body_chunk(self))
72
- (buf ||= +'') << chunk
55
+ if @buffered_body_chunks
56
+ body = @buffered_body_chunks.join
57
+ if !complete?
58
+ rest = @adapter.get_body(self)
59
+ body << rest if rest
60
+ end
61
+ @buffered_body_chunks = nil
62
+ return body
73
63
  end
74
- @buffered_body_chunks = nil
75
- buf
64
+ @adapter.get_body(self)
76
65
  end
77
66
  alias_method :body, :read
67
+
68
+ def complete?
69
+ @adapter.complete?(self)
70
+ end
78
71
 
79
72
  def respond(body, headers = {})
80
73
  @adapter.respond(self, body, headers)
@@ -164,6 +164,8 @@ module Qeweney
164
164
  MAX_PARAMETER_VALUE_SIZE = 2**20 # 1MB
165
165
 
166
166
  def parse_urlencoded_form_data(body)
167
+ return {} unless body
168
+
167
169
  body.force_encoding(Encoding::UTF_8) unless body.encoding == Encoding::UTF_8
168
170
  body.split('&').each_with_object({}) do |i, m|
169
171
  raise 'Invalid parameter format' unless i =~ PARAMETER_RE
@@ -29,22 +29,24 @@ module Qeweney
29
29
  @path_parts.empty? ? '/' : "/#{@path_parts[@path_parts_idx..-1].join('/')}"
30
30
  end
31
31
 
32
- def enter_route
33
- @path_parts_idx += 1
32
+ def enter_route(depth = 1)
33
+ @path_parts_idx += depth
34
34
  end
35
35
 
36
- def leave_route
37
- @path_parts_idx -= 1
36
+ def leave_route(depth = 1)
37
+ @path_parts_idx -= depth
38
38
  end
39
39
 
40
- def on(route = nil, &block)
41
- if route
42
- return unless @path_parts[@path_parts_idx] == route
43
- end
40
+ def on(route, &block)
41
+ return route_found(&block) unless route
42
+
43
+ route_parts = route.split('/')
44
+ route_length = route_parts.size
45
+ return unless @path_parts[@path_parts_idx, route_length] == route_parts
44
46
 
45
- enter_route
47
+ enter_route(route_length)
46
48
  route_found(&block)
47
- leave_route
49
+ leave_route(route_length)
48
50
  end
49
51
 
50
52
  def is(route = '/', &block)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qeweney
4
- VERSION = '0.10'
4
+ VERSION = '0.14'
5
5
  end
@@ -179,7 +179,7 @@ class ServeRackTest < MiniTest::Test
179
179
  })
180
180
 
181
181
  assert_equal [
182
- [:respond, r, 'get /foo/bar', {':status' => 404, 'Foo' => 'Bar' }]
182
+ [:respond, r, 'GET /foo/bar', {':status' => 404, 'Foo' => 'Bar' }]
183
183
  ], r.response_calls
184
184
  end
185
185
  end
data/test/test_routing.rb CHANGED
@@ -114,4 +114,16 @@ class RoutingTest < MiniTest::Test
114
114
  assert_equal '/baz/d/e/f', default_relative_path
115
115
  assert_equal [[:respond, r, '/d/e/f', {}]], r.response_calls
116
116
  end
117
+
118
+ def test_well_known
119
+ app = Qeweney.route do |r|
120
+ r.on('.well-known/acme-challenge') { r.respond(r.route_relative_path) }
121
+ r.default { r.respond('not found') }
122
+ end
123
+
124
+ r = Qeweney.mock(':path' => '/.well-known/acme-challenge/foo')
125
+ app.(r)
126
+ assert_equal [[:respond, r, '/foo', {}]], r.response_calls
127
+ end
117
128
  end
129
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qeweney
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.10'
4
+ version: '0.14'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-24 00:00:00.000000000 Z
11
+ date: 2021-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  requirements: []
139
- rubygems_version: 3.1.4
139
+ rubygems_version: 3.1.6
140
140
  signing_key:
141
141
  specification_version: 4
142
142
  summary: Qeweney - cross library HTTP request / response API