optionsful 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.textile +109 -0
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/lib/baurets/optionsful/config.rb +26 -31
- data/lib/baurets/optionsful/introspections.rb +86 -6
- data/lib/baurets/optionsful/server.rb +11 -6
- data/optionsful.gemspec +7 -8
- data/samples/optionsful.yml.sample +20 -0
- data/samples/optionsful_bug.yml +1 -0
- data/samples/optionsful_true.yml +20 -0
- data/spec/optionsful_config_spec.rb +49 -20
- data/spec/optionsful_server_spec.rb +40 -8
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +1 -0
- data/tasks/optionsful.rake +1 -1
- metadata +10 -11
- data/README.rdoc +0 -17
- data/config/optionsful.yml +0 -18
- data/spec/config/optionsful.yml +0 -18
- data/spec/config/optionsful_host_auto.yml +0 -18
- data/spec/config/optionsful_link_false.yml +0 -18
data/.gitignore
CHANGED
data/README.textile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
h1. *O p t i o n s f u l*
|
2
|
+
|
3
|
+
Provide HTTP OPTIONS support for the Ruby on Rails framework.
|
4
|
+
|
5
|
+
* Note for the impatient: installation instructions below.
|
6
|
+
* Note for the dummies: change host names and paths properly.
|
7
|
+
* Note for the unfaithful: run @rake routes@ to validate the results.
|
8
|
+
|
9
|
+
** *WARNING*: If your application is Rails 2.x please go to "optionsful2":http://github.com/kayaman/optionsful2
|
10
|
+
|
11
|
+
h1. "-No! No! No! *-Show me the code!*"
|
12
|
+
|
13
|
+
h3. Retrieving an HTTP OPTIONS request via telnet:
|
14
|
+
|
15
|
+
<pre>
|
16
|
+
$ telnet localhost 3000
|
17
|
+
OPTIONS /posts HTTP/1.1
|
18
|
+
Host: http://localhost:3000
|
19
|
+
|
20
|
+
HTTP/1.1 204 No Content
|
21
|
+
Allow: GET, POST
|
22
|
+
Connection: close
|
23
|
+
Date: Thu, 22 Jul 2010 17:20:27 GMT
|
24
|
+
Link: "<http://localhost:3000/api/posts>; type=text/html; rel=help"
|
25
|
+
|
26
|
+
OPTIONS /posts/1 HTTP/1.1
|
27
|
+
Host: http://localhost:3000
|
28
|
+
|
29
|
+
HTTP/1.1 204 No Content
|
30
|
+
Allow: GET, PUT, DELETE
|
31
|
+
Connection: close
|
32
|
+
Date: Thu, 22 Jul 2010 18:14:24 GMT
|
33
|
+
Link: "<http://localhost:3000/api/posts/1/>; type=text/html; rel=help"
|
34
|
+
|
35
|
+
OPTIONS /posts/1/comments HTTP/1.1
|
36
|
+
Host: http://localhost:3000
|
37
|
+
|
38
|
+
HTTP/1.1 204 No Content
|
39
|
+
Allow: GET, POST
|
40
|
+
Connection: close
|
41
|
+
Date: Thu, 22 Jul 2010 18:12:43 GMT
|
42
|
+
Link: "<http://localhost:3000/api/posts/1/comments>; type=text/html; rel=help"
|
43
|
+
|
44
|
+
</pre>
|
45
|
+
~Note the empty line which is part of the HTTP protocol.~
|
46
|
+
|
47
|
+
h3. Well, I agree. Telnet is the geekest way.. ;-)
|
48
|
+
|
49
|
+
This is for testing purposes. You would like better to use an HTTP client software. I use "HTTP Client":http://ditchnet.org/httpclient/ on Mac OS X. And on real life, There is a lot of possible usage scenarios.
|
50
|
+
|
51
|
+
h1. INSTALLATION:
|
52
|
+
|
53
|
+
# Change directory to your Ruby on Rails web application,
|
54
|
+
# Add gem dependency to @config/application.rb@:
|
55
|
+
<pre>config.gem "optionsful"</pre>
|
56
|
+
# To install it, run @rake gems:install@ or:
|
57
|
+
<pre>$ gem install optionsful</pre>
|
58
|
+
# Enjoy! And give feedback! :)
|
59
|
+
|
60
|
+
h2. Setting up the @Link@ header
|
61
|
+
|
62
|
+
* To enable and setup the response's @Link@ header, install and edit the configuration file:
|
63
|
+
** run @rake optionsful:yml@
|
64
|
+
** edit the 'optionsful.yml' file at your application's 'config' folder.
|
65
|
+
* Example:
|
66
|
+
<pre>development:
|
67
|
+
link: true
|
68
|
+
host: auto
|
69
|
+
base_path: /api
|
70
|
+
propagate: true</pre>
|
71
|
+
|
72
|
+
h3. Possible values and effects: (the bold values are the default ones)
|
73
|
+
|
74
|
+
** @link@
|
75
|
+
*** *false*: Do not include any "Link" header in the response.
|
76
|
+
*** true: Do include it. Build the URI based on the 'host', 'base_path', and 'propagate' values, explained below.
|
77
|
+
|
78
|
+
** @host@
|
79
|
+
*** *auto*: Use the application's own address and port.
|
80
|
+
*** private.mycompany.com: point it to another location. For instance: www.baurets.net. (Do not include http://).
|
81
|
+
|
82
|
+
|
83
|
+
** @base_path@
|
84
|
+
*** the path to be appended to the host. Default is */api*.
|
85
|
+
*** to disable it, use @/@
|
86
|
+
*** Example: /my_company/my_project/resources/api
|
87
|
+
|
88
|
+
** @propagate@
|
89
|
+
*** false: Do not append the request's path info to the URI.
|
90
|
+
*** *true*: Do append it, as it is.
|
91
|
+
|
92
|
+
Generated Link example:
|
93
|
+
(link: true, host: auto)
|
94
|
+
<pre>Link: "<http://localhost:3000/api/posts/1/comments>; type=text/html; rel=help"</pre>
|
95
|
+
* *Note*: @Allow@ and @Link@ are expected headers on a response to an HTTP OPTIONS request.
|
96
|
+
|
97
|
+
h2. KNOWN ISSUES
|
98
|
+
* Rails route recognition still need some work
|
99
|
+
* Platform: *Rails 3.0.0.rc* !!!
|
100
|
+
|
101
|
+
h2. Get involved
|
102
|
+
* Mailing list: http://groups.google.com/group/optionsful
|
103
|
+
* Bug tracker : http://kayaman.lighthouseapp.com/projects/56438-optionsful/overview
|
104
|
+
|
105
|
+
h2. CONTRIBUTORS
|
106
|
+
* Me, myself and I, so far.
|
107
|
+
* You are welcome, do it. ;-)
|
108
|
+
|
109
|
+
Copyright (c) 2010 Marco Antonio Gonzalez Junior, kayaman@baurets.net, released under the MIT license.
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -1,54 +1,49 @@
|
|
1
|
+
|
2
|
+
require 'yaml'
|
3
|
+
|
1
4
|
module Baurets
|
2
5
|
module Optionsful
|
3
6
|
class Config
|
4
7
|
|
5
|
-
DEFAULT = { :link => false, :host => 'auto', :base_path => "/
|
8
|
+
DEFAULT = { :link => false, :host => 'auto', :base_path => "/api", :propagate => true }
|
6
9
|
|
7
10
|
def initialize(file = nil, options = {})
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
begin
|
12
|
-
if (defined? Rails && File.exist?(File.join(Rails.root, 'config', 'optionsful.yml')))
|
13
|
-
envs = YAML::load_file(File.join(Rails.root, 'config', 'optionsful.yml')).symbolize_keys
|
14
|
-
@config = envs[get_env].symbolize_keys
|
15
|
-
end
|
16
|
-
rescue
|
17
|
-
end
|
11
|
+
if file.nil?
|
12
|
+
file = File.join(Rails.root, 'config', 'optionsful.yml')
|
18
13
|
end
|
19
|
-
|
20
|
-
|
14
|
+
config = load_yaml(file, get_env)
|
15
|
+
config = DEFAULT if config.nil? or config.empty?
|
16
|
+
config.merge!(options) unless options.empty?
|
17
|
+
@config = config
|
18
|
+
config
|
21
19
|
end
|
22
20
|
|
23
21
|
def get_env
|
24
|
-
if
|
25
|
-
|
26
|
-
|
27
|
-
env = :production if Rails.env.production?
|
28
|
-
else
|
29
|
-
env = :development
|
30
|
-
end
|
31
|
-
env
|
22
|
+
:test if Rails.env.test?
|
23
|
+
:development if Rails.env.development?
|
24
|
+
:production if Rails.env.production?
|
32
25
|
end
|
33
26
|
|
34
|
-
def
|
27
|
+
def load_yaml(file, environment)
|
35
28
|
config = nil
|
36
|
-
require 'yaml'
|
37
29
|
if File.exist?(file)
|
38
30
|
begin
|
39
|
-
envs = YAML::load_file(file)
|
40
|
-
|
41
|
-
|
42
|
-
|
31
|
+
envs = YAML::load_file(file)
|
32
|
+
raise "Could not parse the YAML." if (envs.empty? or (not envs.kind_of?(Hash)))
|
33
|
+
envs = envs.symbolize_keys if envs
|
34
|
+
config = envs[environment].symbolize_keys if (envs && envs[environment])
|
35
|
+
rescue
|
36
|
+
config = nil
|
43
37
|
end
|
38
|
+
config
|
44
39
|
end
|
45
|
-
config
|
46
|
-
end
|
47
40
|
|
48
|
-
def method_missing(name, *args)
|
49
|
-
return @config[name.to_sym]
|
50
41
|
end
|
51
42
|
|
43
|
+
def method_missing(name, *args)
|
44
|
+
return @config[name.to_sym]
|
52
45
|
end
|
46
|
+
|
53
47
|
end
|
54
48
|
end
|
49
|
+
end
|
@@ -3,20 +3,100 @@ module Baurets
|
|
3
3
|
module Introspections
|
4
4
|
|
5
5
|
def self.do_the_matches(path_info)
|
6
|
-
routes =
|
7
|
-
routes.reject!{ |r| r.path == "/rails/info/properties" } # skip the route if it's internal info route
|
6
|
+
routes = gimme_routes
|
8
7
|
allow = ""
|
9
|
-
|
8
|
+
allow = match_verbs_tabajara(path_info)
|
9
|
+
if allow.empty?
|
10
|
+
allow = do_rails_recognition(path_info)
|
11
|
+
end
|
12
|
+
allow
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def self.do_rails_recognition(path_info)
|
18
|
+
allow = ""
|
19
|
+
gimme_routes.each do |route|
|
10
20
|
if path_info =~ route.conditions[:path_info]
|
11
21
|
if route.verb
|
12
22
|
allow += (route.verb.to_s.upcase + "|") unless allow.include?(route.verb.to_s.upcase)
|
13
23
|
else
|
14
|
-
# TODO
|
15
|
-
allow = "GET"
|
24
|
+
allow = "GET" # TODO Return 'ANY' doesn't sound ANY good to me.. ;p
|
16
25
|
end
|
17
26
|
end
|
18
27
|
end
|
19
|
-
allow = allow.split("|").join(", ")
|
28
|
+
allow = allow.split("|").join(", ")
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.match_verbs_tabajara(path_info)
|
32
|
+
routes_paths = build_static_paths
|
33
|
+
route_guess = guess_route(routes_paths,path_info)
|
34
|
+
allow = ""
|
35
|
+
routes_paths.each do |route|
|
36
|
+
if route.first == route_guess
|
37
|
+
allow += (route[1].to_s + "|") unless allow.include?(route[1].to_s.upcase)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
allow = allow.split("|").join(", ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.guess_route(routes, path)
|
44
|
+
guess = []
|
45
|
+
parts = prepare_request_path(path)
|
46
|
+
index = 0
|
47
|
+
parts.each do |part|
|
48
|
+
if is_part_static?(routes, index, part)
|
49
|
+
guess << part
|
50
|
+
else
|
51
|
+
guess << :dynamic
|
52
|
+
end
|
53
|
+
index += 1
|
54
|
+
end
|
55
|
+
guess
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.prepare_request_path(path)
|
59
|
+
path_parts = []
|
60
|
+
path = path[0..(path.rindex('.')-1)] if path.include?('.')
|
61
|
+
path_parts = path.split("/")
|
62
|
+
path_parts.delete("")
|
63
|
+
path_parts
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.is_part_static?(routes, index, value)
|
67
|
+
routes.each do |route|
|
68
|
+
return true if route[0][index] == value
|
69
|
+
end
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.build_static_paths
|
74
|
+
# outputs [["paths"], "VERB"]
|
75
|
+
routes_paths = []
|
76
|
+
gimme_routes.each do |route|
|
77
|
+
raw_parts = route.conditions[:path_info].inspect.split("\/")
|
78
|
+
# TODO Check this carefully
|
79
|
+
raw_parts.delete("")
|
80
|
+
raw_parts.delete("\\A\\")
|
81
|
+
raw_parts.delete("([^\\")
|
82
|
+
raw_parts.pop
|
83
|
+
path_parts = []
|
84
|
+
raw_parts.each do |part|
|
85
|
+
if part =~ /\A(\w+)/
|
86
|
+
path_parts << $1
|
87
|
+
else
|
88
|
+
path_parts << :dynamic
|
89
|
+
end
|
90
|
+
end
|
91
|
+
routes_paths << [path_parts, route.verb.to_s.upcase]
|
92
|
+
end
|
93
|
+
routes_paths
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.gimme_routes
|
97
|
+
routes = Rails.application.routes.routes
|
98
|
+
routes.reject!{ |r| r.path == "/rails/info/properties" } # skip the route if it's internal info route
|
99
|
+
routes
|
20
100
|
end
|
21
101
|
|
22
102
|
end
|
@@ -2,11 +2,17 @@ module Baurets
|
|
2
2
|
module Optionsful
|
3
3
|
class Server
|
4
4
|
|
5
|
+
##
|
6
|
+
# Wakes up!
|
7
|
+
#
|
5
8
|
def initialize(app)
|
6
9
|
@app = app
|
7
10
|
@config = Config.new
|
8
11
|
end
|
9
12
|
|
13
|
+
##
|
14
|
+
# Handle HTTP OPTIONS requests.
|
15
|
+
#
|
10
16
|
def call(env)
|
11
17
|
unless env["REQUEST_METHOD"] == "OPTIONS"
|
12
18
|
@app.call(env)
|
@@ -17,6 +23,10 @@ module Baurets
|
|
17
23
|
end
|
18
24
|
|
19
25
|
private
|
26
|
+
|
27
|
+
def extract_options_information
|
28
|
+
allows = ::Baurets::Optionsful::Introspections.do_the_matches(@env["PATH_INFO"])
|
29
|
+
end
|
20
30
|
|
21
31
|
def build_response
|
22
32
|
allows = extract_options_information
|
@@ -26,7 +36,7 @@ module Baurets
|
|
26
36
|
unless allows.empty?
|
27
37
|
headers.merge!({"Allow" => allows})
|
28
38
|
status = 204
|
29
|
-
if @config.link
|
39
|
+
if @config.link == true
|
30
40
|
headers.merge!({"Link" => build_link_header})
|
31
41
|
end
|
32
42
|
else
|
@@ -51,15 +61,10 @@ module Baurets
|
|
51
61
|
if @config.propagate == true
|
52
62
|
link += @env["PATH_INFO"]
|
53
63
|
end
|
54
|
-
|
55
64
|
link += ">; type=text/html; rel=help\""
|
56
65
|
link
|
57
66
|
end
|
58
67
|
|
59
|
-
def extract_options_information
|
60
|
-
allows = ::Baurets::Optionsful::Introspections.do_the_matches(@env["PATH_INFO"])
|
61
|
-
end
|
62
|
-
|
63
68
|
end
|
64
69
|
end
|
65
70
|
end
|
data/optionsful.gemspec
CHANGED
@@ -5,26 +5,25 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{optionsful}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Marco Antonio Gonzalez Junior"]
|
12
|
-
s.date = %q{2010-08-
|
12
|
+
s.date = %q{2010-08-07}
|
13
13
|
s.description = %q{Help building RESTful web services by supporting the HTTP OPTIONS verb on Ruby on Rails applications.}
|
14
14
|
s.email = %q{kayaman@baurets.net}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.textile"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".autotest",
|
21
21
|
".document",
|
22
22
|
".gitignore",
|
23
23
|
"LICENSE",
|
24
|
-
"README.
|
24
|
+
"README.textile",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
|
-
"config/optionsful.yml",
|
28
27
|
"features/optionsful.feature",
|
29
28
|
"features/step_definitions/optionsful3_steps.rb",
|
30
29
|
"features/support/env.rb",
|
@@ -34,9 +33,9 @@ Gem::Specification.new do |s|
|
|
34
33
|
"lib/optionsful.rb",
|
35
34
|
"optionsful.gemspec",
|
36
35
|
"rails/init.rb",
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"
|
36
|
+
"samples/optionsful.yml.sample",
|
37
|
+
"samples/optionsful_bug.yml",
|
38
|
+
"samples/optionsful_true.yml",
|
40
39
|
"spec/fake_app.rb",
|
41
40
|
"spec/optionsful_config_spec.rb",
|
42
41
|
"spec/optionsful_server_spec.rb",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Optionsful custom settings
|
2
|
+
|
3
|
+
# Link header configuration
|
4
|
+
development:
|
5
|
+
link: false
|
6
|
+
host: auto
|
7
|
+
base_path: /api
|
8
|
+
propagate: true
|
9
|
+
|
10
|
+
test:
|
11
|
+
link: false
|
12
|
+
host: auto
|
13
|
+
base_path: /api
|
14
|
+
propagate: false
|
15
|
+
|
16
|
+
production:
|
17
|
+
link: false
|
18
|
+
host: auto
|
19
|
+
base_path: /api
|
20
|
+
propagate: false
|
@@ -0,0 +1 @@
|
|
1
|
+
> 62532532836523ugwsgvzbvciueyrouoskzjh %=$ ;;;'''
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Optionsful custom settings
|
2
|
+
|
3
|
+
# Link header configuration
|
4
|
+
development:
|
5
|
+
link: true
|
6
|
+
host: auto
|
7
|
+
base_path: /api
|
8
|
+
propagate: true
|
9
|
+
|
10
|
+
test:
|
11
|
+
link: true
|
12
|
+
host: auto
|
13
|
+
base_path: /api
|
14
|
+
propagate: false
|
15
|
+
|
16
|
+
production:
|
17
|
+
link: true
|
18
|
+
host: auto
|
19
|
+
base_path: /api
|
20
|
+
propagate: false
|
@@ -1,46 +1,75 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
4
3
|
describe Baurets::Optionsful::Config do
|
5
4
|
|
6
5
|
include Rack::Test::Methods
|
7
6
|
|
8
7
|
context "Config carries specific settings" do
|
9
|
-
|
10
|
-
describe "when there's
|
11
|
-
|
8
|
+
|
9
|
+
describe "when there's NO custom config file, use expected default settings" do
|
10
|
+
|
12
11
|
it "the Link header generation must be disabled" do
|
13
12
|
config = Baurets::Optionsful::Config.new("file_error.txt")
|
14
13
|
config.link.should be false
|
15
14
|
end
|
16
|
-
|
15
|
+
|
17
16
|
end
|
18
|
-
|
17
|
+
|
19
18
|
describe "when there is a custom config file, load the settings from it" do
|
20
|
-
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@config = nil
|
22
|
+
end
|
23
|
+
|
21
24
|
it "the Link header generation must be disabled" do
|
22
|
-
|
23
|
-
config
|
24
|
-
|
25
|
+
@config = Baurets::Optionsful::Config.new()
|
26
|
+
@config.link.should be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "the Link header generation must be disabled (file found but looks corrupted!)" do
|
30
|
+
FileUtils.cp File.join(Rails.root, 'samples', 'optionsful_bug.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
31
|
+
@config = Baurets::Optionsful::Config.new
|
32
|
+
@config.link.should == false
|
33
|
+
end
|
34
|
+
|
35
|
+
it "the Link header generation must be disabled (file given but looks corrupted!)" do
|
36
|
+
@config = Baurets::Optionsful::Config.new(File.join(Rails.root, 'samples', 'optionsful_bug.yml'))
|
37
|
+
@config.link.should be false
|
25
38
|
end
|
26
39
|
|
27
40
|
it "the Link header generation must be enabled" do
|
28
|
-
config = Baurets::Optionsful::Config.new(
|
29
|
-
config.link.should be true
|
41
|
+
@config = Baurets::Optionsful::Config.new(nil, {:link => true})
|
42
|
+
@config.link.should be true
|
30
43
|
end
|
31
|
-
|
44
|
+
|
45
|
+
it "the Link header generation must be enabled (file found)" do
|
46
|
+
FileUtils.cp File.join(Rails.root, 'samples', 'optionsful_true.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
47
|
+
@config = Baurets::Optionsful::Config.new()
|
48
|
+
@config.link.should be true
|
49
|
+
end
|
50
|
+
|
32
51
|
it "if the Link header generation is enabled, host value must be set" do
|
33
|
-
config = Baurets::Optionsful::Config.new(File.join(
|
34
|
-
config.link.should be true
|
35
|
-
config.host.empty?.should_not be true
|
52
|
+
@config = Baurets::Optionsful::Config.new(File.join(Rails.root, 'samples', 'optionsful_true.yml'))
|
53
|
+
@config.link.should be true
|
54
|
+
@config.host.empty?.should_not be true
|
36
55
|
end
|
37
|
-
|
56
|
+
|
38
57
|
it "if the Link header generation is enabled, host value accepts 'auto'" do
|
39
|
-
config = Baurets::Optionsful::Config.new(File.join(File.dirname(__FILE__), 'config', 'optionsful_host_auto.yml'))
|
40
|
-
config.link.should be true
|
41
|
-
config.host.should == "auto"
|
58
|
+
@config = Baurets::Optionsful::Config.new(File.join(File.dirname(__FILE__), 'config', 'optionsful_host_auto.yml'))
|
59
|
+
@config.link.should be true
|
60
|
+
@config.host.should == "auto"
|
61
|
+
end
|
62
|
+
|
63
|
+
after(:each) do
|
64
|
+
FileUtils.rm [File.join(Rails.root, 'config', 'optionsful.yml')] if File.exist? File.join(Rails.root, 'config', 'optionsful.yml')
|
65
|
+
@config = nil
|
42
66
|
end
|
43
67
|
|
68
|
+
after(:all) do
|
69
|
+
FileUtils.rm [File.join(Rails.root, 'config', 'optionsful.yml')] if File.exist? File.join(Rails.root, 'config', 'optionsful.yml')
|
70
|
+
@config = nil
|
71
|
+
end
|
72
|
+
|
44
73
|
end
|
45
74
|
|
46
75
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
include Rack::Test::Methods
|
3
|
-
require 'fileutils'
|
4
3
|
|
5
4
|
describe "Optionsful" do
|
6
5
|
|
@@ -177,7 +176,6 @@ describe "Optionsful" do
|
|
177
176
|
end
|
178
177
|
|
179
178
|
it "the parent resource collection have an entry point for creating a new entry" do
|
180
|
-
pending "check regexp"
|
181
179
|
response = http_options_request("/products/new")
|
182
180
|
validate_response(response)
|
183
181
|
response[0].should be 204
|
@@ -247,7 +245,6 @@ describe "Optionsful" do
|
|
247
245
|
end
|
248
246
|
|
249
247
|
it "the sub-resource collection have an entry point for creating a new entry" do
|
250
|
-
pending "check regexp"
|
251
248
|
response = http_options_request("/products/123/sales/new")
|
252
249
|
validate_response(response)
|
253
250
|
response[0].should be 204
|
@@ -391,11 +388,9 @@ describe "Optionsful" do
|
|
391
388
|
|
392
389
|
end
|
393
390
|
|
394
|
-
|
395
|
-
|
396
391
|
end
|
397
392
|
|
398
|
-
context "Link" do
|
393
|
+
context "the Link header" do
|
399
394
|
|
400
395
|
describe "should not be present" do
|
401
396
|
|
@@ -403,12 +398,12 @@ describe "Optionsful" do
|
|
403
398
|
rails_app.routes.draw do
|
404
399
|
resources :posts
|
405
400
|
end
|
401
|
+
::Baurets::Optionsful::Config.new
|
406
402
|
end
|
407
403
|
|
408
404
|
it "if no directions were given" do
|
409
|
-
|
405
|
+
Baurets::Optionsful::Config.new(nil, {:link => false})
|
410
406
|
response = http_options_request("/posts")
|
411
|
-
FileUtils.mv File.join(Rails.root, 'optionsful.yml'), File.join(Rails.root, 'config', 'optionsful.yml')
|
412
407
|
validate_response(response)
|
413
408
|
response[0].should be 204
|
414
409
|
response[1]["Link"].should be nil
|
@@ -429,12 +424,49 @@ describe "Optionsful" do
|
|
429
424
|
end
|
430
425
|
|
431
426
|
it "the Link header MUST be quoted if it contains a semicolon or comma" do
|
427
|
+
Baurets::Optionsful::Config.new(nil, {:link => true})
|
432
428
|
response = http_options_request("/posts")
|
433
429
|
validate_response(response)
|
434
430
|
response[0].should be 204
|
435
431
|
link = response[1]["Link"]
|
436
432
|
link.should match /\A\".+\"\z/
|
437
433
|
end
|
434
|
+
|
435
|
+
it "the Link header may use its very current host" do
|
436
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'auto'})
|
437
|
+
response = http_options_request("/posts")
|
438
|
+
validate_response(response)
|
439
|
+
response[0].should be 204
|
440
|
+
link = response[1]["Link"]
|
441
|
+
link.should match /\A\"<http:\/\/localhost.+\"\z/
|
442
|
+
end
|
443
|
+
|
444
|
+
it "the Link header may use a custom host value" do
|
445
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net'})
|
446
|
+
response = http_options_request("/posts")
|
447
|
+
validate_response(response)
|
448
|
+
response[0].should be 204
|
449
|
+
link = response[1]["Link"]
|
450
|
+
link.should match /\A\"<http:\/\/www.baurets.net.+\"\z/
|
451
|
+
end
|
452
|
+
|
453
|
+
it "the Link header may use a custom base path value" do
|
454
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net', :base_path => "/private/api/"})
|
455
|
+
response = http_options_request("/posts")
|
456
|
+
validate_response(response)
|
457
|
+
response[0].should be 204
|
458
|
+
link = response[1]["Link"]
|
459
|
+
link.should match /\A\"<http:\/\/www.baurets.net\/private\/api\/.+\"\z/
|
460
|
+
end
|
461
|
+
|
462
|
+
it "the Link header may propagate original path info" do
|
463
|
+
Baurets::Optionsful::Config.new(nil, {:link => true, :host => 'www.baurets.net', :base_path => "/private/api/", :propagate => true})
|
464
|
+
response = http_options_request("/posts")
|
465
|
+
validate_response(response)
|
466
|
+
response[0].should be 204
|
467
|
+
link = response[1]["Link"]
|
468
|
+
link.should match /\A\"<http:\/\/www.baurets.net\/private\/api\/\/posts.+\"\z/
|
469
|
+
end
|
438
470
|
|
439
471
|
after(:all) do
|
440
472
|
Rails.application.reload_routes!
|
data/spec/spec.opts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color
|
1
|
+
--color --debugger
|
data/spec/spec_helper.rb
CHANGED
data/tasks/optionsful.rake
CHANGED
@@ -4,7 +4,7 @@ require 'rake'
|
|
4
4
|
namespace :optionsful do
|
5
5
|
desc "Install 'config/optionsful.yml'"
|
6
6
|
task :yml do
|
7
|
-
FileUtils.cp File.join(Baurets::Optionsful::LIB_ROOT, '..','
|
7
|
+
FileUtils.cp File.join(Baurets::Optionsful::LIB_ROOT, '..','samples', 'optionsful.yml.sample'), File.join(Rails.root, 'config', 'optionsful.yml')
|
8
8
|
puts "\nNow you are able to configure Link hader generation settings"
|
9
9
|
puts "\nEdit the file 'config/optionsful.yml' on your Rails application."
|
10
10
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optionsful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Marco Antonio Gonzalez Junior
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-07 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -87,16 +87,15 @@ extensions: []
|
|
87
87
|
|
88
88
|
extra_rdoc_files:
|
89
89
|
- LICENSE
|
90
|
-
- README.
|
90
|
+
- README.textile
|
91
91
|
files:
|
92
92
|
- .autotest
|
93
93
|
- .document
|
94
94
|
- .gitignore
|
95
95
|
- LICENSE
|
96
|
-
- README.
|
96
|
+
- README.textile
|
97
97
|
- Rakefile
|
98
98
|
- VERSION
|
99
|
-
- config/optionsful.yml
|
100
99
|
- features/optionsful.feature
|
101
100
|
- features/step_definitions/optionsful3_steps.rb
|
102
101
|
- features/support/env.rb
|
@@ -106,9 +105,9 @@ files:
|
|
106
105
|
- lib/optionsful.rb
|
107
106
|
- optionsful.gemspec
|
108
107
|
- rails/init.rb
|
109
|
-
-
|
110
|
-
-
|
111
|
-
-
|
108
|
+
- samples/optionsful.yml.sample
|
109
|
+
- samples/optionsful_bug.yml
|
110
|
+
- samples/optionsful_true.yml
|
112
111
|
- spec/fake_app.rb
|
113
112
|
- spec/optionsful_config_spec.rb
|
114
113
|
- spec/optionsful_server_spec.rb
|
data/README.rdoc
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
= optionsful3
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
-
* Send me a pull request. Bonus points for topic branches.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2010 Marco Antonio Gonzalez Junior. See LICENSE for details.
|
data/config/optionsful.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
data/spec/config/optionsful.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: true
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: true
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: true
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
development:
|
3
|
-
link: false
|
4
|
-
host: auto
|
5
|
-
base_path: /blopts
|
6
|
-
propagate: false
|
7
|
-
|
8
|
-
test:
|
9
|
-
link: false
|
10
|
-
host: auto
|
11
|
-
base_path: /blopts
|
12
|
-
propagate: false
|
13
|
-
|
14
|
-
production:
|
15
|
-
link: false
|
16
|
-
host: auto
|
17
|
-
base_path: /blopts
|
18
|
-
propagate: false
|