webmachine 1.2.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/CHANGELOG.md +218 -0
- data/Gemfile +7 -6
- data/README.md +76 -273
- data/lib/webmachine/adapters/reel.rb +9 -8
- data/lib/webmachine/decision/flow.rb +1 -1
- data/lib/webmachine/decision/fsm.rb +3 -2
- data/lib/webmachine/decision/helpers.rb +8 -0
- data/lib/webmachine/dispatcher.rb +9 -10
- data/lib/webmachine/dispatcher/not_found_resource.rb +5 -0
- data/lib/webmachine/media_type.rb +2 -2
- data/{spec/support → lib/webmachine/spec}/adapter_lint.rb +1 -1
- data/{spec/support → lib/webmachine/spec}/test_resource.rb +0 -0
- data/lib/webmachine/version.rb +1 -1
- data/spec/webmachine/adapters/hatetepe_spec.rb +0 -4
- data/spec/webmachine/adapters/mongrel_spec.rb +1 -1
- data/spec/webmachine/adapters/rack_spec.rb +1 -1
- data/spec/webmachine/adapters/reel_spec.rb +52 -55
- data/spec/webmachine/adapters/webrick_spec.rb +1 -1
- data/spec/webmachine/decision/flow_spec.rb +12 -6
- data/spec/webmachine/dispatcher_spec.rb +7 -0
- data/spec/webmachine/media_type_spec.rb +7 -0
- data/webmachine.gemspec +1 -2
- metadata +9 -26
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
### 1.2.2 January 8, 2014
|
2
|
+
|
3
|
+
1.2.2 is a bugfix/patch release that expands functionality with some edge
|
4
|
+
cases, and fixes a couple of bugs. Thank you to the new contributors:
|
5
|
+
Judson Lester, John Bachir, and @bethesque!
|
6
|
+
|
7
|
+
* Added Date header to responses, it's mandatory.
|
8
|
+
* Updated RSpec options to never load DRb, since it breaks the test suite.
|
9
|
+
* Updated FSM to respond with 404 if no route matches.
|
10
|
+
* Added support for key-only extensions in content negotiation.
|
11
|
+
* Improved the README file.
|
12
|
+
* Fixed insignificance of `handle_exception` callback's return value.
|
13
|
+
* Fixed CI setup with regards to Rubinius and JRuby.
|
14
|
+
* Several smaller code cleanups.
|
15
|
+
|
16
|
+
### 1.2.1 September 28, 2013
|
17
|
+
|
18
|
+
1.2.1 is a bugfix/patch release but does introduce potentially
|
19
|
+
breaking changes in the Reel adapter. With this release, Webmachine no
|
20
|
+
longer explicitly supports Ruby 1.8.
|
21
|
+
|
22
|
+
* Updated Reel compatibility to 0.4.
|
23
|
+
* Updated Hatetepe compatibility to 0.5.2.
|
24
|
+
* Cleaned up the gemspec so bundler scripts are not included.
|
25
|
+
* Added license information to the gemspec.
|
26
|
+
* Added a link to jruby-http-kit in the README.
|
27
|
+
* Moved adapter_lint to lib/webmachine/spec so other libraries can
|
28
|
+
test adapters that are not in the Webmachine gem.
|
29
|
+
|
30
|
+
### 1.2.0 September 7, 2013
|
31
|
+
|
32
|
+
1.2.0 is a major feature release that adds the Events instrumentation
|
33
|
+
framework, support for Websockets in Reel adapter and a bunch of bugfixes.
|
34
|
+
Added Justin McPherson and Hendrik Beskow as contributors. Thank you
|
35
|
+
for your contributions!
|
36
|
+
|
37
|
+
* Websockets support in Reel adapter.
|
38
|
+
* Added `Events` framework implementing ActiveSupport::Notifications
|
39
|
+
instrumentation API.
|
40
|
+
* Linked mailing list and related library in README.
|
41
|
+
* Fixed operator precedence in `IOEncoder#each`.
|
42
|
+
* Fixed typo in Max-Age cookie attribute.
|
43
|
+
* Allowed attributes to be set in a `Cookie`.
|
44
|
+
* Fixed streaming in Rack adapter from Fiber that is expected
|
45
|
+
to block
|
46
|
+
* Added a more comprehensive adapter test suite and fixed various bugs
|
47
|
+
in the existing adapters.
|
48
|
+
* Webmachine::LazyRequestBody no longer double-buffers the request
|
49
|
+
body and cannot be rewound.
|
50
|
+
|
51
|
+
### 1.1.0 January 12, 2013
|
52
|
+
|
53
|
+
1.1.0 is a major feature release that adds the Reel and Hatetepe
|
54
|
+
adapters, support for "weak" entity tags, streaming IO response
|
55
|
+
bodies, better error handling, a shortcut for spinning up specific
|
56
|
+
resources, and a bunch of bugfixes. Added Tony Arcieri, Sebastian
|
57
|
+
Edwards, Russell Garner, Justin McPherson, Paweł Pacana, and Nicholas
|
58
|
+
Young as contributors. Thank you for your contributions!
|
59
|
+
|
60
|
+
* Added Reel adapter.
|
61
|
+
* The trace resource now opens static files in binary mode to ensure
|
62
|
+
compatibility on Windows.
|
63
|
+
* The trace resource uses absolute URIs for its traces.
|
64
|
+
* Added Hatetepe adapter.
|
65
|
+
* Added direct weak entity tag support.
|
66
|
+
* Related libraries are linked from the README.
|
67
|
+
* Removed some circular requires.
|
68
|
+
* Fixed documentation for the `valid_content_headers?` callback.
|
69
|
+
* Fixed `Headers` initialization by downcasing incoming header names.
|
70
|
+
* Added a `Headers#fetch` method.
|
71
|
+
* Conventionally "truthy" and "falsey" values (non-nil, non-false) can
|
72
|
+
now be returned from callbacks that expect a boolean return value.
|
73
|
+
* Updated to the latest RSpec.
|
74
|
+
* Added support for IO response bodies (minimal).
|
75
|
+
* Moved streaming encoders to their own module for clarity.
|
76
|
+
* Added `Resource#run` that starts up a web server with default
|
77
|
+
configuration options and the catch-all route to the resource.
|
78
|
+
* The exception handling flow was improved, clarifying the
|
79
|
+
`handle_exception` and `finish_request` callbacks.
|
80
|
+
* Fix incompatibilities with Rack.
|
81
|
+
* The request URI will not be initialized with parts that are not
|
82
|
+
present in the HTTP request.
|
83
|
+
* The tracing will now commit to storage after the response has been
|
84
|
+
traced.
|
85
|
+
|
86
|
+
### 1.0.0 July 7, 2012
|
87
|
+
|
88
|
+
1.0.0 is a major feature release that finally includes the visual
|
89
|
+
debugger, some nice cookie support, and some new extension
|
90
|
+
points. Added Peter Johanson and Armin Joellenbeck as
|
91
|
+
contributors. Thank you for your contributions!
|
92
|
+
|
93
|
+
* A cookie parsing and manipulation API was added.
|
94
|
+
* Conneg headers now accept any amount of whitespace around commas,
|
95
|
+
including none.
|
96
|
+
* `Callbacks#handle_exception` was added so that resources can handle
|
97
|
+
exceptions that they generate and produce more friendly responses.
|
98
|
+
* Chunked and non-chunked response bodies in the Rack adapter were
|
99
|
+
fixed.
|
100
|
+
* The WEBrick example was updated to use the new API.
|
101
|
+
* `Dispatcher` was refactored so that you can modify how resources
|
102
|
+
are initialized before dispatching occurs.
|
103
|
+
* `Route` now includes the `Translation` module so that exception
|
104
|
+
messages are properly rendered.
|
105
|
+
* The visual debugger was added (more details in the README).
|
106
|
+
* The `Content-Length` header will always be set inside Webmachine and
|
107
|
+
is no longer reliant on the adapter to set it.
|
108
|
+
|
109
|
+
### 0.4.2 March 22, 2012
|
110
|
+
|
111
|
+
0.4.2 is a bugfix release that corrects a few minor issues. Added Lars
|
112
|
+
Gierth and Rob Gleeson as contributors. Thank you for your
|
113
|
+
contributions!
|
114
|
+
|
115
|
+
* I always intended for Webmachine-Ruby to be Apache licensed, but now
|
116
|
+
that is explicit.
|
117
|
+
* When the `#process_post` callback returns an invalid value, that
|
118
|
+
will now be `inspect`ed in the raised exception's message.
|
119
|
+
* Route bindings are now applied to the `Request` object before the
|
120
|
+
`Resource` class is instantiated. This means you can inspect them
|
121
|
+
inside the `#initialize` method of your resource.
|
122
|
+
* Some `NameError` exceptions and scope problems in the Mongrel
|
123
|
+
adapter were resolved.
|
124
|
+
* URL-encoded `=` characters in the query string decoded in the proper
|
125
|
+
order.
|
126
|
+
|
127
|
+
### 0.4.1 February 8, 2012
|
128
|
+
|
129
|
+
0.4.1 is a bugfix release that corrects a few minor issues. Added Sam
|
130
|
+
Goldman as a contributor. Thank you for your contributions!
|
131
|
+
|
132
|
+
* Updated README with `Webmachine::Application` examples.
|
133
|
+
* The CGI env vars `CONTENT_LENGTH` and `CONTENT_TYPE` are now being
|
134
|
+
correctly converted into their Webmachine equivalents.
|
135
|
+
* The request body given via the Rack and Mongrel adapters now
|
136
|
+
responds to `#to_s` and `#each` so it can be treated like a `String`
|
137
|
+
or `Enumerable` that yields chunks.
|
138
|
+
|
139
|
+
### 0.4.0 February 5, 2012
|
140
|
+
|
141
|
+
0.4.0 includes some important refactorings, isolating the idea of
|
142
|
+
global state into an Application object with its own Dispatcher and
|
143
|
+
configuration, and making Adapters into real classes with a consistent
|
144
|
+
interface. It also adds some query methods on the Request object for
|
145
|
+
the HTTP method and scheme and Route guards (matching predicates).
|
146
|
+
Added Michael Maltese, Emmanuel Gomez, and Bernerd Schaefer as
|
147
|
+
committers. Thank you for your contributions!
|
148
|
+
|
149
|
+
* Fixed `Request#query` to handle nil values for the URI query accessor.
|
150
|
+
* `Webmachine::Dispatcher` is a real class rather than a module with
|
151
|
+
state.
|
152
|
+
* `Webmachine::Application` is a class that includes its own
|
153
|
+
dispatcher and configuration. The default instance is accessible via
|
154
|
+
`Webmachine.application`.
|
155
|
+
* `Webmachine::Adapter` is now the superclass of all implemented
|
156
|
+
adapters so that they have a uniform interface.
|
157
|
+
* The Mongrel spec is skipped on JRuby since version 1.2 (pre-release)
|
158
|
+
doesn't work. Direct Mongrel support may be removed in a later
|
159
|
+
release.
|
160
|
+
* `Webmachine::Dispatcher::Route` now accepts guards, which may be
|
161
|
+
expressed as lambdas/procs or any object responding to `call`
|
162
|
+
preceding the `Resource` class in the route definition, or as a
|
163
|
+
trailing block. All guards will be passed the `Request` object when
|
164
|
+
matching the route and should return a truthy or falsey value
|
165
|
+
(without side-effects).
|
166
|
+
|
167
|
+
### 0.3.0 November 9, 2011
|
168
|
+
|
169
|
+
0.3.0 introduces some new features, refactorings, and now has 100%
|
170
|
+
documentation coverage! Among the new features are minimal Rack
|
171
|
+
compatibility, streaming responses via Fibers and a friendlier route
|
172
|
+
definition syntax. Added Jamis Buck as a committer. Thank you for your
|
173
|
+
contributions!
|
174
|
+
|
175
|
+
* Chunked bodies are now wrapped in a way that works on webservers
|
176
|
+
that don't automatically produce them.
|
177
|
+
* HTTP Basic Authentication is easy to add to resources, just include
|
178
|
+
`Webmachine::Resource::Authentication`.
|
179
|
+
* Routes are a little less painful to add, you can now specify them
|
180
|
+
with `Webmachine.routes` which will be evaled into the `Dispatcher`.
|
181
|
+
* The new default port is 8080.
|
182
|
+
* Rack is minimally supported as a host server. _Don't put middleware
|
183
|
+
above Webmachine!_
|
184
|
+
* Fibers can be used as streamed response bodies.
|
185
|
+
* `Dispatcher#add_route` will now return the added `Route` instance.
|
186
|
+
* The header-conversion code for CGI-style servers has been extracted
|
187
|
+
into `Webmachine::Headers`.
|
188
|
+
* `Route#path_spec` is now public so that applications can inspect
|
189
|
+
existing routes, perhaps for URL generation.
|
190
|
+
* `Request#query` now uses `CGI.unescape` so '+' characters are
|
191
|
+
correctly parsed.
|
192
|
+
* YARD documentation has 100% coverage.
|
193
|
+
|
194
|
+
### 0.2.0 September 11, 2011
|
195
|
+
|
196
|
+
0.2.0 includes an adapter for Mongrel and a central place for
|
197
|
+
configuration as well as numerous bugfixes. Added Ian Plosker and
|
198
|
+
Bernd Ahlers as committers. Thank you for your contributions!
|
199
|
+
|
200
|
+
* Acceptable media types are matched less strictly, which has
|
201
|
+
implications on both responses and PUT requests. See the
|
202
|
+
[discussion on the commit](https://github.com/seancribbs/webmachine-ruby/commit/3686d0d9ff77fc98aff59f89478e9c6c18844ca1).
|
203
|
+
* Resources now receive a callback after the language has been
|
204
|
+
negotiated, so they can decide what to do with it.
|
205
|
+
* Added `Webmachine::Configuration` so we can more easily support more
|
206
|
+
than one host server/adapter.
|
207
|
+
* Added Mongrel adapter, supporting 1.2pre+.
|
208
|
+
* Media type headers are more lax about whitespace following
|
209
|
+
semicolons.
|
210
|
+
* Fix some problems with callable response bodies.
|
211
|
+
* Make sure String response bodies get a Content-Length header added
|
212
|
+
and streaming responses get chunked encoding.
|
213
|
+
* Numerous refactorings, including extracting `MediaType` into its own
|
214
|
+
top-level class.
|
215
|
+
|
216
|
+
### 0.1.0 August 25, 2011
|
217
|
+
|
218
|
+
This is the initial release. Most things work, but only WEBrick is supported.
|
data/Gemfile
CHANGED
@@ -8,12 +8,8 @@ gem 'bundler'
|
|
8
8
|
|
9
9
|
group :webservers do
|
10
10
|
gem 'mongrel', '~> 1.2.beta', :platform => [:mri, :rbx]
|
11
|
-
|
12
|
-
|
13
|
-
gem 'reel', '~> 0.3.0', :platform => [:ruby_19, :ruby_20, :jruby]
|
14
|
-
end
|
15
|
-
|
16
|
-
gem 'hatetepe', '~> 0.5'
|
11
|
+
gem 'reel', '~> 0.4.0.pre5'
|
12
|
+
gem 'hatetepe', '~> 0.5.2'
|
17
13
|
end
|
18
14
|
|
19
15
|
group :guard do
|
@@ -38,3 +34,8 @@ end
|
|
38
34
|
platforms :jruby do
|
39
35
|
gem 'jruby-openssl'
|
40
36
|
end
|
37
|
+
|
38
|
+
platform :rbx do
|
39
|
+
gem 'rubysl'
|
40
|
+
gem 'racc'
|
41
|
+
end
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# webmachine for Ruby [![travis](https://
|
1
|
+
# webmachine for Ruby [![travis](https://travis-ci.org/seancribbs/webmachine-ruby.png?branch=master)](http://travis-ci.org/seancribbs/webmachine-ruby)
|
2
2
|
|
3
3
|
webmachine-ruby is a port of
|
4
4
|
[Webmachine](https://github.com/basho/webmachine), which is written in
|
@@ -11,97 +11,118 @@ toolkit for building HTTP-friendly applications. For example, it does
|
|
11
11
|
not provide a templating engine or a persistence layer; those choices
|
12
12
|
are up to you.
|
13
13
|
|
14
|
+
## Features
|
15
|
+
|
16
|
+
* Handles the hard parts of content negotiation, conditional
|
17
|
+
requests, and response codes for you.
|
18
|
+
* Most callbacks can interrupt the decision flow by returning an
|
19
|
+
integer response code. You generally only want to do this when new
|
20
|
+
information comes to light, requiring a modification of the response.
|
21
|
+
* Supports WEBrick and Mongrel (1.2pre+), and a Rack shim. Other host
|
22
|
+
servers are being investigated.
|
23
|
+
* Streaming/chunked response bodies are permitted as Enumerables,
|
24
|
+
Procs, or Fibers!
|
25
|
+
* Unlike the Erlang original, it does real Language negotiation.
|
26
|
+
* Includes the visual debugger so you can look through the decision
|
27
|
+
graph to determine how your resources are behaving.
|
28
|
+
|
29
|
+
## Documentation & Finding Help
|
30
|
+
|
31
|
+
* [API documentation](http://rubydoc.info/gems/webmachine/frames/file/README.md)
|
32
|
+
* [Mailing list](mailto:webmachine.rb@librelist.com)
|
33
|
+
* IRC channel #webmachine on freenode
|
34
|
+
|
14
35
|
## A Note about Rack
|
15
36
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
when given a clear stack.
|
37
|
+
In order to be compatible with popular deployment stacks,
|
38
|
+
Webmachine has a [Rack](https://github.com/rack/rack) adapter (thanks to Jamis Buck).
|
39
|
+
**n.b.:** We recommend that NO middleware is used. The
|
40
|
+
behaviors that are encapsulated in Webmachine assume that no modifications
|
41
|
+
are done to requests or response outside of Webmachine.
|
22
42
|
|
23
|
-
##
|
43
|
+
## A Note about MRI 1.9
|
24
44
|
|
25
|
-
|
26
|
-
|
45
|
+
The [Reel](https://github.com/celluloid/reel) and [Hatetepe](https://github.com/lgierth/hatetepe)
|
46
|
+
adapters might crash with a `SystemStackError` on MRI 1.9 due to its
|
47
|
+
limited fiber stack size. If your application is affected by this, the
|
48
|
+
only known solution is to switch to JRuby, Rubinius or MRI 2.0.
|
27
49
|
|
28
|
-
```ruby
|
29
|
-
require 'webmachine'
|
30
|
-
# Require any of the files that contain your resources here
|
31
|
-
require 'my_resource'
|
32
50
|
|
33
|
-
|
34
|
-
MyApp = Webmachine::Application.new do |app|
|
35
|
-
app.routes do
|
36
|
-
# Point all URIs at the MyResource class
|
37
|
-
add ['*'], MyResource
|
38
|
-
end
|
39
|
-
end
|
51
|
+
## Getting Started
|
40
52
|
|
41
|
-
|
42
|
-
|
43
|
-
|
53
|
+
[GiddyUp](https://github.com/basho/giddyup) is an actively
|
54
|
+
developed webmachine-ruby app that is in production. You
|
55
|
+
can look there for an example of how to write and structure a
|
56
|
+
webmachine-ruby app (although it is hacky in places).
|
57
|
+
|
58
|
+
Below we go through some examples of how to do basic things
|
59
|
+
with webmachine-ruby.
|
44
60
|
|
45
|
-
|
61
|
+
The first example defines a simple resource that doesn't demo the
|
62
|
+
true power of Webmachine but perhaps gives a feel for how a
|
63
|
+
Webmachine resource might look. `Webmachine::Resource.run` is available
|
64
|
+
to provide for quick prototyping and development. In a real application
|
65
|
+
you will want to configure what path a resource is served from.
|
66
|
+
See the __Router__ section in the README for more details on how to
|
67
|
+
do that.
|
68
|
+
|
69
|
+
There are many other HTTP features exposed to a resource through
|
70
|
+
{Webmachine::Resource::Callbacks}. A callback can alter the outcome
|
71
|
+
of the decision tree Webmachine implements, and the decision tree
|
72
|
+
is what makes Webmachine unique and powerful.
|
46
73
|
|
47
74
|
```ruby
|
75
|
+
require 'webmachine'
|
48
76
|
class MyResource < Webmachine::Resource
|
49
77
|
def to_html
|
50
78
|
"<html><body>Hello, world!</body></html>"
|
51
79
|
end
|
52
80
|
end
|
81
|
+
|
82
|
+
# Start a web server to serve requests via localhost
|
83
|
+
MyResource.run
|
53
84
|
```
|
54
85
|
|
55
|
-
|
56
|
-
it! If you want to customize your resource more, look at the available
|
57
|
-
callbacks in lib/webmachine/resource/callbacks.rb. For example, you
|
58
|
-
might want to enable "gzip" compression on your resource, for which
|
59
|
-
you can simply add an `encodings_provided` callback method:
|
86
|
+
### Router
|
60
87
|
|
61
|
-
|
62
|
-
|
63
|
-
def encodings_provided
|
64
|
-
{"gzip" => :encode_gzip, "identity" => :encode_identity}
|
65
|
-
end
|
88
|
+
The router is used to map a resource to a given path. To map the class `MyResource` to
|
89
|
+
the path `/myresource` you would write something along the lines of:
|
66
90
|
|
67
|
-
|
68
|
-
|
69
|
-
|
91
|
+
```ruby
|
92
|
+
Webmachine.application.routes do
|
93
|
+
add ['myresource'], MyResource
|
70
94
|
end
|
71
|
-
```
|
72
95
|
|
73
|
-
|
74
|
-
|
96
|
+
# Start a web server to serve requests via localhost
|
97
|
+
Webmachine.application.run
|
98
|
+
```
|
75
99
|
|
76
100
|
### Application/Configurator
|
77
101
|
|
78
|
-
There's a configurator that allows you to set
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
102
|
+
There's a configurator that allows you to set what IP address and port
|
103
|
+
a web server should bind to as well as what web server should serve a
|
104
|
+
webmachine resource.
|
105
|
+
|
106
|
+
A call to `Webmachine::Application#configure` returns a `Webmachine::Application` instance,
|
107
|
+
so you could chain other method calls if you like. If you don't want to create your own separate
|
108
|
+
application object `Webmachine.application` will return a global one.
|
84
109
|
|
85
110
|
```ruby
|
86
111
|
require 'webmachine'
|
87
112
|
require 'my_resource'
|
88
113
|
|
89
|
-
Webmachine.application.routes do
|
90
|
-
add ['*'], MyResource
|
91
|
-
end
|
92
|
-
|
93
114
|
Webmachine.application.configure do |config|
|
94
115
|
config.ip = '127.0.0.1'
|
95
116
|
config.port = 3000
|
96
117
|
config.adapter = :Mongrel
|
97
118
|
end
|
98
119
|
|
99
|
-
# Start
|
120
|
+
# Start a web server to serve requests via localhost
|
100
121
|
Webmachine.application.run
|
101
122
|
```
|
102
123
|
|
103
124
|
Webmachine includes adapters for [Webrick][webrick], [Mongrel][mongrel],
|
104
|
-
[Reel][reel], and [Hatetepe]. Additionally, the [Rack][rack] adapter lets it
|
125
|
+
[Reel][reel], and [Hatetepe][hatetepe]. Additionally, the [Rack][rack] adapter lets it
|
105
126
|
run on any webserver that provides a Rack interface. It also lets it run on
|
106
127
|
[Shotgun][shotgun] ([example][shotgun_example]).
|
107
128
|
|
@@ -151,37 +172,9 @@ can use to lookup the trace. It might look something like this:
|
|
151
172
|
![preview calls at decision](http://seancribbs-skitch.s3.amazonaws.com/Webmachine_Trace_2156885920-20120625-100153.png)
|
152
173
|
|
153
174
|
Refer to
|
154
|
-
[examples/debugger.rb](/
|
175
|
+
[examples/debugger.rb](/examples/debugger.rb)
|
155
176
|
for an example of how to enable the debugger.
|
156
177
|
|
157
|
-
## Features
|
158
|
-
|
159
|
-
* Handles the hard parts of content negotiation, conditional
|
160
|
-
requests, and response codes for you.
|
161
|
-
* Most callbacks can interrupt the decision flow by returning an
|
162
|
-
integer response code. You generally only want to do this when new
|
163
|
-
information comes to light, requiring a modification of the response.
|
164
|
-
* Supports WEBrick and Mongrel (1.2pre+), and a Rack shim. Other host
|
165
|
-
servers are being investigated.
|
166
|
-
* Streaming/chunked response bodies are permitted as Enumerables,
|
167
|
-
Procs, or Fibers!
|
168
|
-
* Unlike the Erlang original, it does real Language negotiation.
|
169
|
-
* Includes the visual debugger so you can look through the decision
|
170
|
-
graph to determine how your resources are behaving.
|
171
|
-
|
172
|
-
## Caveats
|
173
|
-
|
174
|
-
* The [Reel](https://github.com/celluloid/reel) adapter might fail with a
|
175
|
-
`SystemStackError` on MRI (< 2.0) due to its limited fiber stack size.
|
176
|
-
The only known solution is to switch to JRuby, Rubinius or MRI 2.0.
|
177
|
-
|
178
|
-
|
179
|
-
## Documentation & Finding Help
|
180
|
-
|
181
|
-
* [API documentation](http://rubydoc.info/gems/webmachine/frames/file/README.md)
|
182
|
-
* [Mailing list](mailto:webmachine.rb@librelist.com)
|
183
|
-
* IRC channel #webmachine on freenode
|
184
|
-
|
185
178
|
## Related libraries
|
186
179
|
|
187
180
|
* [irwebmachine](https://github.com/robgleeson/irwebmachine) - IRB/Pry debugging of Webmachine applications
|
@@ -189,6 +182,7 @@ for an example of how to enable the debugger.
|
|
189
182
|
* [webmachine-linking](https://github.com/petejohanson/webmachine-linking) - Helpers for linking between Resources, and Web Linking
|
190
183
|
* [webmachine-sprockets](https://github.com/lgierth/webmachine-sprockets) - Integration with Sprockets assets packaging system
|
191
184
|
* [webmachine-actionview](https://github.com/rgarner/webmachine-actionview) - Integration of some Rails-style view conventions into Webmachine
|
185
|
+
* [jruby-http-kit](https://github.com/nLight/jruby-http-kit) - Includes an adapter for the Clojure-based Ring library/server
|
192
186
|
|
193
187
|
## LICENSE
|
194
188
|
|
@@ -196,194 +190,3 @@ webmachine-ruby is licensed under the
|
|
196
190
|
[Apache v2.0 license](http://www.apache.org/licenses/LICENSE-2.0). See
|
197
191
|
LICENSE for details.
|
198
192
|
|
199
|
-
## Changelog
|
200
|
-
|
201
|
-
### 1.2.0
|
202
|
-
|
203
|
-
1.2.0 is a major feature release that adds the Events instrumentation
|
204
|
-
framework, support for Websockets in Reel adapter and a bunch of bugfixes.
|
205
|
-
Added Justin McPherson and Hendrik Beskow as contributors. Thank you
|
206
|
-
for your contributions!
|
207
|
-
|
208
|
-
* Websockets support in Reel adapter.
|
209
|
-
* Added `Events` framework implementing ActiveSupport::Notifications
|
210
|
-
instrumentation API.
|
211
|
-
* Linked mailing list and related library in README.
|
212
|
-
* Fixed operator precedence in `IOEncoder#each`.
|
213
|
-
* Fixed typo in Max-Age cookie attribute.
|
214
|
-
* Allowed attributes to be set in a `Cookie`.
|
215
|
-
* Fixed streaming in Rack adapter from Fiber that is expected
|
216
|
-
to block
|
217
|
-
* Added a more comprehensive adapter test suite and fixed various bugs
|
218
|
-
in the existing adapters.
|
219
|
-
* Webmachine::LazyRequestBody no longer double-buffers the request
|
220
|
-
body and cannot be rewound.
|
221
|
-
|
222
|
-
### 1.1.0 January 12, 2013
|
223
|
-
|
224
|
-
1.1.0 is a major feature release that adds the Reel and Hatetepe
|
225
|
-
adapters, support for "weak" entity tags, streaming IO response
|
226
|
-
bodies, better error handling, a shortcut for spinning up specific
|
227
|
-
resources, and a bunch of bugfixes. Added Tony Arcieri, Sebastian
|
228
|
-
Edwards, Russell Garner, Justin McPherson, Paweł Pacana, and Nicholas
|
229
|
-
Young as contributors. Thank you for your contributions!
|
230
|
-
|
231
|
-
* Added Reel adapter.
|
232
|
-
* The trace resource now opens static files in binary mode to ensure
|
233
|
-
compatibility on Windows.
|
234
|
-
* The trace resource uses absolute URIs for its traces.
|
235
|
-
* Added Hatetepe adapter.
|
236
|
-
* Added direct weak entity tag support.
|
237
|
-
* Related libraries are linked from the README.
|
238
|
-
* Removed some circular requires.
|
239
|
-
* Fixed documentation for the `valid_content_headers?` callback.
|
240
|
-
* Fixed `Headers` initialization by downcasing incoming header names.
|
241
|
-
* Added a `Headers#fetch` method.
|
242
|
-
* Conventionally "truthy" and "falsey" values (non-nil, non-false) can
|
243
|
-
now be returned from callbacks that expect a boolean return value.
|
244
|
-
* Updated to the latest RSpec.
|
245
|
-
* Added support for IO response bodies (minimal).
|
246
|
-
* Moved streaming encoders to their own module for clarity.
|
247
|
-
* Added `Resource#run` that starts up a web server with default
|
248
|
-
configuration options and the catch-all route to the resource.
|
249
|
-
* The exception handling flow was improved, clarifying the
|
250
|
-
`handle_exception` and `finish_request` callbacks.
|
251
|
-
* Fix incompatibilities with Rack.
|
252
|
-
* The request URI will not be initialized with parts that are not
|
253
|
-
present in the HTTP request.
|
254
|
-
* The tracing will now commit to storage after the response has been
|
255
|
-
traced.
|
256
|
-
|
257
|
-
### 1.0.0 July 7, 2012
|
258
|
-
|
259
|
-
1.0.0 is a major feature release that finally includes the visual
|
260
|
-
debugger, some nice cookie support, and some new extension
|
261
|
-
points. Added Peter Johanson and Armin Joellenbeck as
|
262
|
-
contributors. Thank you for your contributions!
|
263
|
-
|
264
|
-
* A cookie parsing and manipulation API was added.
|
265
|
-
* Conneg headers now accept any amount of whitespace around commas,
|
266
|
-
including none.
|
267
|
-
* `Callbacks#handle_exception` was added so that resources can handle
|
268
|
-
exceptions that they generate and produce more friendly responses.
|
269
|
-
* Chunked and non-chunked response bodies in the Rack adapter were
|
270
|
-
fixed.
|
271
|
-
* The WEBrick example was updated to use the new API.
|
272
|
-
* `Dispatcher` was refactored so that you can modify how resources
|
273
|
-
are initialized before dispatching occurs.
|
274
|
-
* `Route` now includes the `Translation` module so that exception
|
275
|
-
messages are properly rendered.
|
276
|
-
* The visual debugger was added (more details in the README).
|
277
|
-
* The `Content-Length` header will always be set inside Webmachine and
|
278
|
-
is no longer reliant on the adapter to set it.
|
279
|
-
|
280
|
-
### 0.4.2 March 22, 2012
|
281
|
-
|
282
|
-
0.4.2 is a bugfix release that corrects a few minor issues. Added Lars
|
283
|
-
Gierth and Rob Gleeson as contributors. Thank you for your
|
284
|
-
contributions!
|
285
|
-
|
286
|
-
* I always intended for Webmachine-Ruby to be Apache licensed, but now
|
287
|
-
that is explicit.
|
288
|
-
* When the `#process_post` callback returns an invalid value, that
|
289
|
-
will now be `inspect`ed in the raised exception's message.
|
290
|
-
* Route bindings are now applied to the `Request` object before the
|
291
|
-
`Resource` class is instantiated. This means you can inspect them
|
292
|
-
inside the `#initialize` method of your resource.
|
293
|
-
* Some `NameError` exceptions and scope problems in the Mongrel
|
294
|
-
adapter were resolved.
|
295
|
-
* URL-encoded `=` characters in the query string decoded in the proper
|
296
|
-
order.
|
297
|
-
|
298
|
-
### 0.4.1 February 8, 2012
|
299
|
-
|
300
|
-
0.4.1 is a bugfix release that corrects a few minor issues. Added Sam
|
301
|
-
Goldman as a contributor. Thank you for your contributions!
|
302
|
-
|
303
|
-
* Updated README with `Webmachine::Application` examples.
|
304
|
-
* The CGI env vars `CONTENT_LENGTH` and `CONTENT_TYPE` are now being
|
305
|
-
correctly converted into their Webmachine equivalents.
|
306
|
-
* The request body given via the Rack and Mongrel adapters now
|
307
|
-
responds to `#to_s` and `#each` so it can be treated like a `String`
|
308
|
-
or `Enumerable` that yields chunks.
|
309
|
-
|
310
|
-
### 0.4.0 February 5, 2012
|
311
|
-
|
312
|
-
0.4.0 includes some important refactorings, isolating the idea of
|
313
|
-
global state into an Application object with its own Dispatcher and
|
314
|
-
configuration, and making Adapters into real classes with a consistent
|
315
|
-
interface. It also adds some query methods on the Request object for
|
316
|
-
the HTTP method and scheme and Route guards (matching predicates).
|
317
|
-
Added Michael Maltese, Emmanuel Gomez, and Bernerd Schaefer as
|
318
|
-
committers. Thank you for your contributions!
|
319
|
-
|
320
|
-
* Fixed `Request#query` to handle nil values for the URI query accessor.
|
321
|
-
* `Webmachine::Dispatcher` is a real class rather than a module with
|
322
|
-
state.
|
323
|
-
* `Webmachine::Application` is a class that includes its own
|
324
|
-
dispatcher and configuration. The default instance is accessible via
|
325
|
-
`Webmachine.application`.
|
326
|
-
* `Webmachine::Adapter` is now the superclass of all implemented
|
327
|
-
adapters so that they have a uniform interface.
|
328
|
-
* The Mongrel spec is skipped on JRuby since version 1.2 (pre-release)
|
329
|
-
doesn't work. Direct Mongrel support may be removed in a later
|
330
|
-
release.
|
331
|
-
* `Webmachine::Dispatcher::Route` now accepts guards, which may be
|
332
|
-
expressed as lambdas/procs or any object responding to `call`
|
333
|
-
preceding the `Resource` class in the route definition, or as a
|
334
|
-
trailing block. All guards will be passed the `Request` object when
|
335
|
-
matching the route and should return a truthy or falsey value
|
336
|
-
(without side-effects).
|
337
|
-
|
338
|
-
### 0.3.0 November 9, 2011
|
339
|
-
|
340
|
-
0.3.0 introduces some new features, refactorings, and now has 100%
|
341
|
-
documentation coverage! Among the new features are minimal Rack
|
342
|
-
compatibility, streaming responses via Fibers and a friendlier route
|
343
|
-
definition syntax. Added Jamis Buck as a committer. Thank you for your
|
344
|
-
contributions!
|
345
|
-
|
346
|
-
* Chunked bodies are now wrapped in a way that works on webservers
|
347
|
-
that don't automatically produce them.
|
348
|
-
* HTTP Basic Authentication is easy to add to resources, just include
|
349
|
-
`Webmachine::Resource::Authentication`.
|
350
|
-
* Routes are a little less painful to add, you can now specify them
|
351
|
-
with `Webmachine.routes` which will be evaled into the `Dispatcher`.
|
352
|
-
* The new default port is 8080.
|
353
|
-
* Rack is minimally supported as a host server. _Don't put middleware
|
354
|
-
above Webmachine!_
|
355
|
-
* Fibers can be used as streamed response bodies.
|
356
|
-
* `Dispatcher#add_route` will now return the added `Route` instance.
|
357
|
-
* The header-conversion code for CGI-style servers has been extracted
|
358
|
-
into `Webmachine::Headers`.
|
359
|
-
* `Route#path_spec` is now public so that applications can inspect
|
360
|
-
existing routes, perhaps for URL generation.
|
361
|
-
* `Request#query` now uses `CGI.unescape` so '+' characters are
|
362
|
-
correctly parsed.
|
363
|
-
* YARD documentation has 100% coverage.
|
364
|
-
|
365
|
-
### 0.2.0 September 11, 2011
|
366
|
-
|
367
|
-
0.2.0 includes an adapter for Mongrel and a central place for
|
368
|
-
configuration as well as numerous bugfixes. Added Ian Plosker and
|
369
|
-
Bernd Ahlers as committers. Thank you for your contributions!
|
370
|
-
|
371
|
-
* Acceptable media types are matched less strictly, which has
|
372
|
-
implications on both responses and PUT requests. See the
|
373
|
-
[discussion on the commit](https://github.com/seancribbs/webmachine-ruby/commit/3686d0d9ff77fc98aff59f89478e9c6c18844ca1).
|
374
|
-
* Resources now receive a callback after the language has been
|
375
|
-
negotiated, so they can decide what to do with it.
|
376
|
-
* Added `Webmachine::Configuration` so we can more easily support more
|
377
|
-
than one host server/adapter.
|
378
|
-
* Added Mongrel adapter, supporting 1.2pre+.
|
379
|
-
* Media type headers are more lax about whitespace following
|
380
|
-
semicolons.
|
381
|
-
* Fix some problems with callable response bodies.
|
382
|
-
* Make sure String response bodies get a Content-Length header added
|
383
|
-
and streaming responses get chunked encoding.
|
384
|
-
* Numerous refactorings, including extracting `MediaType` into its own
|
385
|
-
top-level class.
|
386
|
-
|
387
|
-
### 0.1.0 August 25, 2011
|
388
|
-
|
389
|
-
This is the initial release. Most things work, but only WEBrick is supported.
|
@@ -4,17 +4,19 @@ require 'webmachine/headers'
|
|
4
4
|
require 'webmachine/request'
|
5
5
|
require 'webmachine/response'
|
6
6
|
require 'webmachine/dispatcher'
|
7
|
-
require 'webmachine/adapters/lazy_request_body'
|
8
7
|
require 'set'
|
9
8
|
|
10
9
|
module Webmachine
|
11
10
|
module Adapters
|
12
11
|
class Reel < Adapter
|
12
|
+
# Used to override default Reel server options (useful in testing)
|
13
|
+
DEFAULT_OPTIONS = {}
|
14
|
+
|
13
15
|
def run
|
14
|
-
@options = {
|
16
|
+
@options = DEFAULT_OPTIONS.merge({
|
15
17
|
:port => configuration.port,
|
16
18
|
:host => configuration.ip
|
17
|
-
}.merge(configuration.adapter_options)
|
19
|
+
}).merge(configuration.adapter_options)
|
18
20
|
|
19
21
|
if extra_verbs = configuration.adapter_options[:extra_verbs]
|
20
22
|
@extra_verbs = Set.new(extra_verbs.map(&:to_s).map(&:upcase))
|
@@ -34,11 +36,11 @@ module Webmachine
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def process(connection)
|
37
|
-
|
39
|
+
connection.each_request do |request|
|
38
40
|
# Users of the adapter can configure a custom WebSocket handler
|
39
|
-
if request.
|
41
|
+
if request.websocket?
|
40
42
|
if handler = @options[:websocket_handler]
|
41
|
-
handler.call(request)
|
43
|
+
handler.call(request.websocket)
|
42
44
|
else
|
43
45
|
# Pretend we don't know anything about the WebSocket protocol
|
44
46
|
# FIXME: This isn't strictly what RFC 6455 would have us do
|
@@ -61,8 +63,7 @@ module Webmachine
|
|
61
63
|
end
|
62
64
|
|
63
65
|
wm_headers = Webmachine::Headers[request.headers.dup]
|
64
|
-
wm_request = Webmachine::Request.new(method, uri, wm_headers,
|
65
|
-
LazyRequestBody.new(request))
|
66
|
+
wm_request = Webmachine::Request.new(method, uri, wm_headers, request.body)
|
66
67
|
wm_response = Webmachine::Response.new
|
67
68
|
@dispatcher.dispatch(wm_request, wm_response)
|
68
69
|
|
@@ -14,7 +14,7 @@ module Webmachine
|
|
14
14
|
#
|
15
15
|
# This module is included into {FSM}, which drives the processing
|
16
16
|
# of the chart.
|
17
|
-
# @see
|
17
|
+
# @see https://raw.github.com/wiki/basho/webmachine/images/http-headers-status-v3.png
|
18
18
|
module Flow
|
19
19
|
# Version of the flow diagram
|
20
20
|
VERSION = 3
|
@@ -49,8 +49,8 @@ module Webmachine
|
|
49
49
|
Webmachine.render_error(400, request, response, :message => e.message)
|
50
50
|
400
|
51
51
|
rescue Exception => e
|
52
|
-
|
53
|
-
|
52
|
+
resource.handle_exception(e)
|
53
|
+
500
|
54
54
|
end
|
55
55
|
|
56
56
|
def respond(code, headers={})
|
@@ -70,6 +70,7 @@ module Webmachine
|
|
70
70
|
end
|
71
71
|
|
72
72
|
ensure_content_length
|
73
|
+
ensure_date_header
|
73
74
|
end
|
74
75
|
|
75
76
|
# When tracing is disabled, this does nothing.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stringio'
|
2
|
+
require 'time'
|
2
3
|
require 'webmachine/streaming'
|
3
4
|
require 'webmachine/media_type'
|
4
5
|
require 'webmachine/quoted_string'
|
@@ -102,6 +103,13 @@ module Webmachine
|
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
106
|
+
# Ensures that responses have an appropriate Date header
|
107
|
+
def ensure_date_header
|
108
|
+
if (200..499).include?(response.code)
|
109
|
+
response.headers['Date'] ||= Time.now.httpdate
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
105
113
|
# Sets the Content-Length header on the response
|
106
114
|
def set_content_length
|
107
115
|
if response.body.respond_to?(:bytesize)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'webmachine/decision'
|
3
3
|
require 'webmachine/dispatcher/route'
|
4
|
+
require 'webmachine/dispatcher/not_found_resource'
|
4
5
|
|
5
6
|
module Webmachine
|
6
7
|
# Handles dispatching incoming requests to the proper registered
|
@@ -39,16 +40,12 @@ module Webmachine
|
|
39
40
|
# @param [Request] request the request object
|
40
41
|
# @param [Response] response the response object
|
41
42
|
def dispatch(request, response)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
payload[:code] = response.code
|
49
|
-
end
|
50
|
-
else
|
51
|
-
Webmachine.render_error(404, request, response)
|
43
|
+
resource = find_resource(request, response)
|
44
|
+
Webmachine::Events.instrument('wm.dispatch') do |payload|
|
45
|
+
Webmachine::Decision::FSM.new(resource, request, response).run
|
46
|
+
payload[:resource] = resource.class.name
|
47
|
+
payload[:request] = request.dup
|
48
|
+
payload[:code] = response.code
|
52
49
|
end
|
53
50
|
end
|
54
51
|
|
@@ -64,6 +61,8 @@ module Webmachine
|
|
64
61
|
def find_resource(request, response)
|
65
62
|
if route = find_route(request)
|
66
63
|
prepare_resource(route, request, response)
|
64
|
+
else
|
65
|
+
NotFoundResource.new(request, response)
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
@@ -8,7 +8,7 @@ module Webmachine
|
|
8
8
|
MEDIA_TYPE_REGEX = /^\s*([^;\s]+)\s*((?:;\s*\S+\s*)*)\s*$/
|
9
9
|
|
10
10
|
# Matches sub-type parameters
|
11
|
-
PARAMS_REGEX = /;\s*([^=]+)=([^;=\s]
|
11
|
+
PARAMS_REGEX = /;\s*([^=]+)(=([^;=\s]*))?/
|
12
12
|
|
13
13
|
# Creates a new MediaType by parsing an alternate representation.
|
14
14
|
# @param [MediaType, String, Array<String,Hash>] obj the raw type
|
@@ -21,7 +21,7 @@ module Webmachine
|
|
21
21
|
obj
|
22
22
|
when MEDIA_TYPE_REGEX
|
23
23
|
type, raw_params = $1, $2
|
24
|
-
params = Hash[raw_params.scan(PARAMS_REGEX)]
|
24
|
+
params = Hash[raw_params.scan(PARAMS_REGEX).map { |m| [m[0], m[2].to_s] }]
|
25
25
|
new(type, params)
|
26
26
|
else
|
27
27
|
unless Array === obj && String === obj[0] && Hash === obj[1]
|
File without changes
|
data/lib/webmachine/version.rb
CHANGED
@@ -1,75 +1,72 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require '
|
2
|
+
require 'webmachine/spec/adapter_lint'
|
3
|
+
describe Webmachine::Adapters::Reel do
|
4
|
+
it_should_behave_like :adapter_lint
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
let(:configuration) { Webmachine::Configuration.default }
|
7
|
+
let(:dispatcher) { Webmachine::Dispatcher.new }
|
8
|
+
let(:adapter) do
|
9
|
+
described_class.new(configuration, dispatcher)
|
10
|
+
end
|
7
11
|
|
8
|
-
|
9
|
-
let(:
|
10
|
-
let(:
|
11
|
-
|
12
|
+
context 'websockets' do
|
13
|
+
let(:example_host) { "www.example.com" }
|
14
|
+
let(:example_path) { "/example"}
|
15
|
+
let(:example_url) { "ws://#{example_host}#{example_path}" }
|
16
|
+
let :handshake_headers do
|
17
|
+
{
|
18
|
+
"Host" => example_host,
|
19
|
+
"Upgrade" => "websocket",
|
20
|
+
"Connection" => "Upgrade",
|
21
|
+
"Sec-WebSocket-Key" => "dGhlIHNhbXBsZSBub25jZQ==",
|
22
|
+
"Origin" => "http://example.com",
|
23
|
+
"Sec-WebSocket-Protocol" => "chat, superchat",
|
24
|
+
"Sec-WebSocket-Version" => "13"
|
25
|
+
}
|
12
26
|
end
|
27
|
+
let(:client_message) { "Hi server!" }
|
28
|
+
let(:server_message) { "Hi client!" }
|
13
29
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
let :handshake_headers do
|
19
|
-
{
|
20
|
-
"Host" => example_host,
|
21
|
-
"Upgrade" => "websocket",
|
22
|
-
"Connection" => "Upgrade",
|
23
|
-
"Sec-WebSocket-Key" => "dGhlIHNhbXBsZSBub25jZQ==",
|
24
|
-
"Origin" => "http://example.com",
|
25
|
-
"Sec-WebSocket-Protocol" => "chat, superchat",
|
26
|
-
"Sec-WebSocket-Version" => "13"
|
27
|
-
}
|
30
|
+
it 'supports websockets' do
|
31
|
+
configuration.adapter_options[:websocket_handler] = proc do |socket|
|
32
|
+
socket.read.should eq client_message
|
33
|
+
socket << server_message
|
28
34
|
end
|
29
|
-
let(:client_message) { "Hi server!" }
|
30
|
-
let(:server_message) { "Hi client!" }
|
31
|
-
|
32
|
-
it 'supports websockets' do
|
33
|
-
configuration.adapter_options[:websocket_handler] = proc do |socket|
|
34
|
-
socket.read.should eq client_message
|
35
|
-
socket << server_message
|
36
|
-
end
|
37
35
|
|
38
|
-
|
39
|
-
|
36
|
+
reel_server(adapter) do |client|
|
37
|
+
client << WebSocket::ClientHandshake.new(:get, example_url, handshake_headers).to_data
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
# Discard handshake response
|
40
|
+
# FIXME: hax
|
41
|
+
client.readpartial(4096)
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
client << WebSocket::Message.new(client_message).to_data
|
44
|
+
parser = WebSocket::Parser.new
|
45
|
+
parser.append client.readpartial(4096) until message = parser.next_message
|
48
46
|
|
49
|
-
|
50
|
-
end
|
47
|
+
message.should eq server_message
|
51
48
|
end
|
52
49
|
end
|
50
|
+
end
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
def reel_server(adptr = adapter)
|
53
|
+
thread = Thread.new { adptr.run }
|
54
|
+
begin
|
55
|
+
timeout(5) do
|
56
|
+
begin
|
57
|
+
sock = TCPSocket.new(adptr.configuration.ip, adptr.configuration.port)
|
58
58
|
begin
|
59
|
-
sock
|
60
|
-
|
61
|
-
|
62
|
-
ensure
|
63
|
-
sock.close
|
64
|
-
end
|
65
|
-
rescue Errno::ECONNREFUSED
|
66
|
-
Thread.pass
|
67
|
-
retry
|
59
|
+
yield(sock)
|
60
|
+
ensure
|
61
|
+
sock.close
|
68
62
|
end
|
63
|
+
rescue Errno::ECONNREFUSED
|
64
|
+
Thread.pass
|
65
|
+
retry
|
69
66
|
end
|
70
|
-
ensure
|
71
|
-
adptr.shutdown
|
72
67
|
end
|
68
|
+
ensure
|
69
|
+
adptr.shutdown
|
73
70
|
end
|
74
71
|
end
|
75
72
|
end
|
@@ -11,6 +11,15 @@ describe Webmachine::Decision::Flow do
|
|
11
11
|
let(:default_resource) { resource_with }
|
12
12
|
let(:missing_resource) { missing_resource_with }
|
13
13
|
|
14
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18:
|
15
|
+
# Origin servers MUST include a Date header field in all responses
|
16
|
+
# ... [except 1xx or 5xx]
|
17
|
+
after(:each) do
|
18
|
+
unless response.code < 200 || response.code >= 500
|
19
|
+
response.headers.should have_key('Date')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
14
23
|
def resource_with(&block)
|
15
24
|
klass = Class.new(Webmachine::Resource) do
|
16
25
|
def to_html; "test resource"; end
|
@@ -944,7 +953,7 @@ describe Webmachine::Decision::Flow do
|
|
944
953
|
true
|
945
954
|
end
|
946
955
|
def delete_completed?; true; end
|
947
|
-
def allowed_methods; %{GET HEAD PUT POST DELETE}; end
|
956
|
+
def allowed_methods; %W{GET HEAD PUT POST DELETE}; end
|
948
957
|
def resource_exists?; @exist; end
|
949
958
|
def allow_missing_post?; true; end
|
950
959
|
def content_types_accepted; [[request.content_type, :accept_all]]; end
|
@@ -1067,7 +1076,6 @@ describe Webmachine::Decision::Flow do
|
|
1067
1076
|
resource_with do
|
1068
1077
|
def handle_exception(e)
|
1069
1078
|
response.body = "error"
|
1070
|
-
501
|
1071
1079
|
end
|
1072
1080
|
|
1073
1081
|
def to_html
|
@@ -1081,12 +1089,10 @@ describe Webmachine::Decision::Flow do
|
|
1081
1089
|
response.body.should == "error"
|
1082
1090
|
end
|
1083
1091
|
|
1084
|
-
it "
|
1092
|
+
it "sets the response code to 500" do
|
1085
1093
|
subject.run
|
1086
|
-
response.code.should ==
|
1094
|
+
response.code.should == 500
|
1087
1095
|
end
|
1088
1096
|
end
|
1089
1097
|
end
|
1090
|
-
|
1091
|
-
|
1092
1098
|
end
|
@@ -69,4 +69,11 @@ describe Webmachine::Dispatcher do
|
|
69
69
|
fsm.should_receive(:run)
|
70
70
|
dispatcher.dispatch(request, response)
|
71
71
|
end
|
72
|
+
|
73
|
+
it "should respond with valid resource missing response for request to non-existing route" do
|
74
|
+
dispatcher.dispatch(request, response)
|
75
|
+
response.code.should eq(404)
|
76
|
+
response.body.should_not be_empty
|
77
|
+
response.headers.should have_key('Content-Length')
|
78
|
+
end
|
72
79
|
end
|
@@ -47,6 +47,13 @@ describe Webmachine::MediaType do
|
|
47
47
|
type.params.should == {"boundary" => "----------------------------2c46a7bec2b9", "charset" => "UTF-8"}
|
48
48
|
end
|
49
49
|
|
50
|
+
it "should parse a type/params pair where type has single-token params" do
|
51
|
+
type = described_class.parse(["text/html;q=1;rdfa", {"charset" => "UTF-8"}])
|
52
|
+
type.should be_kind_of(described_class)
|
53
|
+
type.type.should == "text/html"
|
54
|
+
type.params.should == {"q" => "1", "rdfa" => "", "charset" => "UTF-8"}
|
55
|
+
end
|
56
|
+
|
50
57
|
it "should raise an error when given an invalid type/params pair" do
|
51
58
|
expect {
|
52
59
|
described_class.parse([false, "blah"])
|
data/webmachine.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.homepage = "http://github.com/seancribbs/webmachine-ruby"
|
14
14
|
gem.authors = ["Sean Cribbs"]
|
15
15
|
gem.email = ["sean@basho.com"]
|
16
|
+
gem.license = "Apache 2.0"
|
16
17
|
|
17
18
|
gem.add_runtime_dependency(%q<i18n>, [">= 0.4.0"])
|
18
19
|
gem.add_runtime_dependency(%q<multi_json>)
|
@@ -25,6 +26,4 @@ Gem::Specification.new do |gem|
|
|
25
26
|
ignores = File.read(".gitignore").split(/\r?\n/).reject{ |f| f =~ /^(#.+|\s*)$/ }.map {|f| Dir[f] }.flatten
|
26
27
|
gem.files = (Dir['**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) }
|
27
28
|
gem.test_files = (Dir['spec/**/*','features/**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) }
|
28
|
-
gem.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
29
|
-
gem.require_paths = ['lib']
|
30
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: i18n
|
@@ -129,25 +129,7 @@ description: ! ' webmachine is a toolkit for building HTTP applications in a dec
|
|
129
129
|
its opinionated nature about HTTP. '
|
130
130
|
email:
|
131
131
|
- sean@basho.com
|
132
|
-
executables:
|
133
|
-
- autospec
|
134
|
-
- coderay
|
135
|
-
- gpgen
|
136
|
-
- guard
|
137
|
-
- hatetepe
|
138
|
-
- htmldiff
|
139
|
-
- ldiff
|
140
|
-
- mongrel_rails
|
141
|
-
- pry
|
142
|
-
- rackup
|
143
|
-
- rake
|
144
|
-
- redcarpet
|
145
|
-
- reel
|
146
|
-
- rspec
|
147
|
-
- thor
|
148
|
-
- yard
|
149
|
-
- yardoc
|
150
|
-
- yri
|
132
|
+
executables: []
|
151
133
|
extensions: []
|
152
134
|
extra_rdoc_files: []
|
153
135
|
files:
|
@@ -169,6 +151,7 @@ files:
|
|
169
151
|
- bin/yard
|
170
152
|
- bin/yardoc
|
171
153
|
- bin/yri
|
154
|
+
- CHANGELOG.md
|
172
155
|
- doc/_index.html
|
173
156
|
- doc/class_list.html
|
174
157
|
- doc/css/common.css
|
@@ -270,6 +253,7 @@ files:
|
|
270
253
|
- lib/webmachine/decision/fsm.rb
|
271
254
|
- lib/webmachine/decision/helpers.rb
|
272
255
|
- lib/webmachine/decision.rb
|
256
|
+
- lib/webmachine/dispatcher/not_found_resource.rb
|
273
257
|
- lib/webmachine/dispatcher/route.rb
|
274
258
|
- lib/webmachine/dispatcher.rb
|
275
259
|
- lib/webmachine/errors.rb
|
@@ -289,6 +273,8 @@ files:
|
|
289
273
|
- lib/webmachine/resource/tracing.rb
|
290
274
|
- lib/webmachine/resource.rb
|
291
275
|
- lib/webmachine/response.rb
|
276
|
+
- lib/webmachine/spec/adapter_lint.rb
|
277
|
+
- lib/webmachine/spec/test_resource.rb
|
292
278
|
- lib/webmachine/streaming/callable_encoder.rb
|
293
279
|
- lib/webmachine/streaming/encoder.rb
|
294
280
|
- lib/webmachine/streaming/enumerable_encoder.rb
|
@@ -313,8 +299,6 @@ files:
|
|
313
299
|
- Rakefile
|
314
300
|
- README.md
|
315
301
|
- spec/spec_helper.rb
|
316
|
-
- spec/support/adapter_lint.rb
|
317
|
-
- spec/support/test_resource.rb
|
318
302
|
- spec/webmachine/adapter_spec.rb
|
319
303
|
- spec/webmachine/adapters/hatetepe_spec.rb
|
320
304
|
- spec/webmachine/adapters/mongrel_spec.rb
|
@@ -347,7 +331,8 @@ files:
|
|
347
331
|
- webmachine.gemspec
|
348
332
|
- .gitignore
|
349
333
|
homepage: http://github.com/seancribbs/webmachine-ruby
|
350
|
-
licenses:
|
334
|
+
licenses:
|
335
|
+
- Apache 2.0
|
351
336
|
post_install_message:
|
352
337
|
rdoc_options: []
|
353
338
|
require_paths:
|
@@ -372,8 +357,6 @@ specification_version: 3
|
|
372
357
|
summary: webmachine is a toolkit for building HTTP applications,
|
373
358
|
test_files:
|
374
359
|
- spec/spec_helper.rb
|
375
|
-
- spec/support/adapter_lint.rb
|
376
|
-
- spec/support/test_resource.rb
|
377
360
|
- spec/webmachine/adapter_spec.rb
|
378
361
|
- spec/webmachine/adapters/hatetepe_spec.rb
|
379
362
|
- spec/webmachine/adapters/mongrel_spec.rb
|