webmachine 1.5.0 → 2.0.0.beta
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 +5 -5
- data/CHANGELOG.md +13 -0
- data/README.md +4 -5
- data/documentation/adapters.md +2 -11
- data/documentation/examples.md +12 -6
- data/examples/debugger.rb +5 -3
- data/examples/logging.rb +2 -2
- data/examples/webrick.rb +2 -2
- data/lib/webmachine/adapter.rb +0 -3
- data/lib/webmachine/adapters/lazy_request_body.rb +1 -1
- data/lib/webmachine/adapters/rack.rb +48 -34
- data/lib/webmachine/adapters/rack_mapped.rb +1 -2
- data/lib/webmachine/adapters/webrick.rb +11 -12
- data/lib/webmachine/adapters.rb +0 -2
- data/lib/webmachine/application.rb +2 -2
- data/lib/webmachine/chunked_body.rb +1 -1
- data/lib/webmachine/configuration.rb +1 -1
- data/lib/webmachine/constants.rb +14 -14
- data/lib/webmachine/cookie.rb +20 -18
- data/lib/webmachine/decision/conneg.rb +26 -26
- data/lib/webmachine/decision/falsey.rb +0 -1
- data/lib/webmachine/decision/flow.rb +19 -20
- data/lib/webmachine/decision/fsm.rb +4 -4
- data/lib/webmachine/decision/helpers.rb +21 -21
- data/lib/webmachine/dispatcher/route.rb +30 -16
- data/lib/webmachine/dispatcher.rb +3 -2
- data/lib/webmachine/errors.rb +7 -8
- data/lib/webmachine/etags.rb +2 -1
- data/lib/webmachine/header_negotiation.rb +5 -6
- data/lib/webmachine/headers.rb +5 -5
- data/lib/webmachine/media_type.rb +5 -5
- data/lib/webmachine/quoted_string.rb +3 -3
- data/lib/webmachine/request.rb +7 -10
- data/lib/webmachine/rescueable_exception.rb +3 -3
- data/lib/webmachine/resource/authentication.rb +3 -4
- data/lib/webmachine/resource/callbacks.rb +3 -3
- data/lib/webmachine/resource/encodings.rb +3 -9
- data/lib/webmachine/resource.rb +1 -1
- data/lib/webmachine/response.rb +7 -9
- data/lib/webmachine/spec/adapter_lint.rb +67 -69
- data/lib/webmachine/spec/test_resource.rb +26 -21
- data/lib/webmachine/streaming/encoder.rb +3 -2
- data/lib/webmachine/streaming/io_encoder.rb +4 -3
- data/lib/webmachine/trace/fsm.rb +25 -18
- data/lib/webmachine/trace/resource_proxy.rb +10 -9
- data/lib/webmachine/trace/static/http-headers-status-v3.png +0 -0
- data/lib/webmachine/trace/trace_resource.rb +22 -24
- data/lib/webmachine/trace.rb +7 -6
- data/lib/webmachine/translation.rb +3 -3
- data/lib/webmachine/version.rb +1 -1
- metadata +55 -90
- data/.gitignore +0 -31
- data/Gemfile +0 -44
- data/Guardfile +0 -11
- data/RELEASING.md +0 -21
- data/Rakefile +0 -44
- data/bethtemp +0 -3
- data/lib/webmachine/adapters/httpkit.rb +0 -74
- data/lib/webmachine/adapters/reel.rb +0 -113
- data/memory_test.rb +0 -37
- data/pkg/webmachine-1.5.0.gem +0 -0
- data/spec/spec_helper.rb +0 -56
- data/spec/webmachine/adapter_spec.rb +0 -39
- data/spec/webmachine/adapters/httpkit_spec.rb +0 -10
- data/spec/webmachine/adapters/rack_mapped_spec.rb +0 -71
- data/spec/webmachine/adapters/rack_spec.rb +0 -57
- data/spec/webmachine/adapters/reel_spec.rb +0 -76
- data/spec/webmachine/adapters/webrick_spec.rb +0 -12
- data/spec/webmachine/application_spec.rb +0 -74
- data/spec/webmachine/chunked_body_spec.rb +0 -30
- data/spec/webmachine/configuration_spec.rb +0 -27
- data/spec/webmachine/cookie_spec.rb +0 -99
- data/spec/webmachine/decision/conneg_spec.rb +0 -166
- data/spec/webmachine/decision/falsey_spec.rb +0 -8
- data/spec/webmachine/decision/flow_spec.rb +0 -1148
- data/spec/webmachine/decision/fsm_spec.rb +0 -163
- data/spec/webmachine/decision/helpers_spec.rb +0 -216
- data/spec/webmachine/dispatcher/route_spec.rb +0 -248
- data/spec/webmachine/dispatcher_spec.rb +0 -104
- data/spec/webmachine/errors_spec.rb +0 -13
- data/spec/webmachine/etags_spec.rb +0 -75
- data/spec/webmachine/events_spec.rb +0 -58
- data/spec/webmachine/headers_spec.rb +0 -99
- data/spec/webmachine/media_type_spec.rb +0 -85
- data/spec/webmachine/request_spec.rb +0 -273
- data/spec/webmachine/rescueable_exception_spec.rb +0 -15
- data/spec/webmachine/resource/authentication_spec.rb +0 -68
- data/spec/webmachine/response_spec.rb +0 -51
- data/spec/webmachine/trace/fsm_spec.rb +0 -37
- data/spec/webmachine/trace/resource_proxy_spec.rb +0 -34
- data/spec/webmachine/trace/trace_store_spec.rb +0 -29
- data/spec/webmachine/trace_spec.rb +0 -17
- data/webmachine.gemspec +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9fa67f8c8882d39968e933f1f3e40888e05f25ddb26754f04efb5f0ee6e85342
|
|
4
|
+
data.tar.gz: 979c3bef1f736792ea3b9754b6dd6837e2a02ba92b04ea0ac0b607260b09b5e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed27aee0010e3375d49c8e3e5bc38fba49073c177cf4e271f593beedc9ca7de272869be9ebd20fdafbd834e465d3d77f52052cbfe48f08713a296723a61c1776
|
|
7
|
+
data.tar.gz: e4b38c9ecc8183fefa4b40d90d69cda5c3b9f0b22828bbe59acd03fede5d907d54816488d7ded9b8677343a49a43c4a2c963b4b8aa31d29bb32825ff0361a3c4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
### HEAD
|
|
2
2
|
|
|
3
|
+
### 2.0.0.beta Mar 30, 2023
|
|
4
|
+
|
|
5
|
+
* Drop support for ruby 2.3, 2.4, and 2.5
|
|
6
|
+
* Remove the HTTPkit adapter
|
|
7
|
+
* Format cookie 'Expires' timestamps as per RFC 2616
|
|
8
|
+
|
|
9
|
+
### 1.6.0 June 22, 2021
|
|
10
|
+
|
|
11
|
+
* fix: replace missed URI.decode with new Route.rfc3986_percent_decode (#261)
|
|
12
|
+
* fix: implement rfc3986 Percent-Encoding decoder
|
|
13
|
+
* feat: make rack env available on the webmachine request when using a rack adapter
|
|
14
|
+
|
|
3
15
|
### 1.5.0 September 8, 2017
|
|
16
|
+
|
|
4
17
|
* Removed Fixnum/Integer deprecation warnings in Ruby 2.4
|
|
5
18
|
* Fixed multiple cookie setting code
|
|
6
19
|
* Added support for named captures
|
data/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# webmachine for Ruby
|
|
1
|
+
# webmachine for Ruby
|
|
2
|
+
[](https://badge.fury.io/rb/webmachine)
|
|
3
|
+
[](https://github.com/webmachine/webmachine-ruby/actions/workflows/test.yml)
|
|
2
4
|
|
|
3
5
|
webmachine-ruby is a port of
|
|
4
6
|
[Webmachine](https://github.com/basho/webmachine), which is written in
|
|
@@ -18,8 +20,7 @@ are up to you.
|
|
|
18
20
|
requests, and response codes for you.
|
|
19
21
|
* Provides a base resource with points of extension to let you
|
|
20
22
|
describe what is relevant about your particular resource.
|
|
21
|
-
* Supports WEBrick
|
|
22
|
-
servers are being investigated.
|
|
23
|
+
* Supports WEBrick and a Rack shim. Other host servers are being investigated.
|
|
23
24
|
* Streaming/chunked response bodies are permitted as Enumerables,
|
|
24
25
|
Procs, or Fibers!
|
|
25
26
|
* Unlike the Erlang original, it does real Language negotiation.
|
|
@@ -163,10 +164,8 @@ the "visual debugger". Learn how to configure it [here][visual-debugger].
|
|
|
163
164
|
|
|
164
165
|
## Related libraries
|
|
165
166
|
|
|
166
|
-
* [irwebmachine](https://github.com/generalassembly/irwebmachine) - IRB/Pry debugging of Webmachine applications
|
|
167
167
|
* [webmachine-test](https://github.com/bernd/webmachine-test) - Helpers for testing Webmachine applications
|
|
168
168
|
* [webmachine-linking](https://github.com/petejohanson/webmachine-linking) - Helpers for linking between Resources, and Web Linking
|
|
169
|
-
* [webmachine-sprockets](https://github.com/lgierth/webmachine-sprockets) - Integration with Sprockets assets packaging system
|
|
170
169
|
* [webmachine-actionview](https://github.com/rgarner/webmachine-actionview) - Integration of some Rails-style view conventions into Webmachine
|
|
171
170
|
* [jruby-http-kit](https://github.com/nLight/jruby-http-kit) - Includes an adapter for the Clojure-based Ring library/server
|
|
172
171
|
* [newrelic-webmachine](https://github.com/mdub/newrelic-webmachine) - NewRelic instrumentation
|
data/documentation/adapters.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
### Adapters
|
|
2
2
|
|
|
3
|
-
Webmachine includes
|
|
4
|
-
|
|
3
|
+
Webmachine includes an adapter for [WEBrick][webrick].
|
|
4
|
+
Additionally, the [Rack][rack] adapter lets it
|
|
5
5
|
run on any webserver that provides a Rack interface. It also lets it run on
|
|
6
6
|
[Shotgun][shotgun] ([example][shotgun_example]).
|
|
7
7
|
|
|
@@ -24,16 +24,7 @@ For an example of using Webmachine with Rack middleware, see the [Pact Broker][m
|
|
|
24
24
|
|
|
25
25
|
See the [Rack Adapter API docs][rack-adapter-api-docs] for more information.
|
|
26
26
|
|
|
27
|
-
#### A Note about MRI 1.9
|
|
28
|
-
|
|
29
|
-
The [Reel][reel] and [HTTPkit][httpkit]
|
|
30
|
-
adapters might crash with a `SystemStackError` on MRI 1.9 due to its
|
|
31
|
-
limited fiber stack size. If your application is affected by this, the
|
|
32
|
-
only known solution is to switch to JRuby, Rubinius or MRI 2.0.
|
|
33
|
-
|
|
34
27
|
[webrick]: http://rubydoc.info/stdlib/webrick
|
|
35
|
-
[reel]: https://github.com/celluloid/reel
|
|
36
|
-
[httpkit]: https://github.com/lgierth/httpkit
|
|
37
28
|
[rack]: https://github.com/rack/rack
|
|
38
29
|
[shotgun]: https://github.com/rtomayko/shotgun
|
|
39
30
|
[shotgun_example]: https://gist.github.com/4389220
|
data/documentation/examples.md
CHANGED
|
@@ -92,12 +92,15 @@ end
|
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
# POST to perform a task
|
|
95
|
-
* Override `allowed_methods` and `
|
|
96
|
-
* `
|
|
97
|
-
*
|
|
95
|
+
* Override `allowed_methods`, `process_post`, and `content_types_provided` (if the response has a content type).
|
|
96
|
+
* Rather than providing a method handler in the `content_type_provided` mappings, put all the code to be executed in `process_post`.
|
|
97
|
+
* `process_post` must return true, or the HTTP response code.
|
|
98
98
|
|
|
99
99
|
```ruby
|
|
100
100
|
class DispatchOrderResource < Webmachine::Resource
|
|
101
|
+
def content_types_provided
|
|
102
|
+
[["application/json"]]
|
|
103
|
+
end
|
|
101
104
|
|
|
102
105
|
def allowed_methods
|
|
103
106
|
["POST"]
|
|
@@ -108,9 +111,8 @@ class DispatchOrderResource < Webmachine::Resource
|
|
|
108
111
|
end
|
|
109
112
|
|
|
110
113
|
def process_post
|
|
111
|
-
@order.dispatch
|
|
112
|
-
response.
|
|
113
|
-
response.body = "Successfully dispatched order #{id}"
|
|
114
|
+
@order.dispatch(params['some_param'])
|
|
115
|
+
response.body = { message: "Successfully dispatched order #{id}" }.to_json
|
|
114
116
|
true
|
|
115
117
|
end
|
|
116
118
|
|
|
@@ -119,6 +121,10 @@ class DispatchOrderResource < Webmachine::Resource
|
|
|
119
121
|
def id
|
|
120
122
|
request.path_info[:id]
|
|
121
123
|
end
|
|
124
|
+
|
|
125
|
+
def params
|
|
126
|
+
JSON.parse(request.body.to_s)
|
|
127
|
+
end
|
|
122
128
|
end
|
|
123
129
|
|
|
124
130
|
```
|
data/examples/debugger.rb
CHANGED
|
@@ -2,21 +2,23 @@ require 'webmachine'
|
|
|
2
2
|
require 'webmachine/trace'
|
|
3
3
|
|
|
4
4
|
class MyTracedResource < Webmachine::Resource
|
|
5
|
-
def trace
|
|
5
|
+
def trace?
|
|
6
|
+
true
|
|
7
|
+
end
|
|
6
8
|
|
|
7
9
|
def resource_exists?
|
|
8
10
|
case request.query['e']
|
|
9
11
|
when 'true'
|
|
10
12
|
true
|
|
11
13
|
when 'fail'
|
|
12
|
-
raise
|
|
14
|
+
raise 'BOOM'
|
|
13
15
|
else
|
|
14
16
|
false
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def to_html
|
|
19
|
-
|
|
21
|
+
'<html>You found me.</html>'
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
|
data/examples/logging.rb
CHANGED
|
@@ -18,7 +18,7 @@ class LogListener
|
|
|
18
18
|
resource = event.payload[:resource]
|
|
19
19
|
code = event.payload[:code]
|
|
20
20
|
|
|
21
|
-
puts
|
|
21
|
+
puts '[%s] method=%s uri=%s code=%d resource=%s time=%.4f' % [
|
|
22
22
|
Time.now.iso8601, request.method, request.uri.to_s, code, resource,
|
|
23
23
|
event.duration
|
|
24
24
|
]
|
|
@@ -34,7 +34,7 @@ App = Webmachine::Application.new do |app|
|
|
|
34
34
|
|
|
35
35
|
app.configure do |config|
|
|
36
36
|
config.adapter = :WEBrick
|
|
37
|
-
config.adapter_options = {:
|
|
37
|
+
config.adapter_options = {AccessLog: [], Logger: Logger.new('/dev/null')}
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
data/examples/webrick.rb
CHANGED
|
@@ -6,11 +6,11 @@ class HelloResource < Webmachine::Resource
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def encodings_provided
|
|
9
|
-
{
|
|
9
|
+
{'gzip' => :encode_gzip, 'identity' => :encode_identity}
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def to_html
|
|
13
|
-
|
|
13
|
+
'<html><head><title>Hello from Webmachine</title></head><body>Hello, world!</body></html>'
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
data/lib/webmachine/adapter.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
module Webmachine
|
|
2
|
-
|
|
3
2
|
# The abstract class for definining a Webmachine adapter.
|
|
4
3
|
#
|
|
5
4
|
# @abstract Subclass and override {#run} to implement a custom adapter.
|
|
6
5
|
class Adapter
|
|
7
|
-
|
|
8
6
|
# @return [Webmachine::Application] returns the application
|
|
9
7
|
attr_reader :application
|
|
10
8
|
|
|
@@ -25,6 +23,5 @@ module Webmachine
|
|
|
25
23
|
def run
|
|
26
24
|
raise NotImplementedError
|
|
27
25
|
end
|
|
28
|
-
|
|
29
26
|
end
|
|
30
27
|
end
|
|
@@ -47,9 +47,9 @@ module Webmachine
|
|
|
47
47
|
# Start the Rack adapter
|
|
48
48
|
def run
|
|
49
49
|
options = DEFAULT_OPTIONS.merge({
|
|
50
|
-
:
|
|
51
|
-
:
|
|
52
|
-
:
|
|
50
|
+
app: self,
|
|
51
|
+
Port: application.configuration.port,
|
|
52
|
+
Host: application.configuration.ip
|
|
53
53
|
}).merge(application.configuration.adapter_options)
|
|
54
54
|
|
|
55
55
|
@server = ::Rack::Server.new(options)
|
|
@@ -69,33 +69,34 @@ module Webmachine
|
|
|
69
69
|
|
|
70
70
|
response.headers[SERVER] = VERSION_STRING
|
|
71
71
|
|
|
72
|
-
rack_status
|
|
72
|
+
rack_status = response.code
|
|
73
73
|
rack_headers = response.headers.flattened(NEWLINE)
|
|
74
74
|
rack_body = case response.body
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
75
|
+
when String # Strings are enumerable in ruby 1.8
|
|
76
|
+
[response.body]
|
|
77
|
+
else
|
|
78
|
+
if (io_body = IO.try_convert(response.body))
|
|
79
|
+
io_body
|
|
80
|
+
elsif response.body.respond_to?(:call)
|
|
81
|
+
Webmachine::ChunkedBody.new(Array(response.body.call))
|
|
82
|
+
elsif response.body.respond_to?(:each)
|
|
83
|
+
# This might be an IOEncoder with a Content-Length, which shouldn't be chunked.
|
|
84
|
+
if response.headers[TRANSFER_ENCODING] == 'chunked'
|
|
85
|
+
Webmachine::ChunkedBody.new(response.body)
|
|
86
|
+
else
|
|
87
|
+
response.body
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
[response.body.to_s]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
93
|
|
|
94
94
|
rack_res = RackResponse.new(rack_body, rack_status, rack_headers)
|
|
95
95
|
rack_res.finish
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
protected
|
|
99
|
+
|
|
99
100
|
def routing_tokens(rack_req)
|
|
100
101
|
nil # no-op for default, un-mapped rack adapter
|
|
101
102
|
end
|
|
@@ -105,28 +106,38 @@ module Webmachine
|
|
|
105
106
|
end
|
|
106
107
|
|
|
107
108
|
private
|
|
109
|
+
|
|
108
110
|
def build_webmachine_request(rack_req, headers)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
RackRequest.new(rack_req.request_method,
|
|
112
|
+
rack_req.url,
|
|
113
|
+
headers,
|
|
114
|
+
RequestBody.new(rack_req),
|
|
115
|
+
routing_tokens(rack_req),
|
|
116
|
+
base_uri(rack_req),
|
|
117
|
+
rack_req.env)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
class RackRequest < Webmachine::Request
|
|
121
|
+
attr_reader :env
|
|
122
|
+
|
|
123
|
+
def initialize(method, uri, headers, body, routing_tokens, base_uri, env)
|
|
124
|
+
super(method, uri, headers, body, routing_tokens, base_uri)
|
|
125
|
+
@env = env
|
|
126
|
+
end
|
|
116
127
|
end
|
|
117
128
|
|
|
118
129
|
class RackResponse
|
|
119
130
|
ONE_FIVE = '1.5'.freeze
|
|
120
131
|
|
|
121
132
|
def initialize(body, status, headers)
|
|
122
|
-
@body
|
|
123
|
-
@status
|
|
133
|
+
@body = body
|
|
134
|
+
@status = status
|
|
124
135
|
@headers = headers
|
|
125
136
|
end
|
|
126
137
|
|
|
127
138
|
def finish
|
|
128
139
|
@headers[CONTENT_TYPE] ||= TEXT_HTML if rack_release_enforcing_content_type
|
|
129
|
-
@headers.delete(CONTENT_TYPE)
|
|
140
|
+
@headers.delete(CONTENT_TYPE) if response_without_body
|
|
130
141
|
[@status, @headers, @body]
|
|
131
142
|
end
|
|
132
143
|
|
|
@@ -178,10 +189,13 @@ module Webmachine
|
|
|
178
189
|
# @yieldparam [String] chunk a chunk of the request body
|
|
179
190
|
def each
|
|
180
191
|
if @value
|
|
181
|
-
@value.each {|chunk| yield chunk }
|
|
192
|
+
@value.each { |chunk| yield chunk }
|
|
182
193
|
else
|
|
183
194
|
@value = []
|
|
184
|
-
@request.body.each {|chunk|
|
|
195
|
+
@request.body.each { |chunk|
|
|
196
|
+
@value << chunk
|
|
197
|
+
yield chunk
|
|
198
|
+
}
|
|
185
199
|
end
|
|
186
200
|
end
|
|
187
201
|
end # class RequestBody
|
|
@@ -21,12 +21,11 @@ module Webmachine
|
|
|
21
21
|
# end
|
|
22
22
|
# end
|
|
23
23
|
class RackMapped < Rack
|
|
24
|
-
|
|
25
24
|
protected
|
|
26
25
|
|
|
27
26
|
def routing_tokens(rack_req)
|
|
28
27
|
routing_match = rack_req.path_info.match(Webmachine::Request::ROUTING_PATH_MATCH)
|
|
29
|
-
routing_path = routing_match ? routing_match[1] :
|
|
28
|
+
routing_path = routing_match ? routing_match[1] : ''
|
|
30
29
|
routing_path.split(SLASH)
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -17,9 +17,9 @@ module Webmachine
|
|
|
17
17
|
# Starts the WEBrick adapter
|
|
18
18
|
def run
|
|
19
19
|
options = DEFAULT_OPTIONS.merge({
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
:
|
|
20
|
+
Port: application.configuration.port,
|
|
21
|
+
BindAddress: application.configuration.ip,
|
|
22
|
+
application: application
|
|
23
23
|
}).merge(application.configuration.adapter_options)
|
|
24
24
|
@server = Server.new(options)
|
|
25
25
|
@server.start
|
|
@@ -27,7 +27,6 @@ module Webmachine
|
|
|
27
27
|
|
|
28
28
|
# WEBRick::HTTPServer that is run by the WEBrick adapter.
|
|
29
29
|
class Server < ::WEBrick::HTTPServer
|
|
30
|
-
|
|
31
30
|
def initialize(options)
|
|
32
31
|
@application = options[:application]
|
|
33
32
|
super(options)
|
|
@@ -36,29 +35,29 @@ module Webmachine
|
|
|
36
35
|
# Handles a request
|
|
37
36
|
def service(wreq, wres)
|
|
38
37
|
header = Webmachine::Headers.new
|
|
39
|
-
wreq.each {|k,v| header[k] = v }
|
|
38
|
+
wreq.each { |k, v| header[k] = v }
|
|
40
39
|
request = Webmachine::Request.new(wreq.request_method,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
wreq.request_uri,
|
|
41
|
+
header,
|
|
42
|
+
LazyRequestBody.new(wreq))
|
|
44
43
|
|
|
45
44
|
response = Webmachine::Response.new
|
|
46
45
|
@application.dispatcher.dispatch(request, response)
|
|
47
46
|
wres.status = response.code.to_i
|
|
48
47
|
|
|
49
|
-
headers = response.headers.flattened.reject { |k,v| k == 'Set-Cookie' }
|
|
50
|
-
headers.each { |k,v| wres[k] = v }
|
|
48
|
+
headers = response.headers.flattened.reject { |k, v| k == 'Set-Cookie' }
|
|
49
|
+
headers.each { |k, v| wres[k] = v }
|
|
51
50
|
|
|
52
51
|
cookies = [response.headers['Set-Cookie'] || []].flatten
|
|
53
52
|
cookies.each { |c| wres.cookies << c }
|
|
54
53
|
|
|
55
|
-
wres[SERVER] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(
|
|
54
|
+
wres[SERVER] = [Webmachine::SERVER_STRING, wres.config[:ServerSoftware]].join(' ')
|
|
56
55
|
case response.body
|
|
57
56
|
when String
|
|
58
57
|
wres.body << response.body
|
|
59
58
|
when Enumerable
|
|
60
59
|
wres.chunked = response.headers[TRANSFER_ENCODING] == 'chunked'
|
|
61
|
-
response.body.each {|part| wres.body << part }
|
|
60
|
+
response.body.each { |part| wres.body << part }
|
|
62
61
|
else
|
|
63
62
|
if response.body.respond_to?(:call)
|
|
64
63
|
wres.chunked = true
|
data/lib/webmachine/adapters.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Webmachine
|
|
|
43
43
|
# the Application instance being initialized
|
|
44
44
|
def initialize(configuration = Configuration.default, dispatcher = Dispatcher.new)
|
|
45
45
|
@configuration = configuration
|
|
46
|
-
@dispatcher
|
|
46
|
+
@dispatcher = dispatcher
|
|
47
47
|
|
|
48
48
|
yield self if block_given?
|
|
49
49
|
end
|
|
@@ -73,7 +73,7 @@ module Webmachine
|
|
|
73
73
|
#
|
|
74
74
|
# @see Webmachine::Dispatcher#add_route
|
|
75
75
|
def routes(&block)
|
|
76
|
-
if
|
|
76
|
+
if block
|
|
77
77
|
dispatcher.instance_eval(&block)
|
|
78
78
|
self
|
|
79
79
|
else
|
data/lib/webmachine/constants.rb
CHANGED
|
@@ -28,20 +28,20 @@
|
|
|
28
28
|
|
|
29
29
|
MATCHES_ALL = '*/*'.freeze
|
|
30
30
|
|
|
31
|
-
GET_METHOD
|
|
32
|
-
HEAD_METHOD
|
|
33
|
-
POST_METHOD
|
|
34
|
-
PUT_METHOD
|
|
35
|
-
DELETE_METHOD
|
|
36
|
-
OPTIONS_METHOD =
|
|
37
|
-
TRACE_METHOD
|
|
38
|
-
CONNECT_METHOD =
|
|
31
|
+
GET_METHOD = 'GET'
|
|
32
|
+
HEAD_METHOD = 'HEAD'
|
|
33
|
+
POST_METHOD = 'POST'
|
|
34
|
+
PUT_METHOD = 'PUT'
|
|
35
|
+
DELETE_METHOD = 'DELETE'
|
|
36
|
+
OPTIONS_METHOD = 'OPTIONS'
|
|
37
|
+
TRACE_METHOD = 'TRACE'
|
|
38
|
+
CONNECT_METHOD = 'CONNECT'
|
|
39
39
|
|
|
40
40
|
STANDARD_HTTP_METHODS = [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
GET_METHOD, HEAD_METHOD, POST_METHOD,
|
|
42
|
+
PUT_METHOD, DELETE_METHOD, TRACE_METHOD,
|
|
43
|
+
CONNECT_METHOD, OPTIONS_METHOD
|
|
44
|
+
].map!(&:freeze)
|
|
45
45
|
STANDARD_HTTP_METHODS.freeze
|
|
46
46
|
|
|
47
47
|
# A colon
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
# Charset string
|
|
60
60
|
CHARSET = 'Charset'.freeze
|
|
61
61
|
|
|
62
|
-
#
|
|
63
|
-
|
|
62
|
+
# Comma split match
|
|
63
|
+
SPLIT_COMMA = /\s*,\s*/.freeze
|
|
64
64
|
|
|
65
65
|
# Star Character
|
|
66
66
|
STAR = '*'.freeze
|
data/lib/webmachine/cookie.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Webmachine
|
|
|
11
11
|
def self.parse(cstr, include_dups = false)
|
|
12
12
|
cookies = {}
|
|
13
13
|
(cstr || '').split(/\s*[;,]\s*/n).each { |c|
|
|
14
|
-
k,v = c.split(/\s*=\s*/, 2).map { |s| unescape(s) }
|
|
14
|
+
k, v = c.split(/\s*=\s*/, 2).map { |s| unescape(s) }
|
|
15
15
|
|
|
16
16
|
case cookies[k]
|
|
17
17
|
when nil
|
|
@@ -31,7 +31,7 @@ module Webmachine
|
|
|
31
31
|
# Allowed keys for the attributes parameter of
|
|
32
32
|
# {Webmachine::Cookie#initialize}
|
|
33
33
|
ALLOWED_ATTRIBUTES = [:secure, :httponly, :path, :domain,
|
|
34
|
-
|
|
34
|
+
:comment, :maxage, :expires, :version]
|
|
35
35
|
|
|
36
36
|
# If the cookie is HTTP only
|
|
37
37
|
def http_only?
|
|
@@ -83,32 +83,34 @@ module Webmachine
|
|
|
83
83
|
attributes = ALLOWED_ATTRIBUTES.select { |a| @attributes[a] }.map do |a|
|
|
84
84
|
case a
|
|
85
85
|
when :httponly
|
|
86
|
-
|
|
86
|
+
'HttpOnly' if @attributes[a]
|
|
87
87
|
when :secure
|
|
88
|
-
|
|
88
|
+
'Secure' if @attributes[a]
|
|
89
89
|
when :maxage
|
|
90
|
-
|
|
90
|
+
'Max-Age=' + @attributes[a].to_s
|
|
91
91
|
when :expires
|
|
92
|
-
|
|
92
|
+
'Expires=' + rfc2822(@attributes[a])
|
|
93
93
|
when :comment
|
|
94
|
-
|
|
94
|
+
'Comment=' + escape(@attributes[a].to_s)
|
|
95
95
|
else
|
|
96
|
-
a.to_s.sub(/^\w/) { $&.capitalize } +
|
|
96
|
+
a.to_s.sub(/^\w/) { $&.capitalize } + '=' + @attributes[a].to_s
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
([escape(name) +
|
|
100
|
+
([escape(name) + '=' + escape(value)] + attributes).join('; ')
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
private
|
|
104
104
|
|
|
105
|
+
# Format timestamps for the 'Expires' portion of the cookie string, as per RFC 2822 and 2616.
|
|
106
|
+
#
|
|
107
|
+
# @see https://www.rfc-editor.org/rfc/rfc2616#section-3.3.1
|
|
108
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires
|
|
105
109
|
def rfc2822(time)
|
|
106
|
-
|
|
107
|
-
mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
|
|
108
|
-
time.strftime("#{wday}, %d-#{mon}-%Y %H:%M:%S GMT")
|
|
110
|
+
time.strftime('%a, %d %b %Y %T GMT')
|
|
109
111
|
end
|
|
110
112
|
|
|
111
|
-
if URI.respond_to?(:decode_www_form_component)
|
|
113
|
+
if URI.respond_to?(:decode_www_form_component) && defined?(::Encoding)
|
|
112
114
|
# Escape a cookie
|
|
113
115
|
def escape(s)
|
|
114
116
|
URI.encode_www_form_component(s)
|
|
@@ -132,7 +134,7 @@ module Webmachine
|
|
|
132
134
|
# @private
|
|
133
135
|
TBLDECWWWCOMP_ = {}
|
|
134
136
|
256.times do |i|
|
|
135
|
-
h, l = i>>4, i&15
|
|
137
|
+
h, l = i >> 4, i & 15
|
|
136
138
|
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
|
137
139
|
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
|
138
140
|
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
|
@@ -146,9 +148,9 @@ module Webmachine
|
|
|
146
148
|
# This decodes + to SP.
|
|
147
149
|
#
|
|
148
150
|
# @private
|
|
149
|
-
def self.unescape(str, enc=nil)
|
|
150
|
-
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%\h\h|[^%]+)*\z
|
|
151
|
-
str.gsub(/\+|%\h\h/){|c| TBLDECWWWCOMP_[c] }
|
|
151
|
+
def self.unescape(str, enc = nil)
|
|
152
|
+
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%\h\h|[^%]+)*\z/.match?(str)
|
|
153
|
+
str.gsub(/\+|%\h\h/) { |c| TBLDECWWWCOMP_[c] }
|
|
152
154
|
end
|
|
153
155
|
|
|
154
156
|
# Encode given +str+ to URL-encoded form data.
|
|
@@ -161,7 +163,7 @@ module Webmachine
|
|
|
161
163
|
#
|
|
162
164
|
# @private
|
|
163
165
|
def escape(str)
|
|
164
|
-
str.to_s.gsub(/[^*\-.0-9A-Z_a-z]/){|c| TBLENCWWWCOMP_[c] }
|
|
166
|
+
str.to_s.gsub(/[^*\-.0-9A-Z_a-z]/) { |c| TBLENCWWWCOMP_[c] }
|
|
165
167
|
end
|
|
166
168
|
end
|
|
167
169
|
end
|