module Apache::SecureDownload::Util
Constants
- TIMESTAMP_LENGTH
- TOKEN_KEY
- TOKEN_LENGTH
Public Instance Methods
Joins timestamp
and token
parameters into a single value.
# File lib/apache/secure_download/util.rb 114 def join(timestamp, token) 115 "#{"%0#{TIMESTAMP_LENGTH}x" % timestamp}#{token}" 116 end
Returns path
with timestamp and token parameter removed.
# File lib/apache/secure_download/util.rb 129 def real_path(path) 130 clean(path, :path) 131 end
Returns query
with timestamp and token parameter removed.
# File lib/apache/secure_download/util.rb 134 def real_query(query) 135 clean(query, :query) 136 end
Creates a valid URL to the secured resource, identified by url
. The argument secret
is the shared secret string that has been passed to the relevant RubyAccessHandler instance (cf. SecureDownload.new
).
The expiration time may be either given as a Time (or Integer), or as a Hash with the following parameters:
:expires
-
Same as for the simple
expires
argument :offset
-
The amount of seconds in the future (only if
:expires
is not given) :cache
-
A time window for which identical URLs shall be produced, on average (defaults to
:offset
, if given)
Examples (s = "secret"
):
# Only the path component (and an optional query component) will be taken into account secure_url(s, "/secure/url") #=> "/secure/url?_asd=0047c3f5665671a9b3966e8bbed91fc0bb5594d576c504cdf0" secure_url(s, "http://example.com/secure/url") #=> "http://example.com/secure/url?_asd=0047c3f5665671a9b3966e8bbed91fc0bb5594d576c504cdf0" secure_url(s, "/secure/url?query=value") #=> "/secure/url?query=value&_asd=0047c3f566b482f943c35f4a1b5da6c646df6a65c0edc364cf" # Expires in 10 minutes secure_url(s, "/secure/url", Time.now + 600) #=> "/secure/url?_asd=0047c3f7827e51f91cf4406f308a8df24f4e2cbf188de3c1bf" secure_url(s, "/secure/url", :offset => 600) #=> "/secure/url?_asd=0047c3fa9058eb12f9fc3fcd984fe4e918d3fd0590392c172d" # Setting an offset will also allow caching; turn it off explicitly secure_url(s, "/secure/url", :offset => 600, :cache => false) #=> "/secure/url?_asd=0047c3f7827e51f91cf4406f308a8df24f4e2cbf188de3c1bf" # Produce identical URLs for a window of 1 minute (on average) t = Time.now secure_url(s, "/secure/url", :expires => t, :cache => 60) #=> "/secure/url?_asd=0047c3f568ccf279daf1787d34ad063cbf5851ee88aae967fb" secure_url(s, "/secure/url", :expires => t + 30, :cache => 60) #=> "/secure/url?_asd=0047c3f568ccf279daf1787d34ad063cbf5851ee88aae967fb" secure_url(s, "/secure/url", :expires => t + 60, :cache => 60) #=> "/secure/url?_asd=0047c3f5a4c7dcea5679ad539a7bad1dc4b7f44eb3dd36d6e8" secure_url(s, "/secure/url", :expires => t + 90, :cache => 60) #=> "/secure/url?_asd=0047c3f5a4c7dcea5679ad539a7bad1dc4b7f44eb3dd36d6e8" # Same as before, but use offset secure_url(s, "/secure/url", :offset => 60) #=> "/secure/url?_asd=0047c3f5a4c7dcea5679ad539a7bad1dc4b7f44eb3dd36d6e8" # 30 seconds later... secure_url(s, "/secure/url", :offset => 60) #=> "/secure/url?_asd=0047c3f5a4c7dcea5679ad539a7bad1dc4b7f44eb3dd36d6e8" # 30 seconds later... secure_url(s, "/secure/url", :offset => 60) #=> "/secure/url?_asd=0047c3f5e0aa11618f1cc0883a29e9239b777ca53dfc4d9604" # 30 seconds later... secure_url(s, "/secure/url", :offset => 60) #=> "/secure/url?_asd=0047c3f5e0aa11618f1cc0883a29e9239b777ca53dfc4d9604"
# File lib/apache/secure_download/util.rb 92 def secure_url(s, u, e = Time.now + 60) 93 if e.is_a?(Hash) 94 e[:offset] ||= 60 95 c = e[:cache] || e[:offset] 96 97 t = (e[:expires] || Time.now + e[:offset]).to_i 98 99 unless e[:cache] == false || c.zero? 100 # make the URL cacheable for +c+ seconds *on average* 101 t = ((t / c.to_f).round + 1) * c.to_i 102 end 103 else 104 t = e.to_i 105 end 106 107 r, q = u[0, 1] == '/' ? u.split('?', 2) : URI.split(u).values_at(5, 7) 108 r << '?' << q if q 109 110 u.sub(/#|\z/, "#{q ? '&' : '?'}#{TOKEN_KEY}=#{join(t, token(s, r, t))}\\&") 111 end
Splits value
into timestamp and token parameters.
# File lib/apache/secure_download/util.rb 119 def split(value) 120 [value[0, TIMESTAMP_LENGTH].to_i(16), value[TIMESTAMP_LENGTH, TOKEN_LENGTH]] 121 end
Computes the token from secret
, path
, and timestamp
.
# File lib/apache/secure_download/util.rb 124 def token(secret, path, timestamp) 125 Digest::SHA1.hexdigest("#{secret}#{real_path(path)}#{timestamp}") 126 end
Private Instance Methods
Returns string
with timestamp and token parameter removed. The type
indicates whether it’s a path or a query.
# File lib/apache/secure_download/util.rb 142 def clean(string, type) 143 char = case type 144 when :path then '\?' 145 when :query then '\A' 146 else raise ArgumentError, "type #{type.inspect} not supported" 147 end 148 149 string.sub(/(#{char}|&)_asd=[^&]*(&?)/) { $1 unless $2.empty? } 150 end