boned 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/README.md +6 -4
- data/Rakefile +45 -38
- data/VERSION.yml +4 -0
- data/api/api-set.rb +31 -30
- data/api/api.rb +49 -49
- data/app.ru +36 -0
- data/bin/boned +6 -71
- data/boned.gemspec +68 -46
- data/config/redis-server.conf +149 -131
- data/lib/boned/api/base.rb +163 -0
- data/lib/boned/api.rb +76 -69
- data/lib/boned/app.rb +0 -0
- data/lib/boned.rb +33 -165
- data/try/10_basics_try.rb +37 -0
- data/try/11_signature_try.rb +11 -0
- data/try/20_keys_try.rb +34 -0
- metadata +72 -30
- data/config.ru +0 -31
- data/lib/boned/api/debug.rb +0 -21
- data/lib/boned/api/redis.rb +0 -44
- data/lib/boned/api/service.rb +0 -86
- data/lib/boned/cli.rb +0 -62
- data/lib/boned/models/bone.rb +0 -112
- data/lib/boned/models.rb +0 -34
- data/lib/boned/server.rb +0 -67
- data/try/10_bone_model.rb +0 -21
data/config/redis-server.conf
CHANGED
@@ -1,68 +1,51 @@
|
|
1
|
-
#
|
1
|
+
# BS REDIS 2.0 CONFIG (dev) -- 2010-11-17
|
2
2
|
|
3
|
-
#
|
4
|
-
# * port
|
5
|
-
# * daemonize
|
6
|
-
# * dbfilename
|
3
|
+
# NOTE: NOTE: auto-generated by delano on tucker at 2010-11-29 11:49:17 -0500
|
7
4
|
|
8
|
-
|
9
|
-
|
5
|
+
dir /tmp
|
6
|
+
|
7
|
+
pidfile boned-redis.pid
|
8
|
+
logfile boned-redis.log
|
9
|
+
dbfilename boned-redis.rdb
|
10
|
+
|
11
|
+
port 8045
|
12
|
+
bind 127.0.0.1
|
10
13
|
daemonize yes
|
11
14
|
|
12
|
-
|
13
|
-
dbfilename /tmp/boned-redis.rdb
|
15
|
+
timeout 300
|
14
16
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
17
|
+
#loglevel debug
|
18
|
+
#loglevel verbose
|
19
|
+
loglevel warning
|
18
20
|
|
19
|
-
|
20
|
-
port 8045
|
21
|
+
databases 16
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
# bind 127.0.0.1
|
23
|
+
save 900 100
|
24
|
+
save 300 5000
|
26
25
|
|
27
|
-
# Close the connection after a client is idle for N seconds (0 to disable)
|
28
|
-
timeout 300
|
29
26
|
|
30
|
-
|
31
|
-
#
|
32
|
-
# save <seconds> <changes>
|
33
|
-
#
|
34
|
-
# Will save the DB if both the given number of seconds and the given
|
35
|
-
# number of write operations against the DB occurred.
|
36
|
-
#
|
37
|
-
# In the example below the behaviour will be to save:
|
38
|
-
# after 900 sec (15 min) if at least 1 key changed
|
39
|
-
# after 300 sec (5 min) if at least 10 keys changed
|
40
|
-
# after 60 sec if at least 10000 keys changed
|
41
|
-
save 600 1
|
42
|
-
save 300 10
|
43
|
-
save 60 10000
|
27
|
+
rdbcompression yes
|
44
28
|
|
29
|
+
# requirepass foobared
|
30
|
+
# maxclients 0
|
45
31
|
|
46
|
-
|
47
|
-
|
48
|
-
dir ./
|
32
|
+
appendonly no
|
33
|
+
appendfilename redis.aof
|
49
34
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
# warning (only very important / critical messages are logged)
|
55
|
-
loglevel debug
|
35
|
+
# TODO: Consider having separate configs when the usecase for Redis
|
36
|
+
# changes. For example, one for production, another for batch processing.
|
37
|
+
#
|
38
|
+
# Nothing is changed from here on out:
|
56
39
|
|
57
|
-
|
58
|
-
# the demon to log on the standard output. Note that if you use standard
|
59
|
-
# output for logging but daemonize, logs will be sent to /dev/null
|
60
|
-
logfile stdout
|
40
|
+
################################## INCLUDES ###################################
|
61
41
|
|
62
|
-
#
|
63
|
-
# a
|
64
|
-
#
|
65
|
-
|
42
|
+
# Include one or more other config files here. This is useful if you
|
43
|
+
# have a standard template that goes to all redis server but also need
|
44
|
+
# to customize a few per-server settings. Include files can include
|
45
|
+
# other files, so use this wisely.
|
46
|
+
#
|
47
|
+
# include /path/to/local.conf
|
48
|
+
# include /path/to/other.conf
|
66
49
|
|
67
50
|
################################# REPLICATION #################################
|
68
51
|
|
@@ -70,67 +53,16 @@ databases 16
|
|
70
53
|
# another Redis server. Note that the configuration is local to the slave
|
71
54
|
# so for example it is possible to configure the slave to save the DB with a
|
72
55
|
# different interval, or to listen to another port, and so on.
|
73
|
-
|
74
|
-
# slaveof <masterip> <masterport>
|
75
|
-
|
76
|
-
################################## SECURITY ###################################
|
77
|
-
|
78
|
-
# Require clients to issue AUTH <PASSWORD> before processing any other
|
79
|
-
# commands. This might be useful in environments in which you do not trust
|
80
|
-
# others with access to the host running redis-server.
|
81
56
|
#
|
82
|
-
#
|
83
|
-
# people do not need auth (e.g. they run their own servers).
|
84
|
-
|
85
|
-
# requirepass
|
86
|
-
|
87
|
-
################################### LIMITS ####################################
|
88
|
-
|
89
|
-
# Set the max number of connected clients at the same time. By default there
|
90
|
-
# is no limit, and it's up to the number of file descriptors the Redis process
|
91
|
-
# is able to open. The special value '0' means no limts.
|
92
|
-
# Once the limit is reached Redis will close all the new connections sending
|
93
|
-
# an error 'max number of clients reached'.
|
94
|
-
|
95
|
-
# maxclients 128
|
96
|
-
|
97
|
-
# Don't use more memory than the specified amount of bytes.
|
98
|
-
# When the memory limit is reached Redis will try to remove keys with an
|
99
|
-
# EXPIRE set. It will try to start freeing keys that are going to expire
|
100
|
-
# in little time and preserve keys with a longer time to live.
|
101
|
-
# Redis will also try to remove objects from free lists if possible.
|
102
|
-
#
|
103
|
-
# If all this fails, Redis will start to reply with errors to commands
|
104
|
-
# that will use more memory, like SET, LPUSH, and so on, and will continue
|
105
|
-
# to reply to most read-only commands like GET.
|
106
|
-
#
|
107
|
-
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
|
108
|
-
# 'state' server or cache, not as a real DB. When Redis is used as a real
|
109
|
-
# database the memory usage will grow over the weeks, it will be obvious if
|
110
|
-
# it is going to use too much memory in the long run, and you'll have the time
|
111
|
-
# to upgrade. With maxmemory after the limit is reached you'll start to get
|
112
|
-
# errors for write operations, and this may even lead to DB inconsistency.
|
113
|
-
|
114
|
-
# maxmemory <bytes>
|
115
|
-
|
116
|
-
############################## APPEND ONLY MODE ###############################
|
57
|
+
# slaveof <masterip> <masterport>
|
117
58
|
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
# enable the append only mode: when this mode is enabled Redis will append
|
123
|
-
# every write operation received in the file appendonly.log. This file will
|
124
|
-
# be read on startup in order to rebuild the full dataset in memory.
|
125
|
-
#
|
126
|
-
# Note that you can have both the async dumps and the append only file if you
|
127
|
-
# like (you have to comment the "save" statements above to disable the dumps).
|
128
|
-
# Still if append only mode is enabled Redis will load the data from the
|
129
|
-
# log file at startup ignoring the dump.rdb file.
|
59
|
+
# If the master is password protected (using the "requirepass" configuration
|
60
|
+
# directive below) it is possible to tell the slave to authenticate before
|
61
|
+
# starting the replication synchronization process, otherwise the master will
|
62
|
+
# refuse the slave request.
|
130
63
|
#
|
131
|
-
#
|
64
|
+
# masterauth <master-password>
|
132
65
|
|
133
|
-
appendonly no
|
134
66
|
|
135
67
|
# The fsync() call tells the Operating System to actually write data on disk
|
136
68
|
# instead to wait for more data in the output buffer. Some OS will really flush
|
@@ -142,16 +74,92 @@ appendonly no
|
|
142
74
|
# always: fsync after every write to the append only log . Slow, Safest.
|
143
75
|
# everysec: fsync only if one second passed since the last fsync. Compromise.
|
144
76
|
#
|
145
|
-
# The default is "
|
146
|
-
# understand if you can relax this to
|
147
|
-
#
|
148
|
-
# it
|
149
|
-
# some data loss consider the default persistence mode that's snapshotting)
|
77
|
+
# The default is "everysec" that's usually the right compromise between
|
78
|
+
# speed and data safety. It's up to you to understand if you can relax this to
|
79
|
+
# "no" that will will let the operating system flush the output buffer when
|
80
|
+
# it wants, for better performances (but if you can live with the idea of
|
81
|
+
# some data loss consider the default persistence mode that's snapshotting),
|
82
|
+
# or on the contrary, use "always" that's very slow but a bit safer than
|
83
|
+
# everysec.
|
84
|
+
#
|
85
|
+
# If unsure, use "everysec".
|
150
86
|
|
151
|
-
appendfsync always
|
152
|
-
|
87
|
+
# appendfsync always
|
88
|
+
appendfsync everysec
|
153
89
|
# appendfsync no
|
154
90
|
|
91
|
+
################################ VIRTUAL MEMORY ###############################
|
92
|
+
|
93
|
+
# Virtual Memory allows Redis to work with datasets bigger than the actual
|
94
|
+
# amount of RAM needed to hold the whole dataset in memory.
|
95
|
+
# In order to do so very used keys are taken in memory while the other keys
|
96
|
+
# are swapped into a swap file, similarly to what operating systems do
|
97
|
+
# with memory pages.
|
98
|
+
#
|
99
|
+
# To enable VM just set 'vm-enabled' to yes, and set the following three
|
100
|
+
# VM parameters accordingly to your needs.
|
101
|
+
|
102
|
+
vm-enabled no
|
103
|
+
# vm-enabled yes
|
104
|
+
|
105
|
+
# This is the path of the Redis swap file. As you can guess, swap files
|
106
|
+
# can't be shared by different Redis instances, so make sure to use a swap
|
107
|
+
# file for every redis process you are running. Redis will complain if the
|
108
|
+
# swap file is already in use.
|
109
|
+
#
|
110
|
+
# The best kind of storage for the Redis swap file (that's accessed at random)
|
111
|
+
# is a Solid State Disk (SSD).
|
112
|
+
#
|
113
|
+
# *** WARNING *** if you are using a shared hosting the default of putting
|
114
|
+
# the swap file under /tmp is not secure. Create a dir with access granted
|
115
|
+
# only to Redis user and configure Redis to create the swap file there.
|
116
|
+
vm-swap-file /tmp/redis.swap
|
117
|
+
|
118
|
+
# vm-max-memory configures the VM to use at max the specified amount of
|
119
|
+
# RAM. Everything that deos not fit will be swapped on disk *if* possible, that
|
120
|
+
# is, if there is still enough contiguous space in the swap file.
|
121
|
+
#
|
122
|
+
# With vm-max-memory 0 the system will swap everything it can. Not a good
|
123
|
+
# default, just specify the max amount of RAM you can in bytes, but it's
|
124
|
+
# better to leave some margin. For instance specify an amount of RAM
|
125
|
+
# that's more or less between 60 and 80% of your free RAM.
|
126
|
+
vm-max-memory 0
|
127
|
+
|
128
|
+
# Redis swap files is split into pages. An object can be saved using multiple
|
129
|
+
# contiguous pages, but pages can't be shared between different objects.
|
130
|
+
# So if your page is too big, small objects swapped out on disk will waste
|
131
|
+
# a lot of space. If you page is too small, there is less space in the swap
|
132
|
+
# file (assuming you configured the same number of total swap file pages).
|
133
|
+
#
|
134
|
+
# If you use a lot of small objects, use a page size of 64 or 32 bytes.
|
135
|
+
# If you use a lot of big objects, use a bigger page size.
|
136
|
+
# If unsure, use the default :)
|
137
|
+
vm-page-size 32
|
138
|
+
|
139
|
+
# Number of total memory pages in the swap file.
|
140
|
+
# Given that the page table (a bitmap of free/used pages) is taken in memory,
|
141
|
+
# every 8 pages on disk will consume 1 byte of RAM.
|
142
|
+
#
|
143
|
+
# The total swap size is vm-page-size * vm-pages
|
144
|
+
#
|
145
|
+
# With the default of 32-bytes memory pages and 134217728 pages Redis will
|
146
|
+
# use a 4 GB swap file, that will use 16 MB of RAM for the page table.
|
147
|
+
#
|
148
|
+
# It's better to use the smallest acceptable value for your application,
|
149
|
+
# but the default is large in order to work in most conditions.
|
150
|
+
vm-pages 134217728
|
151
|
+
|
152
|
+
# Max number of VM I/O threads running at the same time.
|
153
|
+
# This threads are used to read/write data from/to swap file, since they
|
154
|
+
# also encode and decode objects from disk to memory or the reverse, a bigger
|
155
|
+
# number of threads can help with big objects even if they can't help with
|
156
|
+
# I/O itself as the physical device may not be able to couple with many
|
157
|
+
# reads/writes operations at the same time.
|
158
|
+
#
|
159
|
+
# The special value of 0 turn off threaded I/O and enables the blocking
|
160
|
+
# Virtual Memory implementation.
|
161
|
+
vm-max-threads 4
|
162
|
+
|
155
163
|
############################### ADVANCED CONFIG ###############################
|
156
164
|
|
157
165
|
# Glue small output buffers together in order to send small replies in a
|
@@ -159,19 +167,29 @@ appendfsync always
|
|
159
167
|
# in terms of number of queries per second. Use 'yes' if unsure.
|
160
168
|
glueoutputbuf yes
|
161
169
|
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
|
177
|
-
|
170
|
+
# Hashes are encoded in a special way (much more memory efficient) when they
|
171
|
+
# have at max a given numer of elements, and the biggest element does not
|
172
|
+
# exceed a given threshold. You can configure this limits with the following
|
173
|
+
# configuration directives.
|
174
|
+
hash-max-zipmap-entries 64
|
175
|
+
hash-max-zipmap-value 512
|
176
|
+
|
177
|
+
# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
|
178
|
+
# order to help rehashing the main Redis hash table (the one mapping top-level
|
179
|
+
# keys to values). The hash table implementation redis uses (see dict.c)
|
180
|
+
# performs a lazy rehashing: the more operation you run into an hash table
|
181
|
+
# that is rhashing, the more rehashing "steps" are performed, so if the
|
182
|
+
# server is idle the rehashing is never complete and some more memory is used
|
183
|
+
# by the hash table.
|
184
|
+
#
|
185
|
+
# The default is to use this millisecond 10 times every second in order to
|
186
|
+
# active rehashing the main dictionaries, freeing memory when possible.
|
187
|
+
#
|
188
|
+
# If unsure:
|
189
|
+
# use "activerehashing no" if you have hard latency requirements and it is
|
190
|
+
# not a good thing in your environment that Redis can reply form time to time
|
191
|
+
# to queries with 2 milliseconds delay.
|
192
|
+
#
|
193
|
+
# use "activerehashing yes" if you don't have such hard requirements but
|
194
|
+
# want to free memory asap when possible.
|
195
|
+
activerehashing yes
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'sinatra/reloader' # consider big_band
|
2
|
+
|
3
|
+
class Boned::APIBase < Sinatra::Base
|
4
|
+
|
5
|
+
set :public => 'public/'
|
6
|
+
set :views => 'views/'
|
7
|
+
set :static => true
|
8
|
+
|
9
|
+
configure :dev do
|
10
|
+
Bone.info "Environment: #{ENV['RACK_ENV']}"
|
11
|
+
register Sinatra::Reloader
|
12
|
+
dont_reload "lib/**/*.rb"
|
13
|
+
also_reload "lib/boned.rb"
|
14
|
+
before do
|
15
|
+
#Bone.debug = true
|
16
|
+
Bone.info $/, $/, "--> #{request_method} #{current_uri_path}"
|
17
|
+
content_type 'text/plain'
|
18
|
+
Boned.allow_register = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
configure :prod do
|
23
|
+
Bone.debug = false
|
24
|
+
before do
|
25
|
+
content_type 'application/json'
|
26
|
+
Boned.allow_register = false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
helpers do
|
31
|
+
def carefully(ret='', &blk)
|
32
|
+
begin
|
33
|
+
ret = blk.call
|
34
|
+
rescue => ex
|
35
|
+
generic_error ex.class, ex
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
|
40
|
+
def generic_error(event=nil, ex=nil)
|
41
|
+
Bone.info "#{event} #{request_token}:#{request_signature}" unless event.nil?
|
42
|
+
unless ex.nil?
|
43
|
+
Bone.info ex.message
|
44
|
+
Bone.ld ex.backtrace
|
45
|
+
end
|
46
|
+
return error(404, "Bad bone rising")
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_message msg
|
50
|
+
Bone.info "[400] #{msg}"
|
51
|
+
return error(400, msg)
|
52
|
+
end
|
53
|
+
|
54
|
+
def request_token
|
55
|
+
env['HTTP_X_BONE_TOKEN'] || params[:token]
|
56
|
+
end
|
57
|
+
def request_signature
|
58
|
+
@request_signature ||= params[:sig] || env['HTTP_X_BONE_SIGNATURE']
|
59
|
+
@request_signature
|
60
|
+
end
|
61
|
+
def request_secret
|
62
|
+
# no leading/trail whitspace end
|
63
|
+
@request_secret ||= (body_content || env['HTTP_X_BONE_SECRET']).strip
|
64
|
+
@request_secret
|
65
|
+
end
|
66
|
+
def body_content
|
67
|
+
@body_content ||= request.body.read
|
68
|
+
@body_content
|
69
|
+
end
|
70
|
+
|
71
|
+
def uri(*path)
|
72
|
+
[root_path, path].flatten.join('/')
|
73
|
+
end
|
74
|
+
def root_path
|
75
|
+
env['SCRIPT_NAME']
|
76
|
+
end
|
77
|
+
def current_uri_path
|
78
|
+
env['REQUEST_URI']
|
79
|
+
end
|
80
|
+
def request_method
|
81
|
+
env['REQUEST_METHOD'].to_s.downcase # important to be downcase for signature check
|
82
|
+
end
|
83
|
+
def current_host
|
84
|
+
env['HTTP_HOST'].to_s.downcase
|
85
|
+
end
|
86
|
+
def secure?
|
87
|
+
(env['HTTP_X_SCHEME'] == "https") # X-Scheme is set by nginx
|
88
|
+
end
|
89
|
+
|
90
|
+
def local?
|
91
|
+
LOCAL_HOSTS.member?(env['SERVER_NAME']) && (client_ipaddress == '127.0.0.1')
|
92
|
+
end
|
93
|
+
|
94
|
+
def assert_token
|
95
|
+
assert_exists request_token, "No token"
|
96
|
+
end
|
97
|
+
|
98
|
+
def assert_secret
|
99
|
+
assert_exists request_secret, "No secret"
|
100
|
+
end
|
101
|
+
|
102
|
+
def check_token
|
103
|
+
generic_error "[unknown-token]" if !Bone.token? request_token
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
def check_signature
|
108
|
+
assert_exists request_signature, "No signature"
|
109
|
+
unless params[:sigversion] == Bone::API::HTTP::SIGVERSION
|
110
|
+
error_message "API must be version: #{Bone::API::HTTP::SIGVERSION}"
|
111
|
+
end
|
112
|
+
# We need to re-parse the query string b/c Sinatra or Rack is
|
113
|
+
# including the value of the POST body as a key with no value.
|
114
|
+
qs = Bone::API::HTTP.parse_query request.query_string
|
115
|
+
qs.delete 'sig' # Yo dawg, I put a signature in your signature
|
116
|
+
stamp, now = (qs['stamp'] || 0).to_i, Bone::API::HTTP.canonical_time
|
117
|
+
generic_error "[sig-expired] #{stamp}" if (now - stamp) > 30.seconds
|
118
|
+
tobj = Bone::API::Redis::Token.new request_token
|
119
|
+
secret = tobj.secret.value
|
120
|
+
path = current_uri_path.split('?').first
|
121
|
+
sig = Bone::API::HTTP.generate_signature secret, current_host, request_method, path, qs, body_content
|
122
|
+
generic_error "[sig-mismatch] #{sig}" if sig != request_signature
|
123
|
+
Bone.new request_token
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# +names+ One or more a required parameter names (Symbol)
|
128
|
+
def assert_params(*names)
|
129
|
+
names.each do |n|
|
130
|
+
return error_message("Missing param: %s" % n) if params[n].to_s.empty?
|
131
|
+
end
|
132
|
+
true
|
133
|
+
end
|
134
|
+
alias_method :assert_param, :assert_params
|
135
|
+
|
136
|
+
def assert_exists(val, msg)
|
137
|
+
return error_message msg if val.to_s.empty?
|
138
|
+
true
|
139
|
+
end
|
140
|
+
|
141
|
+
def assert_true(val, msg)
|
142
|
+
return error_message msg if val != true
|
143
|
+
true
|
144
|
+
end
|
145
|
+
|
146
|
+
def assert_sha1(val)
|
147
|
+
return error_message("#{val} is not a sha1 digest") unless is_sha1?(val)
|
148
|
+
end
|
149
|
+
|
150
|
+
def assert_sha256(val)
|
151
|
+
return error_message("#{val} is not a sha256 digest") unless is_sha256?(val)
|
152
|
+
end
|
153
|
+
|
154
|
+
def is_sha1?(val)
|
155
|
+
val.to_s.match(/\A[0-9a-f]{40}\z/)
|
156
|
+
end
|
157
|
+
def is_sha256?(val)
|
158
|
+
val.to_s.match(/\A[0-9a-f]{64}\z/)
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
data/lib/boned/api.rb
CHANGED
@@ -1,94 +1,101 @@
|
|
1
|
-
|
2
1
|
require 'boned'
|
2
|
+
require 'boned/api/base'
|
3
3
|
|
4
|
+
class Boned::API < Boned::APIBase
|
4
5
|
|
5
|
-
|
6
|
+
# TODO: Remove these.
|
7
|
+
##get '/all' do
|
8
|
+
## keys = Bone::API::Redis::Token.redis.keys '*'
|
9
|
+
## keys.join $/
|
10
|
+
##end
|
11
|
+
##get "/:token/secret/?" do
|
12
|
+
## carefully do
|
13
|
+
## assert_token && check_token
|
14
|
+
## bone = check_signature
|
15
|
+
## bone.secret
|
16
|
+
## end
|
17
|
+
##end
|
6
18
|
|
7
|
-
|
8
|
-
|
9
|
-
|
19
|
+
#get "/:token/:bucket/keys/?" do
|
20
|
+
# Bone.info
|
21
|
+
# "poop"
|
22
|
+
#end
|
23
|
+
#
|
24
|
+
#get "/:token/:bucket/key/:key/?" do
|
25
|
+
# Bone.info
|
26
|
+
# "poop"
|
27
|
+
#end
|
10
28
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
29
|
+
get "/:token/key/:key/?" do
|
30
|
+
carefully do
|
31
|
+
assert_token && check_token
|
32
|
+
bone = check_signature
|
33
|
+
bone.key?(params[:key]) ? bone[params[:key]] : generic_error
|
16
34
|
end
|
17
35
|
end
|
18
36
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
37
|
+
get "/:token/keys/?" do
|
38
|
+
carefully do
|
39
|
+
assert_token && check_token
|
40
|
+
bone = check_signature
|
41
|
+
list = bone.keys || []
|
42
|
+
list.join $/
|
23
43
|
end
|
24
44
|
end
|
25
45
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
rescue => ex
|
33
|
-
Boned.ld "#{current_token}:#{params[:key]}", ex.message
|
34
|
-
Boned.ld ex.backtrace
|
35
|
-
return error(400, "Bad bone rising")
|
36
|
-
end
|
37
|
-
ret
|
38
|
-
end
|
39
|
-
|
40
|
-
def current_token() @env['HTTP_X_BONE_TOKEN'] || params[:token] end
|
41
|
-
def current_sig() @env['HTTP_X_BONE_SIGNATURE'] || params[:sig] end
|
42
|
-
|
43
|
-
def uri(*path)
|
44
|
-
[root_path, path].flatten.join('/')
|
46
|
+
get "/:token/?" do
|
47
|
+
carefully do
|
48
|
+
assert_token && check_token
|
49
|
+
bone = check_signature
|
50
|
+
# list of buckets, currently hardcoded to global
|
51
|
+
bone.token?(request_token) ? 'global' : generic_error
|
45
52
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
return error(400, "Missing param: %s" % n)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
alias_method :assert_param, :assert_params
|
59
|
-
|
60
|
-
def assert_exists(val, msg)
|
61
|
-
return error(400, msg) if val.nil? ||
|
62
|
-
(val.respond_to?(:empty?) && val.empty?)
|
63
|
-
end
|
64
|
-
|
65
|
-
def assert_true(val, msg)
|
66
|
-
return error(400, msg) if val == true
|
67
|
-
end
|
68
|
-
|
69
|
-
def assert_sha1(val)
|
70
|
-
return error(400, "#{val} is not a sha1 digest") unless is_sha1?(val)
|
53
|
+
end
|
54
|
+
|
55
|
+
post "/:token/key/:key/?" do
|
56
|
+
carefully do
|
57
|
+
assert_token && check_token
|
58
|
+
bone = check_signature
|
59
|
+
value = body_content # don't modify content in any way
|
60
|
+
bone.set params[:key], value
|
71
61
|
end
|
72
|
-
|
73
|
-
|
74
|
-
|
62
|
+
end
|
63
|
+
|
64
|
+
delete "/destroy/:token/?" do
|
65
|
+
carefully do
|
66
|
+
assert_token && check_token
|
67
|
+
bone = check_signature
|
68
|
+
Bone.destroy request_token
|
75
69
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
70
|
+
end
|
71
|
+
|
72
|
+
post "/generate/?" do
|
73
|
+
carefully do
|
74
|
+
token, secret = *Bone.generate
|
75
|
+
token.nil? ? generic_error : [token, secret].join($/)
|
79
76
|
end
|
80
|
-
|
81
|
-
|
77
|
+
end
|
78
|
+
|
79
|
+
post "/register/:token/?" do
|
80
|
+
carefully do
|
81
|
+
generic_error '[register-disabled]' unless Boned.allow_register
|
82
|
+
assert_secret
|
83
|
+
generic_error "[rereg-attempt]" if Bone.token? request_token
|
84
|
+
token = Bone.register request_token, request_secret
|
85
|
+
token.nil? ? generic_error("[register-failed]") : token
|
82
86
|
end
|
83
|
-
|
87
|
+
end
|
88
|
+
|
89
|
+
helpers do
|
90
|
+
#Bone.debug = true
|
84
91
|
end
|
85
92
|
end
|
86
93
|
|
87
|
-
|
94
|
+
|
95
|
+
class Boned::API::Stub < Boned::APIBase
|
88
96
|
get '/' do
|
89
97
|
content_type 'text/plain'
|
90
98
|
"Do you want to get bones?"
|
91
99
|
end
|
92
100
|
end
|
93
101
|
|
94
|
-
require 'boned/api/service'
|
data/lib/boned/app.rb
ADDED
File without changes
|