lib/ass.rb in ass-0.0.20 vs lib/ass.rb in ass-0.0.21

- old
+ new

@@ -18,10 +18,11 @@ require 'digest/sha2' require 'will_paginate' require 'will_paginate/sequel' # or data_mapper/sequel require 'uri' require 'sinatra/reloader' if development? +require 'sinatra/synchrony' ############################################################ ## Initilization Setup ############################################################ LIBDIR = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) @@ -45,18 +46,22 @@ ############################################################ env = ENV['SINATRA_ENV'] || "development" config = YAML.load_file("#{Dir.pwd}/ass.yml") $timer = "#{config['timer']}".to_i $cron = config['cron'] || 'cron' -$port = config['port'] || 4567 +$port = "#{config['port']}".to_i || 4567 $mode = config['mode'] || env $VERSION = File.open("#{ROOTDIR}/VERSION", "rb").read $apps = config['apps'] || [] $log = config['log'] || 'off' $user = config['user'] || 'admin' $pass = config['pass'] || 'pass' +$flood = "#{config['flood']}".to_i || 1 # default 1 minute +$client_ip = '127.0.0.1' +$last_access = 0 + ############################################################ ## Certificate Key Setup ############################################################ $certkey = {} @@ -110,48 +115,39 @@ ############################################################ ## Sequel Database Setup ############################################################ -unless File.exist?("#{Dir.pwd}/ass-#{$model}.db") then - $DB = Sequel.connect("sqlite://#{Dir.pwd}/ass-#{$model}.db") - +unless File.exist?("#{Dir.pwd}/ass-#{$mode}.db") then + $DB = Sequel.connect("sqlite://#{Dir.pwd}/ass-#{$mode}.db") $DB.create_table :tokens do primary_key :id String :app, :unique => false, :null => false String :token, :unique => false, :null => false, :size => 100 Time :created_at index [:app, :token] end - $DB.create_table :pushes do primary_key :id - String :pid, :unique => true, :null => false, :size => 100 + String :pid, :unique => false, :null => false, :size => 100 String :app, :unique => false, :null => false, :size => 30 String :message, :unique => false, :null => false, :size => 107 Time :created_at index [:pid, :app, :message] end else - $DB = Sequel.connect("sqlite://#{Dir.pwd}/ass-#{$model}.db") + $DB = Sequel.connect("sqlite://#{Dir.pwd}/ass-#{$mode}.db") end WillPaginate.per_page = 10 -# Token = $DB[:tokens] -# Push = $DB[:pushes] - class Token < Sequel::Model Sequel.extension :pagination - - # here is your code end class Push < Sequel::Model Sequel.extension :pagination - - # here is your code end ############################################################ ## Timer Job Setup ############################################################ @@ -167,26 +163,48 @@ ############################################################ ## Apple Service Server based on Sinatra ############################################################ class App < Sinatra::Base + + register Sinatra::Synchrony + use Rack::MobileDetect set :root, File.expand_path('../../', __FILE__) set :port, "#{$port}".to_i set :public_folder, File.dirname(__FILE__) + '/../public' set :views, File.dirname(__FILE__) + '/../views' helpers do - + + def checkFlood?(req) + if $client_ip != "#{req.ip}" then + $client_ip = "#{req.ip}" + return false + else + if $last_access == 0 then + return false + else + return isFlood? + end + end + end + + def isFlood? + result = (Time.now - $last_access) < $flood * 60 + $last_access = Time.now + return result + end + def iOS? - ret = case request.env['X_MOBILE_DEVICE'] + result = case request.env['X_MOBILE_DEVICE'] when /iPhone|iPod|iPad/ then true else false end - return ret + return result end def authorized? @auth ||= Rack::Auth::Basic::Request.new(request.env) @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ["#{$user}", "#{$pass}"] @@ -196,11 +214,10 @@ unless authorized? response['WWW-Authenticate'] = %(Basic realm="Restricted Area") throw(:halt, [401, "Oops... we need your login name & password\n"]) end end - end configure :production, :development do if "#{$log}".strip == 'on' then enable :logging @@ -271,17 +288,18 @@ $apps.each { |app| ## register token api get "/v1/apps/#{app}/:token" do - if (("#{params[:token]}".length == 64) and iOS? ) then + if (("#{params[:token]}".length == 64) and iOS? and checkFlood?(request) ) then puts "[#{params[:token]}] was added to '#{app}'" if "#{$mode}".strip == 'development' o = Token.first(:app => app, :token => params[:token]) unless o Token.insert( :app => app, - :token => params[:token] + :token => params[:token], + :created_at => Time.now ) end end end @@ -302,10 +320,13 @@ @tokens = Token.where(:app => "#{app}") @exist = Push.first(:pid => "#{pid}", :app => "#{app}") unless @exist + + Push.insert(:pid => pid, :message => message, :created_at => Time.now, :app => "#{app}" ) + openSSLContext = $certkey["#{app}"] # Connect to port 2195 on the server. sock = nil if $mode == 'production' then sock = TCPSocket.new('gateway.push.apple.com', 2195) @@ -313,12 +334,11 @@ sock = TCPSocket.new('gateway.sandbox.push.apple.com', 2195) end # do our SSL handshaking sslSocket = OpenSSL::SSL::SSLSocket.new(sock, openSSLContext) sslSocket.connect - #Push.create( :pid => pid ) - Push.insert(:pid => pid, :message => message, :created_at => Time.now, :app => "#{app}" ) + # write our packet to the stream @tokens.each do |o| tokenText = o[:token] # pack the token to convert the ascii representation back to binary tokenData = [tokenText].pack('H*') @@ -347,10 +367,13 @@ @tokens = Token.where(:app => "#{app}") @exist = Push.first(:pid => "#{pid}", :app => "#{app}") unless @exist + + Push.insert(:pid => pid, :message => message, :created_at => Time.now, :app => "#{app}" ) + openSSLContext = $certkey["#{app}"] # Connect to port 2195 on the server. sock = nil if $mode == 'production' then sock = TCPSocket.new('gateway.push.apple.com', 2195) @@ -358,11 +381,10 @@ sock = TCPSocket.new('gateway.sandbox.push.apple.com', 2195) end # do our SSL handshaking sslSocket = OpenSSL::SSL::SSLSocket.new(sock, openSSLContext) sslSocket.connect - #Push.create( :pid => pid ) - Push.insert(:pid => pid, :message => message, :created_at => Time.now, :app => "#{app}" ) + # write our packet to the stream @tokens.each do |o| tokenText = o[:token] # pack the token to convert the ascii representation back to binary tokenData = [tokenText].pack('H*') \ No newline at end of file