rack-jsonp 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,11 +1,16 @@
1
1
  = rack-jsonp
2
2
 
3
- A Rack middleware for providing JSON-P support. Most of it is taken from the original Rack::JSONP middleware present in rack-contrib.
3
+ A Rack middleware for providing JSON-P support. Most of it is taken from the
4
+ original Rack::JSONP middleware present in rack-contrib.
4
5
 
5
- Since I don't want to include the complete rack-contrib gem when all I need is the JSONP middleware, I created this gem.
6
+ Since I don't want to include the complete rack-contrib gem when all I need is
7
+ the JSONP middleware, I created this gem.
6
8
 
7
9
  == Contributions
8
- * Patches by Sebastián Gamboa (sagmor), Garrett Bjerkhoel (dewski) and Jason Morrison (jasonm).
10
+
11
+ * Patches by Sebastián Gamboa (sagmor), Garrett Bjerkhoel (dewski), Jason
12
+ Morrison (jasonm), Brian Dunn (briandunn), Jon Allured (jonallured), Oleg
13
+ Ivanov (morhekil).
9
14
 
10
15
  == Copyright
11
16
 
data/lib/rack/jsonp.rb CHANGED
@@ -13,19 +13,24 @@ module Rack
13
13
  @callback_param = options[:callback_param] || 'callback'
14
14
  end
15
15
 
16
- # Proxies the request to the application, stripping out the JSON-P callback
17
- # method and padding the response with the appropriate callback format.
16
+ # Proxies the request to the application, stripping out the JSON-P
17
+ # callback method and padding the response with the appropriate callback
18
+ # format.
18
19
  #
19
20
  # Changes nothing if no <tt>callback</tt> param is specified.
20
21
  #
21
22
  def call(env)
22
- # remove the callback and _ parameters BEFORE calling the backend,
23
- # so that caching middleware does not store a copy for each value of the callback parameter
23
+ # remove the callback and _ parameters BEFORE calling the backend, so
24
+ # that caching middleware does not store a copy for each value of the
25
+ # callback parameter
24
26
  request = Rack::Request.new(env)
25
27
  callback = request.params.delete(@callback_param)
26
- env['QUERY_STRING'] = env['QUERY_STRING'].split("&").delete_if{|param| param =~ /^(_|#{@callback_param})=/}.join("&")
28
+ env['QUERY_STRING'] = env['QUERY_STRING'].split("&").delete_if{|param|
29
+ param =~ /^(_|#{@callback_param})=/
30
+ }.join("&")
27
31
 
28
32
  status, headers, response = @app.call(env)
33
+
29
34
  if callback && headers['Content-Type'] =~ /json/i
30
35
  response = pad(callback, response)
31
36
  headers['Content-Length'] = response.first.bytesize.to_s
@@ -35,25 +40,35 @@ module Rack
35
40
  response = carriage_return(response)
36
41
  headers['Content-Length'] = response.first.bytesize.to_s
37
42
  end
43
+
38
44
  [status, headers, response]
39
45
  end
40
46
 
41
47
  # Pads the response with the appropriate callback format according to the
42
48
  # JSON-P spec/requirements.
43
49
  #
44
- # The Rack response spec indicates that it should be enumerable. The method
45
- # of combining all of the data into a single string makes sense since JSON
46
- # is returned as a full string.
50
+ # The Rack response spec indicates that it should be enumerable. The
51
+ # method of combining all of the data into a single string makes sense
52
+ # since JSON is returned as a full string.
47
53
  #
48
54
  def pad(callback, response, body = "")
49
55
  response.each{ |s| body << s.to_s }
56
+ close(response)
50
57
  ["#{callback}(#{body})"]
51
58
  end
52
59
 
53
60
  def carriage_return(response, body = "")
54
61
  response.each{ |s| body << s.to_s }
62
+ close(response)
55
63
  ["#{body}\n"]
56
64
  end
65
+
66
+ # Close original response if it was Rack::BodyProxy (or anything else
67
+ # responding to close, as we're going to lose it anyway), or it will cause
68
+ # thread failures with newer Rack.
69
+ def close(io)
70
+ io.close if io.respond_to?(:close)
71
+ end
57
72
  end
58
73
 
59
74
  end
@@ -4,6 +4,57 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
 
5
5
  describe Rack::JSONP do
6
6
 
7
+ describe "closing application's response" do
8
+ let(:test_body) { ['test_body'] }
9
+ let(:params) { "foo=bar" }
10
+ let(:content_type) { "text/html" }
11
+ let(:app_params) {{}}
12
+ after do
13
+ request = Rack::MockRequest.env_for("/", :params => params)
14
+ app = lambda { |env| [200, {'Content-Type' => content_type}, test_body] }
15
+ Rack::JSONP.new(app, app_params).call(request).last
16
+ end
17
+
18
+ describe "when app response is closeable" do
19
+ let(:test_body) { ['test_body'].stub(:close => true) }
20
+
21
+ describe "and it is json" do
22
+ let(:content_type) { "application/json" }
23
+
24
+ describe "and callback was given" do
25
+ let(:params) { "foo=bar&callback=foo" }
26
+
27
+ it "closes the original body" do
28
+ test_body.should_receive(:close)
29
+ end
30
+ end
31
+
32
+ describe "and carriage return was requested" do
33
+ let(:app_params) {{ :carriage_return => true }}
34
+
35
+ it "closes the original body" do
36
+ test_body.should_receive(:close)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "and it is not json" do
42
+ let(:content_type) { "text/html"}
43
+ let(:params) { "foo=bar&callback=foo" }
44
+ it "does not close original body" do
45
+ test_body.should_not_receive(:close)
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "when app response is not closeable" do
51
+ let(:params) { "foo=bar&callback=foo" }
52
+ it "does not close original body" do
53
+ test_body.should_not_receive(:close)
54
+ end
55
+ end
56
+ end
57
+
7
58
  describe "when a callback parameter is provided" do
8
59
  it "should wrap the response body in the Javascript callback [default callback param]" do
9
60
  test_body = '{"bar":"foo"}'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-jsonp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 2
9
- - 1
10
- version: 1.2.1
8
+ - 3
9
+ - 0
10
+ version: 1.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Cyril Rohr
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-29 00:00:00 +02:00
18
+ date: 2011-10-19 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency