Created
August 11, 2013 11:25
-
-
Save liamzebedee/6204443 to your computer and use it in GitHub Desktop.
BitWeav preliminary JSON-RPC over HTTP with Basic Auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Ok so I've been looking for over 3 hours in total for a nice, simple, RPC solution for local clients. I couldn't find any, so I built this. | |
| module BitWeavD | |
| # We use JSON-RPC over HTTP with basic authentication | |
| class ClientRPC | |
| RESPONSE = { | |
| 'result' => [], | |
| 'id' => nil, | |
| 'error' => nil, | |
| } | |
| # Host a HTTP 1.1 server. | |
| # Accept only POST requests with content type of 'application/json'. | |
| # Check immediately whether HTTP Auth is correct, otherwise close connection. | |
| # Decode the request from JSON to object. | |
| # Lookup the method in the 'services' table and run it with the args | |
| # Send back response encoded as JSON blob. | |
| # Requests: method [string], params [array], id [*] | |
| # Responses: result [array], error [*], id [*] | |
| def initialise(port, username, password) | |
| @server = WEBrick::HTTPServer.new :Port => port | |
| http_auth_config = { :Realm => 'jsonrpc' } | |
| http_auth_config[:UserDB] = WEBrick::HTTPAuth::Htpasswd.new '' | |
| http_auth_config[:UserDB].set_passwd 'jsonrpc', username, password | |
| @basic_auth = WEBrick::HTTPAuth::BasicAuth.new http_auth_config | |
| @procedures = {} | |
| end | |
| def serve | |
| @server.start | |
| server.mount_proc '/' do |req, res| | |
| # Break conditions | |
| break if req.request_method != 'POST' | |
| break if req.content_type != 'application/json' | |
| # XXX break if not localhost | |
| do | |
| @basic_auth.authenticate | |
| rescue auth_exception | |
| break | |
| end | |
| request = JSON.parse req.body | |
| response = RESPONSE | |
| procedure = @procedures[request['method']] | |
| if procedure == nil do | |
| response['error'] = "Procedure not found." | |
| else | |
| do | |
| response['result'] = procedure(*request['params']) | |
| rescue error | |
| response['error'] = error.to_s | |
| end | |
| end | |
| ### Send response | |
| # this is a notification, and thus has no response | |
| break if request['id'] == nil | |
| response['id'] = request['id'] | |
| res.body = JSON.dump reponse | |
| end | |
| end | |
| # Probably not very good for things | |
| def shutdown | |
| server.shutdown | |
| end | |
| def []=(name, method) | |
| @procedures[name] = method | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment