rufus-sixjo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1,87 @@
1
+
2
+ = 'rufus-sixjo'
3
+
4
+ == what is it ?
5
+
6
+ A 'Rack application' for
7
+
8
+
9
+ == features
10
+
11
+ not many.
12
+
13
+
14
+ == getting it
15
+
16
+ sudo gem install -y rufus-sixjo
17
+
18
+ or download[http://rubyforge.org/frs/?group_id=4812] it from RubyForge.
19
+
20
+
21
+ == usage
22
+
23
+ see under the examples/ directory : http://github.com/jmettraux/rufus-sixjo/tree/master/examples
24
+
25
+ It goes like :
26
+
27
+ require 'rubygems'
28
+ require 'rufus/sixjo' # gem 'rufus-sixjo'
29
+
30
+ module ExampleOne
31
+
32
+ extend Rufus::Sixjo
33
+
34
+ get '/toto' do
35
+ "nada at #{request.path_info}"
36
+ end
37
+ end
38
+
39
+ app = Rack::Builder.new do
40
+
41
+ use Rack::CommonLogger
42
+ use Rack::ShowExceptions
43
+ run ExampleOne.new_sixjo_rack_app(nil)
44
+ end
45
+
46
+ Rack::Handler::Mongrel.run app, :Port => 2042
47
+
48
+
49
+ == dependencies
50
+
51
+ the 'rack' gem
52
+
53
+
54
+ == mailing list
55
+
56
+ On the Rufus-Ruby list[http://groups.google.com/group/rufus-ruby] :
57
+
58
+ http://groups.google.com/group/rufus-ruby
59
+
60
+
61
+ == issue tracker
62
+
63
+ http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
64
+
65
+
66
+ == source
67
+
68
+ http://github.com/jmettraux/rufus-sixjo
69
+
70
+ git clone git://github.com/jmettraux/rufus-sixjo.git
71
+
72
+
73
+ == author
74
+
75
+ John Mettraux, jmettraux@gmail.com,
76
+ http://jmettraux.wordpress.com
77
+
78
+
79
+ == the rest of Rufus
80
+
81
+ http://rufus.rubyforge.org
82
+
83
+
84
+ == license
85
+
86
+ MIT
87
+
@@ -0,0 +1,353 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ #
26
+ # "made in Japan"
27
+ #
28
+
29
+ require 'erb'
30
+ require 'rack'
31
+
32
+
33
+ class Rack::Request
34
+
35
+ def content
36
+ @env['rack.request.form_vars']
37
+ end
38
+ end
39
+
40
+ class Rack::Response
41
+
42
+ def location= (l)
43
+ header['Location'] = l
44
+ end
45
+ def content_type= (t)
46
+ header['Content-type'] = t
47
+ end
48
+ end
49
+
50
+
51
+ module Rufus
52
+
53
+ module Sixjo
54
+
55
+ VERSION = "0.1.0"
56
+
57
+ #
58
+ # Sixjo's Rack app
59
+ #
60
+ class App
61
+
62
+ attr_reader :environment
63
+
64
+ def initialize (next_app, routes, helpers, configures, options)
65
+
66
+ @next_app = next_app
67
+ @routes = routes || [] # the 'no route' case is rather useless...
68
+ @helpers = helpers || []
69
+
70
+ #@prefix = options[:prefix] || ''
71
+ #@rprefix = Regexp.new(@prefix)
72
+
73
+ @environment = options[:environment] || 'development'
74
+ @environment = @environment.to_s
75
+
76
+ #
77
+ # run the configure blocks
78
+
79
+ (configures || []).each do |envs, block|
80
+ instance_eval(&block) if envs.empty? or envs.include?(@environment)
81
+ end
82
+ end
83
+
84
+ def application
85
+ self
86
+ end
87
+
88
+ def call (env)
89
+
90
+ block = nil
91
+
92
+ begin
93
+ block = lookup_block(env)
94
+ rescue => e
95
+ #puts e
96
+ #puts e.backtrace
97
+ return [ 400, {}, e.to_s ]
98
+ end
99
+
100
+ if block
101
+ Context.service(self, block, @helpers, env)
102
+ elsif @next_app
103
+ @next_app.call(env)
104
+ else
105
+ [ 404, {}, [ "not found #{env['PATH_INFO']}" ] ]
106
+ end
107
+ end
108
+
109
+ protected
110
+
111
+ H_METHODS = [ 'GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS' ]
112
+ R_METHOD = /_method=(put|delete|PUT|DELETE)/
113
+ R_MULTIPART = /^multipart\/form-data;/
114
+
115
+ def lookup_block (env)
116
+
117
+ request_method = get_request_method(env)
118
+
119
+ @routes.each do |verb, route, block|
120
+ next unless request_method == verb
121
+ next unless route.match?(env)
122
+ return block
123
+ end
124
+
125
+ nil
126
+ end
127
+
128
+ def get_request_method (env)
129
+
130
+ rm = env['X-HTTP-Method-Override'] || env['REQUEST_METHOD']
131
+ rm = rm.upcase
132
+
133
+ #puts env.inspect
134
+
135
+ if rm == 'POST'
136
+ md = R_METHOD.match(env['QUERY_STRING'])
137
+ rm = md[1].upcase if md
138
+
139
+ ct = env['CONTENT_TYPE']
140
+
141
+ if ct and R_MULTIPART.match(ct)
142
+ request = Rack::Request.new(env)
143
+ env['_rack_request'] = request # no need to rebuild later
144
+ hidden_method = request.POST['_method']
145
+ rm = hidden_method.upcase if hidden_method
146
+ end
147
+ end
148
+
149
+ raise "unknown HTTP method '#{rm}'" unless H_METHODS.include?(rm)
150
+
151
+ rm
152
+ end
153
+ end
154
+
155
+ #
156
+ # ERB views
157
+ #
158
+ module Erb
159
+
160
+ #
161
+ # a local [context] for ERB views
162
+ #
163
+ class Local
164
+
165
+ def initialize (context, locals)
166
+ @context = context
167
+ @locals = locals
168
+ end
169
+
170
+ def method_missing (m, *args)
171
+
172
+ l = @locals[m.to_sym]
173
+ return l if l != nil
174
+
175
+ @context.send(m, *args)
176
+ end
177
+
178
+ #def application; @context.application; end
179
+ #def request; @context.request; end
180
+ #def response; @context.response; end
181
+
182
+ def get_binding
183
+ binding
184
+ end
185
+ end
186
+
187
+ def erb (template, options = {})
188
+
189
+ content = File.open("views/#{template}.erb").read
190
+
191
+ l = options[:locals]
192
+ l = Local.new(self, l || {}) unless l.is_a?(Local)
193
+
194
+ ::ERB.new(content).result(l.get_binding)
195
+ end
196
+ end
197
+
198
+ #
199
+ # The context in which an HTTP request is handled
200
+ #
201
+ class Context
202
+
203
+ include Erb
204
+
205
+ def metaclass
206
+ class << self
207
+ self
208
+ end
209
+ end
210
+
211
+ attr_reader :application
212
+ attr_reader :request, :response
213
+
214
+ def initialize (app, env)
215
+
216
+ @application = app
217
+ @request = env.delete('_rack_request') || Rack::Request.new(env)
218
+ @response = Rack::Response.new
219
+
220
+ @params = @request.params.merge(@request.env['_ROUTE_PARAMS'])
221
+ @params = @params.inject({}) { |r, (k, v)| r[k.to_sym] = v; r }
222
+ end
223
+
224
+ def self.service (app, block, helpers, env)
225
+
226
+ r = self.new(app, env)
227
+
228
+ helpers.each { |h| r.instance_eval &h }
229
+
230
+ r.metaclass.instance_eval { define_method :call, &block }
231
+
232
+ begin
233
+
234
+ caught = catch :done do
235
+ r.response.body = r.call || []
236
+ nil
237
+ end
238
+
239
+ if caught
240
+ #puts caught.inspect
241
+ r.response.status = caught[0]
242
+ r.response.body = caught[1]
243
+ end
244
+
245
+ rescue Exception => e
246
+
247
+ r.response.status = 500
248
+ r.response.content_type = 'text/plain'
249
+ r.response.body = e.to_s + "\n" + e.backtrace.join("\n")
250
+ end
251
+
252
+ r.response.finish
253
+ end
254
+
255
+ def params
256
+ @params
257
+ end
258
+
259
+ def redirect (path, status=303, body=nil)
260
+ @response.status = status
261
+ @response.location = path
262
+ @response.body = body || "#{status} redirecting to #{path}"
263
+ throw :done
264
+ end
265
+ end
266
+
267
+ #
268
+ # Wrapping all the details about route.match?(path) here...
269
+ #
270
+ class Route
271
+
272
+ C_CHAR = '[^/?:,&#\.]'
273
+ R_PARAM = /:(#{C_CHAR}+)/ # capturing route params
274
+ R_FORMAT = /\.(#{C_CHAR}+)$/ # capturing the resource/file format
275
+
276
+ def initialize (route, options)
277
+
278
+ @param_keys = []
279
+
280
+ @regex = route.gsub(R_PARAM) do
281
+ @param_keys << $1.to_sym
282
+ "(#{C_CHAR}+)" # ready to capture param values
283
+ end
284
+
285
+ @regex = /^#{@regex}(?:\.(#{C_CHAR}+))?$/
286
+
287
+ # TODO : do something with the options :agent, :accept, ...
288
+ end
289
+
290
+ def match? (env)
291
+
292
+ m = env['PATH_INFO'].match(@regex)
293
+
294
+ return false unless m
295
+
296
+ values = m.to_a[1..-1]
297
+ params = @param_keys.zip(values).inject({}) { |r, (k, v)| r[k] = v; r }
298
+
299
+ env['_ROUTE_PARAMS'] = params
300
+
301
+ env['_FORMAT'] = values.last if values.length > @param_keys.length
302
+
303
+ true
304
+ end
305
+ end
306
+
307
+ #--
308
+ # the methods for registering the routes
309
+ #++
310
+ [ :post, :get, :put, :delete ].each do |v|
311
+ module_eval <<-EOS
312
+ def #{v} (rt, opts={}, &blk)
313
+ (@routes ||= []) << [ '#{v.to_s.upcase}', Route.new(rt, opts), blk ]
314
+ end
315
+ EOS
316
+ end
317
+
318
+ #
319
+ # for example :
320
+ #
321
+ # helpers do
322
+ # def hello
323
+ # "hello #{params['who']}"
324
+ # end
325
+ # end
326
+ #
327
+ def helpers (&block)
328
+
329
+ (@helpers ||= []) << block
330
+ end
331
+
332
+ #
333
+ # Code in the 'configure' block will be run inside the application
334
+ # instance.
335
+ #
336
+ def configure (*envs, &block)
337
+
338
+ (@configures ||= []) << [ envs.collect { |e| e.to_s }, block ]
339
+ end
340
+
341
+ #
342
+ # Packages the routing info into a Rack application, suitable for
343
+ # insertion into a Rack app chain.
344
+ #
345
+ # Returns an instance of Rufus::Sixjo::App
346
+ #
347
+ def new_sixjo_rack_app (next_app, options={})
348
+
349
+ App.new(next_app, @routes, @helpers, @configures, options)
350
+ end
351
+ end
352
+ end
353
+
@@ -0,0 +1,52 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Fri Aug 8 15:14:45 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'testmixins'
12
+
13
+ #
14
+ # the "test" app
15
+ #
16
+ module Simple
17
+ extend Rufus::Sixjo
18
+
19
+ get '/toto' do
20
+ "toto"
21
+ end
22
+
23
+ get '/toto/:id' do
24
+ "toto with id #{params[:id]} .#{request.env['_FORMAT']}"
25
+ end
26
+ end
27
+
28
+ class SimpleTest < Test::Unit::TestCase
29
+ include SixjoTestMixin
30
+
31
+ def setup
32
+ @app = Simple.new_sixjo_rack_app(nil, :environment => 'test')
33
+ end
34
+
35
+ def test_0
36
+
37
+ assert_equal 404, get('/nada').status
38
+
39
+ assert_equal 200, get('/toto').status
40
+ assert_equal "toto", @response.body
41
+
42
+ assert_equal 200, get('/toto/3').status
43
+ assert_equal "toto with id 3 .", @response.body
44
+
45
+ assert_equal 200, get('/toto/3.json').status
46
+ assert_equal "toto with id 3 .json", @response.body
47
+
48
+ assert_equal 200, get('/toto/3.json?q=nada').status
49
+ assert_equal "toto with id 3 .json", @response.body
50
+ end
51
+ end
52
+
@@ -0,0 +1,46 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Sat Aug 9 00:03:47 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'testmixins'
12
+
13
+ #
14
+ # the "test" app
15
+ #
16
+ module WithHelper
17
+ extend Rufus::Sixjo
18
+
19
+ get '/hello' do
20
+ "hello #{hello}"
21
+ end
22
+
23
+ helpers do
24
+ def hello
25
+ params[:target]
26
+ end
27
+ end
28
+ end
29
+
30
+ class HelpersTest < Test::Unit::TestCase
31
+ include SixjoTestMixin
32
+
33
+ def setup
34
+ @app = WithHelper.new_sixjo_rack_app(nil, :environment => 'test')
35
+ end
36
+
37
+ def test_0
38
+
39
+ assert_equal 200, get('/hello').status
40
+ assert_equal "hello ", @response.body
41
+
42
+ assert_equal 200, get('/hello?target=world').status
43
+ assert_equal "hello world", @response.body
44
+ end
45
+ end
46
+
@@ -0,0 +1,37 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Mon Aug 11 17:23:23 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'testmixins'
12
+
13
+ #
14
+ # the "test" app
15
+ #
16
+ module RedirectApp
17
+ extend Rufus::Sixjo
18
+
19
+ get '/' do
20
+ redirect '/elsewhere'
21
+ end
22
+ end
23
+
24
+ class RedirectTest < Test::Unit::TestCase
25
+ include SixjoTestMixin
26
+
27
+ def setup
28
+ @app = RedirectApp.new_sixjo_rack_app(nil, :environment => 'test')
29
+ end
30
+
31
+ def test_0
32
+ assert_equal 303, get('/').status
33
+ assert_equal '/elsewhere', @response.location
34
+ assert_equal "303 redirecting to /elsewhere", @response.body
35
+ end
36
+ end
37
+
data/test/ft_3_erb.rb ADDED
@@ -0,0 +1,71 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Mon Aug 11 19:09:58 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'fileutils'
12
+ require 'testmixins'
13
+
14
+ #
15
+ # the "test" app
16
+ #
17
+ module ErbApp
18
+ extend Rufus::Sixjo
19
+
20
+ get '/' do
21
+ erb 'view0'
22
+ end
23
+
24
+ get '/good' do
25
+ erb 'view0', :locals => { :life => 'good' }
26
+ end
27
+
28
+ get '/good2' do
29
+ erb :view0, :whatever => true, :locals => { :life => 'good' }
30
+ end
31
+
32
+ get '/reckless' do
33
+ erb :view1
34
+ end
35
+ end
36
+
37
+ class ErbTest < Test::Unit::TestCase
38
+ include SixjoTestMixin
39
+
40
+ def setup
41
+
42
+ @app = ErbApp.new_sixjo_rack_app(nil, :environment => 'test')
43
+
44
+ FileUtils.mkdir('views') unless File.exist?('views')
45
+
46
+ fn = 'views/view0.erb'
47
+
48
+ FileUtils.rm(fn) if File.exist?(fn)
49
+ File.open(fn, 'w') { |f| f.write "this is view0, life is <%= life %>" }
50
+
51
+ fn = 'views/view1.erb'
52
+
53
+ FileUtils.rm(fn) if File.exist?(fn)
54
+ File.open(fn, 'w') { |f| f.write "<%= request.path_info %>" }
55
+ end
56
+
57
+ def test_0
58
+
59
+ assert_equal 500, get('/').status
60
+
61
+ assert_equal 200, get('/good').status
62
+ assert_equal 'this is view0, life is good', @response.body.strip
63
+
64
+ assert_equal 200, get('/good2').status
65
+ assert_equal 'this is view0, life is good', @response.body.strip
66
+
67
+ assert_equal 200, get('/reckless').status
68
+ assert_equal '/reckless', @response.body.strip
69
+ end
70
+ end
71
+
@@ -0,0 +1,61 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Tue Aug 12 13:38:16 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'testmixins'
12
+
13
+ #
14
+ # the "test" app
15
+ #
16
+ module ConfigureApp
17
+ extend Rufus::Sixjo
18
+
19
+ configure do
20
+ $apple = 'pomme'
21
+ @pear = 'poire'
22
+ end
23
+
24
+ configure :production, :development do
25
+ $peach = 'pe^che'
26
+ end
27
+
28
+ get '/' do
29
+ "apple is #{$apple}"
30
+ end
31
+
32
+ get '/pear' do
33
+ "pear is #{application.instance_variable_get(:@pear)}"
34
+ end
35
+
36
+ get '/peach' do
37
+ "peach is #{$peach}"
38
+ end
39
+ end
40
+
41
+ class ConfigureTest < Test::Unit::TestCase
42
+ include SixjoTestMixin
43
+
44
+ def setup
45
+
46
+ @app = ConfigureApp.new_sixjo_rack_app(nil, :environment => 'test')
47
+ end
48
+
49
+ def test_0
50
+
51
+ assert_equal 200, get('/').status
52
+ assert_equal 'apple is pomme', @response.body.strip
53
+
54
+ assert_equal 200, get('/pear').status
55
+ assert_equal 'pear is poire', @response.body.strip
56
+
57
+ assert_equal 200, get('/peach').status
58
+ assert_equal 'peach is', @response.body.strip
59
+ end
60
+ end
61
+
data/test/ft_5_put.rb ADDED
@@ -0,0 +1,97 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Tue Aug 12 23:36:22 JST 2008
8
+ #
9
+
10
+ require 'test/unit'
11
+ require 'testmixins'
12
+
13
+ #
14
+ # the "test" app
15
+ #
16
+ module PutApp
17
+ extend Rufus::Sixjo
18
+
19
+ post '/' do
20
+ #puts request.inspect
21
+ #request.env['rack.input'].read
22
+ request.content
23
+ end
24
+
25
+ put '/car' do
26
+ "put : #{request.content || params[:brand]}"
27
+ end
28
+
29
+ delete '/car/:id' do
30
+ end
31
+ end
32
+
33
+ class PutTest < Test::Unit::TestCase
34
+ include SixjoTestMixin
35
+
36
+ def setup
37
+
38
+ @app = PutApp.new_sixjo_rack_app(nil, :environment => 'test')
39
+ end
40
+
41
+ def test_0
42
+
43
+ #puts post('/', { :input => 'toto' }).body
44
+ assert_equal 200, post('/', { :input => 'toto' }).status
45
+ assert_equal 'toto', @response.body
46
+
47
+ assert_equal 200, put('/car', { :input => 'datsun' }).status
48
+ assert_equal 'put : datsun', @response.body
49
+
50
+ assert_equal 200, post('/car?_method=put', { :input => 'nissan' }).status
51
+ assert_equal 'put : nissan', @response.body
52
+
53
+ assert_equal 404, post('/car', { :input => 'mercedes', :_method => 'put' }).status
54
+ #assert_equal 'put : mercedes', @response.body
55
+
56
+ assert_equal 200, delete('/car/fr154147', {}).status
57
+ assert_equal '', @response.body
58
+ end
59
+
60
+ def test_1
61
+
62
+ assert_equal(
63
+ 200,
64
+ post(
65
+ '/car',
66
+ { :input => 'lada', 'X-HTTP-Method-Override' => 'put' }).status)
67
+ assert_equal 'put : lada', @response.body
68
+
69
+ assert_equal(
70
+ 400,
71
+ post(
72
+ '/car',
73
+ { :input => 'lada', 'X-HTTP-Method-Override' => 'push' }).status)
74
+ assert_equal "unknown HTTP method 'PUSH'", @response.body
75
+ end
76
+
77
+ def test_2
78
+
79
+ data = {
80
+ "_method" => "put",
81
+ "brand" => "ford"
82
+ }
83
+ form_data = encode_multipart(data)
84
+
85
+ assert_equal(
86
+ 200,
87
+ post(
88
+ '/car',
89
+ {
90
+ :input => form_data,
91
+ 'CONTENT_LENGTH' => form_data.length.to_s,
92
+ 'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x'
93
+ }).status)
94
+ assert_equal 'put : ford', @response.body
95
+ end
96
+ end
97
+
data/test/test.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ require 'ft_0_simple'
3
+ require 'ft_1_helpers'
4
+ require 'ft_2_redirect'
5
+ require 'ft_3_erb'
6
+ require 'ft_4_configure'
7
+ require 'ft_5_put'
8
+
@@ -0,0 +1,40 @@
1
+
2
+ #
3
+ # Testing rufus-sixjo
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Fri Aug 8 18:01:29 JST 2008
8
+ #
9
+
10
+ require 'rubygems'
11
+ require 'rufus/sixjo'
12
+
13
+
14
+ module SixjoTestMixin
15
+
16
+ [ :post, :get, :put, :delete ].each do |v|
17
+ module_eval <<-EOS
18
+ def #{v} (path, options={})
19
+ @response = \
20
+ Rack::MockRequest.new(@app).request('#{v}'.upcase, path, options)
21
+ @response
22
+ end
23
+ EOS
24
+ end
25
+
26
+ MFD_BOUNDARY = "AaB03x"
27
+
28
+ def encode_multipart (data = {})
29
+ ret = ""
30
+ data.each do |key, value|
31
+ next if value == nil or value.strip == ''
32
+ ret << "--#{MFD_BOUNDARY}\r\n"
33
+ ret << "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
34
+ ret << value
35
+ ret << "\r\n"
36
+ end
37
+ ret << "--#{MFD_BOUNDARY}--\r\n"
38
+ end
39
+ end
40
+
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rufus-sixjo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John Mettraux
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-15 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: john at gmail dot com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.txt
33
+ files:
34
+ - lib/rufus
35
+ - lib/rufus/sixjo.rb
36
+ - test/ft_0_simple.rb
37
+ - test/ft_1_helpers.rb
38
+ - test/ft_2_redirect.rb
39
+ - test/ft_3_erb.rb
40
+ - test/ft_4_configure.rb
41
+ - test/ft_5_put.rb
42
+ - test/test.rb
43
+ - test/testmixins.rb
44
+ - README.txt
45
+ has_rdoc: true
46
+ homepage: http://rufus.rubyforge.org/rufus-sixjo
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements:
65
+ - rack
66
+ rubyforge_project:
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: a rack application
71
+ test_files:
72
+ - test/test.rb