kernul 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ === 1.0.0 / 2009-01-01
2
+
3
+ * Initial release
@@ -0,0 +1,16 @@
1
+ History.txt
2
+ Manifest.txt
3
+ Rakefile
4
+ README.txt
5
+ lib/kernul.rb
6
+ lib/kernul/app.rb
7
+ lib/kernul/base.rb
8
+ lib/kernul/request.rb
9
+ lib/kernul/response.rb
10
+ lib/kernul/unracker.rb
11
+ spec/app_spec.rb
12
+ spec/base_spec.rb
13
+ spec/request_spec.rb
14
+ spec/response_spec.rb
15
+ spec/spec_helper.rb
16
+ spec/unracker_spec.rb
@@ -0,0 +1,41 @@
1
+ = Kernul, A generic web platform for Ruby.
2
+
3
+ Kernul is a semi-centralized, highly extensible, and easy to manage generic web platform written in Ruby. Better documentation will come in version 1.1.0.
4
+
5
+ == Installation
6
+
7
+ === Archive Installation
8
+
9
+ rake install
10
+
11
+ === Gem Installation
12
+
13
+ Make sure that you have installed jchris-couchrest from github before installing Kernul.
14
+
15
+ gem install kernul
16
+
17
+ == Usage
18
+
19
+ require 'rubygems'
20
+ require 'kernul'
21
+ require 'mongrel' # This can be any Rack handler
22
+
23
+ url = 'kernul.com'
24
+ db = 'localhost:5984/kernul'
25
+ host = '0.0.0.0'
26
+ port = 80
27
+
28
+ Kernul::Base.new(:url => url, :db => db, :host => host, :port => port, :handler => Rack::Handler::Mongrel).start
29
+
30
+ This will start up a Rack server. If you would only like to create the Rack class because your host requires a Rackup file, simply
31
+ remove the <tt>start</tt> call at the end of the last line. You can also remove the <tt>:host</tt>, <tt>:port</tt>, and <tt>:handler</tt>
32
+ options. See Kernul::Base for more details.
33
+
34
+
35
+ == Meta
36
+
37
+ Written by Alex Kern
38
+
39
+ Copyright (c) 2008-2009 Alex Kern
40
+
41
+ Released under the MIT License
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/rdoctask'
4
+ require 'hoe'
5
+ require './lib/kernul.rb'
6
+
7
+ Hoe.new('kernul', Kernul::VERSION) do |p|
8
+ p.name = 'kernul'
9
+ p.author = 'Alex Kern'
10
+ p.summary = 'A generic web platform for Ruby.'
11
+ p.description = 'A semi-centralized, highly extensible, and easy to manage generic web platform written in Ruby.'
12
+ p.email = 'capnkernul@gmail.com'
13
+ p.url = 'http://kernul.com/'
14
+ p.remote_rdoc_dir = ''
15
+ p.rubyforge_name = 'kernul'
16
+ p.extra_deps = [['activesupport', '>= 2.0.0'],
17
+ ['rack', '>= 0.4.0'],
18
+ ['jchris-couchrest', '>= 0.9.0']]
19
+
20
+ end
21
+
22
+ desc "Release and publish documentation"
23
+ task :repubdoc => [:release, :publish_docs]
@@ -0,0 +1,38 @@
1
+ #--
2
+ # Copyright (c) 2008 Alexander Kern
3
+
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+
11
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+ # SOFTWARE.
18
+ #--
19
+
20
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
21
+
22
+ # The gems
23
+ require 'rubygems'
24
+ require 'active_support'
25
+ require 'rack'
26
+ require 'couchrest'
27
+ require 'rest_client'
28
+
29
+ module Kernul
30
+ VERSION = '1.0.0'
31
+ end
32
+
33
+ # The other files
34
+ require 'kernul/app'
35
+ require 'kernul/request'
36
+ require 'kernul/response'
37
+ require 'kernul/unracker'
38
+ require 'kernul/base'
@@ -0,0 +1,16 @@
1
+ class App < CouchRest::Model
2
+ key_accessor :name, :symbol, :key, :url
3
+ view_by :symbol
4
+
5
+ # Shortcut to finding an application by its symbol
6
+ def self.find_by_symbol(symbol)
7
+ by_symbol(:key => symbol)[0]
8
+ end
9
+
10
+ # Authenticates an application using its symbol and key
11
+ def self.authenticate(symbol, key)
12
+ app = self.find_by_symbol(symbol)
13
+ return app if app and app.key == key
14
+ return false
15
+ end
16
+ end
@@ -0,0 +1,91 @@
1
+ module Kernul
2
+ # Handles all requests in and out of kernul.
3
+ class Base
4
+ class << self; attr_accessor :url, :handler, :options, :db; end
5
+
6
+ # Creates a new kernul. It requires some configuration options:
7
+ # - <tt>:db</tt> - URL of the CouchDB database.
8
+ # - <tt>:url</tt> - URL that this kernul will be accessed on.
9
+ #
10
+ # And one optional one:
11
+ # - <tt>:handler</tt> - Constant to Rack handler. Needed if using <tt>#start</tt>.
12
+ # - <tt>:host</tt> - Host to listen on. Needed if using <tt>#start</tt>.
13
+ # - <tt>:port</tt> - Port to listen on. Needed if using <tt>#start</tt>.
14
+ # - <tt>:options</tt> - Extra options passed to the handler.
15
+ def initialize(args)
16
+ self.class.url = args[:url]
17
+ self.class.handler = args[:handler]
18
+
19
+ options = { :Host => args[:host], :Port => args[:port] }
20
+ options.merge!(args[:options]) if args[:options]
21
+ self.class.options = options
22
+
23
+ self.class.start_db(args[:db])
24
+ end
25
+
26
+ # Starts up the kernul's Rack server. Not needed on some hosts which require rackup files.
27
+ def start
28
+ self.class.handler.run Rack::CommonLogger.new(self), self.class.options
29
+ end
30
+
31
+ # Starts the CouchDB database with CouchRest. Creates the database
32
+ # if it isn't already created.
33
+ def self.start_db(url)
34
+ CouchRest::Model.default_database = CouchRest.database!(url)
35
+ end
36
+
37
+ # Called by Rack whenever there's a request to the kernul.
38
+ def call(env)
39
+ begin
40
+ request = Unracker.unrack_request(env)
41
+
42
+ request.request_app = App.authenticate(request.user, request.password)
43
+ return Response.invalid_key unless request.request_app
44
+
45
+ request.target_app = App.find_by_symbol(self.class.subdomains(request.url)[-1])
46
+ return Response.invalid_target unless request.target_app
47
+
48
+ return self.class.dispatch(request)
49
+ rescue Exception => e
50
+ return Response.default(e)
51
+ end
52
+ end
53
+
54
+ # Returns all subdomains of the url provided.
55
+ def self.subdomains(url, tld_length = 1)
56
+ parts = URI.parse(url).host.split('.')
57
+ parts[0..-(tld_length+2)]
58
+ end
59
+
60
+ # Prepares and sends the HTTP request to the target application.
61
+ def self.dispatch(request)
62
+ method = request.method
63
+ url = request.target_app.url << URI.parse(request.url).request_uri
64
+ headers = dispatch_headers(request)
65
+ payload = request.payload
66
+
67
+ dispatch = RestClient::Request::NoExceptions.new(:method => method, :url => url, :headers => headers, :payload => payload)
68
+ retrieve = dispatch.execute
69
+ retrieve[1] = filter_headers(retrieve[1])
70
+ retrieve
71
+ end
72
+
73
+ # Prepares the dispatch's headers.
74
+ def self.dispatch_headers(request)
75
+ headers = {}
76
+ request.headers.each { |key, value| headers[key.to_s.gsub(/_/, " ").titleize.gsub(/ /, "-")] = value }
77
+
78
+ headers['Referer'] = "#{request.request_app.symbol}.#{self.url}"
79
+ headers['Pragma'] = [request.target_app.key, headers['Pragma']].join(' ')
80
+ headers.delete_if { |key, value| ['Host', 'Version', 'Authorization'].include? key }
81
+ headers
82
+ end
83
+
84
+ # Filters the returned headers from the dispatch and chooses
85
+ # which ones will be sent back to the request app.
86
+ def self.filter_headers(response_headers)
87
+ response_headers.delete_if { |key, value| ['content-encoding', 'content-length', 'transfer-encoding'].include? key }
88
+ response_headers
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,15 @@
1
+ # Extension of RestClient::Request to allow the HTTP code, headers, and body to be
2
+ # directly accessed without the use of exceptions.
3
+ class RestClient::Request
4
+ attr_accessor :request_app, :target_app # Add the ability to store these apps in a request
5
+
6
+ class NoExceptions < RestClient::Request
7
+ # Returns the results of the request in the form of a Rack array.
8
+ def process_result(res)
9
+ result_headers = res.header.to_hash
10
+ result_headers.each { |key, value| result_headers[key] = value[0]}
11
+
12
+ [res.code, result_headers, decode(res['content-encoding'], res.body)]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ # Convenience class to store the possible responses used
2
+ # in a kernul. They return Rack arrays.
3
+ module Kernul
4
+ module Response
5
+ class << self
6
+
7
+ # The Rack array for an invalid symbol and/or key
8
+ def invalid_key
9
+ [ 401, {
10
+ 'Content-Type' => 'text/plain',
11
+ 'WWW-Authenticate' => "Basic realm=\"#{Kernul::Base.url}\""
12
+ }, 'Invalid key' ]
13
+ end
14
+
15
+ # The Rack array if the target doesn't exist or no target is provided
16
+ def invalid_target
17
+ [ 400, {
18
+ 'Content-Type' => 'text/plain'
19
+ }, 'Invalid target' ]
20
+ end
21
+
22
+ # The Rack array if there was an uncaught error or something horrible occured
23
+ def default(error='')
24
+ [ 500, {
25
+ 'Content-Type' => 'text/plain'
26
+ }, error.to_s ]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ # Takes rack environments and makes them into a RestClient requests.
2
+ module Kernul
3
+ module Unracker
4
+ # Removes all the important data from the Rack request and returns
5
+ # a RestClient::Request with that data for easy access.
6
+ def self.unrack_request(env)
7
+ url = generate_url(env)
8
+
9
+ if ['GET', 'POST', 'PUT', 'DELETE'].include?(env['REQUEST_METHOD'])
10
+ method = env['REQUEST_METHOD']
11
+ else
12
+ method = 'GET'
13
+ end
14
+
15
+ headers = unrack_headers(env)
16
+ payload = env['rack.input']
17
+
18
+ if env['HTTP_AUTHORIZATION']
19
+ auth = env['HTTP_AUTHORIZATION'].split(" ")[1].unpack("m*").first.split(/:/, 2)
20
+ else
21
+ auth = ["",""]
22
+ end
23
+
24
+ user = auth.first
25
+ password = auth.last
26
+
27
+ RestClient::Request.new(:method => method, :url => url, :headers => headers, :user => user, :password => password, :payload => payload)
28
+ end
29
+
30
+ # Recreates the request URL from the Rack environment data.
31
+ def self.generate_url(env)
32
+ url = env['rack.url_scheme'] + "://"
33
+ url << env['SERVER_NAME']
34
+ url << ":" + env["SERVER_PORT"]
35
+ url << env['SCRIPT_NAME']
36
+ url << env['PATH_INFO'] unless env['PATH_INFO'].nil?
37
+ url << "?" << env['QUERY_STRING'] unless env['QUERY_STRING'].empty?
38
+ url
39
+ end
40
+
41
+ # Removes all HTTP headers from the Rack environment data and returns
42
+ # them as a hash.
43
+ def self.unrack_headers(env)
44
+ hash = {}
45
+ http_headers = env.select { |key, value| key[0..4] == "HTTP_" }
46
+ http_headers.each { |t| hash[t[0].dup[5..-1]] = t[1] }
47
+ hash
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe App do
4
+ it "should be able to find things by symbol" do
5
+ app = App.new(:symbol => 'test')
6
+ App.should_receive(:by_symbol).and_return([app])
7
+ App.find_by_symbol('test').should == app
8
+ end
9
+
10
+ it "should return nil if no application with that symbol exists" do
11
+ App.should_receive(:by_symbol).and_return([])
12
+ App.find_by_symbol('no_such_app').should == nil
13
+ end
14
+
15
+ it "should be able to authenticate an app" do
16
+ app = App.new(:symbol => 'symbol', :key => 'key')
17
+ App.should_receive(:by_symbol).and_return([app])
18
+ App.authenticate('symbol', 'key').should == app
19
+ end
20
+
21
+ it "should return false when trying to authenticate an app if the credentials are bad" do
22
+ app = App.new(:symbol => 'symbol', :key => 'key')
23
+ App.should_receive(:by_symbol).and_return([app])
24
+ App.authenticate('wrong', 'wrong').should == false
25
+ end
26
+ end
@@ -0,0 +1,150 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Kernul::Base do
4
+ it "should be able to create a database" do
5
+ Kernul::Base.start_db('localhost:5984').should be_an_instance_of(CouchRest::Database)
6
+ end
7
+
8
+ it "should be able to parse subdomains" do
9
+ Kernul::Base.subdomains('http://sub1.lol.com').should == ['sub1']
10
+ Kernul::Base.subdomains('http://sub2.sub1.lol.com').should == ['sub2', 'sub1']
11
+ end
12
+
13
+ it "should change the request headers" do
14
+ dummy = mock('dummy');
15
+ dummy.stub!(:headers).and_return('TEST' => 'TEST', 'TEST_TEST' => 'TEST', 'PRAGMA' => 'no-cache', 'HOST' => 'test.com', 'VERSION' => '1.3.3.7', 'AUTHORIZATION' => 'topsecret')
16
+ dummy.stub!(:request_app).and_return(dummy)
17
+ dummy.stub!(:symbol).and_return('testing')
18
+ dummy.stub!(:target_app).and_return(dummy)
19
+ dummy.stub!(:key).and_return('password')
20
+ Kernul::Base.should_receive(:url).and_return('example.com')
21
+
22
+ result = Kernul::Base.dispatch_headers(dummy)
23
+ result['Test'].should == 'TEST'
24
+ result['Test-Test'].should == 'TEST'
25
+ result['Referer'].should == 'testing.example.com'
26
+ result['Pragma'].should == 'password no-cache'
27
+ result['Host'].should be_nil
28
+ result['Version'].should be_nil
29
+ result['Authorization'].should be_nil
30
+ end
31
+
32
+ it "should filter out the encoding headers from a response" do
33
+ Kernul::Base.filter_headers('test' => 'test').should == {'test' => 'test'}
34
+ Kernul::Base.filter_headers('test' => 'test', 'content-encoding' => 'gzip').should == {'test' => 'test'}
35
+ Kernul::Base.filter_headers('test' => 'test', 'content-length' => '1').should == {'test' => 'test'}
36
+ Kernul::Base.filter_headers('test' => 'test', 'transfer-encoding' => '1').should == {'test' => 'test'}
37
+ end
38
+
39
+ it "should be able to dispatch a request" do
40
+ request = mock('request')
41
+ target_app = mock('target_app')
42
+ request.stub!(:method).and_return('GET')
43
+ request.stub!(:target_app).and_return(target_app)
44
+ request.stub!(:url).and_return('http://google.com/')
45
+ request.stub!(:payload).and_return('')
46
+ target_app.stub!(:url).and_return('http://google.com/')
47
+ Kernul::Base.should_receive(:dispatch_headers).and_return({})
48
+
49
+ # This will contact google which will always show a 301 Found redirect to their www subdomain.
50
+ result = Kernul::Base.dispatch(request)
51
+ result.should be_an_instance_of(Array)
52
+ result[0].should == '301'
53
+ end
54
+
55
+ it "should be able to be created without being started" do
56
+ Kernul::Base.should_receive(:start_db).and_return(true)
57
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test')
58
+ end
59
+
60
+ it "should merge the handler options when created" do
61
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test', :host => '0.0.0.0', :port => 80, :options => {:test => 'test'})
62
+ Kernul::Base.options.should == { :Host => '0.0.0.0', :Port => 80, :test => 'test' }
63
+ end
64
+
65
+ it "should be able to be started as a Rack server" do
66
+ handler = mock('handler')
67
+ handler.should_receive(:run).and_return(true)
68
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test', :host => '0.0.0.0', :port => 80, :handler => handler)
69
+ kernul.start
70
+ end
71
+ end
72
+
73
+ describe Kernul::Base, "#call" do
74
+ it "should unrack the environment" do
75
+ env = mock('env')
76
+ Kernul::Unracker.should_receive(:unrack_request).and_return(nil)
77
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test')
78
+ kernul.call(env)
79
+ end
80
+
81
+ it "should show an invalid key error if the username and password are wrong" do
82
+ env = mock('env')
83
+ request = mock('request')
84
+ request.should_receive(:user).and_return('user')
85
+ request.should_receive(:password).and_return('password')
86
+ request.should_receive(:request_app).and_return(false)
87
+ request.should_receive(:request_app=).and_return(false)
88
+ App.should_receive(:authenticate).and_return(false)
89
+ Kernul::Unracker.stub!(:unrack_request).and_return(request)
90
+ Kernul::Response.should_receive(:invalid_key).and_return([])
91
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test')
92
+ kernul.call(env).should == []
93
+ end
94
+
95
+ it "should show an invalid target error if an invalid target app is supplied" do
96
+ env = mock('env')
97
+ request = mock('request')
98
+ request_app = mock('request_app')
99
+ request.stub!(:user).and_return('user')
100
+ request.stub!(:password).and_return('password')
101
+ request.stub!(:request_app).and_return(request_app)
102
+ request.stub!(:request_app=).and_return(request_app)
103
+ request.should_receive(:url).and_return('test.example.com')
104
+ request.should_receive(:target_app).and_return(false)
105
+ request.should_receive(:target_app=).and_return(false)
106
+ Kernul::Base.should_receive(:subdomains).and_return([])
107
+ App.stub!(:authenticate).and_return(request_app)
108
+ App.should_receive(:find_by_symbol).and_return(false)
109
+ Kernul::Unracker.stub!(:unrack_request).and_return(request)
110
+ Kernul::Response.should_receive(:invalid_target).and_return([])
111
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test')
112
+ kernul.call(env).should == []
113
+ end
114
+
115
+ it "should dispatch the request if it is valid" do
116
+ env = mock('env')
117
+ request = mock('request')
118
+ request_app = mock('request_app')
119
+ target_app = mock('target_app')
120
+ request.stub!(:user).and_return('user')
121
+ request.stub!(:password).and_return('password')
122
+ request.stub!(:request_app).and_return(request_app)
123
+ request.stub!(:request_app=).and_return(request_app)
124
+ request.stub!(:url).and_return('test.example.com')
125
+ request.stub!(:target_app).and_return(target_app)
126
+ request.stub!(:target_app=).and_return(target_app)
127
+ Kernul::Base.stub!(:subdomains).and_return([])
128
+ App.stub!(:authenticate).and_return(request_app)
129
+ App.stub!(:find_by_symbol).and_return(target_app)
130
+ Kernul::Unracker.stub!(:unrack_request).and_return(request)
131
+ Kernul::Base.should_receive(:dispatch).and_return([])
132
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => 'test')
133
+ kernul.call(env).should == []
134
+ end
135
+
136
+ it "should report database communication errors" do
137
+ env = mock('env')
138
+ request = mock('request')
139
+ request.stub!(:user).and_return('user')
140
+ request.stub!(:password).and_return('password')
141
+ request.stub!(:request_app).and_return(false)
142
+ request.stub!(:request_app=).and_return(false)
143
+ Kernul::Unracker.stub!(:unrack_request).and_return(request)
144
+ Kernul::Response.should_receive(:default).and_return([])
145
+
146
+ # This makes the database fail to connect, causing an Exception to be raised.
147
+ kernul = Kernul::Base.new(:url => 'kernul.com', :db => '1crazyinsaneurl.com')
148
+ kernul.call(env).should == []
149
+ end
150
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe RestClient::Request::NoExceptions do
4
+ it "should return a rack array of the response" do
5
+ dummy = mock('dummy');
6
+ request = RestClient::Request::NoExceptions.new(:method => 'GET', :url => 'nowhere');
7
+ dummy.stub!(:code).and_return(200)
8
+ dummy.stub!(:header).and_return(:test => ['test'])
9
+ dummy.stub!(:body).and_return('testestest')
10
+ dummy.stub!(:[]).with('content-encoding').and_return('text/plain')
11
+ request.should_receive(:decode).and_return('testestest')
12
+
13
+ result = request.process_result(dummy)
14
+ result.should be_an_instance_of(Array)
15
+ result.length.should == 3
16
+ result[0].should be_an_instance_of(Fixnum)
17
+ result[1].should be_an_instance_of(Hash)
18
+ result[2].should be_an_instance_of(String)
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Kernul::Response do
4
+ it "should return a Rack array" do
5
+ [Kernul::Response.invalid_key, Kernul::Response.invalid_target, Kernul::Response.default].each do |array|
6
+ array.should be_an_instance_of(Array)
7
+ array.length.should == 3
8
+ array[0].should be_an_instance_of(Fixnum)
9
+ array[1].should be_an_instance_of(Hash)
10
+ array[2].should be_an_instance_of(String)
11
+ end
12
+ end
13
+
14
+ it "should convert exceptions to text in a default response" do
15
+ Kernul::Response.default[2].should == ''
16
+ Kernul::Response.default('')[2].should == ''
17
+ Kernul::Response.default('test')[2].should == 'test'
18
+ Kernul::Response.default(ArgumentError)[2].should == 'ArgumentError'
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'spec'
4
+
5
+ require File.dirname(__FILE__) + '/../lib/kernul'
@@ -0,0 +1,86 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Kernul::Unracker do
4
+ it "should be able to recreate a url" do
5
+ env = Rack::MockRequest.env_for('http://example.com:80/')
6
+ Kernul::Unracker.generate_url(env).should == 'http://example.com:80/'
7
+
8
+ env = Rack::MockRequest.env_for('http://lol.example.com:80/')
9
+ Kernul::Unracker.generate_url(env).should == 'http://lol.example.com:80/'
10
+
11
+ env = Rack::MockRequest.env_for('http://example.com:23/')
12
+ Kernul::Unracker.generate_url(env).should == 'http://example.com:23/'
13
+
14
+ env = Rack::MockRequest.env_for('https://example.com:80/')
15
+ Kernul::Unracker.generate_url(env).should == 'https://example.com:80/'
16
+
17
+ env = Rack::MockRequest.env_for('http://example.com:80/lol')
18
+ Kernul::Unracker.generate_url(env).should == 'http://example.com:80/lol'
19
+
20
+ env = Rack::MockRequest.env_for('http://example.com:80/?lol')
21
+ Kernul::Unracker.generate_url(env).should == 'http://example.com:80/?lol'
22
+
23
+ env = Rack::MockRequest.env_for('http://example.com:80/#lol')
24
+ Kernul::Unracker.generate_url(env).should == 'http://example.com:80/'
25
+ end
26
+
27
+ it "should be able to unrack the headers" do
28
+ env = Rack::MockRequest.env_for('http://example.com:80/')
29
+ Kernul::Unracker.unrack_headers(env).should == {}
30
+
31
+ env = Rack::MockRequest.env_for('http://example.com:80/', {'lol' => 'lol'})
32
+ Kernul::Unracker.unrack_headers(env).should == {}
33
+
34
+ env = Rack::MockRequest.env_for('http://example.com:80/', {'HTTP_REFERER' => 'lol'})
35
+ Kernul::Unracker.unrack_headers(env).should == {'REFERER' => 'lol'}
36
+ end
37
+ end
38
+
39
+ describe Kernul::Unracker, "#unrack_request" do
40
+ it "should return a RestClient::Request" do
41
+ env = Rack::MockRequest.env_for('http://example.com:80/')
42
+ Kernul::Unracker.unrack_request(env).should be_an_instance_of(RestClient::Request)
43
+ end
44
+
45
+ it "should have a method" do
46
+ env = Rack::MockRequest.env_for('http://example.com:80/')
47
+ Kernul::Unracker.unrack_request(env).method.should == 'GET'
48
+
49
+ env = Rack::MockRequest.env_for('http://example.com:80/', {:method => 'GET'})
50
+ Kernul::Unracker.unrack_request(env).method.should == 'GET'
51
+
52
+ env = Rack::MockRequest.env_for('http://example.com:80/', {:method => 'POST'})
53
+ Kernul::Unracker.unrack_request(env).method.should == 'POST'
54
+
55
+ env = Rack::MockRequest.env_for('http://example.com:80/', {:method => 'PUT'})
56
+ Kernul::Unracker.unrack_request(env).method.should == 'PUT'
57
+
58
+ env = Rack::MockRequest.env_for('http://example.com:80/', {:method => 'DELETE'})
59
+ Kernul::Unracker.unrack_request(env).method.should == 'DELETE'
60
+
61
+ env = Rack::MockRequest.env_for('http://example.com:80/', {:method => 'NOTAMETHOD'})
62
+ Kernul::Unracker.unrack_request(env).method.should == "GET"
63
+ end
64
+
65
+ it "should be able to have a payload" do
66
+ env = Rack::MockRequest.env_for('http://example.com:80/')
67
+ Kernul::Unracker.unrack_request(env).payload.read.should == ''
68
+
69
+ env = Rack::MockRequest.env_for('http://example.com:80/', :input => "lol")
70
+ Kernul::Unracker.unrack_request(env).payload.read.should == 'lol'
71
+ end
72
+
73
+ it "should have a username and password" do
74
+ env = Rack::MockRequest.env_for('http://example.com:80/')
75
+ Kernul::Unracker.unrack_request(env).user.should == ""
76
+ Kernul::Unracker.unrack_request(env).password.should == ""
77
+
78
+ env = Rack::MockRequest.env_for('http://example.com:80/', 'HTTP_AUTHORIZATION' => "Basic #{['lol:rofl'].pack("m*")}")
79
+ Kernul::Unracker.unrack_request(env).user.should == "lol"
80
+ Kernul::Unracker.unrack_request(env).password.should == "rofl"
81
+
82
+ env = Rack::MockRequest.env_for('http://example.com:80/', 'HTTP_AUTHORIZATION' => 'Basic lol:rofl')
83
+ Kernul::Unracker.unrack_request(env).user.should_not == "lol"
84
+ Kernul::Unracker.unrack_request(env).password.should_not == "rofl"
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kernul
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alex Kern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-01 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: jchris-couchrest
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: hoe
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.2
54
+ version:
55
+ description: A semi-centralized, highly extensible, and easy to manage generic web platform written in Ruby.
56
+ email: capnkernul@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - History.txt
63
+ - Manifest.txt
64
+ - README.txt
65
+ files:
66
+ - History.txt
67
+ - Manifest.txt
68
+ - Rakefile
69
+ - README.txt
70
+ - lib/kernul.rb
71
+ - lib/kernul/app.rb
72
+ - lib/kernul/base.rb
73
+ - lib/kernul/request.rb
74
+ - lib/kernul/response.rb
75
+ - lib/kernul/unracker.rb
76
+ - spec/app_spec.rb
77
+ - spec/base_spec.rb
78
+ - spec/request_spec.rb
79
+ - spec/response_spec.rb
80
+ - spec/spec_helper.rb
81
+ - spec/unracker_spec.rb
82
+ has_rdoc: true
83
+ homepage: http://kernul.com/
84
+ post_install_message:
85
+ rdoc_options:
86
+ - --main
87
+ - README.txt
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ version:
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ version:
102
+ requirements: []
103
+
104
+ rubyforge_project: kernul
105
+ rubygems_version: 1.3.1
106
+ signing_key:
107
+ specification_version: 2
108
+ summary: A generic web platform for Ruby.
109
+ test_files: []
110
+