httpthumbnailer-client 0.1.1 → 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/Gemfile +10 -7
- data/Gemfile.lock +56 -49
- data/README.md +39 -15
- data/VERSION +1 -1
- data/bin/httpthumbnailer-client +73 -0
- data/httpthumbnailer-client.gemspec +38 -26
- data/lib/httpthumbnailer-client.rb +122 -48
- data/spec/httpthumbnailer-client_spec.rb +9 -138
- data/spec/spec_helper.rb +11 -4
- data/spec/{test-large.jpg → support/test-large.jpg} +0 -0
- data/spec/{test.jpg → support/test.jpg} +0 -0
- data/spec/{test.txt → support/test.txt} +0 -0
- data/spec/thumbnail_spec.rb +66 -0
- data/spec/thumbnails_spec.rb +110 -0
- data/spec/uri_builder_spec.rb +16 -0
- metadata +83 -32
- data/lib/httpthumbnailer-client/multipart_response.rb +0 -45
- data/spec/multipart_response_spec.rb +0 -95
@@ -1,45 +0,0 @@
|
|
1
|
-
class MultipartResponse
|
2
|
-
class NoBoundaryFoundInContentTypeError < ArgumentError
|
3
|
-
def initialize(content_type_header, exception)
|
4
|
-
super("Content-Type header of '#{content_type_header}' has no boundary defined: #{exception.class.name}: #{exception}")
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
class Part
|
9
|
-
def initialize(data)
|
10
|
-
if data.include?("\r\n\r\n")
|
11
|
-
headers, *body = *data.split("\r\n\r\n")
|
12
|
-
@headers = Hash[headers.split("\r\n").map{|h| h.split(/: ?/)}]
|
13
|
-
@body = body.join("\r\n\r\n")
|
14
|
-
else
|
15
|
-
@headers = {'Content-Type' => 'text/plain'}
|
16
|
-
@body = data
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :headers, :body
|
21
|
-
alias :header :headers
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(content_type_header, body)
|
25
|
-
@boundary = begin
|
26
|
-
content_type_header.split(';').map{|e| e.strip}.select{|e| e =~ /^boundary=/}.first.match(/^boundary="(.*)"/)[1]
|
27
|
-
rescue => e
|
28
|
-
raise NoBoundaryFoundInContentTypeError.new(content_type_header, e)
|
29
|
-
end
|
30
|
-
|
31
|
-
body, epilogue = *body.split("--#{@boundary}--")
|
32
|
-
preamble, *parts = *body.split("--#{@boundary}")
|
33
|
-
|
34
|
-
@preamble = preamble.sub(/\r\n$/m, '')
|
35
|
-
@preamble = nil if @preamble.empty?
|
36
|
-
|
37
|
-
@epilogue = epilogue.sub(/^\r\n/m, '') if epilogue
|
38
|
-
|
39
|
-
@parts = parts.map{|p| p.sub(/^\r\n/m, '').sub(/\r\n$/m, '')}.map{|p| Part.new(p)}
|
40
|
-
end
|
41
|
-
|
42
|
-
attr_reader :boundary, :preamble, :parts, :epilogue
|
43
|
-
alias :part :parts
|
44
|
-
end
|
45
|
-
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'httpthumbnailer-client/multipart_response'
|
3
|
-
|
4
|
-
describe MultipartResponse do
|
5
|
-
describe "parsing" do
|
6
|
-
it "should privide preamble, parts with headers and epilogue" do
|
7
|
-
content_type_header = 'multipart/mixed; boundary="cut here"'
|
8
|
-
body =
|
9
|
-
"""hello
|
10
|
-
--cut here
|
11
|
-
Content-Type: text/plain
|
12
|
-
|
13
|
-
part 1
|
14
|
-
--cut here
|
15
|
-
Content-Type: text/html
|
16
|
-
Content-Transfer-Encoding: base64
|
17
|
-
|
18
|
-
part 2
|
19
|
-
--cut here
|
20
|
-
part 3
|
21
|
-
--cut here--
|
22
|
-
world""".gsub!("\n", "\r\n")
|
23
|
-
|
24
|
-
mr = MultipartResponse.new(content_type_header, body)
|
25
|
-
mr.preamble.should == "hello"
|
26
|
-
|
27
|
-
mr.parts[0].body.should == "part 1"
|
28
|
-
mr.parts[0].header['Content-Type'].should == "text/plain"
|
29
|
-
|
30
|
-
mr.parts[1].body.should == "part 2"
|
31
|
-
mr.parts[1].header['Content-Type'].should == "text/html"
|
32
|
-
mr.parts[1].header['Content-Transfer-Encoding'].should == "base64"
|
33
|
-
|
34
|
-
mr.parts[2].body.should == "part 3"
|
35
|
-
|
36
|
-
mr.epilogue.should == "world"
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should privide nil preamble if no prologue sent" do
|
40
|
-
content_type_header = 'multipart/mixed; boundary="cut here"'
|
41
|
-
body =
|
42
|
-
"""--cut here
|
43
|
-
part 1
|
44
|
-
--cut here--""".gsub!("\n", "\r\n")
|
45
|
-
|
46
|
-
mr = MultipartResponse.new(content_type_header, body)
|
47
|
-
mr.preamble.should be_nil
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should privide nil epilogue if no epilogue sent" do
|
51
|
-
content_type_header = 'multipart/mixed; boundary="cut here"'
|
52
|
-
body =
|
53
|
-
"""--cut here
|
54
|
-
part 1
|
55
|
-
--cut here--""".gsub!("\n", "\r\n")
|
56
|
-
|
57
|
-
mr = MultipartResponse.new(content_type_header, body)
|
58
|
-
mr.epilogue.should be_nil
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should provide default mime type of text/plain if no Content-Type header specified" do
|
62
|
-
content_type_header = 'multipart/mixed; boundary="cut here"'
|
63
|
-
body =
|
64
|
-
"""--cut here
|
65
|
-
part 1
|
66
|
-
--cut here--""".gsub!("\n", "\r\n")
|
67
|
-
|
68
|
-
mr = MultipartResponse.new(content_type_header, body)
|
69
|
-
mr.part[0].header['Content-Type'].should == 'text/plain'
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should fail with MultipartResponse::NoBoundaryFoundInContentTypeError if no boundary specified in content type header" do
|
73
|
-
lambda {
|
74
|
-
MultipartResponse.new("fas", "")
|
75
|
-
}.should raise_error MultipartResponse::NoBoundaryFoundInContentTypeError
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
it "provides part alias" do
|
80
|
-
content_type_header = 'multipart/mixed; boundary="cut here"'
|
81
|
-
body =
|
82
|
-
"""--cut here
|
83
|
-
part 1
|
84
|
-
--cut here
|
85
|
-
part 2
|
86
|
-
--cut here
|
87
|
-
part 3
|
88
|
-
--cut here--""".gsub!("\n", "\r\n")
|
89
|
-
|
90
|
-
mr = MultipartResponse.new(content_type_header, body)
|
91
|
-
mr.part[0].body.should == "part 1"
|
92
|
-
mr.part[1].body.should == "part 2"
|
93
|
-
mr.part[2].body.should == "part 3"
|
94
|
-
end
|
95
|
-
end
|