wd_sinatra 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +148 -0
- data/Rakefile +2 -0
- data/bin/wd_sinatra +47 -0
- data/lib/wd_sinatra.rb +7 -0
- data/lib/wd_sinatra/app_loader.rb +120 -0
- data/lib/wd_sinatra/sinatra_ext.rb +117 -0
- data/lib/wd_sinatra/test_helpers.rb +204 -0
- data/lib/wd_sinatra/version.rb +5 -0
- data/templates/Gemfile +23 -0
- data/templates/Guardfile +13 -0
- data/templates/Rakefile +32 -0
- data/templates/api/hello_world.rb +29 -0
- data/templates/bin/console +7 -0
- data/templates/config.ru +5 -0
- data/templates/config/app.rb +5 -0
- data/templates/config/environments/default.rb +3 -0
- data/templates/config/environments/production.rb +2 -0
- data/templates/config/environments/test.rb +3 -0
- data/templates/config/hooks.rb +74 -0
- data/templates/config/middleware.rb +0 -0
- data/templates/config/sinatra_config.rb +12 -0
- data/templates/lib/body_parser.rb +24 -0
- data/templates/lib/tasks/doc.rake +39 -0
- data/templates/lib/tasks/doc_generator/bootstrap/.gitignore +4 -0
- data/templates/lib/tasks/doc_generator/bootstrap/LICENSE +176 -0
- data/templates/lib/tasks/doc_generator/bootstrap/Makefile +47 -0
- data/templates/lib/tasks/doc_generator/bootstrap/README.md +105 -0
- data/templates/lib/tasks/doc_generator/bootstrap/bootstrap.css +2467 -0
- data/templates/lib/tasks/doc_generator/bootstrap/bootstrap.min.css +356 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/css/docs.css +317 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/ico/bootstrap-apple-114x114.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/ico/bootstrap-apple-57x57.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/ico/bootstrap-apple-72x72.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/ico/favicon.ico +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/bird.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/browsers.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/example-diagram-01.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/example-diagram-02.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/example-diagram-03.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/grid-18px.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/img/twitter-logo-no-bird.png +0 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/js/application.js +52 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/js/google-code-prettify/prettify.css +94 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/assets/js/google-code-prettify/prettify.js +28 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/index.html +2037 -0
- data/templates/lib/tasks/doc_generator/bootstrap/docs/javascript.html +798 -0
- data/templates/lib/tasks/doc_generator/bootstrap/examples/container-app.html +119 -0
- data/templates/lib/tasks/doc_generator/bootstrap/examples/fluid.html +122 -0
- data/templates/lib/tasks/doc_generator/bootstrap/examples/hero.html +79 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-alerts.js +124 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-buttons.js +64 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-dropdown.js +55 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-modal.js +260 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-popover.js +90 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-scrollspy.js +107 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-tabs.js +80 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/bootstrap-twipsy.js +321 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/index.html +40 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-alerts.js +41 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-buttons.js +42 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-dropdown.js +52 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-modal.js +151 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-popover.js +76 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-scrollspy.js +31 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-tabs.js +77 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/unit/bootstrap-twipsy.js +81 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/vendor/qunit.css +232 -0
- data/templates/lib/tasks/doc_generator/bootstrap/js/tests/vendor/qunit.js +1510 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/bootstrap.less +26 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/forms.less +479 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/mixins.less +222 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/patterns.less +1060 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/reset.less +141 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/scaffolding.less +139 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/tables.less +224 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/type.less +187 -0
- data/templates/lib/tasks/doc_generator/bootstrap/lib/variables.less +60 -0
- data/templates/lib/tasks/doc_generator/template.erb +117 -0
- data/templates/public/favicon.ico +0 -0
- data/wd-sinatra.gemspec +22 -0
- metadata +154 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
ENV['RACK_ENV'] ||= 'test'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'json'
|
6
|
+
require 'json_response_verification'
|
7
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'bootloader')
|
8
|
+
|
9
|
+
require 'minitest/autorun'
|
10
|
+
|
11
|
+
ENV['NO_PRINT_ROUTES'] = 'true'
|
12
|
+
Bootloader.start
|
13
|
+
WeaselDiesel.send(:include, JSONResponseVerification)
|
14
|
+
|
15
|
+
ActiveRecord::Base.logger = nil
|
16
|
+
|
17
|
+
class Requester
|
18
|
+
include ::Rack::Test::Methods
|
19
|
+
|
20
|
+
def app
|
21
|
+
Sinatra::Application
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module TestApi
|
26
|
+
module_function
|
27
|
+
|
28
|
+
URL_PLACEHOLDER = /\/*(:[a-z A-Z _]+)\/*/
|
29
|
+
INTERNAL_X_HEADER = AuthHelpers::INTERNAL_X_HEADER[/HTTP_(.*)/, 1] # strip the header marker added by Rack
|
30
|
+
MOBILE_X_HEADER = AuthHelpers::MOBILE_X_HEADER[/HTTP_(.*)/, 1] # strip the header marker added by Rack
|
31
|
+
|
32
|
+
def request(verb, uri, params={}, headers=nil)
|
33
|
+
params ||= {}
|
34
|
+
service_uri = uri.dup
|
35
|
+
matching = uri.scan URL_PLACEHOLDER
|
36
|
+
unless matching.empty?
|
37
|
+
# replace the placeholder by real value
|
38
|
+
matching.flatten.each_with_index do |str, idx|
|
39
|
+
key = str.delete(":").to_sym
|
40
|
+
value = params[key].to_s
|
41
|
+
# delete the value from the params
|
42
|
+
params.delete(key)
|
43
|
+
uri = uri.gsub(str, value)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
request = Requester.new
|
48
|
+
yield request if block_given?
|
49
|
+
headers.each {|name, value| request.header(name, value) } if headers
|
50
|
+
response = request.send(verb, uri, params)
|
51
|
+
@json_response = JsonWrapperResponse.new(response, :verb => verb, :uri => service_uri)
|
52
|
+
end
|
53
|
+
|
54
|
+
def mobile_account=(account)
|
55
|
+
@account = account
|
56
|
+
end
|
57
|
+
|
58
|
+
def get(uri, params=nil, headers=nil)
|
59
|
+
request(:get, uri, params, headers)
|
60
|
+
end
|
61
|
+
|
62
|
+
def internal_get(uri, params=nil, headers=nil)
|
63
|
+
get(uri, params, valid_internal_api_headers(headers))
|
64
|
+
end
|
65
|
+
|
66
|
+
def mobile_get(uri, params=nil, headers=nil)
|
67
|
+
request(:get, uri, params, mobile_headers(headers))
|
68
|
+
end
|
69
|
+
|
70
|
+
def post(uri, params=nil, headers=nil)
|
71
|
+
request(:post, uri, params, headers)
|
72
|
+
end
|
73
|
+
|
74
|
+
def internal_post(uri, params=nil, headers=nil)
|
75
|
+
post(uri, params, valid_internal_api_headers(headers))
|
76
|
+
end
|
77
|
+
|
78
|
+
def mobile_post(uri, params=nil, headers=nil)
|
79
|
+
request(:post, uri, params, mobile_headers(headers))
|
80
|
+
end
|
81
|
+
|
82
|
+
def put(uri, params=nil, headers=nil)
|
83
|
+
request(:put, uri, params, headers)
|
84
|
+
end
|
85
|
+
|
86
|
+
def internal_put(uri, params=nil, headers=nil)
|
87
|
+
put(uri, params, valid_internal_api_headers(headers))
|
88
|
+
end
|
89
|
+
|
90
|
+
def mobile_put(uri, params=nil, headers=nil)
|
91
|
+
request(:put, uri, params, mobile_headers(headers))
|
92
|
+
end
|
93
|
+
|
94
|
+
def delete(uri, params=nil, headers=nil)
|
95
|
+
request(:delete, uri, params, headers)
|
96
|
+
end
|
97
|
+
|
98
|
+
def internal_delete(uri, params=nil, headers=nil)
|
99
|
+
delete(uri, params, valid_internal_api_headers(headers))
|
100
|
+
end
|
101
|
+
|
102
|
+
def mobile_delete(uri, params=nil, headers=nil)
|
103
|
+
request(:delete, uri, params, mobile_headers(headers))
|
104
|
+
end
|
105
|
+
|
106
|
+
def head(uri, params=nil, headers=nil)
|
107
|
+
request(:head, uri, params, headers)
|
108
|
+
end
|
109
|
+
|
110
|
+
def internal_head(uri, params=nil, headers=nil)
|
111
|
+
head(uri, params, valid_internal_api_headers(headers))
|
112
|
+
end
|
113
|
+
|
114
|
+
def mobile_head(uri, params=nil, headers=nil)
|
115
|
+
request(:head, uri, params, mobile_headers(headers))
|
116
|
+
end
|
117
|
+
|
118
|
+
def json_response
|
119
|
+
@json_response
|
120
|
+
end
|
121
|
+
|
122
|
+
def last_response
|
123
|
+
@json_response.rest_response if @json_response
|
124
|
+
end
|
125
|
+
|
126
|
+
def valid_internal_api_headers(headers)
|
127
|
+
custom_headers = {INTERNAL_X_HEADER => AuthHelpers::ALLOWED_API_KEYS[0]}
|
128
|
+
custom_headers.merge!(headers) if headers
|
129
|
+
custom_headers
|
130
|
+
end
|
131
|
+
|
132
|
+
def mobile_headers(headers)
|
133
|
+
custom_headers = {MOBILE_X_HEADER => @account ? Base64.urlsafe_encode64(@account.mobile_token) : nil}
|
134
|
+
custom_headers.merge!(headers) if headers
|
135
|
+
custom_headers
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Wrapper around a rest response
|
142
|
+
class JsonWrapperResponse
|
143
|
+
extend Forwardable
|
144
|
+
|
145
|
+
attr_reader :rest_response
|
146
|
+
attr_reader :verb
|
147
|
+
attr_reader :uri
|
148
|
+
|
149
|
+
def initialize(response, opts={})
|
150
|
+
@rest_response = response
|
151
|
+
@verb = opts[:verb]
|
152
|
+
@uri = opts[:uri]
|
153
|
+
end
|
154
|
+
|
155
|
+
def body
|
156
|
+
@body ||= JSON.load(rest_response.body) rescue rest_response.body
|
157
|
+
end
|
158
|
+
|
159
|
+
def success?
|
160
|
+
@rest_response.status == 200
|
161
|
+
end
|
162
|
+
|
163
|
+
def redirected?
|
164
|
+
@rest_response.status.to_s =~ /30\d/
|
165
|
+
end
|
166
|
+
|
167
|
+
def [](val)
|
168
|
+
if body
|
169
|
+
body[val.to_s]
|
170
|
+
else
|
171
|
+
nil
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def method_missing(meth, *args)
|
176
|
+
body.send(meth, args)
|
177
|
+
end
|
178
|
+
|
179
|
+
def_delegators :rest_response, :code, :headers, :raw_headers, :cookies, :status, :errors
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
# Custom assertions
|
184
|
+
def assert_api_response(response=nil, message=nil)
|
185
|
+
response ||= TestApi.json_response
|
186
|
+
print response.rest_response.errors if response.status === 500
|
187
|
+
assert response.success?, message || ["Body: #{response.rest_response.body}", "Errors: #{response.errors}", "Status code: #{response.status}"].join("\n")
|
188
|
+
service = WSList.all.find{|s| s.verb == response.verb && s.url == response.uri[1..-1]}
|
189
|
+
raise "Service for (#{response.verb.upcase} #{response.uri[1..-1]}) not found" unless service
|
190
|
+
unless service.response.nodes.empty?
|
191
|
+
assert response.body.is_a?(Hash), "Invalid JSON response:\n#{response.body}"
|
192
|
+
valid, errors = service.validate_hash_response(response.body)
|
193
|
+
assert valid, errors.join(" & ") || message
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def assert_api_response_with_redirection(redirection_url=nil)
|
198
|
+
response = TestApi.json_response
|
199
|
+
print response.rest_response.errors if response.status === 500
|
200
|
+
assert response.status == 302, "Redirection expect, but got #{response.status}"
|
201
|
+
if redirection_url
|
202
|
+
assert response.headers["location"], redirection_url
|
203
|
+
end
|
204
|
+
end
|
data/templates/Gemfile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# web engine
|
4
|
+
gem "sinatra", "1.3.2"
|
5
|
+
# service DSL
|
6
|
+
gem "weasel_diesel"
|
7
|
+
gem "wd_sinatra"
|
8
|
+
|
9
|
+
|
10
|
+
if RUBY_VERSION =~ /1.8/
|
11
|
+
gem 'backports', '2.3.0'
|
12
|
+
gem 'json'
|
13
|
+
end
|
14
|
+
|
15
|
+
if ENV['RACK_ENV'] != "production"
|
16
|
+
gem "rack-test", "0.6.1"
|
17
|
+
# gem "foreman"
|
18
|
+
# gem "puma"
|
19
|
+
gem "minitest"
|
20
|
+
# gem "guard-puma"
|
21
|
+
# gem "guard-minitest"
|
22
|
+
gem "rake"
|
23
|
+
end
|
data/templates/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'puma' do
|
5
|
+
watch('Gemfile.lock')
|
6
|
+
watch(%r{^config|lib/.*})
|
7
|
+
end
|
8
|
+
|
9
|
+
guard 'minitest', :test_file_patterns => '*_test.rb' do
|
10
|
+
watch(%r|^test/(.*)_test\.rb|)
|
11
|
+
watch(%r{^api/(.*/)?([^/]+)\.rb$}) { |m| "test/api/#{m[1]}#{m[2]}_test.rb" }
|
12
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
13
|
+
end
|
data/templates/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
Bundler.setup
|
6
|
+
require 'wd_sinatra/app_loader'
|
7
|
+
|
8
|
+
root = File.expand_path(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
Rake::TestTask.new do |t|
|
11
|
+
t.libs << "."
|
12
|
+
t.libs << 'test'
|
13
|
+
t.pattern = "test/**/*_test.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
task :default => :test
|
17
|
+
|
18
|
+
# boot the app
|
19
|
+
task :setup_app do
|
20
|
+
ENV['DONT_CONNECT'] = 'true'
|
21
|
+
WDSinatra::AppLoader.server(root)
|
22
|
+
end
|
23
|
+
|
24
|
+
task :environment do
|
25
|
+
ENV['DONT_CONNECT'] = nil
|
26
|
+
WDSinatra::AppLoader.server(root)
|
27
|
+
end
|
28
|
+
|
29
|
+
WDSinatra::AppLoader.set_loadpath(root)
|
30
|
+
Dir.glob("lib/tasks/**/*.rake").each do |task_file|
|
31
|
+
load task_file
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe_service "hello_world" do |service|
|
2
|
+
service.formats :json
|
3
|
+
service.http_verb :get
|
4
|
+
service.disable_auth # on by default
|
5
|
+
|
6
|
+
# INPUT
|
7
|
+
service.param.string :name, :default => 'World'
|
8
|
+
|
9
|
+
# OUTPUT
|
10
|
+
service.response do |response|
|
11
|
+
response.object do |obj|
|
12
|
+
obj.string :message, :doc => "The greeting message sent back. Defaults to 'World'"
|
13
|
+
obj.datetime :at, :doc => "The timestamp of when the message was dispatched"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# DOCUMENTATION
|
18
|
+
service.documentation do |doc|
|
19
|
+
doc.overall "This service provides a simple hello world implementation example."
|
20
|
+
doc.param :name, "The name of the person to greet."
|
21
|
+
doc.example "<code>curl -I 'http://localhost:9292/hello_world?name=Matt'</code>"
|
22
|
+
end
|
23
|
+
|
24
|
+
# ACTION/IMPLEMENTATION
|
25
|
+
service.implementation do
|
26
|
+
{:message => "Hello #{params[:name]}", :at => Time.now}.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/templates/config.ru
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'body_parser' # from the lib folder
|
2
|
+
# Change the JSON parser if you want to use Yajl for instance.
|
3
|
+
require 'json'
|
4
|
+
BodyParser.json_parser = JSON
|
5
|
+
|
6
|
+
module WDSinatraHooks
|
7
|
+
|
8
|
+
MOBILE_X_HEADER = 'HTTP_X_MOBILE_TOKEN'
|
9
|
+
INTERNAL_X_HEADER = 'HTTP_X_INTERNAL_API_KEY'
|
10
|
+
JSON_BODY_VERBS = %w(POST PUT DELETE)
|
11
|
+
|
12
|
+
####### HOOKS #############################
|
13
|
+
#
|
14
|
+
# This hook gets called before the params
|
15
|
+
# are being verified. It's a good place to add a content type
|
16
|
+
# handler for instance like shown below.
|
17
|
+
# If you don't need this hook, just delete it.
|
18
|
+
# Note that you have access to the request context, see sinatra_ext.rb
|
19
|
+
# in the wd_sinatra repository to see how this is implemented.
|
20
|
+
#
|
21
|
+
# @param [Hash] params the incoming params.
|
22
|
+
# processed.
|
23
|
+
# @returns [Hash] the pre processed params.
|
24
|
+
def params_preprocessor_hook(params)
|
25
|
+
if JSON_BODY_VERBS.include?(request.request_method)
|
26
|
+
BodyParser.parse(params, request.body, request.content_type)
|
27
|
+
else
|
28
|
+
params
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# This hook gets called after the params are being verified.
|
33
|
+
# You can use this hook to modify the params before sending them to
|
34
|
+
# your service.
|
35
|
+
#
|
36
|
+
# @param [Hash] params the incoming params.
|
37
|
+
# processed.
|
38
|
+
# @returns [Hash] the post processed params.
|
39
|
+
# def params_postprocessor_hook(params)
|
40
|
+
# end
|
41
|
+
|
42
|
+
# This hook gets called before dispatching any
|
43
|
+
# requests.
|
44
|
+
#
|
45
|
+
# Implementation example
|
46
|
+
def pre_dispatch_hook
|
47
|
+
if service.extra[:mobile]
|
48
|
+
mobile_auth_check
|
49
|
+
elsif service.extra[:internal]
|
50
|
+
internal_api_key_check
|
51
|
+
elsif !service.auth_required
|
52
|
+
return
|
53
|
+
else
|
54
|
+
halt 403 # protect by default
|
55
|
+
end
|
56
|
+
end
|
57
|
+
#
|
58
|
+
#########################################
|
59
|
+
|
60
|
+
# AUTHENTICATION
|
61
|
+
|
62
|
+
# Implementation example
|
63
|
+
def mobile_auth_check
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
# Implementation example
|
68
|
+
def internal_api_key_check
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
Sinatra::Helpers.send(:include, WDSinatraHooks)
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
set :environment, RACK_ENV
|
2
|
+
set :root, WDSinata.root_path
|
3
|
+
set :app_file, __FILE__
|
4
|
+
set :public_folder, File.join(WDSinata.root_path, "public")
|
5
|
+
# Checks on static files before dispatching calls
|
6
|
+
enable :static
|
7
|
+
# enable rack session
|
8
|
+
enable :session
|
9
|
+
set :raise_errors, false
|
10
|
+
# enable that option to run by calling this file automatically (without using the config.ru file)
|
11
|
+
# enable :run
|
12
|
+
use Rack::ContentLength
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module BodyParser
|
2
|
+
module_function
|
3
|
+
|
4
|
+
JSON_TYPE = "application/json"
|
5
|
+
|
6
|
+
# Parses the body
|
7
|
+
def parse(params, body, content_type)
|
8
|
+
case content_type
|
9
|
+
when JSON_TYPE
|
10
|
+
params.merge(json_parser.parse(body.string))
|
11
|
+
else
|
12
|
+
params
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def json_parser=(parser_klass)
|
17
|
+
@json_parser = parser_klass
|
18
|
+
end
|
19
|
+
|
20
|
+
def json_parser
|
21
|
+
@json_parser
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|