marnen-typhoeus 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG.markdown +84 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +56 -0
  4. data/LICENSE +20 -0
  5. data/Rakefile +43 -0
  6. data/ext/typhoeus/.gitignore +7 -0
  7. data/ext/typhoeus/extconf.rb +65 -0
  8. data/ext/typhoeus/native.c +12 -0
  9. data/ext/typhoeus/native.h +22 -0
  10. data/ext/typhoeus/typhoeus_easy.c +232 -0
  11. data/ext/typhoeus/typhoeus_easy.h +20 -0
  12. data/ext/typhoeus/typhoeus_form.c +59 -0
  13. data/ext/typhoeus/typhoeus_form.h +13 -0
  14. data/ext/typhoeus/typhoeus_multi.c +217 -0
  15. data/ext/typhoeus/typhoeus_multi.h +16 -0
  16. data/lib/typhoeus.rb +58 -0
  17. data/lib/typhoeus/.gitignore +1 -0
  18. data/lib/typhoeus/easy.rb +413 -0
  19. data/lib/typhoeus/filter.rb +28 -0
  20. data/lib/typhoeus/form.rb +32 -0
  21. data/lib/typhoeus/hydra.rb +250 -0
  22. data/lib/typhoeus/hydra/callbacks.rb +24 -0
  23. data/lib/typhoeus/hydra/connect_options.rb +61 -0
  24. data/lib/typhoeus/hydra/stubbing.rb +68 -0
  25. data/lib/typhoeus/hydra_mock.rb +131 -0
  26. data/lib/typhoeus/multi.rb +37 -0
  27. data/lib/typhoeus/normalized_header_hash.rb +58 -0
  28. data/lib/typhoeus/remote.rb +306 -0
  29. data/lib/typhoeus/remote_method.rb +108 -0
  30. data/lib/typhoeus/remote_proxy_object.rb +50 -0
  31. data/lib/typhoeus/request.rb +269 -0
  32. data/lib/typhoeus/response.rb +122 -0
  33. data/lib/typhoeus/service.rb +20 -0
  34. data/lib/typhoeus/utils.rb +74 -0
  35. data/lib/typhoeus/version.rb +3 -0
  36. data/spec/fixtures/placeholder.gif +0 -0
  37. data/spec/fixtures/placeholder.txt +1 -0
  38. data/spec/fixtures/placeholder.ukn +0 -0
  39. data/spec/fixtures/result_set.xml +60 -0
  40. data/spec/servers/app.rb +97 -0
  41. data/spec/spec_helper.rb +19 -0
  42. data/spec/support/typhoeus_localhost_server.rb +58 -0
  43. data/spec/typhoeus/easy_spec.rb +391 -0
  44. data/spec/typhoeus/filter_spec.rb +35 -0
  45. data/spec/typhoeus/form_spec.rb +117 -0
  46. data/spec/typhoeus/hydra_mock_spec.rb +300 -0
  47. data/spec/typhoeus/hydra_spec.rb +602 -0
  48. data/spec/typhoeus/multi_spec.rb +74 -0
  49. data/spec/typhoeus/normalized_header_hash_spec.rb +41 -0
  50. data/spec/typhoeus/remote_method_spec.rb +141 -0
  51. data/spec/typhoeus/remote_proxy_object_spec.rb +65 -0
  52. data/spec/typhoeus/remote_spec.rb +695 -0
  53. data/spec/typhoeus/request_spec.rb +387 -0
  54. data/spec/typhoeus/response_spec.rb +192 -0
  55. data/spec/typhoeus/utils_spec.rb +22 -0
  56. data/typhoeus.gemspec +35 -0
  57. metadata +235 -0
@@ -0,0 +1,20 @@
1
+ module Typhoeus
2
+ class Service
3
+ def initialize(host, port)
4
+ @host = host
5
+ @port = port
6
+ end
7
+
8
+ def get(resource, params)
9
+ end
10
+
11
+ def put(resource, params)
12
+ end
13
+
14
+ def post(resource, params)
15
+ end
16
+
17
+ def delete(resource, params)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,74 @@
1
+ require 'tempfile'
2
+
3
+ module Typhoeus
4
+ module Utils
5
+ # Taken from Rack::Utils, 1.2.1 to remove Rack dependency.
6
+ def escape(s)
7
+ s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/u) {
8
+ '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
9
+ }.tr(' ', '+')
10
+ end
11
+ module_function :escape
12
+
13
+ # Params are NOT escaped.
14
+ def traverse_params_hash(hash, result = nil, current_key = nil)
15
+ result ||= { :files => [], :params => [] }
16
+
17
+ hash.keys.sort { |a, b| a.to_s <=> b.to_s }.collect do |key|
18
+ new_key = (current_key ? "#{current_key}[#{key}]" : key).to_s
19
+ current_value = hash[key]
20
+ process_value current_value, :result => result, :new_key => new_key
21
+ end
22
+ result
23
+ end
24
+ module_function :traverse_params_hash
25
+
26
+ def traversal_to_param_string(traversal, escape = true)
27
+ traversal[:params].collect { |param|
28
+ escape ? "#{Typhoeus::Utils.escape(param[0])}=#{Typhoeus::Utils.escape(param[1])}" : "#{param[0]}=#{param[1]}"
29
+ }.join('&')
30
+ end
31
+ module_function :traversal_to_param_string
32
+
33
+ # Return the bytesize of String; uses String#size under Ruby 1.8 and
34
+ # String#bytesize under 1.9.
35
+ if ''.respond_to?(:bytesize)
36
+ def bytesize(string)
37
+ string.bytesize
38
+ end
39
+ else
40
+ def bytesize(string)
41
+ string.size
42
+ end
43
+ end
44
+ module_function :bytesize
45
+
46
+ private
47
+
48
+ def process_value(current_value, options)
49
+ result = options[:result]
50
+ new_key = options[:new_key]
51
+
52
+ case current_value
53
+ when Hash
54
+ traverse_params_hash(current_value, result, new_key)
55
+ when Array
56
+ current_value.each do |v|
57
+ result[:params] << [new_key, v.to_s]
58
+ end
59
+ when File, Tempfile
60
+ filename = File.basename(current_value.path)
61
+ types = MIME::Types.type_for(filename)
62
+ result[:files] << [
63
+ new_key,
64
+ filename,
65
+ types.empty? ? 'application/octet-stream' : types[0].to_s,
66
+ File.expand_path(current_value.path)
67
+ ]
68
+ else
69
+ result[:params] << [new_key, current_value.to_s]
70
+ end
71
+ end
72
+ module_function :process_value
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module Typhoeus
2
+ VERSION = '0.3.4'
3
+ end
@@ -0,0 +1 @@
1
+ This file is used to test uploading.
File without changes
@@ -0,0 +1,60 @@
1
+ <result_set>
2
+ <ttl>20</ttl>
3
+ <result>
4
+ <id>1</id>
5
+ <name>hello</name>
6
+ <description>
7
+ this is a long description for a text field of some kind.
8
+ this is a long description for a text field of some kind.
9
+ this is a long description for a text field of some kind.
10
+ this is a long description for a text field of some kind.
11
+ this is a long description for a text field of some kind.
12
+ this is a long description for a text field of some kind.
13
+ this is a long description for a text field of some kind.
14
+ this is a long description for a text field of some kind.
15
+ this is a long description for a text field of some kind.
16
+ this is a long description for a text field of some kind.
17
+ this is a long description for a text field of some kind.
18
+ this is a long description for a text field of some kind.
19
+ this is a long description for a text field of some kind.
20
+ </description>
21
+ </result>
22
+ <result>
23
+ <id>2</id>
24
+ <name>hello</name>
25
+ <description>
26
+ this is a long description for a text field of some kind.
27
+ this is a long description for a text field of some kind.
28
+ this is a long description for a text field of some kind.
29
+ this is a long description for a text field of some kind.
30
+ this is a long description for a text field of some kind.
31
+ this is a long description for a text field of some kind.
32
+ this is a long description for a text field of some kind.
33
+ this is a long description for a text field of some kind.
34
+ this is a long description for a text field of some kind.
35
+ this is a long description for a text field of some kind.
36
+ this is a long description for a text field of some kind.
37
+ this is a long description for a text field of some kind.
38
+ this is a long description for a text field of some kind.
39
+ </description>
40
+ </result>
41
+ <result>
42
+ <id>3</id>
43
+ <name>hello</name>
44
+ <description>
45
+ this is a long description for a text field of some kind.
46
+ this is a long description for a text field of some kind.
47
+ this is a long description for a text field of some kind.
48
+ this is a long description for a text field of some kind.
49
+ this is a long description for a text field of some kind.
50
+ this is a long description for a text field of some kind.
51
+ this is a long description for a text field of some kind.
52
+ this is a long description for a text field of some kind.
53
+ this is a long description for a text field of some kind.
54
+ this is a long description for a text field of some kind.
55
+ this is a long description for a text field of some kind.
56
+ this is a long description for a text field of some kind.
57
+ this is a long description for a text field of some kind.
58
+ </description>
59
+ </result>
60
+ </result_set>
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'sinatra'
4
+ require 'json'
5
+ require 'zlib'
6
+
7
+ set :logging, false
8
+
9
+ @@fail_count = 0
10
+
11
+ post '/file' do
12
+ {
13
+ 'content-type' => params[:file][:type],
14
+ 'filename' => params[:file][:filename],
15
+ 'content' => params[:file][:tempfile].read,
16
+ 'request-content-type' => request.env['CONTENT_TYPE']
17
+ }.to_json
18
+ end
19
+
20
+ get '/multiple-headers' do
21
+ [200, { 'Set-Cookie' => %w[ foo bar ], 'Content-Type' => 'text/plain' }, ['']]
22
+ end
23
+
24
+ get '/fail/:number' do
25
+ if @@fail_count >= params[:number].to_i
26
+ "ok"
27
+ else
28
+ @@fail_count += 1
29
+ error 500, "oh noes!"
30
+ end
31
+ end
32
+
33
+ get '/fail_forever' do
34
+ error 500, "oh noes!"
35
+ end
36
+
37
+ get '/redirect' do
38
+ redirect '/'
39
+ end
40
+
41
+ get '/bad_redirect' do
42
+ redirect '/bad_redirect'
43
+ end
44
+
45
+ get '/auth_basic/:username/:password' do
46
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
47
+ # Check that we've got a basic auth, and that it's credentials match the ones
48
+ # provided in the request
49
+ if @auth.provided? && @auth.basic? && @auth.credentials == [ params[:username], params[:password] ]
50
+ # auth is valid - confirm it
51
+ true
52
+ else
53
+ # invalid auth - request the authentication
54
+ response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth")
55
+ throw(:halt, [401, "Not authorized\n"])
56
+ end
57
+ end
58
+
59
+ get '/auth_ntlm' do
60
+ # we're just checking for the existence if NTLM auth header here. It's validation
61
+ # is too troublesome and really doesn't bother is much, it's up to libcurl to make
62
+ # it valid
63
+ response['WWW-Authenticate'] = 'NTLM'
64
+ is_ntlm_auth = /^NTLM/ =~ request.env['HTTP_AUTHORIZATION']
65
+ true if is_ntlm_auth
66
+ throw(:halt, [401, "Not authorized\n"]) if !is_ntlm_auth
67
+ end
68
+
69
+ get '/gzipped' do
70
+ req_env = request.env.to_json
71
+ z = Zlib::Deflate.new
72
+ gzipped_env = z.deflate(req_env, Zlib::FINISH)
73
+ z.close
74
+ response['Content-Encoding'] = 'gzip'
75
+ gzipped_env
76
+ end
77
+
78
+ get '/**' do
79
+ sleep params["delay"].to_i if params.has_key?("delay")
80
+ request.env.merge!(:body => request.body.read).to_json
81
+ end
82
+
83
+ head '/**' do
84
+ sleep params["delay"].to_i if params.has_key?("delay")
85
+ end
86
+
87
+ put '/**' do
88
+ request.env.merge!(:body => request.body.read).to_json
89
+ end
90
+
91
+ post '/**' do
92
+ request.env.merge!(:body => request.body.read).to_json
93
+ end
94
+
95
+ delete '/**' do
96
+ request.env.merge!(:body => request.body.read).to_json
97
+ end
@@ -0,0 +1,19 @@
1
+ require "rubygems"
2
+ require 'json'
3
+ require "rspec"
4
+
5
+ # gem install redgreen for colored test output
6
+ begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
7
+
8
+ path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
9
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
10
+
11
+ require path + '/typhoeus'
12
+
13
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
14
+
15
+ RSpec.configure do |config|
16
+ config.before(:suite) do
17
+ TyphoeusLocalhostServer.start_servers!
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ class TyphoeusLocalhostServer
5
+ class << self
6
+ attr_accessor :pid
7
+
8
+ def start_servers!
9
+ if self.pid = fork
10
+ start_parent
11
+ wait_for_servers_to_start
12
+ else
13
+ start_child
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def start_parent
20
+ # Cleanup.
21
+ at_exit do
22
+ Process.kill('QUIT', self.pid) if self.pid
23
+ end
24
+ end
25
+
26
+ def start_child
27
+ exec('rake', 'start_test_servers')
28
+ end
29
+
30
+ def wait_for_servers_to_start
31
+ puts "Waiting for servers to start..."
32
+ ports = [3000, 3001, 3002]
33
+
34
+ Timeout::timeout(10) do
35
+ loop do
36
+ up = 0
37
+ ports.each do |port|
38
+ url = "http://localhost:#{port}/"
39
+ begin
40
+ response = Net::HTTP.get_response(URI.parse(url))
41
+ if response.is_a?(Net::HTTPSuccess)
42
+ up += 1
43
+ end
44
+ rescue SystemCallError => error
45
+ end
46
+ end
47
+
48
+ if up == ports.size
49
+ puts "Servers are up!"
50
+ break
51
+ end
52
+ end
53
+ end
54
+ rescue Timeout::Error => error
55
+ abort "Servers never started!"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,391 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ if defined?(Encoding)
5
+ Encoding.default_internal = 'utf-8'
6
+ Encoding.default_external = 'utf-8'
7
+ end
8
+
9
+ describe Typhoeus::Easy do
10
+ describe "ssl_version" do
11
+ before(:each) do
12
+ @easy = Typhoeus::Easy.new
13
+ @easy.url = "http://localhost:3000"
14
+ @easy.method = :get
15
+ end
16
+
17
+ it "should allow to set the SSL version to be used" do
18
+ Typhoeus::Easy::SSL_VERSIONS.each do |k, v|
19
+ @easy.ssl_version = k
20
+ @easy.perform
21
+ @easy.response_code.should == 200
22
+ @easy.ssl_version.should == k
23
+ end
24
+ end
25
+
26
+ it "complains when an incorrect SSL version is used" do
27
+ expect { @easy.ssl_version = 'bogus' }.to raise_error
28
+ end
29
+
30
+ it "uses the default SSL version if nothing is supplied" do
31
+ @easy.ssl_version.should == :default
32
+ end
33
+ end
34
+
35
+ describe "#supports_zlib" do
36
+ before(:each) do
37
+ @easy = Typhoeus::Easy.new
38
+ end
39
+
40
+ it "should return true if the version string has zlib" do
41
+ @easy.stub!(:curl_version).and_return("libcurl/7.20.0 OpenSSL/0.9.8l zlib/1.2.3 libidn/1.16")
42
+ @easy.supports_zlib?.should be_true
43
+ end
44
+
45
+ it "should return false if the version string doesn't have zlib" do
46
+ @easy.stub!(:curl_version).and_return("libcurl/7.20.0 OpenSSL/0.9.8l libidn/1.16")
47
+ @easy.supports_zlib?.should be_false
48
+ end
49
+ end
50
+
51
+ describe "curl errors" do
52
+ it "should provide the CURLE_OPERATION_TIMEDOUT return code when a request times out" do
53
+ e = Typhoeus::Easy.new
54
+ e.url = "http://localhost:3001/?delay=1"
55
+ e.method = :get
56
+ e.timeout = 100
57
+ e.perform
58
+ e.curl_return_code.should == 28
59
+ e.curl_error_message.should == "Timeout was reached"
60
+ e.response_code.should == 0
61
+ end
62
+
63
+ it "should provide the CURLE_COULDNT_CONNECT return code when trying to connect to a non existent port" do
64
+ e = Typhoeus::Easy.new
65
+ e.url = "http://localhost:3999"
66
+ e.method = :get
67
+ e.connect_timeout = 100
68
+ e.perform
69
+ e.curl_return_code.should == 7
70
+ e.curl_error_message.should == "Couldn't connect to server"
71
+ e.response_code.should == 0
72
+ end
73
+
74
+ it "should not return an error message on a successful easy operation" do
75
+ easy = Typhoeus::Easy.new
76
+ easy.url = "http://localhost:3002"
77
+ easy.method = :get
78
+ easy.curl_error_message.should == nil
79
+ easy.perform
80
+ easy.response_code.should == 200
81
+ easy.curl_return_code.should == 0
82
+ easy.curl_error_message.should == "No error"
83
+ end
84
+
85
+ end
86
+
87
+ describe "options" do
88
+ it "should not follow redirects if not instructed to" do
89
+ e = Typhoeus::Easy.new
90
+ e.url = "http://localhost:3001/redirect"
91
+ e.method = :get
92
+ e.perform
93
+ e.response_code.should == 302
94
+ end
95
+
96
+ it "should allow for following redirects" do
97
+ e = Typhoeus::Easy.new
98
+ e.url = "http://localhost:3001/redirect"
99
+ e.method = :get
100
+ e.follow_location = true
101
+ e.perform
102
+ e.response_code.should == 200
103
+ JSON.parse(e.response_body)["REQUEST_METHOD"].should == "GET"
104
+ end
105
+
106
+ it "should allow you to set the user agent" do
107
+ e = Typhoeus::Easy.new
108
+ e.url = "http://localhost:3002"
109
+ e.method = :get
110
+ e.headers['User-Agent'] = 'myapp'
111
+ e.perform
112
+ e.response_code.should == 200
113
+ JSON.parse(e.response_body)["HTTP_USER_AGENT"].should == "myapp"
114
+ end
115
+
116
+ it "should provide a timeout in milliseconds" do
117
+ e = Typhoeus::Easy.new
118
+ e.url = "http://localhost:3001/?delay=1"
119
+ e.method = :get
120
+ e.timeout = 10
121
+ e.perform
122
+ e.timed_out?.should == true
123
+ end
124
+
125
+ it "should allow the setting of the max redirects to follow" do
126
+ e = Typhoeus::Easy.new
127
+ e.url = "http://localhost:3001/redirect"
128
+ e.method = :get
129
+ e.follow_location = true
130
+ e.max_redirects = 5
131
+ e.perform
132
+ e.response_code.should == 200
133
+ end
134
+
135
+ it "should handle our bad redirect action, provided we've set max_redirects properly" do
136
+ e = Typhoeus::Easy.new
137
+ e.url = "http://localhost:3001/bad_redirect"
138
+ e.method = :get
139
+ e.follow_location = true
140
+ e.max_redirects = 5
141
+ e.perform
142
+ e.response_code.should == 302
143
+ end
144
+
145
+ it "should provide the primary IP address that was used to perform the HTTP request" do
146
+ e = Typhoeus::Easy.new
147
+ e.url = "http://localhost:3002"
148
+ e.method = :get
149
+ e.perform
150
+ e.response_code.should == 200
151
+ e.primary_ip.should == "127.0.0.1"
152
+ end
153
+ end
154
+
155
+ describe "authentication" do
156
+ it "should allow to set username and password" do
157
+ e = Typhoeus::Easy.new
158
+ username, password = 'foo', 'bar'
159
+ e.auth = { :username => username, :password => password }
160
+ e.url = "http://localhost:3001/auth_basic/#{username}/#{password}"
161
+ e.method = :get
162
+ e.perform
163
+ e.response_code.should == 200
164
+ end
165
+
166
+ it "should allow to query auth methods support by the server" do
167
+ e = Typhoeus::Easy.new
168
+ e.url = "http://localhost:3001/auth_basic/foo/bar"
169
+ e.method = :get
170
+ e.perform
171
+ e.auth_methods.should == Typhoeus::Easy::AUTH_TYPES[:CURLAUTH_BASIC]
172
+ end
173
+
174
+ it "should allow to set authentication method" do
175
+ e = Typhoeus::Easy.new
176
+ e.auth = { :username => 'username', :password => 'password', :method => Typhoeus::Easy::AUTH_TYPES[:CURLAUTH_NTLM] }
177
+ e.url = "http://localhost:3001/auth_ntlm"
178
+ e.method = :get
179
+ e.perform
180
+ e.response_code.should == 200
181
+ end
182
+ end
183
+
184
+ describe "get" do
185
+ it "should perform a get" do
186
+ easy = Typhoeus::Easy.new
187
+ easy.url = "http://localhost:3002"
188
+ easy.method = :get
189
+ easy.perform
190
+ easy.response_code.should == 200
191
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "GET"
192
+ end
193
+ end
194
+
195
+ describe "purge" do
196
+ it "should set custom request to purge" do
197
+ easy = Typhoeus::Easy.new
198
+ easy.should_receive(:set_option).with(Typhoeus::Easy::OPTION_VALUES[:CURLOPT_CUSTOMREQUEST], "PURGE").once
199
+ easy.method = :purge
200
+ end
201
+ end
202
+
203
+ describe "head" do
204
+ it "should perform a head" do
205
+ easy = Typhoeus::Easy.new
206
+ easy.url = "http://localhost:3002"
207
+ easy.method = :head
208
+ easy.perform
209
+ easy.response_code.should == 200
210
+ end
211
+ end
212
+
213
+ describe "start_time" do
214
+ it "should be get/settable" do
215
+ time = Time.now
216
+ easy = Typhoeus::Easy.new
217
+ easy.start_time.should be_nil
218
+ easy.start_time = time
219
+ easy.start_time.should == time
220
+ end
221
+ end
222
+
223
+ describe "params=" do
224
+ it "should handle arrays of params" do
225
+ easy = Typhoeus::Easy.new
226
+ easy.url = "http://localhost:3002/index.html"
227
+ easy.method = :get
228
+ easy.request_body = "this is a body!"
229
+ easy.params = {
230
+ :foo => 'bar',
231
+ :username => ['dbalatero', 'dbalatero2']
232
+ }
233
+ easy.url.should =~ /\?.*foo=bar&username=dbalatero&username=dbalatero2/
234
+ end
235
+ end
236
+
237
+
238
+ describe "put" do
239
+ it "should perform a put" do
240
+ easy = Typhoeus::Easy.new
241
+ easy.url = "http://localhost:3002"
242
+ easy.method = :put
243
+ easy.perform
244
+ easy.response_code.should == 200
245
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "PUT"
246
+ end
247
+
248
+ it "should send a request body" do
249
+ easy = Typhoeus::Easy.new
250
+ easy.url = "http://localhost:3002"
251
+ easy.method = :put
252
+ easy.request_body = "this is a body!"
253
+ easy.perform
254
+ easy.response_code.should == 200
255
+ easy.response_body.should include("this is a body!")
256
+ end
257
+
258
+ it "should be able perform put with empty bodies on the same easy handle" do
259
+ easy = Typhoeus::Easy.new
260
+ easy.url = "http://localhost:3002"
261
+ easy.method = :put
262
+ easy.perform
263
+ easy.response_code.should == 200
264
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "PUT"
265
+
266
+ easy.reset
267
+
268
+ easy.url = "http://localhost:3002"
269
+ easy.method = :put
270
+ easy.perform
271
+ easy.response_code.should == 200
272
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "PUT"
273
+ end
274
+
275
+ it "should set content length correctly for a utf-8 string" do
276
+ body = "this is a body with utf-8 content: Motörhead! WHÖÖ!"
277
+ easy = Typhoeus::Easy.new
278
+ easy.url = "http://localhost:3002"
279
+ easy.method = :post
280
+ easy.should_receive(:set_option).with(Typhoeus::Easy::OPTION_VALUES[:CURLOPT_POSTFIELDSIZE], 55)
281
+ easy.should_receive(:set_option).with(Typhoeus::Easy::OPTION_VALUES[:CURLOPT_COPYPOSTFIELDS], body)
282
+ easy.request_body = body
283
+ end
284
+ end
285
+
286
+ describe "post" do
287
+ it "should perform a post" do
288
+ easy = Typhoeus::Easy.new
289
+ easy.url = "http://localhost:3002"
290
+ easy.method = :post
291
+ easy.perform
292
+ easy.response_code.should == 200
293
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "POST"
294
+ end
295
+
296
+ it "should send a request body" do
297
+ easy = Typhoeus::Easy.new
298
+ easy.url = "http://localhost:3002"
299
+ easy.method = :post
300
+ easy.request_body = "this is a body!"
301
+ easy.perform
302
+ easy.response_code.should == 200
303
+ easy.response_body.should include("this is a body!")
304
+ end
305
+
306
+ it "should handle params" do
307
+ easy = Typhoeus::Easy.new
308
+ easy.url = "http://localhost:3002"
309
+ easy.method = :post
310
+ easy.params = {:foo => "bar"}
311
+ easy.perform
312
+ easy.response_code.should == 200
313
+ easy.response_body.should =~ /foo=bar/
314
+ end
315
+
316
+ it "should use Content-Type: application/x-www-form-urlencoded for normal posts" do
317
+ easy = Typhoeus::Easy.new
318
+ easy.url = "http://localhost:3002/normal_post"
319
+ easy.method = :post
320
+ easy.params = { :a => 'b', :c => 'd',
321
+ :e => { :f => { :g => 'h' } } }
322
+ easy.perform
323
+
324
+ request = JSON.parse(easy.response_body)
325
+ request['CONTENT_TYPE'].should == 'application/x-www-form-urlencoded'
326
+ request['rack.request.form_vars'].should == 'a=b&c=d&e[f][g]=h'
327
+ end
328
+
329
+ it "should handle a file upload, as multipart" do
330
+ easy = Typhoeus::Easy.new
331
+ easy.url = "http://localhost:3002/file"
332
+ easy.method = :post
333
+ easy.params = {:file => File.open(File.expand_path(File.dirname(__FILE__) + "/../fixtures/placeholder.txt"), "r")}
334
+ easy.perform
335
+ easy.response_code.should == 200
336
+ result = JSON.parse(easy.response_body)
337
+
338
+ { 'content-type' => 'text/plain',
339
+ 'filename' => 'placeholder.txt',
340
+ 'content' => 'This file is used to test uploading.'
341
+ }.each do |key, val|
342
+ result[key].should == val
343
+ end
344
+
345
+ result['request-content-type'].should =~ /multipart/
346
+ end
347
+ end
348
+
349
+ describe "delete" do
350
+ it "should perform a delete" do
351
+ easy = Typhoeus::Easy.new
352
+ easy.url = "http://localhost:3002"
353
+ easy.method = :delete
354
+ easy.perform
355
+ easy.response_code.should == 200
356
+ JSON.parse(easy.response_body)["REQUEST_METHOD"].should == "DELETE"
357
+ end
358
+
359
+ it "should send a request body" do
360
+ easy = Typhoeus::Easy.new
361
+ easy.url = "http://localhost:3002"
362
+ easy.method = :delete
363
+ easy.request_body = "this is a body!"
364
+ easy.perform
365
+ easy.response_code.should == 200
366
+ easy.response_body.should include("this is a body!")
367
+ end
368
+ end
369
+
370
+ describe "encoding/compression support" do
371
+
372
+ it "should send valid encoding headers and decode the response" do
373
+ easy = Typhoeus::Easy.new
374
+ easy.url = "http://localhost:3002/gzipped"
375
+ easy.method = :get
376
+ easy.perform
377
+ easy.response_code.should == 200
378
+ JSON.parse(easy.response_body)["HTTP_ACCEPT_ENCODING"].should == "deflate, gzip"
379
+ end
380
+
381
+ it "should send valid encoding headers and decode the response after reset" do
382
+ easy = Typhoeus::Easy.new
383
+ easy.reset
384
+ easy.url = "http://localhost:3002/gzipped"
385
+ easy.method = :get
386
+ easy.perform
387
+ easy.response_code.should == 200
388
+ JSON.parse(easy.response_body)["HTTP_ACCEPT_ENCODING"].should == "deflate, gzip"
389
+ end
390
+ end
391
+ end