-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathhttp.rb
171 lines (147 loc) · 3.74 KB
/
http.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
require 'stockboy/provider'
require 'httpi'
module Stockboy::Providers
# Fetches data from an HTTP endpoint
#
# == Job template DSL
#
# provider :http do
# get "http://example.com/api/things"
# end
#
class HTTP < Stockboy::Provider
# @!group Options
# Shorthand for +:method+ and +:uri+ using HTTP GET
#
# @!attribute [rw] get
# @return [String]
# @example
# get 'http://example.com/api/things'
#
dsl_attr :get, attr_writer: false
# Shorthand for +:method+ and +:uri+ using HTTP POST
#
# @!attribute [rw] post
# @return [String]
# @example
# post 'http://example.com/api/search'
#
dsl_attr :post, attr_writer: false
# HTTP method: +:get+ or +:post+
#
# @!attribute [rw] method
# @return [Symbol]
# @example
# method :post
#
dsl_attr :method, attr_writer: false
# HTTP request headers
#
# @!attribute [rw] headers
# @return [String]
# @example
# headers content_type: "text/json"
#
dsl_attr :headers
# HTTP request body
#
# @!attribute [rw] body
# @return [String]
# @example
# body "<getData></getData>"
#
dsl_attr :body
# User name for basic auth connection credentials
#
# @!attribute [rw] username
# @return [String]
# @example
# username "arthur"
#
dsl_attr :username
# Password for basic auth connection credentials
#
# @!attribute [rw] password
# @return [String]
# @example
# password "424242"
#
dsl_attr :password
def uri
return nil if @uri.nil? || @uri.to_s.empty?
URI(@uri).tap { |u| u.query = URI.encode_www_form(@query) if @query }
end
def uri=(uri)
@uri = uri
end
# HTTP host and path to the data resource
#
# @!attribute [rw] uri
# @return [String]
# @example
# uri 'http://example.com/api/things'
#
dsl_attr :uri, attr_accessor: false, alias: :url
# Hash of query options
#
# @!attribute [rw] query
# @return [Hash]
# @example
# query start: 1, limit: 100
#
dsl_attr :query
def method=(http_method)
return @method = nil unless %w(get post).include? http_method.to_s.downcase
@method = http_method.to_s.downcase.to_sym
end
def get=(uri)
@method = :get
@uri = uri
end
def post=(uri)
@method = :post
@uri = uri
end
# @!endgroup
# Initialize an HTTP provider
#
def initialize(opts={}, &block)
super(opts, &block)
self.uri = opts[:uri]
self.method = opts[:method] || :get
self.query = opts[:query] || Hash.new
self.headers = opts[:headers] || Hash.new
self.body = opts[:body]
self.username = opts[:username]
self.password = opts[:password]
DSL.new(self).instance_eval(&block) if block_given?
end
def client
orig_logger, HTTPI.logger = HTTPI.logger, logger
req = HTTPI::Request.new.tap { |c| c.url = uri }
req.auth.basic(username, password) if username && password
req.headers = headers
req.body = body
block_given? ? yield(req) : req
ensure
HTTPI.logger = orig_logger
end
private
def validate
errors << "uri must be specified" unless uri
errors << "method (:get, :post) must be specified" unless method
errors << "body must be specified" if [:post, :put, :patch].include?(method) && body.to_s.empty?
errors.empty?
end
def fetch_data
client do |request|
response = HTTPI.request(method, request)
if response.error?
errors << "HTTP response error: #{response.code}"
else
@data = response.body
end
end
end
end
end