Skip to content

Commit

Permalink
Merge pull request pusher-community#2 from glenngillen/pusher-ssl-sup…
Browse files Browse the repository at this point in the history
…port

Pusher SSL support
  • Loading branch information
leggetter committed Jul 26, 2012
2 parents 3d38c8b + a1049a5 commit 29f795f
Show file tree
Hide file tree
Showing 11 changed files with 3,930 additions and 55 deletions.
12 changes: 2 additions & 10 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
source "http://rubygems.org"

gem "libwebsocket", "~>0.1.0"

group :development do
gem "bacon", ">= 0"
gem "bundler", "~> 1.0.0"
gem "jeweler", "~> 1.5.2"
gem "rcov", ">= 0"
end
source :rubygems
gemspec
23 changes: 11 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
PATH
remote: .
specs:
pusher-client (0.2.1)
addressable (~> 2.3.1)
libwebsocket (= 0.1.0)
ruby-hmac (~> 0.4.0)

GEM
remote: http://rubygems.org/
specs:
addressable (2.3.1)
bacon (1.1.0)
git (1.2.5)
jeweler (1.5.2)
bundler (~> 1.0.0)
git (>= 1.2.5)
rake
libwebsocket (0.1.0)
rake (0.8.7)
rcov (0.9.9)
rcov (0.9.9-java)
ruby-hmac (0.4.0)

PLATFORMS
java
ruby

DEPENDENCIES
bacon
bundler (~> 1.0.0)
jeweler (~> 1.5.2)
libwebsocket (~> 0.1.0)
rcov
pusher-client!
8 changes: 4 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ require 'jeweler'
Jeweler::Tasks.new do |gem|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
gem.name = "pusher-client"
gem.homepage = "http://github.com/logankoester/pusher-client"
gem.homepage = "http://github.com/pusher/pusher-ruby-client"
gem.license = "MIT"
gem.summary = %Q{Ruby client for consuming WebSockets from http://pusherapp.com}
gem.description = %Q{Ruby client for consuming WebSockets from http://pusherapp.com}
gem.summary = %Q{Ruby client for consuming WebSockets from http://pusher.com}
gem.description = %Q{Ruby client for consuming WebSockets from http://pusher.com}
gem.email = "logan@logankoester.com"
gem.authors = ["Logan Koester"]
gem.authors = ["Logan Koester", "Phil Leggetter"]
end
Jeweler::RubygemsDotOrgTasks.new

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.1
0.2.2-alpha
3,825 changes: 3,825 additions & 0 deletions certs/cacert.pem

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/hello_pusher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

APP_KEY = ENV['PUSHER_KEY'] # || "YOUR_APPLICATION_KEY"

PusherClient.logger = Logger.new('/dev/null')
PusherClient.logger = Logger.new(STDOUT)
socket = PusherClient::Socket.new(APP_KEY)

# Subscribe to a channel
Expand Down
20 changes: 20 additions & 0 deletions examples/hello_pusher_ssl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Usage: $ PUSHER_KEY=YOURKEY ruby examples/hello_pusher.rb

require 'rubygems'
require './lib/pusher-client.rb'
require 'pp'

APP_KEY = ENV['PUSHER_KEY'] # || "YOUR_APPLICATION_KEY"

PusherClient.logger = Logger.new(STDOUT)
socket = PusherClient::Socket.new(APP_KEY, { :encrypted => true } )

# Subscribe to a channel
socket.subscribe('hellopusher')

# Bind to a channel event
socket['hellopusher'].bind('hello') do |data|
pp data
end

socket.connect
21 changes: 21 additions & 0 deletions examples/subscribe_private.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Usage: $ PUSHER_KEY=YOURKEY ruby examples/hello_pusher.rb

require 'rubygems'
require './lib/pusher-client.rb'
require 'pp'

APP_KEY = ENV['PUSHER_KEY'] # || "YOUR_APPLICATION_KEY"
APP_SECRET = ENV['PUSHER_SECRET'] # || "YOUR_APPLICATION_SECRET"

PusherClient.logger = Logger.new(STDOUT)
socket = PusherClient::Socket.new(APP_KEY, { :encrypted => true, :secret => APP_SECRET } )

# Subscribe to a channel
socket.subscribe('private-hellopusher')

# Bind to a channel event
socket['hellopusher'].bind('hello') do |data|
pp data
end

socket.connect
31 changes: 16 additions & 15 deletions lib/pusher-client/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

module PusherClient
class Socket

# Mimick the JavaScript client
CLIENT_ID = 'js'
CLIENT_ID = 'pusher-ruby-client'
VERSION = '1.7.1'

attr_accessor :encrypted, :secure
Expand Down Expand Up @@ -51,7 +51,8 @@ def connect(async = false)
PusherClient.logger.debug("Pusher : connecting : #{url}")

@connection_thread = Thread.new {
@connection = WebSocket.new(url)
options = {:ssl => @encrypted || @secure}
@connection = WebSocket.new(url, options)
PusherClient.logger.debug "Websocket connected"
loop do
msg = @connection.receive[0]
Expand Down Expand Up @@ -82,7 +83,7 @@ def disconnect

def subscribe(channel_name, user_id = nil)
@user_data = {:user_id => user_id}.to_json unless user_id.nil?

channel = @channels << channel_name
if @connected
authorize(channel, method(:authorize_callback))
Expand Down Expand Up @@ -114,11 +115,11 @@ def [](channel_name)
end

def subscribe_all
@channels.channels.clone.each{ |k,v|
@channels.channels.clone.each{ |k,v|
subscribe(k)
}
end

#auth for private and presence
def authorize(channel, callback)
if is_private_channel(channel.name)
Expand All @@ -130,7 +131,7 @@ def authorize(channel, callback)
# could both be nil if didn't require auth
callback.call(channel, auth_data, channel_data)
end

def authorize_callback(channel, auth_data, channel_data)
send_event('pusher:subscribe', {
'channel' => channel.name,
Expand All @@ -139,30 +140,30 @@ def authorize_callback(channel, auth_data, channel_data)
})
channel.acknowledge_subscription(nil)
end

def is_private_channel(channel_name)
channel_name.match(/^private-/)
end

def is_presence_channel(channel_name)
channel_name.match(/^presence-/)
end

def get_private_auth(channel)
string_to_sign = @socket_id + ':' + channel.name
signature = HMAC::SHA256.hexdigest(@secret, string_to_sign)
return "#{@key}:#{signature}"
end

def get_presence_auth(channel)
string_to_sign = @socket_id + ':' + channel.name + ':' + @user_data
signature = HMAC::SHA256.hexdigest(@secret, string_to_sign)
return "#{@key}:#{signature}"
return "#{@key}:#{signature}"
end


# For compatibility with JavaScript client API
alias :subscribeAll :subscribe_all
alias :subscribeAll :subscribe_all

def send_event(event_name, data)
payload = {'event' => event_name, 'data' => data}.to_json
Expand Down
20 changes: 20 additions & 0 deletions lib/pusher-client/websocket.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'rubygems'
require 'socket'
require 'libwebsocket'
require 'openssl'

module PusherClient
class WebSocket
Expand All @@ -11,6 +12,21 @@ def initialize(url, params = {})

@socket = TCPSocket.new(@hs.url.host, @hs.url.port || 80)

if params[:ssl] == true

ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
# http://curl.haxx.se/ca/cacert.pem
ctx.ca_file = path_to_cert()

ssl_sock = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
ssl_sock.sync_close = true
ssl_sock.connect

@socket = ssl_sock

end

@socket.write(@hs.to_s)
@socket.flush

Expand All @@ -29,6 +45,10 @@ def initialize(url, params = {})
end
end

def path_to_cert
File.join(File.dirname(File.expand_path(__FILE__)), '../../certs/cacert.pem')
end

def send(data)
raise "no handshake!" unless @handshaked

Expand Down
21 changes: 9 additions & 12 deletions pusher-client.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,21 @@ Gem::Specification.new do |s|
s.specification_version = 3

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<libwebsocket>, ["~> 0.1.0"])
s.add_runtime_dependency(%q<libwebsocket>, ["0.1.0"])
s.add_runtime_dependency(%q<ruby-hmac>, ["~> 0.4.0"])
s.add_runtime_dependency(%q<addressable>, ["~> 2.3.1"])
s.add_development_dependency(%q<bacon>, [">= 0"])
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
s.add_development_dependency(%q<rcov>, [">= 0"])
else
s.add_dependency(%q<libwebsocket>, ["~> 0.1.0"])
s.add_dependency(%q<libwebsocket>, ["0.1.0"])
s.add_dependency(%q<ruby-hmac>, ["~> 0.4.0"])
s.add_dependency(%q<addressable>, ["~> 2.3.1"])
s.add_dependency(%q<bacon>, [">= 0"])
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
s.add_dependency(%q<rcov>, [">= 0"])
end
else
s.add_dependency(%q<libwebsocket>, ["~> 0.1.0"])
s.add_dependency(%q<libwebsocket>, ["0.1.0"])
s.add_dependency(%q<addressable>, ["~> 2.3.1"])
s.add_dependency(%q<ruby-hmac>, ["~> 0.4.0"])
s.add_dependency(%q<bacon>, [">= 0"])
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
s.add_dependency(%q<rcov>, [">= 0"])
end
end

0 comments on commit 29f795f

Please sign in to comment.