sinatra-restful 0.0.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.
- checksums.yaml +7 -0
- data/lib/sinatra/restful.rb +117 -0
- metadata +43 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 15d78e1e8c4fedb1f80e63dd6bb854d35b6d4278
|
4
|
+
data.tar.gz: 5919cc10737740374311f1cfe3b78996a1fa7733
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c7468d4fddc6c9634edc92a0ef98238949de9bd9717d2a58eb2c3fe913641ff097208987e65e7ce0832b3a0952796e03a8eea19fbcb3d5eb8034732c509dd751
|
7
|
+
data.tar.gz: 2287e672afdf9830bc440f85c0a0acf5278ac4657e39258aaed303fdc346c9bd1725e61668af654f53f9608149bf577a9fe8d5dcf9a93969c16f85feccb96b6f
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'rack/deflater'
|
3
|
+
require 'rack/throttle'
|
4
|
+
require 'sinatra/base'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
module Restful
|
8
|
+
VERSION_CHECK = %r{/v([^/]+)}
|
9
|
+
|
10
|
+
module Throttle
|
11
|
+
class Interval < Rack::Throttle::Limiter
|
12
|
+
def initialize(app, options = {})
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
# Token bucket algorithm to limit QPS
|
17
|
+
# @see http://en.wikipedia.org/wiki/Token_bucket
|
18
|
+
def allowed?(request)
|
19
|
+
value = options[:value] || 10
|
20
|
+
|
21
|
+
key = cache_key(request)
|
22
|
+
time = request_start_time(request)
|
23
|
+
bucket = cache_get(key) rescue nil
|
24
|
+
if bucket == nil
|
25
|
+
bucket = {
|
26
|
+
:time => Time.now.to_i,
|
27
|
+
:tokens => value
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
if bucket[:tokens] < value
|
32
|
+
delta = (value * (Time.now.to_i - bucket[:time]))
|
33
|
+
bucket[:tokens] = [value, bucket[:tokens] + (value * delta)].min
|
34
|
+
end
|
35
|
+
bucket[:time] = Time.now.to_i
|
36
|
+
|
37
|
+
allowed = false
|
38
|
+
if bucket[:tokens] > 0
|
39
|
+
bucket[:tokens] -= 1
|
40
|
+
allowed = true
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
cache_set(key, bucket)
|
45
|
+
allowed
|
46
|
+
rescue
|
47
|
+
# If cache_set fails, just allow the request
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def http_error(code, message = nil, headers = {})
|
53
|
+
content = {
|
54
|
+
:error => {
|
55
|
+
:message => message
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
[code, {'Content-Type' => 'text/json; charset=utf-8'}.merge(headers),
|
60
|
+
[JSON.generate(content)]]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Compress < Rack::Deflater
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.registered(app)
|
69
|
+
# Condition for matching Accept-Encoding
|
70
|
+
def accept_encoding(type, version = nil)
|
71
|
+
condition do
|
72
|
+
request.accept_encoding.each do |k, v|
|
73
|
+
if type == k
|
74
|
+
return version == nil || version >= v
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def version(version)
|
83
|
+
condition do
|
84
|
+
# FIXME: If a route with a higher version number is defined
|
85
|
+
# after the older one, the older one will always be matched
|
86
|
+
# first
|
87
|
+
return env.has_key?('sinatra.rest.version') &&
|
88
|
+
env['sinatra.rest.version'] >= version
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
app.before VERSION_CHECK do
|
93
|
+
match = request.path_info.match(VERSION_CHECK)
|
94
|
+
env['sinatra.rest.version'] = match[1]
|
95
|
+
request.path_info = match.post_match
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return hash for not found response
|
99
|
+
app.not_found do
|
100
|
+
content = {
|
101
|
+
:error => {
|
102
|
+
:message => env['sinatra.error']
|
103
|
+
}
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
# Encode the response as json
|
108
|
+
app.after do
|
109
|
+
content_type :json
|
110
|
+
body JSON.generate(body)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
register Restful
|
116
|
+
end
|
117
|
+
|
metadata
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-restful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamal Fanaian
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Sinatra extension to make RESTful APIs super simple
|
14
|
+
email: j@jamalfanaian.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/sinatra/restful.rb
|
20
|
+
homepage: http://github.com/jamal/sinatra-rest
|
21
|
+
licenses: []
|
22
|
+
metadata: {}
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
32
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
requirements: []
|
38
|
+
rubyforge_project:
|
39
|
+
rubygems_version: 2.0.0
|
40
|
+
signing_key:
|
41
|
+
specification_version: 4
|
42
|
+
summary: Sinatra extension to make RESTful APIs super simple
|
43
|
+
test_files: []
|