optionsful 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +15 -0
- data/README.textile +60 -0
- data/lib/optionsful.rb +89 -0
- data/rails/init.rb +2 -0
- metadata +70 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (c) 2010 Marco Antonio Gonzalez Junior (kayaman@baurets.net).
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
5
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
6
|
+
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
7
|
+
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
9
|
+
of the Software.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
12
|
+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
13
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
14
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
15
|
+
DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
h1. Rails OPTIONSful
|
2
|
+
|
3
|
+
Provide dynamic information about resources via the OPTIONS' HTTP method on a RESTful design over 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
|
+
h2. "-No! No! No! *-Show me the code!*"
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
|
13
|
+
$ telnet kayaman.baurets.net 3000
|
14
|
+
OPTIONS /notes HTTP/1.1
|
15
|
+
Host: kayaman.baurets.net
|
16
|
+
|
17
|
+
HTTP/1.1 204 No Content
|
18
|
+
Allow: GET, POST
|
19
|
+
Date: Sat, 10 Jul 2010 23:46:00 GMT
|
20
|
+
Link: <http://baurets.net/api/resources>; type=text/html; rel=help
|
21
|
+
|
22
|
+
OPTIONS /notes/1 HTTP/1.1
|
23
|
+
Host: kayaman.baurets.net
|
24
|
+
|
25
|
+
HTTP/1.1 204 No Content
|
26
|
+
Allow: GET, PUT, DELETE
|
27
|
+
Date: Sat, 10 Jul 2010 23:47:47 GMT
|
28
|
+
Link: <http://baurets.net/api/resources>; type=text/html; rel=help
|
29
|
+
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
~Note the empty line which is part of the HTTP protocol.~
|
33
|
+
|
34
|
+
h2. INSTALLATION:
|
35
|
+
|
36
|
+
# Change directory to your Ruby on Rails web application,
|
37
|
+
# Run:
|
38
|
+
<pre>
|
39
|
+
$ script/plugin install git://github.com/kayaman/optionsful.git
|
40
|
+
</pre>
|
41
|
+
# Have fun!
|
42
|
+
|
43
|
+
h2. TODO & WHISH-LIST
|
44
|
+
* -Make the installation easier.-
|
45
|
+
* Create tests! (Oh no! Psst! Don't tell anyone!)
|
46
|
+
* Research if there are means to know whether formats (types) each one of available methods can accept and serve - WHY NOT make use of BRUTE FORCE? 8-D - We Will Rock You approach - IT WILL BE ANOTHER PROJECT?
|
47
|
+
* Provide on demand human readable documentation (maybe attribute oriented programming) hopefully supporting the _about to be given_ @Link@ HTTP header
|
48
|
+
* -Implement instrumentation, logging - (really needed?)-
|
49
|
+
* -Research if there are means to test authorization, if Authorization header provided in the request- OUT_OF_SCOPE
|
50
|
+
|
51
|
+
|
52
|
+
h2. KNOWN ISSUES
|
53
|
+
* -Rails route recognition need hard work-
|
54
|
+
* Platform: ruby 1.8.7, rails 2.3.8, rack 1.2.1
|
55
|
+
|
56
|
+
h2. CONTRIBUTORS
|
57
|
+
* Me, myself and I, so far.
|
58
|
+
* You are welcome, do it. ;-)
|
59
|
+
|
60
|
+
Copyright (c) 2010 Marco Antonio Gonzalez Junior, kayaman@baurets.net, released under the MIT license.
|
data/lib/optionsful.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
class Optionsful
|
2
|
+
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
unless env["REQUEST_METHOD"] == "OPTIONS"
|
9
|
+
@app.call(env)
|
10
|
+
else
|
11
|
+
extract_options_information(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def extract_options_information(env)
|
18
|
+
[204, {"Allow" => extract_allowed_methods(env), "Link" => build_help_link}, ""]
|
19
|
+
end
|
20
|
+
|
21
|
+
def extract_allowed_methods(env)
|
22
|
+
# do routing introspection:
|
23
|
+
routes = do_routing_introspection
|
24
|
+
# do request path investigation
|
25
|
+
route_guess = guess_route(routes, env["PATH_INFO"])
|
26
|
+
allows = ""
|
27
|
+
# do the matches:
|
28
|
+
routes.each do |route|
|
29
|
+
if route.first == route_guess
|
30
|
+
allows += route[1].to_s.upcase! + "|"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
allows = allows.split("|").join(", ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_help_link
|
37
|
+
#PENDING
|
38
|
+
"<http://baurets.net/api/resources>; type=text/html; rel=help"
|
39
|
+
end
|
40
|
+
|
41
|
+
def guess_route(routes, path)
|
42
|
+
parts = prepare_request_path(path)
|
43
|
+
guess = []
|
44
|
+
index = 0
|
45
|
+
parts.each do |part|
|
46
|
+
if is_part_static?(routes, index, part)
|
47
|
+
guess << part
|
48
|
+
else
|
49
|
+
guess << :dynamic
|
50
|
+
end
|
51
|
+
index += 1
|
52
|
+
end
|
53
|
+
guess
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_part_static?(routes, index, value)
|
57
|
+
routes.each do |route|
|
58
|
+
if route[0][index] == value
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
|
65
|
+
def do_routing_introspection
|
66
|
+
routes = []
|
67
|
+
ActionController::Routing::Routes.routes.each do |route|
|
68
|
+
static_path = []
|
69
|
+
route.segments.each do |segment|
|
70
|
+
if segment.kind_of?(ActionController::Routing::StaticSegment)
|
71
|
+
static_path << segment.value if (segment.respond_to?(:value) && segment.value != "/")
|
72
|
+
elsif segment.kind_of?(ActionController::Routing::DynamicSegment)
|
73
|
+
#TODO ignoring (.:format), think about it:
|
74
|
+
static_path << :dynamic unless (segment.respond_to?(:key) && segment.key == :format)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
routes << [static_path, route.conditions[:method]] unless route.conditions[:method].nil?
|
78
|
+
end
|
79
|
+
routes
|
80
|
+
end
|
81
|
+
|
82
|
+
def prepare_request_path(path)
|
83
|
+
path = path[0..(path.rindex('.')-1)] if path.include?('.') #TODO ignoring (.:format), think about it
|
84
|
+
path_parts = path.split("/")
|
85
|
+
path_parts.delete("")
|
86
|
+
path_parts
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
data/rails/init.rb
ADDED
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: optionsful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Marco Antonio Gonzalez Junior
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-15 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Optionsful provide dynamic information via HTTP's OPTION method.
|
23
|
+
email: kayaman@baurets.net
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- README.textile
|
32
|
+
- MIT-LICENSE
|
33
|
+
- lib/optionsful.rb
|
34
|
+
- rails/init.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://optionsful.rubyforge.org
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
hash: 3
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.7
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Optionsful provide dynamic information via HTTP's OPTION method over a Ruby on Rails applications.
|
69
|
+
test_files: []
|
70
|
+
|