Skip to content

Commit c0f4d71

Browse files
committed
Handle redirects recursively
1 parent a9528b4 commit c0f4d71

2 files changed

Lines changed: 49 additions & 15 deletions

File tree

lib/drip/client.rb

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
require "json"
2020

2121
module Drip
22+
class TooManyRedirectsError < StandardError; end
23+
2224
class Client
2325
include Accounts
2426
include Broadcasts
@@ -36,14 +38,9 @@ class Client
3638
include Workflows
3739
include WorkflowTriggers
3840

39-
attr_accessor :access_token, :api_key, :account_id, :url_prefix
41+
REDIRECT_LIMIT = 10
4042

41-
VERB_MAPPING = {
42-
get: Net::HTTP::Get,
43-
post: Net::HTTP::Post,
44-
put: Net::HTTP::Put,
45-
delete: Net::HTTP::Delete
46-
}.freeze
43+
attr_accessor :access_token, :api_key, :account_id, :url_prefix
4744

4845
def initialize(options = {})
4946
@account_id = options[:account_id]
@@ -62,26 +59,31 @@ def content_type
6259
end
6360

6461
def get(url, options = {})
65-
make_request(Net::HTTP::Get, url, options)
62+
make_request(Net::HTTP::Get, make_uri(url), options)
6663
end
6764

6865
def post(url, options = {})
69-
make_request(Net::HTTP::Post, url, options)
66+
make_request(Net::HTTP::Post, make_uri(url), options)
7067
end
7168

7269
def put(url, options = {})
73-
make_request(Net::HTTP::Put, url, options)
70+
make_request(Net::HTTP::Put, make_uri(url), options)
7471
end
7572

7673
def delete(url, options = {})
77-
make_request(Net::HTTP::Delete, url, options)
74+
make_request(Net::HTTP::Delete, make_uri(url), options)
7875
end
7976

8077
private
8178

82-
def make_request(verb_klass, url, options)
79+
def make_uri(path)
80+
URI(url_prefix) + URI(path)
81+
end
82+
83+
def make_request(verb_klass, uri, options, step = 0)
84+
raise TooManyRedirectsError, 'too many HTTP redirects' if step >= REDIRECT_LIMIT
85+
8386
build_response do
84-
uri = URI(url_prefix) + URI(url)
8587
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
8688
if verb_klass.is_a? Net::HTTP::Get
8789
uri.query = URI.encode_www_form(options)
@@ -92,7 +94,7 @@ def make_request(verb_klass, url, options)
9294
unless verb_klass.is_a? Net::HTTP::Get
9395
request.body = options.to_json
9496
end
95-
97+
9698
request['User-Agent'] = "Drip Ruby v#{Drip::VERSION}"
9799
request['Content-Type'] = content_type
98100
request['Accept'] = "*/*"
@@ -103,7 +105,12 @@ def make_request(verb_klass, url, options)
103105
request.basic_auth api_key, ""
104106
end
105107

106-
http.request request
108+
response = http.request request
109+
if response.is_a?(Net::HTTPRedirection)
110+
return make_request(verb_klass, URI(response["Location"]), options, step + 1)
111+
else
112+
response
113+
end
107114
end
108115
end
109116
end

test/drip/client_test.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,31 @@ class Drip::ClientTest < Drip::TestCase
119119
assert_requested :get, "https://api.getdrip.com/v2/testpath", headers: { 'Authorization' => header }
120120
end
121121
end
122+
123+
context "given a redirecting url" do
124+
setup do
125+
@client = Drip::Client.new
126+
end
127+
128+
should "follow redirect" do
129+
stub_request(:get, "https://api.getdrip.com/v2/testpath").
130+
to_return(status: 301, body: "", headers: {"Location" => "https://api.example.com/mytestpath"})
131+
stub_request(:get, "https://api.example.com/mytestpath").
132+
to_return(status: 200, body: "mybody")
133+
response = @client.get("testpath")
134+
assert_requested :get, "https://api.getdrip.com/v2/testpath"
135+
assert_requested :get, "https://api.example.com/mytestpath"
136+
assert_equal "mybody", response.body
137+
end
138+
139+
should "not follow too many redirects" do
140+
stub_request(:get, "https://api.getdrip.com/v2/testpath").
141+
to_return(status: 301, body: "", headers: {"Location" => "https://api.example.com/mytestpath"})
142+
stub_request(:get, "https://api.example.com/mytestpath").
143+
to_return(status: 302, body: "", headers: {"Location" => "https://api.getdrip.com/v2/testpath"})
144+
assert_raises(Drip::TooManyRedirectsError) { @client.get("testpath") }
145+
assert_requested :get, "https://api.getdrip.com/v2/testpath", times: 5
146+
assert_requested :get, "https://api.example.com/mytestpath", times: 5
147+
end
148+
end
122149
end

0 commit comments

Comments
 (0)