|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
1 |
require 'net/http' |
| |
2 |
require 'net/https' |
| |
3 |
require 'uri' |
|
de9b4fb6
»
|
jnunemaker |
2008-07-27 |
Put in first wave of parsin...  |
4 |
require 'ostruct' |
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
5 |
require 'rubygems' |
| |
6 |
require 'active_support' |
| |
7 |
|
|
fda012a3
»
|
jnunemaker |
2008-11-08 |
Removed stupid core extensi... |
8 |
directory = File.dirname(__FILE__) |
| |
9 |
$:.unshift(directory) unless $:.include?(directory) || $:.include?(File.expand_path(directory)) |
|
ae7ce309
»
|
evri |
2008-09-19 |
Add the ability to automati... |
10 |
|
|
1d48da03
»
|
jnunemaker |
2008-07-28 |
Renamed to HTTParty which i... |
11 |
module HTTParty |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
12 |
class UnsupportedFormat < StandardError; end |
|
ae7ce309
»
|
evri |
2008-09-19 |
Add the ability to automati... |
13 |
class RedirectionTooDeep < StandardError; end |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
14 |
|
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
15 |
def self.included(base) |
| |
16 |
base.extend ClassMethods |
| |
17 |
end |
| |
18 |
|
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
19 |
AllowedFormats = {:xml => 'text/xml', :json => 'application/json'} |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
20 |
SupportedHTTPMethods = [Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put, Net::HTTP::Delete] |
|
0a1737e2
»
|
jnunemaker |
2008-07-28 |
Added several specs for htt... |
21 |
|
| |
22 |
module ClassMethods |
|
b0f1cc2a
»
|
francxk |
2008-08-18 |
Raises exception when http ... |
23 |
# |
| |
24 |
# Set an http proxy |
| |
25 |
# |
| |
26 |
# class Twitter |
| |
27 |
# include HTTParty |
| |
28 |
# http_proxy http://myProxy, 1080 |
| |
29 |
# .... |
| |
30 |
def http_proxy(addr=nil, port = nil) |
| |
31 |
@http_proxyaddr = addr |
| |
32 |
@http_proxyport = port |
| |
33 |
end |
| |
34 |
|
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
35 |
def base_uri(base_uri=nil) |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
36 |
return @base_uri unless base_uri |
|
0a1737e2
»
|
jnunemaker |
2008-07-28 |
Added several specs for htt... |
37 |
@base_uri = normalize_base_uri(base_uri) |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
38 |
end |
| |
39 |
|
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
40 |
# Warning: This is not thread safe most likely and |
| |
41 |
# only works if you use one set of credentials. I |
| |
42 |
# leave it because it is convenient on some occasions. |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
43 |
def basic_auth(u, p) |
| |
44 |
@auth = {:username => u, :password => p} |
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
45 |
end |
| |
46 |
|
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
47 |
# Updates the default query string parameters |
| |
48 |
# that should be appended to each request. |
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
49 |
def default_params(h={}) |
| |
50 |
raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash) |
|
0c05dcda
»
|
jnunemaker |
2008-07-28 |
Added #default_params metho... |
51 |
@default_params ||= {} |
| |
52 |
return @default_params if h.blank? |
| |
53 |
@default_params.merge!(h) |
| |
54 |
end |
| |
55 |
|
| |
56 |
def headers(h={}) |
| |
57 |
raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash) |
| |
58 |
@headers ||= {} |
| |
59 |
return @headers if h.blank? |
| |
60 |
@headers.merge!(h) |
| |
61 |
end |
| |
62 |
|
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
63 |
def format(f) |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
64 |
raise UnsupportedFormat, "Must be one of: #{AllowedFormats.keys.join(', ')}" unless AllowedFormats.key?(f) |
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
65 |
@format = f |
| |
66 |
end |
| |
67 |
|
| |
68 |
# TODO: spec out this |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
69 |
def get(path, options={}) |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
70 |
send_request Net::HTTP::Get, path, options |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
71 |
end |
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
72 |
|
| |
73 |
# TODO: spec out this |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
74 |
def post(path, options={}) |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
75 |
send_request Net::HTTP::Post, path, options |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
76 |
end |
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
77 |
|
| |
78 |
# TODO: spec out this |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
79 |
def put(path, options={}) |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
80 |
send_request Net::HTTP::Put, path, options |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
81 |
end |
|
236b3ad4
»
|
jnunemaker |
2008-07-28 |
Made it so default_params a... |
82 |
|
| |
83 |
# TODO: spec out this |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
84 |
def delete(path, options={}) |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
85 |
send_request Net::HTTP::Delete, path, options |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
86 |
end |
| |
87 |
|
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
88 |
private |
|
b3094fc1
»
|
jnunemaker |
2008-07-30 |
nodoc'd some stuff |
89 |
def http(uri) #:nodoc: |
|
3101b531
»
|
jnunemaker |
2008-11-08 |
Got redirection all work pr... |
90 |
http = Net::HTTP.new(uri.host, uri.port, @http_proxyaddr, @http_proxyport) |
| |
91 |
http.use_ssl = (uri.port == 443) |
| |
92 |
http.verify_mode = OpenSSL::SSL::VERIFY_NONE |
| |
93 |
http |
|
f4570a46
»
|
jnunemaker |
2008-07-28 |
base_uri is no longer requi... |
94 |
end |
| |
95 |
|
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
96 |
# FIXME: this method is doing way to much and needs to be split up |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
97 |
# options can be any or all of: |
|
9b423a22
»
|
jnunemaker |
2008-07-30 |
:body and :query now both t... |
98 |
# query => hash of keys/values or a query string (foo=bar&baz=poo) |
| |
99 |
# body => hash of keys/values or a query string (foo=bar&baz=poo) |
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
100 |
# headers => hash of headers to send request with |
| |
101 |
# basic_auth => :username and :password to use as basic http authentication (overrides @auth class instance variable) |
|
b0f1cc2a
»
|
francxk |
2008-08-18 |
Raises exception when http ... |
102 |
# Raises exception Net::XXX (http error code) if an http error occured |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
103 |
def send_request(klass, path, options={}) #:nodoc: |
|
ae7ce309
»
|
evri |
2008-09-19 |
Add the ability to automati... |
104 |
options = {:limit => 5}.merge(options) |
| |
105 |
options[:limit] = 0 if options.delete(:no_follow) |
|
3101b531
»
|
jnunemaker |
2008-11-08 |
Got redirection all work pr... |
106 |
|
|
ae7ce309
»
|
evri |
2008-09-19 |
Add the ability to automati... |
107 |
raise HTTParty::RedirectionTooDeep, 'HTTP redirects too deep' if options[:limit].to_i <= 0 |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
108 |
raise ArgumentError, 'only get, post, put and delete methods are supported' unless SupportedHTTPMethods.include?(klass) |
|
a8ff3e36
»
|
jnunemaker |
2008-07-28 |
Added some argument errors ... |
109 |
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash) |
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
110 |
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash) |
|
3101b531
»
|
jnunemaker |
2008-11-08 |
Got redirection all work pr... |
111 |
|
|
a279df8f
»
|
evri |
2008-09-19 |
Be a little smarter with th... |
112 |
path = URI.parse(path) |
| |
113 |
uri = path.relative? ? URI.parse("#{base_uri}#{path}") : path |
|
9b423a22
»
|
jnunemaker |
2008-07-30 |
:body and :query now both t... |
114 |
existing_query = uri.query ? "#{uri.query}&" : '' |
| |
115 |
uri.query = if options[:query].blank? |
|
a3f744b2
»
|
jnunemaker |
2008-08-09 |
Fixed that default_params w... |
116 |
existing_query + default_params.to_query |
|
9b423a22
»
|
jnunemaker |
2008-07-30 |
:body and :query now both t... |
117 |
else |
| |
118 |
existing_query + (options[:query].is_a?(Hash) ? default_params.merge(options[:query]).to_query : options[:query]) |
| |
119 |
end |
|
3101b531
»
|
jnunemaker |
2008-11-08 |
Got redirection all work pr... |
120 |
|
|
9b423a22
»
|
jnunemaker |
2008-07-30 |
:body and :query now both t... |
121 |
request = klass.new(uri.request_uri) |
| |
122 |
request.body = options[:body].is_a?(Hash) ? options[:body].to_query : options[:body] unless options[:body].blank? |
| |
123 |
basic_auth = options.delete(:basic_auth) || @auth |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
124 |
request.initialize_http_header headers.merge(options[:headers] || {}) |
|
3a8ad1da
»
|
jnunemaker |
2008-07-30 |
Added :basic_auth as an opt... |
125 |
request.basic_auth(basic_auth[:username], basic_auth[:password]) if basic_auth |
|
9b423a22
»
|
jnunemaker |
2008-07-30 |
:body and :query now both t... |
126 |
response = http(uri).request(request) |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
127 |
@format ||= format_from_mimetype(response['content-type']) |
| |
128 |
|
|
b0f1cc2a
»
|
francxk |
2008-08-18 |
Raises exception when http ... |
129 |
case response |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
130 |
when Net::HTTPSuccess |
|
b0f1cc2a
»
|
francxk |
2008-08-18 |
Raises exception when http ... |
131 |
parse_response(response.body) |
|
ae7ce309
»
|
evri |
2008-09-19 |
Add the ability to automati... |
132 |
when Net::HTTPRedirection |
| |
133 |
options[:limit] -= 1 |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
134 |
send_request(klass, response['location'], options) |
|
b0f1cc2a
»
|
francxk |
2008-08-18 |
Raises exception when http ... |
135 |
else |
| |
136 |
response.instance_eval { class << self; attr_accessor :body_parsed; end } |
| |
137 |
begin; response.body_parsed = parse_response(response.body); rescue; end |
| |
138 |
response.error! # raises exception corresponding to http error Net::XXX |
| |
139 |
end |
| |
140 |
|
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
141 |
end |
| |
142 |
|
|
b3094fc1
»
|
jnunemaker |
2008-07-30 |
nodoc'd some stuff |
143 |
def parse_response(body) #:nodoc: |
|
31ad4f91
»
|
evri |
2008-08-27 |
Treat nil or empty bodies s... |
144 |
return nil if body.nil? or body.empty? |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
145 |
case @format |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
146 |
when :xml |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
147 |
Hash.from_xml(body) |
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
148 |
when :json |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
149 |
ActiveSupport::JSON.decode(body) |
|
de9b4fb6
»
|
jnunemaker |
2008-07-27 |
Put in first wave of parsin...  |
150 |
else |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
151 |
body |
|
de9b4fb6
»
|
jnunemaker |
2008-07-27 |
Put in first wave of parsin...  |
152 |
end |
|
8e143785
»
|
jnunemaker |
2008-07-27 |
get, post, put and delete n... |
153 |
end |
| |
154 |
|
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
155 |
# Makes it so uri is sure to parse stuff like google.com with the http |
|
bcc38bcf
»
|
jnunemaker |
2008-11-08 |
Cleaned up base uri normali... |
156 |
def normalize_base_uri(url) #:nodoc: |
| |
157 |
use_ssl = (url =~ /^https/) || url.include?(':443') |
| |
158 |
url.chop! if url.ends_with?('/') |
| |
159 |
url.gsub!(/^https?:\/\//i, '') |
| |
160 |
"http#{'s' if use_ssl}://#{url}" |
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
161 |
end |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
162 |
|
|
76601ba0
»
|
jnunemaker |
2008-08-22 |
Changed format detection fr... |
163 |
# Uses the HTTP Content-Type header to determine the format of the response |
| |
164 |
# It compares the MIME type returned to the types stored in the AllowedFormats hash |
| |
165 |
def format_from_mimetype(mimetype) #:nodoc: |
| |
166 |
AllowedFormats.each { |k, v| return k if mimetype.include?(v) } |
|
13620e30
»
|
jnunemaker |
2008-07-27 |
Added Hash#to_struct for ma... |
167 |
end |
|
df29a552
»
|
jnunemaker |
2008-07-27 |
Initial commit |
168 |
end |
|
a2fd0925
»
|
reinh |
2008-11-08 |
Replacing string parameters... |
169 |
end |