Skip to content

Commit a4befdd

Browse files
committed
ipip: add dag-cbor to reframe over http
1 parent f5a023e commit a4befdd

File tree

2 files changed

+121
-14
lines changed

2 files changed

+121
-14
lines changed

IPIP/0000-http-reframe-cbor.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# IPIP 0000: Add DAG-CBOR support to Reframe over HTTP
2+
3+
<!-- IPIP number will be assigned by an editor. When opening a pull request to
4+
submit your IPIP, please use number 0000 and an abbreviated title in the filename,
5+
`0000-draft-title-abbrev.md`. -->
6+
7+
- Start Date: 2022-09-29
8+
- Related Issues:
9+
- https://github.com/ipld/edelweiss/issues/16#issuecomment-1074161577
10+
- https://github.com/ipfs/kubo/issues/8823
11+
12+
## Summary
13+
14+
<!--One paragraph explanation of the IPIP.-->
15+
This IPIP adds DAG-CBOR support to Reframe over HTTP.
16+
17+
## Motivation
18+
19+
We've been using Reframe in Kubo for a while and it is clear that Reframe
20+
messages are not designed to be created or read by humans.
21+
22+
The plaintext DAG-JSON representation of messages does not really bring
23+
anything to the table (because both CIDs and Multiaddrs are in a format that
24+
needs manual encoding/decoding anyway),
25+
26+
## Detailed design
27+
28+
We already support DAG-JSON, with its own content type.
29+
The change here is to add support for requests and responses sent as DAG-CBOR,
30+
with own content type: `application/vnd.ipfs.rpc+dag-cbor`.
31+
32+
For details, see changes made to `reframe/REFRAME_HTTP_TRANSPORT.md`
33+
34+
## Test fixtures
35+
36+
TODO: add CIDs of sample DAG-CBOR messages after https://github.com/ipfs/go-delegated-routing implements it, and has own tests.
37+
38+
## Design rationale
39+
40+
IPFS stack aims to support both DAG-CBOR and DAG-JSON. Users can store JSON as
41+
CBOR and vice versa. Having consitent support for both in Reframe not only
42+
aligns with user expectations, but also allows us to save some bytes
43+
(bandwidth, response caching requirements) by using a binary CBOR as the
44+
production format.
45+
46+
### User benefit
47+
48+
User will be able to choose between binary and human-readable representation,
49+
just like they do in other parts of IPFS/IPLD stack.
50+
51+
### Compatibility
52+
53+
Explain the upgrade considerations for existing implementations.
54+
55+
This IPIP add DAG-CBOR next to already existing DAG-JSON. Preexisting clients
56+
that only speak DAG-JSON will continue working, no change is required.
57+
58+
### Security
59+
60+
61+
N/A, we will use the same DAG-CBOR encoder/decoder as the rest of the stack.
62+
63+
### Alternatives
64+
65+
Alternative is to do nothing, and end up with:
66+
- inconsitent user experience
67+
- wasted bandwidth and cache storage
68+
69+
### Copyright
70+
71+
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

reframe/REFRAME_HTTP_TRANSPORT.md

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# ![](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) Reframe: HTTP Transport
1+
# ![draft](https://img.shields.io/badge/status-draft-yellow.svg?style=flat-square) Reframe: HTTP Transport
22

33
**Author(s)**:
44
- Adin Schmahmann
@@ -15,36 +15,72 @@ The Reframe over HTTP protocol is defining the transport and message
1515
serialization mechanisms for sending Reframe messages over HTTP `POST` and
1616
`GET`, and provides guidance for implementers around HTTP caching.
1717

18-
# Organization of this document
19-
20-
- [HTTP Transport Design](#http-transport-design)
21-
- [HTTP Caching Considerations](#http-caching-considerations)
22-
- [POST vs GET](#post-vs-get)
23-
- [Avoiding sending the same response messages twice](#avoiding-sending-the-same-response-messages-twice)
24-
- [Client controls for time-based caching](#client-controls-for-time-based-caching)
25-
- [Rate-limiting non-cachable POST requests](#rate-limiting-non-cachable-post-requests)
18+
## Organization of this document
19+
20+
- [HTTP Endpoint](#http-endpoint)
21+
- [Content type](#content-type)
22+
- [HTTP methods](#http-methods)
23+
- [Other notes](#other-notes)
24+
- [HTTP Caching Considerations](#http-caching-considerations)
25+
- [POST vs GET](#post-vs-get)
26+
- [Avoiding sending the same response messages twice](#avoiding-sending-the-same-response-messages-twice)
27+
- [Client controls for time-based caching](#client-controls-for-time-based-caching)
28+
- [Rate-limiting non-cachable POST requests](#rate-limiting-non-cachable-post-requests)
2629
- [Implementations](#implementations)
2730

28-
# HTTP Transport Design
31+
## HTTP Endpoint
32+
33+
```
34+
https://rpc-service.example.net/reframe
35+
```
36+
37+
URL of a Reframe endpoint must end with `/reframe` path.
38+
39+
### Content type
40+
41+
Requests SHOULD be sent with explicit `Accept` and `Content-Type` HTTP headers specifying the body format.
42+
43+
All messages sent in HTTP body MUST be encoded as either:
44+
- [DAG-CBOR](https://ipld.io/specs/codecs/dag-cbor/spec/), and use explicit content type `application/vnd.ipfs.rpc+dag-cbor; version=1`
45+
- **This is a CBOR (binary) format for use in production.**
46+
- CBOR request MUST include HTTP header: `Accept: application/vnd.ipfs.rpc+dag-cbor; version=1`
47+
- CBOR request AND response MUST include header: `Content-Type: application/vnd.ipfs.rpc+dag-cbor; version=1`
48+
- [DAG-JSON](https://ipld.io/specs/codecs/dag-json/spec/), and use explicit content type `application/vnd.ipfs.rpc+dag-json; version=1`
49+
- **This is a human-readable plain text format for use in testing and debugging.**
50+
- JSON request MUST include header: `Accept: application/vnd.ipfs.rpc+dag-json; version=1`
51+
- JSON request AND response MUST include header: `Content-Type: application/vnd.ipfs.rpc+dag-json; version=1`
52+
53+
54+
Implementations SHOULD error when an explicit content type is missing, but MAY decide to implement some defaults instead.
55+
The rules around implicit content type are as follows:
56+
- Requests without a matching `Content-Type` header MAY be interpreted as DAG-JSON.
57+
- Requests without a matching `Accept` header MAY produce a DAG-JSON response.
58+
- Responses without a matching `Content-Type` header MAY be interpreted as DAG-JSON.
2959

30-
All messages sent in HTTP body MUST be encoded as DAG-JSON and use explicit content type `application/vnd.ipfs.rpc+dag-json; version=1`
60+
### HTTP methods
3161

3262
Requests MUST be sent as either:
63+
- `GET /reframe/{mbase64url-dag-cbor}`
64+
- Cachable HTTP `GET` requests with message passed as DAG-CBOR in HTTP path segment, encoded as URL-safe [`base64url` multibase](https://docs.ipfs.io/concepts/glossary/#base64url) string
65+
- DAG-CBOR in multibase `base64url` is used (even when request body is DAG-JSON) because JSON may include characters that are not safe to be used in URLs, and percent-encoding or base-encoding a big JSON query may take too much space.
66+
- Suitable for sharing links, sending bigger messages, and when a query result MUST benefit from HTTP caching (see _HTTP Caching Considerations_ below).
3367
- `GET /reframe?q={percent-encoded-dag-json}`
3468
- DAG-JSON is supported via a `?q` query parameter, and the value MUST be [percent-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
3569
- Suitable for sharing links, sending smaller messages, testing and debugging.
3670
- `POST /reframe`
37-
- Ephemeral HTTP `POST` request with message passed as DAG-JSON in HTTP request body
71+
- Ephemeral HTTP `POST` request with DAG-JSON or DAG-CBOR message passed in HTTP request body
3872
- Suitable for bigger messages, and when HTTP caching should be skipped for the most fresh results
3973

4074
Servers MUST support `GET` for methods marked as cachable and MUST support `POST` for all methods (both cachable and not-cachable). This allows servers to rate-limit `POST` when cachable `GET` could be used instead, and enables clients to use `POST` as a fallback in case there is a technical problem with bigger Reframe messages not fitting in a `GET` URL. See "Caching Considerations" section.
4175

76+
### Other notes
4277

4378
If a server supports HTTP/1.1, then it MAY send chunked-encoded messages. Clients supporting HTTP/1.1 MUST accept chunked-encoded responses.
4479

4580
Requests and Responses MUST occur over a single HTTP call instead of the server being allowed to dial back the client with a response at a later time. The response status code MUST be 200 if the RPC transaction succeeds, even when there's an error at the application layer, and a non-200 status code if the RPC transaction fails.
4681

47-
If a server chooses to respond to a single request message with a group of messages in the response it should do so as a set of `\n` delimited DAG-JSON messages (i.e. `{Response1}\n{Response2}...`).
82+
If a server chooses to respond to a single request message with a group of DAG-JSON messages in the response it should do so as a set of `\n` delimited DAG-JSON messages (i.e. `{Response1}\n{Response2}...`).
83+
DAG-CBOR responses require no special handling, as they are already self-delimiting due to the nature of the CBOR encoding.
4884

4985
Requests and responses MUST come with `version=1` as a _Required Parameter_ in the `Accept` and `Content-Type` HTTP headers.
5086

@@ -99,6 +135,6 @@ too many POST requests: consider switching to cachable GET or try again later (s
99135
```
100136

101137

102-
# Implementations
138+
## Implementations
103139

104140
https://github.com/ipfs/go-delegated-routing

0 commit comments

Comments
 (0)