otto 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-