Skip to content
Browse files

bug fix for Curl::Easy.http_post with internal post_body setter

  • Loading branch information...
1 parent 438c4de commit c2fb5d36349c7c39f6e7f5a67c750d7c9b2bce62 Todd Fisher committed
Showing with 90 additions and 3 deletions.
  1. +7 −3 ext/curb_easy.c
  2. +83 −0 tests/bug_curb_easy_post_with_string_no_content_length_header.rb
View
10 ext/curb_easy.c
@@ -656,7 +656,7 @@ static VALUE ruby_curl_easy_post_body_set(VALUE self, VALUE post_body) {
char *data;
long len;
-
+
Data_Get_Struct(self, ruby_curl_easy, rbce);
curl = rbce->curl;
@@ -1988,12 +1988,16 @@ static VALUE ruby_curl_easy_perform_post(int argc, VALUE *argv, VALUE self) {
return ret;
} else {
- VALUE post_body;
+ VALUE post_body = Qnil;
if ((post_body = rb_funcall(args_ary, idJoin, 1, rbstrAmp)) == Qnil) {
rb_raise(eCurlErrError, "Failed to join arguments");
return Qnil;
} else {
- ruby_curl_easy_post_body_set(self, post_body);
+ /* if the function call above returns an empty string because no additional arguments were passed this makes sure
+ a previously set easy.post_body = "arg=foo&bar=bin" will be honored */
+ if( post_body != Qnil && rb_type(post_body) == T_STRING && RSTRING_LEN(post_body) > 0 ) {
+ ruby_curl_easy_post_body_set(self, post_body);
+ }
return handle_perform(self,rbce);
}
View
83 tests/bug_curb_easy_post_with_string_no_content_length_header.rb
@@ -0,0 +1,83 @@
+=begin
+From jwhitmire
+Todd, I'm trying to use curb to post data to a REST url. We're using it to post support questions from our iphone app directly to tender. The post looks good to me, but curl is not adding the content-length header so I get a 411 length required response from the server.
+
+Here's my post block, do you see anything obvious? Do I need to manually add the Content-Length header?
+
+c = Curl::Easy.http_post(url) do |curl|
+ curl.headers["User-Agent"] = "Curl/Ruby"
+ if user
+ curl.headers["X-Multipass"] = user.multipass
+ else
+ curl.headers["X-Tender-Auth"] = TOKEN
+ end
+ curl.headers["Accept"] = "application/vnd.tender-v1+json"
+
+ curl.post_body = params.map{|f,k| "#{curl.escape(f)}=#{curl.escape(k)}"}.join('&')
+
+ curl.verbose = true
+ curl.follow_location = true
+ curl.enable_cookies = true
+end
+Any insight you care to share would be helpful. Thanks.
+=end
+require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
+require 'webrick'
+class ::WEBrick::HTTPServer ; def access_log(config, req, res) ; end ; end
+class ::WEBrick::BasicLog ; def log(level, data) ; end ; end
+
+class BugCurbEasyPostWithStringNoContentLengthHeader < Test::Unit::TestCase
+ def test_bug_workaround
+ server = WEBrick::HTTPServer.new( :Port => 9999 )
+ server.mount_proc("/test") do|req,res|
+ assert_equal '15', req['Content-Length']
+ res.body = "hi"
+ res['Content-Type'] = "text/html"
+ end
+
+ thread = Thread.new(server) do|srv|
+ srv.start
+ end
+ params = {:cat => "hat", :foo => "bar"}
+
+ post_body = params.map{|f,k| "#{Curl::Easy.new.escape(f)}=#{Curl::Easy.new.escape(k)}"}.join('&')
+ c = Curl::Easy.http_post("http://127.0.0.1:9999/test",post_body) do |curl|
+ curl.headers["User-Agent"] = "Curl/Ruby"
+ curl.headers["X-Tender-Auth"] = "A Token"
+ curl.headers["Accept"] = "application/vnd.tender-v1+json"
+
+ curl.follow_location = true
+ curl.enable_cookies = true
+ end
+
+ server.shutdown
+ thread.join
+ end
+ def test_bug
+ server = WEBrick::HTTPServer.new( :Port => 9999 )
+ server.mount_proc("/test") do|req,res|
+ assert_equal '15', req['Content-Length']
+ res.body = "hi"
+ res['Content-Type'] = "text/html"
+ end
+
+ thread = Thread.new(server) do|srv|
+ srv.start
+ end
+ params = {:cat => "hat", :foo => "bar"}
+
+ c = Curl::Easy.http_post("http://127.0.0.1:9999/test") do |curl|
+ curl.headers["User-Agent"] = "Curl/Ruby"
+ curl.headers["X-Tender-Auth"] = "A Token"
+ curl.headers["Accept"] = "application/vnd.tender-v1+json"
+
+ curl.post_body = params.map{|f,k| "#{curl.escape(f)}=#{curl.escape(k)}"}.join('&')
+
+ curl.follow_location = true
+ curl.enable_cookies = true
+ end
+
+ server.shutdown
+ thread.join
+ end
+end

0 comments on commit c2fb5d3

Please sign in to comment.
Something went wrong with that request. Please try again.