otto 0.3.0 → 0.3.1
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.
- data/CHANGES.txt +7 -0
- data/README.md +2 -2
- data/Rakefile +3 -3
- data/VERSION.yml +1 -1
- data/example/routes +2 -0
- data/lib/otto.rb +28 -19
- data/otto.gemspec +1 -1
- metadata +33 -40
data/CHANGES.txt
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
OTTO, CHANGES
|
2
2
|
|
3
|
+
#### 0.3.1 (2012-12-17) ###############################
|
4
|
+
|
5
|
+
* ADDED: Otto.debug (set w/ Otto.debug= or env variable OTTO_DEBUG)
|
6
|
+
* ADDED: RequestHelpers#ajax?
|
7
|
+
* CHANGE: Added internal subnets to RequestHelpers#local?
|
8
|
+
|
9
|
+
|
3
10
|
#### 0.3.0 (2011-12-17) ###############################
|
4
11
|
|
5
12
|
* ADDED: Example app, better docs in readme
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
# Otto - 0.
|
1
|
+
# Otto - 0.3
|
2
2
|
|
3
3
|
**Auto-define your rack-apps in plain-text.**
|
4
4
|
|
5
5
|
## Overview ##
|
6
6
|
|
7
|
-
Apps
|
7
|
+
Apps built with Otto have three, basic parts: a rackup file, a ruby file, and a routes file. If you've built a [Rack app](http://rack.rubyforge.org/) before, then you've seen a rackup file before. The ruby file is your actual app and the routes file is what Otto uses to map URI paths to a Ruby class and method.
|
8
8
|
|
9
9
|
A barebones app directory looks something like this:
|
10
10
|
|
data/Rakefile
CHANGED
@@ -3,8 +3,8 @@ require "rake"
|
|
3
3
|
require "rake/clean"
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
-
require '
|
7
|
-
|
6
|
+
require 'rdoc/task'
|
7
|
+
|
8
8
|
config = YAML.load_file("VERSION.yml")
|
9
9
|
task :default => ["build"]
|
10
10
|
CLEAN.include [ 'pkg', 'doc' ]
|
@@ -30,7 +30,7 @@ rescue LoadError
|
|
30
30
|
end
|
31
31
|
|
32
32
|
|
33
|
-
|
33
|
+
RDoc::Task.new do |rdoc|
|
34
34
|
version = "#{config[:MAJOR]}.#{config[:MINOR]}.#{config[:PATCH]}"
|
35
35
|
rdoc.rdoc_dir = "doc"
|
36
36
|
rdoc.title = "otto #{version}"
|
data/VERSION.yml
CHANGED
data/example/routes
CHANGED
@@ -11,6 +11,8 @@ GET /redirect App#redirect
|
|
11
11
|
GET /robots.txt App#robots_text
|
12
12
|
GET /product/:prodid App#display_product
|
13
13
|
|
14
|
+
GET /bogus App#no_such_method
|
15
|
+
|
14
16
|
# You can also define these handlers when no
|
15
17
|
# route can be found or there's a server error. (optional)
|
16
18
|
GET /404 App#not_found
|
data/lib/otto.rb
CHANGED
@@ -5,8 +5,9 @@ require 'rack/utils'
|
|
5
5
|
require 'addressable/uri'
|
6
6
|
|
7
7
|
class Otto
|
8
|
+
@debug = ENV['OTTO_DEBUG'] == 'true'
|
8
9
|
LIB_HOME = File.expand_path File.dirname(__FILE__) unless defined?(Otto::LIB_HOME)
|
9
|
-
|
10
|
+
|
10
11
|
module VERSION
|
11
12
|
def self.to_s
|
12
13
|
load_config
|
@@ -49,7 +50,7 @@ class Otto
|
|
49
50
|
route.otto = self
|
50
51
|
path_clean = path.gsub /\/$/, ''
|
51
52
|
@route_definitions[route.definition] = route
|
52
|
-
STDERR.puts "route: #{route.pattern}"
|
53
|
+
STDERR.puts "route: #{route.pattern}" if Otto.debug
|
53
54
|
@routes[route.verb] ||= []
|
54
55
|
@routes[route.verb] << route
|
55
56
|
@routes_literal[route.verb] ||= {}
|
@@ -66,25 +67,25 @@ class Otto
|
|
66
67
|
pathstr = File.join(option[:public], path)
|
67
68
|
File.fnmatch?(globstr, pathstr) && (File.owned?(pathstr) || File.grpowned?(pathstr)) && File.readable?(pathstr) && !File.directory?(pathstr)
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
def safe_dir? path
|
71
72
|
(File.owned?(path) || File.grpowned?(path)) && File.directory?(path)
|
72
73
|
end
|
73
|
-
|
74
|
+
|
74
75
|
def add_static_path path
|
75
76
|
if safe_file?(path)
|
76
77
|
base_path = File.split(path).first
|
77
78
|
# Files in the root directory can refer to themselves
|
78
79
|
base_path = path if base_path == '/'
|
79
80
|
static_path = File.join(option[:public], base_path)
|
80
|
-
STDERR.puts "new static route: #{base_path} (#{path})"
|
81
|
+
STDERR.puts "new static route: #{base_path} (#{path})" if Otto.debug
|
81
82
|
routes_static[:GET][base_path] = base_path
|
82
83
|
end
|
83
84
|
end
|
84
|
-
|
85
|
+
|
85
86
|
def call env
|
86
87
|
if option[:public] && safe_dir?(option[:public])
|
87
|
-
@static_route ||= Rack::File.new(option[:public])
|
88
|
+
@static_route ||= Rack::File.new(option[:public])
|
88
89
|
end
|
89
90
|
path_info = Rack::Utils.unescape(env['PATH_INFO'])
|
90
91
|
path_info = '/' if path_info.to_s.empty?
|
@@ -112,7 +113,7 @@ class Otto
|
|
112
113
|
found_route = nil
|
113
114
|
valid_routes = routes[http_verb] || []
|
114
115
|
valid_routes.push *routes[:GET] if http_verb == :HEAD
|
115
|
-
valid_routes.each { |route|
|
116
|
+
valid_routes.each { |route|
|
116
117
|
#STDERR.puts " request: #{http_verb} #{path_info} (trying route: #{route.verb} #{route.pattern})"
|
117
118
|
if (match = route.pattern.match(path_info))
|
118
119
|
values = match.captures.to_a
|
@@ -154,8 +155,8 @@ class Otto
|
|
154
155
|
@server_error || Otto::Static.server_error
|
155
156
|
end
|
156
157
|
end
|
157
|
-
|
158
|
-
|
158
|
+
|
159
|
+
|
159
160
|
# Return the URI path for the given +route_definition+
|
160
161
|
# e.g.
|
161
162
|
#
|
@@ -172,7 +173,7 @@ class Otto
|
|
172
173
|
end
|
173
174
|
local_params.each_pair { |k,v|
|
174
175
|
next unless local_path.match(":#{k}")
|
175
|
-
local_path.gsub!(":#{k}", local_params.delete(k))
|
176
|
+
local_path.gsub!(":#{k}", local_params.delete(k))
|
176
177
|
}
|
177
178
|
uri = Addressable::URI.new
|
178
179
|
uri.path = local_path
|
@@ -180,7 +181,7 @@ class Otto
|
|
180
181
|
uri.to_s
|
181
182
|
end
|
182
183
|
end
|
183
|
-
|
184
|
+
|
184
185
|
module Static
|
185
186
|
extend self
|
186
187
|
def server_error
|
@@ -213,7 +214,7 @@ class Otto
|
|
213
214
|
end
|
214
215
|
end
|
215
216
|
#
|
216
|
-
# e.g.
|
217
|
+
# e.g.
|
217
218
|
#
|
218
219
|
# GET /uri/path YourApp.method
|
219
220
|
# GET /uri/path2 YourApp#method
|
@@ -300,6 +301,7 @@ class Otto
|
|
300
301
|
end
|
301
302
|
end
|
302
303
|
class << self
|
304
|
+
attr_accessor :debug
|
303
305
|
def default
|
304
306
|
@default ||= Otto.new
|
305
307
|
@default
|
@@ -325,7 +327,7 @@ class Otto
|
|
325
327
|
# and it can take the form: 74.121.244.2, 10.252.130.147
|
326
328
|
# HTTP_X_REAL_IP is from nginx
|
327
329
|
# REMOTE_ADDR is from thin
|
328
|
-
# There's no way to get the client IP address in HTTPS.
|
330
|
+
# There's no way to get the client IP address in HTTPS.
|
329
331
|
def client_ipaddress
|
330
332
|
env['HTTP_X_FORWARDED_FOR'].to_s.split(/,\s*/).first ||
|
331
333
|
env['HTTP_X_REAL_IP'] || env['REMOTE_ADDR']
|
@@ -356,13 +358,20 @@ class Otto
|
|
356
358
|
[prefix, host, request_path].join
|
357
359
|
end
|
358
360
|
def local?
|
359
|
-
Otto.env?(:dev, :development) &&
|
361
|
+
Otto.env?(:dev, :development) &&
|
362
|
+
(client_ipaddress == '127.0.0.1' ||
|
363
|
+
!client_ipaddress.match(/^10\.0\./).nil? ||
|
364
|
+
!client_ipaddress.match(/^192\.168\./).nil?)
|
360
365
|
end
|
361
366
|
def secure?
|
362
367
|
# X-Scheme is set by nginx
|
363
368
|
# X-FORWARDED-PROTO is set by elastic load balancer
|
364
369
|
(env['HTTP_X_FORWARDED_PROTO'] == 'https' || env['HTTP_X_SCHEME'] == "https")
|
365
|
-
end
|
370
|
+
end
|
371
|
+
# See: http://stackoverflow.com/questions/10013812/how-to-prevent-jquery-ajax-from-following-a-redirect-after-a-post
|
372
|
+
def ajax?
|
373
|
+
env['HTTP_X_REQUESTED_WITH'].to_s.downcase == 'xmlhttprequest'
|
374
|
+
end
|
366
375
|
def cookie name
|
367
376
|
cookies[name.to_s]
|
368
377
|
end
|
@@ -382,8 +391,8 @@ class Otto
|
|
382
391
|
def send_cookie name, value, ttl, secure=true
|
383
392
|
secure = false if request.local?
|
384
393
|
opts = {
|
385
|
-
:value => value,
|
386
|
-
:path => '/',
|
394
|
+
:value => value,
|
395
|
+
:path => '/',
|
387
396
|
:expires => (Time.now + ttl + 10).utc,
|
388
397
|
:secure => secure
|
389
398
|
}
|
@@ -395,4 +404,4 @@ class Otto
|
|
395
404
|
send_cookie name, nil, -1.day
|
396
405
|
end
|
397
406
|
end
|
398
|
-
end
|
407
|
+
end
|
data/otto.gemspec
CHANGED
metadata
CHANGED
@@ -1,49 +1,46 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: otto
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
4
5
|
prerelease:
|
5
|
-
version: 0.3.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Delano Mandelbaum
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-12-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: rack
|
17
|
-
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70311787119140 !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
21
|
-
- -
|
22
|
-
- !ruby/object:Gem::Version
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 1.2.1
|
24
22
|
type: :runtime
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: addressable
|
28
23
|
prerelease: false
|
29
|
-
|
24
|
+
version_requirements: *70311787119140
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: addressable
|
27
|
+
requirement: &70311787118660 !ruby/object:Gem::Requirement
|
30
28
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
34
32
|
version: 2.2.6
|
35
33
|
type: :runtime
|
36
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70311787118660
|
37
36
|
description: Auto-define your rack-apps in plaintext.
|
38
37
|
email: delano@solutious.com
|
39
38
|
executables: []
|
40
|
-
|
41
39
|
extensions: []
|
42
|
-
|
43
|
-
extra_rdoc_files:
|
40
|
+
extra_rdoc_files:
|
44
41
|
- LICENSE.txt
|
45
42
|
- README.md
|
46
|
-
files:
|
43
|
+
files:
|
47
44
|
- CHANGES.txt
|
48
45
|
- LICENSE.txt
|
49
46
|
- README.md
|
@@ -58,30 +55,26 @@ files:
|
|
58
55
|
- otto.gemspec
|
59
56
|
homepage: http://github.com/delano/otto
|
60
57
|
licenses: []
|
61
|
-
|
62
58
|
post_install_message:
|
63
59
|
rdoc_options: []
|
64
|
-
|
65
|
-
require_paths:
|
60
|
+
require_paths:
|
66
61
|
- lib
|
67
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
63
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version:
|
73
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
69
|
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version:
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
79
74
|
requirements: []
|
80
|
-
|
81
75
|
rubyforge_project: otto
|
82
76
|
rubygems_version: 1.8.10
|
83
77
|
signing_key:
|
84
78
|
specification_version: 3
|
85
79
|
summary: Auto-define your rack-apps in plaintext.
|
86
80
|
test_files: []
|
87
|
-
|