raw 0.49.0
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/doc/CONTRIBUTORS +106 -0
- data/doc/LICENSE +32 -0
- data/doc/coding_conventions.txt +11 -0
- data/lib/raw.rb +42 -0
- data/lib/raw/adapter.rb +113 -0
- data/lib/raw/adapter/cgi.rb +41 -0
- data/lib/raw/adapter/fastcgi.rb +48 -0
- data/lib/raw/adapter/mongrel.rb +146 -0
- data/lib/raw/adapter/script.rb +94 -0
- data/lib/raw/adapter/webrick.rb +144 -0
- data/lib/raw/adapter/webrick/vcr.rb +91 -0
- data/lib/raw/cgi.rb +323 -0
- data/lib/raw/cgi/cookie.rb +47 -0
- data/lib/raw/cgi/http.rb +62 -0
- data/lib/raw/compiler.rb +138 -0
- data/lib/raw/compiler/filter/cleanup.rb +21 -0
- data/lib/raw/compiler/filter/elements.rb +166 -0
- data/lib/raw/compiler/filter/elements/element.rb +210 -0
- data/lib/raw/compiler/filter/localization.rb +23 -0
- data/lib/raw/compiler/filter/markup.rb +32 -0
- data/lib/raw/compiler/filter/morph.rb +123 -0
- data/lib/raw/compiler/filter/morph/each.rb +34 -0
- data/lib/raw/compiler/filter/morph/for.rb +11 -0
- data/lib/raw/compiler/filter/morph/if.rb +26 -0
- data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
- data/lib/raw/compiler/filter/morph/standard.rb +55 -0
- data/lib/raw/compiler/filter/morph/times.rb +27 -0
- data/lib/raw/compiler/filter/script.rb +116 -0
- data/lib/raw/compiler/filter/squeeze.rb +16 -0
- data/lib/raw/compiler/filter/static_include.rb +74 -0
- data/lib/raw/compiler/filter/template.rb +121 -0
- data/lib/raw/compiler/reloader.rb +96 -0
- data/lib/raw/context.rb +154 -0
- data/lib/raw/context/flash.rb +157 -0
- data/lib/raw/context/global.rb +88 -0
- data/lib/raw/context/request.rb +338 -0
- data/lib/raw/context/response.rb +57 -0
- data/lib/raw/context/session.rb +198 -0
- data/lib/raw/context/session/drb.rb +11 -0
- data/lib/raw/context/session/file.rb +15 -0
- data/lib/raw/context/session/memcached.rb +13 -0
- data/lib/raw/context/session/memory.rb +12 -0
- data/lib/raw/context/session/og.rb +15 -0
- data/lib/raw/context/session/pstore.rb +13 -0
- data/lib/raw/control.rb +18 -0
- data/lib/raw/control/attribute.rb +91 -0
- data/lib/raw/control/attribute/checkbox.rb +25 -0
- data/lib/raw/control/attribute/datetime.rb +21 -0
- data/lib/raw/control/attribute/file.rb +20 -0
- data/lib/raw/control/attribute/fixnum.rb +26 -0
- data/lib/raw/control/attribute/float.rb +26 -0
- data/lib/raw/control/attribute/options.rb +38 -0
- data/lib/raw/control/attribute/password.rb +16 -0
- data/lib/raw/control/attribute/text.rb +16 -0
- data/lib/raw/control/attribute/textarea.rb +16 -0
- data/lib/raw/control/none.rb +16 -0
- data/lib/raw/control/relation.rb +59 -0
- data/lib/raw/control/relation/belongs_to.rb +0 -0
- data/lib/raw/control/relation/has_many.rb +97 -0
- data/lib/raw/control/relation/joins_many.rb +0 -0
- data/lib/raw/control/relation/many_to_many.rb +0 -0
- data/lib/raw/control/relation/refers_to.rb +29 -0
- data/lib/raw/controller.rb +37 -0
- data/lib/raw/controller/publishable.rb +160 -0
- data/lib/raw/dispatcher.rb +209 -0
- data/lib/raw/dispatcher/format.rb +108 -0
- data/lib/raw/dispatcher/format/atom.rb +31 -0
- data/lib/raw/dispatcher/format/css.rb +0 -0
- data/lib/raw/dispatcher/format/html.rb +42 -0
- data/lib/raw/dispatcher/format/json.rb +31 -0
- data/lib/raw/dispatcher/format/rss.rb +33 -0
- data/lib/raw/dispatcher/format/xoxo.rb +31 -0
- data/lib/raw/dispatcher/mounter.rb +60 -0
- data/lib/raw/dispatcher/router.rb +111 -0
- data/lib/raw/errors.rb +19 -0
- data/lib/raw/helper.rb +86 -0
- data/lib/raw/helper/benchmark.rb +23 -0
- data/lib/raw/helper/buffer.rb +60 -0
- data/lib/raw/helper/cookie.rb +32 -0
- data/lib/raw/helper/debug.rb +28 -0
- data/lib/raw/helper/default.rb +16 -0
- data/lib/raw/helper/feed.rb +451 -0
- data/lib/raw/helper/form.rb +284 -0
- data/lib/raw/helper/javascript.rb +59 -0
- data/lib/raw/helper/layout.rb +40 -0
- data/lib/raw/helper/navigation.rb +87 -0
- data/lib/raw/helper/pager.rb +305 -0
- data/lib/raw/helper/table.rb +247 -0
- data/lib/raw/helper/xhtml.rb +218 -0
- data/lib/raw/helper/xml.rb +125 -0
- data/lib/raw/mixin/magick.rb +35 -0
- data/lib/raw/mixin/sweeper.rb +71 -0
- data/lib/raw/mixin/thumbnails.rb +1 -0
- data/lib/raw/mixin/webfile.rb +165 -0
- data/lib/raw/render.rb +271 -0
- data/lib/raw/render/builder.rb +26 -0
- data/lib/raw/render/caching.rb +81 -0
- data/lib/raw/render/call.rb +43 -0
- data/lib/raw/render/send_file.rb +46 -0
- data/lib/raw/render/stream.rb +39 -0
- data/lib/raw/scaffold.rb +13 -0
- data/lib/raw/scaffold/controller.rb +25 -0
- data/lib/raw/scaffold/model.rb +157 -0
- data/lib/raw/test.rb +5 -0
- data/lib/raw/test/assertions.rb +169 -0
- data/lib/raw/test/context.rb +55 -0
- data/lib/raw/test/testcase.rb +79 -0
- data/lib/raw/util/attr.rb +128 -0
- data/lib/raw/util/encode_uri.rb +149 -0
- data/lib/raw/util/html_filter.rb +538 -0
- data/lib/raw/util/markup.rb +130 -0
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/CONFIG.rb +3 -0
- data/test/nitro/adapter/raw_post1.bin +9 -0
- data/test/nitro/adapter/tc_webrick.rb +16 -0
- data/test/nitro/cgi/tc_cookie.rb +14 -0
- data/test/nitro/cgi/tc_request.rb +61 -0
- data/test/nitro/compiler/tc_client_morpher.rb +47 -0
- data/test/nitro/compiler/tc_compiler.rb +25 -0
- data/test/nitro/dispatcher/tc_mounter.rb +47 -0
- data/test/nitro/helper/tc_feed.rb +135 -0
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_pager.rb +35 -0
- data/test/nitro/helper/tc_table.rb +68 -0
- data/test/nitro/helper/tc_xhtml.rb +19 -0
- data/test/nitro/tc_caching.rb +19 -0
- data/test/nitro/tc_cgi.rb +222 -0
- data/test/nitro/tc_context.rb +17 -0
- data/test/nitro/tc_controller.rb +103 -0
- data/test/nitro/tc_controller_aspect.rb +32 -0
- data/test/nitro/tc_controller_params.rb +885 -0
- data/test/nitro/tc_dispatcher.rb +109 -0
- data/test/nitro/tc_element.rb +85 -0
- data/test/nitro/tc_flash.rb +59 -0
- data/test/nitro/tc_helper.rb +47 -0
- data/test/nitro/tc_render.rb +119 -0
- data/test/nitro/tc_router.rb +61 -0
- data/test/nitro/tc_server.rb +35 -0
- data/test/nitro/tc_session.rb +66 -0
- data/test/nitro/tc_template.rb +71 -0
- data/test/nitro/util/tc_encode_url.rb +87 -0
- data/test/nitro/util/tc_markup.rb +31 -0
- data/test/public/blog/another/very_litle/index.xhtml +1 -0
- data/test/public/blog/inc1.xhtml +2 -0
- data/test/public/blog/inc2.xhtml +1 -0
- data/test/public/blog/list.xhtml +9 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- metadata +244 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
require "nitro/aspects"
|
|
2
|
+
|
|
3
|
+
module Raw
|
|
4
|
+
|
|
5
|
+
# This module adds flashing support to the Controllers.
|
|
6
|
+
|
|
7
|
+
module Flashing
|
|
8
|
+
|
|
9
|
+
def self.included(base)
|
|
10
|
+
super
|
|
11
|
+
base.before(:call => :init_flash)
|
|
12
|
+
base.after(:call => :clean_flash)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# A Flash is a special hash object that lives in the session.
|
|
16
|
+
# The values stored in the Flash are typically maintained
|
|
17
|
+
# for the duration of one request. After the request is over,
|
|
18
|
+
# the Hash is cleared.
|
|
19
|
+
#
|
|
20
|
+
# You may want to use the Flash to pass error messages or
|
|
21
|
+
# other short lived objects.
|
|
22
|
+
#
|
|
23
|
+
# Use capitalized keys to denote system variables. Reserve
|
|
24
|
+
# lower case keys for user application variables.
|
|
25
|
+
|
|
26
|
+
class Flash < Hash
|
|
27
|
+
|
|
28
|
+
def initialize
|
|
29
|
+
super
|
|
30
|
+
@dirty = {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def []=(key, val)
|
|
34
|
+
super
|
|
35
|
+
keep(key)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Keep the specific key or the whole Flash.
|
|
39
|
+
|
|
40
|
+
def keep(key = nil)
|
|
41
|
+
set_dirty(key, false)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Discard the specific key or the whole Flash.
|
|
45
|
+
|
|
46
|
+
def discard(key = nil)
|
|
47
|
+
set_dirty(key)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def clean # :nodoc:
|
|
51
|
+
keys.each do |k|
|
|
52
|
+
unless @dirty[k]
|
|
53
|
+
set_dirty(k)
|
|
54
|
+
else
|
|
55
|
+
delete(k)
|
|
56
|
+
@dirty.delete(k)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# remove externaly updated keys.
|
|
61
|
+
|
|
62
|
+
(@dirty.keys - keys).each { |k| @dirty.delete k }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# :section: Helpers
|
|
66
|
+
|
|
67
|
+
# Push a value in an array flash variable.
|
|
68
|
+
#
|
|
69
|
+
# === Example
|
|
70
|
+
#
|
|
71
|
+
# flash.push :ERRORS, 'This is the first error'
|
|
72
|
+
# flash.push :ERRORS, 'This is the second error'
|
|
73
|
+
#
|
|
74
|
+
# flash[:ERRORS] # => []
|
|
75
|
+
|
|
76
|
+
def push(key, *values)
|
|
77
|
+
val = self[key]
|
|
78
|
+
val ||= []
|
|
79
|
+
if values.size == 1
|
|
80
|
+
val << values[0]
|
|
81
|
+
else
|
|
82
|
+
val << values
|
|
83
|
+
end
|
|
84
|
+
self[key] = val
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Pop a value from an array flash variable.
|
|
88
|
+
|
|
89
|
+
def pop(key)
|
|
90
|
+
if arr = self[key]
|
|
91
|
+
if arr.is_a? Array
|
|
92
|
+
return arr.pop
|
|
93
|
+
else
|
|
94
|
+
return arr
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
return nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Another helper, concats a whole array to the given flash
|
|
101
|
+
# key.
|
|
102
|
+
|
|
103
|
+
def concat(key, arr)
|
|
104
|
+
for val in arr.to_a
|
|
105
|
+
push key, val
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Join helper
|
|
110
|
+
|
|
111
|
+
def join(key, sep = ', ')
|
|
112
|
+
value = self[key]
|
|
113
|
+
|
|
114
|
+
if value.is_a? Array
|
|
115
|
+
return value.join(sep)
|
|
116
|
+
else
|
|
117
|
+
return value
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
def set_dirty(key = nil, flag = true)
|
|
124
|
+
if key
|
|
125
|
+
@dirty[key] = flag
|
|
126
|
+
else
|
|
127
|
+
keys.each { |k| @dirty[k] = flag }
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def flash
|
|
136
|
+
session[:FLASH] ||= Flash.new
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Some useful aspects.
|
|
140
|
+
|
|
141
|
+
# Marks flash entries as used and expose the flash to the
|
|
142
|
+
# view.
|
|
143
|
+
|
|
144
|
+
def init_flash
|
|
145
|
+
flash.discard
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Deletes the flash entries that were not marked for
|
|
149
|
+
# keeping.
|
|
150
|
+
|
|
151
|
+
def clean_flash
|
|
152
|
+
flash.clean
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Global scoped variables. This is backed by a Cache store.
|
|
2
|
+
#--
|
|
3
|
+
# TODO: implement as a refactoring of session?
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
class Global
|
|
7
|
+
|
|
8
|
+
# The type of the global cache. The generalized caching
|
|
9
|
+
# system in Glue is used. The following options are available:
|
|
10
|
+
#
|
|
11
|
+
# * :memory [default]
|
|
12
|
+
# * :drb
|
|
13
|
+
# * :og
|
|
14
|
+
# * :file
|
|
15
|
+
# * :memcached
|
|
16
|
+
|
|
17
|
+
setting :cache_type, :default => :memory, :doc => 'The type of global cache'
|
|
18
|
+
|
|
19
|
+
# The address of the store.
|
|
20
|
+
|
|
21
|
+
setting :cache_address, :default => '127.0.0.1', :doc => 'The address of the global cache'
|
|
22
|
+
|
|
23
|
+
# The port of the store.
|
|
24
|
+
|
|
25
|
+
setting :cache_port, :default => 9079, :doc => 'The port of the global cache'
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
# The global cache (store).
|
|
29
|
+
|
|
30
|
+
attr_accessor :cache
|
|
31
|
+
|
|
32
|
+
# Init the correct Global cache.
|
|
33
|
+
|
|
34
|
+
def setup(type = Global.cache_type)
|
|
35
|
+
return if Global.cache
|
|
36
|
+
|
|
37
|
+
case type
|
|
38
|
+
when :memory
|
|
39
|
+
require 'glue/cache/memory'
|
|
40
|
+
Global.cache = Glue::MemoryCache.new
|
|
41
|
+
|
|
42
|
+
when :drb
|
|
43
|
+
require 'glue/cache/drb'
|
|
44
|
+
Global.cache = DrbCache.new(Global.cache_address, Global.cache_port)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Initialize a global value once.
|
|
49
|
+
|
|
50
|
+
def init(key, value)
|
|
51
|
+
unless Global[key]
|
|
52
|
+
Global[key] = value
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def set(key, value)
|
|
57
|
+
Global.cache[key] = value
|
|
58
|
+
end
|
|
59
|
+
alias_method :[]=, :set
|
|
60
|
+
|
|
61
|
+
def get(key)
|
|
62
|
+
return Global.cache[key]
|
|
63
|
+
end
|
|
64
|
+
alias_method :[], :get
|
|
65
|
+
|
|
66
|
+
# If block is given it acts as an update methods,
|
|
67
|
+
# that transparently handles distributed stores.
|
|
68
|
+
#
|
|
69
|
+
# Global.update(:USERS) do |users|
|
|
70
|
+
# users << 'gmosx'
|
|
71
|
+
# end
|
|
72
|
+
|
|
73
|
+
def update(key)
|
|
74
|
+
if block_given?
|
|
75
|
+
# update, also handles distributed stores.
|
|
76
|
+
val = Global.cache[key]
|
|
77
|
+
yield val
|
|
78
|
+
Global.cache[key] = val
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def delete(key)
|
|
83
|
+
Global.cache.delete(key)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
module Raw
|
|
2
|
+
|
|
3
|
+
# Encapsulates a request. This is an abstract request
|
|
4
|
+
# typically extended by sub-classes. This module
|
|
5
|
+
# is included in Context.
|
|
6
|
+
|
|
7
|
+
module Request
|
|
8
|
+
|
|
9
|
+
# The request input stream.
|
|
10
|
+
|
|
11
|
+
attr_accessor :in
|
|
12
|
+
|
|
13
|
+
# The request headers collection. Also called
|
|
14
|
+
# the request environment (env).
|
|
15
|
+
|
|
16
|
+
attr_accessor :headers
|
|
17
|
+
alias_method :env, :headers
|
|
18
|
+
alias_method :env=, :headers=
|
|
19
|
+
alias_method :env_table, :headers
|
|
20
|
+
|
|
21
|
+
attr_accessor :post_params
|
|
22
|
+
attr_accessor :get_params
|
|
23
|
+
|
|
24
|
+
# The parsed query parameters collection.
|
|
25
|
+
|
|
26
|
+
def params
|
|
27
|
+
if method == :post
|
|
28
|
+
@post_params
|
|
29
|
+
else
|
|
30
|
+
@get_params
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def params=(pa)
|
|
35
|
+
if method == :post
|
|
36
|
+
@post_params = pa
|
|
37
|
+
else
|
|
38
|
+
@get_params = pa
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
alias_method :query, :params
|
|
43
|
+
alias_method :parameters, :params
|
|
44
|
+
|
|
45
|
+
# The request cookies.
|
|
46
|
+
|
|
47
|
+
attr_accessor :cookies
|
|
48
|
+
alias_method :cookie, :cookies
|
|
49
|
+
|
|
50
|
+
# The request protocol.
|
|
51
|
+
|
|
52
|
+
def protocol
|
|
53
|
+
@headers['HTTPS'] == "on" ? "https://" : "http://"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Is this an ssl request?
|
|
57
|
+
|
|
58
|
+
def ssl?
|
|
59
|
+
@headers["HTTPS"] == "on"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The request uri.
|
|
63
|
+
|
|
64
|
+
def uri
|
|
65
|
+
@headers["REQUEST_URI"]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The path info. Typically this is the rewritten uri without
|
|
69
|
+
# the query string.
|
|
70
|
+
|
|
71
|
+
def path_info
|
|
72
|
+
@headers["PATH_INFO"]
|
|
73
|
+
end
|
|
74
|
+
alias_method :path, :path_info
|
|
75
|
+
|
|
76
|
+
# Returns the domain part of a host.
|
|
77
|
+
#
|
|
78
|
+
# === Examples
|
|
79
|
+
#
|
|
80
|
+
# www.nitroproject.org: request.domain # => 'nitroproject.org'
|
|
81
|
+
# www.nitroproject.co.uk: request.domain(2) # => 'nitroproject.co.uk'
|
|
82
|
+
|
|
83
|
+
def domain tld_length = 1
|
|
84
|
+
host.split('.').last(1 + tld_length).join('.')
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Returns all the subdomains as an array.
|
|
88
|
+
#
|
|
89
|
+
# === Examples
|
|
90
|
+
#
|
|
91
|
+
# my.name.nitroproject.org: request.subdomains # => ['my', 'name']
|
|
92
|
+
|
|
93
|
+
def subdomains tld_length = 1
|
|
94
|
+
parts = host.split('.')
|
|
95
|
+
parts[0..-(tld_length+2)]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# The request query string.
|
|
99
|
+
|
|
100
|
+
def query_string
|
|
101
|
+
headers["QUERY_STRING"]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# The request method. Alternatively you could use the
|
|
105
|
+
# request method predicates.
|
|
106
|
+
#
|
|
107
|
+
# === Examples
|
|
108
|
+
#
|
|
109
|
+
# if request.method == :get
|
|
110
|
+
# if request.get?
|
|
111
|
+
|
|
112
|
+
def method
|
|
113
|
+
@headers["REQUEST_METHOD"].downcase.to_sym
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#--
|
|
117
|
+
# Define a set of helpers to determine the request
|
|
118
|
+
# method (get?, post?, put?, delete?, head?)
|
|
119
|
+
#++
|
|
120
|
+
|
|
121
|
+
for m in [:get, :post, :put, :delete, :head]
|
|
122
|
+
eval %{
|
|
123
|
+
def #{m}?; method == :#{m}; end
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Determine whether the body of a POST request is URL-encoded
|
|
128
|
+
# (default), XML, or YAML by checking the Content-Type HTTP
|
|
129
|
+
# header:
|
|
130
|
+
#
|
|
131
|
+
# Content-Type Post Format
|
|
132
|
+
# application/xml :xml
|
|
133
|
+
# text/xml :xml
|
|
134
|
+
# application/x-yaml :yaml
|
|
135
|
+
# text/x-yaml :yaml
|
|
136
|
+
# * :url_encoded
|
|
137
|
+
|
|
138
|
+
def post_format
|
|
139
|
+
@post_format ||= if @headers['HTTP_X_POST_DATA_FORMAT']
|
|
140
|
+
@headers['HTTP_X_POST_DATA_FORMAT'].downcase.to_sym
|
|
141
|
+
else
|
|
142
|
+
case @headers['CONTENT_TYPE'].to_s.downcase
|
|
143
|
+
when 'application/xml', 'text/xml' then :xml
|
|
144
|
+
when 'application/x-yaml', 'text/x-yaml' then :yaml
|
|
145
|
+
else :url_encoded
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Is this a POST request formatted as XML or YAML?
|
|
151
|
+
|
|
152
|
+
def formatted_post?
|
|
153
|
+
post? && (post_format == :xml || post_format == :yaml)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Is this a POST request formatted as XML?
|
|
157
|
+
|
|
158
|
+
def xml_post?
|
|
159
|
+
post? && post_format == :xml
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Is this a POST request formatted as YAML?
|
|
163
|
+
|
|
164
|
+
def yaml_post?
|
|
165
|
+
post? && post_format == :yaml
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Is this an XhtmlRpcRequest?
|
|
169
|
+
# Returns true if the request's 'X-Requested-With' header
|
|
170
|
+
# contains 'XMLHttpRequest'. Compatible with the Prototype
|
|
171
|
+
# Javascript library.
|
|
172
|
+
|
|
173
|
+
def xml_http_request?
|
|
174
|
+
not /XMLHttpRequest/i.match(@headers['HTTP_X_REQUESTED_WITH']).nil?
|
|
175
|
+
end
|
|
176
|
+
alias_method :xhr?, :xml_http_request?
|
|
177
|
+
alias_method :script?, :xml_http_request?
|
|
178
|
+
|
|
179
|
+
# Return the referer. For the initial page in the
|
|
180
|
+
# clickstream there is no referer, set "/" by default.
|
|
181
|
+
|
|
182
|
+
def referer
|
|
183
|
+
@headers["HTTP_REFERER"] || "/"
|
|
184
|
+
end
|
|
185
|
+
alias_method :referrer, :referer
|
|
186
|
+
|
|
187
|
+
# The content_length
|
|
188
|
+
|
|
189
|
+
def content_length
|
|
190
|
+
@headers["CONTENT_LENGTH"].to_i
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# The remote IP address. REMOTE_ADDR is the standard
|
|
194
|
+
# but will fail if the user is behind a proxy.
|
|
195
|
+
# HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by
|
|
196
|
+
# proxies so check for these before falling back to
|
|
197
|
+
# REMOTE_ADDR. HTTP_X_FORWARDED_FOR may be a comma-delimited
|
|
198
|
+
# list in the case of multiple chained proxies; the first
|
|
199
|
+
# is the originating IP.
|
|
200
|
+
|
|
201
|
+
def remote_ip
|
|
202
|
+
return @headers['HTTP_CLIENT_IP'] if @headers.include?('HTTP_CLIENT_IP')
|
|
203
|
+
|
|
204
|
+
if @headers.include?('HTTP_X_FORWARDED_FOR') then
|
|
205
|
+
remote_ips = @headers['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip|
|
|
206
|
+
ip =~ /^unknown$/i or local_net?(ip)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
return remote_ips.first.strip unless remote_ips.empty?
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
return @headers['REMOTE_ADDR']
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Request is from a local network? (RFC1918 + localhost)
|
|
216
|
+
|
|
217
|
+
def local_net?(ip = remote_ip)
|
|
218
|
+
bip = ip.split('.').map{ |x| x.to_i }.pack('C4').unpack('N')[0]
|
|
219
|
+
|
|
220
|
+
# 127.0.0.1/32 => 2130706433
|
|
221
|
+
# 192.168.0.0/16 => 49320
|
|
222
|
+
# 172.16.0.0/12 => 2753
|
|
223
|
+
# 10.0.0.0/8 => 10
|
|
224
|
+
|
|
225
|
+
{ 0 => 2130706433, 16 => 49320, 20 => 2753, 24 => 10}.each do |s,c|
|
|
226
|
+
return true if (bip >> s) == c
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
return false
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Request comming from local?
|
|
233
|
+
|
|
234
|
+
def local?(ip = remote_ip)
|
|
235
|
+
# TODO: should check if requesting machine is the one the server is running
|
|
236
|
+
return true if ip == '127.0.0.1'
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# The server port.
|
|
240
|
+
|
|
241
|
+
def port
|
|
242
|
+
@headers['SERVER_PORT'].to_i
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# The server host name.
|
|
246
|
+
# Also handles proxy forwarding.
|
|
247
|
+
|
|
248
|
+
def host
|
|
249
|
+
@headers['HTTP_X_FORWARDED_HOST'] || @headers['HTTP_HOST']
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# The host uri.
|
|
253
|
+
|
|
254
|
+
def host_uri
|
|
255
|
+
"#{protocol}#{host}"
|
|
256
|
+
end
|
|
257
|
+
alias_method :server_uri, :host_uri
|
|
258
|
+
# This is deprecated.
|
|
259
|
+
alias_method :host_url, :host_uri
|
|
260
|
+
|
|
261
|
+
# Different servers hold user agent in differnet
|
|
262
|
+
# strings (unify this).
|
|
263
|
+
|
|
264
|
+
def user_agent
|
|
265
|
+
headers["HTTP_USER_AGENT"] || headers["USER-AGENT"]
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# The raw data of the request.
|
|
269
|
+
# Useful to implement Webservices.
|
|
270
|
+
#--
|
|
271
|
+
# FIXME: better name and implementation.
|
|
272
|
+
#++
|
|
273
|
+
|
|
274
|
+
def raw_body
|
|
275
|
+
unless @raw_body
|
|
276
|
+
@in.rewind
|
|
277
|
+
@raw_body = @in.read(content_length)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
@raw_body
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Lookup a query parameter.
|
|
284
|
+
#--
|
|
285
|
+
# TODO: Check if unescape is needed.
|
|
286
|
+
#++
|
|
287
|
+
|
|
288
|
+
def [](param)
|
|
289
|
+
params[param]
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Set a query parameter.
|
|
293
|
+
|
|
294
|
+
def []=(param, value)
|
|
295
|
+
params[param] = value
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Check if a boolean param (checkbox) is true.
|
|
299
|
+
|
|
300
|
+
def true?(param)
|
|
301
|
+
params[param] == 'on'
|
|
302
|
+
end
|
|
303
|
+
alias_method :enabled?, :true?
|
|
304
|
+
alias_method :boolean, :true?
|
|
305
|
+
|
|
306
|
+
# Check if a boolean param (checkbox) is false.
|
|
307
|
+
|
|
308
|
+
def false?(param)
|
|
309
|
+
!true?(param)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Fetch a parameter with default value.
|
|
313
|
+
|
|
314
|
+
def fetch param, default = nil
|
|
315
|
+
params.fetch(param, default)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Check if a param is available.
|
|
319
|
+
#--
|
|
320
|
+
# gmosx: use instead of nil test to be more robust.
|
|
321
|
+
# (nil can be a hash element !)
|
|
322
|
+
#++
|
|
323
|
+
|
|
324
|
+
def has_key?(key)
|
|
325
|
+
params.keys.include?(key)
|
|
326
|
+
end
|
|
327
|
+
alias_method :has_param?, :has_key?
|
|
328
|
+
alias_method :param?, :has_key?
|
|
329
|
+
alias_method :has?, :has_key?
|
|
330
|
+
alias_method :is?, :has_key?
|
|
331
|
+
|
|
332
|
+
def keys
|
|
333
|
+
params.keys
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
end
|