Skip to content

Commit e7a549d

Browse files
author
Jon Elverkilde
authored
Merge pull request #170 from pusher/refactor_client
Handle nil cluster, minor refactor
2 parents a0b6424 + afb6dc0 commit e7a549d

File tree

3 files changed

+60
-59
lines changed

3 files changed

+60
-59
lines changed

lib/pusher/client.rb

+37-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
require 'base64'
2-
32
require 'pusher-signature'
43

54
module Pusher
@@ -10,6 +9,11 @@ class Client
109
:keep_alive_timeout
1110

1211
## CONFIGURATION ##
12+
DEFAULT_CONNECT_TIMEOUT = 5
13+
DEFAULT_SEND_TIMEOUT = 5
14+
DEFAULT_RECEIVE_TIMEOUT = 5
15+
DEFAULT_KEEP_ALIVE_TIMEOUT = 30
16+
DEFAULT_CLUSTER = "mt1"
1317

1418
# Loads the configuration from an url in the environment
1519
def self.from_env(key = 'PUSHER_URL')
@@ -25,43 +29,31 @@ def self.from_url(url)
2529
end
2630

2731
def initialize(options = {})
28-
default_options = {
29-
:scheme => 'http',
30-
:port => 80,
31-
}
32+
@scheme = "http"
33+
@port = options[:port] || 80
3234

3335
if options[:use_tls] || options[:encrypted]
34-
default_options[:scheme] = "https"
35-
default_options[:port] = 443
36+
@scheme = "https"
37+
@port = options[:port] || 443
3638
end
3739

38-
merged_options = default_options.merge(options)
39-
40-
if options.has_key?(:host)
41-
merged_options[:host] = options[:host]
42-
elsif options.has_key?(:cluster)
43-
merged_options[:host] = "api-#{options[:cluster]}.pusher.com"
44-
else
45-
merged_options[:host] = "api.pusherapp.com"
46-
end
40+
@app_id = options[:app_id]
41+
@key = options[:key]
42+
@secret = options[:secret]
4743

48-
@scheme, @host, @port, @app_id, @key, @secret =
49-
merged_options.values_at(
50-
:scheme, :host, :port, :app_id, :key, :secret
51-
)
44+
@host = options[:host]
45+
@host ||= "api-#{options[:cluster]}.pusher.com" unless options[:cluster].nil? || options[:cluster].empty?
46+
@host ||= "api-#{DEFAULT_CLUSTER}.pusher.com"
5247

53-
if options.has_key?(:encryption_master_key_base64)
54-
@encryption_master_key =
55-
Base64.strict_decode64(options[:encryption_master_key_base64])
56-
end
48+
@encryption_master_key = Base64.strict_decode64(options[:encryption_master_key_base64]) if options[:encryption_master_key_base64]
5749

5850
@http_proxy = options[:http_proxy]
5951

6052
# Default timeouts
61-
@connect_timeout = 5
62-
@send_timeout = 5
63-
@receive_timeout = 5
64-
@keep_alive_timeout = 30
53+
@connect_timeout = DEFAULT_CONNECT_TIMEOUT
54+
@send_timeout = DEFAULT_SEND_TIMEOUT
55+
@receive_timeout = DEFAULT_RECEIVE_TIMEOUT
56+
@keep_alive_timeout = DEFAULT_KEEP_ALIVE_TIMEOUT
6557
end
6658

6759
# @private Returns the authentication token for the client
@@ -75,10 +67,10 @@ def authentication_token
7567
def url(path = nil)
7668
raise ConfigurationError, :app_id unless @app_id
7769
URI::Generic.build({
78-
:scheme => @scheme,
79-
:host => @host,
80-
:port => @port,
81-
:path => "/apps/#{@app_id}#{path}"
70+
scheme: @scheme,
71+
host: @host,
72+
port: @port,
73+
path: "/apps/#{@app_id}#{path}"
8274
})
8375
end
8476

@@ -102,13 +94,12 @@ def http_proxy=(http_proxy)
10294
@http_proxy = http_proxy
10395
uri = URI.parse(http_proxy)
10496
@proxy = {
105-
:scheme => uri.scheme,
106-
:host => uri.host,
107-
:port => uri.port,
108-
:user => uri.user,
109-
:password => uri.password
97+
scheme: uri.scheme,
98+
host: uri.host,
99+
port: uri.port,
100+
user: uri.user,
101+
password: uri.password
110102
}
111-
@http_proxy
112103
end
113104

114105
# Configure whether Pusher API calls should be made over SSL
@@ -128,6 +119,8 @@ def encrypted?
128119
end
129120

130121
def cluster=(cluster)
122+
cluster = DEFAULT_CLUSTER if cluster.nil? || cluster.empty?
123+
131124
@host = "api-#{cluster}.pusher.com"
132125
end
133126

@@ -360,9 +353,9 @@ def authenticate(channel_name, socket_id, custom_data = nil)
360353

361354
# @private Construct a net/http http client
362355
def sync_http_client
363-
@client ||= begin
364-
require 'httpclient'
356+
require 'httpclient'
365357

358+
@client ||= begin
366359
HTTPClient.new(@http_proxy).tap do |c|
367360
c.connect_timeout = @connect_timeout
368361
c.send_timeout = @send_timeout
@@ -381,14 +374,14 @@ def em_http_client(uri)
381374
require 'em-http' unless defined?(EventMachine::HttpRequest)
382375

383376
connection_opts = {
384-
:connect_timeout => @connect_timeout,
385-
:inactivity_timeout => @receive_timeout,
377+
connect_timeout: @connect_timeout,
378+
inactivity_timeout: @receive_timeout,
386379
}
387380

388381
if defined?(@proxy)
389382
proxy_opts = {
390-
:host => @proxy[:host],
391-
:port => @proxy[:port]
383+
host: @proxy[:host],
384+
port: @proxy[:port]
392385
}
393386
if @proxy[:user]
394387
proxy_opts[:authorization] = [@proxy[:user], @proxy[:password]]

spec/channel_spec.rb

+3-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def stub_post_to_raise(e)
2929
describe '#trigger!' do
3030
it "should use @client.trigger internally" do
3131
expect(@client).to receive(:trigger)
32-
@channel.trigger('new_event', 'Some data')
32+
@channel.trigger!('new_event', 'Some data')
3333
end
3434
end
3535

@@ -39,16 +39,14 @@ def stub_post_to_raise(e)
3939

4040
expect(Pusher.logger).to receive(:error).with("Exception from WebMock (HTTPClient::BadResponseError) (Pusher::HTTPError)")
4141
expect(Pusher.logger).to receive(:debug) #backtrace
42-
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
43-
channel.trigger('new_event', 'Some data')
42+
@channel.trigger('new_event', 'Some data')
4443
end
4544

4645
it "should log failure if Pusher returns an error response" do
4746
stub_post 401, "some signature info"
4847
expect(Pusher.logger).to receive(:error).with("some signature info (Pusher::AuthenticationError)")
4948
expect(Pusher.logger).to receive(:debug) #backtrace
50-
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
51-
channel.trigger('new_event', 'Some data')
49+
@channel.trigger('new_event', 'Some data')
5250
end
5351
end
5452

spec/client_spec.rb

+20-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
describe 'default configuration' do
1919
it 'should be preconfigured for api host' do
20-
expect(@client.host).to eq('api.pusherapp.com')
20+
expect(@client.host).to eq('api-mt1.pusher.com')
2121
end
2222

2323
it 'should be preconfigured for port 80' do
@@ -79,6 +79,16 @@
7979
expect(@client.host).to eq('api-eu.pusher.com')
8080
end
8181

82+
it 'should handle nil gracefully' do
83+
@client.cluster = nil
84+
expect(@client.host).to eq('api-mt1.pusher.com')
85+
end
86+
87+
it 'should handle empty string' do
88+
@client.cluster = ""
89+
expect(@client.host).to eq('api-mt1.pusher.com')
90+
end
91+
8292
it 'should be overridden by host if it comes after' do
8393
@client.cluster = 'eu'
8494
@client.host = 'api.staging.pusher.com'
@@ -518,7 +528,7 @@
518528
[:get, :post].each do |verb|
519529
describe "##{verb}" do
520530
before :each do
521-
@url_regexp = %r{api.pusherapp.com}
531+
@url_regexp = %r{api-mt1.pusher.com}
522532
stub_request(verb, @url_regexp).
523533
to_return(:status => 200, :body => "{}")
524534
end
@@ -527,13 +537,13 @@
527537

528538
it "should use http by default" do
529539
call_api
530-
expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
540+
expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com/apps/20/path})
531541
end
532542

533543
it "should use https if configured" do
534544
@client.encrypted = true
535545
call_api
536-
expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
546+
expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com})
537547
end
538548

539549
it "should format the respose hash with symbols at first level" do
@@ -598,7 +608,7 @@
598608
[[:get, :get_async], [:post, :post_async]].each do |verb, method|
599609
describe "##{method}" do
600610
before :each do
601-
@url_regexp = %r{api.pusherapp.com}
611+
@url_regexp = %r{api-mt1.pusher.com}
602612
stub_request(verb, @url_regexp).
603613
to_return(:status => 200, :body => "{}")
604614
end
@@ -614,13 +624,13 @@
614624

615625
it "should use http by default" do
616626
call_api
617-
expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
627+
expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com/apps/20/path})
618628
end
619629

620630
it "should use https if configured" do
621631
@client.encrypted = true
622632
call_api
623-
expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
633+
expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com})
624634
end
625635

626636
# Note that the raw httpclient connection object is returned and
@@ -640,7 +650,7 @@
640650
[[:get, :get_async], [:post, :post_async]].each do |verb, method|
641651
describe "##{method}" do
642652
before :each do
643-
@url_regexp = %r{api.pusherapp.com}
653+
@url_regexp = %r{api-mt1.pusher.com}
644654
stub_request(verb, @url_regexp).
645655
to_return(:status => 200, :body => "{}")
646656
end
@@ -650,7 +660,7 @@
650660
it "should use http by default" do
651661
EM.run {
652662
call_api.callback {
653-
expect(WebMock).to have_requested(verb, %r{http://api.pusherapp.com/apps/20/path})
663+
expect(WebMock).to have_requested(verb, %r{http://api-mt1.pusher.com/apps/20/path})
654664
EM.stop
655665
}
656666
}
@@ -660,7 +670,7 @@
660670
EM.run {
661671
@client.encrypted = true
662672
call_api.callback {
663-
expect(WebMock).to have_requested(verb, %r{https://api.pusherapp.com})
673+
expect(WebMock).to have_requested(verb, %r{https://api-mt1.pusher.com})
664674
EM.stop
665675
}
666676
}

0 commit comments

Comments
 (0)