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.
@@ -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.2
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 build 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 method.
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 'hanna/rdoctask'
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
- Rake::RDocTask.new do |rdoc|
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}"
@@ -1,3 +1,3 @@
1
1
  :MAJOR: 0
2
2
  :MINOR: 3
3
- :PATCH: 0
3
+ :PATCH: 1
@@ -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
@@ -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) && client_ipaddress == '127.0.0.1'
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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "otto"
8
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Delano Mandelbaum"]
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
- date: 2011-12-20 00:00:00 Z
14
- dependencies:
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
- prerelease: false
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- version_requirements: *id002
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: "0"
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: "0"
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
-