github.com/readium/readium-lcp-server@v0.0.0-20240101192032-6e95190e99f1/sign/canon.go (about) 1 // Copyright 2017 European Digital Reading Lab. All rights reserved. 2 // Licensed to the Readium Foundation under one or more contributor license agreements. 3 // Use of this source code is governed by a BSD-style license 4 // that can be found in the LICENSE file exposed on Github (readium) in the project repository. 5 6 package sign 7 8 import ( 9 "bytes" 10 "encoding/json" 11 "io" 12 "strings" 13 ) 14 15 func Canon(in interface{}) ([]byte, error) { 16 // the easiest way to canonicalize is to marshal it and reify it as a map 17 // which will sort stuff correctly 18 b, err1 := json.Marshal(in) 19 if err1 != nil { 20 return b, err1 21 } 22 23 var jsonObj interface{} // map[string]interface{} ==> auto sorting 24 25 dec := json.NewDecoder(strings.NewReader(string(b))) 26 dec.UseNumber() 27 for { 28 if err2 := dec.Decode(&jsonObj); err2 == io.EOF { 29 break 30 } else if err2 != nil { 31 return nil, err2 32 } 33 } 34 var buf bytes.Buffer 35 enc := json.NewEncoder(&buf) 36 // do not escape characters 37 enc.SetEscapeHTML(false) 38 err := enc.Encode(jsonObj) 39 if err != nil { 40 return nil, err 41 } 42 // remove the trailing newline, added by encode 43 return bytes.TrimRight(buf.Bytes(), "\n"), nil 44 45 }