class IRails::Session
Constants
- DELIM
Public Class Methods
new(config)
click to toggle source
# File lib/irails/session.rb, line 5 def initialize(config) c = ZMQ::Context.new connection = "#{config['transport']}://#{config['ip']}:%d" reply_socket = c.socket(:ROUTER) reply_socket.bind(connection % config['shell_port']) pub_socket = c.socket(:PUB) pub_socket.bind(connection % config['iopub_port']) Thread.new do begin hb_socket = c.socket(:REP) hb_socket.bind(connection % config['hb_port']) ZMQ.proxy(hb_socket, hb_socket) rescue Exception => e IRails.logger.fatal "Kernel heartbeat died: #{e.message}\n#{e.backtrace.join("\n")}" end end @sockets = { publish: pub_socket, reply: reply_socket } @session = SecureRandom.uuid unless config['key'].to_s.empty? || config['signature_scheme'].to_s.empty? raise 'Unknown signature scheme' unless config['signature_scheme'] =~ /\Ahmac-(.*)\Z/ @hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new($1)) end require './config/boot' require './config/application' Rails.application.require_environment! end
Public Instance Methods
recv(socket)
click to toggle source
Receive a message and decode it
# File lib/irails/session.rb, line 57 def recv(socket) @last_recvd_msg = unserialize(@sockets[socket].recv_message) end
send(socket, type, content)
click to toggle source
Build and send a message
# File lib/irails/session.rb, line 39 def send(socket, type, content) idents = if socket == :reply && @last_recvd_msg @last_recvd_msg[:idents] else type == :stream ? "stream.#{content[:name]}" : type end header = { msg_type: type, msg_id: SecureRandom.uuid, username: 'kernel', session: @session, version: '5.0' } @sockets[socket].send_message(serialize(idents, header, content)) end
Private Instance Methods
serialize(idents, header, content)
click to toggle source
# File lib/irails/session.rb, line 63 def serialize(idents, header, content) msg = [MultiJson.dump(header), MultiJson.dump(@last_recvd_msg ? @last_recvd_msg[:header] : {}), '{}', MultiJson.dump(content || {})] frames = ([*idents].compact.map(&:to_s) << DELIM << sign(msg)) + msg IRails.logger.debug "Sent #{frames.inspect}" ZMQ::Message(*frames) end
sign(list)
click to toggle source
Sign using HMAC
# File lib/irails/session.rb, line 96 def sign(list) return '' unless @hmac @hmac.reset list.each {|m| @hmac.update(m) } @hmac.hexdigest end
unserialize(msg)
click to toggle source
# File lib/irails/session.rb, line 73 def unserialize(msg) raise 'no message received' unless msg frames = msg.to_a.map(&:to_s) IRails.logger.debug "Received #{frames.inspect}" i = frames.index(DELIM) idents, msg_list = frames[0..i-1], frames[i+1..-1] minlen = 5 raise 'malformed message, must have at least #{minlen} elements' unless msg_list.length >= minlen s, header, parent_header, metadata, content, buffers = *msg_list raise 'Invalid signature' unless s == sign(msg_list[1..-1]) { idents: idents, header: MultiJson.load(header), parent_header: MultiJson.load(parent_header), metadata: MultiJson.load(metadata), content: MultiJson.load(content), buffers: buffers } end