rack-jsonp 1.2.1 → 1.3.0

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.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