Conditions | 1 |
Total Lines | 151 |
Lines | 0 |
Ratio | 0 % |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | require 'midb/server_controller' |
||
55 | # @param port [Fixnum] Port to which the server will listen. |
||
56 | def start(port=8081) |
||
57 | serv = TCPServer.new("localhost", port) |
||
58 | MIDB::Interface::Server.info(:start, port) |
||
59 | |||
60 | # Manage the requests |
||
61 | loop do |
||
62 | socket = serv.accept |
||
63 | MIDB::Interface::Server.info(:incoming_request, socket.addr[3]) |
||
64 | |||
65 | request = self.parse_request(socket.gets) |
||
66 | |||
67 | # Get a hash with the headers |
||
68 | headers = {} |
||
69 | while line = socket.gets.split(' ', 2) |
||
|
|||
70 | break if line[0] == "" |
||
71 | headers[line[0].chop] = line[1].strip |
||
72 | end |
||
73 | data = socket.read(headers["Content-Length"].to_i) |
||
74 | |||
75 | |||
76 | MIDB::Interface::Server.info(:request, request) |
||
77 | response_json = Hash.new() |
||
78 | |||
79 | # Endpoint syntax: ["", FILE, ID, (ACTION)] |
||
80 | endpoint = request[1].split("/") |
||
81 | if endpoint.length >= 2 |
||
82 | ep_file = endpoint[1].split("?")[0] |
||
83 | else |
||
84 | ep_file = "" |
||
85 | end |
||
86 | |||
87 | method = request[0] |
||
88 | endpoints = [] # Valid endpoints |
||
89 | |||
90 | # Load the JSON served files |
||
91 | @config["serves"].each do |js| |
||
92 | # The filename is a valid endpoint |
||
93 | endpoints.push File.basename(js, ".*") |
||
94 | end |
||
95 | |||
96 | # Load the endpoints |
||
97 | found = false |
||
98 | endpoints.each do |ep| |
||
99 | if ep_file == ep |
||
100 | found = true |
||
101 | MIDB::Interface::Server.info(:match_json, ep) |
||
102 | # Create the model |
||
103 | dbop = MIDB::API::Model.new(ep, @db, self) |
||
104 | # Analyze the request and pass it to the model |
||
105 | # Is the method accepted? |
||
106 | accepted_methods = ["GET", "POST", "PUT", "DELETE"] |
||
107 | unless accepted_methods.include? method |
||
108 | @http_status = "405 Method Not Allowed" |
||
109 | response_json = MIDB::Interface::Server.json_error(405, "Method Not Allowed").to_json |
||
110 | else |
||
111 | # Do we need authentication? |
||
112 | auth_req = false |
||
113 | unauthenticated = false |
||
114 | if @config["privacy#{method.downcase}"] == true |
||
115 | MIDB::Interface::Server.info(:auth_required) |
||
116 | auth_req = true |
||
117 | |||
118 | # For GET and DELETE requests, the object of the digest is the endpoint |
||
119 | if (method == "GET") || (method == "DELETE") |
||
120 | data = ep_file |
||
121 | end |
||
122 | |||
123 | # If it's a GET request and we have a different key for GET methods... |
||
124 | if (@config["apigetkey"] != nil) && (method == "GET") |
||
125 | unauthenticated = (not headers.has_key? "Authentication") || |
||
126 | (not MIDB::API::Security.check?(headers["Authentication"], data, @config["apigetkey"])) |
||
127 | else |
||
128 | unauthenticated = (not headers.has_key? "Authentication") || |
||
129 | (not MIDB::API::Security.check?(headers["Authentication"], data, @config["apikey"])) |
||
130 | end |
||
131 | end |
||
132 | # Proceed to handle the request |
||
133 | if unauthenticated |
||
134 | response_json = self.unauth_request |
||
135 | puts ">> has header: #{headers.has_key? "Authentication"}" |
||
136 | else |
||
137 | MIDB::Interface::Server.info(:auth_success) if (not unauthenticated) && auth_req |
||
138 | if method == "GET" |
||
139 | case endpoint.length |
||
140 | when 2 |
||
141 | # No ID has been specified. Return all the entries |
||
142 | # Pass it to the model and get the JSON |
||
143 | MIDB::Interface::Server.info(:fetch, "get_all_entries()") |
||
144 | response_json = dbop.get_all_entries().to_json |
||
145 | when 3 |
||
146 | # This regular expression checks if it contains an integer |
||
147 | if /\A[-+]?\d+\z/ === endpoint[2] |
||
148 | # An ID has been specified. Should it exist, return all of its entries. |
||
149 | MIDB::Interface::Server.info(:fetch, "get_entries(#{endpoint[2]})") |
||
150 | response_json = dbop.get_entries(endpoint[2].to_i).to_json |
||
151 | else |
||
152 | # A row has been specified, but no pattern |
||
153 | MIDB::Interface::Server.info(:fetch, "get_column_entries(#{endpoint[2]})") |
||
154 | response_json = dbop.get_column_entries(endpoint[2]).to_json |
||
155 | end |
||
156 | when 4 |
||
157 | if (endpoint[2].is_a? String) && (endpoint[3].is_a? String) then |
||
158 | # A row and a pattern have been specified |
||
159 | MIDB::Interface::Server.info(:fetch, "get_matching_rows(#{endpoint[2]}, #{endpoint[3]})") |
||
160 | response_json = dbop.get_matching_rows(endpoint[2], endpoint[3]).to_json |
||
161 | end |
||
162 | end |
||
163 | elsif method == "POST" |
||
164 | MIDB::Interface::Server.info(:fetch, "post(#{data})") |
||
165 | response_json = dbop.post(data).to_json |
||
166 | else |
||
167 | if endpoint.length >= 3 |
||
168 | if method == "DELETE" |
||
169 | MIDB::Interface::Server.info(:fetch, "delete(#{endpoint[2]})") |
||
170 | response_json = dbop.delete(endpoint[2]).to_json |
||
171 | elsif method == "PUT" |
||
172 | MIDB::Interface::Server.info(:fetch, "put(#{endpoint[2]}, data)") |
||
173 | response_json = dbop.put(endpoint[2], data).to_json |
||
174 | end |
||
175 | else |
||
176 | @http_status = "404 Not Found" |
||
177 | response_json = MIDB::Interface::Server.json_error(404, "Must specify an ID.").to_json |
||
178 | end |
||
179 | end |
||
180 | end |
||
181 | end |
||
182 | MIDB::Interface::Server.info(:response, response_json) |
||
183 | # Return the results via HTTP |
||
184 | socket.print "HTTP/1.1 #{@http_status}\r\n" + |
||
185 | "Content-Type: text/json\r\n" + |
||
186 | "Content-Length: #{response_json.size}\r\n" + |
||
187 | "Connection: close\r\n" |
||
188 | socket.print "\r\n" |
||
189 | socket.print response_json |
||
190 | socket.print "\r\n" |
||
191 | MIDB::Interface::Server.info(:success) |
||
192 | end |
||
193 | end |
||
194 | unless found |
||
195 | MIDB::Interface::Server.info(:not_found) |
||
196 | response = MIDB::Interface::Server.json_error(404, "Invalid API endpoint.").to_json |
||
197 | |||
198 | socket.print "HTTP/1.1 404 Not Found\r\n" + |
||
199 | "Content-Type: text/json\r\n" + |
||
200 | "Content-Length: #{response.size}\r\n" + |
||
201 | "Connection: close\r\n" |
||
202 | socket.print "\r\n" |
||
203 | socket.print response |
||
204 | end |
||
205 | end |
||
206 | end |
||
215 | end |