| #!/usr/bin/env ruby |
| |
| # Web socket client: |
| # - securely connects and authenticates with the web socket |
| # - outputs the messages received |
| |
| $LOAD_PATH.unshift '/srv/whimsy/lib' |
| |
| require 'websocket-eventmachine-client' |
| require 'optparse' |
| require 'ostruct' |
| require 'etc' |
| require 'net/http' |
| require 'json' |
| |
| require_relative './session' |
| |
| ######################################################################## |
| # Parse argument list # |
| ######################################################################## |
| |
| options = OpenStruct.new |
| options.host = 'whimsy.local' |
| options.path = '/board/agenda/websocket/' |
| options.user = Etc.getlogin |
| options.restart = false |
| options.verify = true |
| |
| opt_parser = OptionParser.new do |opts| |
| opts.banner = "Usage: #{File.basename(__FILE__)} [options]" |
| |
| opts.on "-h", "--host HOST", 'Host to connect to' do |host| |
| options.host = host |
| end |
| |
| opts.on "--port PORT", 'Port to connect to' do |port| |
| options.port = port |
| end |
| |
| opts.on "--path PORT", 'Path to connect to' do |path| |
| options.path = path |
| end |
| |
| opts.on "--secure", 'Use secure web sockets (wss)' do |
| options.protocol = 'wss' |
| end |
| |
| opts.on "--noverify", 'Bypass SSL certificate verification' do |
| options.verify = false |
| end |
| |
| opts.on "--user USER", 'User to log in as' do |user| |
| options.user = user |
| end |
| |
| opts.on "--restart", 'restart WebSocket daemon process' do |
| options.restart = true |
| end |
| end |
| |
| opt_parser.parse!(ARGV) |
| |
| options.protocol ||= (options.host.include?('local') ? 'ws' : 'wss') |
| options.port ||= 34234 if options.path=='/' |
| options.port ||= (options.protocol == 'ws' ? 80 : 443) |
| |
| ######################################################################## |
| # Connect to WebSocket # |
| ######################################################################## |
| |
| EM.run do |
| url = "#{options.protocol}://#{options.host}:#{options.port}#{options.path}" |
| puts "coonnecting to #{url}..." |
| ws = WebSocket::EventMachine::Client.connect uri: url |
| |
| ws.onmessage do |msg, type| |
| puts msg |
| end |
| |
| ws.onopen do |
| session = nil |
| |
| # see if there is a local session we can use |
| if options.host.include? 'local' |
| Dir["#{Session::WORKDIR}/*"].find do |file| |
| session = File.basename(file) if File.read(file) == options.user |
| end |
| end |
| |
| # fetch remote session |
| while not session |
| require 'io/console' |
| password = $stdin.getpass("password for #{options.user}: ") |
| |
| path = File.expand_path('../session.json', options.path) |
| request = Net::HTTP::Get.new(path) |
| request.basic_auth options.user, password |
| |
| http = Net::HTTP.new(options.host, options.port) |
| if options.protocol == 'wss' |
| http.use_ssl = true |
| http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless options.verify |
| end |
| response = http.request(request) |
| |
| if response.is_a? Net::HTTPOK |
| session = JSON.parse(response.body)['session'] |
| else |
| p response |
| end |
| end |
| |
| if session |
| if options.restart |
| ws.send "session: #{session}\nrestart: true\n\n" |
| else |
| ws.send "session: #{session}\n\n" |
| end |
| end |
| end |
| |
| ws.onclose do |code, reason| |
| puts "closing: #{code}" |
| exit 1 |
| end |
| |
| ws.onerror do |error| |
| puts "error: #{error.inspect}" |
| end |
| end |