150 private def handle_connection(socket: Socket) |
155 private def handle_connection(socket: Socket) |
151 { |
156 { |
152 val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, UTF8.charset)) |
157 val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, UTF8.charset)) |
153 val writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream, UTF8.charset)) |
158 val writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream, UTF8.charset)) |
154 |
159 |
155 val Blank_Line = """^\s*$""".r |
|
156 val Command_Line = """^(\S+)\s*(.*)$""".r |
|
157 |
|
158 def reply_line(msg: String) |
160 def reply_line(msg: String) |
159 { |
161 { |
160 require(split_lines(msg).length <= 1) |
162 require(split_lines(msg).length <= 1) |
161 writer.write(msg) |
163 writer.write(msg) |
162 writer.newLine() |
164 writer.newLine() |
168 reply_line(if (t == JSON.empty) r.toString else r.toString + " " + JSON.Format(t)) |
170 reply_line(if (t == JSON.empty) r.toString else r.toString + " " + JSON.Format(t)) |
169 } |
171 } |
170 |
172 |
171 def reply_ok(t: JSON.T) { reply(Server.Reply.OK, t) } |
173 def reply_ok(t: JSON.T) { reply(Server.Reply.OK, t) } |
172 def reply_error(t: JSON.T) { reply(Server.Reply.ERROR, t) } |
174 def reply_error(t: JSON.T) { reply(Server.Reply.ERROR, t) } |
|
175 def reply_error_message(message: String, more: (String, JSON.T)*): Unit = |
|
176 reply_error(Map("message" -> message) ++ more) |
|
177 |
|
178 val Command_Line = """^(\S+)\s*(.*)$""".r |
173 |
179 |
174 reader.readLine() match { |
180 reader.readLine() match { |
175 case null => |
181 case null => |
176 case bad if bad != password => reply_error("Bad password -- connection closed") |
182 case bad if bad != password => reply_error("Bad password -- connection closed") |
177 case _ => |
183 case _ => |
178 var finished = false |
184 var finished = false |
179 while (!finished) { |
185 while (!finished) { |
180 reader.readLine() match { |
186 reader.readLine() match { |
181 case null => finished = true |
187 case null => finished = true |
182 case Blank_Line() => |
188 case Command_Line(cmd, input) => |
183 case Command_Line(cmd, arg) => |
189 Server.commands.get(cmd) match { |
184 proper_string(arg) getOrElse "{}" match { |
190 case None => reply_error("Unknown command " + quote(cmd)) |
185 case JSON.Format(json) => |
191 case Some(body) => |
186 reply_ok(Map("command" -> cmd, "argument" -> json)) |
192 proper_string(input) getOrElse "{}" match { |
187 case _ => |
193 case JSON.Format(arg) => |
188 reply_error( |
194 if (body.isDefinedAt(arg)) { |
189 Map("message" -> "Malformed command", "command" -> cmd, "input" -> arg)) |
195 try { reply_ok(body(arg)) } |
|
196 catch { case ERROR(msg) => reply_error(msg) } |
|
197 } |
|
198 else { |
|
199 reply_error_message( |
|
200 "Bad argument for command", "command" -> cmd, "argument" -> arg) |
|
201 } |
|
202 case _ => |
|
203 reply_error_message( |
|
204 "Malformed command-line", "command" -> cmd, "input" -> input) |
|
205 } |
190 } |
206 } |
191 case _ => |
207 case _ => |
192 } |
208 } |
193 } |
209 } |
194 } |
210 } |