Merge bitcoin/bitcoin#27101: Support JSON-RPC 2.0 when requested by client
cbc6c440e3doc: add comments and release-notes for JSON-RPC 2.0 (Matthew Zipkin)e7ee80dcf2rpc: JSON-RPC 2.0 should not respond to "notifications" (Matthew Zipkin)bf1a1f1662rpc: Avoid returning HTTP errors for JSON-RPC 2.0 requests (Matthew Zipkin)466b90562frpc: Add "jsonrpc" field and drop null "result"/"error" fields (Matthew Zipkin)2ca1460ae3rpc: identify JSON-RPC 2.0 requests (Matthew Zipkin)a64a2b77e0rpc: refactor single/batch requests (Matthew Zipkin)df6e3756d6rpc: Avoid copies in JSONRPCReplyObj() (Matthew Zipkin)09416f9ec4test: cover JSONRPC 2.0 requests, batches, and notifications (Matthew Zipkin)4202c170datest: refactor interface_rpc.py (Matthew Zipkin) Pull request description: Closes https://github.com/bitcoin/bitcoin/issues/2960 Bitcoin Core's JSONRPC server behaves with a special blend of 1.0, 1.1 and 2.0 behaviors. This introduces compliance issues with more strict clients. There are the major misbehaviors that I found: - returning non-200 HTTP codes for RPC errors like "Method not found" (this is not a server error or an HTTP error) - returning both `"error"` and `"result"` fields together in a response object. - different error-handling behavior for single and batched RPC requests (batches contain errors in the response but single requests will actually throw HTTP errors) https://github.com/bitcoin/bitcoin/pull/15495 added regression tests after a discussion in https://github.com/bitcoin/bitcoin/pull/15381 to kinda lock in our RPC behavior to preserve backwards compatibility. https://github.com/bitcoin/bitcoin/pull/12435 was an attempt to allow strict 2.0 compliance behind a flag, but was abandoned. The approach in this PR is not strict and preserves backwards compatibility in a familiar bitcoin-y way: all old behavior is preserved, but new rules are applied to clients that opt in. One of the rules in the [JSON RPC 2.0 spec](https://www.jsonrpc.org/specification#request_object) is that the kv pair `"jsonrpc": "2.0"` must be present in the request. Well, let's just use that to trigger strict 2.0 behavior! When that kv pair is included in a request object, the [response will adhere to strict JSON-RPC 2.0 rules](https://www.jsonrpc.org/specification#response_object), essentially: - always return HTTP 200 "OK" unless there really is a server error or malformed request - either return `"error"` OR `"result"` but never both - same behavior for single and batch requests If this is merged next steps can be: - Refactor bitcoin-cli to always use strict 2.0 - Refactor the python test framework to always use strict 2.0 for everything - Begin deprecation process for 1.0/1.1 behavior (?) If we can one day remove the old 1.0/1.1 behavior we can clean up the rpc code quite a bit. ACKs for top commit: cbergqvist: re ACKcbc6c440e3ryanofsky: Code review ACKcbc6c440e3. Just suggested changes since the last review: changing uncaught exception error code from PARSE_ERROR to MISC_ERROR, renaming a few things, and adding comments. tdb3: re ACK forcbc6c440e3Tree-SHA512: 0b702ed32368b34b29ad570d090951a7aeb56e3b0f2baf745bd32fdc58ef68fee6b0b8fad901f1ca42573ed714b150303829cddad4a34ca7ad847350feeedb36
This commit is contained in:
13 files changed
+349
-95
No files matched your search
@@ -160,6 +160,15 @@ class AuthServiceProxy():
|
||||
raise JSONRPCException({
|
||||
'code': -342, 'message': 'missing HTTP response from server'})
|
||||
|
||||
# Check for no-content HTTP status code, which can be returned when an
|
||||
# RPC client requests a JSON-RPC 2.0 "notification" with no response.
|
||||
# Currently this is only possible if clients call the _request() method
|
||||
# directly to send a raw request.
|
||||
if http_response.status == HTTPStatus.NO_CONTENT:
|
||||
if len(http_response.read()) != 0:
|
||||
raise JSONRPCException({'code': -342, 'message': 'Content received with NO CONTENT status code'})
|
||||
return None, http_response.status
|
||||
|
||||
content_type = http_response.getheader('Content-Type')
|
||||
if content_type != 'application/json':
|
||||
raise JSONRPCException(
|
||||
|
||||
Reference in new issue
Block a user