2015-04-20 07:41:32 +00:00
|
|
|
<!--GITHUB
|
|
|
|
page_title: Docker Distribution JSON Canonicalization
|
|
|
|
page_description: Explains registry JSON objects
|
|
|
|
page_keywords: registry, service, images, repository, json
|
|
|
|
IGNORES-->
|
|
|
|
|
|
|
|
|
2015-03-03 06:42:08 +00:00
|
|
|
# Docker Distribution JSON Canonicalization
|
|
|
|
|
|
|
|
To provide consistent content hashing of JSON objects throughout Docker
|
2015-04-02 15:11:19 +00:00
|
|
|
Distribution APIs, the specification defines a canonical JSON format. Adopting
|
|
|
|
such a canonicalization also aids in caching JSON responses.
|
2015-03-03 06:42:08 +00:00
|
|
|
|
|
|
|
## Rules
|
|
|
|
|
|
|
|
Compliant JSON should conform to the following rules:
|
|
|
|
|
|
|
|
1. All generated JSON should comply with [RFC
|
|
|
|
7159](http://www.ietf.org/rfc/rfc7159.txt).
|
|
|
|
2. Resulting "JSON text" shall always be encoded in UTF-8.
|
|
|
|
3. Unless a canonical key order is defined for a particular schema, object
|
|
|
|
keys shall always appear in lexically sorted order.
|
|
|
|
4. All whitespace between tokens should be removed.
|
|
|
|
5. No "trailing commas" are allowed in object or array definitions.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
The following is a simple example of a canonicalized JSON string:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"asdf":1,"qwer":[],"zxcv":[{},true,1000000000,"tyui"]}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Reference
|
|
|
|
|
|
|
|
### Other Canonicalizations
|
|
|
|
|
|
|
|
The OLPC project specifies [Canonical
|
|
|
|
JSON](http://wiki.laptop.org/go/Canonical_JSON). While this is used in
|
|
|
|
[TUF](http://theupdateframework.com/), which may be used with other
|
|
|
|
distribution-related protocols, this alternative format has been proposed in
|
|
|
|
case the original source changes. Specifications complying with either this
|
|
|
|
specification or an alternative should explicitly call out the
|
|
|
|
canonicalization format. Except for key ordering, this specification is mostly
|
|
|
|
compatible.
|
|
|
|
|
|
|
|
### Go
|
|
|
|
|
|
|
|
In Go, the [`encoding/json`](http://golang.org/pkg/encoding/json/) library
|
|
|
|
will emit canonical JSON by default. Simply using `json.Marshal` will suffice
|
|
|
|
in most cases:
|
|
|
|
|
|
|
|
```go
|
|
|
|
incoming := map[string]interface{}{
|
|
|
|
"asdf": 1,
|
|
|
|
"qwer": []interface{}{},
|
|
|
|
"zxcv": []interface{}{
|
|
|
|
map[string]interface{}{},
|
|
|
|
true,
|
|
|
|
int(1e9),
|
|
|
|
"tyui",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
canonical, err := json.Marshal(incoming)
|
|
|
|
if err != nil {
|
|
|
|
// ... handle error
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
To apply canonical JSON format spacing to an existing serialized JSON buffer, one
|
|
|
|
can use
|
|
|
|
[`json.Indent`](http://golang.org/src/encoding/json/indent.go?s=1918:1989#L65)
|
|
|
|
with the following arguments:
|
|
|
|
|
|
|
|
```go
|
|
|
|
incoming := getBytes()
|
|
|
|
var canonical bytes.Buffer
|
|
|
|
if err := json.Indent(&canonical, incoming, "", ""); err != nil {
|
|
|
|
// ... handle error
|
|
|
|
}
|
|
|
|
```
|