diff --git a/README.rdoc b/README.rdoc index 70db237..7408333 100644 --- a/README.rdoc +++ b/README.rdoc @@ -217,6 +217,15 @@ use whatever proxy the system is configured to use: RestClient.proxy = ENV['http_proxy'] +== Query parameters + +Request objects know about query parameters and will automatically add them to +the url for GET, HEAD and DELETE requests and escape the keys and values as +needed: + + RestClient.get 'http://example.com/resource', :params => {:foo => 'bar', :baz => 'qux'} + # will GET http://example.com/resource?foo=bar&baz=qux + == Cookies Request and Response objects know about HTTP cookies, and will automatically diff --git a/history.md b/history.md index e4f26bb..c01b8df 100644 --- a/history.md +++ b/history.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD # 1.6.5 - RFC6265 requires single SP after ';' for separating parameters pairs in the 'Cookie:' header (patch provided by Hiroshi Nakamura) @@ -8,6 +9,8 @@ # 1.6.4 - fix restclient script compatibility with 1.9.2 +- fix unlinking temp file (patch provided by Evan Smith) +- monkeypatching ruby for http patch method (patch provided by Syl Turner) # 1.6.3 diff --git a/lib/restclient/net_http_ext.rb b/lib/restclient/net_http_ext.rb index 74148cd..ee40e9e 100644 --- a/lib/restclient/net_http_ext.rb +++ b/lib/restclient/net_http_ext.rb @@ -1,12 +1,46 @@ -# -# Replace the request method in Net::HTTP to sniff the body type -# and set the stream if appropriate -# -# Taken from: -# http://www.missiondata.com/blog/ruby/29/streaming-data-to-s3-with-ruby/ - module Net - class HTTP + class HTTP + + # Adding the patch method if it doesn't exist (rest-client issue: https://github.com/archiloque/rest-client/issues/79) + if !defined?(Net::HTTP::Patch) + # Code taken from this commit: https://github.com/ruby/ruby/commit/ab70e53ac3b5102d4ecbe8f38d4f76afad29d37d#lib/net/http.rb + class Protocol + # Sends a PATCH request to the +path+ and gets a response, + # as an HTTPResponse object. + def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+ + send_entity(path, data, initheader, dest, Patch, &block) + end + + # Executes a request which uses a representation + # and returns its body. + def send_entity(path, data, initheader, dest, type, &block) + res = nil + request(type.new(path, initheader), data) {|r| + r.read_body dest, &block + res = r + } + unless @newimpl + res.value + return res, res.body + end + res + end + end + + class Patch < HTTPRequest + METHOD = 'PATCH' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + end + + # + # Replace the request method in Net::HTTP to sniff the body type + # and set the stream if appropriate + # + # Taken from: + # http://www.missiondata.com/blog/ruby/29/streaming-data-to-s3-with-ruby/ + alias __request__ request def request(req, body=nil, &block) diff --git a/lib/restclient/payload.rb b/lib/restclient/payload.rb index e59c3bd..77b2d31 100644 --- a/lib/restclient/payload.rb +++ b/lib/restclient/payload.rb @@ -106,7 +106,7 @@ module RestClient alias :length :size def close - @stream.close + @stream.close unless @stream.closed? end def inspect diff --git a/lib/restclient/request.rb b/lib/restclient/request.rb index 98d50aa..766831b 100644 --- a/lib/restclient/request.rb +++ b/lib/restclient/request.rb @@ -62,6 +62,8 @@ module RestClient def execute & block uri = parse_url_with_auth(url) transmit uri, net_http_request_class(method).new(uri.request_uri, processed_headers), payload, & block + ensure + payload.close if payload end # Extract the query parameters and append them to the url diff --git a/spec/payload_spec.rb b/spec/payload_spec.rb index 5507d1e..89ded79 100644 --- a/spec/payload_spec.rb +++ b/spec/payload_spec.rb @@ -54,6 +54,11 @@ describe RestClient::Payload do RestClient::Payload::UrlEncoded.new({:foo => ['bar', 'baz']}).to_s. should == "foo[]=bar&foo[]=baz" end + + it 'should not close if stream already closed' do + p = RestClient::Payload::UrlEncoded.new({'foo ' => 'bar'}) + 3.times {p.close} + end end @@ -63,6 +68,11 @@ describe RestClient::Payload do m.stub!(:boundary).and_return(123) m.headers['Content-Type'].should == 'multipart/form-data; boundary=123' end + + it 'should not error on close if stream already closed' do + m = RestClient::Payload::Multipart.new(:file => File.new(File.join(File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg'))) + 3.times {m.close} + end it "should form properly separated multipart data" do m = RestClient::Payload::Multipart.new([[:bar, "baz"], [:foo, "bar"]]) diff --git a/spec/request2_spec.rb b/spec/request2_spec.rb index 7a897bd..8870657 100644 --- a/spec/request2_spec.rb +++ b/spec/request2_spec.rb @@ -23,5 +23,18 @@ describe RestClient::Request do response_value.should == "foo" end + it 'closes payload if not nil' do + test_file = File.new(File.join( File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg')) + initial_count = tmp_count + + stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).to_return(:body => 'foo', :status => 200) + RestClient::Request.execute(:url => 'http://some/resource', :method => :post, :payload => {:file => test_file}) + + tmp_count.should == initial_count + end + end +def tmp_count + Dir.glob(Dir::tmpdir + "/*").size +end \ No newline at end of file