webmachine 0.4.0 → 0.4.1
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.
- data/README.md +58 -11
- data/b/autospec +16 -0
- data/b/gpgen +16 -0
- data/b/guard +16 -0
- data/b/htmldiff +16 -0
- data/b/ldiff +16 -0
- data/b/mongrel_rails +16 -0
- data/b/rackup +16 -0
- data/b/rake +16 -0
- data/b/rake2thor +16 -0
- data/b/redcarpet +16 -0
- data/b/rspec +16 -0
- data/b/thor +16 -0
- data/b/yard +16 -0
- data/b/yardoc +16 -0
- data/b/yri +16 -0
- data/lib/webmachine/adapters/mongrel.rb +27 -2
- data/lib/webmachine/adapters/rack.rb +37 -1
- data/lib/webmachine/headers.rb +1 -1
- data/lib/webmachine/version.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/webmachine/adapters/mongrel_spec.rb +31 -1
- data/spec/webmachine/adapters/rack_spec.rb +34 -1
- data/spec/webmachine/headers_spec.rb +7 -0
- metadata +633 -66
data/README.md
CHANGED
@@ -29,12 +29,17 @@ application for it!
|
|
29
29
|
require 'webmachine'
|
30
30
|
# Require any of the files that contain your resources here
|
31
31
|
require 'my_resource'
|
32
|
-
|
33
|
-
#
|
34
|
-
Webmachine::
|
35
|
-
|
32
|
+
|
33
|
+
# Create an application which encompasses routes and configruation
|
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
|
40
|
+
|
36
41
|
# Start the server, binds to port 8080 using WEBrick
|
37
|
-
|
42
|
+
MyApp.run
|
38
43
|
```
|
39
44
|
|
40
45
|
Your resource will look something like this:
|
@@ -68,29 +73,31 @@ end
|
|
68
73
|
There are many other HTTP features exposed to your resource through
|
69
74
|
{Webmachine::Resource::Callbacks}. Give them a try!
|
70
75
|
|
71
|
-
### Configurator
|
76
|
+
### Application/Configurator
|
72
77
|
|
73
78
|
There's a configurator that allows you to set the ip address and port
|
74
79
|
bindings as well as a different webserver adapter. You can also add
|
75
|
-
your routes in a block. Both of these call return the
|
76
|
-
|
80
|
+
your routes in a block (as shown above). Both of these call return the
|
81
|
+
`Webmachine::Application` instance, so you could chain them if you
|
82
|
+
like. If you don't want to create your own separate application
|
83
|
+
object, `Webmachine.application` will return a global one.
|
77
84
|
|
78
85
|
```ruby
|
79
86
|
require 'webmachine'
|
80
87
|
require 'my_resource'
|
81
88
|
|
82
|
-
Webmachine.routes do
|
89
|
+
Webmachine.application.routes do
|
83
90
|
add ['*'], MyResource
|
84
91
|
end
|
85
92
|
|
86
|
-
Webmachine.configure do |config|
|
93
|
+
Webmachine.application.configure do |config|
|
87
94
|
config.ip = '127.0.0.1'
|
88
95
|
config.port = 3000
|
89
96
|
config.adapter = :Mongrel
|
90
97
|
end
|
91
98
|
|
92
99
|
# Start the server.
|
93
|
-
Webmachine.run
|
100
|
+
Webmachine.application.run
|
94
101
|
```
|
95
102
|
|
96
103
|
## Features
|
@@ -115,6 +122,46 @@ Webmachine.run
|
|
115
122
|
|
116
123
|
## Changelog
|
117
124
|
|
125
|
+
### 0.4.1 February 8, 2012
|
126
|
+
|
127
|
+
0.4.1 is a bugfix release that corrects a few minor issues. Added Sam
|
128
|
+
Goldman as a contributor. Thank you for your contributions!
|
129
|
+
|
130
|
+
* Updated README with `Webmachine::Application` examples.
|
131
|
+
* The CGI env vars `CONTENT_LENGTH` and `CONTENT_TYPE` are now being
|
132
|
+
correctly converted into their Webmachine equivalents.
|
133
|
+
* The request body given via the Rack and Mongrel adapters now
|
134
|
+
responds to `#to_s` and `#each` so it can be treated like a `String`
|
135
|
+
or `Enumerable` that yields chunks.
|
136
|
+
|
137
|
+
### 0.4.0 February 5, 2012
|
138
|
+
|
139
|
+
0.4.0 includes some important refactorings, isolating the idea of
|
140
|
+
global state into an Application object with its own Dispatcher and
|
141
|
+
configuration, and making Adapters into real classes with a consistent
|
142
|
+
interface. It also adds some query methods on the Request object for
|
143
|
+
the HTTP method and scheme and Route guards (matching predicates).
|
144
|
+
Added Michael Maltese, Emmanuel Gomez, and Bernerd Schaefer as
|
145
|
+
committers. Thank you for your contributions!
|
146
|
+
|
147
|
+
* Fixed `Request#query` to handle nil values for the URI query accessor.
|
148
|
+
* `Webmachine::Dispatcher` is a real class rather than a module with
|
149
|
+
state.
|
150
|
+
* `Webmachine::Application` is a class that includes its own
|
151
|
+
dispatcher and configuration. The default instance is accessible via
|
152
|
+
`Webmachine.application`.
|
153
|
+
* `Webmachine::Adapter` is now the superclass of all implemented
|
154
|
+
adapters so that they have a uniform interface.
|
155
|
+
* The Mongrel spec is skipped on JRuby since version 1.2 (pre-release)
|
156
|
+
doesn't work. Direct Mongrel support may be removed in a later
|
157
|
+
release.
|
158
|
+
* `Webmachine::Dispatcher::Route` now accepts guards, which may be
|
159
|
+
expressed as lambdas/procs or any object responding to `call`
|
160
|
+
preceding the `Resource` class in the route definition, or as a
|
161
|
+
trailing block. All guards will be passed the `Request` object when
|
162
|
+
matching the route and should return a truthy or falsey value
|
163
|
+
(without side-effects).
|
164
|
+
|
118
165
|
### 0.3.0 November 9, 2011
|
119
166
|
|
120
167
|
0.3.0 introduces some new features, refactorings, and now has 100%
|
data/b/autospec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'autospec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'autospec')
|
data/b/gpgen
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'gpgen' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('gem_plugin', 'gpgen')
|
data/b/guard
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'guard' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('guard', 'guard')
|
data/b/htmldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'htmldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'htmldiff')
|
data/b/ldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'ldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'ldiff')
|
data/b/mongrel_rails
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'mongrel_rails' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('mongrel', 'mongrel_rails')
|
data/b/rackup
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rackup' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rack', 'rackup')
|
data/b/rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rake', 'rake')
|
data/b/rake2thor
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake2thor' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('thor', 'rake2thor')
|
data/b/redcarpet
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'redcarpet' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('redcarpet', 'redcarpet')
|
data/b/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/b/thor
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'thor' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('thor', 'thor')
|
data/b/yard
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'yard' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('yard', 'yard')
|
data/b/yardoc
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'yardoc' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('yard', 'yardoc')
|
data/b/yri
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'yri' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('yard', 'yri')
|
@@ -31,7 +31,7 @@ module Webmachine
|
|
31
31
|
class Handler < ::Mongrel::HttpHandler
|
32
32
|
def initialize(dispatcher)
|
33
33
|
@dispatcher = dispatcher
|
34
|
-
super
|
34
|
+
super()
|
35
35
|
end
|
36
36
|
|
37
37
|
# Processes an individual request from Mongrel through Webmachine.
|
@@ -41,7 +41,7 @@ module Webmachine
|
|
41
41
|
request = Webmachine::Request.new(wreq.params["REQUEST_METHOD"],
|
42
42
|
URI.parse(wreq.params["REQUEST_URI"]),
|
43
43
|
header,
|
44
|
-
|
44
|
+
RequestBody.new(wreq))
|
45
45
|
|
46
46
|
response = Webmachine::Response.new
|
47
47
|
@dispatcher.dispatch(request, response)
|
@@ -81,6 +81,31 @@ module Webmachine
|
|
81
81
|
end
|
82
82
|
end # class Handler
|
83
83
|
|
84
|
+
# Wraps a Mongrel request body so that it can behave like a
|
85
|
+
# String.
|
86
|
+
# @api private
|
87
|
+
class RequestBody
|
88
|
+
# @return the request from Mongrel
|
89
|
+
attr_reader :request
|
90
|
+
|
91
|
+
# @param request the request from Mongrel
|
92
|
+
def initialize(request)
|
93
|
+
@request = request
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [String] the request body as a string
|
97
|
+
def to_s
|
98
|
+
request.body.rewind
|
99
|
+
request.body.read
|
100
|
+
end
|
101
|
+
|
102
|
+
# @yield [chunk]
|
103
|
+
# @yieldparam [String] chunk a chunk of the request body
|
104
|
+
def each(&block)
|
105
|
+
request.body.each(&block)
|
106
|
+
end
|
107
|
+
end # class RequestBody
|
108
|
+
|
84
109
|
end # module Mongrel
|
85
110
|
end # module Adapters
|
86
111
|
end # module Webmachine
|
@@ -51,7 +51,7 @@ module Webmachine
|
|
51
51
|
request = Webmachine::Request.new(rack_req.request_method,
|
52
52
|
URI.parse(rack_req.url),
|
53
53
|
headers,
|
54
|
-
rack_req
|
54
|
+
RequestBody.new(rack_req))
|
55
55
|
|
56
56
|
response = Webmachine::Response.new
|
57
57
|
@dispatcher.dispatch(request, response)
|
@@ -63,6 +63,42 @@ module Webmachine
|
|
63
63
|
|
64
64
|
[response.code.to_i, response.headers, body || []]
|
65
65
|
end
|
66
|
+
|
67
|
+
# Wraps the Rack input so it can be treated like a String or
|
68
|
+
# Enumerable.
|
69
|
+
# @api private
|
70
|
+
class RequestBody
|
71
|
+
# @param [Rack::Request] request the Rack request
|
72
|
+
def initialize(request)
|
73
|
+
@request = request
|
74
|
+
end
|
75
|
+
|
76
|
+
# Converts the body to a String so you can work with the entire
|
77
|
+
# thing.
|
78
|
+
# @return [String] the request body as a string
|
79
|
+
def to_s
|
80
|
+
if @value
|
81
|
+
@value.join
|
82
|
+
else
|
83
|
+
@request.body.rewind
|
84
|
+
@request.body.read
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Iterates over the body in chunks. If the body has previously
|
89
|
+
# been read, this method can be called again and get the same
|
90
|
+
# sequence of chunks.
|
91
|
+
# @yield [chunk]
|
92
|
+
# @yieldparam [String] chunk a chunk of the request body
|
93
|
+
def each
|
94
|
+
if @value
|
95
|
+
@value.each {|chunk| yield chunk }
|
96
|
+
else
|
97
|
+
@value = []
|
98
|
+
@request.body.each {|chunk| @value << chunk; yield chunk }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end # class RequestBody
|
66
102
|
end # class Rack
|
67
103
|
|
68
104
|
end # module Adapters
|