class Apnotic::Connection

Attributes

cert_path[R]
url[R]

Public Class Methods

development(options={}) click to toggle source
# File lib/apnotic/connection.rb, line 14
def development(options={})
  options.merge!(url: APPLE_DEVELOPMENT_SERVER_URL)
  new(options)
end
new(options={}) click to toggle source
# File lib/apnotic/connection.rb, line 20
def initialize(options={})
  @url             = options[:url] || APPLE_PRODUCTION_SERVER_URL
  @cert_path       = options[:cert_path]
  @cert_pass       = options[:cert_pass]
  @connect_timeout = options[:connect_timeout] || 30
  @auth_method     = options[:auth_method] || :cert
  @team_id         = options[:team_id]
  @key_id          = options[:key_id]
  @first_push      = true

  raise "Cert file not found: #{@cert_path}" unless @cert_path && (@cert_path.respond_to?(:read) || File.exist?(@cert_path))

  http2_options = {
    ssl_context: ssl_context,
    connect_timeout: @connect_timeout
  }
  PROXY_SETTINGS_KEYS.each do |key|
    http2_options[key] = options[key] if options[key]
  end

  @client = NetHttp2::Client.new(@url, http2_options)
end

Public Instance Methods

close() click to toggle source
# File lib/apnotic/connection.rb, line 71
def close
  @client.close
end
join(timeout: nil) click to toggle source
# File lib/apnotic/connection.rb, line 75
def join(timeout: nil)
  @client.join(timeout: timeout)
end
on(event, &block) click to toggle source
# File lib/apnotic/connection.rb, line 79
def on(event, &block)
  @client.on(event, &block)
end
prepare_push(notification) click to toggle source
# File lib/apnotic/connection.rb, line 62
def prepare_push(notification)
  request       = prepare_request(notification)
  http2_request = @client.prepare_request(:post, request.path,
    body:    request.body,
    headers: request.headers
  )
  Apnotic::Push.new(http2_request)
end
push(notification, options={}) click to toggle source
# File lib/apnotic/connection.rb, line 43
def push(notification, options={})
  request  = prepare_request(notification)
  response = @client.call(:post, request.path,
    body:    request.body,
    headers: request.headers,
    timeout: options[:timeout]
  )
  Apnotic::Response.new(headers: response.headers, body: response.body) if response
end
push_async(push) click to toggle source
# File lib/apnotic/connection.rb, line 53
def push_async(push)
  if @first_push
    @client.call_async(push.http2_request)
    @first_push = false
  else
    delayed_push_async(push)
  end
end

Private Instance Methods

build_ssl_context() click to toggle source
# File lib/apnotic/connection.rb, line 114
def build_ssl_context
  @build_ssl_context ||= begin
    ctx = OpenSSL::SSL::SSLContext.new
    begin
      p12      = OpenSSL::PKCS12.new(certificate, @cert_pass)
      ctx.key  = p12.key
      ctx.cert = p12.certificate
    rescue OpenSSL::PKCS12::PKCS12Error
      ctx.key  = OpenSSL::PKey::RSA.new(certificate, @cert_pass)
      ctx.cert = OpenSSL::X509::Certificate.new(certificate)
    end
    ctx
  end
end
certificate() click to toggle source
# File lib/apnotic/connection.rb, line 129
def certificate
  @certificate ||= begin
    if @cert_path.respond_to?(:read)
      cert = @cert_path.read
      @cert_path.rewind if @cert_path.respond_to?(:rewind)
    else
      cert = File.read(@cert_path)
    end
    cert
  end
end
delayed_push_async(push) click to toggle source
# File lib/apnotic/connection.rb, line 90
def delayed_push_async(push)
  until streams_available? do
    sleep 0.001
  end
  @client.call_async(push.http2_request)
end
prepare_request(notification) click to toggle source
# File lib/apnotic/connection.rb, line 85
def prepare_request(notification)
  notification.authorization = provider_token if @auth_method == :token
  Apnotic::Request.new(notification)
end
provider_token() click to toggle source
# File lib/apnotic/connection.rb, line 141
def provider_token
  @provider_token_cache ||= begin
    instance = ProviderToken.new(certificate, @team_id, @key_id)
    InstanceCache.new(instance, :token, 30 * 60)
  end
  @provider_token_cache.call
end
remote_max_concurrent_streams() click to toggle source
# File lib/apnotic/connection.rb, line 101
def remote_max_concurrent_streams
  # 0x7fffffff is the default value from http-2 gem (2^31)
  if @client.remote_settings[:settings_max_concurrent_streams] == 0x7fffffff
    1
  else
    @client.remote_settings[:settings_max_concurrent_streams]
  end
end
ssl_context() click to toggle source
# File lib/apnotic/connection.rb, line 110
def ssl_context
  @auth_method == :cert ? build_ssl_context : nil
end
streams_available?() click to toggle source
# File lib/apnotic/connection.rb, line 97
def streams_available?
  remote_max_concurrent_streams - @client.stream_count > 0
end