Class: Kernul::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/kernul/base.rb

Overview

Handles all requests in and out of kernul.

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Base

Creates a new kernul. It requires some configuration options:

  • :db - URL of the CouchDB database.

  • :url - URL that this kernul will be accessed on.

And one optional one:

  • :handler - Constant to Rack handler. Needed if using #start.

  • :host - Host to listen on. Needed if using #start.

  • :port - Port to listen on. Needed if using #start.

  • :options - Extra options passed to the handler.



15
16
17
18
19
20
21
22
23
24
# File 'lib/kernul/base.rb', line 15

def initialize(args)
  self.class.url = args[:url]
  self.class.handler = args[:handler]
  
  options = { :Host => args[:host], :Port => args[:port] }
  options.merge!(args[:options]) if args[:options]
  self.class.options = options
  
  self.class.start_db(args[:db])
end

Class Attribute Details

.dbObject

Returns the value of attribute db.



4
5
6
# File 'lib/kernul/base.rb', line 4

def db
  @db
end

.handlerObject

Returns the value of attribute handler.



4
5
6
# File 'lib/kernul/base.rb', line 4

def handler
  @handler
end

.optionsObject

Returns the value of attribute options.



4
5
6
# File 'lib/kernul/base.rb', line 4

def options
  @options
end

.urlObject

Returns the value of attribute url.



4
5
6
# File 'lib/kernul/base.rb', line 4

def url
  @url
end

Class Method Details

.dispatch(request) ⇒ Object

Prepares and sends the HTTP request to the target application.



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/kernul/base.rb', line 61

def self.dispatch(request)
  method = request.method
  url = request.target_app.url << URI.parse(request.url).request_uri
  headers = dispatch_headers(request)
  payload = request.payload
  
  dispatch = RestClient::Request::NoExceptions.new(:method => method, :url => url, :headers => headers, :payload => payload)
  retrieve = dispatch.execute
  retrieve[1] = filter_headers(retrieve[1])
  retrieve
end

.dispatch_headers(request) ⇒ Object

Prepares the dispatch’s headers.



74
75
76
77
78
79
80
81
82
# File 'lib/kernul/base.rb', line 74

def self.dispatch_headers(request)
  headers = {}
  request.headers.each { |key, value| headers[key.to_s.gsub(/_/, " ").titleize.gsub(/ /, "-")] = value }
  
  headers['Referer'] = "#{request.request_app.symbol}.#{self.url}"
  headers['Pragma'] = [request.target_app.key, headers['Pragma']].join(' ')
  headers.delete_if { |key, value| ['Host', 'Version', 'Authorization'].include? key }
  headers
end

.filter_headers(response_headers) ⇒ Object

Filters the returned headers from the dispatch and chooses which ones will be sent back to the request app.



86
87
88
89
# File 'lib/kernul/base.rb', line 86

def self.filter_headers(response_headers)
  response_headers.delete_if { |key, value| ['content-encoding', 'content-length', 'transfer-encoding'].include? key }
  response_headers
end

.start_db(url) ⇒ Object

Starts the CouchDB database with CouchRest. Creates the database if it isn’t already created.



33
34
35
# File 'lib/kernul/base.rb', line 33

def self.start_db(url)
  CouchRest::Model.default_database = CouchRest.database!(url)
end

.subdomains(url, tld_length = 1) ⇒ Object

Returns all subdomains of the url provided.



55
56
57
58
# File 'lib/kernul/base.rb', line 55

def self.subdomains(url, tld_length = 1)
  parts = URI.parse(url).host.split('.')
  parts[0..-(tld_length+2)]
end

Instance Method Details

#call(env) ⇒ Object

Called by Rack whenever there’s a request to the kernul.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/kernul/base.rb', line 38

def call(env)
  begin
    request = Unracker.unrack_request(env)
    
    request.request_app = App.authenticate(request.user, request.password)
    return Response.invalid_key unless request.request_app
    
    request.target_app = App.find_by_symbol(self.class.subdomains(request.url)[-1])
    return Response.invalid_target unless request.target_app
    
    return self.class.dispatch(request)
  rescue Exception => e
    return Response.default(e)
  end
end

#startObject

Starts up the kernul’s Rack server. Not needed on some hosts which require rackup files.



27
28
29
# File 'lib/kernul/base.rb', line 27

def start
  self.class.handler.run Rack::CommonLogger.new(self), self.class.options
end