Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/toland/patron
Browse files Browse the repository at this point in the history
  • Loading branch information
windy committed Mar 20, 2012
2 parents 90f81e0 + 6214c29 commit 0aa6085
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 30 deletions.
17 changes: 9 additions & 8 deletions ext/patron/session_ext.c
Expand Up @@ -336,8 +336,10 @@ static void set_options_from_request(VALUE self, VALUE request) {
rb_hash_foreach(headers, each_http_header, self); rb_hash_foreach(headers, each_http_header, self);
} }


action = SYM2ID(rb_iv_get(request, "@action")); VALUE action_name = rb_iv_get(request, "@action");
if (action == rb_intern("get")) {
action = rb_to_id(action_name);
if (action == rb_intern("GET")) {
VALUE data = rb_iv_get(request, "@upload_data"); VALUE data = rb_iv_get(request, "@upload_data");
VALUE download_file = rb_iv_get(request, "@file_name"); VALUE download_file = rb_iv_get(request, "@file_name");


Expand All @@ -357,7 +359,7 @@ static void set_options_from_request(VALUE self, VALUE request) {
} else { } else {
state->download_file = NULL; state->download_file = NULL;
} }
} else if (action == rb_intern("post") || action == rb_intern("put")) { } else if (action == rb_intern("POST") || action == rb_intern("PUT")) {
VALUE data = rb_iv_get(request, "@upload_data"); VALUE data = rb_iv_get(request, "@upload_data");
VALUE filename = rb_iv_get(request, "@file_name"); VALUE filename = rb_iv_get(request, "@file_name");
VALUE multipart = rb_iv_get(request, "@multipart"); VALUE multipart = rb_iv_get(request, "@multipart");
Expand All @@ -367,7 +369,7 @@ static void set_options_from_request(VALUE self, VALUE request) {


state->upload_buf = StringValuePtr(data); state->upload_buf = StringValuePtr(data);


if (action == rb_intern("post")) { if (action == rb_intern("POST")) {
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, state->upload_buf); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, state->upload_buf);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
Expand All @@ -382,14 +384,14 @@ static void set_options_from_request(VALUE self, VALUE request) {


curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);


if (action == rb_intern("post")) { if (action == rb_intern("POST")) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
} }


state->upload_file = open_file(filename, "rb"); state->upload_file = open_file(filename, "rb");
curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file); curl_easy_setopt(curl, CURLOPT_READDATA, state->upload_file);
} else if (!NIL_P(multipart)) { } else if (!NIL_P(multipart)) {
if (action == rb_intern("post")) { if (action == rb_intern("POST")) {
if(!NIL_P(data) && !NIL_P(filename)) { if(!NIL_P(data) && !NIL_P(filename)) {
if (rb_type(data) == T_HASH && rb_type(filename) == T_HASH) { if (rb_type(data) == T_HASH && rb_type(filename) == T_HASH) {
rb_hash_foreach(data, formadd_values, self); rb_hash_foreach(data, formadd_values, self);
Expand All @@ -405,10 +407,9 @@ static void set_options_from_request(VALUE self, VALUE request) {
} else { } else {
rb_raise(rb_eArgError, "Must provide either data or a filename when doing a PUT or POST"); rb_raise(rb_eArgError, "Must provide either data or a filename when doing a PUT or POST");
} }
} else if (action == rb_intern("head")) { } else if (action == rb_intern("HEAD")) {
curl_easy_setopt(curl, CURLOPT_NOBODY, 1); curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
} else { } else {
VALUE action_name = rb_funcall(request, rb_intern("action_name"), 0);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, StringValuePtr(action_name)); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, StringValuePtr(action_name));
} }


Expand Down
58 changes: 42 additions & 16 deletions lib/patron/request.rb
Expand Up @@ -32,19 +32,29 @@ module Patron
# used in every request. # used in every request.
class Request class Request


VALID_ACTIONS = [:get, :put, :post, :delete, :head, :copy] VALID_ACTIONS = %w[GET PUT POST DELETE HEAD COPY]


def initialize def initialize
@action = :get @action = 'GET'
@headers = {} @headers = {}
@timeout = 0 @timeout = 0
@connect_timeout = 0 @connect_timeout = 0
@max_redirects = -1 @max_redirects = -1
end end


attr_accessor :url, :username, :password, :file_name, :proxy, :proxy_type, :auth_type, :insecure, :ignore_content_length, :multipart READER_VARS = [
attr_reader :action, :timeout, :connect_timeout, :max_redirects, :headers, :buffer_size :url, :username, :password, :file_name, :proxy, :proxy_type, :insecure,
attr_reader :auth_type :ignore_content_length, :multipart, :action, :timeout, :connect_timeout,
:max_redirects, :headers, :auth_type, :upload_data, :buffer_size
]

WRITER_VARS = [
:url, :username, :password, :file_name, :proxy, :proxy_type, :insecure,
:ignore_content_length, :multipart
]

attr_reader *READER_VARS
attr_writer *WRITER_VARS


# Set the type of authentication to use for this request. # Set the type of authentication to use for this request.
# #
Expand All @@ -71,22 +81,20 @@ def auth_type=(type=:basic)
def upload_data=(data) def upload_data=(data)
@upload_data = case data @upload_data = case data
when Hash when Hash
self.multipart ? data : Util.build_query_string_from_hash(data, @action == :post) self.multipart ? data : Util.build_query_string_from_hash(data, action == 'POST')
else else
data data
end end
end end


def upload_data
@upload_data
end

def action=(new_action) def action=(new_action)
if !VALID_ACTIONS.include?(new_action) action = new_action.to_s.upcase

if !VALID_ACTIONS.include?(action)
raise ArgumentError, "Action must be one of #{VALID_ACTIONS.join(', ')}" raise ArgumentError, "Action must be one of #{VALID_ACTIONS.join(', ')}"
end end


@action = new_action @action = action
end end


def timeout=(new_timeout) def timeout=(new_timeout)
Expand Down Expand Up @@ -129,14 +137,32 @@ def buffer_size=(buffer_size)
@buffer_size = buffer_size != nil ? buffer_size.to_i : nil @buffer_size = buffer_size != nil ? buffer_size.to_i : nil
end end


def action_name
@action.to_s.upcase
end

def credentials def credentials
return nil if username.nil? || password.nil? return nil if username.nil? || password.nil?
"#{username}:#{password}" "#{username}:#{password}"
end end


def eql?(request)
return false unless Request === request

READER_VARS.inject(true) do |memo, name|
memo && (self.send(name) == request.send(name))
end
end

alias_method :==, :eql?

def marshal_dump
[ @url, @username, @password, @file_name, @proxy, @proxy_type, @insecure,
@ignore_content_length, @multipart, @action, @timeout, @connect_timeout,
@max_redirects, @headers, @auth_type, @upload_data, @buffer_size ]
end

def marshal_load(data)
@url, @username, @password, @file_name, @proxy, @proxy_type, @insecure,
@ignore_content_length, @multipart, @action, @timeout, @connect_timeout,
@max_redirects, @headers, @auth_type, @upload_data, @buffer_size = data
end

end end
end end
18 changes: 13 additions & 5 deletions lib/patron/response.rb
Expand Up @@ -35,13 +35,13 @@ def initialize(url, status, redirect_count, header_data, body, default_charset =
@status = status @status = status
@redirect_count = redirect_count @redirect_count = redirect_count
@body = body @body = body

@charset = determine_charset(header_data, body) || default_charset @charset = determine_charset(header_data, body) || default_charset

[url, header_data].each do |attr| [url, header_data].each do |attr|
convert_to_default_encoding!(attr) convert_to_default_encoding!(attr)
end end

parse_headers(header_data) parse_headers(header_data)
if @headers["Content-Type"] && @headers["Content-Type"][0, 5] == "text/" if @headers["Content-Type"] && @headers["Content-Type"][0, 5] == "text/"
convert_to_default_encoding!(@body) convert_to_default_encoding!(@body)
Expand All @@ -55,14 +55,22 @@ def inspect
"#<Patron::Response @status_line='#{@status_line}'>" "#<Patron::Response @status_line='#{@status_line}'>"
end end


def marshal_dump
[@url, @status, @status_line, @redirect_count, @body, @headers, @charset]
end

def marshal_load(data)
@url, @status, @status_line, @redirect_count, @body, @headers, @charset = data
end

private private


def determine_charset(header_data, body) def determine_charset(header_data, body)
header_data.match(charset_regex) || (body && body.match(charset_regex)) header_data.match(charset_regex) || (body && body.match(charset_regex))

$1 $1
end end

def charset_regex def charset_regex
/(?:charset|encoding)="?([a-z0-9-]+)"?/i /(?:charset|encoding)="?([a-z0-9-]+)"?/i
end end
Expand Down
18 changes: 18 additions & 0 deletions spec/request_spec.rb
Expand Up @@ -83,4 +83,22 @@
end end


end end

describe :eql? do

it "should return true when two requests are equal" do
@request.should eql(Patron::Request.new)
end

it "should return false when two requests are not equal" do
req = Patron::Request.new
req.action = :post
@request.should_not eql(req)
end

end

it "should be able to serialize and deserialize itself" do
Marshal.load(Marshal.dump(@request)).should eql(@request)
end
end end
6 changes: 5 additions & 1 deletion spec/response_spec.rb
Expand Up @@ -48,11 +48,15 @@
response.headers['Content-Type'].should == 'image/png' response.headers['Content-Type'].should == 'image/png'
response.body.encoding.should == Encoding::ASCII_8BIT response.body.encoding.should == Encoding::ASCII_8BIT
end end

it "should not allow a default charset to be nil" do it "should not allow a default charset to be nil" do
Encoding.stub(:default_internal).and_return("UTF-8") Encoding.stub(:default_internal).and_return("UTF-8")
expect { expect {
Patron::Response.new("url", "status", 0, "", "", nil) Patron::Response.new("url", "status", 0, "", "", nil)
}.to_not raise_error }.to_not raise_error
end end

it "should be able to serialize and deserialize itself" do
Marshal.load(Marshal.dump(@request)).should eql(@request)
end
end end

0 comments on commit 0aa6085

Please sign in to comment.