Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Add GET & OPTIONS request functionality to JSON-RPC servers #712

Merged
merged 41 commits into from
Nov 20, 2018

Conversation

jseagrave21
Copy link
Contributor

@jseagrave21 jseagrave21 commented Nov 8, 2018

What current issue(s) does this address, or what feature is it adding?
@xxedocxx (@ed#2854 on Discord) brought up the issue that GET requests do not work and he DM'ed me saying he would like to see this functionality added. I have also noticed this and desired the same, so I could query RPC nodes from my phone's web browser.

@xxedocxx contributed the initial ability to parse GET request URI's into dictionary format using furl. It was great teamwork!

NOTE: this implementation requires that the "params" field not be last in GET requests (or there are parse errors)
-edit-

  • this implementation does support having "params" as the last field

NOTE: also, GET requests do not support multiple requests in 1 transaction (tested; maintains parody with neo-cli)

How did you solve this problem?
trial, error, and teamwork

How did you make sure your solution works?
lots of personal testing and unittest

Are there any special changes in the code that we should be aware of?
Adds furl to requirements.tx

Please check the following, if applicable:

  • Did you add any tests?
  • Did you run make lint?
  • Did you run make test?
  • Are you making a PR to a feature branch or development rather than master?
  • Did you add an entry to CHANGELOG.rst? (if not, please do)

jseagrave21 and others added 23 commits October 9, 2018 20:38
Merge CoZ Development into jseagrave21 Development
Merge CoZ Development into jseagrave21 Development
Merge CoZ Development into jseagrave21 Development
* Update ExtendedJsonRpcApi.py

- add fix provided by @localhuman so original methods are returned as well as extended methods
…yOfZion#661)

* Add the option -u (unittest-net) to prompt.py

* Add unittest guildeline and add the smart contract source codes (UnitTest-SM.zip) to the fixtures package
for compatibility
* Fix ExtendedJsonRpcApi (CityOfZion#662)

* Update ExtendedJsonRpcApi.py

- add fix provided by @localhuman so original methods are returned as well as extended methods

* Mute expected test stacktrace and clearly identify why an exception is thrown. (CityOfZion#663)

* Add guideline for adding tests to the neo-privnet-unittest image (CityOfZion#661)

* Add the option -u (unittest-net) to prompt.py

* Add unittest guildeline and add the smart contract source codes (UnitTest-SM.zip) to the fixtures package

* Add raw transaction building examples (CityOfZion#665)

* Update neo-boa version to fix core building test
Merge CoZ Development into jseagrave21 Development
Merge CoZ Development into jseagrave21 Development
Merge CoZ Development into jseagrave21 Development
Merge CoZ Development into jseagrave21 development
Merge CoZ development into jseagrave21 development
- add tests for "showallaccounts" and "showallaccountstates"
Merge neo-python development into jseagrave21 development
- add support for GET Requests
- update tests to include GET requests
- update tests for GET requests
- update tests for GET requests
@coveralls
Copy link

coveralls commented Nov 8, 2018

Coverage Status

Coverage increased (+0.2%) to 83.931% when pulling a3fe3aa on jseagrave21:GET-Requests into 2a501a1 on CityOfZion:development.

- add a test for a GET request with bad "params" field
@ixje
Copy link
Member

ixje commented Nov 8, 2018

NOTE: this implementation requires that the "params" field not be last in GET requests (or there are parse errors)

Where does this limitation come from? Is that implementation based or also described in the JSON-RPC specifications?

NOTE: also, GET requests do not support multiple requests in 1 transaction

Same question as above

@jseagrave21
Copy link
Contributor Author

jseagrave21 commented Nov 8, 2018

@ixje The first limitation occurs because of how content = furl(request.uri).args works. The last argument appears to receive an extra set of quotation marks (i.e. "&id=2# becomes {'id': "2'"}

The second limitation occurs also because of how content = furl(request.uri).args works. It turns every arg in the URI into a dictionary. So, /?[jsonrpc=2.0&method=getblock&params=[1]&id=1,jsonrpc=2.0&method=getblock&params=[1,1]&id=2] will be converted into a single dictionary key with no value.

Both of these limitations are mentioned here: /~https://github.com/CityOfZion/neo-python/pull/712/files#diff-f9e9d3e0fbf0fb287940a8d009a379b2R132

@jseagrave21
Copy link
Contributor Author

jseagrave21 commented Nov 9, 2018

@ixje @localhuman One of the new features of this implementation is the sorting of URI methods. After watching my RPC server for a bit I noticed that other than "POST" methods, I also see "OPTIONS" method requests:

[I 181109 09:39:15 _observer:131] "82.196.0.91" - - [09/Nov/2018:17:39:15 +0000] "POST / HTTP/1.1" 200 166 "-" "Python-urllib/2.7"
[I 181109 09:39:16 _observer:131] "82.196.0.91" - - [09/Nov/2018:17:39:16 +0000] "POST / HTTP/1.1" 200 83 "-" "Python-urllib/2.7"
[I 181109 09:39:16 _observer:131] "82.196.0.91" - - [09/Nov/2018:17:39:16 +0000] "POST / HTTP/1.1" 200 166 "-" "Python-urllib/2.7"
[I 181109 09:39:16 _observer:131] "91.225.214.15" - - [09/Nov/2018:17:39:16 +0000] "OPTIONS / HTTP/1.1" 200 83 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
[I 181109 09:39:16 _observer:131] "91.225.214.15" - - [09/Nov/2018:17:39:16 +0000] "OPTIONS / HTTP/1.1" 200 83 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
[I 181109 09:39:16 _observer:131] "91.225.214.15" - - [09/Nov/2018:17:39:16 +0000] "OPTIONS / HTTP/1.1" 200 83 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"

Originally, I filtered out all other request methods other than "POST" or "GET". Do I need to add some kind of functionality if an "OPTIONS" method request is made, or a different method? (reference https://www.tutorialspoint.com/http/http_methods.htm)

-update-

I just tried an "OPTIONS" request and received:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Server: TwistedWeb/18.7.0
Date: Fri, 09 Nov 2018 17:52:05 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With
Content-Type: application/json

{"jsonrpc": "2.0", "id": null, "error": {"code": -32700, "message": "Parse error"}}

I think it would be nice to add a message indicating that "GET" and "POST" methods are accepted.

@ixje
Copy link
Member

ixje commented Nov 9, 2018

neo-cli supports having params as the last element, so if we want to have feature parity we need to support it as well. Might be worth either reporting the issue on the furl package repo or find a library that does work. Note that the build in request.args parses this fine:

http://localhost:8080/?jsonrpc=2.0&method=getblockcount&params=[]&id=5

But this

http://localhost:8080/?[jsonrpc=2.0&method=getblockcount&params=[]&id=5]

get's an additional [ and ] for the first and last param

I don't know about OPTIONS. The basic validation rule to check against is;
if neo-cli supports it we want to support it in the exact same manner (with the one exception of dumpprivkey)

@jseagrave21
Copy link
Contributor Author

@ixje I solved the params problem. Also, neo-cli does not support multiple requests in a GET request, so I am not going to try to add support for it. For example: http://seed3.aphelion-neo.com:10332/?[jsonrpc=2.0&method=getblock&id=1&params=[1],jsonrpc=2.0&method=getblock&id=1&params=[1,1]] yields

{"jsonrpc":"2.0","id":"1,1","error":{"code":-32601,"message":"Method not found","data":"   at Neo.Network.RPC.RpcServer.Process(String method, JArray _params, String requestGuid) in \/home\/solinsky\/repos\/aph-server\/neo\/Network\/RPC\/RpcServer.cs:line 611\n   at Neo.Network.RPC.RpcServer.ProcessRequest(HttpContext context, JObject request) in \/home\/solinsky\/repos\/aph-server\/neo\/Network\/RPC\/RpcServer.cs:line 703"}}

- add functionality for having params field as last field
- add a response for an HTTP OPTIONS request to identify the supported HTTP methods
- add test for HTTP OPTIONS request
- show support for having params as last field
for compatibility
Merge neo-python development into jseagrave21 development
@jseagrave21 jseagrave21 changed the title Add GET request functionality to JSON-RPC servers Add GET & OPTIONS request functionality to JSON-RPC servers Nov 10, 2018
@jseagrave21
Copy link
Contributor Author

jseagrave21 commented Nov 10, 2018

I had a thought that it would be nice to identify the JSON-RPC server type with an OPTIONS request. So, an OPTIONS request will yield:

{"supported HTTP methods": ["GET", "POST"], "JSON-RPC server type": "default"}

for default RPC servers and

{"supported HTTP methods": ["GET", "POST"], "JSON-RPC server type": "extended-rpc"}

for Extended-RPC servers

- add server-type identifier for OPTIONS request
- update OPTIONS test for server-type
- add server-type for OPTIONS request
- add specific test for OPTIONS request
- add a functional return for an unsupported HTTP method
- update test_invalid_request_method for functional return
- update test for unsupported HTTP method for an extended-rpc server
- update test for invalid HTTP request
for compatibility
for compatibility
Merge neo-python development into jseagrave21 GET-Requests
@ixje
Copy link
Member

ixje commented Nov 20, 2018

all looks good, thanks! 💪

@ixje ixje merged commit 1aec5f0 into CityOfZion:development Nov 20, 2018
@jseagrave21 jseagrave21 deleted the GET-Requests branch November 20, 2018 10:16
jseagrave21 added a commit to jseagrave21/neo-python that referenced this pull request Nov 20, 2018
Add GET & OPTIONS request functionality to JSON-RPC servers (CityOfZion#712)
jseagrave21 added a commit to jseagrave21/neo-python that referenced this pull request Nov 20, 2018
- update documentation for CityOfZion#712 and CityOfZion#719
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants