kernul 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+