webmachine 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|