midb 1.0.4 → 1.0.5
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 +4 -4
- data/lib/midb.rb +2 -1
- data/lib/midb/server_controller.rb +197 -257
- data/lib/midb/serverengine_controller.rb +149 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aee36621935f7db48f10ae5e199e1e04fa6af949
|
4
|
+
data.tar.gz: 125adfc8de0773ea3dc2c87bafa110ca84f011b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdc131cdc0c230b93d3f323fd712e4e9eb53fee916ec1385ad4caa9bd810e37b7039907ac6776e64923084908832006fe667854aef9fd1568e09824aca2b9ef1
|
7
|
+
data.tar.gz: 496d34906597bca28076bdc7cdb67f425d0fe498dccb403f1a1c57a59c1aeaa43361eee11913922432f76e2f1619ebb27ec6f85dcc0272891d3ea4976eda8649
|
data/lib/midb.rb
CHANGED
@@ -2,6 +2,7 @@ require 'midb/server_model'
|
|
2
2
|
require 'midb/server_view'
|
3
3
|
require 'midb/errors_view'
|
4
4
|
require 'midb/security_controller'
|
5
|
+
require 'midb/serverengine_controller'
|
5
6
|
|
6
7
|
require 'yaml'
|
7
8
|
require 'socket'
|
@@ -38,7 +39,195 @@ module MIDB
|
|
38
39
|
@config = Hash.new()
|
39
40
|
@port = 8081
|
40
41
|
|
41
|
-
|
42
|
+
#####################
|
43
|
+
# Server commands #
|
44
|
+
#####################
|
45
|
+
|
46
|
+
# $ midb help
|
47
|
+
#
|
48
|
+
# Show some help for either midb or a command.
|
49
|
+
def self.do_help()
|
50
|
+
if @args.length > 1
|
51
|
+
case @args[1]
|
52
|
+
when "bootstrap"
|
53
|
+
MIDB::ServerView.help(:bootstrap)
|
54
|
+
when "set"
|
55
|
+
MIDB::ServerView.help(:set)
|
56
|
+
when "start"
|
57
|
+
MIDB::ServerView.help(:start)
|
58
|
+
when "serve"
|
59
|
+
MIDB::ServerView.help(:serve)
|
60
|
+
when "unserve"
|
61
|
+
MIDB::ServerView.help(:unserve)
|
62
|
+
else
|
63
|
+
MIDB::ErrorsView.die(:no_help)
|
64
|
+
end
|
65
|
+
else
|
66
|
+
MIDB::ServerView.help(:list)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# $ midb bootstrap
|
71
|
+
#
|
72
|
+
# Bootstrap a new midb project in the active directory.
|
73
|
+
def self.do_bootstrap()
|
74
|
+
if File.file?(".midb.yaml")
|
75
|
+
MIDB::ErrorsView.die(:already_project)
|
76
|
+
else
|
77
|
+
# If the file doesn't exist it, create it with the default stuff
|
78
|
+
@config["serves"] = []
|
79
|
+
@config["status"] = :asleep # The server is initially asleep
|
80
|
+
@config["apikey"] = "midb-api" # This should be changed, it's the private API key
|
81
|
+
@config["dbengine"] = :sqlite3 # SQLite is the default engine
|
82
|
+
# Default DB configuration for MySQL and other engines
|
83
|
+
@config["dbhost"] = "localhost"
|
84
|
+
@config["dbport"] = 3306
|
85
|
+
@config["dbuser"] = "nobody"
|
86
|
+
@config["dbpassword"] = "openaccess"
|
87
|
+
File.open(".midb.yaml", 'w') do |l|
|
88
|
+
l.write @config.to_yaml
|
89
|
+
end
|
90
|
+
# Create json/ and db/ directory if it doesn't exist
|
91
|
+
Dir.mkdir("json") unless File.exists?("json")
|
92
|
+
Dir.mkdir("db") unless File.exists?("db")
|
93
|
+
MIDB::ServerView.info(:bootstrap)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# $ midb set
|
98
|
+
#
|
99
|
+
# Set the config for the project.
|
100
|
+
# Check syntax
|
101
|
+
def self.do_set()
|
102
|
+
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
103
|
+
subset = @args[1].split(":")[0]
|
104
|
+
subcmd = @args[1].split(":")[1]
|
105
|
+
set = @args.length < 3 ? false : true
|
106
|
+
setter = @args[2] if set
|
107
|
+
case subset
|
108
|
+
when "db"
|
109
|
+
# DB Config
|
110
|
+
case subcmd
|
111
|
+
when "engine"
|
112
|
+
if set
|
113
|
+
@config["dbengine"] = case setter.downcase
|
114
|
+
when "sqlite3" then :sqlite3
|
115
|
+
when "mysql" then :mysql
|
116
|
+
else :undef
|
117
|
+
end
|
118
|
+
if @config["dbengine"] == :undef
|
119
|
+
MIDB::ErrorsView.die(:unsupported_engine)
|
120
|
+
@config["dbengine"] = :sqlite3
|
121
|
+
end
|
122
|
+
end
|
123
|
+
MIDB::ServerView.out_config(:dbengine)
|
124
|
+
when "host"
|
125
|
+
@config["dbhost"] = setter if set
|
126
|
+
MIDB::ServerView.out_config(:dbhost)
|
127
|
+
when "port"
|
128
|
+
@config["dbport"] = setter if set
|
129
|
+
MIDB::ServerView.out_config(:dbport)
|
130
|
+
when "user"
|
131
|
+
@config["dbuser"] = setter if set
|
132
|
+
MIDB::ServerView.out_config(:dbuser)
|
133
|
+
when "password"
|
134
|
+
@config["dbpassword"] = setter if set
|
135
|
+
MIDB::ServerView.out_config(:dbpassword)
|
136
|
+
else
|
137
|
+
MIDB::ErrorsView.die(:synax)
|
138
|
+
end
|
139
|
+
when "api"
|
140
|
+
case subcmd
|
141
|
+
when "key"
|
142
|
+
@config["apikey"] = setter if set
|
143
|
+
MIDB::ServerView.out_config(:apikey)
|
144
|
+
end
|
145
|
+
else
|
146
|
+
MIDB::ErrorsView.die(:syntax)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# $ midb start
|
151
|
+
#
|
152
|
+
# Start the server (call the loop)
|
153
|
+
def self.do_start()
|
154
|
+
# Check syntax
|
155
|
+
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
156
|
+
MIDB::ErrorsView.die(:syntax) if @args[1].split(":")[0] != "db"
|
157
|
+
# Is the server already started?
|
158
|
+
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
159
|
+
# Are any files being served?
|
160
|
+
MIDB::ErrorsView.die(:no_serves) if @config["serves"].length == 0
|
161
|
+
# If it successfully starts, change our status and notify thru view
|
162
|
+
@args.each do |arg|
|
163
|
+
if arg.split(":")[0] == "db"
|
164
|
+
@db = arg.split(":")[1]
|
165
|
+
elsif arg.split(":")[0] == "port"
|
166
|
+
@port = arg.split(":")[1]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Call the server engine
|
171
|
+
if MIDB::ServerEngineController.start(@port)
|
172
|
+
@config["status"] = :running
|
173
|
+
MIDB::ServerView.success()
|
174
|
+
else
|
175
|
+
MIDB::ErrorsView.die(:server_error)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# $ midb serve
|
180
|
+
#
|
181
|
+
# Serve a JSON file
|
182
|
+
def self.do_serve()
|
183
|
+
# Check if there's a second argument
|
184
|
+
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
185
|
+
# Is the server running? It shouldn't
|
186
|
+
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
187
|
+
# Is there such file as @args[1]?
|
188
|
+
MIDB::ErrorsView.die(:file_404) unless File.file?("./json/" + @args[1])
|
189
|
+
# Is the file a JSON file?
|
190
|
+
MIDB::ErrorsView.die(:not_json) unless File.extname(@args[1]) == ".json"
|
191
|
+
# Is the file already loaded?
|
192
|
+
MIDB::ErrorsView.die(:json_exists) if @config["serves"].include? @args[1]
|
193
|
+
|
194
|
+
# Tests passed, so let's add the file to the served list!
|
195
|
+
@config["serves"].push @args[1]
|
196
|
+
MIDB::ServerView.show_serving()
|
197
|
+
end
|
198
|
+
|
199
|
+
# $ midb unserve
|
200
|
+
#
|
201
|
+
# Stop serving a JSON file
|
202
|
+
def self.do_unserve()
|
203
|
+
# Check if there's a second argument
|
204
|
+
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
205
|
+
# Is the server running? It shouldn't
|
206
|
+
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
207
|
+
# Is the file already loaded?
|
208
|
+
MIDB::ErrorsView.die(:json_not_exists) unless @config["serves"].include? @args[1]
|
209
|
+
|
210
|
+
# Delete it!
|
211
|
+
@config["serves"].delete @args[1]
|
212
|
+
MIDB::ServerView.show_serving()
|
213
|
+
end
|
214
|
+
|
215
|
+
# $ midb stop
|
216
|
+
#
|
217
|
+
# Stop the server in case it's running in the background.
|
218
|
+
def self.do_stop()
|
219
|
+
# Is the server running?
|
220
|
+
MIDB::ErrorsView.die(:server_not_running) unless @config["status"] == :running
|
221
|
+
|
222
|
+
@config["status"] = :asleep
|
223
|
+
MIDB::ServerView.server_stopped()
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
# $ midb
|
229
|
+
#
|
230
|
+
# Decide the behavior of the server in function of the arguments.
|
42
231
|
def self.init()
|
43
232
|
# We should have at least one argument, which can be `run` or `serve`
|
44
233
|
MIDB::ErrorsView.die(:noargs) if @args.length < 1
|
@@ -54,288 +243,39 @@ module MIDB
|
|
54
243
|
case @args[0]
|
55
244
|
|
56
245
|
# Command: help
|
57
|
-
# Shows the help
|
58
246
|
when "help"
|
59
|
-
|
60
|
-
case @args[1]
|
61
|
-
when "bootstrap"
|
62
|
-
MIDB::ServerView.help(:bootstrap)
|
63
|
-
when "set"
|
64
|
-
MIDB::ServerView.help(:set)
|
65
|
-
when "start"
|
66
|
-
MIDB::ServerView.help(:start)
|
67
|
-
when "serve"
|
68
|
-
MIDB::ServerView.help(:serve)
|
69
|
-
when "unserve"
|
70
|
-
MIDB::ServerView.help(:unserve)
|
71
|
-
else
|
72
|
-
MIDB::ErrorsView.die(:no_help)
|
73
|
-
end
|
74
|
-
else
|
75
|
-
MIDB::ServerView.help(:list)
|
76
|
-
end
|
247
|
+
self.do_help()
|
77
248
|
|
78
249
|
# Command: bootstrap
|
79
|
-
# Create config file and initial directories
|
80
250
|
when "bootstrap"
|
81
|
-
|
82
|
-
MIDB::ErrorsView.die(:already_project)
|
83
|
-
else
|
84
|
-
# If the file doesn't exist it, create it with the default stuff
|
85
|
-
@config["serves"] = []
|
86
|
-
@config["status"] = :asleep # The server is initially asleep
|
87
|
-
@config["apikey"] = "midb-api" # This should be changed, it's the private API key
|
88
|
-
@config["dbengine"] = :sqlite3 # SQLite is the default engine
|
89
|
-
# Default DB configuration for MySQL and other engines
|
90
|
-
@config["dbhost"] = "localhost"
|
91
|
-
@config["dbport"] = 3306
|
92
|
-
@config["dbuser"] = "nobody"
|
93
|
-
@config["dbpassword"] = "openaccess"
|
94
|
-
File.open(".midb.yaml", 'w') do |l|
|
95
|
-
l.write @config.to_yaml
|
96
|
-
end
|
97
|
-
# Create json/ and db/ directory if it doesn't exist
|
98
|
-
Dir.mkdir("json") unless File.exists?("json")
|
99
|
-
Dir.mkdir("db") unless File.exists?("db")
|
100
|
-
MIDB::ServerView.info(:bootstrap)
|
101
|
-
end
|
251
|
+
self.do_bootstrap()
|
102
252
|
|
103
253
|
# Command: set
|
104
|
-
# Sets configuration factors.
|
105
254
|
when "set"
|
106
|
-
|
107
|
-
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
108
|
-
subset = @args[1].split(":")[0]
|
109
|
-
subcmd = @args[1].split(":")[1]
|
110
|
-
set = @args.length < 3 ? false : true
|
111
|
-
setter = @args[2] if set
|
112
|
-
case subset
|
113
|
-
when "db"
|
114
|
-
# DB Config
|
115
|
-
case subcmd
|
116
|
-
when "engine"
|
117
|
-
if set
|
118
|
-
@config["dbengine"] = case setter.downcase
|
119
|
-
when "sqlite3" then :sqlite3
|
120
|
-
when "mysql" then :mysql
|
121
|
-
else :undef
|
122
|
-
end
|
123
|
-
if @config["dbengine"] == :undef
|
124
|
-
MIDB::ErrorsView.die(:unsupported_engine)
|
125
|
-
@config["dbengine"] = :sqlite3
|
126
|
-
end
|
127
|
-
end
|
128
|
-
MIDB::ServerView.out_config(:dbengine)
|
129
|
-
when "host"
|
130
|
-
@config["dbhost"] = setter if set
|
131
|
-
MIDB::ServerView.out_config(:dbhost)
|
132
|
-
when "port"
|
133
|
-
@config["dbport"] = setter if set
|
134
|
-
MIDB::ServerView.out_config(:dbport)
|
135
|
-
when "user"
|
136
|
-
@config["dbuser"] = setter if set
|
137
|
-
MIDB::ServerView.out_config(:dbuser)
|
138
|
-
when "password"
|
139
|
-
@config["dbpassword"] = setter if set
|
140
|
-
MIDB::ServerView.out_config(:dbpassword)
|
141
|
-
else
|
142
|
-
MIDB::ErrorsView.die(:synax)
|
143
|
-
end
|
144
|
-
when "api"
|
145
|
-
case subcmd
|
146
|
-
when "key"
|
147
|
-
@config["apikey"] = setter if set
|
148
|
-
MIDB::ServerView.out_config(:apikey)
|
149
|
-
end
|
150
|
-
else
|
151
|
-
MIDB::ErrorsView.die(:syntax)
|
152
|
-
end
|
255
|
+
self.do_set()
|
153
256
|
|
154
257
|
|
155
258
|
# Command: start
|
156
|
-
# Starts the server
|
157
259
|
when "start"
|
158
|
-
|
159
|
-
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
160
|
-
MIDB::ErrorsView.die(:syntax) if @args[1].split(":")[0] != "db"
|
161
|
-
# Is the server already started?
|
162
|
-
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
163
|
-
# Are any files being served?
|
164
|
-
MIDB::ErrorsView.die(:no_serves) if @config["serves"].length == 0
|
165
|
-
# If it successfully starts, change our status and notify thru view
|
166
|
-
@args.each do |arg|
|
167
|
-
if arg.split(":")[0] == "db"
|
168
|
-
@db = arg.split(":")[1]
|
169
|
-
elsif arg.split(":")[0] == "port"
|
170
|
-
@port = arg.split(":")[1]
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
if self.start(@port)
|
175
|
-
@config["status"] = :running
|
176
|
-
MIDB::ServerView.success()
|
177
|
-
else
|
178
|
-
MIDB::ErrorsView.die(:server_error)
|
179
|
-
end
|
260
|
+
self.do_start()
|
180
261
|
|
181
262
|
# Command: serve
|
182
263
|
# Serves a JSON file
|
183
264
|
when "serve"
|
184
|
-
|
185
|
-
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
186
|
-
# Is the server running? It shouldn't
|
187
|
-
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
188
|
-
# Is there such file as @args[1]?
|
189
|
-
MIDB::ErrorsView.die(:file_404) unless File.file?("./json/" + @args[1])
|
190
|
-
# Is the file a JSON file?
|
191
|
-
MIDB::ErrorsView.die(:not_json) unless File.extname(@args[1]) == ".json"
|
192
|
-
# Is the file already loaded?
|
193
|
-
MIDB::ErrorsView.die(:json_exists) if @config["serves"].include? @args[1]
|
194
|
-
|
195
|
-
# Tests passed, so let's add the file to the served list!
|
196
|
-
@config["serves"].push @args[1]
|
197
|
-
MIDB::ServerView.show_serving()
|
265
|
+
self.do_serve()
|
198
266
|
|
199
267
|
# Command: unserve
|
200
268
|
# Stop serving a JSON file.
|
201
269
|
when "unserve"
|
202
|
-
|
203
|
-
MIDB::ErrorsView.die(:syntax) if @args.length < 2
|
204
|
-
# Is the server running? It shouldn't
|
205
|
-
MIDB::ErrorsView.die(:server_already_started) if @config["status"] == :running
|
206
|
-
# Is the file already loaded?
|
207
|
-
MIDB::ErrorsView.die(:json_not_exists) unless @config["serves"].include? @args[1]
|
208
|
-
|
209
|
-
# Delete it!
|
210
|
-
@config["serves"].delete @args[1]
|
211
|
-
MIDB::ServerView.show_serving()
|
270
|
+
self.do_unserve()
|
212
271
|
|
213
272
|
# Command: stop
|
214
273
|
# Stops the server.
|
215
274
|
when "stop"
|
216
|
-
|
217
|
-
MIDB::ErrorsView.die(:server_not_running) unless @config["status"] == :running
|
218
|
-
|
219
|
-
@config["status"] = :asleep
|
220
|
-
MIDB::ServerView.server_stopped()
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# Method: start
|
225
|
-
# Starts the server on the given port (default: 8080)
|
226
|
-
def self.start(port=8081)
|
227
|
-
serv = TCPServer.new("localhost", port)
|
228
|
-
MIDB::ServerView.info(:start, port)
|
229
|
-
|
230
|
-
# Manage the requests
|
231
|
-
loop do
|
232
|
-
socket = serv.accept
|
233
|
-
MIDB::ServerView.info(:incoming_request, socket.addr[3])
|
234
|
-
|
235
|
-
request = self.parse_request(socket.gets)
|
236
|
-
|
237
|
-
# Get a hash with the headers
|
238
|
-
headers = {}
|
239
|
-
while line = socket.gets.split(' ', 2)
|
240
|
-
break if line[0] == ""
|
241
|
-
headers[line[0].chop] = line[1].strip
|
242
|
-
end
|
243
|
-
data = socket.read(headers["Content-Length"].to_i)
|
244
|
-
|
245
|
-
|
246
|
-
MIDB::ServerView.info(:request, request)
|
247
|
-
response_json = Hash.new()
|
248
|
-
|
249
|
-
# Endpoint syntax: ["", FILE, ID, (ACTION)]
|
250
|
-
endpoint = request[1].split("/")
|
251
|
-
ep_file = endpoint[1]
|
252
|
-
|
253
|
-
method = request[0]
|
254
|
-
endpoints = [] # Valid endpoints
|
255
|
-
|
256
|
-
# Load the JSON served files
|
257
|
-
@config["serves"].each do |js|
|
258
|
-
# The filename is a valid endpoint
|
259
|
-
endpoints.push File.basename(js, ".*")
|
260
|
-
end
|
261
|
-
|
262
|
-
# Load the endpoints
|
263
|
-
found = false
|
264
|
-
endpoints.each do |ep|
|
265
|
-
if ep_file == ep
|
266
|
-
found = true
|
267
|
-
MIDB::ServerView.info(:match_json, ep)
|
268
|
-
# Analyze the request and pass it to the model
|
269
|
-
if method == "GET"
|
270
|
-
case endpoint.length
|
271
|
-
when 2
|
272
|
-
# No ID has been specified. Return all the entries
|
273
|
-
# Pass it to the model and get the JSON
|
274
|
-
response_json = MIDB::ServerModel.get_all_entries(@db, ep).to_json
|
275
|
-
when 3
|
276
|
-
# An ID has been specified. Should it exist, return all of its entries.
|
277
|
-
response_json = MIDB::ServerModel.get_entries(@db, ep, endpoint[2]).to_json
|
278
|
-
end
|
279
|
-
else
|
280
|
-
# An action has been specified. We're going to need HTTP authentification here.
|
281
|
-
MIDB::ServerView.info(:auth_required)
|
282
|
-
|
283
|
-
if (not headers.has_key? "Authentication") ||
|
284
|
-
(not MIDB::SecurityController.check?(headers["Authentication"], data, @config["apikey"]))
|
285
|
-
@http_status = "401 Unauthorized"
|
286
|
-
response_json = MIDB::ServerView.json_error(401, "Unauthorized").to_json
|
287
|
-
MIDB::ServerView.info(:no_auth)
|
288
|
-
|
289
|
-
else
|
290
|
-
MIDB::ServerView.info(:auth_success)
|
291
|
-
if method == "POST"
|
292
|
-
response_json = MIDB::ServerModel.post(@db, ep, data).to_json
|
293
|
-
else
|
294
|
-
if endpoint.length >= 3
|
295
|
-
if method == "DELETE"
|
296
|
-
response_json = MIDB::ServerModel.delete(@db, ep, endpoint[2]).to_json
|
297
|
-
elsif method == "PUT"
|
298
|
-
response_json = MIDB::ServerModel.put(@db, ep, endpoint[2], data).to_json
|
299
|
-
end
|
300
|
-
else
|
301
|
-
@http_status = "404 Not Found"
|
302
|
-
response_json = MIDB::ServerView.json_error(404, "Must specify an ID.").to_json
|
303
|
-
end
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
307
|
-
MIDB::ServerView.info(:response, response_json)
|
308
|
-
# Return the results via HTTP
|
309
|
-
socket.print "HTTP/1.1 #{@http_status}\r\n" +
|
310
|
-
"Content-Type: text/json\r\n" +
|
311
|
-
"Content-Length: #{response_json.size}\r\n" +
|
312
|
-
"Connection: close\r\n"
|
313
|
-
socket.print "\r\n"
|
314
|
-
socket.print response_json
|
315
|
-
socket.print "\r\n"
|
316
|
-
MIDB::ServerView.info(:success)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
unless found
|
320
|
-
MIDB::ServerView.info(:not_found)
|
321
|
-
response = MIDB::ServerView.json_error(404, "Invalid API endpoint.").to_json
|
322
|
-
|
323
|
-
socket.print "HTTP/1.1 404 Not Found\r\n" +
|
324
|
-
"Content-Type: text/json\r\n" +
|
325
|
-
"Content-Length: #{response.size}\r\n" +
|
326
|
-
"Connection: close\r\n"
|
327
|
-
socket.print "\r\n"
|
328
|
-
socket.print response
|
329
|
-
end
|
275
|
+
self.do_stop()
|
330
276
|
end
|
331
277
|
end
|
332
278
|
|
333
|
-
# Method: parse_request
|
334
|
-
# Parses an HTTP requests and returns an array [method, uri]
|
335
|
-
def self.parse_request(req)
|
336
|
-
[req.split(" ")[0], req.split(" ")[1]]
|
337
|
-
end
|
338
|
-
|
339
279
|
# Method: save
|
340
280
|
# Saves config to .midb.yaml
|
341
281
|
def self.save()
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'midb/server_controller'
|
2
|
+
require 'midb/server_model'
|
3
|
+
require 'midb/server_view'
|
4
|
+
require 'midb/errors_view'
|
5
|
+
require 'midb/security_controller'
|
6
|
+
|
7
|
+
require 'yaml'
|
8
|
+
require 'socket'
|
9
|
+
require 'uri'
|
10
|
+
require 'json'
|
11
|
+
require 'sqlite3'
|
12
|
+
|
13
|
+
module MIDB
|
14
|
+
# @author unrar
|
15
|
+
# This class handles runs the server engine using sockets and a loop.
|
16
|
+
class ServerEngineController
|
17
|
+
# Attribute declaration here
|
18
|
+
class << self
|
19
|
+
# @!attribute config
|
20
|
+
# @return [Hash] Contains the project's configuration, saved in .midb.yaml
|
21
|
+
# @!attribute db
|
22
|
+
# @return [String] Database name (if SQLite is the engine, file name without extension)
|
23
|
+
# @!attribute http_status
|
24
|
+
# @return [String] HTTP status code and string representation for the header
|
25
|
+
attr_accessor :config, :db, :http_status
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Starts the server on a given port (default: 8081)
|
30
|
+
#
|
31
|
+
# @param port [Fixnum] Port to which the server will listen.
|
32
|
+
def self.start(port=8081)
|
33
|
+
# Copy these values from the server controller
|
34
|
+
@http_status = MIDB::ServerController.http_status
|
35
|
+
@config = MIDB::ServerController.config
|
36
|
+
@db = MIDB::ServerController.db
|
37
|
+
serv = TCPServer.new("localhost", port)
|
38
|
+
MIDB::ServerView.info(:start, port)
|
39
|
+
|
40
|
+
# Manage the requests
|
41
|
+
loop do
|
42
|
+
socket = serv.accept
|
43
|
+
MIDB::ServerView.info(:incoming_request, socket.addr[3])
|
44
|
+
|
45
|
+
request = self.parse_request(socket.gets)
|
46
|
+
|
47
|
+
# Get a hash with the headers
|
48
|
+
headers = {}
|
49
|
+
while line = socket.gets.split(' ', 2)
|
50
|
+
break if line[0] == ""
|
51
|
+
headers[line[0].chop] = line[1].strip
|
52
|
+
end
|
53
|
+
data = socket.read(headers["Content-Length"].to_i)
|
54
|
+
|
55
|
+
|
56
|
+
MIDB::ServerView.info(:request, request)
|
57
|
+
response_json = Hash.new()
|
58
|
+
|
59
|
+
# Endpoint syntax: ["", FILE, ID, (ACTION)]
|
60
|
+
endpoint = request[1].split("/")
|
61
|
+
ep_file = endpoint[1]
|
62
|
+
|
63
|
+
method = request[0]
|
64
|
+
endpoints = [] # Valid endpoints
|
65
|
+
|
66
|
+
# Load the JSON served files
|
67
|
+
@config["serves"].each do |js|
|
68
|
+
# The filename is a valid endpoint
|
69
|
+
endpoints.push File.basename(js, ".*")
|
70
|
+
end
|
71
|
+
|
72
|
+
# Load the endpoints
|
73
|
+
found = false
|
74
|
+
endpoints.each do |ep|
|
75
|
+
if ep_file == ep
|
76
|
+
found = true
|
77
|
+
MIDB::ServerView.info(:match_json, ep)
|
78
|
+
# Analyze the request and pass it to the model
|
79
|
+
if method == "GET"
|
80
|
+
case endpoint.length
|
81
|
+
when 2
|
82
|
+
# No ID has been specified. Return all the entries
|
83
|
+
# Pass it to the model and get the JSON
|
84
|
+
response_json = MIDB::ServerModel.get_all_entries(@db, ep).to_json
|
85
|
+
when 3
|
86
|
+
# An ID has been specified. Should it exist, return all of its entries.
|
87
|
+
response_json = MIDB::ServerModel.get_entries(@db, ep, endpoint[2]).to_json
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# An action has been specified. We're going to need HTTP authentification here.
|
91
|
+
MIDB::ServerView.info(:auth_required)
|
92
|
+
|
93
|
+
if (not headers.has_key? "Authentication") ||
|
94
|
+
(not MIDB::SecurityController.check?(headers["Authentication"], data, @config["apikey"]))
|
95
|
+
@http_status = "401 Unauthorized"
|
96
|
+
response_json = MIDB::ServerView.json_error(401, "Unauthorized").to_json
|
97
|
+
MIDB::ServerView.info(:no_auth)
|
98
|
+
|
99
|
+
else
|
100
|
+
MIDB::ServerView.info(:auth_success)
|
101
|
+
if method == "POST"
|
102
|
+
response_json = MIDB::ServerModel.post(@db, ep, data).to_json
|
103
|
+
else
|
104
|
+
if endpoint.length >= 3
|
105
|
+
if method == "DELETE"
|
106
|
+
response_json = MIDB::ServerModel.delete(@db, ep, endpoint[2]).to_json
|
107
|
+
elsif method == "PUT"
|
108
|
+
response_json = MIDB::ServerModel.put(@db, ep, endpoint[2], data).to_json
|
109
|
+
end
|
110
|
+
else
|
111
|
+
@http_status = "404 Not Found"
|
112
|
+
response_json = MIDB::ServerView.json_error(404, "Must specify an ID.").to_json
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
MIDB::ServerView.info(:response, response_json)
|
118
|
+
# Return the results via HTTP
|
119
|
+
socket.print "HTTP/1.1 #{@http_status}\r\n" +
|
120
|
+
"Content-Type: text/json\r\n" +
|
121
|
+
"Content-Length: #{response_json.size}\r\n" +
|
122
|
+
"Connection: close\r\n"
|
123
|
+
socket.print "\r\n"
|
124
|
+
socket.print response_json
|
125
|
+
socket.print "\r\n"
|
126
|
+
MIDB::ServerView.info(:success)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
unless found
|
130
|
+
MIDB::ServerView.info(:not_found)
|
131
|
+
response = MIDB::ServerView.json_error(404, "Invalid API endpoint.").to_json
|
132
|
+
|
133
|
+
socket.print "HTTP/1.1 404 Not Found\r\n" +
|
134
|
+
"Content-Type: text/json\r\n" +
|
135
|
+
"Content-Length: #{response.size}\r\n" +
|
136
|
+
"Connection: close\r\n"
|
137
|
+
socket.print "\r\n"
|
138
|
+
socket.print response
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Method: parse_request
|
144
|
+
# Parses an HTTP requests and returns an array [method, uri]
|
145
|
+
def self.parse_request(req)
|
146
|
+
[req.split(" ")[0], req.split(" ")[1]]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: midb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- unrar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/midb/server_controller.rb
|
107
107
|
- lib/midb/server_model.rb
|
108
108
|
- lib/midb/server_view.rb
|
109
|
+
- lib/midb/serverengine_controller.rb
|
109
110
|
homepage: http://www.github.com/unrar/midb
|
110
111
|
licenses:
|
111
112
|
- TPOL
|