pusher 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pusher (0.10.0)
4
+ pusher (0.11.0)
5
5
  multi_json (~> 1.0)
6
6
  signature (~> 0.1.4)
7
7
 
data/README.md CHANGED
@@ -3,80 +3,151 @@ Pusher gem
3
3
 
4
4
  [![Build Status](https://secure.travis-ci.org/pusher/pusher-gem.png?branch=master)](http://travis-ci.org/pusher/pusher-gem)
5
5
 
6
- Getting started
7
- ---------------
6
+ ## Configuration
8
7
 
9
- After registering at <http://pusher.com> configure your app with the security credentials
8
+ After registering at <http://pusher.com> configure your app with the security credentials.
9
+
10
+ ### Global
11
+
12
+ The most standard way of configuring Pusher is to do it globally on the Pusher class.
10
13
 
11
14
  Pusher.app_id = 'your-pusher-app-id'
12
15
  Pusher.key = 'your-pusher-key'
13
16
  Pusher.secret = 'your-pusher-secret'
14
17
 
15
- Trigger an event with {Pusher::Channel#trigger!}
18
+ Global configuration will automatically be set from the `PUSHER_URL` environment variable if it exists. This should be in the form `http://KEY:SECRET@api.pusherapp.com/apps/APP_ID`. On Heroku this environment variable will already be set.
19
+
20
+ If you need to make requests via a HTTP proxy then it can be configured
21
+
22
+ Pusher.http_proxy = 'http://(user):(password)@(host):(port)'
23
+
24
+ By default API requests are made over HTTP. HTTPS can be used by setting
25
+
26
+ Pusher.encrypted = true
27
+
28
+ ### Instantiating a Pusher client
29
+
30
+ Sometimes you may have multiple sets of API keys, or want different configuration in different parts of your application. In these scenarios, a pusher `client` may be configured:
31
+
32
+ pusher_client = Pusher.new({
33
+ app_id: 'your-pusher-app-id',
34
+ key: 'your-pusher-key',
35
+ secret: 'your-pusher-secret'
36
+ })
37
+
38
+ This `client` will have all the functionality listed on the main Pusher class (which proxies to a client internally).
16
39
 
17
- Pusher['a_channel'].trigger!('an_event', {:some => 'data'})
18
40
 
19
- Handle errors by rescuing `Pusher::Error` (all Pusher errors are descendants of this error)
41
+
42
+ ## Interacting with the Pusher service
43
+
44
+ The Pusher gem contains a number of helpers for interacting with the service. As a general rule, the library adheres to a set of conventions that we have aimed to make universal.
45
+
46
+ ### Handling errors
47
+
48
+ Handle errors by rescuing `Pusher::Error` (all errors are descendants of this error)
20
49
 
21
50
  begin
22
- Pusher['a_channel'].trigger!('an_event', {:some => 'data'})
51
+ Pusher.trigger('a_channel', 'an_event', {:some => 'data'})
23
52
  rescue Pusher::Error => e
24
53
  # (Pusher::AuthenticationError, Pusher::HTTPError, or Pusher::Error)
25
54
  end
26
55
 
27
- Optionally a socket id may be provided. This will exclude the event from being triggered on this socket id (see <http://pusher.com/docs/publisher_api_guide/publisher_excluding_recipients> for more info).
56
+ ### Logging
28
57
 
29
- Pusher['a_channel'].trigger!('an_event', {:some => 'data'}, socket_id)
58
+ Errors are logged to `Pusher.logger`. It will by default log at info level to STDOUT using `Logger` from the standard library, however you can assign any logger:
30
59
 
31
- If you don't need to handle failure cases, then you can simply use the {Pusher::Channel#trigger} method, which will rescue and log any errors for you
60
+ Pusher.logger = Rails.logger
61
+
62
+ ### Publishing events
63
+
64
+ An event can be sent to Pusher in in the following ways:
65
+
66
+ # on the Pusher class
67
+ Pusher.trigger('channel_name', 'event_name', {some: 'data'})
68
+ Pusher.trigger(['channel_1', 'channel_2'], 'event_name', {some: 'data'})
69
+
70
+ # or on a pusher_client
71
+ pusher_client.trigger(['your_channels'], 'your_event_name', {some: 'data'})
72
+
73
+ Note: the first `channels` argument can contain multiple channels you'd like your event and data payload to go to. There is a limit of 100 on the number of channels this can contain.
74
+
75
+ An optional fourth argument of this method can specify a `socket_id` that will be excluded from receiving the event (generally the user where the event originated -- see <http://pusher.com/docs/publisher_api_guide/publisher_excluding_recipients> for more info).
76
+
77
+ #### Original publisher API
78
+
79
+ Most examples and documentation will refer to the following syntax for triggering an event:
32
80
 
33
81
  Pusher['a_channel'].trigger('an_event', {:some => 'data'})
34
82
 
35
- Logging
36
- -------
83
+ This will continue to work, but will be replaced as the canonical version by `Pusher.trigger` which supports multiple channels.
37
84
 
38
- Errors are logged to `Pusher.logger`. It will by default use `Logger` from stdlib, however you can assign any logger:
85
+ ### Generic requests to the Pusher REST API
39
86
 
40
- Pusher.logger = Rails.logger
87
+ Aside from triggering events, the REST API also supports a number of operations for querying the state of the system. A reference of the available methods is available at <http://pusher.com/docs/rest_api>.
88
+
89
+ All requests must be signed by using your secret key, which is handled automatically using these methods:
90
+
91
+ # using the Pusher class
92
+ Pusher.get('url_without_app_id', params)
93
+
94
+ # using a client
95
+ pusher_client.post('url_without_app_id', params)
96
+
97
+ Note that you don't need to specify your app_id in the URL, as this is inferred from your credentials. As with the trigger method above, `_async` can be suffixed to the method name to return a deferrable.
41
98
 
42
- Asynchronous triggering
43
- -----------------------
99
+ ### Asynchronous requests
44
100
 
45
- To avoid blocking in a typical web application, you may wish to use the {Pusher::Channel#trigger_async} method which makes asynchronous API requests. `trigger_async` returns a deferrable which you can optionally bind to with success and failure callbacks.
101
+ If you are running your application in an evented environment, you may want to use the asynchronous versions of the Pusher API methods to avoid blocking. The convention for this is to add the suffix `_async` to the method, e.g. `trigger_async` or `post_async`.
46
102
 
47
103
  You need to be running eventmachine to make use of this functionality. This is already the case if, for example, you're deploying to Heroku or using the Thin web server. You will also need to add `em-http-request` to your Gemfile.
48
104
 
49
- $ gem install em-http-request
105
+ When using an asynchronous version of a method, it will return a deferrable.
50
106
 
51
- deferrable = Pusher['a_channel'].trigger_async('an_event', {
107
+ Pusher.trigger_async(['a_channel'], 'an_event', {
52
108
  :some => 'data'
53
- }, socket_id)
54
- deferrable.callback {
109
+ }, socket_id).callback {
55
110
  # Do something on success
56
- }
57
- deferrable.errback { |error|
111
+ }.errback { |error|
58
112
  # error is a instance of Pusher::Error
59
113
  }
60
114
 
61
- Private channels
62
- ----------------
63
115
 
64
- The Pusher Gem also deals with signing requests for authenticated private channels. A quick Rails controller example:
65
116
 
66
- reponse = Pusher['private-my_channel'].authenticate(params[:socket_id])
67
- render :json => response
68
-
69
- Read more about private channels in [the docs](http://pusher.com/docs/client_api_guide/client_channels#subscribe-private-channels) and under {Pusher::Channel#authenticate}.
117
+ ## Authenticating subscription requests
118
+
119
+ It's possible to use the gem to authenticate subscription requests to private or presence channels. The `authenticate` method is available on a channel object for this purpose and returns a JSON object that can be returned to the client that made the request. More information on this authentication scheme can be found in the docs on <http://pusher.com>
120
+
121
+ ### Private channels
122
+
123
+ Pusher['private-my_channel'].authenticate(params[:socket_id])
70
124
 
71
- WebHooks
72
- --------
125
+ ### Presence channels
73
126
 
74
- See {Pusher::WebHook}
127
+ These work in a very similar way, but require a unique identifier for the user being authenticated, and optionally some attributes that are provided to clients via presence events:
75
128
 
76
- Developing
77
- ----------
129
+ Pusher['presence-my_channel'].authenticate(params[:socket_id], {
130
+ user_id: 'user_id',
131
+ user_info: {} # optional
132
+ })
78
133
 
79
- Use bundler in order to run specs with the correct dependencies.
80
134
 
81
- bundle
82
- bundle exec rspec spec/*_spec.rb
135
+
136
+ ## Receiving WebHooks
137
+
138
+ A WebHook object may be created to validate received WebHooks against your app credentials, and to extract events. It should be created with the `Rack::Request` object (available as `request` in Rails controllers or Sinatra handlers for example).
139
+
140
+ webhook = Pusher.webhook(request)
141
+ if webhook.valid?
142
+ webhook.events.each do |event|
143
+ case event["name"]
144
+ when 'channel_occupied'
145
+ puts "Channel occupied: #{event["channel"]}"
146
+ when 'channel_vacated'
147
+ puts "Channel vacated: #{event["channel"]}"
148
+ end
149
+ end
150
+ render text: 'ok'
151
+ else
152
+ render text: 'invalid', status: 401
153
+ end
@@ -7,12 +7,11 @@ require 'pusher/client'
7
7
  # Used for configuring API credentials and creating Channel objects
8
8
  #
9
9
  module Pusher
10
- # All Pusher errors descend from this class so you can easily rescue Pusher
11
- # errors
10
+ # All errors descend from this class so they can be easily rescued
12
11
  #
13
12
  # @example
14
13
  # begin
15
- # Pusher['a_channel'].trigger!('an_event', {:some => 'data'})
14
+ # Pusher.trigger('channel_name', 'event_name, {:some => 'data'})
16
15
  # rescue Pusher::Error => e
17
16
  # # Do something on error
18
17
  # end
@@ -24,31 +23,18 @@ module Pusher
24
23
  class << self
25
24
  extend Forwardable
26
25
 
27
- def_delegators :default_client, :scheme, :host, :port, :app_id, :key, :secret
28
- def_delegators :default_client, :scheme=, :host=, :port=, :app_id=, :key=, :secret=
26
+ def_delegators :default_client, :scheme, :host, :port, :app_id, :key, :secret, :http_proxy
27
+ def_delegators :default_client, :scheme=, :host=, :port=, :app_id=, :key=, :secret=, :http_proxy=
29
28
 
30
29
  def_delegators :default_client, :authentication_token, :url
31
30
  def_delegators :default_client, :encrypted=, :url=
32
31
 
33
- def_delegators :default_client, :channels, :channel_info, :trigger
32
+ def_delegators :default_client, :get, :get_async, :post, :post_async
33
+ def_delegators :default_client, :channels, :channel_info, :trigger, :trigger_async
34
+ def_delegators :default_client, :webhook, :channel, :[]
34
35
 
35
36
  attr_writer :logger
36
37
 
37
- # Return a channel by name
38
- #
39
- # @example
40
- # Pusher['my-channel']
41
- # @return [Channel]
42
- # @raise [ConfigurationError] unless key, secret and app_id have been
43
- # configured
44
- def [](channel_name)
45
- begin
46
- default_client[channel_name]
47
- rescue ConfigurationError
48
- raise ConfigurationError, 'Missing configuration: please check that Pusher.key, Pusher.secret and Pusher.app_id are configured.'
49
- end
50
- end
51
-
52
38
  def logger
53
39
  @logger ||= begin
54
40
  log = Logger.new($stdout)
@@ -70,5 +56,7 @@ module Pusher
70
56
  end
71
57
 
72
58
  require 'pusher/channel'
59
+ require 'pusher/query_encoder'
73
60
  require 'pusher/request'
61
+ require 'pusher/resource'
74
62
  require 'pusher/webhook'
@@ -15,6 +15,9 @@ module Pusher
15
15
 
16
16
  # Trigger event asynchronously using EventMachine::HttpRequest
17
17
  #
18
+ # [Deprecated] This method will be removed in a future gem version. Please
19
+ # switch to Pusher.trigger_async or Pusher::Client#trigger_async instead
20
+ #
18
21
  # @param (see #trigger!)
19
22
  # @return [EM::DefaultDeferrable]
20
23
  # Attach a callback to be notified of success (with no parameters).
@@ -24,13 +27,17 @@ module Pusher
24
27
  # @raise [Pusher::Error] unless the eventmachine reactor is running. You
25
28
  # probably want to run your application inside a server such as thin
26
29
  #
27
- def trigger_async(event_name, data, socket_id = nil, &block)
28
- request = construct_event_request(event_name, data, socket_id)
29
- request.send_async
30
+ def trigger_async(event_name, data, socket_id = nil)
31
+ params = {}
32
+ params[:socket_id] = socket_id if socket_id
33
+ @client.trigger_async(name, event_name, data, params)
30
34
  end
31
35
 
32
36
  # Trigger event
33
37
  #
38
+ # [Deprecated] This method will be removed in a future gem version. Please
39
+ # switch to Pusher.trigger or Pusher::Client#trigger instead
40
+ #
34
41
  # @example
35
42
  # begin
36
43
  # Pusher['my-channel'].trigger!('an_event', {:some => 'data'})
@@ -47,12 +54,16 @@ module Pusher
47
54
  # @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
48
55
  #
49
56
  def trigger!(event_name, data, socket_id = nil)
50
- request = construct_event_request(event_name, data, socket_id)
51
- request.send_sync
57
+ params = {}
58
+ params[:socket_id] = socket_id if socket_id
59
+ @client.trigger(name, event_name, data, params)
52
60
  end
53
61
 
54
62
  # Trigger event, catching and logging any errors.
55
63
  #
64
+ # [Deprecated] This method will be removed in a future gem version. Please
65
+ # switch to Pusher.trigger or Pusher::Client#trigger instead
66
+ #
56
67
  # @note CAUTION! No exceptions will be raised on failure
57
68
  # @param (see #trigger!)
58
69
  #
@@ -71,7 +82,7 @@ module Pusher
71
82
  # @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
72
83
  #
73
84
  def info(attributes = [])
74
- @client.channel_info(name, :info => attributes.join(','))
85
+ @client.get("/channels/#{name}", :info => attributes.join(','))
75
86
  end
76
87
 
77
88
  # Compute authentication string required as part of the authentication
@@ -132,28 +143,5 @@ module Pusher
132
143
  r[:channel_data] = custom_data if custom_data
133
144
  r
134
145
  end
135
-
136
- private
137
-
138
- def construct_event_request(event_name, data, socket_id)
139
- params = {
140
- :name => event_name,
141
- }
142
- params[:socket_id] = socket_id if socket_id
143
-
144
- body = case data
145
- when String
146
- data
147
- else
148
- begin
149
- MultiJson.encode(data)
150
- rescue MultiJson::DecodeError => e
151
- Pusher.logger.error("Could not convert #{data.inspect} into JSON")
152
- raise e
153
- end
154
- end
155
-
156
- request = Pusher::Request.new(:post, @uri + 'events', params, body, nil, @client)
157
- end
158
146
  end
159
147
  end
@@ -2,9 +2,11 @@ require 'signature'
2
2
 
3
3
  module Pusher
4
4
  class Client
5
- attr_accessor :scheme, :host, :port, :app_id, :key, :secret
5
+ attr_accessor :scheme, :host, :port, :app_id, :key, :secret, :http_proxy
6
+ attr_reader :proxy
7
+
8
+ ## CONFIGURATION ##
6
9
 
7
- # Initializes the client object.
8
10
  def initialize(options = {})
9
11
  options = {
10
12
  :scheme => 'http',
@@ -14,6 +16,7 @@ module Pusher
14
16
  @scheme, @host, @port, @app_id, @key, @secret = options.values_at(
15
17
  :scheme, :host, :port, :app_id, :key, :secret
16
18
  )
19
+ self.http_proxy = options[:http_proxy] if options[:http_proxy]
17
20
  end
18
21
 
19
22
  # @private Returns the authentication token for the client
@@ -47,6 +50,19 @@ module Pusher
47
50
  @port = uri.port
48
51
  end
49
52
 
53
+ def http_proxy=(http_proxy)
54
+ @http_proxy = http_proxy
55
+ uri = URI.parse(http_proxy)
56
+ @proxy = {
57
+ :scheme => uri.scheme,
58
+ :host => uri.host,
59
+ :port => uri.port,
60
+ :user => uri.user,
61
+ :password => uri.password
62
+ }
63
+ @http_proxy
64
+ end
65
+
50
66
  # Configure whether Pusher API calls should be made over SSL
51
67
  # (default false)
52
68
  #
@@ -59,6 +75,83 @@ module Pusher
59
75
  @port = boolean ? 443 : 80
60
76
  end
61
77
 
78
+ def encrypted?
79
+ @scheme == 'https'
80
+ end
81
+
82
+ ## INTERACE WITH THE API ##
83
+
84
+ def resource(path)
85
+ Resource.new(self, path)
86
+ end
87
+
88
+ # GET arbitrary REST API resource using a synchronous http client.
89
+ # All request signing is handled automatically.
90
+ #
91
+ # @example
92
+ # begin
93
+ # Pusher.get('/channels', filter_by_prefix: 'private-')
94
+ # rescue Pusher::Error => e
95
+ # # Handle error
96
+ # end
97
+ #
98
+ # @param path [String] Path excluding /apps/APP_ID
99
+ # @param params [Hash] API params (see http://pusher.com/docs/rest_api)
100
+ #
101
+ # @return [Hash] See Pusher API docs
102
+ #
103
+ # @raise [Pusher::Error] Unsuccessful response - see the error message
104
+ # @raise [Pusher::HTTPError] Error raised inside Net::HTTP. The original error is wrapped in error.original_error
105
+ #
106
+ def get(path, params = {})
107
+ Resource.new(self, path).get(params)
108
+ end
109
+
110
+ # GET arbitrary REST API resource using an asynchronous http client.
111
+ # All request signing is handled automatically.
112
+ #
113
+ # @example
114
+ # Pusher.get_async('/channels', {
115
+ # filter_by_prefix: 'private-'
116
+ # }).callback { |response_hash|
117
+ # # ...
118
+ # }.errback { |error|
119
+ # # error is a instance of Pusher::Error
120
+ # }
121
+ #
122
+ # @param path [String] Path excluding /apps/APP_ID
123
+ # @param params [Hash] API params (see http://pusher.com/docs/rest_api)
124
+ #
125
+ # @return [EM::DefaultDeferrable]
126
+ #
127
+ def get_async(path, params = {})
128
+ Resource.new(self, path).get_async(params)
129
+ end
130
+
131
+ # POST arbitrary REST API resource using a synchronous http client.
132
+ # Works identially to get method, but posts params as JSON in post body.
133
+ def post(path, params = {})
134
+ Resource.new(self, path).post(params)
135
+ end
136
+
137
+ # POST arbitrary REST API resource using an asynchronous http client.
138
+ # Works identially to get_async method, but posts params as JSON in post
139
+ # body.
140
+ def post_async(path, params = {})
141
+ Resource.new(self, path).post_async(params)
142
+ end
143
+
144
+ ## HELPER METHODS ##
145
+
146
+ # Convenience method for creating a new WebHook instance for validating
147
+ # and extracting info from a received WebHook
148
+ #
149
+ # @param request [Rack::Request] Either a Rack::Request or a Hash containing :key, :signature, :body, and optionally :content_type.
150
+ #
151
+ def webhook(request)
152
+ WebHook.new(request, self)
153
+ end
154
+
62
155
  # Return a convenience channel object by name. No API request is made.
63
156
  #
64
157
  # @example
@@ -66,25 +159,26 @@ module Pusher
66
159
  # @return [Channel]
67
160
  # @raise [ConfigurationError] unless key, secret and app_id have been
68
161
  # configured
69
- def [](channel_name)
162
+ def channel(channel_name)
70
163
  raise ConfigurationError, 'Missing client configuration: please check that key, secret and app_id are configured.' unless configured?
71
- @channels ||= {}
72
- @channels[channel_name.to_s] ||= Channel.new(url, channel_name, self)
164
+ Channel.new(url, channel_name, self)
73
165
  end
74
166
 
167
+ alias :[] :channel
168
+
75
169
  # Request a list of occupied channels from the API
76
170
  #
77
171
  # GET /apps/[id]/channels
78
172
  #
79
- # @param options [Hash] Hash of options for the API - see Pusher API docs
173
+ # @param params [Hash] Hash of parameters for the API - see REST API docs
174
+ #
80
175
  # @return [Hash] See Pusher API docs
81
- # @raise [Pusher::Error] on invalid Pusher response - see the error message for more details
82
- # @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
83
176
  #
84
- def channels(options = {})
85
- @_channels_url ||= url('/channels')
86
- request = Request.new(:get, @_channels_url, options, nil, nil, self)
87
- return request.send_sync
177
+ # @raise [Pusher::Error] Unsuccessful response - see the error message
178
+ # @raise [Pusher::HTTPError] Error raised inside Net::HTTP. The original error is wrapped in error.original_error
179
+ #
180
+ def channels(params = {})
181
+ get('/channels', params)
88
182
  end
89
183
 
90
184
  # Request info for a specific channel
@@ -92,31 +186,98 @@ module Pusher
92
186
  # GET /apps/[id]/channels/[channel_name]
93
187
  #
94
188
  # @param channel_name [String] Channel name
95
- # @param options [Hash] Hash of options for the API - see Pusher API docs
189
+ # @param params [Hash] Hash of parameters for the API - see REST API docs
190
+ #
96
191
  # @return [Hash] See Pusher API docs
97
- # @raise [Pusher::Error] on invalid Pusher response - see the error message for more details
98
- # @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
99
192
  #
100
- def channel_info(channel_name, options = {})
101
- request = Request.new(:get, url("/channels/#{channel_name}"), options, nil, nil, self)
102
- return request.send_sync
193
+ # @raise [Pusher::Error] Unsuccessful response - see the error message
194
+ # @raise [Pusher::HTTPError] Error raised inside Net::HTTP. The original error is wrapped in error.original_error
195
+ #
196
+ def channel_info(channel_name, params = {})
197
+ get("/channels/#{channel_name}", params)
103
198
  end
104
199
 
105
200
  # Trigger an event on one or more channels
106
201
  #
107
202
  # POST /apps/[app_id]/events
108
203
  #
109
- # @param channels [Array] One of more channel names
204
+ # @param channels [String or Array] One of more channel names
110
205
  # @param event_name [String]
111
206
  # @param data [Object] Event data to be triggered in javascript.
112
207
  # Objects other than strings will be converted to JSON
113
- # @param options [Hash] Additional options to send to api, e.g socket_id
208
+ # @param params [Hash] Additional parameters to send to api, e.g socket_id
209
+ #
114
210
  # @return [Hash] See Pusher API docs
115
- # @raise [Pusher::Error] on invalid Pusher response - see the error message for more details
116
- # @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
117
211
  #
118
- def trigger(channels, event_name, data, options = {})
119
- @_trigger_url ||= url('/events')
212
+ # @raise [Pusher::Error] Unsuccessful response - see the error message
213
+ # @raise [Pusher::HTTPError] Error raised inside Net::HTTP. The original error is wrapped in error.original_error
214
+ #
215
+ def trigger(channels, event_name, data, params = {})
216
+ post('/events', trigger_params(channels, event_name, data, params))
217
+ end
218
+
219
+ # Trigger an event on one or more channels asynchronously.
220
+ # For parameters see #trigger
221
+ #
222
+ def trigger_async(channels, event_name, data, params = {})
223
+ post_async('/events', trigger_params(channels, event_name, data, params))
224
+ end
225
+
226
+ # @private Construct a net/http http client
227
+ def net_http_client
228
+ @_http_sync ||= begin
229
+ if encrypted?
230
+ require 'net/https' unless defined?(Net::HTTPS)
231
+ else
232
+ require 'net/http' unless defined?(Net::HTTP)
233
+ end
234
+
235
+ http_klass = if (p = @proxy)
236
+ Net::HTTP.Proxy(p[:host], p[:port], p[:user], p[:password])
237
+ else
238
+ Net::HTTP
239
+ end
240
+
241
+ http = http_klass.new(@host, @port)
242
+
243
+ if encrypted?
244
+ http.use_ssl = true
245
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
246
+ end
247
+
248
+ http
249
+ end
250
+ end
251
+
252
+ # @private Construct an em-http-request http client
253
+ def em_http_client(uri)
254
+ begin
255
+ unless defined?(EventMachine) && EventMachine.reactor_running?
256
+ raise Error, "In order to use async calling you must be running inside an eventmachine loop"
257
+ end
258
+ require 'em-http' unless defined?(EventMachine::HttpRequest)
259
+
260
+ connection_opts = {}
261
+
262
+ if @proxy
263
+ proxy_opts = {
264
+ :host => @proxy[:host],
265
+ :port => @proxy[:port]
266
+ }
267
+ if @proxy[:user]
268
+ proxy_opts[:authorization] = [@proxy[:user], @proxy[:password]]
269
+ end
270
+ connection_opts[:proxy] = proxy_opts
271
+ end
272
+
273
+ EventMachine::HttpRequest.new(uri, connection_opts)
274
+ end
275
+ end
276
+
277
+ private
278
+
279
+ def trigger_params(channels, event_name, data, params)
280
+ channels = [channels] if channels.kind_of?(String)
120
281
 
121
282
  encoded_data = case data
122
283
  when String
@@ -130,18 +291,13 @@ module Pusher
130
291
  end
131
292
  end
132
293
 
133
- options.merge!({
294
+ return params.merge({
134
295
  :name => event_name,
135
296
  :channels => channels,
136
297
  :data => encoded_data,
137
298
  })
138
-
139
- request = Request.new(:post, @_trigger_url, {}, MultiJson.encode(options), nil, self)
140
- return request.send_sync
141
299
  end
142
300
 
143
- private
144
-
145
301
  def configured?
146
302
  host && scheme && key && secret && app_id
147
303
  end