Add Suborigin header to gateway responses (#3209)
This existed before but was disabled in 912a972 because the Suborigin spec changed and it became incompatible. This commit updates the generated Suborigin header to be conformant with the latest spec. License: MIT Signed-off-by: James Stanley <james@incoherency.co.uk>
James Stanley committed
May 10, 2017 at 10:39 UTC
cb2a38d89b3c02b509f1d974b60f114cf7cf44ac
1 file changed
+34
core/corehttp/gateway_handler.go
+34
@@ -27,6 +27,7 @@ import (
27
cid "gx/ipfs/QmYhQaCYEcaPPjxJX7YcPcVKkQfRy6sJ7B3XmGFk82XYdQ/go-cid"
28
routing "gx/ipfs/QmafuecpeZp3k3sHJ5mUARHd4795revuadECQMkmHB8LfW/go-libp2p-routing"
29
node "gx/ipfs/Qmb3Hm9QDFmfYuET4pu7Kyg8JV78jFa1nvZx5vnCZsK4ck/go-ipld-format"
30
+ multibase "gx/ipfs/QmcxkxTVuURV2Ptse8TvkqH5BQDwV62X1x19JqqvbBzwUM/go-multibase"
31
)
32
33
const (
@@ -210,6 +211,39 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
211
// expose those headers
212
w.Header().Set("Access-Control-Expose-Headers", "X-Stream-Output, X-Chunked-Output")
213
214
+ // Suborigin header, sandboxes apps from each other in the browser (even
215
+ // though they are served from the same gateway domain).
216
+ //
217
+ // Omitted if the path was treated by IPNSHostnameOption(), for example
218
+ // a request for http://example.net/ would be changed to /ipns/example.net/,
219
+ // which would turn into an incorrect Suborigin header.
220
+ // In this case the correct thing to do is omit the header because it is already
221
+ // handled correctly without a Suborigin.
222
+ //
223
+ // NOTE: This is not yet widely supported by browsers.
224
+ if !ipnsHostname {
225
+ // e.g.: 1="ipfs", 2="QmYuNaKwY...", ...
226
+ pathComponents := strings.SplitN(urlPath, "/", 4)
227
+
228
+ var suboriginRaw []byte
229
+ cidDecoded, err := cid.Decode(pathComponents[2])
230
+ if err != nil {
231
+ // component 2 doesn't decode with cid, so it must be a hostname
232
+ suboriginRaw = []byte(strings.ToLower(pathComponents[2]))
233
+ } else {
234
+ suboriginRaw = cidDecoded.Bytes()
235
+ }
236
+
237
+ base32Encoded, err := multibase.Encode(multibase.Base32, suboriginRaw)
238
+ if err != nil {
239
+ internalWebError(w, err)
240
+ return
241
+ }
242
+
243
+ suborigin := pathComponents[1] + "000" + strings.ToLower(base32Encoded)
244
+ w.Header().Set("Suborigin", suborigin)
245
+ }
246
+
247
// set these headers _after_ the error, for we may just not have it
248
// and dont want the client to cache a 500 response...
249
// and only if it's /ipfs!