rack-stripper 1.0.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/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/LICENSE +13 -0
- data/Rakefile +2 -0
- data/lib/rack/stripper.rb +50 -0
- data/rack-stripper.gemspec +21 -0
- data/readme.markdown +32 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/stripper_spec.rb +112 -0
- metadata +111 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format=documentation --debugger
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Stripper
|
5
|
+
VERSION = '1.0.0'
|
6
|
+
|
7
|
+
attr_accessor :add_xml_instruction
|
8
|
+
attr_accessor :is_xml_response
|
9
|
+
|
10
|
+
def initialize(app, options={})
|
11
|
+
@app = app
|
12
|
+
self.add_xml_instruction = options[:add_xml_instruction] || false
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
dup._call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def _call(env)
|
20
|
+
status, headers, response = @app.call(env)
|
21
|
+
|
22
|
+
if headers.has_key?('Content-Type')
|
23
|
+
self.is_xml_response = !headers['Content-Type'].match(/xml/).nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
if response.respond_to?(:body)
|
27
|
+
stripped_body = process_body(response.body)
|
28
|
+
headers['Content-Length'] = stripped_body.bytesize if headers.has_key?('Content-Length')
|
29
|
+
response = Rack::Response.new(stripped_body, status, headers)
|
30
|
+
response.to_a
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def process_body(body)
|
37
|
+
body = body[0] if body.is_a?(Array)
|
38
|
+
body.strip!
|
39
|
+
if self.add_xml_instruction && doesnt_have_xml_instruction_already?(body) && self.is_xml_response
|
40
|
+
body = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n#{body}"
|
41
|
+
end
|
42
|
+
body
|
43
|
+
end
|
44
|
+
|
45
|
+
def doesnt_have_xml_instruction_already?(body)
|
46
|
+
match = body.match /<?xml version=/
|
47
|
+
match.nil?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/rack/stripper', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Benjamin Kreeger']
|
6
|
+
gem.email = ['ben@kree.gr']
|
7
|
+
gem.description = 'Trims whitespace from response bodies sent through rack.'
|
8
|
+
gem.summary = 'Trims whitespace from response bodies sent through rack.'
|
9
|
+
gem.homepage = 'http://github.com/kreeger/rack-stripper'
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = 'rack-stripper'
|
15
|
+
gem.require_paths = ['lib']
|
16
|
+
gem.version = Rack::Stripper::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency 'rspec'
|
19
|
+
gem.add_development_dependency 'debugger'
|
20
|
+
gem.add_dependency 'rack', '>= 1.0.0'
|
21
|
+
end
|
data/readme.markdown
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Rack::Stripper: not as sexy as it sounds
|
2
|
+
|
3
|
+
Rack::Stripper merely performs `String#strip` on the body of the response. I wrote this out of a need for this when Rails sends out RSS feeds (for some reason, the XML instruction is replaced with a blank line on outgoing RSS responses).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile and `bundle install` it:
|
8
|
+
|
9
|
+
gem 'rack-stripper'
|
10
|
+
|
11
|
+
Rack::Stripper is Rack middleware and can be used with any Rack-based application. In `config/application.rb`, place the following code.
|
12
|
+
|
13
|
+
config.middleware.use Rack::Stripper
|
14
|
+
|
15
|
+
Then you'll see `Rack::Stripper` when you run `rake middleware`. Simple as that. More info about using Rack middleware with Rails can be found [here][rails]. If you'd like the middleware to ensure an XML instruction is added to the bodies to XML-based responses, make that line look like this.
|
16
|
+
|
17
|
+
config.middleware.use Rack::Stripper, add_xml_instruction: true
|
18
|
+
|
19
|
+
## Contributing
|
20
|
+
|
21
|
+
1. Fork it
|
22
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
23
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
24
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
25
|
+
5. Create new Pull Request
|
26
|
+
|
27
|
+
## Copyright
|
28
|
+
|
29
|
+
I made this. I released it under the [WTFPL][]. See LICENSE for details, if you're into that sort of thing.
|
30
|
+
|
31
|
+
[rails]: http://guides.rubyonrails.org/rails_on_rack.html
|
32
|
+
[WTFPL]: http://sam.zoy.org/wtfpl
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'rack/stripper'
|
3
|
+
|
4
|
+
class DummyWare
|
5
|
+
|
6
|
+
def initialize(body)
|
7
|
+
@body = body
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
status = 200
|
12
|
+
headers = {'Content-Type' => 'application/xml; charset=utf-8'}
|
13
|
+
response = Rack::Response.new(@body, status, headers)
|
14
|
+
response.to_a
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
rss_feed = <<-EOS
|
4
|
+
|
5
|
+
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
6
|
+
<channel>
|
7
|
+
<title>Lookit me, I'm an RSS feed!</title>
|
8
|
+
<link>http://feedvalidator.org/</link>
|
9
|
+
<description>An RSS feed.</description>
|
10
|
+
<language>en-us</language>
|
11
|
+
<copyright>Your mom, last night.</copyright>
|
12
|
+
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
13
|
+
</channel>
|
14
|
+
</rss>
|
15
|
+
EOS
|
16
|
+
|
17
|
+
describe :rack do
|
18
|
+
describe :stripper do
|
19
|
+
before(:each) { @stripper = Rack::Stripper.new(DummyWare.new(rss_feed), {}) }
|
20
|
+
|
21
|
+
describe :_call do
|
22
|
+
it 'should clean up the body of a response' do
|
23
|
+
status, headers, response = @stripper._call({})
|
24
|
+
response.body.should_not be_nil
|
25
|
+
body = response.body.first
|
26
|
+
body.should start_with('<rss')
|
27
|
+
body.should == rss_feed.strip
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should add an instruction if told to do so' do
|
31
|
+
opts = { add_xml_instruction: true }
|
32
|
+
@stripper = Rack::Stripper.new(DummyWare.new(rss_feed), opts)
|
33
|
+
status, headers, response = @stripper._call({})
|
34
|
+
response.body.should_not be_nil
|
35
|
+
body = response.body.first
|
36
|
+
body.should start_with('<?xml version')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe :doesnt_have_xml_instruction_already? do
|
41
|
+
let(:method) { :doesnt_have_xml_instruction_already? }
|
42
|
+
|
43
|
+
it 'should match on a basic xml instruction' do
|
44
|
+
string = "<?xml version='1.0'?>"
|
45
|
+
result = @stripper.send(method, string)
|
46
|
+
result.should be_false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should match on a slightly more complicated xml instruction' do
|
50
|
+
string = "<?xml version=\"1.0\" standalone=\"no\"?>"
|
51
|
+
result = @stripper.send(method, string)
|
52
|
+
result.should be_false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should match on a crazy nutshit complicated xml instruction' do
|
56
|
+
string = "<?xml version=\"1.0\" standalone=\"no\" charset=\"utf8\"?>"
|
57
|
+
result = @stripper.send(method, string)
|
58
|
+
result.should be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
it "shouln't match on a missing xml instruction" do
|
62
|
+
string = "<?xml version='1.0' />"
|
63
|
+
result = @stripper.send(method, string)
|
64
|
+
result.should be_false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe :process_body do
|
69
|
+
let(:method) { :process_body }
|
70
|
+
let(:before_and_after) { " here's a sweet-ass string " }
|
71
|
+
let(:line_breaks) { "\n\n\nhere's a sweet-ass string\n\n\n" }
|
72
|
+
let(:none_before) { "here's another string \n"}
|
73
|
+
let(:none_after) { " \n here's another string"}
|
74
|
+
|
75
|
+
it 'should strip whitespace from the beginning of a string' do
|
76
|
+
result = @stripper.send(method, before_and_after)
|
77
|
+
result.should start_with("here's")
|
78
|
+
result.should_not start_with(' ')
|
79
|
+
|
80
|
+
result = @stripper.send(method, line_breaks)
|
81
|
+
result.should start_with("here's")
|
82
|
+
result.should_not start_with("\n")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should strip whitespace from the end of a string' do
|
86
|
+
result = @stripper.send(method, before_and_after)
|
87
|
+
result.should end_with("string")
|
88
|
+
result.should_not end_with(' ')
|
89
|
+
|
90
|
+
result = @stripper.send(method, line_breaks)
|
91
|
+
result.should end_with("string")
|
92
|
+
result.should_not end_with("\n")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should leave a string alone at the beginning if there's not whitespace there" do
|
96
|
+
result = @stripper.send(method, none_before)
|
97
|
+
result.should end_with("string")
|
98
|
+
result.should start_with("here's")
|
99
|
+
result.should_not end_with(" ")
|
100
|
+
result.should_not end_with("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should leave a string alone at the end if there's not whitespace there" do
|
104
|
+
result = @stripper.send(method, none_after)
|
105
|
+
result.should end_with("string")
|
106
|
+
result.should start_with("here's")
|
107
|
+
result.should_not start_with(" ")
|
108
|
+
result.should_not start_with("\n")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-stripper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Benjamin Kreeger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: debugger
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rack
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.0.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.0.0
|
62
|
+
description: Trims whitespace from response bodies sent through rack.
|
63
|
+
email:
|
64
|
+
- ben@kree.gr
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- Rakefile
|
74
|
+
- lib/rack/stripper.rb
|
75
|
+
- rack-stripper.gemspec
|
76
|
+
- readme.markdown
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
- spec/stripper_spec.rb
|
79
|
+
homepage: http://github.com/kreeger/rack-stripper
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
hash: -4515052134336603542
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: -4515052134336603542
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 1.8.23
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: Trims whitespace from response bodies sent through rack.
|
109
|
+
test_files:
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
- spec/stripper_spec.rb
|