mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-24 11:57:44 +08:00
commit
ea77213e31
@ -33,7 +33,7 @@ default_environment: &default_environment
|
||||
executors:
|
||||
golang:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.2
|
||||
- image: circleci/golang:1.14.4
|
||||
working_directory: ~/ipfs/go-ipfs
|
||||
environment:
|
||||
<<: *default_environment
|
||||
@ -58,9 +58,9 @@ executors:
|
||||
IPFS_REUSEPORT: false
|
||||
LIBP2P_ALLOW_WEAK_RSA_KEYS: 1
|
||||
E2E_IPFSD_TYPE: go
|
||||
dockerizer:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.2
|
||||
dockerizer:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.4
|
||||
environment:
|
||||
IMAGE_NAME: ipfs/go-ipfs
|
||||
WIP_IMAGE_TAG: wip
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
- run: |
|
||||
make -j 1 test/unit/gotest.junit.xml \
|
||||
&& [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]]
|
||||
- run:
|
||||
- run:
|
||||
when: always
|
||||
command: bash <(curl -s https://codecov.io/bash) -cF unittests -X search -f coverage/unit_tests.coverprofile
|
||||
|
||||
@ -170,36 +170,20 @@ jobs:
|
||||
- *make_out_dirs
|
||||
- attach_workspace:
|
||||
at: /tmp/circleci-workspace
|
||||
- run:
|
||||
name: Cloning
|
||||
command: |
|
||||
git clone https://github.com/ipfs/interop.git
|
||||
git -C interop log -1
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v2-interop-{{ checksum "~/ipfs/go-ipfs/interop/package-lock.json" }}
|
||||
- v2-interop-
|
||||
- run:
|
||||
name: Installing dependencies
|
||||
command: |
|
||||
npm install
|
||||
working_directory: ~/ipfs/go-ipfs/interop
|
||||
- save_cache:
|
||||
key: v2-interop-{{ checksum "~/ipfs/go-ipfs/interop/package-lock.json" }}
|
||||
paths:
|
||||
- ~/ipfs/go-ipfs/interop/node_modules
|
||||
- run:
|
||||
name: Installing reporting tools
|
||||
command: |
|
||||
npm install --save-dev mocha-circleci-reporter@0.0.3
|
||||
npm init -y
|
||||
npm install ipfs@^0.50.1
|
||||
npm install ipfs-interop@^3.0.0
|
||||
npm install mocha-circleci-reporter@0.0.3
|
||||
working_directory: ~/ipfs/go-ipfs/interop
|
||||
- run:
|
||||
name: Running tests
|
||||
command: |
|
||||
mkdir -p /tmp/test-results/interop/
|
||||
export MOCHA_FILE="$(mktemp /tmp/test-results/interop/unit.XXXXXX.xml)"
|
||||
node_modules/.bin/mocha --reporter mocha-circleci-reporter \
|
||||
$(sed -n -e "s|^require('\(.*\)')$|test/\1|p" test/node.js | circleci tests split)
|
||||
npx ipfs-interop -- -t node -f $(sed -n -e "s|^require('\(.*\)')$|test/\1|p" node_modules/ipfs-interop/test/node.js | circleci tests split) -- --reporter mocha-circleci-reporter
|
||||
working_directory: ~/ipfs/go-ipfs/interop
|
||||
environment:
|
||||
IPFS_REUSEPORT: false
|
||||
@ -386,12 +370,12 @@ workflows:
|
||||
# also means tag-based jobs can only depend on other tag-based jobs, so we
|
||||
# use a separate workflow because every job needs to be tagged together.
|
||||
# see: https://circleci.com/docs/2.0/workflows/#executing-workflows-for-a-git-tag
|
||||
docker-on-tag:
|
||||
docker-on-tag:
|
||||
jobs:
|
||||
- docker-build:
|
||||
filters: *only-version-tags
|
||||
filters: *only-version-tags
|
||||
- docker-push:
|
||||
context: dockerhub
|
||||
filters: *only-version-tags
|
||||
filters: *only-version-tags
|
||||
requires:
|
||||
- docker-build
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug-report.md
vendored
2
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -4,6 +4,8 @@ about: 'Report a bug in go-ipfs.'
|
||||
labels: kind/bug, need/triage
|
||||
---
|
||||
|
||||
<!-- Please report security issues by email to security@ipfs.io -->
|
||||
|
||||
#### Version information:
|
||||
<!-- Output From `ipfs version --all`
|
||||
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -10,7 +10,7 @@ contact_links:
|
||||
url: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md
|
||||
about: Documentation on Private Networks, Filestore and other experimental features.
|
||||
- name: HTTP API Reference
|
||||
url: https://docs-beta.ipfs.io/reference/http/api/#api-v0-add
|
||||
url: https://docs.ipfs.io/reference/http/api/#api-v0-add
|
||||
about: Documentation of all go-ipfs HTTP API endpoints.
|
||||
- name: IPFS Official Forum
|
||||
url: https://discuss.ipfs.io
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@ -27,3 +27,9 @@ vendor
|
||||
go-ipfs-source.tar.gz
|
||||
docs/examples/go-ipfs-as-a-library/example-folder/Qm*
|
||||
/test/sharness/t0054-dag-car-import-export-data/*.car
|
||||
|
||||
# ignore build output from snapcraft
|
||||
/ipfs_*.snap
|
||||
/parts
|
||||
/stage
|
||||
/prime
|
||||
|
||||
296
.mailmap
Normal file
296
.mailmap
Normal file
@ -0,0 +1,296 @@
|
||||
# This file allows re-mapping author names/emails
|
||||
# while maintaining the integrity of the repository
|
||||
#
|
||||
# Spec: https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html#_mapping_authors
|
||||
#
|
||||
|
||||
@RubenKelevra <cyrond@gmail.com>
|
||||
Aaron Hill <aa1ronham@gmail.com>
|
||||
Adam Gashlin <agashlin@gmail.com>
|
||||
Adam Uhlir <uhlir.a@gmail.com>
|
||||
Adin Schmahmann <adin.schmahmann@gmail.com>
|
||||
Adrian Lanzafame <adrianlanzafame92@gmail.com>
|
||||
Adrian Ulrich <adrian@blinkenlights.ch>
|
||||
Alan Shaw <alan.shaw@protocol.ai> <alan@tableflip.io>
|
||||
Alec Brickner <alecjbrick@gmail.com>
|
||||
Alex <alexgbahm@gmail.com>
|
||||
Alfie John <alfie@alfie.wtf>
|
||||
Alfonso Montero <amontero@tinet.org>
|
||||
Ali Mirlou <alimirlou@gmail.com>
|
||||
Andres Buritica <andres@thelinuxkid.com>
|
||||
Andrew Chin <achin@eminence32.net>
|
||||
Andrew Nesbitt <andrewnez@gmail.com>
|
||||
Andy Leap <andyleap@gmail.com>
|
||||
Antti Kaihola <antti+ipfs@kaihola.fi>
|
||||
Artem Andreenko <mio@volmy.com>
|
||||
Arthur Elliott <clownpriest@gmail.com>
|
||||
Bamvor Zhang <jian.zhang@ipfsbit.com>
|
||||
Baptiste Jonglez <baptiste--git@jonglez.org>
|
||||
Bernhard M. Wiedemann <bwiedemann@suse.de>
|
||||
Boris Mann <boris@bmannconsulting.com>
|
||||
Brendan Mc <Bren2010@users.noreply.github.com>
|
||||
Brendan McMillion <brendan@cloudflare.com>
|
||||
Brendan O'Brien <sparkle_pony_2000@qri.io>
|
||||
Brian Tiger Chow <brian.holderchow@gmail.com>
|
||||
Brian Tiger Chow <perfmode@users.noreply.github.com>
|
||||
Caian <caian@ggaunicamp.com>
|
||||
Caio Alonso <caio@caioalonso.com>
|
||||
Carlos Cobo <toqueteos@gmail.com>
|
||||
Casey Chance <caseyjchance@gmail.com>
|
||||
Cayman Nava <caymannava@gmail.com>
|
||||
Chas Leichner <chas@chas.io>
|
||||
Chris Boddy <chris@boddy.im>
|
||||
Chris Chinchilla <chris.ward@consensys.net>
|
||||
Chris Grimmett <xtoast@gmail.com>
|
||||
Chris P <sahib@online.de>
|
||||
Christopher Sasarak <chris.sasarak@gmail.com>
|
||||
Christian Couder <chriscool@tuxfamily.org>
|
||||
Christian Kniep <christian@qnib.org>
|
||||
Christopher Buesser <christopher.buesser@gmail.com>
|
||||
Cole Brown <bigswim@gmail.com>
|
||||
Corbin Page <corbin.page@gmail.com>
|
||||
Cornelius Toole <cornelius.toole@gmail.com>
|
||||
Dan <35669742+NukeManDan@users.noreply.github.com>
|
||||
Daniel Aleksandersen <code@daniel.priv.no>
|
||||
Daniel Grossmann-Kavanagh <me@danielgk.com>
|
||||
Daniel Mack <daniel@zonque.org>
|
||||
David <github@kattfest.se>
|
||||
David Braun <David.Braun@Toptal.com>
|
||||
David Brennan <david.n.brennan@gmail.com>
|
||||
David Dias <mail@daviddias.me> <daviddias.p@gmail.com>
|
||||
David Wagner <wagdav@gmail.com>
|
||||
Devin <studyzy@gmail.com>
|
||||
Dimitris Apostolou <dimitris.apostolou@icloud.com>
|
||||
Diogo Silva <fsdiogo@gmail.com>
|
||||
Dirk McCormick <dirkmdev@gmail.com>
|
||||
Djalil Dreamski <32184973+dreamski21@users.noreply.github.com>
|
||||
Dominic Della Valle <ddvpublic@gmail.com> <DDVpublic@Gmail.com> <ddvpublic@Gmail.com> <not@yet.net>
|
||||
Dominic Tarr <dominic.tarr@gmail.com>
|
||||
Ian Preston <ianopolous@protonmail.com> <ianopolous@gmail.com>
|
||||
Dylan Powers <dylan.kyle.powers@gmail.com>
|
||||
Edison Lee <edisonlee@edisonlee55.com>
|
||||
Elias Gabrielsson <elias@benefactory.se>
|
||||
Emery Hemingway <emery@vfemail.net>
|
||||
Enrique Erne <enrique.erne@gmail.com>
|
||||
Eoghan Ó Carragáin <eoghan.ocarragain@gmail.com>
|
||||
Erik Ingenito <erik@carbonfive.com>
|
||||
Esteban <eginez@gmail.com>
|
||||
Ethan Buchman <ethan@coinculture.info>
|
||||
Etienne Laurin <etienne@atnnn.com>
|
||||
Forrest Weston <forrest@protocol.ai> <fweston@eecs.wsu.edu> <Forrest.Weston@gmail.com>
|
||||
Francesco Canessa <makevoid@gmail.com>
|
||||
Frank Sachsenheim <funkyfuture@users.noreply.github.com>
|
||||
Frederik Riedel <frederik.riedel@frogg.io>
|
||||
Friedel Ziegelmayer <dignifiedquire@gmail.com>
|
||||
George Antoniadis <george@noodles.gr>
|
||||
George Masgras <gmasgras@gmail.com>
|
||||
Giulitti Salvatore <sgiulitti@cloudbasesolutions.com>
|
||||
Giuseppe Bertone <bertone.giuseppe@gmail.com>
|
||||
Gowtham G <gowthamgts12@gmail.com>
|
||||
Harald Nordgren <haraldnordgren@gmail.com>
|
||||
Harlan T Wood <harlantwood@users.noreply.github.com>
|
||||
Hector Sanjuan <hector@protocol.ai> <code@hector.link> <hsanjuan@users.noreply.github.com>
|
||||
Henrique Dias <hacdias@gmail.com>
|
||||
Henry <cryptix@riseup.net>
|
||||
Herman Junge <chpdg42@gmail.com>
|
||||
Hlib <Glebasya2000@mail.ru>
|
||||
Ho-Sheng Hsiao <talktohosh@gmail.com>
|
||||
Hucg <41573766+hcg1314@users.noreply.github.com>
|
||||
Iaroslav Gridin <voker57@gmail.com>
|
||||
Igor Velkov <mozdiav@iav.lv>
|
||||
Ivan <ivan386@users.noreply.github.com>
|
||||
JP Hastings-Spital <jphastings@gmail.com>
|
||||
Jack Loughran <30052269+jackloughran@users.noreply.github.com>
|
||||
Jakub Sztandera <kubuxu@protocol.ai> <kubuxu@gmail.com> <kubuxu@ipfs.io> <kubuxu@protonmail.ch>
|
||||
Jakub Kaczmarzyk <jakubk@mit.edu>
|
||||
James Stanley <james@incoherency.co.uk>
|
||||
Jamie Wilkinson <jamie@jamiedubs.com>
|
||||
Jan Winkelmann <keks@cryptoscope.co> <j-winkelmann@tuhh.de>
|
||||
Jason Carver <jacarver@linkedin.com>
|
||||
Jeff Thompson <jefft0@remap.ucla.edu>
|
||||
Jeromy Johnson <why@ipfs.io> <jeromyj@gmail.com> <jeromy.johnson@isilon.com> <whyrusleeping@users.noreply.github.com>
|
||||
Jesse Weinstein <jesse@wefu.org>
|
||||
Jessica Schilling <jessica@protocol.ai>
|
||||
Jim McDonald <Jim@mcdee.net>
|
||||
John Reed <john@re2d.xyz> <john.reeed@gmail.com>
|
||||
Johnny <9611008+johnnymatthews@users.noreply.github.com>
|
||||
Jon Choi <choi.jonathanh@gmail.com>
|
||||
Jonathan Dahan <jonathan@jonathan.is>
|
||||
Jordan Danford <jordandanford@gmail.com>
|
||||
Jorropo <jorropo.pgm@gmail.com>
|
||||
Juan Batiz-Benet <juan@benet.ai>
|
||||
Justin Drake <drakefjustin@gmail.com>
|
||||
Kacper Łukawski <kacluk98@gmail.com>
|
||||
Karthik Bala <drmelonhead@gmail.com>
|
||||
Kejie Zhang <601172892@qq.com>
|
||||
Kerem <keremgocen@gmail.com>
|
||||
Kevin Atkinson <k@kevina.org>
|
||||
Kevin Simper <kevin.simper@gmail.com>
|
||||
Kevin Wallace <kevin@pentabarf.net>
|
||||
Kirill Goncharov <kdgoncharov@gmail.com>
|
||||
Kishan Mohanbhai Sagathiya <kishansagathiya@gmail.com>
|
||||
Knut Ahlers <knut@ahlers.me>
|
||||
Konstantin Koroviev <kkoroviev@gmail.com>
|
||||
Koushik Roy <koushik@meff.me>
|
||||
Kristoffer Ström <kristoffer@rymdkoloni.se>
|
||||
Kuro1 <412681778@qq.com>
|
||||
Lars Gierth <larsg@systemli.org> <lgierth@users.noreply.github.com>
|
||||
Leo Arias <yo@elopio.net> <leo.arias@canonical.com>
|
||||
Li Zheng <flyskywhy@gmail.com>
|
||||
Lorenzo Manacorda <lorenzo@mailbox.org>
|
||||
Lorenzo Setale <koalalorenzo@users.noreply.github.com>
|
||||
Louis Thibault <l.thibault@sentimens.com>
|
||||
Lucas Garron <code@garron.net>
|
||||
Lucas Molas <schomatis@gmail.com>
|
||||
Marcin Janczyk <marcinjanczyk@gmail.com>
|
||||
Marcin Rataj <lidel@lidel.org>
|
||||
Markus Amalthea Magnuson <markus.magnuson@gmail.com>
|
||||
Marten Seemann <martenseemann@gmail.com>
|
||||
Masashi Salvador Mitsuzawa <masashisalvador57f@gmail.com>
|
||||
Massino Tinovan <massino@droppod,io>
|
||||
Mat Kelly <mkelly@cs.odu.edu>
|
||||
Mathijs de Bruin <mathijs@mathijsfietst.nl>
|
||||
Matouš Skála <skala.matous@gmail.com>
|
||||
Matt Bell <mappum@gmail.com>
|
||||
Matt Joiner <anacrolix@gmail.com>
|
||||
Max Chechel <hexdigest@gmail.com> <mc@gojuno.com>
|
||||
Max Kerp <maxkerp@gmail.com>
|
||||
Mib Kd743naq <mib.kd743naq@gmail.com>
|
||||
Michael Avila <me@michaelavila.com> <davidmichaelavila@gmail.com>
|
||||
Michael Lovci <michaeltlovci@gmail.com>
|
||||
Michael Muré <mure.michael@gmail.com> <batolettre@gmail.com> <michael.mure@consensys.net>
|
||||
Michael Pfister <pfista@gmail.com>
|
||||
Michelle Lee <michelle@protocol.ai>
|
||||
Miguel Torres <migueltorreslopez@gmail.com>
|
||||
Mikaela Suomalainen <mikaela+git@mikaela.info>
|
||||
Mildred Ki'Lya <mildred-pub.git@mildred.fr>
|
||||
Molly <momack2@users.noreply.github.com>
|
||||
Muneeb Ali <muneeb@ali.vc>
|
||||
Mykola Nikishov <mn@mn.com.ua>
|
||||
Nathan Musoke <nathan.musoke@gmail.com>
|
||||
Nick Hamann <nick@wabbo.org>
|
||||
Oli Evans <oli@tableflip.io>
|
||||
Or Rikon <rikonor@gmail.com>
|
||||
Overbool <overbool.xu@gmail.com>
|
||||
Patrick Connolly <patrick.c.connolly@gmail.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Peter Borzov <peter@sowingo.com> <tihoutrom@gmail.com>
|
||||
Peter Rabbitson <ribasushi@protocol.ai> <peter@protocol.ai> <ribasushi@leporine.io> <mib.kd743naq@gmail.com>
|
||||
Peter Wu <pwu@cloudflare.com>
|
||||
Philip Nelson <me@pnelson.ca>
|
||||
Pierre-Alain TORET <pierre-alain.toret@protonmail.com>
|
||||
PoorPockets McNewHold <poorpocketsmcnewhold@protonmail.ch>
|
||||
Pretty Please Mark Darkly <55382229+pleasemarkdarkly@users.noreply.github.com>
|
||||
Péter Szilágyi <peterke@gmail.com>
|
||||
Quantomic <minima38123@gmail.com>
|
||||
Quinn Slack <sqs@sourcegraph.com>
|
||||
Raúl Kripalani <raul@protocol.ai> <raul.kripalani@consensys.net>
|
||||
ReadmeCritic <frankensteinbot@gmail.com>
|
||||
Remco Bloemen <remco-git@xn--2-umb.com>
|
||||
Richard Littauer <richard.littauer@gmail.com>
|
||||
RideWindX <ridewindx@163.com>
|
||||
Rob Brackett <rob@robbrackett.com>
|
||||
Robert Carlsen <rwcarlsen@gmail.com>
|
||||
Rod Vagg <rod@vagg.org>
|
||||
Roerick Sweeney <sroerick@gmail.com>
|
||||
Roman Khafizianov <requilence@gmail.com>
|
||||
Roman Proskuryakov <humbug@deeptown.org>
|
||||
Ronsor <ronsor@ronsor.pw>
|
||||
RubenKelevra <cyrond@gmail.com>
|
||||
Ryan Carver <ryan@ryancarver.com>
|
||||
Ryan Morey <ryan.t.morey@gmail.com>
|
||||
SH <github@hertenberger.bayern>
|
||||
Sag0Sag0 <Sag0Sag0@users.noreply.github.com>
|
||||
Sander Pick <sanderpick@gmail.com>
|
||||
Scott Bigelow <epheph@gmail.com>
|
||||
Sean Lang <slang800@gmail.com>
|
||||
Shanti Bouchez-Mongardé <shanti-pub.git@mildred.fr>
|
||||
Shaun Bruce <shaun.m.bruce@gmail.com>
|
||||
Sherod Taylor <staylor@itbit.com>
|
||||
Simon Kirkby <tigger@interthingy.com>
|
||||
Simon Menke <simon.menke@gmail.com>
|
||||
Siraj Ravel <sirajravel@gmail.com> <llSourcell@gmail.com> <jason.ravel@cbsinteractive.com>
|
||||
Siva Chandran <siva.chandran@realimage.com>
|
||||
Spartucus <spartucus@users.noreply.github.com>
|
||||
Stephan Kulla <git.mail@kulla.me>
|
||||
Stephan Seidt <evilhackerdude@gmail.com> <stephan.seidt@gmail.com>
|
||||
Stephen Sugden <me@stephensugden.com>
|
||||
Stephen Whitmore <stephen.whitmore@gmail.com> <noffle@users.noreply.github.com>
|
||||
Steve Recio <stevenrecio@gmail.com>
|
||||
Steven Allen <steven@stebalien.com>
|
||||
Steven Vandevelde <icid.asset@gmail.com>
|
||||
Sönke Hahn <soenkehahn@gmail.com>
|
||||
TUSF <ragef33@gmail.com>
|
||||
Tarnay Kálmán <kalmisoft@gmail.com>
|
||||
Thomas Gardner <tmg@fastmail.com>
|
||||
Tiger <rbalajis25@gmail.com>
|
||||
Tim Groeneveld <tim@timg.ws>
|
||||
Tim Stahel <git@swedneck.xyz>
|
||||
Timothy Hobbs <timothyhobbs@seznam.cz>
|
||||
Tom O'Donnell <todonnel91@gmail.com>
|
||||
Tom Swindell <t.swindell@rubyx.co.uk>
|
||||
Tommi Virtanen <tv@eagain.net>
|
||||
Tonis Tiigi <tonistiigi@gmail.com>
|
||||
Tor Arne Vestbø <torarnv@gmail.com>
|
||||
Travis Person <travis.person@gmail.com> <travis@protocol.ai>
|
||||
Tylar <murray.tylar@gmail.com>
|
||||
John Reed <john@re2d.xyz>
|
||||
Vasil Dimov <vd@FreeBSD.org>
|
||||
Vijayee Kulkaa <vijayee.kulkaa@.husmail.com>
|
||||
Vikram <vikram1791@gmail.com>
|
||||
Vitor Baptista <vitor@vitorbaptista.com>
|
||||
W. Trevor King <wking@tremily.us>
|
||||
Wes Morgan <wesmorgan@icloud.com>
|
||||
Will Scott <will@cypherpunk.email>
|
||||
Willi Butz <wbutz@cyberfnord.de>
|
||||
Xiaoyi Wang <wangxiaoyi@hyperchain.cn>
|
||||
Yuval Langer <yuval.langer@gmail.com>
|
||||
Zander Mackie <zmackie@gmail.com>
|
||||
ZenGround0 <ZenGround0@users.noreply.github.com>
|
||||
achingbrain <alex@achingbrain.net>
|
||||
adamliesko <adamliesko@gmail.com>
|
||||
anarcat <anarcat@users.noreply.github.com>
|
||||
bbenshoof <brendan@glidr.net>
|
||||
camelmasa <camelmasa@gmail.com>
|
||||
chenminjian <727180553@qq.com>
|
||||
devedge <devedge@outlook.com>
|
||||
dgrisham <dgrisham@mines.edu>
|
||||
drathir <drathir87@gmail.com>
|
||||
epitron <chris@ill-logic.com>
|
||||
eric wu <eric.wu@blockheaders.com>
|
||||
flowed <yoginth@protonmail.com>
|
||||
forstmeier <john.forstmeier@gmail.com>
|
||||
fyrchik <kraunid@gmail.com>
|
||||
gatesvp <gatesvp@gmail.com>
|
||||
hannahhoward <hannah@hannahhoward.net>
|
||||
hikerpig <hikerpigwinnie@gmail.com>
|
||||
hoenirvili <hoenirvili@gmail.com>
|
||||
hucg <hucg>
|
||||
ivan386 <ivan386@yandex.ru>
|
||||
klauspost <klauspost@gmail.com>
|
||||
kpcyrd <git@rxv.cc>
|
||||
kvm2116 <kvm2116@columbia.edu>
|
||||
mateon1 <matin1111@wp.pl>
|
||||
matrushka <barisgumustas@gmail.com>
|
||||
michael <pfista@gmail.com>
|
||||
myself659 <myself659@163.com>
|
||||
nmalhotra <nitish.malhotra@cspi.com>
|
||||
palkeo <contact@palkeo.com>
|
||||
requilence <requilence@gmail.com>
|
||||
rht <rhtbot@gmail.com> <rudyht@gmail.com>
|
||||
rob-deutsch <robzyb+altgithub@gmail.com>
|
||||
slothbag <slothbag>
|
||||
sroerick <sroerick@gmail.com>
|
||||
swedneck <40505480+swedneck@users.noreply.github.com>
|
||||
tarekbadr <tarekbadrshalaan@gmail.com>
|
||||
tcme <hi@this-connect.me>
|
||||
tg <tolstov.georgij@gmail.com>
|
||||
theswitch <theswitch@users.noreply.github.com>
|
||||
verokarhu <andreas.metsala@gmail.com>
|
||||
vitzli <vitzli@gmail.com>
|
||||
vyzo <vyzo@hackzen.org>
|
||||
wzhd <dev@wzhd.org>
|
||||
zramsay <zach@monax.io> <zach@erisindustries.com>
|
||||
Łukasz Magiera <magik6k@gmail.com> <magik6k@users.noreply.github.com>
|
||||
ᴍᴀᴛᴛ ʙᴇʟʟ <mappum@gmail.com>
|
||||
ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>
|
||||
539
CHANGELOG.md
539
CHANGELOG.md
@ -1,5 +1,544 @@
|
||||
# go-ipfs changelog
|
||||
|
||||
## v0.7.0 2020-09-22
|
||||
|
||||
### Highlights
|
||||
|
||||
#### Secio is now disabled by default
|
||||
|
||||
As part of deprecating and removing support for the Secio security transport, we have disabled it by default. TLS1.3 will remain the default security transport with fallback to Noise. You can read more about the deprecation in the blog post, https://blog.ipfs.io/2020-08-07-deprecating-secio/. If you're running IPFS older than 0.5, this may start to impact your performance on the public network.
|
||||
|
||||
#### Ed25519 keys are now used by default
|
||||
|
||||
Previously go-ipfs generated 2048 bit RSA keys for new nodes, but it will now use ed25519 keys by default. This will not affect any existing keys, but newly created keys will be ed25519 by default. The main benefit of using ed25519 keys over RSA is that ed25519 keys have an inline public key. This means that someone only needs your PeerId to verify things you've signed, which means we don't have to worry about storing those bulky RSA public keys.
|
||||
|
||||
##### Rotating keys
|
||||
|
||||
Along with switching the default, we've added support for rotating keys. If you would like to change the key type of your IPFS node, you can now do so with the rotate command. **NOTE: This will affect your Peer Id, so be sure you want to do this!** Your existing identity key will be backed up in the Keystore.
|
||||
|
||||
```bash
|
||||
ipfs key rotate -o my-old-key -t ed25519
|
||||
```
|
||||
|
||||
#### Key export/import
|
||||
|
||||
We've added commands to allow you to export and import keys from the IPFS Keystore to a local .key file. This does not apply to the IPFS identity key, `self`.
|
||||
|
||||
```bash
|
||||
ipfs key gen mykey
|
||||
ipfs key export -o mykey.key mykey # ./<name>.key is the default path
|
||||
ipfs key import mykey mykey.key # on another node
|
||||
```
|
||||
|
||||
#### IPNS paths now encode the key name as a base36 CIDv1 by default
|
||||
|
||||
Previously go-ipfs encoded the key names for IPNS paths as base58btc multihashes (e.g. Qmabc...). We now encode them as base36 encoded CIDv1s as defined in the [peerID spec](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#string-representation) (e.g. k51xyz...) which also deals with encoding of public keys. This is nice because it means that IPNS keys will by default be case-insensitive and that they will fit into DNS labels (e.g. k51xyz...ipns.localhost) and therefore that subdomain gateway redirections (e.g. from localhost:8080/ipns/{key} to {key}.ipns.localhost) will look better to users in the default case.
|
||||
|
||||
Many commands will accept a `--ipns-base` option that allows changing command outputs to use a particular encoding (i.e. base58btc multihash, or CIDv1 encoded in any supported base)
|
||||
|
||||
#### Multiaddresses now accept PeerIDs encoded as CIDv1
|
||||
|
||||
In preparation for eventually changing the default PeerID representation multiaddresses can now contain strings like `/p2p/k51xyz...` in addition to the default `/p2p/Qmabc...`. There is a corresponding `--peerid-base` option to many functions that output peerIDs.
|
||||
|
||||
#### `dag stat`
|
||||
|
||||
Initial support has been added for the `ipfs dag stat` command. Running this command will traverse the DAG for the given root CID and report statistics. By default, progress will be shown as the DAG is traversed. Supported statistics currently include DAG size and number of blocks.
|
||||
|
||||
```bash
|
||||
ipfs dag stat bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e # the IPFS webui
|
||||
Size: 30362191, NumBlocks: 346
|
||||
```
|
||||
|
||||
#### Plugin build changes
|
||||
|
||||
We have changed the build flags used by the official binary distributions on dist.ipfs.io (or `/ipns/dist.ipfs.io`) to use the simpler and more reliable `-trimpath` flag instead of the more complicated and brittle `-asmflags=all=-trimpath="$(GOPATH)" -gcflags=all=-trimpath="$(GOPATH)"` flags, however the build flags used by default in go-ipfs remain the same.
|
||||
|
||||
The scripts in https://github.com/ipfs/go-ipfs-example-plugin have been updated to reflect this change. This is a breaking change to how people have been building plugins against the dist.ipfs.io binary of go-ipfs and plugins should update their build processes accordingly see https://github.com/ipfs/go-ipfs-example-plugin/pull/9 for details.
|
||||
|
||||
### Changelog
|
||||
|
||||
- github.com/ipfs/go-ipfs:
|
||||
- chore: bump webui version
|
||||
- fix: remove the (empty) alias for --peerid-base
|
||||
- Release v0.7.0-rc2
|
||||
- fix: use override GOFLAGS changes from 480defab689610550ee3d346e31441a2bb881fcb but keep trimpath usage as is
|
||||
- Revert "fix: override GOFLAGS"
|
||||
- fix: remove the (empty) alias for --ipns-base
|
||||
- refactor: put all --ipns-base options in one place
|
||||
- docs: update config to indicate SECIO deprecation
|
||||
- fix: ipfs dht put/get commands now work on keys encoded as peerIDs and fail early for namespaces other than /pk or /ipns
|
||||
- Release v0.7.0-rc1
|
||||
- chore: cleanup ([ipfs/go-ipfs#7628](https://github.com/ipfs/go-ipfs/pull/7628))
|
||||
- namesys: fixed IPNS republisher to not overwrite IPNS record lifetimes ([ipfs/go-ipfs#7627](https://github.com/ipfs/go-ipfs/pull/7627))
|
||||
- Fix #7624: Do not fetch dag nodes when checking if a pin exists ([ipfs/go-ipfs#7625](https://github.com/ipfs/go-ipfs/pull/7625))
|
||||
- chore: update dependencies ([ipfs/go-ipfs#7610](https://github.com/ipfs/go-ipfs/pull/7610))
|
||||
- use t.Cleanup() to reduce the need to clean up servers in tests ([ipfs/go-ipfs#7550](https://github.com/ipfs/go-ipfs/pull/7550))
|
||||
- fix: ipfs pin ls - ignore pins that have errors ([ipfs/go-ipfs#7612](https://github.com/ipfs/go-ipfs/pull/7612))
|
||||
- docs(config): fix Peering header ([ipfs/go-ipfs#7623](https://github.com/ipfs/go-ipfs/pull/7623))
|
||||
- sharness: use dnsaddr example in ipfs p2p command tests ([ipfs/go-ipfs#7620](https://github.com/ipfs/go-ipfs/pull/7620))
|
||||
- fix(key): dont allow backup key to be named 'self' ([ipfs/go-ipfs#7615](https://github.com/ipfs/go-ipfs/pull/7615))
|
||||
- [BOUNTY] Directory page UI improvements ([ipfs/go-ipfs#7536](https://github.com/ipfs/go-ipfs/pull/7536))
|
||||
- fix: make assets deterministic ([ipfs/go-ipfs#7609](https://github.com/ipfs/go-ipfs/pull/7609))
|
||||
- use ed25519 keys by default ([ipfs/go-ipfs#7579](https://github.com/ipfs/go-ipfs/pull/7579))
|
||||
- feat: wildcard support for public gateways ([ipfs/go-ipfs#7319](https://github.com/ipfs/go-ipfs/pull/7319))
|
||||
- fix: fix go-bindata import path ([ipfs/go-ipfs#7605](https://github.com/ipfs/go-ipfs/pull/7605))
|
||||
- Upgrade graphsync deps ([ipfs/go-ipfs#7598](https://github.com/ipfs/go-ipfs/pull/7598))
|
||||
- Add --peerid-base to ipfs id command ([ipfs/go-ipfs#7591](https://github.com/ipfs/go-ipfs/pull/7591))
|
||||
- use b36 keys by default for keys and IPNS ([ipfs/go-ipfs#7582](https://github.com/ipfs/go-ipfs/pull/7582))
|
||||
- add ipfs dag stat command (#7553) ([ipfs/go-ipfs#7553](https://github.com/ipfs/go-ipfs/pull/7553))
|
||||
- Move key rotation command to ipfs key rotate ([ipfs/go-ipfs#7599](https://github.com/ipfs/go-ipfs/pull/7599))
|
||||
- Disable secio by default ([ipfs/go-ipfs#7600](https://github.com/ipfs/go-ipfs/pull/7600))
|
||||
- Stop searching for public keys before doing an IPNS Get (#7549) ([ipfs/go-ipfs#7549](https://github.com/ipfs/go-ipfs/pull/7549))
|
||||
- feat: return supported protocols in id output ([ipfs/go-ipfs#7409](https://github.com/ipfs/go-ipfs/pull/7409))
|
||||
- docs: fix typo in default swarm addrs config docs ([ipfs/go-ipfs#7585](https://github.com/ipfs/go-ipfs/pull/7585))
|
||||
- feat: nice errors when failing to load plugins ([ipfs/go-ipfs#7429](https://github.com/ipfs/go-ipfs/pull/7429))
|
||||
- doc: document reverse proxy bug ([ipfs/go-ipfs#7478](https://github.com/ipfs/go-ipfs/pull/7478))
|
||||
- fix: ipfs name resolve --dht-record-count flag uses correct type and now works
|
||||
- refactor: get rid of cmdDetails awkwardness
|
||||
- IPNS format keys in b36cid ([ipfs/go-ipfs#7554](https://github.com/ipfs/go-ipfs/pull/7554))
|
||||
- Key import and export cli commands ([ipfs/go-ipfs#7546](https://github.com/ipfs/go-ipfs/pull/7546))
|
||||
- feat: add snap package configuration ([ipfs/go-ipfs#7529](https://github.com/ipfs/go-ipfs/pull/7529))
|
||||
- chore: bump webui version
|
||||
- repeat gateway subdomain test for all key types (#7542) ([ipfs/go-ipfs#7542](https://github.com/ipfs/go-ipfs/pull/7542))
|
||||
- fix: override GOFLAGS
|
||||
- update QUIC, enable the RetireBugBackwardsCompatibilityMode
|
||||
- Document add behavior when the daemon is not running ([ipfs/go-ipfs#7514](https://github.com/ipfs/go-ipfs/pull/7514))
|
||||
- ([ipfs/go-ipfs#7515](https://github.com/ipfs/go-ipfs/pull/7515))
|
||||
- Choose Key type at initialization ([ipfs/go-ipfs#7251](https://github.com/ipfs/go-ipfs/pull/7251))
|
||||
- feat: add flag to ipfs key and list to output keys in b36/CIDv1 (#7531) ([ipfs/go-ipfs#7531](https://github.com/ipfs/go-ipfs/pull/7531))
|
||||
- feat: support ED25519 libp2p-key in subdomains
|
||||
- chore: fix a typo
|
||||
- docs: document X-Forwarded-Host
|
||||
- feat: support X-Forwarded-Host when doing gateway redirect
|
||||
- chore: update test deps for graphsync
|
||||
- chore: bump test dependencies ([ipfs/go-ipfs#7524](https://github.com/ipfs/go-ipfs/pull/7524))
|
||||
- fix: use static binaries in docker container ([ipfs/go-ipfs#7505](https://github.com/ipfs/go-ipfs/pull/7505))
|
||||
- chore:bump webui version to 2.10.1 ([ipfs/go-ipfs#7504](https://github.com/ipfs/go-ipfs/pull/7504))
|
||||
- chore: bump webui version ([ipfs/go-ipfs#7501](https://github.com/ipfs/go-ipfs/pull/7501))
|
||||
- update version to 0.7.0-dev
|
||||
- Merge branch 'release' into master
|
||||
- systemd: specify repo path, to avoid unnecessary subdirectory ([ipfs/go-ipfs#7472](https://github.com/ipfs/go-ipfs/pull/7472))
|
||||
- doc(prod): start documenting production stuff ([ipfs/go-ipfs#7469](https://github.com/ipfs/go-ipfs/pull/7469))
|
||||
- Readme: Update link about init systems (and import old readme) ([ipfs/go-ipfs#7473](https://github.com/ipfs/go-ipfs/pull/7473))
|
||||
- doc(config): expand peering docs ([ipfs/go-ipfs#7466](https://github.com/ipfs/go-ipfs/pull/7466))
|
||||
- fix: Use the -p option in Dockerfile to make parents as needed ([ipfs/go-ipfs#7464](https://github.com/ipfs/go-ipfs/pull/7464))
|
||||
- systemd: enable systemd hardening features ([ipfs/go-ipfs#7286](https://github.com/ipfs/go-ipfs/pull/7286))
|
||||
- fix(migration): migrate /ipfs/ bootstrappers to /p2p/ ([ipfs/go-ipfs#7450](https://github.com/ipfs/go-ipfs/pull/7450))
|
||||
- readme: update go-version ([ipfs/go-ipfs#7447](https://github.com/ipfs/go-ipfs/pull/7447))
|
||||
- fix(migration): correctly migrate quic addresses ([ipfs/go-ipfs#7446](https://github.com/ipfs/go-ipfs/pull/7446))
|
||||
- chore: add migration to listen on QUIC by default ([ipfs/go-ipfs#7443](https://github.com/ipfs/go-ipfs/pull/7443))
|
||||
- go: bump minimal dependency to 1.14.4 ([ipfs/go-ipfs#7419](https://github.com/ipfs/go-ipfs/pull/7419))
|
||||
- fix: use bitswap sessions for ipfs refs ([ipfs/go-ipfs#7389](https://github.com/ipfs/go-ipfs/pull/7389))
|
||||
- fix(commands): print consistent addresses in ipfs id ([ipfs/go-ipfs#7397](https://github.com/ipfs/go-ipfs/pull/7397))
|
||||
- fix two pubsub issues. ([ipfs/go-ipfs#7394](https://github.com/ipfs/go-ipfs/pull/7394))
|
||||
- docs: add pacman.store (@RubenKelevra) to the early testers ([ipfs/go-ipfs#7368](https://github.com/ipfs/go-ipfs/pull/7368))
|
||||
- Update docs-beta links to final URLs ([ipfs/go-ipfs#7386](https://github.com/ipfs/go-ipfs/pull/7386))
|
||||
- feat: webui v2.9.0 ([ipfs/go-ipfs#7387](https://github.com/ipfs/go-ipfs/pull/7387))
|
||||
- chore: update WebUI to 2.8.0 ([ipfs/go-ipfs#7380](https://github.com/ipfs/go-ipfs/pull/7380))
|
||||
- mailmap support ([ipfs/go-ipfs#7375](https://github.com/ipfs/go-ipfs/pull/7375))
|
||||
- doc: update the release template for git flow changes ([ipfs/go-ipfs#7370](https://github.com/ipfs/go-ipfs/pull/7370))
|
||||
- chore: update deps ([ipfs/go-ipfs#7369](https://github.com/ipfs/go-ipfs/pull/7369))
|
||||
- github.com/ipfs/go-bitswap (v0.2.19 -> v0.2.20):
|
||||
- fix: don't say we're sending a full wantlist unless we are (#429) ([ipfs/go-bitswap#429](https://github.com/ipfs/go-bitswap/pull/429))
|
||||
- github.com/ipfs/go-cid (v0.0.6 -> v0.0.7):
|
||||
- feat: optimize cid.Prefix ([ipfs/go-cid#109](https://github.com/ipfs/go-cid/pull/109))
|
||||
- github.com/ipfs/go-datastore (v0.4.4 -> v0.4.5):
|
||||
- Add test to ensure that Delete returns no error for missing keys ([ipfs/go-datastore#162](https://github.com/ipfs/go-datastore/pull/162))
|
||||
- Fix typo in sync/sync.go ([ipfs/go-datastore#159](https://github.com/ipfs/go-datastore/pull/159))
|
||||
- Add the generated flatfs stub, since it cannot be auto-generated ([ipfs/go-datastore#158](https://github.com/ipfs/go-datastore/pull/158))
|
||||
- support flatfs fuzzing ([ipfs/go-datastore#157](https://github.com/ipfs/go-datastore/pull/157))
|
||||
- fuzzing harness (#153) ([ipfs/go-datastore#153](https://github.com/ipfs/go-datastore/pull/153))
|
||||
- feat(mount): don't give up on error ([ipfs/go-datastore#146](https://github.com/ipfs/go-datastore/pull/146))
|
||||
- /test: fix bad ElemCount/10 lenght (should not be divided) ([ipfs/go-datastore#152](https://github.com/ipfs/go-datastore/pull/152))
|
||||
- github.com/ipfs/go-ds-flatfs (v0.4.4 -> v0.4.5):
|
||||
- Add os.Rename wrapper for Plan 9 (#87) ([ipfs/go-ds-flatfs#87](https://github.com/ipfs/go-ds-flatfs/pull/87))
|
||||
- github.com/ipfs/go-fs-lock (v0.0.5 -> v0.0.6):
|
||||
- Fix build on Plan 9 ([ipfs/go-fs-lock#17](https://github.com/ipfs/go-fs-lock/pull/17))
|
||||
- github.com/ipfs/go-graphsync (v0.0.5 -> v0.1.1):
|
||||
- docs(CHANGELOG): update for v0.1.1
|
||||
- docs(CHANGELOG): update for v0.1.0 release ([ipfs/go-graphsync#84](https://github.com/ipfs/go-graphsync/pull/84))
|
||||
- Dedup by key extension (#83) ([ipfs/go-graphsync#83](https://github.com/ipfs/go-graphsync/pull/83))
|
||||
- Release infrastructure (#81) ([ipfs/go-graphsync#81](https://github.com/ipfs/go-graphsync/pull/81))
|
||||
- feat(persistenceoptions): add unregister ability (#80) ([ipfs/go-graphsync#80](https://github.com/ipfs/go-graphsync/pull/80))
|
||||
- fix(message): regen protobuf code (#79) ([ipfs/go-graphsync#79](https://github.com/ipfs/go-graphsync/pull/79))
|
||||
- feat(requestmanager): run response hooks on completed requests (#77) ([ipfs/go-graphsync#77](https://github.com/ipfs/go-graphsync/pull/77))
|
||||
- Revert "add extensions on complete (#76)"
|
||||
- add extensions on complete (#76) ([ipfs/go-graphsync#76](https://github.com/ipfs/go-graphsync/pull/76))
|
||||
- All changes to date including pause requests & start paused, along with new adds for cleanups and checking of execution (#75) ([ipfs/go-graphsync#75](https://github.com/ipfs/go-graphsync/pull/75))
|
||||
- More fine grained response controls (#71) ([ipfs/go-graphsync#71](https://github.com/ipfs/go-graphsync/pull/71))
|
||||
- Refactor request execution and use IPLD SkipMe functionality for proper partial results on a request (#70) ([ipfs/go-graphsync#70](https://github.com/ipfs/go-graphsync/pull/70))
|
||||
- feat(graphsync): implement do-no-send-cids extension (#69) ([ipfs/go-graphsync#69](https://github.com/ipfs/go-graphsync/pull/69))
|
||||
- Incoming Block Hooks (#68) ([ipfs/go-graphsync#68](https://github.com/ipfs/go-graphsync/pull/68))
|
||||
- fix(responsemanager): add nil check (#67) ([ipfs/go-graphsync#67](https://github.com/ipfs/go-graphsync/pull/67))
|
||||
- refactor(hooks): use external pubsub (#65) ([ipfs/go-graphsync#65](https://github.com/ipfs/go-graphsync/pull/65))
|
||||
- Update of IPLD Prime (#66) ([ipfs/go-graphsync#66](https://github.com/ipfs/go-graphsync/pull/66))
|
||||
- feat(responsemanager): add listener for completed responses (#64) ([ipfs/go-graphsync#64](https://github.com/ipfs/go-graphsync/pull/64))
|
||||
- Update Requests (#63) ([ipfs/go-graphsync#63](https://github.com/ipfs/go-graphsync/pull/63))
|
||||
- Add pausing and unpausing of requests (#62) ([ipfs/go-graphsync#62](https://github.com/ipfs/go-graphsync/pull/62))
|
||||
- Outgoing Request Hooks, swapping persistence layers (#61) ([ipfs/go-graphsync#61](https://github.com/ipfs/go-graphsync/pull/61))
|
||||
- Feat/request hook loader chooser (#60) ([ipfs/go-graphsync#60](https://github.com/ipfs/go-graphsync/pull/60))
|
||||
- Option to Reject requests by default (#58) ([ipfs/go-graphsync#58](https://github.com/ipfs/go-graphsync/pull/58))
|
||||
- Testify refactor (#56) ([ipfs/go-graphsync#56](https://github.com/ipfs/go-graphsync/pull/56))
|
||||
- Switch To Circle CI (#57) ([ipfs/go-graphsync#57](https://github.com/ipfs/go-graphsync/pull/57))
|
||||
- fix(deps): go mod tidy
|
||||
- docs(README): remove ipldbridge reference
|
||||
- Tech Debt: Remove IPLD Bridge ([ipfs/go-graphsync#55](https://github.com/ipfs/go-graphsync/pull/55))
|
||||
- github.com/ipfs/go-ipfs-cmds (v0.2.9 -> v0.4.0):
|
||||
- fix: allow requests from electron renderer (#201) ([ipfs/go-ipfs-cmds#201](https://github.com/ipfs/go-ipfs-cmds/pull/201))
|
||||
- refactor: move external command checks into commands lib (#198) ([ipfs/go-ipfs-cmds#198](https://github.com/ipfs/go-ipfs-cmds/pull/198))
|
||||
- Fix build on Plan 9 ([ipfs/go-ipfs-cmds#199](https://github.com/ipfs/go-ipfs-cmds/pull/199))
|
||||
- github.com/ipfs/go-ipfs-config (v0.8.0 -> v0.9.0):
|
||||
- error if bit size specified with ed25519 keys (#105) ([ipfs/go-ipfs-config#105](https://github.com/ipfs/go-ipfs-config/pull/105))
|
||||
- github.com/ipfs/go-log/v2 (v2.0.8 -> v2.1.1):
|
||||
failed to fetch repo
|
||||
- github.com/ipfs/go-path (v0.0.7 -> v0.0.8):
|
||||
- ResolveToLastNode no longer fetches nodes it does not need ([ipfs/go-path#30](https://github.com/ipfs/go-path/pull/30))
|
||||
- doc: add a lead maintainer
|
||||
- github.com/ipfs/interface-go-ipfs-core (v0.3.0 -> v0.4.0):
|
||||
- Add ID formatting functions, used by various IPFS cli commands ([ipfs/interface-go-ipfs-core#65](https://github.com/ipfs/interface-go-ipfs-core/pull/65))
|
||||
- github.com/ipld/go-car (v0.1.0 -> v0.1.1-0.20200429200904-c222d793c339):
|
||||
- Update go-ipld-prime to the era of NodeAssembler. ([ipld/go-car#31](https://github.com/ipld/go-car/pull/31))
|
||||
- fix: update the cli tool's car dep ([ipld/go-car#30](https://github.com/ipld/go-car/pull/30))
|
||||
- github.com/ipld/go-ipld-prime (v0.0.2-0.20191108012745-28a82f04c785 -> v0.0.2-0.20200428162820-8b59dc292b8e):
|
||||
- Add two basic examples of usage, as go tests.
|
||||
- Fix marshalling error ([ipld/go-ipld-prime#53](https://github.com/ipld/go-ipld-prime/pull/53))
|
||||
- Add more test specs for list and map nesting.
|
||||
- traversal.SkipMe feature ([ipld/go-ipld-prime#51](https://github.com/ipld/go-ipld-prime/pull/51))
|
||||
- Improvements to traversal docs.
|
||||
- Drop code coverage bot config. ([ipld/go-ipld-prime#50](https://github.com/ipld/go-ipld-prime/pull/50))
|
||||
- Promote NodeAssembler/NodeStyle interface rework to core, and use improved basicnode implementation. ([ipld/go-ipld-prime#49](https://github.com/ipld/go-ipld-prime/pull/49))
|
||||
- Merge branch 'traversal-benchmarks'
|
||||
- Merge branch 'cycle-breaking-and-traversal-benchmarks'
|
||||
- Merge branch 'assembler-upgrade-to-codecs'
|
||||
- Path clarifications ([ipld/go-ipld-prime#47](https://github.com/ipld/go-ipld-prime/pull/47))
|
||||
- Merge branch 'research-admissions'
|
||||
- Add a typed link node to allow traversal with code gen'd builders across links ([ipld/go-ipld-prime#41](https://github.com/ipld/go-ipld-prime/pull/41))
|
||||
- Merge branch 'research-admissions'
|
||||
- Library updates.
|
||||
- Feat/add code gen disclaimer ([ipld/go-ipld-prime#39](https://github.com/ipld/go-ipld-prime/pull/39))
|
||||
- Readme and key Node interface docs improvements.
|
||||
- fix(schema/gen): return value not reference ([ipld/go-ipld-prime#38](https://github.com/ipld/go-ipld-prime/pull/38))
|
||||
- github.com/ipld/go-ipld-prime-proto (v0.0.0-20191113031812-e32bd156a1e5 -> v0.0.0-20200428191222-c1ffdadc01e1):
|
||||
- feat(deps): upgrade to new IPLD prime ([ipld/go-ipld-prime-proto#1](https://github.com/ipld/go-ipld-prime-proto/pull/1))
|
||||
- Update to latest ipld before rework ([ipld/go-ipld-prime-proto#2](https://github.com/ipld/go-ipld-prime-proto/pull/2))
|
||||
- github.com/libp2p/go-libp2p (v0.9.6 -> v0.11.0):
|
||||
- Added parsing of IPv6 addresses for incoming mDNS requests ([libp2p/go-libp2p#990](https://github.com/libp2p/go-libp2p/pull/990))
|
||||
- Switch from SECIO to Noise ([libp2p/go-libp2p#972](https://github.com/libp2p/go-libp2p/pull/972))
|
||||
- fix tests ([libp2p/go-libp2p#995](https://github.com/libp2p/go-libp2p/pull/995))
|
||||
- Bump Autonat version & validate fixed call loop in `.Addrs` (#988) ([libp2p/go-libp2p#988](https://github.com/libp2p/go-libp2p/pull/988))
|
||||
- fix: use the correct external address when NAT port-mapping ([libp2p/go-libp2p#987](https://github.com/libp2p/go-libp2p/pull/987))
|
||||
- upgrade deps + interoperable uvarint delimited writer/reader. (#985) ([libp2p/go-libp2p#985](https://github.com/libp2p/go-libp2p/pull/985))
|
||||
- fix host can be dialed by autonat public addr, but lost the public addr to announce ([libp2p/go-libp2p#983](https://github.com/libp2p/go-libp2p/pull/983))
|
||||
- Fix address advertisement bugs (#974) ([libp2p/go-libp2p#974](https://github.com/libp2p/go-libp2p/pull/974))
|
||||
- fix: avoid a close deadlock in the natmanager ([libp2p/go-libp2p#971](https://github.com/libp2p/go-libp2p/pull/971))
|
||||
- upgrade swarm; add ID() on mock conns and streams. (#970) ([libp2p/go-libp2p#970](https://github.com/libp2p/go-libp2p/pull/970))
|
||||
- github.com/libp2p/go-libp2p-asn-util (null -> v0.0.0-20200825225859-85005c6cf052):
|
||||
- chore: go fmt
|
||||
- feat: use deferred initialization of the asnStore ([libp2p/go-libp2p-asn-util#3](https://github.com/libp2p/go-libp2p-asn-util/pull/3))
|
||||
- chore: switch to forked cidranger
|
||||
- fixed code
|
||||
- library for ASN mappings
|
||||
- github.com/libp2p/go-libp2p-autonat (v0.2.3 -> v0.3.2):
|
||||
- static nat shouldn't call host.Addrs()
|
||||
- upgrade deps + interoperable uvarint delimited writer/reader. (#95) ([libp2p/go-libp2p-autonat#95](https://github.com/libp2p/go-libp2p-autonat/pull/95))
|
||||
- fix: a type switch nit ([libp2p/go-libp2p-autonat#83](https://github.com/libp2p/go-libp2p-autonat/pull/83))
|
||||
- github.com/libp2p/go-libp2p-blankhost (v0.1.6 -> v0.2.0):
|
||||
- call reset where appropriate (and update deps) ([libp2p/go-libp2p-blankhost#52](https://github.com/libp2p/go-libp2p-blankhost/pull/52))
|
||||
- github.com/libp2p/go-libp2p-circuit (v0.2.3 -> v0.3.1):
|
||||
- upgrade deps + interoperable uvarints. (#122) ([libp2p/go-libp2p-circuit#122](https://github.com/libp2p/go-libp2p-circuit/pull/122))
|
||||
- Fix/remove deprecated logging ([libp2p/go-libp2p-circuit#85](https://github.com/libp2p/go-libp2p-circuit/pull/85))
|
||||
- github.com/libp2p/go-libp2p-core (v0.5.7 -> v0.6.1):
|
||||
- experimental introspection support (#159) ([libp2p/go-libp2p-core#159](https://github.com/libp2p/go-libp2p-core/pull/159))
|
||||
- github.com/libp2p/go-libp2p-discovery (v0.4.0 -> v0.5.0):
|
||||
- Put period at end of sentence ([libp2p/go-libp2p-discovery#65](https://github.com/libp2p/go-libp2p-discovery/pull/65))
|
||||
- github.com/libp2p/go-libp2p-kad-dht (v0.8.2 -> v0.9.0):
|
||||
- chore: update deps ([libp2p/go-libp2p-kad-dht#689](https://github.com/libp2p/go-libp2p-kad-dht/pull/689))
|
||||
- allow overwriting builtin dual DHT options ([libp2p/go-libp2p-kad-dht#688](https://github.com/libp2p/go-libp2p-kad-dht/pull/688))
|
||||
- Hardening Improvements: RT diversity and decreased RT churn ([libp2p/go-libp2p-kad-dht#687](https://github.com/libp2p/go-libp2p-kad-dht/pull/687))
|
||||
- Fix key log encoding ([libp2p/go-libp2p-kad-dht#682](https://github.com/libp2p/go-libp2p-kad-dht/pull/682))
|
||||
- upgrade deps + uvarint delimited writer/reader. (#684) ([libp2p/go-libp2p-kad-dht#684](https://github.com/libp2p/go-libp2p-kad-dht/pull/684))
|
||||
- periodicBootstrapInterval should be ticker? (#678) ([libp2p/go-libp2p-kad-dht#678](https://github.com/libp2p/go-libp2p-kad-dht/pull/678))
|
||||
- removes duplicate comment ([libp2p/go-libp2p-kad-dht#674](https://github.com/libp2p/go-libp2p-kad-dht/pull/674))
|
||||
- Revert "Peer Diversity in the Routing Table (#658)" ([libp2p/go-libp2p-kad-dht#670](https://github.com/libp2p/go-libp2p-kad-dht/pull/670))
|
||||
- Fixed problem with refresh logging ([libp2p/go-libp2p-kad-dht#667](https://github.com/libp2p/go-libp2p-kad-dht/pull/667))
|
||||
- feat: protect all peers in low buckets, tag everyone else with 5 ([libp2p/go-libp2p-kad-dht#666](https://github.com/libp2p/go-libp2p-kad-dht/pull/666))
|
||||
- Peer Diversity in the Routing Table (#658) ([libp2p/go-libp2p-kad-dht#658](https://github.com/libp2p/go-libp2p-kad-dht/pull/658))
|
||||
- github.com/libp2p/go-libp2p-kbucket (v0.4.2 -> v0.4.7):
|
||||
- chore: switch from go-multiaddr-net to go-multiaddr/net
|
||||
- Use crypto/rand for generating random prefixes
|
||||
- feat: when using the diversity filter for ipv6 addresses if the ASN cannot be found for a particular address then fallback on using the /32 mask of the address as the group name instead of simply rejecting the peer from routing table
|
||||
- simplify filter (#92) ([libp2p/go-libp2p-kbucket#92](https://github.com/libp2p/go-libp2p-kbucket/pull/92))
|
||||
- fix: switch to forked cid ranger dep ([libp2p/go-libp2p-kbucket#91](https://github.com/libp2p/go-libp2p-kbucket/pull/91))
|
||||
- Reduce Routing Table churn (#90) ([libp2p/go-libp2p-kbucket#90](https://github.com/libp2p/go-libp2p-kbucket/pull/90))
|
||||
- Peer Diversity for Routing Table and Querying (#88) ([libp2p/go-libp2p-kbucket#88](https://github.com/libp2p/go-libp2p-kbucket/pull/88))
|
||||
- fix bug in peer eviction (#87) ([libp2p/go-libp2p-kbucket#87](https://github.com/libp2p/go-libp2p-kbucket/pull/87))
|
||||
- feat: add an AddedAt timestamp (#84) ([libp2p/go-libp2p-kbucket#84](https://github.com/libp2p/go-libp2p-kbucket/pull/84))
|
||||
- github.com/libp2p/go-libp2p-pubsub (v0.3.1 -> v0.3.5):
|
||||
- regenerate protobufs (#381) ([libp2p/go-libp2p-pubsub#381](https://github.com/libp2p/go-libp2p-pubsub/pull/381))
|
||||
- track validation time
|
||||
- fullfill promise as soon as a message begins validation
|
||||
- don't apply penalty in self origin rejections
|
||||
- add behaviour penalty threshold
|
||||
- Add String() method to Topic.
|
||||
- add regression test for issue 371
|
||||
- don't add direct peers to fanout
|
||||
- reference spec change in comment.
|
||||
- fix backoff slack time
|
||||
- use the heartbeat interval for slack time
|
||||
- add slack time to prune backoff clearance
|
||||
- fix: call the correct tracer function in FloodSubRouter.Leave (#373) ([libp2p/go-libp2p-pubsub#373](https://github.com/libp2p/go-libp2p-pubsub/pull/373))
|
||||
- downgrade trace buffer overflow log to debug
|
||||
- track topics in Reject/Duplicate/Deliver events
|
||||
- add topics to Reject/Duplicate/Deliver events
|
||||
- fix flaky test
|
||||
- refactor ip colocation factor computation that is common for score and inspection
|
||||
- better handling of intermediate topic score snapshots
|
||||
- disallow duplicate score inspectors
|
||||
- make peer score inspect function types aliases
|
||||
- extended peer score inspection
|
||||
- upgrade deps + interoperable uvarint delimited writer/reader.
|
||||
- Add warning about messageIDs
|
||||
- Signing policy + optional Signature, From and Seqno ([libp2p/go-libp2p-pubsub#359](https://github.com/libp2p/go-libp2p-pubsub/pull/359))
|
||||
- Update pubsub.go
|
||||
- Define a public error ErrSubscriptionCancelled.
|
||||
- only do PX on leave if PX was enabled in the node
|
||||
- drop warning about failure to open stream to a debug log
|
||||
- reinstate tagging (now protection) tests
|
||||
- disable tests for direct/mesh tags, we don't have an interface to query the connman yet
|
||||
- protect direct and mesh peers in the connection manager
|
||||
- feat: add direct connect ticks option
|
||||
- github.com/libp2p/go-libp2p-pubsub-router (v0.3.0 -> v0.3.2):
|
||||
- upgrade deps + interoperable uvarint delimited writer/reader. (#79) ([libp2p/go-libp2p-pubsub-router#79](https://github.com/libp2p/go-libp2p-pubsub-router/pull/79))
|
||||
- github.com/libp2p/go-libp2p-quic-transport (v0.6.0 -> v0.8.0):
|
||||
- update quic-go to v0.18.0 (#171) ([libp2p/go-libp2p-quic-transport#171](https://github.com/libp2p/go-libp2p-quic-transport/pull/171))
|
||||
- github.com/libp2p/go-libp2p-swarm (v0.2.6 -> v0.2.8):
|
||||
- slim down dependencies ([libp2p/go-libp2p-swarm#225](https://github.com/libp2p/go-libp2p-swarm/pull/225))
|
||||
- `ID()` method on connections and streams + record opening time (#224) ([libp2p/go-libp2p-swarm#224](https://github.com/libp2p/go-libp2p-swarm/pull/224))
|
||||
- github.com/libp2p/go-libp2p-testing (v0.1.1 -> v0.2.0):
|
||||
- Add net benchmark harness ([libp2p/go-libp2p-testing#21](https://github.com/libp2p/go-libp2p-testing/pull/21))
|
||||
- Update suite to check that streams respect mux.ErrReset. ([libp2p/go-libp2p-testing#16](https://github.com/libp2p/go-libp2p-testing/pull/16))
|
||||
- github.com/libp2p/go-maddr-filter (v0.0.5 -> v0.1.0):
|
||||
- deprecate this package; moved to multiformats/go-multiaddr. (#23) ([libp2p/go-maddr-filter#23](https://github.com/libp2p/go-maddr-filter/pull/23))
|
||||
- chore(dep): update ([libp2p/go-maddr-filter#18](https://github.com/libp2p/go-maddr-filter/pull/18))
|
||||
- github.com/libp2p/go-msgio (v0.0.4 -> v0.0.6):
|
||||
- interoperable uvarints. (#21) ([libp2p/go-msgio#21](https://github.com/libp2p/go-msgio/pull/21))
|
||||
- upgrade deps + interoperable uvarint delimited writer/reader. (#20) ([libp2p/go-msgio#20](https://github.com/libp2p/go-msgio/pull/20))
|
||||
- github.com/libp2p/go-netroute (v0.1.2 -> v0.1.3):
|
||||
- add Plan 9 support
|
||||
- github.com/libp2p/go-openssl (v0.0.5 -> v0.0.7):
|
||||
- make ed25519 less special ([libp2p/go-openssl#7](https://github.com/libp2p/go-openssl/pull/7))
|
||||
- Add required bindings to support openssl in libp2p-tls ([libp2p/go-openssl#6](https://github.com/libp2p/go-openssl/pull/6))
|
||||
- github.com/libp2p/go-reuseport (v0.0.1 -> v0.0.2):
|
||||
- Fix build on Plan 9 ([libp2p/go-reuseport#79](https://github.com/libp2p/go-reuseport/pull/79))
|
||||
- farewell gx; thanks for serving us well.
|
||||
- update readme badges
|
||||
- remove Jenkinsfile.
|
||||
- github.com/libp2p/go-reuseport-transport (v0.0.3 -> v0.0.4):
|
||||
- Update go-netroute and go-reuseport for Plan 9 support
|
||||
- Fix build on Plan 9
|
||||
- github.com/lucas-clemente/quic-go (v0.16.2 -> v0.18.0):
|
||||
- create a milestone version for v0.18.x
|
||||
- add Changelog entries for v0.17 ([lucas-clemente/quic-go#2726](https://github.com/lucas-clemente/quic-go/pull/2726))
|
||||
- regenerate the testdata certificate with SAN instead of CommonName ([lucas-clemente/quic-go#2723](https://github.com/lucas-clemente/quic-go/pull/2723))
|
||||
- make it possible to use multiple qtls versions at the same time, add support for Go 1.15 ([lucas-clemente/quic-go#2720](https://github.com/lucas-clemente/quic-go/pull/2720))
|
||||
- add fuzzing for transport parameters ([lucas-clemente/quic-go#2713](https://github.com/lucas-clemente/quic-go/pull/2713))
|
||||
- run golangci-lint on Github Actions ([lucas-clemente/quic-go#2700](https://github.com/lucas-clemente/quic-go/pull/2700))
|
||||
- disallow values above 2^60 for Config.MaxIncoming{Uni}Streams ([lucas-clemente/quic-go#2711](https://github.com/lucas-clemente/quic-go/pull/2711))
|
||||
- never send a value larger than 2^60 in MAX_STREAMS frames ([lucas-clemente/quic-go#2710](https://github.com/lucas-clemente/quic-go/pull/2710))
|
||||
- run the check for go generated files on Github Actions instead of Travis ([lucas-clemente/quic-go#2703](https://github.com/lucas-clemente/quic-go/pull/2703))
|
||||
- update QUIC draft version information in README ([lucas-clemente/quic-go#2715](https://github.com/lucas-clemente/quic-go/pull/2715))
|
||||
- remove Fuzzit badge from README ([lucas-clemente/quic-go#2714](https://github.com/lucas-clemente/quic-go/pull/2714))
|
||||
- use the correct return values in Fuzz() functions ([lucas-clemente/quic-go#2705](https://github.com/lucas-clemente/quic-go/pull/2705))
|
||||
- simplify the connection, rename it to sendConn ([lucas-clemente/quic-go#2707](https://github.com/lucas-clemente/quic-go/pull/2707))
|
||||
- update qpack to v0.2.0 ([lucas-clemente/quic-go#2704](https://github.com/lucas-clemente/quic-go/pull/2704))
|
||||
- remove redundant error check in the stream ([lucas-clemente/quic-go#2718](https://github.com/lucas-clemente/quic-go/pull/2718))
|
||||
- put back the packet buffer when parsing the connection ID fails ([lucas-clemente/quic-go#2708](https://github.com/lucas-clemente/quic-go/pull/2708))
|
||||
- update fuzzing code for oss-fuzz ([lucas-clemente/quic-go#2702](https://github.com/lucas-clemente/quic-go/pull/2702))
|
||||
- fix travis script ([lucas-clemente/quic-go#2701](https://github.com/lucas-clemente/quic-go/pull/2701))
|
||||
- remove Fuzzit from Travis config ([lucas-clemente/quic-go#2699](https://github.com/lucas-clemente/quic-go/pull/2699))
|
||||
- add a script to check if go generated files are correct ([lucas-clemente/quic-go#2692](https://github.com/lucas-clemente/quic-go/pull/2692))
|
||||
- only arm the application data PTO timer after the handshake is confirmed ([lucas-clemente/quic-go#2689](https://github.com/lucas-clemente/quic-go/pull/2689))
|
||||
- fix tracing of congestion state updates ([lucas-clemente/quic-go#2691](https://github.com/lucas-clemente/quic-go/pull/2691))
|
||||
- fix reading of flag values in integration tests ([lucas-clemente/quic-go#2690](https://github.com/lucas-clemente/quic-go/pull/2690))
|
||||
- remove ACK decimation ([lucas-clemente/quic-go#2599](https://github.com/lucas-clemente/quic-go/pull/2599))
|
||||
- add a metric for PTOs ([lucas-clemente/quic-go#2686](https://github.com/lucas-clemente/quic-go/pull/2686))
|
||||
- remove the H3_EARLY_RESPONSE error ([lucas-clemente/quic-go#2687](https://github.com/lucas-clemente/quic-go/pull/2687))
|
||||
- implement tracing for congestion state changes ([lucas-clemente/quic-go#2684](https://github.com/lucas-clemente/quic-go/pull/2684))
|
||||
- remove the N connection simulation from the Reno code ([lucas-clemente/quic-go#2682](https://github.com/lucas-clemente/quic-go/pull/2682))
|
||||
- remove the SSLR (slow start large reduction) experiment ([lucas-clemente/quic-go#2680](https://github.com/lucas-clemente/quic-go/pull/2680))
|
||||
- remove unused connectionStats counters from the Reno implementation ([lucas-clemente/quic-go#2683](https://github.com/lucas-clemente/quic-go/pull/2683))
|
||||
- add an integration test that randomly sets tracers ([lucas-clemente/quic-go#2679](https://github.com/lucas-clemente/quic-go/pull/2679))
|
||||
- privatize some methods in the congestion controller package ([lucas-clemente/quic-go#2681](https://github.com/lucas-clemente/quic-go/pull/2681))
|
||||
- fix out-of-bounds read when creating a multiplexed tracer ([lucas-clemente/quic-go#2678](https://github.com/lucas-clemente/quic-go/pull/2678))
|
||||
- run integration tests with qlog and metrics on CircleCI ([lucas-clemente/quic-go#2677](https://github.com/lucas-clemente/quic-go/pull/2677))
|
||||
- add a metric for closed connections ([lucas-clemente/quic-go#2676](https://github.com/lucas-clemente/quic-go/pull/2676))
|
||||
- trace packets that are sent outside of a connection ([lucas-clemente/quic-go#2675](https://github.com/lucas-clemente/quic-go/pull/2675))
|
||||
- trace dropped packets that are dropped before they are passed to any session ([lucas-clemente/quic-go#2670](https://github.com/lucas-clemente/quic-go/pull/2670))
|
||||
- add a metric for sent packets ([lucas-clemente/quic-go#2673](https://github.com/lucas-clemente/quic-go/pull/2673))
|
||||
- add a metric for lost packets ([lucas-clemente/quic-go#2672](https://github.com/lucas-clemente/quic-go/pull/2672))
|
||||
- simplify the Tracer interface by combining the TracerFor... methods ([lucas-clemente/quic-go#2671](https://github.com/lucas-clemente/quic-go/pull/2671))
|
||||
- add a metrics package using OpenCensus, trace connections ([lucas-clemente/quic-go#2646](https://github.com/lucas-clemente/quic-go/pull/2646))
|
||||
- add a multiplexer for the tracer ([lucas-clemente/quic-go#2665](https://github.com/lucas-clemente/quic-go/pull/2665))
|
||||
- introduce a type for stateless reset tokens ([lucas-clemente/quic-go#2668](https://github.com/lucas-clemente/quic-go/pull/2668))
|
||||
- log all reasons why a connection is closed ([lucas-clemente/quic-go#2669](https://github.com/lucas-clemente/quic-go/pull/2669))
|
||||
- add integration tests using faulty packet conns ([lucas-clemente/quic-go#2663](https://github.com/lucas-clemente/quic-go/pull/2663))
|
||||
- don't block sendQueue.Send() if the runloop already exited. ([lucas-clemente/quic-go#2656](https://github.com/lucas-clemente/quic-go/pull/2656))
|
||||
- move the SupportedVersions slice out of the wire.Header ([lucas-clemente/quic-go#2664](https://github.com/lucas-clemente/quic-go/pull/2664))
|
||||
- add a flag to disable conn ID generation and the check for retired conn IDs ([lucas-clemente/quic-go#2660](https://github.com/lucas-clemente/quic-go/pull/2660))
|
||||
- put the session in the packet handler map directly (for client sessions) ([lucas-clemente/quic-go#2667](https://github.com/lucas-clemente/quic-go/pull/2667))
|
||||
- don't send write error in CONNECTION_CLOSE frames ([lucas-clemente/quic-go#2666](https://github.com/lucas-clemente/quic-go/pull/2666))
|
||||
- reset the PTO count before setting the timer when dropping a PN space ([lucas-clemente/quic-go#2657](https://github.com/lucas-clemente/quic-go/pull/2657))
|
||||
- enforce that a connection ID is not retired in a packet that uses that connection ID ([lucas-clemente/quic-go#2651](https://github.com/lucas-clemente/quic-go/pull/2651))
|
||||
- don't retire the conn ID that's in use when receiving a retransmission ([lucas-clemente/quic-go#2652](https://github.com/lucas-clemente/quic-go/pull/2652))
|
||||
- fix flaky cancelation integration test ([lucas-clemente/quic-go#2649](https://github.com/lucas-clemente/quic-go/pull/2649))
|
||||
- fix crash when the qlog callbacks returns a nil io.WriteCloser ([lucas-clemente/quic-go#2648](https://github.com/lucas-clemente/quic-go/pull/2648))
|
||||
- fix flaky server test on Travis ([lucas-clemente/quic-go#2645](https://github.com/lucas-clemente/quic-go/pull/2645))
|
||||
- fix a typo in the logging package test suite
|
||||
- introduce type aliases in the logging package ([lucas-clemente/quic-go#2643](https://github.com/lucas-clemente/quic-go/pull/2643))
|
||||
- rename frame fields to the names used in the draft ([lucas-clemente/quic-go#2644](https://github.com/lucas-clemente/quic-go/pull/2644))
|
||||
- split the qlog package into a logging and a qlog package, use a tracer interface in the quic.Config ([lucas-clemente/quic-go#2638](https://github.com/lucas-clemente/quic-go/pull/2638))
|
||||
- fix HTTP request writing if the Request.Body reads data and returns EOF ([lucas-clemente/quic-go#2642](https://github.com/lucas-clemente/quic-go/pull/2642))
|
||||
- handle Version Negotiation packets in the session ([lucas-clemente/quic-go#2640](https://github.com/lucas-clemente/quic-go/pull/2640))
|
||||
- increase the packet size of the client's Initial packet ([lucas-clemente/quic-go#2634](https://github.com/lucas-clemente/quic-go/pull/2634))
|
||||
- introduce an assertion in the server ([lucas-clemente/quic-go#2637](https://github.com/lucas-clemente/quic-go/pull/2637))
|
||||
- use the new qtls interface for (re)storing app data with a session state ([lucas-clemente/quic-go#2631](https://github.com/lucas-clemente/quic-go/pull/2631))
|
||||
- remove buffering of HTTP requests ([lucas-clemente/quic-go#2626](https://github.com/lucas-clemente/quic-go/pull/2626))
|
||||
- remove superfluous parameters logged when not doing 0-RTT ([lucas-clemente/quic-go#2632](https://github.com/lucas-clemente/quic-go/pull/2632))
|
||||
- return an infinite bandwidth if the RTT is zero ([lucas-clemente/quic-go#2636](https://github.com/lucas-clemente/quic-go/pull/2636))
|
||||
- drop support for Go 1.13 ([lucas-clemente/quic-go#2628](https://github.com/lucas-clemente/quic-go/pull/2628))
|
||||
- remove superfluos handleResetStreamFrame method on the stream ([lucas-clemente/quic-go#2623](https://github.com/lucas-clemente/quic-go/pull/2623))
|
||||
- implement a token-bucket pacing algorithm ([lucas-clemente/quic-go#2615](https://github.com/lucas-clemente/quic-go/pull/2615))
|
||||
- gracefully handle concurrent stream writes and cancellations ([lucas-clemente/quic-go#2624](https://github.com/lucas-clemente/quic-go/pull/2624))
|
||||
- log sent packets right before sending them out ([lucas-clemente/quic-go#2613](https://github.com/lucas-clemente/quic-go/pull/2613))
|
||||
- remove unused packet counter in the receivedPacketTracker ([lucas-clemente/quic-go#2611](https://github.com/lucas-clemente/quic-go/pull/2611))
|
||||
- rewrite the proxy to avoid packet reordering ([lucas-clemente/quic-go#2617](https://github.com/lucas-clemente/quic-go/pull/2617))
|
||||
- fix flaky INVALID_TOKEN integration test ([lucas-clemente/quic-go#2610](https://github.com/lucas-clemente/quic-go/pull/2610))
|
||||
- make DialEarly return EarlySession ([lucas-clemente/quic-go#2621](https://github.com/lucas-clemente/quic-go/pull/2621))
|
||||
- add debug logging to the packet handler map ([lucas-clemente/quic-go#2608](https://github.com/lucas-clemente/quic-go/pull/2608))
|
||||
- increase the minimum pacing delay to 1ms ([lucas-clemente/quic-go#2605](https://github.com/lucas-clemente/quic-go/pull/2605))
|
||||
- github.com/marten-seemann/qpack (v0.1.0 -> v0.2.0):
|
||||
- don't reuse the encoder in the integration tests ([marten-seemann/qpack#18](https://github.com/marten-seemann/qpack/pull/18))
|
||||
- use Huffman encoding for field names and values ([marten-seemann/qpack#16](https://github.com/marten-seemann/qpack/pull/16))
|
||||
- add more tests for encoding using the static table ([marten-seemann/qpack#15](https://github.com/marten-seemann/qpack/pull/15))
|
||||
- Encoder uses the static table. ([marten-seemann/qpack#10](https://github.com/marten-seemann/qpack/pull/10))
|
||||
- add gofmt to golangci-lint
|
||||
- update qifs to the current version ([marten-seemann/qpack#14](https://github.com/marten-seemann/qpack/pull/14))
|
||||
- use golangci-lint for linting ([marten-seemann/qpack#12](https://github.com/marten-seemann/qpack/pull/12))
|
||||
- add fuzzing ([marten-seemann/qpack#9](https://github.com/marten-seemann/qpack/pull/9))
|
||||
- update qifs
|
||||
- use https protocol for submodule clone ([marten-seemann/qpack#7](https://github.com/marten-seemann/qpack/pull/7))
|
||||
- github.com/marten-seemann/qtls (v0.9.1 -> v0.10.0):
|
||||
- add callbacks to store and restore app data along a session state
|
||||
- remove support for Go 1.13
|
||||
- github.com/marten-seemann/qtls-go1-15 (null -> v0.1.0):
|
||||
- use a prefix for client session cache keys
|
||||
- add callbacks to store and restore app data along a session state
|
||||
- don't use TLS 1.3 compatibility mode when using alternative record layer
|
||||
- delete the session ticket after attempting 0-RTT
|
||||
- reject 0-RTT when a different ALPN is chosen
|
||||
- encode the ALPN into the session ticket
|
||||
- add a field to the ConnectionState to tell if 0-RTT was used
|
||||
- add a callback to tell the client about rejection of 0-RTT
|
||||
- don't offer 0-RTT after a HelloRetryRequest
|
||||
- add Accept0RTT to Config callback to decide if 0-RTT should be accepted
|
||||
- add the option to encode application data into the session ticket
|
||||
- export the 0-RTT write key
|
||||
- abuse the nonce field of ClientSessionState to save max_early_data_size
|
||||
- export the 0-RTT read key
|
||||
- close connection if client attempts 0-RTT, but ticket didn't allow it
|
||||
- encode the max early data size into the session ticket
|
||||
- implement parsing of the early_data extension in the EncryptedExtensions
|
||||
- add a tls.Config.MaxEarlyData option to enable 0-RTT
|
||||
- accept TLS 1.3 cipher suites in Config.CipherSuites
|
||||
- introduce a function on the connection to generate a session ticket
|
||||
- add a config option to enforce selection of an application protocol
|
||||
- export Conn.HandlePostHandshakeMessage
|
||||
- export Alert
|
||||
- reject Configs that set MaxVersion < 1.3 when using a record layer
|
||||
- enforce TLS 1.3 when using an alternative record layer
|
||||
- github.com/multiformats/go-multiaddr (v0.2.2 -> v0.3.1):
|
||||
- dep: add "codependencies" for handling version conflicts ([multiformats/go-multiaddr#132](https://github.com/multiformats/go-multiaddr/pull/132))
|
||||
- Support /p2p addresses encoded as CIDs ([multiformats/go-multiaddr#130](https://github.com/multiformats/go-multiaddr/pull/130))
|
||||
- Merge go-multiaddr-net
|
||||
- github.com/multiformats/go-multiaddr-net (v0.1.5 -> v0.2.0):
|
||||
- Deprecate ([multiformats/go-multiaddr-net#72](https://github.com/multiformats/go-multiaddr-net/pull/72))
|
||||
- github.com/multiformats/go-multihash (v0.0.13 -> v0.0.14):
|
||||
- fix: only register one blake2s length ([multiformats/go-multihash#129](https://github.com/multiformats/go-multihash/pull/129))
|
||||
- feat: add two filecoin hashes, without Sum() implementations ([multiformats/go-multihash#128](https://github.com/multiformats/go-multihash/pull/128))
|
||||
- feat: reduce blake2b allocations by special-casing the 256/512 variants ([multiformats/go-multihash#126](https://github.com/multiformats/go-multihash/pull/126))
|
||||
- github.com/multiformats/go-multistream (v0.1.1 -> v0.1.2):
|
||||
- upgrade deps + interoperable varints. (#51) ([multiformats/go-multistream#51](https://github.com/multiformats/go-multistream/pull/51))
|
||||
- github.com/multiformats/go-varint (v0.0.5 -> v0.0.6):
|
||||
- fix minor interoperability issues. (#6) ([multiformats/go-varint#6](https://github.com/multiformats/go-varint/pull/6))
|
||||
- github.com/warpfork/go-wish (v0.0.0-20190328234359-8b3e70f8e830 -> v0.0.0-20200122115046-b9ea61034e4a):
|
||||
- Add ShouldBeSameTypeAs checker.
|
||||
- Integration test update for go versions.
|
||||
- github.com/whyrusleeping/cbor-gen (v0.0.0-20200123233031-1cdf64d27158 -> v0.0.0-20200402171437-3d27c146c105):
|
||||
- Handle Nil values for cbg.Deferred ([whyrusleeping/cbor-gen#14](https://github.com/whyrusleeping/cbor-gen/pull/14))
|
||||
- add name of struct field to error messages
|
||||
- Support uint64 pointers ([whyrusleeping/cbor-gen#13](https://github.com/whyrusleeping/cbor-gen/pull/13))
|
||||
- int64 support in map encoders ([whyrusleeping/cbor-gen#12](https://github.com/whyrusleeping/cbor-gen/pull/12))
|
||||
- Fix uint64 typed array gen ([whyrusleeping/cbor-gen#10](https://github.com/whyrusleeping/cbor-gen/pull/10))
|
||||
- Fix cbg self referencing import path ([whyrusleeping/cbor-gen#8](https://github.com/whyrusleeping/cbor-gen/pull/8))
|
||||
|
||||
### Contributors
|
||||
|
||||
| Contributor | Commits | Lines ± | Files Changed |
|
||||
|-------------|---------|---------|---------------|
|
||||
| Marten Seemann | 156 | +16428/-42621 | 979 |
|
||||
| hannahhoward | 42 | +15132/-9819 | 467 |
|
||||
| Eric Myhre | 114 | +13709/-6898 | 586 |
|
||||
| Steven Allen | 55 | +1211/-2714 | 95 |
|
||||
| Adin Schmahmann | 54 | +1660/-783 | 117 |
|
||||
| Petar Maymounkov | 23 | +1677/-671 | 75 |
|
||||
| Aarsh Shah | 10 | +1926/-341 | 39 |
|
||||
| Raúl Kripalani | 17 | +1134/-537 | 53 |
|
||||
| Will | 1 | +841/-0 | 9 |
|
||||
| rendaw | 3 | +425/-195 | 12 |
|
||||
| Will Scott | 8 | +302/-229 | 15 |
|
||||
| vyzo | 22 | +345/-166 | 23 |
|
||||
| Fazlul Shahriar | 7 | +452/-44 | 19 |
|
||||
| Peter Rabbitson | 1 | +353/-118 | 5 |
|
||||
| Hector Sanjuan | 10 | +451/-3 | 14 |
|
||||
| Marcin Rataj | 9 | +298/-106 | 16 |
|
||||
| Łukasz Magiera | 4 | +329/-51 | 12 |
|
||||
| RubenKelevra | 9 | +331/-7 | 12 |
|
||||
| Michael Muré | 2 | +259/-69 | 6 |
|
||||
| jstordeur | 1 | +252/-2 | 5 |
|
||||
| Diederik Loerakker | 1 | +168/-35 | 7 |
|
||||
| Tiger | 3 | +138/-52 | 8 |
|
||||
| Kevin Neaton | 3 | +103/-21 | 9 |
|
||||
| Rod Vagg | 1 | +50/-40 | 4 |
|
||||
| Oli Evans | 4 | +60/-9 | 6 |
|
||||
| achingbrain | 4 | +30/-30 | 5 |
|
||||
| Cyril Fougeray | 2 | +34/-24 | 2 |
|
||||
| Luke Tucker | 1 | +31/-1 | 2 |
|
||||
| sandman | 2 | +23/-7 | 3 |
|
||||
| Alan Shaw | 1 | +18/-9 | 2 |
|
||||
| Jacob Heun | 4 | +13/-3 | 4 |
|
||||
| Jessica Schilling | 3 | +7/-7 | 3 |
|
||||
| Rafael Ramalho | 4 | +9/-4 | 4 |
|
||||
| Jeromy Johnson | 2 | +6/-6 | 4 |
|
||||
| Nick Cabatoff | 1 | +7/-2 | 1 |
|
||||
| Stephen Solka | 1 | +1/-7 | 1 |
|
||||
| Preston Van Loon | 2 | +6/-2 | 2 |
|
||||
| Jakub Sztandera | 2 | +5/-2 | 2 |
|
||||
| llx | 1 | +3/-3 | 1 |
|
||||
| Adrian Lanzafame | 1 | +3/-3 | 1 |
|
||||
| Yusef Napora | 1 | +3/-2 | 1 |
|
||||
| Louis Thibault | 1 | +5/-0 | 1 |
|
||||
| Martín Triay | 1 | +4/-0 | 1 |
|
||||
| Hlib | 1 | +2/-2 | 1 |
|
||||
| Shotaro Yamada | 1 | +2/-1 | 1 |
|
||||
| phuslu | 1 | +1/-1 | 1 |
|
||||
| Zero King | 1 | +1/-1 | 1 |
|
||||
| Rüdiger Klaehn | 1 | +2/-0 | 1 |
|
||||
| Nex | 1 | +1/-1 | 1 |
|
||||
| Mark Gaiser | 1 | +1/-1 | 1 |
|
||||
| Luflosi | 1 | +1/-1 | 1 |
|
||||
| David Florness | 1 | +1/-1 | 1 |
|
||||
| Dean Eigenmann | 1 | +0/-1 | 1 |
|
||||
|
||||
## v0.6.0 2020-06-19
|
||||
|
||||
This is a relatively small release in terms of code changes, but it contains some significant changes to the IPFS protocol.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
FROM golang:1.14.2-buster
|
||||
# Note: when updating the go minor version here, also update the go-channel in snap/snapcraft.yml
|
||||
FROM golang:1.14.4-buster
|
||||
LABEL maintainer="Steven Allen <steven@stebalien.com>"
|
||||
|
||||
# Install deps
|
||||
@ -33,14 +34,14 @@ ENV TINI_VERSION v0.19.0
|
||||
RUN set -eux; \
|
||||
dpkgArch="$(dpkg --print-architecture)"; \
|
||||
case "${dpkgArch##*-}" in \
|
||||
"amd64" | "armhf" | "arm64") tiniArch="tini-$dpkgArch" ;;\
|
||||
"amd64" | "armhf" | "arm64") tiniArch="tini-static-$dpkgArch" ;;\
|
||||
*) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \
|
||||
esac; \
|
||||
cd /tmp \
|
||||
&& git clone https://github.com/ncopa/su-exec.git \
|
||||
&& cd su-exec \
|
||||
&& git checkout -q $SUEXEC_VERSION \
|
||||
&& make \
|
||||
&& make su-exec-static \
|
||||
&& cd /tmp \
|
||||
&& wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/$tiniArch \
|
||||
&& chmod +x tini
|
||||
@ -53,7 +54,7 @@ LABEL maintainer="Steven Allen <steven@stebalien.com>"
|
||||
ENV SRC_DIR /go-ipfs
|
||||
COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs
|
||||
COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs
|
||||
COPY --from=0 /tmp/su-exec/su-exec /sbin/su-exec
|
||||
COPY --from=0 /tmp/su-exec/su-exec-static /sbin/su-exec
|
||||
COPY --from=0 /tmp/tini /sbin/tini
|
||||
COPY --from=0 /bin/fusermount /usr/local/bin/fusermount
|
||||
COPY --from=0 /etc/ssl/certs /etc/ssl/certs
|
||||
|
||||
@ -160,7 +160,7 @@ PS> scoop install go-ipfs
|
||||
|
||||
### Build from Source
|
||||
|
||||
go-ipfs's build system requires Go 1.14.2 and some standard POSIX build tools:
|
||||
go-ipfs's build system requires Go 1.14.4 and some standard POSIX build tools:
|
||||
|
||||
* GNU make
|
||||
* Git
|
||||
@ -170,7 +170,7 @@ To build without GCC, build with `CGO_ENABLED=0` (e.g., `make build CGO_ENABLED=
|
||||
|
||||
#### Install Go
|
||||
|
||||
The build process for ipfs requires Go 1.14.2 or higher. If you don't have it: [Download Go 1.14+](https://golang.org/dl/).
|
||||
The build process for ipfs requires Go 1.14.4 or higher. If you don't have it: [Download Go 1.14+](https://golang.org/dl/).
|
||||
|
||||
You'll need to add Go's bin directories to your `$PATH` environment variable e.g., by adding these lines to your `/etc/profile` (for a system-wide installation) or `$HOME/.profile`:
|
||||
|
||||
@ -224,7 +224,7 @@ dependencies as well.
|
||||
(See https://github.com/ipfs/go-ipfs/issues/177)
|
||||
- For more details on setting up FUSE (so that you can mount the filesystem), see the docs folder.
|
||||
- Shell command completion is available in `misc/completion/ipfs-completion.bash`. Read [docs/command-completion.md](docs/command-completion.md) to learn how to install it.
|
||||
- See the [init examples](https://github.com/ipfs/website/tree/master/static/docs/examples/init) for how to connect IPFS to systemd or whatever init system your distro uses.
|
||||
- See the [misc folder](https://github.com/ipfs/go-ipfs/tree/master/misc) for how to connect IPFS to systemd or whatever init system your distro uses.
|
||||
|
||||
### Updating go-ipfs
|
||||
|
||||
|
||||
@ -45,6 +45,7 @@ commit.
|
||||
```bash
|
||||
> go generate .
|
||||
> git add bindata.go
|
||||
> git add bindata_version_hash.go
|
||||
> go mod tidy
|
||||
> git commit --amend --no-edit
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//go:generate git submodule update --init ./dir-index-html
|
||||
//go:generate go run github.com/go-bindata/go-bindata/go-bindata -pkg=assets init-doc dir-index-html/dir-index.html dir-index-html/knownIcons.txt
|
||||
//go:generate go run github.com/go-bindata/go-bindata/v3/go-bindata -mode=0644 -modtime=1403768328 -pkg=assets init-doc dir-index-html/dir-index.html dir-index-html/knownIcons.txt
|
||||
//go:generate gofmt -w bindata.go
|
||||
//go:generate sh -c "sed -i \"s/.*BindataVersionHash.*/BindataVersionHash=\\\"$(git hash-object bindata.go)\\\"/\" bindata_version_hash.go"
|
||||
//go:generate gofmt -w bindata_version_hash.go
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -2,5 +2,5 @@
|
||||
package assets
|
||||
|
||||
const (
|
||||
BindataVersionHash = "c1aa0601ac3eac2c50b296cf618a6747eeba8579"
|
||||
BindataVersionHash = "514e5ae28d8adb84955801b56ef47aca44bf9cc8"
|
||||
)
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit e39165569c4b2f9d382f925b77c1126c5170946f
|
||||
Subproject commit 9603194e10c40ca8585497828fc4a7b7c72dea90
|
||||
@ -33,15 +33,22 @@ AUTHORS=(
|
||||
|
||||
NL=$'\n'
|
||||
|
||||
ROOT_DIR="$(git rev-parse --show-toplevel)"
|
||||
|
||||
msg() {
|
||||
echo "$*" >&2
|
||||
}
|
||||
|
||||
statlog() {
|
||||
rpath="$GOPATH/src/$1"
|
||||
start="${2:-}"
|
||||
end="${3:-HEAD}"
|
||||
git -C "$rpath" log --shortstat --no-merges --pretty="tformat:%H%n%aN%n%aE" "$start..$end" | while
|
||||
local rpath="$GOPATH/src/$1"
|
||||
local start="${2:-}"
|
||||
local end="${3:-HEAD}"
|
||||
local mailmap_file="$rpath/.mailmap"
|
||||
if ! [[ -e "$mailmap_file" ]]; then
|
||||
mailmap_file="$ROOT_DIR/.mailmap"
|
||||
fi
|
||||
|
||||
git -C "$rpath" -c mailmap.file="$mailmap_file" log --use-mailmap --shortstat --no-merges --pretty="tformat:%H%n%aN%n%aE" "$start..$end" | while
|
||||
read hash
|
||||
read name
|
||||
read email
|
||||
|
||||
@ -31,9 +31,10 @@ import (
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
mprome "github.com/ipfs/go-metrics-prometheus"
|
||||
options "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
goprocess "github.com/jbenet/goprocess"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
prometheus "github.com/prometheus/client_golang/prometheus"
|
||||
promauto "github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
@ -181,6 +182,8 @@ Headers.
|
||||
// cmds.StringOption(swarmAddrKwd, "Address for the swarm socket (overrides config)"),
|
||||
},
|
||||
Subcommands: map[string]*cmds.Command{},
|
||||
NoRemote: true,
|
||||
Extra: commands.CreateCmdExtras(commands.SetDoesNotUseConfigAsInput(true)),
|
||||
Run: daemonFunc,
|
||||
}
|
||||
|
||||
@ -247,7 +250,14 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
|
||||
}
|
||||
}
|
||||
|
||||
if err = doInit(os.Stdout, cctx.ConfigRoot, false, nBitsForKeypairDefault, profiles, conf); err != nil {
|
||||
identity, err := config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
|
||||
options.Key.Type(algorithmDefault),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = doInit(os.Stdout, cctx.ConfigRoot, false, &identity, profiles, conf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,19 +13,22 @@ import (
|
||||
assets "github.com/ipfs/go-ipfs/assets"
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
"github.com/ipfs/go-ipfs/core/commands"
|
||||
namesys "github.com/ipfs/go-ipfs/namesys"
|
||||
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
config "github.com/ipfs/go-ipfs-config"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
options "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
)
|
||||
|
||||
const (
|
||||
nBitsForKeypairDefault = 2048
|
||||
bitsOptionName = "bits"
|
||||
emptyRepoOptionName = "empty-repo"
|
||||
profileOptionName = "profile"
|
||||
algorithmDefault = options.Ed25519Key
|
||||
algorithmOptionName = "algorithm"
|
||||
bitsOptionName = "bits"
|
||||
emptyRepoOptionName = "empty-repo"
|
||||
profileOptionName = "profile"
|
||||
)
|
||||
|
||||
var errRepoExists = errors.New(`ipfs configuration file already exists!
|
||||
@ -54,7 +57,8 @@ environment variable:
|
||||
cmds.FileArg("default-config", false, false, "Initialize with the given configuration.").EnableStdin(),
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key.").WithDefault(nBitsForKeypairDefault),
|
||||
cmds.StringOption(algorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(algorithmDefault),
|
||||
cmds.IntOption(bitsOptionName, "b", "Number of bits to use in the generated RSA private key."),
|
||||
cmds.BoolOption(emptyRepoOptionName, "e", "Don't add and pin help files to the local storage."),
|
||||
cmds.StringOption(profileOptionName, "p", "Apply profile settings to config. Multiple profiles can be separated by ','"),
|
||||
|
||||
@ -63,6 +67,8 @@ environment variable:
|
||||
// name of the file?
|
||||
// TODO cmds.StringOption("event-logs", "l", "Location for machine-readable event logs."),
|
||||
},
|
||||
NoRemote: true,
|
||||
Extra: commands.CreateCmdExtras(commands.SetDoesNotUseRepo(true), commands.SetDoesNotUseConfigAsInput(true)),
|
||||
PreRun: func(req *cmds.Request, env cmds.Environment) error {
|
||||
cctx := env.(*oldcmds.Context)
|
||||
daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot)
|
||||
@ -82,7 +88,8 @@ environment variable:
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
cctx := env.(*oldcmds.Context)
|
||||
empty, _ := req.Options[emptyRepoOptionName].(bool)
|
||||
nBitsForKeypair, _ := req.Options[bitsOptionName].(int)
|
||||
algorithm, _ := req.Options[algorithmOptionName].(string)
|
||||
nBitsForKeypair, nBitsGiven := req.Options[bitsOptionName].(int)
|
||||
|
||||
var conf *config.Config
|
||||
|
||||
@ -106,8 +113,24 @@ environment variable:
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
var identity config.Identity
|
||||
if nBitsGiven {
|
||||
identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
|
||||
options.Key.Size(nBitsForKeypair),
|
||||
options.Key.Type(algorithm),
|
||||
})
|
||||
} else {
|
||||
identity, err = config.CreateIdentity(os.Stdout, []options.KeyGenerateOption{
|
||||
options.Key.Type(algorithm),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
profiles, _ := req.Options[profileOptionName].(string)
|
||||
return doInit(os.Stdout, cctx.ConfigRoot, empty, nBitsForKeypair, profiles, conf)
|
||||
return doInit(os.Stdout, cctx.ConfigRoot, empty, &identity, profiles, conf)
|
||||
},
|
||||
}
|
||||
|
||||
@ -129,7 +152,7 @@ func applyProfiles(conf *config.Config, profiles string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, confProfiles string, conf *config.Config) error {
|
||||
func doInit(out io.Writer, repoRoot string, empty bool, identity *config.Identity, confProfiles string, conf *config.Config) error {
|
||||
if _, err := fmt.Fprintf(out, "initializing IPFS node at %s\n", repoRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -142,9 +165,13 @@ func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, con
|
||||
return errRepoExists
|
||||
}
|
||||
|
||||
if identity == nil {
|
||||
return fmt.Errorf("No Identity provided for initialization")
|
||||
}
|
||||
|
||||
if conf == nil {
|
||||
var err error
|
||||
conf, err = config.Init(out, nBitsForKeypair)
|
||||
conf, err = config.InitWithIdentity(*identity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
commands "github.com/ipfs/go-ipfs/core/commands"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
@ -38,59 +36,3 @@ func init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NB: when necessary, properties are described using negatives in order to
|
||||
// provide desirable defaults
|
||||
type cmdDetails struct {
|
||||
cannotRunOnClient bool
|
||||
cannotRunOnDaemon bool
|
||||
doesNotUseRepo bool
|
||||
|
||||
// doesNotUseConfigAsInput describes commands that do not use the config as
|
||||
// input. These commands either initialize the config or perform operations
|
||||
// that don't require access to the config.
|
||||
//
|
||||
// pre-command hooks that require configs must not be run before these
|
||||
// commands.
|
||||
doesNotUseConfigAsInput bool
|
||||
|
||||
// preemptsAutoUpdate describes commands that must be executed without the
|
||||
// auto-update pre-command hook
|
||||
preemptsAutoUpdate bool
|
||||
}
|
||||
|
||||
func (d *cmdDetails) String() string {
|
||||
return fmt.Sprintf("on client? %t, on daemon? %t, uses repo? %t",
|
||||
d.canRunOnClient(), d.canRunOnDaemon(), d.usesRepo())
|
||||
}
|
||||
|
||||
func (d *cmdDetails) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"canRunOnClient": d.canRunOnClient(),
|
||||
"canRunOnDaemon": d.canRunOnDaemon(),
|
||||
"preemptsAutoUpdate": d.preemptsAutoUpdate,
|
||||
"usesConfigAsInput": d.usesConfigAsInput(),
|
||||
"usesRepo": d.usesRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *cmdDetails) usesConfigAsInput() bool { return !d.doesNotUseConfigAsInput }
|
||||
func (d *cmdDetails) canRunOnClient() bool { return !d.cannotRunOnClient }
|
||||
func (d *cmdDetails) canRunOnDaemon() bool { return !d.cannotRunOnDaemon }
|
||||
func (d *cmdDetails) usesRepo() bool { return !d.doesNotUseRepo }
|
||||
|
||||
// "What is this madness!?" you ask. Our commands have the unfortunate problem of
|
||||
// not being able to run on all the same contexts. This map describes these
|
||||
// properties so that other code can make decisions about whether to invoke a
|
||||
// command or return an error to the user.
|
||||
var cmdDetailsMap = map[string]cmdDetails{
|
||||
"init": {doesNotUseConfigAsInput: true, cannotRunOnDaemon: true, doesNotUseRepo: true},
|
||||
"daemon": {doesNotUseConfigAsInput: true, cannotRunOnDaemon: true},
|
||||
"commands": {doesNotUseRepo: true},
|
||||
"version": {doesNotUseConfigAsInput: true, doesNotUseRepo: true}, // must be permitted to run before init
|
||||
"log": {cannotRunOnClient: true},
|
||||
"diag/cmds": {cannotRunOnClient: true},
|
||||
"repo/fsck": {cannotRunOnDaemon: true},
|
||||
"config/edit": {cannotRunOnDaemon: true, doesNotUseRepo: true},
|
||||
"cid": {doesNotUseRepo: true},
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
util "github.com/ipfs/go-ipfs/cmd/ipfs/util"
|
||||
@ -31,7 +30,7 @@ import (
|
||||
loggables "github.com/libp2p/go-libp2p-loggables"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
// log is the command logger
|
||||
@ -202,16 +201,17 @@ func apiAddrOption(req *cmds.Request) (ma.Multiaddr, error) {
|
||||
func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
|
||||
exe := cmds.NewExecutor(req.Root)
|
||||
cctx := env.(*oldcmds.Context)
|
||||
details := commandDetails(req.Path)
|
||||
|
||||
// Check if the command is disabled.
|
||||
if details.cannotRunOnClient && details.cannotRunOnDaemon {
|
||||
if req.Command.NoLocal && req.Command.NoRemote {
|
||||
return nil, fmt.Errorf("command disabled: %v", req.Path)
|
||||
}
|
||||
|
||||
// Can we just run this locally?
|
||||
if !details.cannotRunOnClient && details.doesNotUseRepo {
|
||||
return exe, nil
|
||||
if !req.Command.NoLocal {
|
||||
if doesNotUseRepo, ok := corecmds.GetDoesNotUseRepo(req.Command.Extra); doesNotUseRepo && ok {
|
||||
return exe, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Get the API option from the commandline.
|
||||
@ -225,7 +225,7 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
|
||||
daemonRequested := apiAddr != nil && req.Command != daemonCmd
|
||||
|
||||
// Run this on the client if required.
|
||||
if details.cannotRunOnDaemon || req.Command.External {
|
||||
if req.Command.NoRemote {
|
||||
if daemonRequested {
|
||||
// User requested that the command be run on the daemon but we can't.
|
||||
// NOTE: We drop this check for the `ipfs daemon` command.
|
||||
@ -247,7 +247,7 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
|
||||
|
||||
// Still no api specified? Run it on the client or fail.
|
||||
if apiAddr == nil {
|
||||
if details.cannotRunOnClient {
|
||||
if req.Command.NoLocal {
|
||||
return nil, fmt.Errorf("command must be run on the daemon: %v", req.Path)
|
||||
}
|
||||
return exe, nil
|
||||
@ -293,22 +293,6 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
|
||||
return cmdhttp.NewClient(host, opts...), nil
|
||||
}
|
||||
|
||||
// commandDetails returns a command's details for the command given by |path|.
|
||||
func commandDetails(path []string) cmdDetails {
|
||||
if len(path) == 0 {
|
||||
// special case root command
|
||||
return cmdDetails{doesNotUseRepo: true}
|
||||
}
|
||||
var details cmdDetails
|
||||
// find the last command in path that has a cmdDetailsMap entry
|
||||
for i := range path {
|
||||
if cmdDetails, found := cmdDetailsMap[strings.Join(path[:i+1], "/")]; found {
|
||||
details = cmdDetails
|
||||
}
|
||||
}
|
||||
return details
|
||||
}
|
||||
|
||||
func getRepoPath(req *cmds.Request) (string, error) {
|
||||
repoOpt, found := req.Options["config"].(string)
|
||||
if found && repoOpt != "" {
|
||||
|
||||
@ -23,6 +23,7 @@ var ActiveReqsCmd = &cmds.Command{
|
||||
Lists running and recently run commands.
|
||||
`,
|
||||
},
|
||||
NoLocal: true,
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
ctx := env.(*oldcmds.Context)
|
||||
return cmds.EmitOnce(res, ctx.ReqLog.Report())
|
||||
|
||||
@ -60,6 +60,10 @@ Adds contents of <path> to ipfs. Use -r to add directories.
|
||||
Note that directories are added recursively, to form the ipfs
|
||||
MerkleDAG.
|
||||
|
||||
If the daemon is not running, it will just add locally.
|
||||
If the daemon is started later, it will be advertised after a few
|
||||
seconds when the reprovider runs.
|
||||
|
||||
The wrap option, '-w', wraps the file (or files, if using the
|
||||
recursive option) in a directory. This directory contains only
|
||||
the files which have been added, and means that the file retains
|
||||
|
||||
@ -26,6 +26,7 @@ var CidCmd = &cmds.Command{
|
||||
"codecs": codecsCmd,
|
||||
"hashes": hashesCmd,
|
||||
},
|
||||
Extra: CreateCmdExtras(SetDoesNotUseRepo(true)),
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@ -66,6 +66,7 @@ func CommandsCmd(root *cmds.Command) *cmds.Command {
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption(flagsOptionName, "f", "Show command flags"),
|
||||
},
|
||||
Extra: CreateCmdExtras(SetDoesNotUseRepo(true)),
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
rootCmd := cmd2outputCmd("ipfs", root)
|
||||
rootCmd.showOpts, _ = req.Options[flagsOptionName].(bool)
|
||||
|
||||
@ -25,6 +25,7 @@ func TestROCommands(t *testing.T) {
|
||||
"/dag",
|
||||
"/dag/get",
|
||||
"/dag/resolve",
|
||||
"/dag/stat",
|
||||
"/dns",
|
||||
"/get",
|
||||
"/ls",
|
||||
@ -99,6 +100,7 @@ func TestCommands(t *testing.T) {
|
||||
"/dag/put",
|
||||
"/dag/import",
|
||||
"/dag/resolve",
|
||||
"/dag/stat",
|
||||
"/dht",
|
||||
"/dht/findpeer",
|
||||
"/dht/findprovs",
|
||||
@ -133,9 +135,12 @@ func TestCommands(t *testing.T) {
|
||||
"/id",
|
||||
"/key",
|
||||
"/key/gen",
|
||||
"/key/export",
|
||||
"/key/import",
|
||||
"/key/list",
|
||||
"/key/rename",
|
||||
"/key/rm",
|
||||
"/key/rotate",
|
||||
"/log",
|
||||
"/log/level",
|
||||
"/log/ls",
|
||||
|
||||
@ -239,7 +239,8 @@ To use 'ipfs config edit', you must have the $EDITOR environment
|
||||
variable set to your preferred text editor.
|
||||
`,
|
||||
},
|
||||
|
||||
NoRemote: true,
|
||||
Extra: CreateCmdExtras(SetDoesNotUseRepo(true)),
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
"github.com/ipfs/go-ipfs/core/commands/e"
|
||||
"github.com/ipfs/go-ipfs/core/coredag"
|
||||
iface "github.com/ipfs/interface-go-ipfs-core"
|
||||
|
||||
@ -19,6 +20,7 @@ import (
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
mdag "github.com/ipfs/go-merkledag"
|
||||
traverse "github.com/ipfs/go-merkledag/traverse"
|
||||
ipfspath "github.com/ipfs/go-path"
|
||||
"github.com/ipfs/interface-go-ipfs-core/options"
|
||||
path "github.com/ipfs/interface-go-ipfs-core/path"
|
||||
@ -54,6 +56,7 @@ to deprecate and replace the existing 'ipfs object' command moving forward.
|
||||
"resolve": DagResolveCmd,
|
||||
"import": DagImportCmd,
|
||||
"export": DagExportCmd,
|
||||
"stat": DagStatCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@ -668,3 +671,116 @@ The output of blocks happens in strict DAG-traversal, first-seen, order.
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type DagStat struct {
|
||||
Size uint64
|
||||
NumBlocks int64
|
||||
}
|
||||
|
||||
func (s *DagStat) String() string {
|
||||
return fmt.Sprintf("Size: %d, NumBlocks: %d", s.Size, s.NumBlocks)
|
||||
}
|
||||
|
||||
var DagStatCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Gets stats for a DAG",
|
||||
ShortDescription: `
|
||||
'ipfs dag size' fetches a dag and returns various statistics about the DAG.
|
||||
Statistics include size and number of blocks.
|
||||
|
||||
Note: This command skips duplicate blocks in reporting both size and the number of blocks
|
||||
`,
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("root", true, false, "CID of a DAG root to get statistics for").EnableStdin(),
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption(progressOptionName, "p", "Return progressive data while reading through the DAG").WithDefault(true),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
progressive := req.Options[progressOptionName].(bool)
|
||||
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rp, err := api.ResolvePath(req.Context, path.New(req.Arguments[0]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(rp.Remainder()) > 0 {
|
||||
return fmt.Errorf("cannot return size for anything other than a DAG with a root CID")
|
||||
}
|
||||
|
||||
nodeGetter := mdag.NewSession(req.Context, api.Dag())
|
||||
obj, err := nodeGetter.Get(req.Context, rp.Cid())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dagstats := &DagStat{}
|
||||
err = traverse.Traverse(obj, traverse.Options{
|
||||
DAG: nodeGetter,
|
||||
Order: traverse.DFSPre,
|
||||
Func: func(current traverse.State) error {
|
||||
dagstats.Size += uint64(len(current.Node.RawData()))
|
||||
dagstats.NumBlocks++
|
||||
|
||||
if progressive {
|
||||
if err := res.Emit(dagstats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
ErrFunc: nil,
|
||||
SkipDuplicates: true,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error traversing DAG: %w", err)
|
||||
}
|
||||
|
||||
if !progressive {
|
||||
if err := res.Emit(dagstats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Type: DagStat{},
|
||||
PostRun: cmds.PostRunMap{
|
||||
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
|
||||
var dagStats *DagStat
|
||||
for {
|
||||
v, err := res.Next()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
out, ok := v.(*DagStat)
|
||||
if !ok {
|
||||
return e.TypeErr(out, v)
|
||||
}
|
||||
dagStats = out
|
||||
fmt.Fprintf(os.Stderr, "%v\r", out)
|
||||
}
|
||||
return re.Emit(dagStats)
|
||||
},
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, event *DagStat) error {
|
||||
_, err := fmt.Fprintf(
|
||||
w,
|
||||
"%v\n",
|
||||
event,
|
||||
)
|
||||
return err
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ import (
|
||||
path "github.com/ipfs/go-path"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
routing "github.com/libp2p/go-libp2p-core/routing"
|
||||
b58 "github.com/mr-tron/base58/base58"
|
||||
)
|
||||
|
||||
var ErrNotDHT = errors.New("routing service is not a DHT")
|
||||
@ -676,20 +675,15 @@ func printEvent(obj *routing.QueryEvent, out io.Writer, verbose bool, override p
|
||||
|
||||
func escapeDhtKey(s string) (string, error) {
|
||||
parts := path.SplitList(s)
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
k, err := b58.Decode(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(k), nil
|
||||
case 3:
|
||||
k, err := b58.Decode(parts[2])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path.Join(append(parts[:2], string(k))), nil
|
||||
default:
|
||||
if len(parts) != 3 ||
|
||||
parts[0] != "" ||
|
||||
!(parts[1] == "ipns" || parts[1] == "pk") {
|
||||
return "", errors.New("invalid key")
|
||||
}
|
||||
|
||||
k, err := peer.Decode(parts[2])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path.Join(append(parts[:2], string(k))), nil
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ func ExternalBinary(instructions string) *cmds.Command {
|
||||
cmds.StringArg("args", false, true, "Arguments for subcommand."),
|
||||
},
|
||||
External: true,
|
||||
NoRemote: true,
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
binname := strings.Join(append([]string{"ipfs"}, req.Path...), "-")
|
||||
_, err := exec.LookPath(binname)
|
||||
|
||||
65
core/commands/extra.go
Normal file
65
core/commands/extra.go
Normal file
@ -0,0 +1,65 @@
|
||||
package commands
|
||||
|
||||
import cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
|
||||
func CreateCmdExtras(opts ...func(e *cmds.Extra)) *cmds.Extra {
|
||||
e := new(cmds.Extra)
|
||||
for _, o := range opts {
|
||||
o(e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
type doesNotUseRepo struct{}
|
||||
|
||||
func SetDoesNotUseRepo(val bool) func(e *cmds.Extra) {
|
||||
return func(e *cmds.Extra) {
|
||||
e.SetValue(doesNotUseRepo{}, val)
|
||||
}
|
||||
}
|
||||
|
||||
func GetDoesNotUseRepo(e *cmds.Extra) (val bool, found bool) {
|
||||
return getBoolFlag(e, doesNotUseRepo{})
|
||||
}
|
||||
|
||||
// doesNotUseConfigAsInput describes commands that do not use the config as
|
||||
// input. These commands either initialize the config or perform operations
|
||||
// that don't require access to the config.
|
||||
//
|
||||
// pre-command hooks that require configs must not be run before these
|
||||
// commands.
|
||||
type doesNotUseConfigAsInput struct{}
|
||||
|
||||
func SetDoesNotUseConfigAsInput(val bool) func(e *cmds.Extra) {
|
||||
return func(e *cmds.Extra) {
|
||||
e.SetValue(doesNotUseConfigAsInput{}, val)
|
||||
}
|
||||
}
|
||||
|
||||
func GetDoesNotUseConfigAsInput(e *cmds.Extra) (val bool, found bool) {
|
||||
return getBoolFlag(e, doesNotUseConfigAsInput{})
|
||||
}
|
||||
|
||||
// preemptsAutoUpdate describes commands that must be executed without the
|
||||
// auto-update pre-command hook
|
||||
type preemptsAutoUpdate struct{}
|
||||
|
||||
func SetPreemptsAutoUpdate(val bool) func(e *cmds.Extra) {
|
||||
return func(e *cmds.Extra) {
|
||||
e.SetValue(preemptsAutoUpdate{}, val)
|
||||
}
|
||||
}
|
||||
|
||||
func GetPreemptsAutoUpdate(e *cmds.Extra) (val bool, found bool) {
|
||||
return getBoolFlag(e, preemptsAutoUpdate{})
|
||||
}
|
||||
|
||||
func getBoolFlag(e *cmds.Extra, key interface{}) (val bool, found bool) {
|
||||
var ival interface{}
|
||||
ival, found = e.GetValue(key)
|
||||
if !found {
|
||||
return false, false
|
||||
}
|
||||
val = ival.(bool)
|
||||
return val, found
|
||||
}
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
version "github.com/ipfs/go-ipfs"
|
||||
@ -13,6 +14,7 @@ import (
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
|
||||
ic "github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
@ -36,10 +38,12 @@ type IdOutput struct {
|
||||
Addresses []string
|
||||
AgentVersion string
|
||||
ProtocolVersion string
|
||||
Protocols []string
|
||||
}
|
||||
|
||||
const (
|
||||
formatOptionName = "format"
|
||||
formatOptionName = "format"
|
||||
idFormatOptionName = "peerid-base"
|
||||
)
|
||||
|
||||
var IDCmd = &cmds.Command{
|
||||
@ -66,8 +70,14 @@ EXAMPLE:
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(formatOptionName, "f", "Optional output format."),
|
||||
cmds.StringOption(idFormatOptionName, "Encoding used for peer IDs: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("b58mh"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[idFormatOptionName].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -85,7 +95,7 @@ EXAMPLE:
|
||||
}
|
||||
|
||||
if id == n.Identity {
|
||||
output, err := printSelf(n)
|
||||
output, err := printSelf(keyEnc, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -97,15 +107,17 @@ EXAMPLE:
|
||||
return errors.New(offlineIdErrorMessage)
|
||||
}
|
||||
|
||||
p, err := n.Routing.FindPeer(req.Context, id)
|
||||
if err == kb.ErrLookupFailure {
|
||||
// We need to actually connect to run identify.
|
||||
err = n.PeerHost.Connect(req.Context, peer.AddrInfo{ID: id})
|
||||
switch err {
|
||||
case nil:
|
||||
case kb.ErrLookupFailure:
|
||||
return errors.New(offlineIdErrorMessage)
|
||||
}
|
||||
if err != nil {
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
||||
output, err := printPeer(n.Peerstore, p.ID)
|
||||
output, err := printPeer(keyEnc, n.Peerstore, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -121,6 +133,7 @@ EXAMPLE:
|
||||
output = strings.Replace(output, "<pver>", out.ProtocolVersion, -1)
|
||||
output = strings.Replace(output, "<pubkey>", out.PublicKey, -1)
|
||||
output = strings.Replace(output, "<addrs>", strings.Join(out.Addresses, "\n"), -1)
|
||||
output = strings.Replace(output, "<protocols>", strings.Join(out.Protocols, "\n"), -1)
|
||||
output = strings.Replace(output, "\\n", "\n", -1)
|
||||
output = strings.Replace(output, "\\t", "\t", -1)
|
||||
fmt.Fprint(w, output)
|
||||
@ -138,13 +151,13 @@ EXAMPLE:
|
||||
Type: IdOutput{},
|
||||
}
|
||||
|
||||
func printPeer(ps pstore.Peerstore, p peer.ID) (interface{}, error) {
|
||||
func printPeer(keyEnc ke.KeyEncoder, ps pstore.Peerstore, p peer.ID) (interface{}, error) {
|
||||
if p == "" {
|
||||
return nil, errors.New("attempted to print nil peer")
|
||||
}
|
||||
|
||||
info := new(IdOutput)
|
||||
info.ID = p.Pretty()
|
||||
info.ID = keyEnc.FormatID(p)
|
||||
|
||||
if pk := ps.PubKey(p); pk != nil {
|
||||
pkb, err := ic.MarshalPublicKey(pk)
|
||||
@ -154,9 +167,22 @@ func printPeer(ps pstore.Peerstore, p peer.ID) (interface{}, error) {
|
||||
info.PublicKey = base64.StdEncoding.EncodeToString(pkb)
|
||||
}
|
||||
|
||||
for _, a := range ps.Addrs(p) {
|
||||
addrInfo := ps.PeerInfo(p)
|
||||
addrs, err := peer.AddrInfoToP2pAddrs(&addrInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, a := range addrs {
|
||||
info.Addresses = append(info.Addresses, a.String())
|
||||
}
|
||||
sort.Strings(info.Addresses)
|
||||
|
||||
protocols, _ := ps.GetProtocols(p) // don't care about errors here.
|
||||
for _, p := range protocols {
|
||||
info.Protocols = append(info.Protocols, string(p))
|
||||
}
|
||||
sort.Strings(info.Protocols)
|
||||
|
||||
if v, err := ps.Get(p, "ProtocolVersion"); err == nil {
|
||||
if vs, ok := v.(string); ok {
|
||||
@ -173,9 +199,9 @@ func printPeer(ps pstore.Peerstore, p peer.ID) (interface{}, error) {
|
||||
}
|
||||
|
||||
// printing self is special cased as we get values differently.
|
||||
func printSelf(node *core.IpfsNode) (interface{}, error) {
|
||||
func printSelf(keyEnc ke.KeyEncoder, node *core.IpfsNode) (interface{}, error) {
|
||||
info := new(IdOutput)
|
||||
info.ID = node.Identity.Pretty()
|
||||
info.ID = keyEnc.FormatID(node.Identity)
|
||||
|
||||
pk := node.PrivateKey.GetPublic()
|
||||
pkb, err := ic.MarshalPublicKey(pk)
|
||||
@ -192,6 +218,9 @@ func printSelf(node *core.IpfsNode) (interface{}, error) {
|
||||
for _, a := range addrs {
|
||||
info.Addresses = append(info.Addresses, a.String())
|
||||
}
|
||||
sort.Strings(info.Addresses)
|
||||
info.Protocols = node.PeerHost.Mux().Protocols()
|
||||
sort.Strings(info.Protocols)
|
||||
}
|
||||
info.ProtocolVersion = identify.LibP2PVersion
|
||||
info.AgentVersion = version.UserAgent
|
||||
|
||||
40
core/commands/keyencode/keyencode.go
Normal file
40
core/commands/keyencode/keyencode.go
Normal file
@ -0,0 +1,40 @@
|
||||
package keyencode
|
||||
|
||||
import (
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
)
|
||||
|
||||
const ipnsKeyFormatOptionName = "ipns-base"
|
||||
|
||||
var OptionIPNSBase = cmds.StringOption(ipnsKeyFormatOptionName, "Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}.").WithDefault("base36")
|
||||
|
||||
type KeyEncoder struct {
|
||||
baseEnc *mbase.Encoder
|
||||
}
|
||||
|
||||
func KeyEncoderFromString(formatLabel string) (KeyEncoder, error) {
|
||||
switch formatLabel {
|
||||
case "b58mh", "v0":
|
||||
return KeyEncoder{}, nil
|
||||
default:
|
||||
if enc, err := mbase.EncoderByName(formatLabel); err != nil {
|
||||
return KeyEncoder{}, err
|
||||
} else {
|
||||
return KeyEncoder{&enc}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (enc KeyEncoder) FormatID(id peer.ID) string {
|
||||
if enc.baseEnc == nil {
|
||||
//nolint deprecated
|
||||
return peer.IDB58Encode(id)
|
||||
}
|
||||
if s, err := peer.ToCid(id).StringOfBase(enc.baseEnc.Encoding()); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
return s
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,25 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
config "github.com/ipfs/go-ipfs-config"
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
"github.com/ipfs/go-ipfs/core/commands/e"
|
||||
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
|
||||
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
|
||||
options "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
)
|
||||
|
||||
var KeyCmd = &cmds.Command{
|
||||
@ -30,9 +41,12 @@ publish'.
|
||||
},
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"gen": keyGenCmd,
|
||||
"export": keyExportCmd,
|
||||
"import": keyImportCmd,
|
||||
"list": keyListCmd,
|
||||
"rename": keyRenameCmd,
|
||||
"rm": keyRmCmd,
|
||||
"rotate": keyRotateCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@ -54,8 +68,10 @@ type KeyRenameOutput struct {
|
||||
}
|
||||
|
||||
const (
|
||||
keyStoreTypeOptionName = "type"
|
||||
keyStoreSizeOptionName = "size"
|
||||
keyStoreAlgorithmDefault = options.Ed25519Key
|
||||
keyStoreTypeOptionName = "type"
|
||||
keyStoreSizeOptionName = "size"
|
||||
oldKeyOptionName = "oldkey"
|
||||
)
|
||||
|
||||
var keyGenCmd = &cmds.Command{
|
||||
@ -63,8 +79,9 @@ var keyGenCmd = &cmds.Command{
|
||||
Tagline: "Create a new keypair",
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault("rsa"),
|
||||
cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault),
|
||||
cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name of key to create"),
|
||||
@ -91,6 +108,10 @@ var keyGenCmd = &cmds.Command{
|
||||
if sizefound {
|
||||
opts = append(opts, options.Key.Size(size))
|
||||
}
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := api.Key().Generate(req.Context, name, opts...)
|
||||
|
||||
@ -100,7 +121,171 @@ var keyGenCmd = &cmds.Command{
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutput{
|
||||
Name: name,
|
||||
Id: key.ID().Pretty(),
|
||||
Id: keyEnc.FormatID(key.ID()),
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ko *KeyOutput) error {
|
||||
_, err := w.Write([]byte(ko.Id + "\n"))
|
||||
return err
|
||||
}),
|
||||
},
|
||||
Type: KeyOutput{},
|
||||
}
|
||||
|
||||
var keyExportCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Export a keypair",
|
||||
ShortDescription: `
|
||||
Exports a named libp2p key to disk.
|
||||
|
||||
By default, the output will be stored at './<key-name>.key', but an alternate
|
||||
path can be specified with '--output=<path>' or '-o=<path>'.
|
||||
`,
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name of key to export").EnableStdin(),
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."),
|
||||
},
|
||||
NoRemote: true,
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
name := req.Arguments[0]
|
||||
|
||||
if name == "self" {
|
||||
return fmt.Errorf("cannot export key with name 'self'")
|
||||
}
|
||||
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := fsrepo.Open(cfgRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
sk, err := r.Keystore().Get(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("key with name '%s' doesn't exist", name)
|
||||
}
|
||||
|
||||
encoded, err := crypto.MarshalPrivateKey(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return res.Emit(bytes.NewReader(encoded))
|
||||
},
|
||||
PostRun: cmds.PostRunMap{
|
||||
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
|
||||
req := res.Request()
|
||||
|
||||
v, err := res.Next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outReader, ok := v.(io.Reader)
|
||||
if !ok {
|
||||
return e.New(e.TypeErr(outReader, v))
|
||||
}
|
||||
|
||||
outPath, _ := req.Options[outputOptionName].(string)
|
||||
if outPath == "" {
|
||||
trimmed := strings.TrimRight(fmt.Sprintf("%s.key", req.Arguments[0]), "/")
|
||||
_, outPath = filepath.Split(trimmed)
|
||||
outPath = filepath.Clean(outPath)
|
||||
}
|
||||
|
||||
// create file
|
||||
file, err := os.Create(outPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, outReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var keyImportCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Import a key and prints imported key id",
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("name", true, false, "name to associate with key in keychain"),
|
||||
cmds.FileArg("key", true, false, "key provided by generate or export"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
name := req.Arguments[0]
|
||||
|
||||
if name == "self" {
|
||||
return fmt.Errorf("cannot import key with name 'self'")
|
||||
}
|
||||
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := cmdenv.GetFileArg(req.Files.Entries())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sk, err := crypto.UnmarshalPrivateKey(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfgRoot, err := cmdenv.GetConfigRoot(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := fsrepo.Open(cfgRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
_, err = r.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return fmt.Errorf("key with name '%s' already exists", name)
|
||||
}
|
||||
|
||||
err = r.Keystore().Put(name, sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid, err := peer.IDFromPrivateKey(sk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutput{
|
||||
Name: name,
|
||||
Id: keyEnc.FormatID(pid),
|
||||
})
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
@ -118,8 +303,14 @@ var keyListCmd = &cmds.Command{
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption("l", "Show extra information about keys."),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -133,7 +324,10 @@ var keyListCmd = &cmds.Command{
|
||||
list := make([]KeyOutput, 0, len(keys))
|
||||
|
||||
for _, key := range keys {
|
||||
list = append(list, KeyOutput{Name: key.Name(), Id: key.ID().Pretty()})
|
||||
list = append(list, KeyOutput{
|
||||
Name: key.Name(),
|
||||
Id: keyEnc.FormatID(key.ID()),
|
||||
})
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutputList{list})
|
||||
@ -158,12 +352,17 @@ var keyRenameCmd = &cmds.Command{
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := req.Arguments[0]
|
||||
newName := req.Arguments[1]
|
||||
@ -177,7 +376,7 @@ var keyRenameCmd = &cmds.Command{
|
||||
return cmds.EmitOnce(res, &KeyRenameOutput{
|
||||
Was: name,
|
||||
Now: newName,
|
||||
Id: key.ID().Pretty(),
|
||||
Id: keyEnc.FormatID(key.ID()),
|
||||
Overwrite: overwritten,
|
||||
})
|
||||
},
|
||||
@ -203,12 +402,17 @@ var keyRmCmd = &cmds.Command{
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption("l", "Show extra information about keys."),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
names := req.Arguments
|
||||
|
||||
@ -219,7 +423,10 @@ var keyRmCmd = &cmds.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
list = append(list, KeyOutput{Name: name, Id: key.ID().Pretty()})
|
||||
list = append(list, KeyOutput{
|
||||
Name: name,
|
||||
Id: keyEnc.FormatID(key.ID()),
|
||||
})
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &KeyOutputList{list})
|
||||
@ -230,6 +437,109 @@ var keyRmCmd = &cmds.Command{
|
||||
Type: KeyOutputList{},
|
||||
}
|
||||
|
||||
var keyRotateCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Rotates the ipfs identity.",
|
||||
ShortDescription: `
|
||||
Generates a new ipfs identity and saves it to the ipfs config file.
|
||||
Your existing identity key will be backed up in the Keystore.
|
||||
The daemon must not be running when calling this command.
|
||||
|
||||
ipfs uses a repository in the local file system. By default, the repo is
|
||||
located at ~/.ipfs. To change the repo location, set the $IPFS_PATH
|
||||
environment variable:
|
||||
|
||||
export IPFS_PATH=/path/to/ipfsrepo
|
||||
`,
|
||||
},
|
||||
Arguments: []cmds.Argument{},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption(oldKeyOptionName, "o", "Keystore name to use for backing up your existing identity"),
|
||||
cmds.StringOption(keyStoreTypeOptionName, "t", "type of the key to create: rsa, ed25519").WithDefault(keyStoreAlgorithmDefault),
|
||||
cmds.IntOption(keyStoreSizeOptionName, "s", "size of the key to generate"),
|
||||
},
|
||||
NoRemote: true,
|
||||
PreRun: func(req *cmds.Request, env cmds.Environment) error {
|
||||
cctx := env.(*oldcmds.Context)
|
||||
daemonLocked, err := fsrepo.LockedByOtherProcess(cctx.ConfigRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("checking if daemon is running...")
|
||||
if daemonLocked {
|
||||
log.Debug("ipfs daemon is running")
|
||||
e := "ipfs daemon is running. please stop it to run this command"
|
||||
return cmds.ClientError(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
cctx := env.(*oldcmds.Context)
|
||||
nBitsForKeypair, nBitsGiven := req.Options[keyStoreSizeOptionName].(int)
|
||||
algorithm, _ := req.Options[keyStoreTypeOptionName].(string)
|
||||
oldKey, ok := req.Options[oldKeyOptionName].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("keystore name for backing up old key must be provided")
|
||||
}
|
||||
if oldKey == "self" {
|
||||
return fmt.Errorf("keystore name for back up cannot be named 'self'")
|
||||
}
|
||||
return doRotate(os.Stdout, cctx.ConfigRoot, oldKey, algorithm, nBitsForKeypair, nBitsGiven)
|
||||
},
|
||||
}
|
||||
|
||||
func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, nBitsForKeypair int, nBitsGiven bool) error {
|
||||
// Open repo
|
||||
repo, err := fsrepo.Open(repoRoot)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening repo (%v)", err)
|
||||
}
|
||||
defer repo.Close()
|
||||
|
||||
// Read config file from repo
|
||||
cfg, err := repo.Config()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading config from repo (%v)", err)
|
||||
}
|
||||
|
||||
// Generate new identity
|
||||
var identity config.Identity
|
||||
if nBitsGiven {
|
||||
identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
|
||||
options.Key.Size(nBitsForKeypair),
|
||||
options.Key.Type(algorithm),
|
||||
})
|
||||
} else {
|
||||
identity, err = config.CreateIdentity(out, []options.KeyGenerateOption{
|
||||
options.Key.Type(algorithm),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating identity (%v)", err)
|
||||
}
|
||||
|
||||
// Save old identity to keystore
|
||||
oldPrivKey, err := cfg.Identity.DecodePrivateKey("")
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding old private key (%v)", err)
|
||||
}
|
||||
keystore := repo.Keystore()
|
||||
if err := keystore.Put(oldKey, oldPrivKey); err != nil {
|
||||
return fmt.Errorf("saving old key in keystore (%v)", err)
|
||||
}
|
||||
|
||||
// Update identity
|
||||
cfg.Identity = identity
|
||||
|
||||
// Write config file to repo
|
||||
if err = repo.SetConfig(cfg); err != nil {
|
||||
return fmt.Errorf("saving new key to config (%v)", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func keyOutputListEncoders() cmds.EncoderFunc {
|
||||
return cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *KeyOutputList) error {
|
||||
withID, _ := req.Options["l"].(bool)
|
||||
|
||||
@ -55,6 +55,7 @@ the event log.
|
||||
One of: debug, info, warn, error, dpanic, panic, fatal.
|
||||
`),
|
||||
},
|
||||
NoLocal: true,
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
args := req.Arguments
|
||||
subsystem, level := args[0], args[1]
|
||||
|
||||
@ -99,7 +99,7 @@ Resolve the value of a dnslink:
|
||||
}
|
||||
|
||||
recursive, _ := req.Options[recursiveOptionName].(bool)
|
||||
rc, rcok := req.Options[dhtRecordCountOptionName].(int)
|
||||
rc, rcok := req.Options[dhtRecordCountOptionName].(uint)
|
||||
dhtt, dhttok := req.Options[dhtTimeoutOptionName].(string)
|
||||
stream, _ := req.Options[streamOptionName].(bool)
|
||||
|
||||
@ -111,7 +111,7 @@ Resolve the value of a dnslink:
|
||||
opts = append(opts, options.Name.ResolveOption(nsopts.Depth(1)))
|
||||
}
|
||||
if rcok {
|
||||
opts = append(opts, options.Name.ResolveOption(nsopts.DhtRecordCount(uint(rc))))
|
||||
opts = append(opts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc)))
|
||||
}
|
||||
if dhttok {
|
||||
d, err := time.ParseDuration(dhtt)
|
||||
|
||||
@ -5,10 +5,11 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/go-ipfs-cmds"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
"github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-record"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
)
|
||||
|
||||
type ipnsPubsubState struct {
|
||||
@ -72,7 +73,15 @@ var ipnspsSubsCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Show current name subscriptions",
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -93,7 +102,7 @@ var ipnspsSubsCmd = &cmds.Command{
|
||||
log.Errorf("ipns key not a valid peer ID: %s", err)
|
||||
continue
|
||||
}
|
||||
paths = append(paths, "/ipns/"+peer.Encode(pid))
|
||||
paths = append(paths, "/ipns/"+keyEnc.FormatID(pid))
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &stringList{paths})
|
||||
|
||||
@ -9,9 +9,11 @@ import (
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
ke "github.com/ipfs/go-ipfs/core/commands/keyencode"
|
||||
iface "github.com/ipfs/interface-go-ipfs-core"
|
||||
options "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
path "github.com/ipfs/interface-go-ipfs-core/path"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -81,12 +83,17 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"),
|
||||
cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"),
|
||||
cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."),
|
||||
ke.OptionIPNSBase,
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
|
||||
kname, _ := req.Options[keyOptionName].(string)
|
||||
@ -129,8 +136,14 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
return err
|
||||
}
|
||||
|
||||
// parse path, extract cid, re-base cid, reconstruct path
|
||||
pid, err := peer.Decode(out.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &IpnsEntry{
|
||||
Name: out.Name(),
|
||||
Name: keyEnc.FormatID(pid),
|
||||
Value: out.Value().String(),
|
||||
})
|
||||
},
|
||||
|
||||
@ -499,6 +499,9 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun
|
||||
}
|
||||
|
||||
for p := range pins {
|
||||
if p.Err() != nil {
|
||||
return err
|
||||
}
|
||||
err = emit(&PinLsOutputWrapper{
|
||||
PinLsObject: PinLsObject{
|
||||
Type: p.Type(),
|
||||
|
||||
@ -74,7 +74,7 @@ This command outputs data in the following encodings:
|
||||
cmds.StringArg("topic", true, false, "String name of topic to subscribe to."),
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption(pubsubDiscoverOptionName, "try to discover other peers subscribed to the same topic"),
|
||||
cmds.BoolOption(pubsubDiscoverOptionName, "Deprecated option to instruct pubsub to discovery peers for the topic. Discovery is now built into pubsub."),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
@ -83,9 +83,7 @@ This command outputs data in the following encodings:
|
||||
}
|
||||
|
||||
topic := req.Arguments[0]
|
||||
discover, _ := req.Options[pubsubDiscoverOptionName].(bool)
|
||||
|
||||
sub, err := api.PubSub().Subscribe(req.Context, topic, options.PubSub.Discover(discover))
|
||||
sub, err := api.PubSub().Subscribe(req.Context, topic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -217,6 +217,7 @@ var repoFsckCmd = &cmds.Command{
|
||||
'ipfs repo fsck' is now a no-op.
|
||||
`,
|
||||
},
|
||||
NoRemote: true,
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
return cmds.EmitOnce(res, &MessageOutput{"`ipfs repo fsck` is deprecated and does nothing.\n"})
|
||||
},
|
||||
|
||||
@ -82,23 +82,6 @@ Resolve the value of an IPFS DAG path:
|
||||
name := req.Arguments[0]
|
||||
recursive, _ := req.Options[resolveRecursiveOptionName].(bool)
|
||||
|
||||
var enc cidenc.Encoder
|
||||
switch {
|
||||
case !cmdenv.CidBaseDefined(req):
|
||||
// Not specified, check the path.
|
||||
enc, err = cmdenv.CidEncoderFromPath(name)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
// Nope, fallback on the default.
|
||||
fallthrough
|
||||
default:
|
||||
enc, err = cmdenv.GetCidEncoder(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// the case when ipns is resolved step by step
|
||||
if strings.HasPrefix(name, "/ipns/") && !recursive {
|
||||
rc, rcok := req.Options[resolveDhtRecordCountOptionName].(uint)
|
||||
@ -128,6 +111,23 @@ Resolve the value of an IPFS DAG path:
|
||||
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: ipfspath.Path(p.String())})
|
||||
}
|
||||
|
||||
var enc cidenc.Encoder
|
||||
switch {
|
||||
case !cmdenv.CidBaseDefined(req) && !strings.HasPrefix(name, "/ipns/"):
|
||||
// Not specified, check the path.
|
||||
enc, err = cmdenv.CidEncoderFromPath(name)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
// Nope, fallback on the default.
|
||||
fallthrough
|
||||
default:
|
||||
enc, err = cmdenv.GetCidEncoder(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// else, ipfs path or ipns with recursive flag
|
||||
rp, err := api.ResolvePath(req.Context, path.New(name))
|
||||
if err != nil {
|
||||
|
||||
@ -191,6 +191,7 @@ var rootROSubcommands = map[string]*cmds.Command{
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"get": dag.DagGetCmd,
|
||||
"resolve": dag.DagResolveCmd,
|
||||
"stat": dag.DagStatCmd,
|
||||
},
|
||||
},
|
||||
"resolve": ResolveCmd,
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
sysi "github.com/whyrusleeping/go-sysinfo"
|
||||
)
|
||||
|
||||
|
||||
@ -43,6 +43,8 @@ var VersionCmd = &cmds.Command{
|
||||
cmds.BoolOption(versionRepoOptionName, "Show repo version."),
|
||||
cmds.BoolOption(versionAllOptionName, "Show all version information"),
|
||||
},
|
||||
// must be permitted to run before init
|
||||
Extra: CreateCmdExtras(SetDoesNotUseRepo(true), SetDoesNotUseConfigAsInput(true)),
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
return cmds.EmitOnce(res, &VersionOutput{
|
||||
Version: version.CurrentVersionNumber,
|
||||
|
||||
@ -26,7 +26,6 @@ import (
|
||||
"github.com/ipfs/go-ipfs-provider"
|
||||
offlineroute "github.com/ipfs/go-ipfs-routing/offline"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
logging "github.com/ipfs/go-log"
|
||||
dag "github.com/ipfs/go-merkledag"
|
||||
coreiface "github.com/ipfs/interface-go-ipfs-core"
|
||||
"github.com/ipfs/interface-go-ipfs-core/options"
|
||||
@ -44,8 +43,6 @@ import (
|
||||
"github.com/ipfs/go-ipfs/repo"
|
||||
)
|
||||
|
||||
var log = logging.Logger("core/coreapi")
|
||||
|
||||
type CoreAPI struct {
|
||||
nctx context.Context
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ func (k *key) Name() string {
|
||||
|
||||
// Path returns the path of the key.
|
||||
func (k *key) Path() path.Path {
|
||||
return path.New(ipfspath.Join([]string{"/ipns", k.peerID.Pretty()}))
|
||||
return path.New(ipfspath.Join([]string{"/ipns", coreiface.FormatKeyID(k.peerID)}))
|
||||
}
|
||||
|
||||
// ID returns key PeerID
|
||||
|
||||
@ -76,7 +76,7 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
|
||||
}
|
||||
|
||||
return &ipnsEntry{
|
||||
name: pid.Pretty(),
|
||||
name: coreiface.FormatKeyID(pid),
|
||||
value: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -57,9 +57,9 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c
|
||||
}
|
||||
|
||||
func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) {
|
||||
dagNode, err := api.core().ResolveNode(ctx, p)
|
||||
resolved, err := api.core().ResolvePath(ctx, p)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("pin: %s", err)
|
||||
return "", false, fmt.Errorf("error resolving path: %s", err)
|
||||
}
|
||||
|
||||
settings, err := caopts.PinIsPinnedOptions(opts...)
|
||||
@ -72,7 +72,7 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin
|
||||
return "", false, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.WithType)
|
||||
}
|
||||
|
||||
return api.pinning.IsPinnedWithType(ctx, dagNode.Cid(), mode)
|
||||
return api.pinning.IsPinnedWithType(ctx, resolved.Cid(), mode)
|
||||
}
|
||||
|
||||
// Rm pin rm api
|
||||
|
||||
@ -3,14 +3,9 @@ package coreapi
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
coreiface "github.com/ipfs/interface-go-ipfs-core"
|
||||
caopts "github.com/ipfs/interface-go-ipfs-core/options"
|
||||
p2phost "github.com/libp2p/go-libp2p-core/host"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
routing "github.com/libp2p/go-libp2p-core/routing"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
@ -19,7 +14,6 @@ import (
|
||||
type PubSubAPI CoreAPI
|
||||
|
||||
type pubSubSubscription struct {
|
||||
cancel context.CancelFunc
|
||||
subscription *pubsub.Subscription
|
||||
}
|
||||
|
||||
@ -61,12 +55,16 @@ func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) er
|
||||
}
|
||||
|
||||
func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) {
|
||||
options, err := caopts.PubSubSubscribeOptions(opts...)
|
||||
// Parse the options to avoid introducing silent failures for invalid
|
||||
// options. However, we don't currently have any use for them. The only
|
||||
// subscription option, discovery, is now a no-op as it's handled by
|
||||
// pubsub itself.
|
||||
_, err := caopts.PubSubSubscribeOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r, err := api.checkNode()
|
||||
_, err = api.checkNode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -77,45 +75,7 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pubctx, cancel := context.WithCancel(api.nctx)
|
||||
|
||||
if options.Discover {
|
||||
go func() {
|
||||
blk, err := api.core().Block().Put(pubctx, strings.NewReader("floodsub:"+topic))
|
||||
if err != nil {
|
||||
log.Error("pubsub discovery: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
connectToPubSubPeers(pubctx, r, api.peerHost, blk.Path().Cid())
|
||||
}()
|
||||
}
|
||||
|
||||
return &pubSubSubscription{cancel, sub}, nil
|
||||
}
|
||||
|
||||
func connectToPubSubPeers(ctx context.Context, r routing.Routing, ph p2phost.Host, cid cid.Cid) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
provs := r.FindProvidersAsync(ctx, cid, 10)
|
||||
var wg sync.WaitGroup
|
||||
for p := range provs {
|
||||
wg.Add(1)
|
||||
go func(pi peer.AddrInfo) {
|
||||
defer wg.Done()
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||
defer cancel()
|
||||
err := ph.Connect(ctx, pi)
|
||||
if err != nil {
|
||||
log.Info("pubsub discover: ", err)
|
||||
return
|
||||
}
|
||||
log.Info("connected to pubsub peer:", pi.ID)
|
||||
}(p)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return &pubSubSubscription{sub}, nil
|
||||
}
|
||||
|
||||
func (api *PubSubAPI) checkNode() (routing.Routing, error) {
|
||||
@ -132,7 +92,6 @@ func (api *PubSubAPI) checkNode() (routing.Routing, error) {
|
||||
}
|
||||
|
||||
func (sub *pubSubSubscription) Close() error {
|
||||
sub.cancel()
|
||||
sub.subscription.Cancel()
|
||||
return nil
|
||||
}
|
||||
@ -161,7 +120,3 @@ func (msg *pubSubMessage) Seq() []byte {
|
||||
func (msg *pubSubMessage) Topics() []string {
|
||||
return msg.msg.TopicIDs
|
||||
}
|
||||
|
||||
func (api *PubSubAPI) core() coreiface.CoreAPI {
|
||||
return (*CoreAPI)(api)
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
"github.com/jbenet/goprocess"
|
||||
periodicproc "github.com/jbenet/goprocess/periodic"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var log = logging.Logger("core/server")
|
||||
|
||||
@ -328,8 +328,20 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
|
||||
size = humanize.Bytes(uint64(s))
|
||||
}
|
||||
|
||||
hash := ""
|
||||
if r, err := i.api.ResolvePath(r.Context(), ipath.Join(resolvedPath, dirit.Name())); err == nil {
|
||||
// Path may not be resolved. Continue anyways.
|
||||
hash = r.Cid().String()
|
||||
}
|
||||
|
||||
// See comment above where originalUrlPath is declared.
|
||||
di := directoryItem{size, dirit.Name(), gopath.Join(originalUrlPath, dirit.Name())}
|
||||
di := directoryItem{
|
||||
Size: size,
|
||||
Name: dirit.Name(),
|
||||
Path: gopath.Join(originalUrlPath, dirit.Name()),
|
||||
Hash: hash,
|
||||
ShortHash: shortHash(hash),
|
||||
}
|
||||
dirListing = append(dirListing, di)
|
||||
}
|
||||
if dirit.Err() != nil {
|
||||
@ -359,14 +371,34 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
}
|
||||
|
||||
size := "?"
|
||||
if s, err := dir.Size(); err == nil {
|
||||
// Size may not be defined/supported. Continue anyways.
|
||||
size = humanize.Bytes(uint64(s))
|
||||
}
|
||||
|
||||
hash := resolvedPath.Cid().String()
|
||||
|
||||
// Storage for gateway URL to be used when linking to other rootIDs. This
|
||||
// will be blank unless subdomain resolution is being used for this request.
|
||||
var gwURL string
|
||||
|
||||
// Get gateway hostname and build gateway URL.
|
||||
if h, ok := r.Context().Value("gw-hostname").(string); ok {
|
||||
gwURL = "//" + h
|
||||
} else {
|
||||
gwURL = ""
|
||||
}
|
||||
|
||||
// See comment above where originalUrlPath is declared.
|
||||
tplData := listingTemplateData{
|
||||
Listing: dirListing,
|
||||
Path: urlPath,
|
||||
BackLink: backLink,
|
||||
Hash: hash,
|
||||
GatewayURL: gwURL,
|
||||
Listing: dirListing,
|
||||
Size: size,
|
||||
Path: urlPath,
|
||||
Breadcrumbs: breadcrumbs(urlPath),
|
||||
BackLink: backLink,
|
||||
Hash: hash,
|
||||
}
|
||||
|
||||
err = listingTemplate.Execute(w, tplData)
|
||||
|
||||
@ -7,22 +7,61 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/go-ipfs/assets"
|
||||
ipfspath "github.com/ipfs/go-path"
|
||||
)
|
||||
|
||||
// structs for directory listing
|
||||
type listingTemplateData struct {
|
||||
Listing []directoryItem
|
||||
Path string
|
||||
BackLink string
|
||||
Hash string
|
||||
GatewayURL string
|
||||
Listing []directoryItem
|
||||
Size string
|
||||
Path string
|
||||
Breadcrumbs []breadcrumb
|
||||
BackLink string
|
||||
Hash string
|
||||
}
|
||||
|
||||
type directoryItem struct {
|
||||
Size string
|
||||
Size string
|
||||
Name string
|
||||
Path string
|
||||
Hash string
|
||||
ShortHash string
|
||||
}
|
||||
|
||||
type breadcrumb struct {
|
||||
Name string
|
||||
Path string
|
||||
}
|
||||
|
||||
func breadcrumbs(urlPath string) []breadcrumb {
|
||||
var ret []breadcrumb
|
||||
|
||||
p, err := ipfspath.ParsePath(urlPath)
|
||||
if err != nil {
|
||||
// No breadcrumbs, fallback to bare Path in template
|
||||
return ret
|
||||
}
|
||||
|
||||
segs := p.Segments()
|
||||
for i, seg := range segs {
|
||||
if i == 0 {
|
||||
ret = append(ret, breadcrumb{Name: seg})
|
||||
} else {
|
||||
ret = append(ret, breadcrumb{
|
||||
Name: seg,
|
||||
Path: "/" + strings.Join(segs[0:i+1], "/"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func shortHash(hash string) string {
|
||||
return (hash[0:4] + "\u2026" + hash[len(hash)-4:])
|
||||
}
|
||||
|
||||
var listingTemplate *template.Template
|
||||
|
||||
func init() {
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -135,6 +136,7 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface
|
||||
// listener, and server with handler. yay cycles.
|
||||
dh := &delegatedHandler{}
|
||||
ts := httptest.NewServer(dh)
|
||||
t.Cleanup(func() { ts.Close() })
|
||||
|
||||
dh.Handler, err = makeHandler(n,
|
||||
ts.Listener,
|
||||
@ -154,10 +156,14 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface
|
||||
return ts, api, n.Context()
|
||||
}
|
||||
|
||||
func matchPathOrBreadcrumbs(s string, expected string) bool {
|
||||
matched, _ := regexp.MatchString("Index of\n[\t ]*"+regexp.QuoteMeta(expected), s)
|
||||
return matched
|
||||
}
|
||||
|
||||
func TestGatewayGet(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, api, ctx := newTestServerAndNode(t, ns)
|
||||
defer ts.Close()
|
||||
|
||||
k, err := api.Unixfs().Add(ctx, files.NewBytesFile([]byte("fnord")))
|
||||
if err != nil {
|
||||
@ -238,7 +244,6 @@ func TestGatewayGet(t *testing.T) {
|
||||
func TestPretty404(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, api, ctx := newTestServerAndNode(t, ns)
|
||||
defer ts.Close()
|
||||
|
||||
f1 := files.NewMapDirectory(map[string]files.Node{
|
||||
"ipfs-404.html": files.NewBytesFile([]byte("Custom 404")),
|
||||
@ -303,7 +308,6 @@ func TestIPNSHostnameRedirect(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, api, ctx := newTestServerAndNode(t, ns)
|
||||
t.Logf("test server url: %s", ts.URL)
|
||||
defer ts.Close()
|
||||
|
||||
// create /ipns/example.net/foo/index.html
|
||||
|
||||
@ -391,7 +395,6 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, api, ctx := newTestServerAndNode(t, ns)
|
||||
t.Logf("test server url: %s", ts.URL)
|
||||
defer ts.Close()
|
||||
|
||||
f1 := files.NewMapDirectory(map[string]files.Node{
|
||||
"file.txt": files.NewBytesFile([]byte("1")),
|
||||
@ -442,7 +445,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
s := string(body)
|
||||
t.Logf("body: %s\n", string(body))
|
||||
|
||||
if !strings.Contains(s, "Index of /ipns/example.net/foo? #<'/") {
|
||||
if !matchPathOrBreadcrumbs(s, "/ipns/<a href=\"/ipns/example.net\">example.net</a>/<a href=\"/ipns/example.net/foo%3F%20%23%3C%27\">foo? #<'</a>") {
|
||||
t.Fatalf("expected a path in directory listing")
|
||||
}
|
||||
if !strings.Contains(s, "<a href=\"/foo%3F%20%23%3C%27/./..\">") {
|
||||
@ -475,7 +478,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
s = string(body)
|
||||
t.Logf("body: %s\n", string(body))
|
||||
|
||||
if !strings.Contains(s, "Index of /") {
|
||||
if !matchPathOrBreadcrumbs(s, "/") {
|
||||
t.Fatalf("expected a path in directory listing")
|
||||
}
|
||||
if !strings.Contains(s, "<a href=\"/\">") {
|
||||
@ -508,7 +511,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
s = string(body)
|
||||
t.Logf("body: %s\n", string(body))
|
||||
|
||||
if !strings.Contains(s, "Index of /ipns/example.net/foo? #<'/bar/") {
|
||||
if !matchPathOrBreadcrumbs(s, "/ipns/<a href=\"/ipns/example.net\">example.net</a>/<a href=\"/ipns/example.net/foo%3F%20%23%3C%27\">foo? #<'</a>/<a href=\"/ipns/example.net/foo%3F%20%23%3C%27/bar\">bar</a>") {
|
||||
t.Fatalf("expected a path in directory listing")
|
||||
}
|
||||
if !strings.Contains(s, "<a href=\"/foo%3F%20%23%3C%27/bar/./..\">") {
|
||||
@ -542,7 +545,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
s = string(body)
|
||||
t.Logf("body: %s\n", string(body))
|
||||
|
||||
if !strings.Contains(s, "Index of /ipns/example.net") {
|
||||
if !matchPathOrBreadcrumbs(s, "/ipns/<a href=\"/ipns/example.net\">example.net</a>") {
|
||||
t.Fatalf("expected a path in directory listing")
|
||||
}
|
||||
if !strings.Contains(s, "<a href=\"/good-prefix/\">") {
|
||||
@ -584,7 +587,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
s = string(body)
|
||||
t.Logf("body: %s\n", string(body))
|
||||
|
||||
if !strings.Contains(s, "Index of /") {
|
||||
if !matchPathOrBreadcrumbs(s, "/") {
|
||||
t.Fatalf("expected a path in directory listing")
|
||||
}
|
||||
if !strings.Contains(s, "<a href=\"/\">") {
|
||||
@ -601,7 +604,6 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
|
||||
func TestCacheControlImmutable(t *testing.T) {
|
||||
ts, _, _ := newTestServerAndNode(t, nil)
|
||||
t.Logf("test server url: %s", ts.URL)
|
||||
defer ts.Close()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, ts.URL+emptyDir+"/", nil)
|
||||
if err != nil {
|
||||
@ -627,7 +629,6 @@ func TestCacheControlImmutable(t *testing.T) {
|
||||
func TestGoGetSupport(t *testing.T) {
|
||||
ts, _, _ := newTestServerAndNode(t, nil)
|
||||
t.Logf("test server url: %s", ts.URL)
|
||||
defer ts.Close()
|
||||
|
||||
// mimic go-get
|
||||
req, err := http.NewRequest(http.MethodGet, ts.URL+emptyDir+"?go-get=1", nil)
|
||||
@ -651,7 +652,6 @@ func TestVersion(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, _, _ := newTestServerAndNode(t, ns)
|
||||
t.Logf("test server url: %s", ts.URL)
|
||||
defer ts.Close()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, ts.URL+"/version", nil)
|
||||
if err != nil {
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@ -24,29 +25,32 @@ import (
|
||||
|
||||
var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/", "/version"}
|
||||
|
||||
var pathGatewaySpec = config.GatewaySpec{
|
||||
var pathGatewaySpec = &config.GatewaySpec{
|
||||
Paths: defaultPaths,
|
||||
UseSubdomains: false,
|
||||
}
|
||||
|
||||
var subdomainGatewaySpec = config.GatewaySpec{
|
||||
var subdomainGatewaySpec = &config.GatewaySpec{
|
||||
Paths: defaultPaths,
|
||||
UseSubdomains: true,
|
||||
}
|
||||
|
||||
var defaultKnownGateways = map[string]config.GatewaySpec{
|
||||
var defaultKnownGateways = map[string]*config.GatewaySpec{
|
||||
"localhost": subdomainGatewaySpec,
|
||||
"ipfs.io": pathGatewaySpec,
|
||||
"gateway.ipfs.io": pathGatewaySpec,
|
||||
"dweb.link": subdomainGatewaySpec,
|
||||
}
|
||||
|
||||
// Label's max length in DNS (https://tools.ietf.org/html/rfc1034#page-7)
|
||||
const dnsLabelMaxLength int = 63
|
||||
|
||||
// HostnameOption rewrites an incoming request based on the Host header.
|
||||
func HostnameOption() ServeOption {
|
||||
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
|
||||
childMux := http.NewServeMux()
|
||||
|
||||
coreApi, err := coreapi.NewCoreAPI(n)
|
||||
coreAPI, err := coreapi.NewCoreAPI(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -55,22 +59,8 @@ func HostnameOption() ServeOption {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
knownGateways := make(
|
||||
map[string]config.GatewaySpec,
|
||||
len(defaultKnownGateways)+len(cfg.Gateway.PublicGateways),
|
||||
)
|
||||
for hostname, gw := range defaultKnownGateways {
|
||||
knownGateways[hostname] = gw
|
||||
}
|
||||
for hostname, gw := range cfg.Gateway.PublicGateways {
|
||||
if gw == nil {
|
||||
// Allows the user to remove gateways but _also_
|
||||
// allows us to continuously update the list.
|
||||
delete(knownGateways, hostname)
|
||||
} else {
|
||||
knownGateways[hostname] = *gw
|
||||
}
|
||||
}
|
||||
|
||||
knownGateways := prepareKnownGateways(cfg.Gateway.PublicGateways)
|
||||
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// Unfortunately, many (well, ipfs.io) gateways use
|
||||
@ -81,8 +71,15 @@ func HostnameOption() ServeOption {
|
||||
// and the paths that they serve "gateway" content on.
|
||||
// That way, we can use DNSLink for everything else.
|
||||
|
||||
// Support X-Forwarded-Host if added by a reverse proxy
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
|
||||
host := r.Host
|
||||
if xHost := r.Header.Get("X-Forwarded-Host"); xHost != "" {
|
||||
host = xHost
|
||||
}
|
||||
|
||||
// HTTP Host & Path check: is this one of our "known gateways"?
|
||||
if gw, ok := isKnownHostname(r.Host, knownGateways); ok {
|
||||
if gw, ok := isKnownHostname(host, knownGateways); ok {
|
||||
// This is a known gateway but request is not using
|
||||
// the subdomain feature.
|
||||
|
||||
@ -94,7 +91,12 @@ func HostnameOption() ServeOption {
|
||||
if gw.UseSubdomains {
|
||||
// Yes, redirect if applicable
|
||||
// Example: dweb.link/ipfs/{cid} → {cid}.ipfs.dweb.link
|
||||
if newURL, ok := toSubdomainURL(r.Host, r.URL.Path, r); ok {
|
||||
newURL, err := toSubdomainURL(host, r.URL.Path, r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if newURL != "" {
|
||||
// Just to be sure single Origin can't be abused in
|
||||
// web browsers that ignored the redirect for some
|
||||
// reason, Clear-Site-Data header clears browsing
|
||||
@ -124,9 +126,9 @@ func HostnameOption() ServeOption {
|
||||
// Not a whitelisted path
|
||||
|
||||
// Try DNSLink, if it was not explicitly disabled for the hostname
|
||||
if !gw.NoDNSLink && isDNSLinkRequest(r.Context(), coreApi, r) {
|
||||
if !gw.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) {
|
||||
// rewrite path and handle as DNSLink
|
||||
r.URL.Path = "/ipns/" + stripPort(r.Host) + r.URL.Path
|
||||
r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path
|
||||
childMux.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@ -138,36 +140,68 @@ func HostnameOption() ServeOption {
|
||||
|
||||
// HTTP Host check: is this one of our subdomain-based "known gateways"?
|
||||
// Example: {cid}.ipfs.localhost, {cid}.ipfs.dweb.link
|
||||
if gw, hostname, ns, rootID, ok := knownSubdomainDetails(r.Host, knownGateways); ok {
|
||||
// Looks like we're using known subdomain gateway.
|
||||
if gw, hostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok {
|
||||
// Looks like we're using a known gateway in subdomain mode.
|
||||
|
||||
// Add gateway hostname context for linking to other root ids.
|
||||
// Example: localhost/ipfs/{cid}
|
||||
ctx := context.WithValue(r.Context(), "gw-hostname", hostname)
|
||||
|
||||
// Assemble original path prefix.
|
||||
pathPrefix := "/" + ns + "/" + rootID
|
||||
|
||||
// Does this gateway _handle_ this path?
|
||||
// Does this gateway _handle_ subdomains AND this path?
|
||||
if !(gw.UseSubdomains && hasPrefix(pathPrefix, gw.Paths...)) {
|
||||
// If not, resource does not exist, return 404
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Do we need to fix multicodec in PeerID represented as CIDv1?
|
||||
if isPeerIDNamespace(ns) {
|
||||
keyCid, err := cid.Decode(rootID)
|
||||
if err == nil && keyCid.Type() != cid.Libp2pKey {
|
||||
if newURL, ok := toSubdomainURL(hostname, pathPrefix+r.URL.Path, r); ok {
|
||||
// Redirect to CID fixed inside of toSubdomainURL()
|
||||
// Check if rootID is a valid CID
|
||||
if rootCID, err := cid.Decode(rootID); err == nil {
|
||||
// Do we need to redirect root CID to a canonical DNS representation?
|
||||
dnsCID, err := toDNSPrefix(rootID, rootCID)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(r.Host, dnsCID) {
|
||||
dnsPrefix := "/" + ns + "/" + dnsCID
|
||||
newURL, err := toSubdomainURL(hostname, dnsPrefix+r.URL.Path, r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if newURL != "" {
|
||||
// Redirect to deterministic CID to ensure CID
|
||||
// always gets the same Origin on the web
|
||||
http.Redirect(w, r, newURL, http.StatusMovedPermanently)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Do we need to fix multicodec in PeerID represented as CIDv1?
|
||||
if isPeerIDNamespace(ns) {
|
||||
if rootCID.Type() != cid.Libp2pKey {
|
||||
newURL, err := toSubdomainURL(hostname, pathPrefix+r.URL.Path, r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if newURL != "" {
|
||||
// Redirect to CID fixed inside of toSubdomainURL()
|
||||
http.Redirect(w, r, newURL, http.StatusMovedPermanently)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite the path to not use subdomains
|
||||
r.URL.Path = pathPrefix + r.URL.Path
|
||||
|
||||
// Serve path request
|
||||
childMux.ServeHTTP(w, r)
|
||||
childMux.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
// We don't have a known gateway. Fallback on DNSLink lookup
|
||||
@ -176,9 +210,9 @@ func HostnameOption() ServeOption {
|
||||
// 1. is wildcard DNSLink enabled (Gateway.NoDNSLink=false)?
|
||||
// 2. does Host header include a fully qualified domain name (FQDN)?
|
||||
// 3. does DNSLink record exist in DNS?
|
||||
if !cfg.Gateway.NoDNSLink && isDNSLinkRequest(r.Context(), coreApi, r) {
|
||||
if !cfg.Gateway.NoDNSLink && isDNSLinkRequest(r.Context(), coreAPI, host) {
|
||||
// rewrite path and handle as DNSLink
|
||||
r.URL.Path = "/ipns/" + stripPort(r.Host) + r.URL.Path
|
||||
r.URL.Path = "/ipns/" + stripPort(host) + r.URL.Path
|
||||
childMux.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@ -190,22 +224,83 @@ func HostnameOption() ServeOption {
|
||||
}
|
||||
}
|
||||
|
||||
// isKnownHostname checks Gateway.PublicGateways and returns matching
|
||||
// GatewaySpec with gracefull fallback to version without port
|
||||
func isKnownHostname(hostname string, knownGateways map[string]config.GatewaySpec) (gw config.GatewaySpec, ok bool) {
|
||||
// Try hostname (host+optional port - value from Host header as-is)
|
||||
if gw, ok := knownGateways[hostname]; ok {
|
||||
return gw, ok
|
||||
}
|
||||
// Fallback to hostname without port
|
||||
gw, ok = knownGateways[stripPort(hostname)]
|
||||
return gw, ok
|
||||
type gatewayHosts struct {
|
||||
exact map[string]*config.GatewaySpec
|
||||
wildcard []wildcardHost
|
||||
}
|
||||
|
||||
// Parses Host header and looks for a known subdomain gateway host.
|
||||
type wildcardHost struct {
|
||||
re *regexp.Regexp
|
||||
spec *config.GatewaySpec
|
||||
}
|
||||
|
||||
func prepareKnownGateways(publicGateways map[string]*config.GatewaySpec) gatewayHosts {
|
||||
var hosts gatewayHosts
|
||||
|
||||
hosts.exact = make(map[string]*config.GatewaySpec, len(publicGateways)+len(defaultKnownGateways))
|
||||
|
||||
// First, implicit defaults such as subdomain gateway on localhost
|
||||
for hostname, gw := range defaultKnownGateways {
|
||||
hosts.exact[hostname] = gw
|
||||
}
|
||||
|
||||
// Then apply values from Gateway.PublicGateways, if present in the config
|
||||
for hostname, gw := range publicGateways {
|
||||
if gw == nil {
|
||||
// Remove any implicit defaults, if present. This is useful when one
|
||||
// wants to disable subdomain gateway on localhost etc.
|
||||
delete(hosts.exact, hostname)
|
||||
continue
|
||||
}
|
||||
if strings.Contains(hostname, "*") {
|
||||
// from *.domain.tld, construct a regexp that match any direct subdomain
|
||||
// of .domain.tld.
|
||||
//
|
||||
// Regexp will be in the form of ^[^.]+\.domain.tld(?::\d+)?$
|
||||
|
||||
escaped := strings.ReplaceAll(hostname, ".", `\.`)
|
||||
regexed := strings.ReplaceAll(escaped, "*", "[^.]+")
|
||||
|
||||
re, err := regexp.Compile(fmt.Sprintf(`^%s(?::\d+)?$`, regexed))
|
||||
if err != nil {
|
||||
log.Warn("invalid wildcard gateway hostname \"%s\"", hostname)
|
||||
}
|
||||
|
||||
hosts.wildcard = append(hosts.wildcard, wildcardHost{re: re, spec: gw})
|
||||
} else {
|
||||
hosts.exact[hostname] = gw
|
||||
}
|
||||
}
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
// isKnownHostname checks Gateway.PublicGateways and returns matching
|
||||
// GatewaySpec with gracefull fallback to version without port
|
||||
func isKnownHostname(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, ok bool) {
|
||||
// Try hostname (host+optional port - value from Host header as-is)
|
||||
if gw, ok := knownGateways.exact[hostname]; ok {
|
||||
return gw, ok
|
||||
}
|
||||
// Also test without port
|
||||
if gw, ok = knownGateways.exact[stripPort(hostname)]; ok {
|
||||
return gw, ok
|
||||
}
|
||||
|
||||
// Wildcard support. Test both with and without port.
|
||||
for _, host := range knownGateways.wildcard {
|
||||
if host.re.MatchString(hostname) {
|
||||
return host.spec, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Parses Host header and looks for a known gateway matching subdomain host.
|
||||
// If found, returns GatewaySpec and subdomain components.
|
||||
// Note: hostname is host + optional port
|
||||
func knownSubdomainDetails(hostname string, knownGateways map[string]config.GatewaySpec) (gw config.GatewaySpec, knownHostname, ns, rootID string, ok bool) {
|
||||
func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *config.GatewaySpec, knownHostname, ns, rootID string, ok bool) {
|
||||
labels := strings.Split(hostname, ".")
|
||||
// Look for FQDN of a known gateway hostname.
|
||||
// Example: given "dist.ipfs.io.ipns.dweb.link":
|
||||
@ -230,14 +325,14 @@ func knownSubdomainDetails(hostname string, knownGateways map[string]config.Gate
|
||||
rootID := strings.Join(labels[:i-1], ".")
|
||||
return gw, fqdn, ns, rootID, true
|
||||
}
|
||||
// not a known subdomain gateway
|
||||
return gw, "", "", "", false
|
||||
// no match
|
||||
return nil, "", "", "", false
|
||||
}
|
||||
|
||||
// isDNSLinkRequest returns bool that indicates if request
|
||||
// should return data from content path listed in DNSLink record (if exists)
|
||||
func isDNSLinkRequest(ctx context.Context, ipfs iface.CoreAPI, r *http.Request) bool {
|
||||
fqdn := stripPort(r.Host)
|
||||
func isDNSLinkRequest(ctx context.Context, ipfs iface.CoreAPI, host string) bool {
|
||||
fqdn := stripPort(host)
|
||||
if len(fqdn) == 0 && !isd.IsDomain(fqdn) {
|
||||
return false
|
||||
}
|
||||
@ -266,18 +361,38 @@ func isPeerIDNamespace(ns string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Converts an identifier to DNS-safe representation that fits in 63 characters
|
||||
func toDNSPrefix(rootID string, rootCID cid.Cid) (prefix string, err error) {
|
||||
// Return as-is if things fit
|
||||
if len(rootID) <= dnsLabelMaxLength {
|
||||
return rootID, nil
|
||||
}
|
||||
|
||||
// Convert to Base36 and see if that helped
|
||||
rootID, err = cid.NewCidV1(rootCID.Type(), rootCID.Hash()).StringOfBase(mbase.Base36)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(rootID) <= dnsLabelMaxLength {
|
||||
return rootID, nil
|
||||
}
|
||||
|
||||
// Can't win with DNS at this point, return error
|
||||
return "", fmt.Errorf("CID incompatible with DNS label length limit of 63: %s", rootID)
|
||||
}
|
||||
|
||||
// Converts a hostname/path to a subdomain-based URL, if applicable.
|
||||
func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, ok bool) {
|
||||
func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, err error) {
|
||||
var scheme, ns, rootID, rest string
|
||||
|
||||
query := r.URL.RawQuery
|
||||
parts := strings.SplitN(path, "/", 4)
|
||||
safeRedirectURL := func(in string) (out string, ok bool) {
|
||||
safeRedirectURL := func(in string) (out string, err error) {
|
||||
safeURI, err := url.ParseRequestURI(in)
|
||||
if err != nil {
|
||||
return "", false
|
||||
return "", err
|
||||
}
|
||||
return safeURI.String(), true
|
||||
return safeURI.String(), nil
|
||||
}
|
||||
|
||||
// Support X-Forwarded-Proto if added by a reverse proxy
|
||||
@ -297,11 +412,11 @@ func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, ok
|
||||
ns = parts[1]
|
||||
rootID = parts[2]
|
||||
default:
|
||||
return "", false
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if !isSubdomainNamespace(ns) {
|
||||
return "", false
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// add prefix if query is present
|
||||
@ -320,25 +435,42 @@ func toSubdomainURL(hostname, path string, r *http.Request) (redirURL string, ok
|
||||
}
|
||||
|
||||
// If rootID is a CID, ensure it uses DNS-friendly text representation
|
||||
if rootCid, err := cid.Decode(rootID); err == nil {
|
||||
multicodec := rootCid.Type()
|
||||
if rootCID, err := cid.Decode(rootID); err == nil {
|
||||
multicodec := rootCID.Type()
|
||||
var base mbase.Encoding = mbase.Base32
|
||||
|
||||
// PeerIDs represented as CIDv1 are expected to have libp2p-key
|
||||
// multicodec (https://github.com/libp2p/specs/pull/209).
|
||||
// We ease the transition by fixing multicodec on the fly:
|
||||
// https://github.com/ipfs/go-ipfs/issues/5287#issuecomment-492163929
|
||||
if isPeerIDNamespace(ns) && multicodec != cid.Libp2pKey {
|
||||
multicodec = cid.Libp2pKey
|
||||
// Normalizations specific to /ipns/{libp2p-key}
|
||||
if isPeerIDNamespace(ns) {
|
||||
// Using Base36 for /ipns/ for consistency
|
||||
// Context: https://github.com/ipfs/go-ipfs/pull/7441#discussion_r452372828
|
||||
base = mbase.Base36
|
||||
|
||||
// PeerIDs represented as CIDv1 are expected to have libp2p-key
|
||||
// multicodec (https://github.com/libp2p/specs/pull/209).
|
||||
// We ease the transition by fixing multicodec on the fly:
|
||||
// https://github.com/ipfs/go-ipfs/issues/5287#issuecomment-492163929
|
||||
if multicodec != cid.Libp2pKey {
|
||||
multicodec = cid.Libp2pKey
|
||||
}
|
||||
}
|
||||
|
||||
// if object turns out to be a valid CID,
|
||||
// ensure text representation used in subdomain is CIDv1 in Base32
|
||||
// https://github.com/ipfs/in-web-browsers/issues/89
|
||||
rootID, err = cid.NewCidV1(multicodec, rootCid.Hash()).StringOfBase(mbase.Base32)
|
||||
// Ensure CID text representation used in subdomain is compatible
|
||||
// with the way DNS and URIs are implemented in user agents.
|
||||
//
|
||||
// 1. Switch to CIDv1 and enable case-insensitive Base encoding
|
||||
// to avoid issues when user agent force-lowercases the hostname
|
||||
// before making the request
|
||||
// (https://github.com/ipfs/in-web-browsers/issues/89)
|
||||
rootCID = cid.NewCidV1(multicodec, rootCID.Hash())
|
||||
rootID, err = rootCID.StringOfBase(base)
|
||||
if err != nil {
|
||||
// should not error, but if it does, its clealy not possible to
|
||||
// produce a subdomain URL
|
||||
return "", false
|
||||
return "", err
|
||||
}
|
||||
// 2. Make sure CID fits in a DNS label, adjust encoding if needed
|
||||
// (https://github.com/ipfs/go-ipfs/issues/7318)
|
||||
rootID, err = toDNSPrefix(rootID, rootCID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package corehttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
config "github.com/ipfs/go-ipfs-config"
|
||||
)
|
||||
|
||||
@ -15,23 +17,26 @@ func TestToSubdomainURL(t *testing.T) {
|
||||
path string
|
||||
// out:
|
||||
url string
|
||||
ok bool
|
||||
err error
|
||||
}{
|
||||
// DNSLink
|
||||
{"localhost", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost/", true},
|
||||
{"localhost", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost/", nil},
|
||||
// Hostname with port
|
||||
{"localhost:8080", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost:8080/", true},
|
||||
{"localhost:8080", "/ipns/dnslink.io", "http://dnslink.io.ipns.localhost:8080/", nil},
|
||||
// CIDv0 → CIDv1base32
|
||||
{"localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/", true},
|
||||
{"localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.localhost/", nil},
|
||||
// CIDv1 with long sha512
|
||||
{"localhost", "/ipfs/bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")},
|
||||
// PeerID as CIDv1 needs to have libp2p-key multicodec
|
||||
{"localhost", "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://bafzbeieqhtl2l3mrszjnhv6hf2iloiitsx7mexiolcnywnbcrzkqxwslja.ipns.localhost/", true},
|
||||
{"localhost", "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://bafzbeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm.ipns.localhost/", true},
|
||||
// PeerID: ed25519+identity multihash
|
||||
{"localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://bafzaajaiaejcat4yhiwnr2qz73mtu6vrnj2krxlpfoa3wo2pllfi37quorgwh2jw.ipns.localhost/", true},
|
||||
{"localhost", "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://k2k4r8n0flx3ra0y5dr8fmyvwbzy3eiztmtq6th694k5a3rznayp3e4o.ipns.localhost/", nil},
|
||||
{"localhost", "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://k2k4r8l9ja7hkzynavdqup76ou46tnvuaqegbd04a4o1mpbsey0meucb.ipns.localhost/", nil},
|
||||
// PeerID: ed25519+identity multihash → CIDv1Base36
|
||||
{"localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna.ipns.localhost/", nil},
|
||||
{"sub.localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.sub.localhost/", nil},
|
||||
} {
|
||||
url, ok := toSubdomainURL(test.hostname, test.path, r)
|
||||
if ok != test.ok || url != test.url {
|
||||
t.Errorf("(%s, %s) returned (%s, %t), expected (%s, %t)", test.hostname, test.path, url, ok, test.url, ok)
|
||||
url, err := toSubdomainURL(test.hostname, test.path, r)
|
||||
if url != test.url || !equalError(err, test.err) {
|
||||
t.Errorf("(%s, %s) returned (%s, %v), expected (%s, %v)", test.hostname, test.path, url, err, test.url, test.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,61 +80,98 @@ func TestPortStripping(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestDNSPrefix(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
out string
|
||||
err error
|
||||
}{
|
||||
// <= 63
|
||||
{"QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", nil},
|
||||
{"bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", nil},
|
||||
// > 63
|
||||
// PeerID: ed25519+identity multihash → CIDv1Base36
|
||||
{"bafzaajaiaejca4syrpdu6gdx4wsdnokxkprgzxf4wrstuc34gxw5k5jrag2so5gk", "k51qzi5uqu5dj16qyiq0tajolkojyl9qdkr254920wxv7ghtuwcz593tp69z9m", nil},
|
||||
// CIDv1 with long sha512 → error
|
||||
{"bafkrgqe3ohjcjplc6n4f3fwunlj6upltggn7xqujbsvnvyw764srszz4u4rshq6ztos4chl4plgg4ffyyxnayrtdi5oc4xb2332g645433aeg", "", errors.New("CID incompatible with DNS label length limit of 63: kf1siqrebi3vir8sab33hu5vcy008djegvay6atmz91ojesyjs8lx350b7y7i1nvyw2haytfukfyu2f2x4tocdrfa0zgij6p4zpl4u5oj")},
|
||||
} {
|
||||
inCID, _ := cid.Decode(test.in)
|
||||
out, err := toDNSPrefix(test.in, inCID)
|
||||
if out != test.out || !equalError(err, test.err) {
|
||||
t.Errorf("(%s): returned (%s, %v) expected (%s, %v)", test.in, out, err, test.out, test.err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestKnownSubdomainDetails(t *testing.T) {
|
||||
gwSpec := config.GatewaySpec{
|
||||
UseSubdomains: true,
|
||||
}
|
||||
knownGateways := map[string]config.GatewaySpec{
|
||||
"localhost": gwSpec,
|
||||
"dweb.link": gwSpec,
|
||||
"dweb.ipfs.pvt.k12.ma.us": gwSpec, // note the sneaky ".ipfs." ;-)
|
||||
}
|
||||
gwLocalhost := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true}
|
||||
gwDweb := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true}
|
||||
gwLong := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true}
|
||||
gwWildcard1 := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true}
|
||||
gwWildcard2 := &config.GatewaySpec{Paths: []string{"/ipfs", "/ipns", "/api"}, UseSubdomains: true}
|
||||
|
||||
knownGateways := prepareKnownGateways(map[string]*config.GatewaySpec{
|
||||
"localhost": gwLocalhost,
|
||||
"dweb.link": gwDweb,
|
||||
"dweb.ipfs.pvt.k12.ma.us": gwLong, // note the sneaky ".ipfs." ;-)
|
||||
"*.wildcard1.tld": gwWildcard1,
|
||||
"*.*.wildcard2.tld": gwWildcard2,
|
||||
})
|
||||
|
||||
for _, test := range []struct {
|
||||
// in:
|
||||
hostHeader string
|
||||
// out:
|
||||
gw *config.GatewaySpec
|
||||
hostname string
|
||||
ns string
|
||||
rootID string
|
||||
ok bool
|
||||
}{
|
||||
// no subdomain
|
||||
{"127.0.0.1:8080", "", "", "", false},
|
||||
{"[::1]:8080", "", "", "", false},
|
||||
{"hey.look.example.com", "", "", "", false},
|
||||
{"dweb.link", "", "", "", false},
|
||||
{"127.0.0.1:8080", nil, "", "", "", false},
|
||||
{"[::1]:8080", nil, "", "", "", false},
|
||||
{"hey.look.example.com", nil, "", "", "", false},
|
||||
{"dweb.link", nil, "", "", "", false},
|
||||
// malformed Host header
|
||||
{".....dweb.link", "", "", "", false},
|
||||
{"link", "", "", "", false},
|
||||
{"8080:dweb.link", "", "", "", false},
|
||||
{" ", "", "", "", false},
|
||||
{"", "", "", "", false},
|
||||
{".....dweb.link", nil, "", "", "", false},
|
||||
{"link", nil, "", "", "", false},
|
||||
{"8080:dweb.link", nil, "", "", "", false},
|
||||
{" ", nil, "", "", "", false},
|
||||
{"", nil, "", "", "", false},
|
||||
// unknown gateway host
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.unknown.example.com", "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.unknown.example.com", nil, "", "", "", false},
|
||||
// cid in subdomain, known gateway
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.localhost:8080", "localhost:8080", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.link", "dweb.link", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.localhost:8080", gwLocalhost, "localhost:8080", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.link", gwDweb, "dweb.link", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
// capture everything before .ipfs.
|
||||
{"foo.bar.boo-buzz.ipfs.dweb.link", "dweb.link", "ipfs", "foo.bar.boo-buzz", true},
|
||||
{"foo.bar.boo-buzz.ipfs.dweb.link", gwDweb, "dweb.link", "ipfs", "foo.bar.boo-buzz", true},
|
||||
// ipns
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.localhost:8080", "localhost:8080", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.link", "dweb.link", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.link", gwDweb, "dweb.link", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
// edge case check: public gateway under long TLD (see: https://publicsuffix.org)
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
// dnslink in subdomain
|
||||
{"en.wikipedia-on-ipfs.org.ipns.localhost:8080", "localhost:8080", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
{"en.wikipedia-on-ipfs.org.ipns.localhost", "localhost", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
{"dist.ipfs.io.ipns.localhost:8080", "localhost:8080", "ipns", "dist.ipfs.io", true},
|
||||
{"en.wikipedia-on-ipfs.org.ipns.dweb.link", "dweb.link", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
{"en.wikipedia-on-ipfs.org.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
{"en.wikipedia-on-ipfs.org.ipns.localhost", gwLocalhost, "localhost", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
{"dist.ipfs.io.ipns.localhost:8080", gwLocalhost, "localhost:8080", "ipns", "dist.ipfs.io", true},
|
||||
{"en.wikipedia-on-ipfs.org.ipns.dweb.link", gwDweb, "dweb.link", "ipns", "en.wikipedia-on-ipfs.org", true},
|
||||
// edge case check: public gateway under long TLD (see: https://publicsuffix.org)
|
||||
{"foo.dweb.ipfs.pvt.k12.ma.us", "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
{"foo.dweb.ipfs.pvt.k12.ma.us", nil, "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju.ipns.dweb.ipfs.pvt.k12.ma.us", gwLong, "dweb.ipfs.pvt.k12.ma.us", "ipns", "bafzbeihe35nmjqar22thmxsnlsgxppd66pseq6tscs4mo25y55juhh6bju", true},
|
||||
// other namespaces
|
||||
{"api.localhost", "", "", "", false},
|
||||
{"peerid.p2p.localhost", "localhost", "p2p", "peerid", true},
|
||||
{"api.localhost", nil, "", "", "", false},
|
||||
{"peerid.p2p.localhost", gwLocalhost, "localhost", "p2p", "peerid", true},
|
||||
// wildcards
|
||||
{"wildcard1.tld", nil, "", "", "", false},
|
||||
{".wildcard1.tld", nil, "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.wildcard1.tld", nil, "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub.wildcard1.tld", gwWildcard1, "sub.wildcard1.tld", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub1.sub2.wildcard1.tld", nil, "", "", "", false},
|
||||
{"bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am.ipfs.sub1.sub2.wildcard2.tld", gwWildcard2, "sub1.sub2.wildcard2.tld", "ipfs", "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am", true},
|
||||
} {
|
||||
gw, hostname, ns, rootID, ok := knownSubdomainDetails(test.hostHeader, knownGateways)
|
||||
if ok != test.ok {
|
||||
@ -144,9 +186,13 @@ func TestKnownSubdomainDetails(t *testing.T) {
|
||||
if hostname != test.hostname {
|
||||
t.Errorf("knownSubdomainDetails(%s): hostname is '%s', expected '%s'", test.hostHeader, hostname, test.hostname)
|
||||
}
|
||||
if ok && gw.UseSubdomains != gwSpec.UseSubdomains {
|
||||
t.Errorf("knownSubdomainDetails(%s): gw is %+v, expected %+v", test.hostHeader, gw, gwSpec)
|
||||
if gw != test.gw {
|
||||
t.Errorf("knownSubdomainDetails(%s): gw is %+v, expected %+v", test.hostHeader, gw, test.gw)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func equalError(a, b error) bool {
|
||||
return (a == nil && b == nil) || (a != nil && b != nil && a.Error() == b.Error())
|
||||
}
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
package corehttp
|
||||
|
||||
// TODO: move to IPNS
|
||||
const WebUIPath = "/ipfs/bafybeigkbbjnltbd4ewfj7elajsbnjwinyk6tiilczkqsibf3o7dcr6nn4" // v2.9.0
|
||||
const WebUIPath = "/ipfs/bafybeianwe4vy7sprht5sm3hshvxjeqhwcmvbzq73u55sdhqngmohkjgs4" // v2.11.1
|
||||
|
||||
// this is a list of all past webUI paths.
|
||||
var WebUIPaths = []string{
|
||||
WebUIPath,
|
||||
"/ipfs/bafybeicitin4p7ggmyjaubqpi3xwnagrwarsy6hiihraafk5rcrxqxju6m",
|
||||
"/ipfs/bafybeihpetclqvwb4qnmumvcn7nh4pxrtugrlpw4jgjpqicdxsv7opdm6e",
|
||||
"/ipfs/bafybeibnnxd4etu4tq5fuhu3z5p4rfu3buabfkeyr3o3s4h6wtesvvw6mu",
|
||||
"/ipfs/bafybeid6luolenf4fcsuaw5rgdwpqbyerce4x3mi3hxfdtp5pwco7h7qyq",
|
||||
"/ipfs/bafybeigkbbjnltbd4ewfj7elajsbnjwinyk6tiilczkqsibf3o7dcr6nn4",
|
||||
"/ipfs/bafybeicp23nbcxtt2k2twyfivcbrc6kr3l5lnaiv3ozvwbemtrb7v52r6i",
|
||||
"/ipfs/bafybeidatpz2hli6fgu3zul5woi27ujesdf5o5a7bu622qj6ugharciwjq",
|
||||
"/ipfs/QmfQkD8pBSBCBxWEwFSu4XaDVSWK6bjnNuaWZjMyQbyDub",
|
||||
|
||||
@ -3,10 +3,9 @@ package node
|
||||
import (
|
||||
"github.com/ipfs/go-graphsync"
|
||||
gsimpl "github.com/ipfs/go-graphsync/impl"
|
||||
"github.com/ipfs/go-graphsync/ipldbridge"
|
||||
"github.com/ipfs/go-graphsync/network"
|
||||
"github.com/ipfs/go-graphsync/storeutil"
|
||||
"github.com/ipfs/go-ipfs-blockstore"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
libp2p "github.com/libp2p/go-libp2p-core"
|
||||
"go.uber.org/fx"
|
||||
|
||||
@ -18,9 +17,7 @@ func Graphsync(lc fx.Lifecycle, mctx helpers.MetricsCtx, host libp2p.Host, bs bl
|
||||
ctx := helpers.LifecycleCtx(mctx, lc)
|
||||
|
||||
network := network.NewFromLibp2pHost(host)
|
||||
ipldBridge := ipldbridge.NewIPLDBridge()
|
||||
return gsimpl.New(ctx,
|
||||
network, ipldBridge,
|
||||
return gsimpl.New(ctx, network,
|
||||
storeutil.LoaderForBlockstore(bs),
|
||||
storeutil.StorerForBlockstore(bs),
|
||||
)
|
||||
|
||||
@ -17,6 +17,10 @@ func FloodSub(pubsubOptions ...pubsub.Option) interface{} {
|
||||
|
||||
func GossipSub(pubsubOptions ...pubsub.Option) interface{} {
|
||||
return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, disc discovery.Discovery) (service *pubsub.PubSub, err error) {
|
||||
return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, append(pubsubOptions, pubsub.WithDiscovery(disc))...)
|
||||
return pubsub.NewGossipSub(helpers.LifecycleCtx(mctx, lc), host, append(
|
||||
pubsubOptions,
|
||||
pubsub.WithDiscovery(disc),
|
||||
pubsub.WithFloodPublish(true))...,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,11 +37,12 @@ func constructDHTRouting(mode dht.ModeOpt) func(
|
||||
) (routing.Routing, error) {
|
||||
return dual.New(
|
||||
ctx, host,
|
||||
dht.Concurrency(10),
|
||||
dht.Mode(mode),
|
||||
dht.Datastore(dstore),
|
||||
dht.Validator(validator),
|
||||
dht.BootstrapPeers(bootstrapPeers...),
|
||||
dual.DHTOption(
|
||||
dht.Concurrency(10),
|
||||
dht.Mode(mode),
|
||||
dht.Datastore(dstore),
|
||||
dht.Validator(validator)),
|
||||
dual.WanDHTOption(dht.BootstrapPeers(bootstrapPeers...)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ func Security(enabled bool, tptConfig config.Transports) interface{} {
|
||||
opt: libp2p.Security(tls.ID, tls.New),
|
||||
}, {
|
||||
priority: tptConfig.Security.SECIO,
|
||||
defaultPriority: 200,
|
||||
defaultPriority: config.Disabled,
|
||||
opt: libp2p.Security(secio.ID, secio.New),
|
||||
}, {
|
||||
priority: tptConfig.Security.Noise,
|
||||
|
||||
@ -9,10 +9,18 @@ import (
|
||||
libp2pquic "github.com/libp2p/go-libp2p-quic-transport"
|
||||
tcp "github.com/libp2p/go-tcp-transport"
|
||||
websocket "github.com/libp2p/go-ws-transport"
|
||||
quic "github.com/lucas-clemente/quic-go"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
// See https://github.com/ipfs/go-ipfs/issues/7526 and
|
||||
// https://github.com/lucas-clemente/quic-go/releases/tag/v0.17.3.
|
||||
// TODO: remove this once the network has upgraded to > v0.6.0.
|
||||
func init() {
|
||||
quic.RetireBugBackwardsCompatibilityMode = true
|
||||
}
|
||||
|
||||
func Transports(tptConfig config.Transports) interface{} {
|
||||
return func(pnet struct {
|
||||
fx.In
|
||||
|
||||
@ -22,6 +22,7 @@ We will ask early testers to participate at two points in the process:
|
||||
|
||||
## Who has signed up?
|
||||
|
||||
- [ ] pacman.store ([@RubenKelevra](https://github.com/RubenKelevra))
|
||||
- [ ] Infura (@MichaelMure)
|
||||
- [ ] Textile (@sanderpick)
|
||||
- [ ] Pinata (@obo20)
|
||||
|
||||
@ -24,8 +24,8 @@ We're happy to announce go-ipfs X.Y.Z, bla bla...
|
||||
|
||||
For each RC published in each stage:
|
||||
|
||||
- version string in `version.go` has been updated
|
||||
- tag commit with vX.Y.Z-rcN
|
||||
- version string in `version.go` has been updated (in the `release-vX.Y.Z` branch).
|
||||
- tag commit with `vX.Y.Z-rcN`
|
||||
- upload to dist.ipfs.io
|
||||
1. Build: https://github.com/ipfs/distributions#usage.
|
||||
2. Pin the resulting release.
|
||||
@ -39,7 +39,9 @@ For each RC published in each stage:
|
||||
Checklist:
|
||||
|
||||
- [ ] **Stage 0 - Automated Testing**
|
||||
- [ ] Feature freeze. If any "non-trivial" changes (see the footnotes of [docs/releases.md](https://github.com/ipfs/go-ipfs/tree/master/docs/releases.md) for a definition) get added to the release, uncheck all the checkboxes and return to this stage.
|
||||
- [ ] Fork a new branch (`release-vX.Y.Z`) from `master` and make any further release related changes to this branch. If any "non-trivial" changes (see the footnotes of [docs/releases.md](https://github.com/ipfs/go-ipfs/tree/master/docs/releases.md) for a definition) get added to the release, uncheck all the checkboxes and return to this stage.
|
||||
- [ ] Follow the RC release process to cut the first RC.
|
||||
- [ ] Bump the version in `version.go` in the `master` branch to `vX.(Y+1).0-dev`.
|
||||
- [ ] Automated Testing (already tested in CI) - Ensure that all tests are passing, this includes:
|
||||
- [ ] unit, sharness, cross-build, etc (`make test`)
|
||||
- [ ] lint (`make test_go_lint`)
|
||||
@ -79,9 +81,9 @@ Checklist:
|
||||
- [ ] IRC
|
||||
- [ ] **Stage 4 - Release**
|
||||
- [ ] Final preparation
|
||||
- [ ] Verify that version string in [`version.go`](https://github.com/ipfs/go-ipfs/tree/master/version.go) has been updated
|
||||
- [ ] tag commit with vX.Y.Z
|
||||
- [ ] update release branch to point to release commit (`git merge vX.Y.Z`).
|
||||
- [ ] Verify that version string in [`version.go`](https://github.com/ipfs/go-ipfs/tree/master/version.go) has been updated.
|
||||
- [ ] Merge `release-vX.Y.Z` into the `release` branch.
|
||||
- [ ] Tag this merge commit (on the `release` branch) with `vX.Y.Z`.
|
||||
- [ ] Release published
|
||||
- [ ] to [dist.ipfs.io](https://dist.ipfs.io)
|
||||
- [ ] to [npm-go-ipfs](https://github.com/ipfs/npm-go-ipfs)
|
||||
@ -98,7 +100,7 @@ Checklist:
|
||||
- [ ] [discuss.ipfs.io](https://discuss.ipfs.io/c/announcements)
|
||||
- [ ] Announce it on the [IPFS Users Mailing List](https://groups.google.com/forum/#!forum/ipfs-users)
|
||||
- [ ] **Post-Release**
|
||||
- [ ] Bump the version in `version.go` to `vX.(Y+1).0-dev`.
|
||||
- [ ] Merge the `release` branch back into `master`, ignoring the changes to `version.go` (keep the `-dev` version from master).
|
||||
- [ ] Create an issue using this release issue template for the _next_ release.
|
||||
- [ ] Make sure any last-minute changelog updates from the blog post make it back into the CHANGELOG.
|
||||
|
||||
|
||||
@ -179,8 +179,8 @@ does (e.g, `"1d2h4m40.01s"`).
|
||||
- [`Pubsub`](#pubsub)
|
||||
- [`Pubsub.Router`](#pubsubrouter)
|
||||
- [`Pubsub.DisableSigning`](#pubsubdisablesigning)
|
||||
- [`Peering`](#peering)
|
||||
- [`Peering.Peers`](#peeringpeers)
|
||||
- [`Peering`](#peering)
|
||||
- [`Peering.Peers`](#peeringpeers)
|
||||
- [`Reprovider`](#reprovider)
|
||||
- [`Reprovider.Interval`](#reproviderinterval)
|
||||
- [`Reprovider.Strategy`](#reproviderstrategy)
|
||||
@ -260,7 +260,7 @@ Default:
|
||||
[
|
||||
"/ip4/0.0.0.0/tcp/4001",
|
||||
"/ip6/::/tcp/4001",
|
||||
"/ip6/0.0.0.0/udp/4001/quic",
|
||||
"/ip4/0.0.0.0/udp/4001/quic",
|
||||
"/ip6/::/udp/4001/quic"
|
||||
]
|
||||
```
|
||||
@ -586,6 +586,12 @@ Type: `array[string]`
|
||||
|
||||
`PublicGateways` is a dictionary for defining gateway behavior on specified hostnames.
|
||||
|
||||
Hostnames can optionally be defined with one or more wildcards.
|
||||
|
||||
Examples:
|
||||
- `*.example.com` will match requests to `http://foo.example.com/ipfs/*` or `http://{cid}.ipfs.bar.example.com/*`.
|
||||
- `foo-*.example.com` will match requests to `http://foo-bar.example.com/ipfs/*` or `http://{cid}.ipfs.foo-xyz.example.com/*`.
|
||||
|
||||
#### `Gateway.PublicGateways: Paths`
|
||||
|
||||
Array of paths that should be exposed on the hostname.
|
||||
@ -614,7 +620,7 @@ Type: `array[string]`
|
||||
A boolean to configure whether the gateway at the hostname provides [Origin isolation](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
|
||||
between content roots.
|
||||
|
||||
- `true` - enables [subdomain gateway](#https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://*.{hostname}/`
|
||||
- `true` - enables [subdomain gateway](#https://docs.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://*.{hostname}/`
|
||||
- **Requires whitelist:** make sure respective `Paths` are set.
|
||||
For example, `Paths: ["/ipfs", "/ipns"]` are required for `http://{cid}.ipfs.{hostname}` and `http://{foo}.ipns.{hostname}` to work:
|
||||
```json
|
||||
@ -630,7 +636,7 @@ between content roots.
|
||||
- **Backward-compatible:** requests for content paths such as `http://{hostname}/ipfs/{cid}` produce redirect to `http://{cid}.ipfs.{hostname}`
|
||||
- **API:** if `/api` is on the `Paths` whitelist, `http://{hostname}/api/{cmd}` produces redirect to `http://api.{hostname}/api/{cmd}`
|
||||
|
||||
- `false` - enables [path gateway](https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#path-gateway) at `http://{hostname}/*`
|
||||
- `false` - enables [path gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#path-gateway) at `http://{hostname}/*`
|
||||
- Example:
|
||||
```json
|
||||
"Gateway": {
|
||||
@ -687,7 +693,7 @@ $ ipfs config --json Gateway.PublicGateways '{"localhost": null }'
|
||||
|
||||
Below is a list of the most common public gateway setups.
|
||||
|
||||
* Public [subdomain gateway](https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://{cid}.ipfs.dweb.link` (each content root gets its own Origin)
|
||||
* Public [subdomain gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://{cid}.ipfs.dweb.link` (each content root gets its own Origin)
|
||||
```console
|
||||
$ ipfs config --json Gateway.PublicGateways '{
|
||||
"dweb.link": {
|
||||
@ -698,10 +704,13 @@ Below is a list of the most common public gateway setups.
|
||||
```
|
||||
**Note I:** this enables automatic redirects from content paths to subdomains:
|
||||
`http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.dweb.link`
|
||||
**Note II:** if you run go-ipfs behind a reverse proxy that provides TLS, make it adds a `X-Forwarded-Proto: https` HTTP header to ensure users are redirected to `https://`, not `http://`. The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.:
|
||||
`https://dweb.link/ipfs/{cid}` → `https://{cid}.ipfs.dweb.link`
|
||||
**Note II:** if you run go-ipfs behind a reverse proxy that provides TLS, make it add a `X-Forwarded-Proto: https` HTTP header to ensure users are redirected to `https://`, not `http://`. The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.:
|
||||
`http://dweb.link/ipfs/{cid}` → `https://{cid}.ipfs.dweb.link`
|
||||
**Note III:** we also support `X-Forwarded-Proto: example.com` if you want to override subdomain gateway host from the original request:
|
||||
`http://dweb.link/ipfs/{cid}` → `http://{cid}.ipfs.example.com`
|
||||
|
||||
|
||||
* Public [path gateway](https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#path-gateway) at `http://ipfs.io/ipfs/{cid}` (no Origin separation)
|
||||
* Public [path gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#path-gateway) at `http://ipfs.io/ipfs/{cid}` (no Origin separation)
|
||||
```console
|
||||
$ ipfs config --json Gateway.PublicGateways '{
|
||||
"ipfs.io": {
|
||||
@ -717,7 +726,7 @@ Below is a list of the most common public gateway setups.
|
||||
```
|
||||
* Note that `NoDNSLink: false` is the default (it works out of the box unless set to `true` manually)
|
||||
|
||||
* Hardened, site-specific [DNSLink gateway](https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#dnslink-gateway).
|
||||
* Hardened, site-specific [DNSLink gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#dnslink-gateway).
|
||||
Disable fetching of remote data (`NoFetch: true`)
|
||||
and resolving DNSLink at unknown hostnames (`NoDNSLink: true`).
|
||||
Then, enable DNSLink gateway only for the specific hostname (for which data
|
||||
@ -837,7 +846,7 @@ Default: `false`
|
||||
|
||||
Type: `bool`
|
||||
|
||||
### `Peering`
|
||||
## `Peering`
|
||||
|
||||
Configures the peering subsystem. The peering subsystem configures go-ipfs to
|
||||
connect to, remain connected to, and reconnect to a set of nodes. Nodes should
|
||||
@ -874,17 +883,30 @@ Peering can be asymmetric or symmetric:
|
||||
connection may flap repeatedly. Be careful when asymmetrically peering to not
|
||||
overload peers.
|
||||
|
||||
#### `Peering.Peers`
|
||||
### `Peering.Peers`
|
||||
|
||||
The set of peers with which to peer. Each entry is of the form:
|
||||
The set of peers with which to peer.
|
||||
|
||||
```js
|
||||
```json
|
||||
{
|
||||
"ID": "QmSomePeerID", # The peers ID.
|
||||
"Addrs": ["/ip4/1.2.3.4/tcp/1234"] # Known addresses for the peer. If none are specified, the DHT will be queried.
|
||||
"Peering": {
|
||||
"Peers": [
|
||||
{
|
||||
"ID": "QmPeerID1",
|
||||
"Addrs": ["/ip4/18.1.1.1/tcp/4001"]
|
||||
},
|
||||
{
|
||||
"ID": "QmPeerID2",
|
||||
"Addrs": ["/ip4/18.1.1.2/tcp/4001", "/ip4/18.1.1.2/udp/4001/quic"]
|
||||
}
|
||||
]
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Where `ID` is the peer ID and `Addrs` is a set of known addresses for the peer. If no addresses are specified, the DHT will be queried.
|
||||
|
||||
Additional fields may be added in the future.
|
||||
|
||||
Default: empty.
|
||||
@ -1233,7 +1255,7 @@ receiver supports. When establishing an _inbound_ connection, go-ipfs will let
|
||||
the initiator choose the protocol, but will refuse to use any of the disabled
|
||||
transports.
|
||||
|
||||
Supported transports are: TLS (priority 100), SECIO (priority 200), Noise
|
||||
Supported transports are: TLS (priority 100), SECIO (Disabled: i.e. priority false), Noise
|
||||
(priority 300).
|
||||
|
||||
No default priority will ever be less than 100.
|
||||
@ -1250,12 +1272,12 @@ Type: `priority`
|
||||
|
||||
#### `Swarm.Transports.Security.SECIO`
|
||||
|
||||
[SECIO](https://github.com/libp2p/specs/tree/master/secio) is the most widely
|
||||
[SECIO](https://github.com/libp2p/specs/tree/master/secio) was the most widely
|
||||
supported IPFS & libp2p security transport. However, it is currently being
|
||||
phased out in favor of more popular and better vetted protocols like TLS and
|
||||
Noise.
|
||||
|
||||
Default: `200`
|
||||
Default: `false`
|
||||
|
||||
Type: `priority`
|
||||
|
||||
|
||||
@ -3,11 +3,13 @@ module github.com/ipfs/go-ipfs/examples/go-ipfs-as-a-library
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/ipfs/go-ipfs v0.5.0
|
||||
github.com/ipfs/go-ipfs-config v0.5.3
|
||||
github.com/ipfs/go-ipfs v0.7.0
|
||||
github.com/ipfs/go-ipfs-config v0.9.0
|
||||
github.com/ipfs/go-ipfs-files v0.0.8
|
||||
github.com/ipfs/interface-go-ipfs-core v0.2.7
|
||||
github.com/libp2p/go-libp2p-core v0.5.2
|
||||
github.com/libp2p/go-libp2p-peerstore v0.2.3
|
||||
github.com/multiformats/go-multiaddr v0.2.1
|
||||
github.com/ipfs/interface-go-ipfs-core v0.4.0
|
||||
github.com/libp2p/go-libp2p-core v0.6.0
|
||||
github.com/libp2p/go-libp2p-peerstore v0.2.6
|
||||
github.com/multiformats/go-multiaddr v0.2.2
|
||||
)
|
||||
|
||||
replace github.com/ipfs/go-ipfs => ./../../..
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
66
docs/production/reverse-proxy.md
Normal file
66
docs/production/reverse-proxy.md
Normal file
@ -0,0 +1,66 @@
|
||||
# IPFS & Reverse HTTP Proxies
|
||||
|
||||
When run in production environments, go-ipfs should generally be run behind a
|
||||
reverse HTTP proxy (usually NGINX). You may need a reverse proxy to:
|
||||
|
||||
* Load balance requests across multiple go-ipfs daemons.
|
||||
* Cache responses.
|
||||
* Buffer requests, only releasing them to go-ipfs when complete. This can help
|
||||
protect go-ipfs from the
|
||||
[slowloris](https://en.wikipedia.org/wiki/Slowloris_(computer_security)
|
||||
attack.
|
||||
* Block content.
|
||||
* Rate limit and timeout requests.
|
||||
* Apply QoS rules (e.g., prioritize traffic for certain important IPFS resources).
|
||||
|
||||
This document contains a collection of tips, tricks, and pitfalls when running a
|
||||
go-ipfs node behind a reverse HTTP proxy.
|
||||
|
||||
**WARNING:** Due to
|
||||
[nginx#1293](https://trac.nginx.org/nginx/ticket/1293)/[go-ipfs#6402](https://github.com/ipfs/go-ipfs/issues/6402),
|
||||
parts of the go-ipfs API will not work correctly behind an NGINX reverse proxy
|
||||
as go-ipfs starts sending back a response before it finishes reading the request
|
||||
body. The gateway itself is unaffected.
|
||||
|
||||
## Peering
|
||||
|
||||
Go-ipfs gateways behind a single load balancing reverse proxy should use the
|
||||
[peering](../config.md#peering) subsystem to peer with each other. That way, as
|
||||
long as one go-ipfs daemon has the content being requested, the others will be
|
||||
able to serve it.
|
||||
|
||||
# Garbage Collection
|
||||
|
||||
Gateways rarely store content permanently. However, running garbage collection
|
||||
can slow down a go-ipfs node significantly. If you've noticed this issue in
|
||||
production, consider "garbage collecting" by resetting the go-ipfs repo whenever
|
||||
you run out of space, instead of garbage collecting.
|
||||
|
||||
1. Initialize your gateways repo to some known-good state (possibly pre-seeding
|
||||
it with some content, a config, etc.).
|
||||
2. When you start running low on space, for each load-balanced go-ipfs node:
|
||||
1. Use the nginx API to set one of the upstream go-ipfs node's to "down".
|
||||
2. Wait a minute to let go-ipfs finish processing any in-progress requests
|
||||
(or the short-lived ones, at least).
|
||||
3. Take the go-ipfs node down.
|
||||
4. Rollback the go-ipfs repo to the seed state.
|
||||
5. Restart the go-ipfs daemon.
|
||||
6. Update the nginx config, removing the "down" status from the node.
|
||||
|
||||
This will effectively "garbage collect" without actually running the garbage
|
||||
collector.
|
||||
|
||||
# Content Blocking
|
||||
|
||||
TODO:
|
||||
|
||||
* Filtering requests
|
||||
* Checking the X-IPFS-Path header in responses to filter again after resolving.
|
||||
|
||||
# Subdomain Gateway
|
||||
|
||||
TODO: Reverse proxies and the subdomain gateway.
|
||||
|
||||
# Load balancing
|
||||
|
||||
TODO: discuss load balancing based on the CID versus the source IP.
|
||||
71
go.mod
71
go.mod
@ -5,34 +5,34 @@ require (
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d
|
||||
github.com/coreos/go-systemd/v22 v22.0.0
|
||||
github.com/coreos/go-systemd/v22 v22.1.0
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302
|
||||
github.com/fatih/color v1.9.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gabriel-vasile/mimetype v1.1.0
|
||||
github.com/gabriel-vasile/mimetype v1.1.1
|
||||
github.com/go-bindata/go-bindata/v3 v3.1.3
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/hashicorp/go-multierror v1.1.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/ipfs/go-bitswap v0.2.19
|
||||
github.com/ipfs/go-bitswap v0.2.20
|
||||
github.com/ipfs/go-block-format v0.0.2
|
||||
github.com/ipfs/go-blockservice v0.1.3
|
||||
github.com/ipfs/go-cid v0.0.6
|
||||
github.com/ipfs/go-cid v0.0.7
|
||||
github.com/ipfs/go-cidutil v0.0.2
|
||||
github.com/ipfs/go-datastore v0.4.4
|
||||
github.com/ipfs/go-datastore v0.4.5
|
||||
github.com/ipfs/go-detect-race v0.0.1
|
||||
github.com/ipfs/go-ds-badger v0.2.4
|
||||
github.com/ipfs/go-ds-flatfs v0.4.4
|
||||
github.com/ipfs/go-ds-flatfs v0.4.5
|
||||
github.com/ipfs/go-ds-leveldb v0.4.2
|
||||
github.com/ipfs/go-ds-measure v0.1.0
|
||||
github.com/ipfs/go-filestore v0.0.3
|
||||
github.com/ipfs/go-fs-lock v0.0.5
|
||||
github.com/ipfs/go-graphsync v0.0.5
|
||||
github.com/ipfs/go-fs-lock v0.0.6
|
||||
github.com/ipfs/go-graphsync v0.1.1
|
||||
github.com/ipfs/go-ipfs-blockstore v0.1.4
|
||||
github.com/ipfs/go-ipfs-chunker v0.0.5
|
||||
github.com/ipfs/go-ipfs-cmds v0.2.9
|
||||
github.com/ipfs/go-ipfs-config v0.8.0
|
||||
github.com/ipfs/go-ipfs-cmds v0.4.0
|
||||
github.com/ipfs/go-ipfs-config v0.9.0
|
||||
github.com/ipfs/go-ipfs-ds-help v0.1.1
|
||||
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
|
||||
github.com/ipfs/go-ipfs-exchange-offline v0.0.1
|
||||
@ -51,64 +51,61 @@ require (
|
||||
github.com/ipfs/go-metrics-interface v0.0.1
|
||||
github.com/ipfs/go-metrics-prometheus v0.0.2
|
||||
github.com/ipfs/go-mfs v0.1.2
|
||||
github.com/ipfs/go-path v0.0.7
|
||||
github.com/ipfs/go-path v0.0.8
|
||||
github.com/ipfs/go-unixfs v0.2.4
|
||||
github.com/ipfs/go-verifcid v0.0.1
|
||||
github.com/ipfs/interface-go-ipfs-core v0.3.0
|
||||
github.com/ipld/go-car v0.1.0
|
||||
github.com/ipfs/interface-go-ipfs-core v0.4.0
|
||||
github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339
|
||||
github.com/jbenet/go-is-domain v1.0.5
|
||||
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0
|
||||
github.com/jbenet/goprocess v0.1.4
|
||||
github.com/libp2p/go-libp2p v0.9.6
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.3
|
||||
github.com/libp2p/go-libp2p v0.11.0
|
||||
github.com/libp2p/go-libp2p-circuit v0.3.1
|
||||
github.com/libp2p/go-libp2p-connmgr v0.2.4
|
||||
github.com/libp2p/go-libp2p-core v0.5.7
|
||||
github.com/libp2p/go-libp2p-discovery v0.4.0
|
||||
github.com/libp2p/go-libp2p-core v0.6.1
|
||||
github.com/libp2p/go-libp2p-discovery v0.5.0
|
||||
github.com/libp2p/go-libp2p-http v0.1.5
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.8.2
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.2
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.9.0
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.7
|
||||
github.com/libp2p/go-libp2p-loggables v0.1.0
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.3
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.4
|
||||
github.com/libp2p/go-libp2p-noise v0.1.1
|
||||
github.com/libp2p/go-libp2p-peerstore v0.2.6
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.1
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.0
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.6.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.5
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.2
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0
|
||||
github.com/libp2p/go-libp2p-record v0.1.3
|
||||
github.com/libp2p/go-libp2p-routing-helpers v0.2.3
|
||||
github.com/libp2p/go-libp2p-secio v0.2.2
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.6
|
||||
github.com/libp2p/go-libp2p-testing v0.1.1
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.8
|
||||
github.com/libp2p/go-libp2p-testing v0.2.0
|
||||
github.com/libp2p/go-libp2p-tls v0.1.3
|
||||
github.com/libp2p/go-libp2p-yamux v0.2.8
|
||||
github.com/libp2p/go-socket-activation v0.0.2
|
||||
github.com/libp2p/go-tcp-transport v0.2.0
|
||||
github.com/libp2p/go-tcp-transport v0.2.1
|
||||
github.com/libp2p/go-ws-transport v0.3.1
|
||||
github.com/lucas-clemente/quic-go v0.18.0
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/miekg/dns v1.1.29 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mr-tron/base58 v1.1.3
|
||||
github.com/multiformats/go-multiaddr v0.2.2
|
||||
github.com/multiformats/go-multiaddr v0.3.1
|
||||
github.com/multiformats/go-multiaddr-dns v0.2.0
|
||||
github.com/multiformats/go-multiaddr-net v0.1.5
|
||||
github.com/multiformats/go-multibase v0.0.3
|
||||
github.com/multiformats/go-multihash v0.0.13
|
||||
github.com/opentracing/opentracing-go v1.1.0
|
||||
github.com/multiformats/go-multihash v0.0.14
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.6.0
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc
|
||||
github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1
|
||||
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
|
||||
github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c
|
||||
go.uber.org/fx v1.12.0
|
||||
go.uber.org/fx v1.13.1
|
||||
go.uber.org/zap v1.15.0
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
|
||||
golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28
|
||||
)
|
||||
|
||||
265
go.sum
265
go.sum
@ -39,8 +39,6 @@ github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3o
|
||||
github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=
|
||||
github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY=
|
||||
github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@ -49,10 +47,10 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5
|
||||
github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/benbjohnson/clock v1.0.1 h1:lVM1R/o5khtrr7t3qAr+sS6uagZOP+7iprc7gS3V9CE=
|
||||
github.com/benbjohnson/clock v1.0.1/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.0.2 h1:Z0CN0Yb4ig9sGPXkvAQcGJfnrrMQ5QYLCMPRi9iD7YE=
|
||||
github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@ -65,7 +63,6 @@ github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d/go.mod h1:Jbj8eK
|
||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
|
||||
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
||||
@ -102,6 +99,8 @@ github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
|
||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
|
||||
@ -113,8 +112,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 h1:6xT9KW8zLC5IlbaIF5Q7JNieBoACT7iW0YTxQHR0in0=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc=
|
||||
github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
|
||||
github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
|
||||
github.com/dgraph-io/badger v1.6.0-rc1 h1:JphPpoBZJ3WHha133BGYlQqltSGIhV+VsEID0++nN9A=
|
||||
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||
@ -147,8 +144,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gabriel-vasile/mimetype v1.1.0 h1:+ahX+MvQPFve4kO9Qjjxf3j49i0ACdV236kJlOCRAnU=
|
||||
github.com/gabriel-vasile/mimetype v1.1.0/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
|
||||
github.com/gabriel-vasile/mimetype v1.1.1 h1:qbN9MPuRf3bstHu9zkI9jDWNfH//9+9kHxr9oRBBBOA=
|
||||
github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI=
|
||||
@ -173,6 +170,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -183,6 +181,8 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -195,6 +195,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@ -211,6 +213,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
|
||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
|
||||
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@ -225,6 +229,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
@ -235,6 +241,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg
|
||||
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
|
||||
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
|
||||
github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE=
|
||||
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY=
|
||||
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||
@ -261,8 +269,8 @@ github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSA
|
||||
github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs=
|
||||
github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps=
|
||||
github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM=
|
||||
github.com/ipfs/go-bitswap v0.2.19 h1:EhgRz8gqWQIBADY9gpqJOrfs5E1MtVfQFy1Vq8Z+Fq8=
|
||||
github.com/ipfs/go-bitswap v0.2.19/go.mod h1:C7TwBgHnu89Q8sHsTJP7IhUqF9XYLe71P4tT5adgmYo=
|
||||
github.com/ipfs/go-bitswap v0.2.20 h1:Zfi5jDUoqxDThORUznqdeL77DdGniAzlccNJ4vr+Itc=
|
||||
github.com/ipfs/go-bitswap v0.2.20/go.mod h1:C7TwBgHnu89Q8sHsTJP7IhUqF9XYLe71P4tT5adgmYo=
|
||||
github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc=
|
||||
github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
@ -284,6 +292,8 @@ github.com/ipfs/go-cid v0.0.5 h1:o0Ix8e/ql7Zb5UVUJEUfjsWCIY8t48++9lR8qi6oiJU=
|
||||
github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog=
|
||||
github.com/ipfs/go-cid v0.0.6 h1:go0y+GcDOGeJIV01FeBsta4FHngoA4Wz7KMeLkXAhMs=
|
||||
github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY=
|
||||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
github.com/ipfs/go-cidutil v0.0.2 h1:CNOboQf1t7Qp0nuNh8QMmhJs0+Q//bRL1axtCnIB1Yo=
|
||||
github.com/ipfs/go-cidutil v0.0.2/go.mod h1:ewllrvrxG6AMYStla3GD7Cqn+XYSLqjK0vc+086tB6s=
|
||||
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||
@ -299,6 +309,8 @@ github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13X
|
||||
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||
github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8=
|
||||
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||
github.com/ipfs/go-datastore v0.4.5 h1:cwOUcGMLdLPWgu3SlrCckCMznaGADbPqE0r8h768/Dg=
|
||||
github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8=
|
||||
@ -312,8 +324,8 @@ github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6Qxxkod
|
||||
github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk=
|
||||
github.com/ipfs/go-ds-badger v0.2.4 h1:UPGB0y7luFHk+mY/tUZrif/272M8o+hFsW+avLUeWrM=
|
||||
github.com/ipfs/go-ds-badger v0.2.4/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk=
|
||||
github.com/ipfs/go-ds-flatfs v0.4.4 h1:DmGZ4qOYQLNgu8Mltuz1DtUHpm+BjWMcVN3F3H3VJzQ=
|
||||
github.com/ipfs/go-ds-flatfs v0.4.4/go.mod h1:e4TesLyZoA8k1gV/yCuBTnt2PJtypn4XUlB5n8KQMZY=
|
||||
github.com/ipfs/go-ds-flatfs v0.4.5 h1:4QceuKEbH+HVZ2ZommstJMi3o3II+dWS3IhLaD7IGHs=
|
||||
github.com/ipfs/go-ds-flatfs v0.4.5/go.mod h1:e4TesLyZoA8k1gV/yCuBTnt2PJtypn4XUlB5n8KQMZY=
|
||||
github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc=
|
||||
github.com/ipfs/go-ds-leveldb v0.1.0 h1:OsCuIIh1LMTk4WIQ1UJH7e3j01qlOP+KWVhNS6lBDZY=
|
||||
github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8=
|
||||
@ -325,10 +337,10 @@ github.com/ipfs/go-ds-measure v0.1.0 h1:vE4TyY4aeLeVgnnPBC5QzKIjKrqzha0NCujTfgvV
|
||||
github.com/ipfs/go-ds-measure v0.1.0/go.mod h1:1nDiFrhLlwArTME1Ees2XaBOl49OoCgd2A3f8EchMSY=
|
||||
github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9EwE=
|
||||
github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE=
|
||||
github.com/ipfs/go-fs-lock v0.0.5 h1:nlKE27N7hlvsTXT3CSDkM6KRqgXpnaDjvyCHjAiZyK8=
|
||||
github.com/ipfs/go-fs-lock v0.0.5/go.mod h1:fq8gXFwbi1on9KScveHuVJ2wjuqo5jaDgCtZdKLuCO8=
|
||||
github.com/ipfs/go-graphsync v0.0.5 h1:5U9iC58JgYfUSZI55oRXe22Cj6Ln0Xjd5VF4Eoo3foc=
|
||||
github.com/ipfs/go-graphsync v0.0.5/go.mod h1:SGKa4rVgCCz3KDNqe38wLEDYFa/PUF6w/ertGSQk33I=
|
||||
github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0=
|
||||
github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM=
|
||||
github.com/ipfs/go-graphsync v0.1.1 h1:bFDAYS0Z48yd8ROPI6f/zIVmJxaDLA6m8cVuJPKC5fE=
|
||||
github.com/ipfs/go-graphsync v0.1.1/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
|
||||
github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
|
||||
github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88=
|
||||
github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
|
||||
@ -340,10 +352,10 @@ github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE
|
||||
github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw=
|
||||
github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8=
|
||||
github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8=
|
||||
github.com/ipfs/go-ipfs-cmds v0.2.9 h1:zQTENe9UJrtCb2bOtRoDGjtuo3rQjmuPdPnVlqoBV/M=
|
||||
github.com/ipfs/go-ipfs-cmds v0.2.9/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
|
||||
github.com/ipfs/go-ipfs-config v0.8.0 h1:4Tc7DC3dz4e7VadOjxXxFQGTQ1g7EYZClJ/ih8qOrxE=
|
||||
github.com/ipfs/go-ipfs-config v0.8.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
|
||||
github.com/ipfs/go-ipfs-cmds v0.4.0 h1:xUavIxA9Ts8U6PAHmQBvDGMlGfUrQ13Rymd+5t8LIF4=
|
||||
github.com/ipfs/go-ipfs-cmds v0.4.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
|
||||
github.com/ipfs/go-ipfs-config v0.9.0 h1:qTXJ9CyOyQv1LFJUMysxz8fi6RxxnP9QqcmiobuANvw=
|
||||
github.com/ipfs/go-ipfs-config v0.9.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
|
||||
github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
|
||||
@ -357,7 +369,6 @@ github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C
|
||||
github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0=
|
||||
github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.4/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg=
|
||||
github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
|
||||
github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA=
|
||||
@ -410,14 +421,13 @@ github.com/ipfs/go-log/v2 v2.0.3 h1:Q2gXcBoCALyLN/pUQlz1qgu0x3uFV6FzP9oXhpfyJpc=
|
||||
github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
||||
github.com/ipfs/go-log/v2 v2.0.5 h1:fL4YI+1g5V/b1Yxr1qAiXTMg1H8z9vx/VmJxBuQMHvU=
|
||||
github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.0.8 h1:3b3YNopMHlj4AvyhWAx0pDxqSQWYi4/WuWO7yRV6/Qg=
|
||||
github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0=
|
||||
github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA=
|
||||
github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto=
|
||||
github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
github.com/ipfs/go-merkledag v0.2.3 h1:aMdkK9G1hEeNvn3VXfiEMLY0iJnbiQQUHnM0HFJREsE=
|
||||
github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
github.com/ipfs/go-merkledag v0.2.4/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
|
||||
github.com/ipfs/go-merkledag v0.3.0 h1:1bXv/ZRPZLVdij/a33CkXMVdxUdred9sz4xyph+0ls0=
|
||||
github.com/ipfs/go-merkledag v0.3.0/go.mod h1:4pymaZLhSLNVuiCITYrpViD6vmfZ/Ws4n/L9tfNv3S4=
|
||||
github.com/ipfs/go-merkledag v0.3.1 h1:3UqWINBEr3/N+r6OwgFXAddDP/8zpQX/8J7IGVOCqRQ=
|
||||
@ -433,6 +443,8 @@ github.com/ipfs/go-mfs v0.1.2/go.mod h1:T1QBiZPEpkPLzDqEJLNnbK55BVKVlNi2a+gVm4di
|
||||
github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo=
|
||||
github.com/ipfs/go-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho=
|
||||
github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno=
|
||||
github.com/ipfs/go-path v0.0.8 h1:R0k6t9x/pa+g8qzl5apQIPurJFozXhopks3iw3MX+jU=
|
||||
github.com/ipfs/go-path v0.0.8/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8=
|
||||
github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ=
|
||||
github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U=
|
||||
github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U=
|
||||
@ -440,19 +452,20 @@ github.com/ipfs/go-peertaskqueue v0.2.0 h1:2cSr7exUGKYyDeUyQ7P/nHPs9P7Ht/B+ROrpN
|
||||
github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY=
|
||||
github.com/ipfs/go-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8=
|
||||
github.com/ipfs/go-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s=
|
||||
github.com/ipfs/go-unixfs v0.2.2-0.20190827150610-868af2e9e5cb/go.mod h1:IwAAgul1UQIcNZzKPYZWOCijryFBeCV79cNubPzol+k=
|
||||
github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo=
|
||||
github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw=
|
||||
github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=
|
||||
github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0=
|
||||
github.com/ipfs/interface-go-ipfs-core v0.3.0 h1:oZdLLfh256gPGcYPURjivj/lv296GIcr8mUqZUnXOEI=
|
||||
github.com/ipfs/interface-go-ipfs-core v0.3.0/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s=
|
||||
github.com/ipld/go-car v0.1.0 h1:AaIEA5ITRnFA68uMyuIPYGM2XXllxsu8sNjFJP797us=
|
||||
github.com/ipld/go-car v0.1.0/go.mod h1:RCWzaUh2i4mOEkB3W45Vc+9jnS/M6Qay5ooytiBHl3g=
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785 h1:fASnkvtR+SmB2y453RxmDD3Uvd4LonVUgFGk9JoDaZs=
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785/go.mod h1:bDDSvVz7vaK12FNvMeRYnpRFkSUPNQOiCYQezMD/P3w=
|
||||
github.com/ipld/go-ipld-prime-proto v0.0.0-20191113031812-e32bd156a1e5 h1:lSip43rAdyGA+yRQuy6ju0ucZkWpYc1F2CTQtZTVW/4=
|
||||
github.com/ipld/go-ipld-prime-proto v0.0.0-20191113031812-e32bd156a1e5/go.mod h1:gcvzoEDBjwycpXt3LBE061wT9f46szXGHAmj9uoP6fU=
|
||||
github.com/ipfs/interface-go-ipfs-core v0.4.0 h1:+mUiamyHIwedqP8ZgbCIwpy40oX7QcXUbo4CZOeJVJg=
|
||||
github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o=
|
||||
github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339 h1:YEYaf6mrrjoTfGpi7MajslcGvhP23Sh0b3ubcGYRMw0=
|
||||
github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339/go.mod h1:eajxljm6I8o3LitnFeVEmucwZmz7+yLSiKce9yYMefg=
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e h1:ZISbJlM0urTANR9KRfRaqlBmyOj5uUtxs2r4Up9IXsA=
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8=
|
||||
github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1 h1:K1Ysr7kgIlo7YQkPqdkA6H7BVdIugvuAz7OQUTJxLdE=
|
||||
github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1/go.mod h1:OAV6xBmuTLsPZ+epzKkPB1e25FHk/vCtyatkdHcArLs=
|
||||
github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
|
||||
github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc=
|
||||
github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
|
||||
@ -481,7 +494,7 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
@ -515,6 +528,8 @@ github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwn
|
||||
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk=
|
||||
github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE=
|
||||
github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE=
|
||||
@ -522,8 +537,6 @@ github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD
|
||||
github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc=
|
||||
github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M=
|
||||
github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU=
|
||||
github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk=
|
||||
github.com/libp2p/go-eventbus v0.0.3/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk=
|
||||
github.com/libp2p/go-eventbus v0.1.0 h1:mlawomSAjjkk97QnYiEmHsLu7E136+2oCWSHRUvMfzQ=
|
||||
github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4=
|
||||
github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc=
|
||||
@ -538,7 +551,6 @@ github.com/libp2p/go-libp2p v0.0.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mW
|
||||
github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A=
|
||||
github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM=
|
||||
github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8=
|
||||
github.com/libp2p/go-libp2p v0.2.1/go.mod h1:HZbtEOrgZN4F1fGZVvkV+930Wx3DkqlpBlO8dIoZWds=
|
||||
github.com/libp2p/go-libp2p v0.6.0 h1:EFArryT9N7AVA70LCcOh8zxsW+FeDnxwcpWQx9k7+GM=
|
||||
github.com/libp2p/go-libp2p v0.6.0/go.mod h1:mfKWI7Soz3ABX+XEBR61lGbg+ewyMtJHVt043oWeqwg=
|
||||
github.com/libp2p/go-libp2p v0.6.1 h1:mxabyJf4l6AmotDOKObwSfBNBWjL5VYXysVFLUMAuB8=
|
||||
@ -548,12 +560,12 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS
|
||||
github.com/libp2p/go-libp2p v0.7.4 h1:xVj1oSlN0C+FlxqiLuHC8WruMvq24xxfeVxmNhTG0r0=
|
||||
github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw=
|
||||
github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o=
|
||||
github.com/libp2p/go-libp2p v0.8.2 h1:gVuk8nZGjnRagJ/mLpBCSJw7bW1yWJrq3EwOk/AC6FM=
|
||||
github.com/libp2p/go-libp2p v0.8.2/go.mod h1:NQDA/F/qArMHGe0J7sDScaKjW8Jh4y/ozQqBbYJ+BnA=
|
||||
github.com/libp2p/go-libp2p v0.8.3 h1:IFWeNzxkBaNO1N8stN9ayFGdC6RmVuSsKd5bou7qpK0=
|
||||
github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM=
|
||||
github.com/libp2p/go-libp2p v0.9.6 h1:sDiuVhuLpWQOjSFmxOJEXVM9RHKIUTKgi8ArSS9nBtE=
|
||||
github.com/libp2p/go-libp2p v0.9.6/go.mod h1:EA24aHpFs3BscMWvO286AiaKs3a7efQdLo+tbZ2tUSk=
|
||||
github.com/libp2p/go-libp2p v0.11.0 h1:jb5mqdqYEBAybTEhD8io43Cz5LzVKuWxOK7znSN69jE=
|
||||
github.com/libp2p/go-libp2p v0.11.0/go.mod h1:3/ogJDXsbbepEfqtZKBR/DedzxJXCeK17t2Z9RE9bEE=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo=
|
||||
github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4=
|
||||
github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE=
|
||||
github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU=
|
||||
@ -566,15 +578,16 @@ github.com/libp2p/go-libp2p-autonat v0.2.1 h1:T0CRQhrvTBKfBSYw6Xo2K3ixtNpAnRCrax
|
||||
github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI=
|
||||
github.com/libp2p/go-libp2p-autonat v0.2.2 h1:4dlgcEEugTFWSvdG2UIFxhnOMpX76QaZSRAtXmYB8n4=
|
||||
github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A=
|
||||
github.com/libp2p/go-libp2p-autonat v0.2.3 h1:w46bKK3KTOUWDe5mDYMRjJu1uryqBp8HCNDp/TWMqKw=
|
||||
github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM=
|
||||
github.com/libp2p/go-libp2p-autonat v0.3.2 h1:OhDSwVVaq7liTaRIsFFYvsaPp0pn2yi0WazejZ4DUmo=
|
||||
github.com/libp2p/go-libp2p-autonat v0.3.2/go.mod h1:0OzOi1/cVc7UcxfOddemYD5vzEqi4fwRbnZcJGLi68U=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.4 h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.6 h1:CkPp1/zaCrCnBo0AdsQA0O1VkUYoUOtyHOnoa8gKIcE=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.1.6/go.mod h1:jONCAJqEP+Z8T6EQviGL4JsQcLx1LgTGtVqFNY8EMfQ=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk=
|
||||
github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ=
|
||||
github.com/libp2p/go-libp2p-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE=
|
||||
github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU=
|
||||
github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
|
||||
@ -584,18 +597,14 @@ github.com/libp2p/go-libp2p-circuit v0.2.1 h1:BDiBcQxX/ZJJ/yDl3sqZt1bjj4PkZCEi7I
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo=
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.2 h1:87RLabJ9lrhoiSDDZyCJ80ZlI5TLJMwfyoGAaWXzWqA=
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4=
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.3 h1:3Uw1fPHWrp1tgIhBz0vSOxRUmnKL8L/NGUyEd5WfSGM=
|
||||
github.com/libp2p/go-libp2p-circuit v0.2.3/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4=
|
||||
github.com/libp2p/go-libp2p-connmgr v0.2.3 h1:v7skKI9n+0obPpzMIO6aIlOSdQOmhxTf40cbpzqaGMQ=
|
||||
github.com/libp2p/go-libp2p-connmgr v0.2.3/go.mod h1:Gqjg29zI8CwXX21zRxy6gOg8VYu3zVerJRt2KyktzH4=
|
||||
github.com/libp2p/go-libp2p-circuit v0.3.1 h1:69ENDoGnNN45BNDnBd+8SXSetDuw0eJFcGmOvvtOgBw=
|
||||
github.com/libp2p/go-libp2p-circuit v0.3.1/go.mod h1:8RMIlivu1+RxhebipJwFDA45DasLx+kkrp4IlJj53F4=
|
||||
github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w=
|
||||
github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0=
|
||||
github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco=
|
||||
github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco=
|
||||
github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE=
|
||||
github.com/libp2p/go-libp2p-core v0.0.4/go.mod h1:jyuCQP356gzfCFtRKyvAbNkyeuxb7OlyhWZ3nls5d2I=
|
||||
github.com/libp2p/go-libp2p-core v0.0.6/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE=
|
||||
github.com/libp2p/go-libp2p-core v0.0.9/go.mod h1:0d9xmaYAVY5qmbp/fcgxHT3ZJsLjYeYPMJAUKpaCHrE=
|
||||
github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI=
|
||||
github.com/libp2p/go-libp2p-core v0.2.2/go.mod h1:8fcwTbsG2B+lTgRJ1ICZtiM5GWCWZVoVrLaDRvIRng0=
|
||||
github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g=
|
||||
@ -621,6 +630,10 @@ github.com/libp2p/go-libp2p-core v0.5.6 h1:IxFH4PmtLlLdPf4fF/i129SnK/C+/v8WEX644
|
||||
github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo=
|
||||
github.com/libp2p/go-libp2p-core v0.5.7 h1:QK3xRwFxqd0Xd9bSZL+8yZ8ncZZbl6Zngd/+Y+A6sgQ=
|
||||
github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo=
|
||||
github.com/libp2p/go-libp2p-core v0.6.0 h1:u03qofNYTBN+yVg08PuAKylZogVf0xcTEeM8skGf+ak=
|
||||
github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo=
|
||||
github.com/libp2p/go-libp2p-core v0.6.1 h1:XS+Goh+QegCDojUZp00CaPMfiEADCrLjNZskWE7pvqs=
|
||||
github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
|
||||
github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I=
|
||||
github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ=
|
||||
@ -635,6 +648,8 @@ github.com/libp2p/go-libp2p-discovery v0.3.0 h1:+JnYBRLzZQtRq0mK3xhyjBwHytLmJXMT
|
||||
github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw=
|
||||
github.com/libp2p/go-libp2p-discovery v0.4.0 h1:dK78UhopBk48mlHtRCzbdLm3q/81g77FahEBTjcqQT8=
|
||||
github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4=
|
||||
github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ=
|
||||
github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug=
|
||||
github.com/libp2p/go-libp2p-gostream v0.2.1 h1:JjA9roGokaR2BgWmaI/3HQu1/+jSbVVDLatQGnVdGjI=
|
||||
github.com/libp2p/go-libp2p-gostream v0.2.1/go.mod h1:1Mjp3LDmkqICe5tH9yLVNCqFaRTy6OwBvuJV6j1b9Nk=
|
||||
github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go=
|
||||
@ -645,10 +660,10 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM
|
||||
github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
|
||||
github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
|
||||
github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k=
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.8.2 h1:s7y38B+hdj1AkNR3PCTpvNqBsZHxOf7hoUy7+fNlSZQ=
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.8.2/go.mod h1:u3rbYbp3CSraAHD5s81CJ3hHozKTud/UOXfAgh93Gek=
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.2 h1:wg+VPpCtY61bCasGRexCuXOmEmdKjN+k1w+JtTwu9gA=
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.2/go.mod h1:7sCeZx2GkNK1S6lQnGUW5JYZCFPnXzAZCCBBS70lytY=
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.9.0 h1:AKeFYZvfAa/32Sgm0LrPDxGXB62AUtU8MRqqMobBfUM=
|
||||
github.com/libp2p/go-libp2p-kad-dht v0.9.0/go.mod h1:LEKcCFHxnvypOPaqZ0m6h0fLQ9Y8t1iZMOg7a0aQDD4=
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70=
|
||||
github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk=
|
||||
github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg=
|
||||
github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8=
|
||||
github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90=
|
||||
@ -661,6 +676,8 @@ github.com/libp2p/go-libp2p-mplex v0.2.2 h1:+Ld7YDAfVERQ0E+qqjE7o6fHwKuM0SqTzYiw
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo=
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.3 h1:2zijwaJvpdesST2MXpI5w9wWFRgYtMcpRX7rrw0jmOo=
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek=
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.4 h1:XFFXaN4jhqnIuJVjYOR3k6bnRj0mFfJOlIuDVww+4Zo=
|
||||
github.com/libp2p/go-libp2p-mplex v0.2.4/go.mod h1:mI7iOezdWFOisvUwaYd3IDrJ4oVmgoXK8H331ui39CE=
|
||||
github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ=
|
||||
github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw=
|
||||
github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY=
|
||||
@ -682,7 +699,6 @@ github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMg
|
||||
github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.2/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.3 h1:wMgajt1uM2tMiqf4M+4qWKVyyFc8SfA+84VV9glZq1M=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI=
|
||||
github.com/libp2p/go-libp2p-peerstore v0.1.4 h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k=
|
||||
@ -703,17 +719,16 @@ github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6n
|
||||
github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA=
|
||||
github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s=
|
||||
github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.0 h1:K5FSYyfcSrJWrGExgdbogCLMqwC3pQaXEVt2CaUy1SA=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.0/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.1 h1:7Hyv2d8BK/x1HGRJTZ8X++VQEP+WqDTSwpUSZGTVLYA=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato=
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.0 h1:ghpHApTMXN+aZ+InYvpJa/ckBW4orypzNI0aWQDth3s=
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.0/go.mod h1:6kZb1gGV1yGzXTfyNsi4p+hyt1JnA1OMGHeExTOJR3A=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.3.7/go.mod h1:Kr4aDtnfHHNeENn5J+sZIVc+t8HpQn9W6BOxhVGHbgI=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.6.0 h1:d5bcq7y+t6IiumD9Ib0S4oHgWu66rRjQ1Y8ligii6G8=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.6.0/go.mod h1:HR435saAZhTrFabI+adf3tVBY7ZJg5rKNoJ+CrIIg8c=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.2/go.mod h1:Uss7/Cfz872KggNb+doCVPHeCDmXB7z500m/R8DaAUk=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.5 h1:iF75GWpcxKEUQU8tTkgLy69qIQvfhL+t6U6ndQrB6ho=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.3.5/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.2 h1:BGC4irCUXlwmlCSxnA2DVDNY8JqhfAUUaiq3CZvcddw=
|
||||
github.com/libp2p/go-libp2p-pubsub-router v0.3.2/go.mod h1:G4MAvYzPxhoR0LEBluS9Ow+Nnr/8iDalUN+RNwVgNkY=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0 h1:mHA94K2+TD0e9XtjWx/P5jGGZn0GdQ4OFYwNllagv4E=
|
||||
github.com/libp2p/go-libp2p-quic-transport v0.8.0/go.mod h1:F2FG/6Bzz0U6essUVxDzE0s9CrY4XGLbl7QEmDNvU7A=
|
||||
github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q=
|
||||
github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q=
|
||||
github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg=
|
||||
github.com/libp2p/go-libp2p-record v0.1.2 h1:M50VKzWnmUrk/M5/Dz99qO9Xh4vs8ijsK+7HkJvRP+0=
|
||||
github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk=
|
||||
github.com/libp2p/go-libp2p-record v0.1.3 h1:R27hoScIhQf/A8XJZ8lYpnqh9LatJ5YbHs28kCIfql0=
|
||||
@ -724,7 +739,6 @@ github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASo
|
||||
github.com/libp2p/go-libp2p-secio v0.0.1/go.mod h1:IdG6iQybdcYmbTzxp4J5dwtUEDTOvZrT0opIDVNPrJs=
|
||||
github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0=
|
||||
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
||||
github.com/libp2p/go-libp2p-secio v0.1.1/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
|
||||
github.com/libp2p/go-libp2p-secio v0.2.0 h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng=
|
||||
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
|
||||
github.com/libp2p/go-libp2p-secio v0.2.1 h1:eNWbJTdyPA7NxhP7J3c5lT97DC5d+u+IldkgCYFTPVA=
|
||||
@ -734,15 +748,14 @@ github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncH
|
||||
github.com/libp2p/go-libp2p-swarm v0.0.1/go.mod h1:mh+KZxkbd3lQnveQ3j2q60BM1Cw2mX36XXQqwfPOShs=
|
||||
github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8=
|
||||
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
|
||||
github.com/libp2p/go-libp2p-swarm v0.1.1/go.mod h1:4NVJaLwq/dr5kEq79Jo6pMin7ZFwLx73ln1FTefR91Q=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.2 h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.3 h1:uVkCb8Blfg7HQ/f30TyHn1g/uCwXsAET7pU0U59gx/A=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.4 h1:94XL76/tFeTdJNcIGugi+1uZo5O/a7y4i21PirwbgZI=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.6 h1:UhMXIa+yCOALQyceENEIStMlbTCzOM6aWo6vw8QW17Q=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.6/go.mod h1:F9hrkZjO7dDbcEiYii/fAB1QdpLuU6h1pa4P5VNsEgc=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.8 h1:cIUUvytBzNQmGSjnXFlI6UpoBGsaud82mJPIJVfkDlg=
|
||||
github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM=
|
||||
github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
|
||||
github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
|
||||
github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E=
|
||||
@ -751,6 +764,8 @@ github.com/libp2p/go-libp2p-testing v0.1.0 h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/
|
||||
github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
|
||||
github.com/libp2p/go-libp2p-testing v0.1.1 h1:U03z3HnGI7Ni8Xx6ONVZvUFOAzWYmolWf5W5jAOPNmU=
|
||||
github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
|
||||
github.com/libp2p/go-libp2p-testing v0.2.0 h1:DdC8Dthjf97Hz3t3siZCRD1U3nuNxQgEyTWvLh6ayvw=
|
||||
github.com/libp2p/go-libp2p-testing v0.2.0/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc=
|
||||
github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM=
|
||||
github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
|
||||
github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk=
|
||||
@ -781,6 +796,7 @@ github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9
|
||||
github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q=
|
||||
github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg=
|
||||
github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
|
||||
github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU=
|
||||
github.com/libp2p/go-mplex v0.0.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
|
||||
github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
|
||||
github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
|
||||
@ -795,6 +811,8 @@ github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+
|
||||
github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
|
||||
github.com/libp2p/go-msgio v0.0.4 h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA=
|
||||
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
|
||||
github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA=
|
||||
github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA=
|
||||
github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI=
|
||||
github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI=
|
||||
github.com/libp2p/go-nat v0.0.4 h1:KbizNnq8YIf7+Hn7+VFL/xE0eDrkPru2zIO9NMwL8UQ=
|
||||
@ -803,6 +821,8 @@ github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q=
|
||||
github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU=
|
||||
github.com/libp2p/go-netroute v0.1.2 h1:UHhB35chwgvcRI392znJA3RCBtZ3MpE3ahNCN5MR4Xg=
|
||||
github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
|
||||
github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig=
|
||||
github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
|
||||
github.com/libp2p/go-openssl v0.0.2 h1:9pP2d3Ubaxkv7ZisLjx9BFwgOGnQdQYnfcH29HNY3ls=
|
||||
github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0=
|
||||
github.com/libp2p/go-openssl v0.0.3 h1:wjlG7HvQkt4Fq4cfH33Ivpwp0omaElYEi9z26qaIkIk=
|
||||
@ -811,17 +831,21 @@ github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fo
|
||||
github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
|
||||
github.com/libp2p/go-openssl v0.0.5 h1:pQkejVhF0xp08D4CQUcw8t+BFJeXowja6RVcb5p++EA=
|
||||
github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
|
||||
github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw=
|
||||
github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
|
||||
github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=
|
||||
github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
|
||||
github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU=
|
||||
github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.3 h1:zzOeXnTooCkRvoH+bSXEfXhn76+LAiwoneM0gnXjF2M=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM=
|
||||
github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw=
|
||||
github.com/libp2p/go-sockaddr v0.0.2 h1:tCuXfpA9rq7llM/v834RKc/Xvovy/AqM9kHvTV/jY/Q=
|
||||
github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
|
||||
github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0=
|
||||
github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
|
||||
github.com/libp2p/go-socket-activation v0.0.2 h1:VLU3IbrUUqu4DMhxA9857Q63qUpEAbCz5RqSnLCx5jE=
|
||||
github.com/libp2p/go-socket-activation v0.0.2/go.mod h1:KP44C+yZ7gA8sTxavgaD0b8vXVFJwam2CEW0s7+f094=
|
||||
github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14=
|
||||
@ -838,6 +862,8 @@ github.com/libp2p/go-tcp-transport v0.1.1 h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8N
|
||||
github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
|
||||
github.com/libp2p/go-tcp-transport v0.2.0 h1:YoThc549fzmNJIh7XjHVtMIFaEDRtIrtWciG5LyYAPo=
|
||||
github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0=
|
||||
github.com/libp2p/go-tcp-transport v0.2.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KXwWaVi8Ns=
|
||||
github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M=
|
||||
github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I=
|
||||
github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc=
|
||||
github.com/libp2p/go-ws-transport v0.0.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww=
|
||||
@ -861,18 +887,18 @@ github.com/libp2p/go-yamux v1.3.5 h1:ibuz4naPAully0pN6J/kmUARiqLpnDQIzI/8GCOrljg
|
||||
github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
|
||||
github.com/libp2p/go-yamux v1.3.7 h1:v40A1eSPJDIZwz2AvrV3cxpTZEGDP11QJbukmEhYyQI=
|
||||
github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE=
|
||||
github.com/lucas-clemente/quic-go v0.15.7 h1:Pu7To5/G9JoP1mwlrcIvfV8ByPBlCzif3MCl8+1W83I=
|
||||
github.com/lucas-clemente/quic-go v0.15.7/go.mod h1:Myi1OyS0FOjL3not4BxT7KN29bRkcMUV5JVVFLKtDp8=
|
||||
github.com/lucas-clemente/quic-go v0.16.2 h1:A27xKWQtPTeOcIUF4EymmROkKlF/RbKBiMbflwv6RK0=
|
||||
github.com/lucas-clemente/quic-go v0.16.2/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE=
|
||||
github.com/lucas-clemente/quic-go v0.18.0 h1:JhQDdqxdwdmGdKsKgXi1+coHRoGhvU6z0rNzOJqZ/4o=
|
||||
github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI=
|
||||
github.com/marten-seemann/qtls v0.9.1 h1:O0YKQxNVPaiFgMng0suWEOY2Sb4LT2sRn9Qimq3Z1IQ=
|
||||
github.com/marten-seemann/qtls v0.9.1/go.mod h1:T1MmAdDPyISzxlK6kjRr0pcZFBVd1OZbBb/j3cvzHhk=
|
||||
github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||
github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc=
|
||||
github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
|
||||
github.com/marten-seemann/qtls-go1-15 v0.1.0 h1:i/YPXVxz8q9umso/5y474CNcHmTpA+5DH+mFPjx6PZg=
|
||||
github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
@ -896,8 +922,8 @@ github.com/miekg/dns v1.1.12 h1:WMhc1ik4LNkTg8U9l3hI1LvxKmIL+f1+WV/SZtCbDDA=
|
||||
github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.28 h1:gQhy5bsJa8zTlVI8lywCTZp1lguor+xevFoYlzeCTQY=
|
||||
github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
@ -919,6 +945,8 @@ github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
|
||||
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
|
||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||
github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4=
|
||||
@ -935,9 +963,12 @@ github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4
|
||||
github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE=
|
||||
github.com/multiformats/go-multiaddr v0.2.2 h1:XZLDTszBIJe6m0zF6ITBrEcZR73OPUhCBBS9rYAuUzI=
|
||||
github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y=
|
||||
github.com/multiformats/go-multiaddr v0.3.0 h1:z1Old9IYcUyMEtSbvwCOJ1jcrmJdU0LYH8aFBvZKzcQ=
|
||||
github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI=
|
||||
github.com/multiformats/go-multiaddr v0.3.1 h1:1bxa+W7j9wZKTZREySx1vPMs2TqrYWjVZ7zE6/XLG1I=
|
||||
github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
|
||||
github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA=
|
||||
github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q=
|
||||
@ -956,6 +987,8 @@ github.com/multiformats/go-multiaddr-net v0.1.4 h1:g6gwydsfADqFvrHoMkS0n9Ok9CG6F
|
||||
github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA=
|
||||
github.com/multiformats/go-multiaddr-net v0.1.5 h1:QoRKvu0xHN1FCFJcMQLbG/yQE2z441L5urvG3+qyz7g=
|
||||
github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA=
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk=
|
||||
github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA=
|
||||
github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
|
||||
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
|
||||
github.com/multiformats/go-multibase v0.0.2 h1:2pAgScmS1g9XjH7EtAfNhTuyrWYEWcxy0G5Wo85hWDA=
|
||||
@ -964,7 +997,6 @@ github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77
|
||||
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
|
||||
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
|
||||
github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po=
|
||||
github.com/multiformats/go-multihash v0.0.6/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM=
|
||||
github.com/multiformats/go-multihash v0.0.7/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM=
|
||||
github.com/multiformats/go-multihash v0.0.8 h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg=
|
||||
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||
@ -974,17 +1006,23 @@ github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6w
|
||||
github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||
github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc=
|
||||
github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||
github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I=
|
||||
github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc=
|
||||
github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
|
||||
github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
|
||||
github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ=
|
||||
github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
|
||||
github.com/multiformats/go-multistream v0.1.1 h1:JlAdpIFhBhGRLxe9W6Om0w++Gd6KMWoFPZL/dEnm9nI=
|
||||
github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38=
|
||||
github.com/multiformats/go-multistream v0.1.2 h1:knyamLYMPFPngQjGQ0lhnlys3jtVR/3xV6TREUJr+fE=
|
||||
github.com/multiformats/go-multistream v0.1.2/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k=
|
||||
github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M=
|
||||
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
|
||||
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
|
||||
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
@ -994,21 +1032,25 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -1021,12 +1063,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
|
||||
github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14 h1:2m16U/rLwVaRdz7ANkHtHTodP3zTP3N451MADg64x5k=
|
||||
github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
|
||||
github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
|
||||
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr2us7vdy04YWz3LVAirzP7reh8+M=
|
||||
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
|
||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -1036,14 +1081,14 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
@ -1077,11 +1122,13 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smola/gocompat v0.2.0 h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns=
|
||||
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
@ -1120,14 +1167,17 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE=
|
||||
github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
||||
github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0=
|
||||
github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
||||
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w=
|
||||
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
||||
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4=
|
||||
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105 h1:Sh6UG5dW5xW8Ek2CtRGq4ipdEvvx9hOyBJjEGyTYDl0=
|
||||
github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
|
||||
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
|
||||
@ -1168,16 +1218,18 @@ go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/dig v1.9.0 h1:pJTDXKEhRqBI8W7rU7kwT5EgyRZuSMVSFcZolOvKK9U=
|
||||
go.uber.org/dig v1.9.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
|
||||
go.uber.org/fx v1.12.0 h1:+1+3Cz9M0dFMPy9SW9XUIUHye8bnPUm7q7DroNGWYG4=
|
||||
go.uber.org/fx v1.12.0/go.mod h1:egT3Kyg1JFYQkvKLZ3EsykxkNrZxgXS+gKoKo7abERY=
|
||||
go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY=
|
||||
go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
|
||||
go.uber.org/fx v1.13.1 h1:CFNTr1oin5OJ0VCZ8EycL3wzF29Jz2g0xe55RFsf2a4=
|
||||
go.uber.org/fx v1.13.1/go.mod h1:bREWhavnedxpJeTq9pQT53BbvwhUv7TcpsOqcH4a+3w=
|
||||
go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4=
|
||||
go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI=
|
||||
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
|
||||
@ -1216,16 +1268,18 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1269,7 +1323,6 @@ golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@ -1289,10 +1342,9 @@ golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU=
|
||||
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -1346,18 +1398,16 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1458,6 +1508,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@ -1489,6 +1540,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
|
||||
249
misc/README.md
Normal file
249
misc/README.md
Normal file
@ -0,0 +1,249 @@
|
||||
## init system integration
|
||||
|
||||
go-ipfs can be started by your operating system's native init system.
|
||||
|
||||
- [systemd](#systemd)
|
||||
- [LSB init script](#initd)
|
||||
- [Upstart/startup job](#upstart)
|
||||
- [launchd](#launchd)
|
||||
|
||||
### systemd
|
||||
|
||||
For `systemd`, the best approach is to run the daemon in a user session. Here is a sample service file:
|
||||
|
||||
```systemd
|
||||
[Unit]
|
||||
Description=IPFS daemon
|
||||
|
||||
[Service]
|
||||
# Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default ($HOME/.ipfs)
|
||||
ExecStart=/usr/bin/ipfs daemon
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
To run this in your user session, save it as `~/.config/systemd/user/ipfs.service` (creating directories as necessary). Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the following commands:
|
||||
|
||||
* `systemctl --user start ipfs` - start the daemon
|
||||
* `systemctl --user stop ipfs` - stop the daemon
|
||||
* `systemctl --user status ipfs` - get status of the daemon
|
||||
* `systemctl --user enable ipfs` - enable starting the daemon at boot
|
||||
* `systemctl --user disable ipfs` - disable starting the daemon at boot
|
||||
|
||||
*Note:* If you want this `--user` service to run at system boot, you must [`enable-linger`](http://www.freedesktop.org/software/systemd/man/loginctl.html) on the account that runs the service:
|
||||
|
||||
```
|
||||
# loginctl enable-linger [user]
|
||||
```
|
||||
Read more about `--user` services here: [wiki.archlinux.org:Systemd ](https://wiki.archlinux.org/index.php/Systemd/User#Automatic_start-up_of_systemd_user_instances)
|
||||
|
||||
### initd
|
||||
|
||||
- Here is a full-featured sample service file: https://github.com/dylanPowers/ipfs-linux-service/blob/master/init.d/ipfs
|
||||
- Use `service` or your distribution's equivalent to control the service.
|
||||
|
||||
## upstart
|
||||
|
||||
- And below is a very basic sample upstart job. **Note the username jbenet**.
|
||||
|
||||
```
|
||||
cat /etc/init/ipfs.conf
|
||||
```
|
||||
```
|
||||
description "ipfs: interplanetary filesystem"
|
||||
|
||||
start on (local-filesystems and net-device-up IFACE!=lo)
|
||||
stop on runlevel [!2345]
|
||||
|
||||
limit nofile 524288 1048576
|
||||
limit nproc 524288 1048576
|
||||
setuid jbenet
|
||||
chdir /home/jbenet
|
||||
respawn
|
||||
exec ipfs daemon
|
||||
```
|
||||
|
||||
Another version is available here:
|
||||
|
||||
```sh
|
||||
ipfs cat /ipfs/QmbYCwVeA23vz6mzAiVQhJNa2JSiRH4ebef1v2e5EkDEZS/ipfs.conf >/etc/init/ipfs.conf
|
||||
```
|
||||
|
||||
For both, edit to replace occurrences of `jbenet` with whatever user you want it to run as:
|
||||
|
||||
```sh
|
||||
sed -i s/jbenet/<chosen-username>/ /etc/init/ipfs.conf
|
||||
```
|
||||
|
||||
Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the `init.d` commands:
|
||||
|
||||
```sh
|
||||
sudo service ipfs start
|
||||
sudo service ipfs stop
|
||||
sudo service ipfs restart
|
||||
...
|
||||
```
|
||||
|
||||
## launchd
|
||||
|
||||
Similar to `systemd`, on macOS you can run `go-ipfs` via a user LaunchAgent.
|
||||
|
||||
- Create `~/Library/LaunchAgents/io.ipfs.go-ipfs.plist`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>io.ipfs.go-ipfs</string>
|
||||
<key>ProcessType</key>
|
||||
<string>Background</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/sh</string>
|
||||
<string>-c</string>
|
||||
<string>~/go/bin/ipfs daemon</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
The reason for running `ipfs` under a shell is to avoid needing to hard-code the user's home directory in the job.
|
||||
|
||||
- To start the job, run `launchctl load ~/Library/LaunchAgents/io.ipfs.go-ipfs.plist`
|
||||
|
||||
Notes:
|
||||
|
||||
- To check that the job is running, run `launchctl list | grep ipfs`.
|
||||
- IPFS should now start whenever you log in (and exit when you log out).
|
||||
- [LaunchControl](http://www.soma-zone.com/LaunchControl/) is a GUI tool which simplifies management of LaunchAgents.## init system integration
|
||||
|
||||
go-ipfs can be started by your operating system's native init system.
|
||||
|
||||
- [systemd](#systemd)
|
||||
- [LSB init script](#initd)
|
||||
- [Upstart/startup job](#upstart)
|
||||
- [launchd](#launchd)
|
||||
|
||||
### systemd
|
||||
|
||||
For `systemd`, the best approach is to run the daemon in a user session. Here is a sample service file:
|
||||
|
||||
```systemd
|
||||
[Unit]
|
||||
Description=IPFS daemon
|
||||
|
||||
[Service]
|
||||
# Environment="IPFS_PATH=/data/ipfs" # optional path to ipfs init directory if not default ($HOME/.ipfs)
|
||||
ExecStart=/usr/bin/ipfs daemon
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
To run this in your user session, save it as `~/.config/systemd/user/ipfs.service` (creating directories as necessary). Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the following commands:
|
||||
|
||||
* `systemctl --user start ipfs` - start the daemon
|
||||
* `systemctl --user stop ipfs` - stop the daemon
|
||||
* `systemctl --user status ipfs` - get status of the daemon
|
||||
* `systemctl --user enable ipfs` - enable starting the daemon at boot
|
||||
* `systemctl --user disable ipfs` - disable starting the daemon at boot
|
||||
|
||||
*Note:* If you want this `--user` service to run at system boot, you must [`enable-linger`](http://www.freedesktop.org/software/systemd/man/loginctl.html) on the account that runs the service:
|
||||
|
||||
```
|
||||
# loginctl enable-linger [user]
|
||||
```
|
||||
Read more about `--user` services here: [wiki.archlinux.org:Systemd ](https://wiki.archlinux.org/index.php/Systemd/User#Automatic_start-up_of_systemd_user_instances)
|
||||
|
||||
### initd
|
||||
|
||||
- Here is a full-featured sample service file: https://github.com/dylanPowers/ipfs-linux-service/blob/master/init.d/ipfs
|
||||
- Use `service` or your distribution's equivalent to control the service.
|
||||
|
||||
## upstart
|
||||
|
||||
- And below is a very basic sample upstart job. **Note the username jbenet**.
|
||||
|
||||
```
|
||||
cat /etc/init/ipfs.conf
|
||||
```
|
||||
```
|
||||
description "ipfs: interplanetary filesystem"
|
||||
|
||||
start on (local-filesystems and net-device-up IFACE!=lo)
|
||||
stop on runlevel [!2345]
|
||||
|
||||
limit nofile 524288 1048576
|
||||
limit nproc 524288 1048576
|
||||
setuid jbenet
|
||||
chdir /home/jbenet
|
||||
respawn
|
||||
exec ipfs daemon
|
||||
```
|
||||
|
||||
Another version is available here:
|
||||
|
||||
```sh
|
||||
ipfs cat /ipfs/QmbYCwVeA23vz6mzAiVQhJNa2JSiRH4ebef1v2e5EkDEZS/ipfs.conf >/etc/init/ipfs.conf
|
||||
```
|
||||
|
||||
For both, edit to replace occurrences of `jbenet` with whatever user you want it to run as:
|
||||
|
||||
```sh
|
||||
sed -i s/jbenet/<chosen-username>/ /etc/init/ipfs.conf
|
||||
```
|
||||
|
||||
Once you run `ipfs init` to create your IPFS settings, you can control the daemon using the `init.d` commands:
|
||||
|
||||
```sh
|
||||
sudo service ipfs start
|
||||
sudo service ipfs stop
|
||||
sudo service ipfs restart
|
||||
...
|
||||
```
|
||||
|
||||
## launchd
|
||||
|
||||
Similar to `systemd`, on macOS you can run `go-ipfs` via a user LaunchAgent.
|
||||
|
||||
- Create `~/Library/LaunchAgents/io.ipfs.go-ipfs.plist`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>io.ipfs.go-ipfs</string>
|
||||
<key>ProcessType</key>
|
||||
<string>Background</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/sh</string>
|
||||
<string>-c</string>
|
||||
<string>~/go/bin/ipfs daemon</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
The reason for running `ipfs` under a shell is to avoid needing to hard-code the user's home directory in the job.
|
||||
|
||||
- To start the job, run `launchctl load ~/Library/LaunchAgents/io.ipfs.go-ipfs.plist`
|
||||
|
||||
Notes:
|
||||
|
||||
- To check that the job is running, run `launchctl list | grep ipfs`.
|
||||
- IPFS should now start whenever you log in (and exit when you log out).
|
||||
- [LaunchControl](http://www.soma-zone.com/LaunchControl/) is a GUI tool which simplifies management of LaunchAgents.
|
||||
71
misc/systemd/ipfs-hardened.service
Normal file
71
misc/systemd/ipfs-hardened.service
Normal file
@ -0,0 +1,71 @@
|
||||
# This file will be overwritten on package upgrades, avoid customizations here.
|
||||
#
|
||||
# To make persistant changes, create file in
|
||||
# "/etc/systemd/system/ipfs.service.d/overwrite.conf" with
|
||||
# `systemctl edit ipfs.service`. This file will be parsed after this
|
||||
# file has been parsed.
|
||||
#
|
||||
# To overwrite a variable, like ExecStart you have to specify it once
|
||||
# blank and a second time with a new value, like:
|
||||
# ExecStart=
|
||||
# ExecStart=/usr/bin/ipfs daemon --flag1 --flag2
|
||||
#
|
||||
# For more info about custom unit files see systemd.unit(5).
|
||||
|
||||
# This service file enables systemd-hardening features compatible with IPFS,
|
||||
# while breaking compability with the fuse-mount function. Use this one only
|
||||
# if you don't need the fuse-mount functionality.
|
||||
|
||||
[Unit]
|
||||
Description=InterPlanetary File System (IPFS) daemon
|
||||
Documentation=https://docs.ipfs.io/
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
# hardening
|
||||
ReadWritePaths="/var/lib/ipfs/"
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelLogs=true
|
||||
PrivateDevices=true
|
||||
DevicePolicy=closed
|
||||
ProtectControlGroups=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
||||
ProtectHostname=true
|
||||
PrivateTmp=true
|
||||
ProtectClock=true
|
||||
LockPersonality=true
|
||||
RestrictNamespaces=true
|
||||
RestrictRealtime=true
|
||||
MemoryDenyWriteExecute=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged
|
||||
ProtectHome=true
|
||||
RemoveIPC=true
|
||||
RestrictSUIDSGID=true
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
# enable for 1-1024 port listening
|
||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
# enable to specify a custom path see docs/environment-variables.md for further documentations
|
||||
#Environment=IPFS_PATH=/custom/ipfs/path
|
||||
# enable to specify a higher limit for open files/connections
|
||||
#LimitNOFILE=1000000
|
||||
|
||||
#don't use swap
|
||||
MemorySwapMax=0
|
||||
|
||||
Type=notify
|
||||
User=ipfs
|
||||
Group=ipfs
|
||||
StateDirectory=ipfs
|
||||
Environment=IPFS_PATH="${HOME}"
|
||||
ExecStart=/usr/bin/ipfs daemon --init --migrate
|
||||
Restart=on-failure
|
||||
KillSignal=SIGINT
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@ -33,6 +33,7 @@ Type=notify
|
||||
User=ipfs
|
||||
Group=ipfs
|
||||
StateDirectory=ipfs
|
||||
Environment=IPFS_PATH="${HOME}"
|
||||
ExecStart=/usr/bin/ipfs daemon --init --migrate
|
||||
Restart=on-failure
|
||||
KillSignal=SIGINT
|
||||
|
||||
@ -1,17 +1,18 @@
|
||||
# golang utilities
|
||||
GO_MIN_VERSION = 1.14.2
|
||||
GO_MIN_VERSION = 1.14.4
|
||||
export GO111MODULE=on
|
||||
|
||||
|
||||
# pre-definitions
|
||||
GOCC ?= go
|
||||
GOTAGS ?=
|
||||
unexport GOFLAGS
|
||||
GOFLAGS ?=
|
||||
GOTFLAGS ?=
|
||||
|
||||
# Unexport GOFLAGS so we only apply it where we actually want it.
|
||||
unexport GOFLAGS
|
||||
# Override so we can combine with the user's go flags.
|
||||
# Try to make building as reproducible as possible by stripping the go path.
|
||||
GOFLAGS += "-asmflags=all='-trimpath=$(GOPATH)'" "-gcflags=all='-trimpath=$(GOPATH)'"
|
||||
override GOFLAGS += "-asmflags=all='-trimpath=$(GOPATH)'" "-gcflags=all='-trimpath=$(GOPATH)'"
|
||||
|
||||
ifeq ($(tarball-is),1)
|
||||
GOFLAGS += -mod=vendor
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
mockrouting "github.com/ipfs/go-ipfs-routing/mock"
|
||||
offline "github.com/ipfs/go-ipfs-routing/offline"
|
||||
ipns "github.com/ipfs/go-ipns"
|
||||
ipns_pb "github.com/ipfs/go-ipns/pb"
|
||||
path "github.com/ipfs/go-path"
|
||||
opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
|
||||
ci "github.com/libp2p/go-libp2p-core/crypto"
|
||||
@ -23,6 +24,25 @@ import (
|
||||
)
|
||||
|
||||
func TestResolverValidation(t *testing.T) {
|
||||
t.Run("RSA",
|
||||
func(t *testing.T) {
|
||||
testResolverValidation(t, ci.RSA)
|
||||
})
|
||||
t.Run("Ed25519",
|
||||
func(t *testing.T) {
|
||||
testResolverValidation(t, ci.Ed25519)
|
||||
})
|
||||
t.Run("ECDSA",
|
||||
func(t *testing.T) {
|
||||
testResolverValidation(t, ci.ECDSA)
|
||||
})
|
||||
t.Run("Secp256k1",
|
||||
func(t *testing.T) {
|
||||
testResolverValidation(t, ci.Secp256k1)
|
||||
})
|
||||
}
|
||||
|
||||
func testResolverValidation(t *testing.T, keyType int) {
|
||||
ctx := context.Background()
|
||||
rid := testutil.RandIdentityOrFatal(t)
|
||||
dstore := dssync.MutexWrap(ds.NewMapDatastore())
|
||||
@ -34,16 +54,10 @@ func TestResolverValidation(t *testing.T) {
|
||||
nvVstore := offline.NewOfflineRouter(dstore, mockrouting.MockValidator{})
|
||||
|
||||
// Create entry with expiry in one hour
|
||||
priv, id, _, ipnsDHTPath := genKeys(t)
|
||||
priv, id, _, ipnsDHTPath := genKeys(t, keyType)
|
||||
ts := time.Now()
|
||||
p := []byte("/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG")
|
||||
entry, err := ipns.Create(priv, p, 1, ts.Add(time.Hour))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Make peer's public key available in peer store
|
||||
err = peerstore.AddPubKey(id, priv.GetPublic())
|
||||
entry, err := createIPNSRecordWithEmbeddedPublicKey(priv, p, 1, ts.Add(time.Hour))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -63,7 +77,7 @@ func TestResolverValidation(t *testing.T) {
|
||||
t.Fatalf("Mismatch between published path %s and resolved path %s", p, resp)
|
||||
}
|
||||
// Create expired entry
|
||||
expiredEntry, err := ipns.Create(priv, p, 1, ts.Add(-1*time.Hour))
|
||||
expiredEntry, err := createIPNSRecordWithEmbeddedPublicKey(priv, p, 1, ts.Add(-1*time.Hour))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -81,14 +95,26 @@ func TestResolverValidation(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create IPNS record path with a different private key
|
||||
priv2, id2, _, ipnsDHTPath2 := genKeys(t)
|
||||
priv2, id2, _, ipnsDHTPath2 := genKeys(t, keyType)
|
||||
|
||||
// Make peer's public key available in peer store
|
||||
err = peerstore.AddPubKey(id2, priv2.GetPublic())
|
||||
// Publish entry
|
||||
err = PublishEntry(ctx, nvVstore, ipnsDHTPath2, entry)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Record should fail validation because public key defined by
|
||||
// ipns path doesn't match record signature
|
||||
_, err = resolve(ctx, resolver, id2.Pretty(), opts.DefaultResolveOpts())
|
||||
if err == nil {
|
||||
t.Fatal("ValidateIpnsRecord should have failed signature verification")
|
||||
}
|
||||
|
||||
// Try embedding the incorrect private key inside the entry
|
||||
if err := ipns.EmbedPublicKey(priv2.GetPublic(), entry); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Publish entry
|
||||
err = PublishEntry(ctx, nvVstore, ipnsDHTPath2, entry)
|
||||
if err != nil {
|
||||
@ -101,43 +127,15 @@ func TestResolverValidation(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("ValidateIpnsRecord should have failed signature verification")
|
||||
}
|
||||
|
||||
// Publish entry without making public key available in peer store
|
||||
priv3, id3, pubkDHTPath3, ipnsDHTPath3 := genKeys(t)
|
||||
entry3, err := ipns.Create(priv3, p, 1, ts.Add(time.Hour))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = PublishEntry(ctx, nvVstore, ipnsDHTPath3, entry3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Record should fail validation because public key is not available
|
||||
// in peer store or on network
|
||||
_, err = resolve(ctx, resolver, id3.Pretty(), opts.DefaultResolveOpts())
|
||||
if err == nil {
|
||||
t.Fatal("ValidateIpnsRecord should have failed because public key was not found")
|
||||
}
|
||||
|
||||
// Publish public key to the network
|
||||
err = PublishPublicKey(ctx, vstore, pubkDHTPath3, priv3.GetPublic())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Record should now pass validation because resolver will ensure
|
||||
// public key is available in the peer store by looking it up in
|
||||
// the DHT, which causes the DHT to fetch it and cache it in the
|
||||
// peer store
|
||||
_, err = resolve(ctx, resolver, id3.Pretty(), opts.DefaultResolveOpts())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func genKeys(t *testing.T) (ci.PrivKey, peer.ID, string, string) {
|
||||
sk, pk, err := test.RandTestKeyPair(ci.RSA, 2048)
|
||||
func genKeys(t *testing.T, keyType int) (ci.PrivKey, peer.ID, string, string) {
|
||||
bits := 0
|
||||
if keyType == ci.RSA {
|
||||
bits = 2048
|
||||
}
|
||||
|
||||
sk, pk, err := test.RandTestKeyPair(keyType, bits)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -148,6 +146,18 @@ func genKeys(t *testing.T) (ci.PrivKey, peer.ID, string, string) {
|
||||
return sk, id, PkKeyForID(id), ipns.RecordKey(id)
|
||||
}
|
||||
|
||||
func createIPNSRecordWithEmbeddedPublicKey(sk ci.PrivKey, val []byte, seq uint64, eol time.Time) (*ipns_pb.IpnsEntry, error) {
|
||||
entry, err := ipns.Create(sk, val, seq, eol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ipns.EmbedPublicKey(sk.GetPublic(), entry); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
type mockValueStore struct {
|
||||
r routing.ValueStore
|
||||
kbook pstore.KeyBook
|
||||
|
||||
@ -122,24 +122,13 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
|
||||
|
||||
key := segments[2]
|
||||
|
||||
if p, ok := ns.cacheGet(key); ok {
|
||||
var err error
|
||||
if len(segments) > 3 {
|
||||
p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
|
||||
}
|
||||
|
||||
out <- onceResult{value: p, err: err}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// Resolver selection:
|
||||
// 1. if it is a PeerID/CID/multihash resolve through "ipns".
|
||||
// 2. if it is a domain name, resolve through "dns"
|
||||
// 3. otherwise resolve through the "proquint" resolver
|
||||
|
||||
var res resolver
|
||||
_, err := peer.Decode(key)
|
||||
ipnsKey, err := peer.Decode(key)
|
||||
|
||||
// CIDs in IPNS are expected to have libp2p-key multicodec
|
||||
// We ease the transition by returning a more meaningful error with a valid CID
|
||||
@ -155,6 +144,22 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
|
||||
}
|
||||
}
|
||||
|
||||
cacheKey := key
|
||||
if err == nil {
|
||||
cacheKey = string(ipnsKey)
|
||||
}
|
||||
|
||||
if p, ok := ns.cacheGet(cacheKey); ok {
|
||||
var err error
|
||||
if len(segments) > 3 {
|
||||
p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
|
||||
}
|
||||
|
||||
out <- onceResult{value: p, err: err}
|
||||
close(out)
|
||||
return out
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
res = ns.ipnsResolver
|
||||
} else if isd.IsDomain(key) {
|
||||
@ -172,7 +177,7 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
|
||||
case res, ok := <-resCh:
|
||||
if !ok {
|
||||
if best != (onceResult{}) {
|
||||
ns.cacheSet(key, best.value, best.ttl)
|
||||
ns.cacheSet(cacheKey, best.value, best.ttl)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -218,7 +223,7 @@ func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.
|
||||
if err := ns.ipnsPublisher.PublishWithEOL(ctx, name, value, eol); err != nil {
|
||||
// Invalidate the cache. Publishing may _partially_ succeed but
|
||||
// still return an error.
|
||||
ns.cacheInvalidate(peer.Encode(id))
|
||||
ns.cacheInvalidate(string(id))
|
||||
return err
|
||||
}
|
||||
ttl := DefaultResolverCacheTTL
|
||||
@ -228,6 +233,6 @@ func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.
|
||||
if ttEol := time.Until(eol); ttEol < ttl {
|
||||
ttl = ttEol
|
||||
}
|
||||
ns.cacheSet(peer.Encode(id), value, ttl)
|
||||
ns.cacheSet(string(id), value, ttl)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ func TestPublishWithTTL(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ientry, ok := nsys.(*mpns).cache.Get(pid.Pretty())
|
||||
ientry, ok := nsys.(*mpns).cache.Get(string(pid))
|
||||
if !ok {
|
||||
t.Fatal("cache get failed")
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
ipns "github.com/ipfs/go-ipns"
|
||||
pb "github.com/ipfs/go-ipns/pb"
|
||||
logging "github.com/ipfs/go-log"
|
||||
goprocess "github.com/jbenet/goprocess"
|
||||
@ -126,7 +127,7 @@ func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) erro
|
||||
log.Debugf("republishing ipns entry for %s", id)
|
||||
|
||||
// Look for it locally only
|
||||
p, err := rp.getLastVal(id)
|
||||
e, err := rp.getLastIPNSEntry(id)
|
||||
if err != nil {
|
||||
if err == errNoEntry {
|
||||
return nil
|
||||
@ -134,25 +135,34 @@ func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) erro
|
||||
return err
|
||||
}
|
||||
|
||||
p := path.Path(e.GetValue())
|
||||
prevEol, err := ipns.GetEOL(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update record with same sequence number
|
||||
eol := time.Now().Add(rp.RecordLifetime)
|
||||
if prevEol.After(eol) {
|
||||
eol = prevEol
|
||||
}
|
||||
return rp.ns.PublishWithEOL(ctx, priv, p, eol)
|
||||
}
|
||||
|
||||
func (rp *Republisher) getLastVal(id peer.ID) (path.Path, error) {
|
||||
func (rp *Republisher) getLastIPNSEntry(id peer.ID) (*pb.IpnsEntry, error) {
|
||||
// Look for it locally only
|
||||
val, err := rp.ds.Get(namesys.IpnsDsKey(id))
|
||||
switch err {
|
||||
case nil:
|
||||
case ds.ErrNotFound:
|
||||
return "", errNoEntry
|
||||
return nil, errNoEntry
|
||||
default:
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := new(pb.IpnsEntry)
|
||||
if err := proto.Unmarshal(val, e); err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return path.Path(e.Value), nil
|
||||
return e, nil
|
||||
}
|
||||
|
||||
@ -6,16 +6,22 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
goprocess "github.com/jbenet/goprocess"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
"github.com/ipfs/go-ipns"
|
||||
"github.com/ipfs/go-ipns/pb"
|
||||
path "github.com/ipfs/go-path"
|
||||
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
"github.com/ipfs/go-ipfs/core/bootstrap"
|
||||
mock "github.com/ipfs/go-ipfs/core/mock"
|
||||
namesys "github.com/ipfs/go-ipfs/namesys"
|
||||
. "github.com/ipfs/go-ipfs/namesys/republisher"
|
||||
path "github.com/ipfs/go-path"
|
||||
|
||||
goprocess "github.com/jbenet/goprocess"
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
|
||||
)
|
||||
|
||||
func TestRepublish(t *testing.T) {
|
||||
@ -109,6 +115,107 @@ func TestRepublish(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLongEOLRepublish(t *testing.T) {
|
||||
// set cache life to zero for testing low-period repubs
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// create network
|
||||
mn := mocknet.New(ctx)
|
||||
|
||||
var nodes []*core.IpfsNode
|
||||
for i := 0; i < 10; i++ {
|
||||
nd, err := mock.MockPublicNode(ctx, mn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
nd.Namesys = namesys.NewNameSystem(nd.Routing, nd.Repo.Datastore(), 0)
|
||||
|
||||
nodes = append(nodes, nd)
|
||||
}
|
||||
|
||||
if err := mn.LinkAll(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bsinf := bootstrap.BootstrapConfigWithPeers(
|
||||
[]peer.AddrInfo{
|
||||
nodes[0].Peerstore.PeerInfo(nodes[0].Identity),
|
||||
},
|
||||
)
|
||||
|
||||
for _, n := range nodes[1:] {
|
||||
if err := n.Bootstrap(bsinf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// have one node publish a record that is valid for 1 second
|
||||
publisher := nodes[3]
|
||||
p := path.FromString("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") // does not need to be valid
|
||||
rp := namesys.NewIpnsPublisher(publisher.Routing, publisher.Repo.Datastore())
|
||||
name := "/ipns/" + publisher.Identity.Pretty()
|
||||
|
||||
expiration := time.Now().Add(time.Hour)
|
||||
err := rp.PublishWithEOL(ctx, publisher.PrivateKey, p, expiration)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = verifyResolution(nodes, name, p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// The republishers that are contained within the nodes have their timeout set
|
||||
// to 12 hours. Instead of trying to tweak those, we're just going to pretend
|
||||
// they don't exist and make our own.
|
||||
repub := NewRepublisher(rp, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
|
||||
repub.Interval = time.Millisecond * 500
|
||||
repub.RecordLifetime = time.Second
|
||||
|
||||
proc := goprocess.Go(repub.Run)
|
||||
defer proc.Close()
|
||||
|
||||
// now wait a couple seconds for it to fire a few times
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
err = verifyResolution(nodes, name, p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
entry, err := getLastIPNSEntry(publisher.Repo.Datastore(), publisher.Identity)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
finalEol, err := ipns.GetEOL(entry)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !finalEol.Equal(expiration) {
|
||||
t.Fatal("expiration time modified")
|
||||
}
|
||||
}
|
||||
|
||||
func getLastIPNSEntry(dstore ds.Datastore, id peer.ID) (*ipns_pb.IpnsEntry, error) {
|
||||
// Look for it locally only
|
||||
val, err := dstore.Get(namesys.IpnsDsKey(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := new(ipns_pb.IpnsEntry)
|
||||
if err := proto.Unmarshal(val, e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func verifyResolution(nodes []*core.IpfsNode, key string, exp path.Path) error {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@ -69,20 +69,6 @@ func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, option
|
||||
return out
|
||||
}
|
||||
|
||||
// Name should be the hash of a public key retrievable from ipfs.
|
||||
// We retrieve the public key here to make certain that it's in the peer
|
||||
// store before calling GetValue() on the DHT - the DHT will call the
|
||||
// ipns validator, which in turn will get the public key from the peer
|
||||
// store to verify the record signature
|
||||
_, err = routing.GetPublicKey(r.routing, ctx, pid)
|
||||
if err != nil {
|
||||
log.Debugf("RoutingResolver: could not retrieve public key %s: %s\n", name, err)
|
||||
out <- onceResult{err: err}
|
||||
close(out)
|
||||
cancel()
|
||||
return out
|
||||
}
|
||||
|
||||
// Use the routing system to get the name.
|
||||
// Note that the DHT will call the ipns validator when retrieving
|
||||
// the value, which in turn verifies the ipns record signature
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/multiformats/go-multiaddr-net"
|
||||
"github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
// localListener manet streams and proxies them to libp2p services
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
net "github.com/libp2p/go-libp2p-core/network"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var maPrefix = "/" + ma.ProtocolWithCode(ma.P_IPFS).Name + "/"
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
peer "github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
const cmgrTag = "stream-fwd"
|
||||
|
||||
18
plugin/loader/load_nocgo.go
Normal file
18
plugin/loader/load_nocgo.go
Normal file
@ -0,0 +1,18 @@
|
||||
// +build !cgo,!noplugin
|
||||
// +build linux darwin
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
iplugin "github.com/ipfs/go-ipfs/plugin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
loadPluginFunc = nocgoLoadPlugin
|
||||
}
|
||||
|
||||
func nocgoLoadPlugin(fi string) ([]iplugin.Plugin, error) {
|
||||
return nil, errors.New("not built with cgo support")
|
||||
}
|
||||
17
plugin/loader/load_noplugin.go
Normal file
17
plugin/loader/load_noplugin.go
Normal file
@ -0,0 +1,17 @@
|
||||
// +build noplugin
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
iplugin "github.com/ipfs/go-ipfs/plugin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
loadPluginFunc = nopluginLoadPlugin
|
||||
}
|
||||
|
||||
func nopluginLoadPlugin(string) ([]iplugin.Plugin, error) {
|
||||
return nil, errors.New("not built with plugin support")
|
||||
}
|
||||
@ -1,56 +1,20 @@
|
||||
// +build !noplugin
|
||||
// +build linux,cgo darwin,cgo
|
||||
// +build cgo,!noplugin
|
||||
// +build linux darwin
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"plugin"
|
||||
|
||||
iplugin "github.com/ipfs/go-ipfs/plugin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
loadPluginsFunc = linuxLoadFunc
|
||||
loadPluginFunc = unixLoadPlugin
|
||||
}
|
||||
|
||||
func linuxLoadFunc(pluginDir string) ([]iplugin.Plugin, error) {
|
||||
var plugins []iplugin.Plugin
|
||||
|
||||
err := filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
if fi != pluginDir {
|
||||
log.Warnf("found directory inside plugins directory: %s", fi)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if info.Mode().Perm()&0111 == 0 {
|
||||
// file is not executable let's not load it
|
||||
// this is to prevent loading plugins from for example non-executable
|
||||
// mounts, some /tmp mounts are marked as such for security
|
||||
log.Errorf("non-executable file in plugins directory: %s", fi)
|
||||
return nil
|
||||
}
|
||||
|
||||
if newPlugins, err := loadPlugin(fi); err == nil {
|
||||
plugins = append(plugins, newPlugins...)
|
||||
} else {
|
||||
return fmt.Errorf("loading plugin %s: %s", fi, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return plugins, err
|
||||
}
|
||||
|
||||
func loadPlugin(fi string) ([]iplugin.Plugin, error) {
|
||||
func unixLoadPlugin(fi string) ([]iplugin.Plugin, error) {
|
||||
pl, err := plugin.Open(fi)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
config "github.com/ipfs/go-ipfs-config"
|
||||
@ -30,8 +31,8 @@ func Preload(plugins ...plugin.Plugin) {
|
||||
|
||||
var log = logging.Logger("plugin/loader")
|
||||
|
||||
var loadPluginsFunc = func(string) ([]plugin.Plugin, error) {
|
||||
return nil, nil
|
||||
var loadPluginFunc = func(string) ([]plugin.Plugin, error) {
|
||||
return nil, fmt.Errorf("unsupported platform %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
type loaderState int
|
||||
@ -182,7 +183,36 @@ func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return loadPluginsFunc(pluginDir)
|
||||
var plugins []plugin.Plugin
|
||||
|
||||
err = filepath.Walk(pluginDir, func(fi string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
if fi != pluginDir {
|
||||
log.Warnf("found directory inside plugins directory: %s", fi)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if info.Mode().Perm()&0111 == 0 {
|
||||
// file is not executable let's not load it
|
||||
// this is to prevent loading plugins from for example non-executable
|
||||
// mounts, some /tmp mounts are marked as such for security
|
||||
log.Errorf("non-executable file in plugins directory: %s", fi)
|
||||
return nil
|
||||
}
|
||||
|
||||
if newPlugins, err := loadPluginFunc(fi); err == nil {
|
||||
plugins = append(plugins, newPlugins...)
|
||||
} else {
|
||||
return fmt.Errorf("loading plugin %s: %s", fi, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return plugins, err
|
||||
}
|
||||
|
||||
// Initialize initializes all loaded plugins
|
||||
|
||||
44
snap/snapcraft.yaml
Normal file
44
snap/snapcraft.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
# This snap will build go-ipfs from source.
|
||||
name: ipfs
|
||||
summary: global, versioned, peer-to-peer filesystem # 79 char long summary
|
||||
description: |
|
||||
IPFS combines good ideas from Git, BitTorrent, Kademlia, SFS, and the Web.
|
||||
It is like a single bittorrent swarm, exchanging git objects. IPFS provides
|
||||
an interface as simple as the HTTP web, but with permanence built in. You
|
||||
can also mount the world at /ipfs.
|
||||
|
||||
# fetch the version number in the `ipfs` part rather than hardcode it here
|
||||
# see: https://snapcraft.io/docs/using-external-metadata#heading--scriptlet
|
||||
adopt-info: ipfs
|
||||
base: core18
|
||||
grade: stable
|
||||
confinement: strict
|
||||
|
||||
apps:
|
||||
ipfs:
|
||||
command: ipfs
|
||||
# the home plug is included so the user can `ipfs add` files from their home dir without a permission error.
|
||||
plugs: [home, network, network-bind, removable-media]
|
||||
environment:
|
||||
# Snaps versions are isolated by default. This keeps the same ipfs repo across upgrades.
|
||||
IPFS_PATH: "$SNAP_USER_COMMON"
|
||||
|
||||
parts:
|
||||
ipfs:
|
||||
source: '.'
|
||||
source-tag: master
|
||||
plugin: go
|
||||
# keep me up to date with the go version that go-ipfs expects to be built with.
|
||||
go-channel: 1.14/stable
|
||||
go-importpath: github.com/ipfs/go-ipfs
|
||||
build-packages:
|
||||
- build-essential
|
||||
|
||||
# use `make` to build and set the snap version from `ipfs version` output
|
||||
override-build: |
|
||||
export GOPATH=$SNAPCRAFT_PART_BUILD/go
|
||||
make install
|
||||
cp $SNAPCRAFT_PART_BUILD/go/bin/ipfs $SNAPCRAFT_PART_INSTALL
|
||||
export IPFS_VERSION=$($SNAPCRAFT_PART_BUILD/go/bin/ipfs version --commit | cut -c 14-)
|
||||
echo "found version $IPFS_VERSION"
|
||||
snapcraftctl set-version $IPFS_VERSION
|
||||
@ -4,27 +4,27 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd
|
||||
github.com/golangci/golangci-lint v1.18.0
|
||||
github.com/ipfs/go-blockservice v0.1.2
|
||||
github.com/ipfs/go-cid v0.0.5
|
||||
github.com/golangci/golangci-lint v1.26.0
|
||||
github.com/ipfs/go-blockservice v0.1.3
|
||||
github.com/ipfs/go-cid v0.0.6
|
||||
github.com/ipfs/go-cidutil v0.0.2
|
||||
github.com/ipfs/go-datastore v0.4.4
|
||||
github.com/ipfs/go-graphsync v0.0.4
|
||||
github.com/ipfs/go-graphsync v0.1.1
|
||||
github.com/ipfs/go-ipfs-blockstore v1.0.0
|
||||
github.com/ipfs/go-ipfs-exchange-offline v0.0.1
|
||||
github.com/ipfs/go-log v1.0.2
|
||||
github.com/ipfs/go-merkledag v0.3.1
|
||||
github.com/ipfs/go-log v1.0.4
|
||||
github.com/ipfs/go-merkledag v0.3.2
|
||||
github.com/ipfs/go-unixfs v0.2.4
|
||||
github.com/ipfs/hang-fds v0.0.2
|
||||
github.com/ipfs/iptb v1.4.0
|
||||
github.com/ipfs/iptb-plugins v0.2.2
|
||||
github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785
|
||||
github.com/ipfs/iptb-plugins v0.3.0
|
||||
github.com/ipld/go-ipld-prime v0.0.4-0.20200503082126-7e0619f3a984
|
||||
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
|
||||
github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded
|
||||
github.com/libp2p/go-libp2p v0.5.2
|
||||
github.com/libp2p/go-libp2p-core v0.3.1
|
||||
github.com/multiformats/go-multiaddr v0.2.0
|
||||
github.com/multiformats/go-multiaddr-net v0.1.2
|
||||
github.com/libp2p/go-libp2p v0.9.6
|
||||
github.com/libp2p/go-libp2p-core v0.5.7
|
||||
github.com/multiformats/go-multiaddr v0.2.2
|
||||
github.com/multiformats/go-multiaddr-net v0.1.5
|
||||
github.com/multiformats/go-multihash v0.0.13
|
||||
gotest.tools/gotestsum v0.3.5
|
||||
gotest.tools/gotestsum v0.4.2
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -13,16 +13,15 @@ import (
|
||||
dssync "github.com/ipfs/go-datastore/sync"
|
||||
"github.com/ipfs/go-graphsync"
|
||||
gsimpl "github.com/ipfs/go-graphsync/impl"
|
||||
"github.com/ipfs/go-graphsync/ipldbridge"
|
||||
"github.com/ipfs/go-graphsync/network"
|
||||
"github.com/ipfs/go-graphsync/storeutil"
|
||||
"github.com/ipfs/go-ipfs-blockstore"
|
||||
"github.com/ipfs/go-ipfs-exchange-offline"
|
||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
uio "github.com/ipfs/go-unixfs/io"
|
||||
"github.com/ipld/go-ipld-prime"
|
||||
ipldfree "github.com/ipld/go-ipld-prime/impl/free"
|
||||
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
|
||||
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
||||
ipldselector "github.com/ipld/go-ipld-prime/traversal/selector"
|
||||
"github.com/ipld/go-ipld-prime/traversal/selector/builder"
|
||||
"github.com/libp2p/go-libp2p"
|
||||
@ -33,16 +32,15 @@ import (
|
||||
|
||||
func newGraphsync(ctx context.Context, p2p host.Host, bs blockstore.Blockstore) (graphsync.GraphExchange, error) {
|
||||
network := network.NewFromLibp2pHost(p2p)
|
||||
ipldBridge := ipldbridge.NewIPLDBridge()
|
||||
return gsimpl.New(ctx,
|
||||
network, ipldBridge,
|
||||
network,
|
||||
storeutil.LoaderForBlockstore(bs),
|
||||
storeutil.StorerForBlockstore(bs),
|
||||
), nil
|
||||
}
|
||||
|
||||
var selectAll ipld.Node = func() ipld.Node {
|
||||
ssb := builder.NewSelectorSpecBuilder(ipldfree.NodeBuilder())
|
||||
ssb := builder.NewSelectorSpecBuilder(basicnode.Style.Any)
|
||||
return ssb.ExploreRecursive(
|
||||
ipldselector.RecursionLimitDepth(100), // default max
|
||||
ssb.ExploreAll(ssb.ExploreRecursiveEdge()),
|
||||
|
||||
@ -50,7 +50,8 @@ func TestDHTConnectivitySlowRouting(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var wanPrefix = net.ParseIP("2000::")
|
||||
// wan prefix must have a real corresponding ASN for the peer diversity filter to work.
|
||||
var wanPrefix = net.ParseIP("2001:218:3004::")
|
||||
var lanPrefix = net.ParseIP("fe80::")
|
||||
|
||||
func makeAddr(n uint32, wan bool) ma.Multiaddr {
|
||||
|
||||
@ -193,7 +193,7 @@ test_init_ipfs() {
|
||||
|
||||
test_expect_success "ipfs init succeeds" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
ipfs init --profile=test -b=2048 > /dev/null
|
||||
ipfs init --profile=test > /dev/null
|
||||
'
|
||||
|
||||
test_expect_success "prepare config -- mounting" '
|
||||
@ -443,14 +443,50 @@ file_size() {
|
||||
$_STAT "$1"
|
||||
}
|
||||
|
||||
# len 46: 2048-bit RSA keys, b58mh-encoded
|
||||
# len 52: ED25519 keys, b58mh-encoded
|
||||
# len 56: 2048-bit RSA keys, base36-encoded
|
||||
# len 62: ED25519 keys, base36-encoded
|
||||
test_check_peerid() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$peeridlen" = "46" || {
|
||||
test "$peeridlen" = "46" -o "$peeridlen" = "52" -o "$peeridlen" = "56" -o "$peeridlen" = "62" || {
|
||||
echo "Bad peerid '$1' with len '$peeridlen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
test_check_rsa2048_b58mh_peerid() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$peeridlen" = "46" || {
|
||||
echo "Bad RSA2048 B58MH peerid '$1' with len '$peeridlen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
test_check_ed25519_b58mh_peerid() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$peeridlen" = "52" || {
|
||||
echo "Bad ED25519 B58MH peerid '$1' with len '$peeridlen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
test_check_rsa2048_base36_peerid() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$peeridlen" = "56" || {
|
||||
echo "Bad RSA2048 B36CID peerid '$1' with len '$peeridlen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
test_check_ed25519_base36_peerid() {
|
||||
peeridlen=$(echo "$1" | tr -dC "[:alnum:]" | wc -c | tr -d " ") &&
|
||||
test "$peeridlen" = "62" || {
|
||||
echo "Bad ED25519 B36CID peerid '$1' with len '$peeridlen'"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
convert_tcp_maddr() {
|
||||
echo $1 | awk -F'/' '{ printf "%s:%s", $3, $5 }'
|
||||
}
|
||||
|
||||
@ -50,93 +50,154 @@ test_expect_success "ipfs cat no repo message looks good" '
|
||||
test_path_cmp cat_fail_exp cat_fail_out
|
||||
'
|
||||
|
||||
# test that init succeeds
|
||||
test_expect_success "ipfs init succeeds" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
echo "IPFS_PATH: \"$IPFS_PATH\"" &&
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" >actual_init ||
|
||||
test_fsh cat actual_init
|
||||
'
|
||||
# $1 must be one of 'rsa', 'ed25519' or '' (for default key algorithm).
|
||||
test_ipfs_init_flags() {
|
||||
TEST_ALG=$1
|
||||
|
||||
test_expect_success ".ipfs/ has been created" '
|
||||
test -d ".ipfs" &&
|
||||
test -f ".ipfs/config" &&
|
||||
test -d ".ipfs/datastore" &&
|
||||
test -d ".ipfs/blocks" &&
|
||||
test ! -f ._check_writeable ||
|
||||
test_fsh ls -al .ipfs
|
||||
'
|
||||
# test that init succeeds
|
||||
test_expect_success "ipfs init succeeds" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
echo "IPFS_PATH: \"$IPFS_PATH\"" &&
|
||||
RSA_BITS="2048" &&
|
||||
case $TEST_ALG in
|
||||
"rsa")
|
||||
ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init
|
||||
;;
|
||||
"ed25519")
|
||||
ipfs init --algorithm=ed25519 >actual_init || test_fsh cat actual_init
|
||||
;;
|
||||
*)
|
||||
ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "ipfs config succeeds" '
|
||||
echo /ipfs >expected_config &&
|
||||
ipfs config Mounts.IPFS >actual_config &&
|
||||
test_cmp expected_config actual_config
|
||||
'
|
||||
test_expect_success ".ipfs/ has been created" '
|
||||
test -d ".ipfs" &&
|
||||
test -f ".ipfs/config" &&
|
||||
test -d ".ipfs/datastore" &&
|
||||
test -d ".ipfs/blocks" &&
|
||||
test ! -f ._check_writeable ||
|
||||
test_fsh ls -al .ipfs
|
||||
'
|
||||
|
||||
test_expect_success "ipfs peer id looks good" '
|
||||
PEERID=$(ipfs config Identity.PeerID) &&
|
||||
test_check_peerid "$PEERID"
|
||||
'
|
||||
test_expect_success "ipfs config succeeds" '
|
||||
echo /ipfs >expected_config &&
|
||||
ipfs config Mounts.IPFS >actual_config &&
|
||||
test_cmp expected_config actual_config
|
||||
'
|
||||
|
||||
test_expect_success "ipfs init output looks good" '
|
||||
STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" &&
|
||||
echo "initializing IPFS node at $IPFS_PATH" >expected &&
|
||||
echo "generating $BITS-bit RSA keypair...done" >>expected &&
|
||||
echo "peer identity: $PEERID" >>expected &&
|
||||
echo "to get started, enter:" >>expected &&
|
||||
printf "\\n\\t$STARTFILE\\n\\n" >>expected &&
|
||||
test_cmp expected actual_init
|
||||
'
|
||||
test_expect_success "ipfs peer id looks good" '
|
||||
PEERID=$(ipfs config Identity.PeerID) &&
|
||||
test_check_peerid "$PEERID"
|
||||
'
|
||||
|
||||
test_expect_success "Welcome readme exists" '
|
||||
ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
|
||||
'
|
||||
test_expect_success "ipfs init output looks good" '
|
||||
STARTFILE="ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme" &&
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected &&
|
||||
echo "peer identity: $PEERID" >>rsa_expected &&
|
||||
echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected &&
|
||||
echo "to get started, enter:" >>rsa_expected &&
|
||||
printf "\\n\\t$STARTFILE\\n\\n" >>rsa_expected &&
|
||||
|
||||
test_expect_success "'ipfs init --empty-repo' succeeds" '
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" --empty-repo >actual_init
|
||||
'
|
||||
echo "generating ED25519 keypair...done" >ed25519_expected &&
|
||||
echo "peer identity: $PEERID" >>ed25519_expected &&
|
||||
echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected &&
|
||||
echo "to get started, enter:" >>ed25519_expected &&
|
||||
printf "\\n\\t$STARTFILE\\n\\n" >>ed25519_expected &&
|
||||
|
||||
test_expect_success "ipfs peer id looks good" '
|
||||
PEERID=$(ipfs config Identity.PeerID) &&
|
||||
test_check_peerid "$PEERID"
|
||||
'
|
||||
case $TEST_ALG in
|
||||
rsa)
|
||||
test_cmp rsa_expected actual_init
|
||||
;;
|
||||
ed25519)
|
||||
test_cmp ed25519_expected actual_init
|
||||
;;
|
||||
*)
|
||||
test_cmp rsa_expected actual_init
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs init --empty-repo' output looks good" '
|
||||
echo "initializing IPFS node at $IPFS_PATH" >expected &&
|
||||
echo "generating $BITS-bit RSA keypair...done" >>expected &&
|
||||
echo "peer identity: $PEERID" >>expected &&
|
||||
test_cmp expected actual_init
|
||||
'
|
||||
test_expect_success "Welcome readme exists" '
|
||||
ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
|
||||
'
|
||||
|
||||
test_expect_success "Welcome readme doesn't exist" '
|
||||
test_must_fail ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
|
||||
'
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
|
||||
test_expect_success "ipfs id agent string contains correct version" '
|
||||
ipfs id -f "<aver>" | grep $(ipfs version -n)
|
||||
'
|
||||
test_expect_success "'ipfs init --empty-repo' succeeds" '
|
||||
RSA_BITS="2048" &&
|
||||
case $TEST_ALG in
|
||||
rsa)
|
||||
ipfs init --algorithm=rsa --bits="$RSA_BITS" --empty-repo >actual_init
|
||||
;;
|
||||
ed25519)
|
||||
ipfs init --algorithm=ed25519 --empty-repo >actual_init
|
||||
;;
|
||||
*)
|
||||
ipfs init --empty-repo >actual_init
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
test_expect_success "ipfs peer id looks good" '
|
||||
PEERID=$(ipfs config Identity.PeerID) &&
|
||||
test_check_peerid "$PEERID"
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs init --empty-repo' output looks good" '
|
||||
|
||||
echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected &&
|
||||
echo "peer identity: $PEERID" >>rsa_expected &&
|
||||
echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected &&
|
||||
|
||||
echo "generating ED25519 keypair...done" >ed25519_expected &&
|
||||
echo "peer identity: $PEERID" >>ed25519_expected &&
|
||||
echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected &&
|
||||
|
||||
case $TEST_ALG in
|
||||
rsa)
|
||||
test_cmp rsa_expected actual_init
|
||||
;;
|
||||
ed25519)
|
||||
test_cmp ed25519_expected actual_init
|
||||
;;
|
||||
*)
|
||||
test_cmp ed25519_expected actual_init
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "Welcome readme doesn't exist" '
|
||||
test_must_fail ipfs cat /ipfs/$HASH_WELCOME_DOCS/readme
|
||||
'
|
||||
|
||||
test_expect_success "ipfs id agent string contains correct version" '
|
||||
ipfs id -f "<aver>" | grep $(ipfs version -n)
|
||||
'
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
}
|
||||
test_ipfs_init_flags 'ed25519'
|
||||
test_ipfs_init_flags 'rsa'
|
||||
test_ipfs_init_flags ''
|
||||
|
||||
# test init profiles
|
||||
test_expect_success "'ipfs init --profile' with invalid profile fails" '
|
||||
BITS="2048" &&
|
||||
test_must_fail ipfs init --bits="$BITS" --profile=nonexistent_profile 2> invalid_profile_out
|
||||
RSA_BITS="2048" &&
|
||||
test_must_fail ipfs init --profile=nonexistent_profile 2> invalid_profile_out
|
||||
EXPECT="Error: invalid configuration profile: nonexistent_profile" &&
|
||||
grep "$EXPECT" invalid_profile_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs init --profile' succeeds" '
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" --profile=server
|
||||
RSA_BITS="2048" &&
|
||||
ipfs init --profile=server
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config Swarm.AddrFilters' looks good" '
|
||||
@ -149,8 +210,8 @@ test_expect_success "clean up ipfs dir" '
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs init --profile=test' succeeds" '
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" --profile=test
|
||||
RSA_BITS="2048" &&
|
||||
ipfs init --profile=test
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config Bootstrap' looks good" '
|
||||
@ -182,8 +243,8 @@ test_expect_success "clean up ipfs dir" '
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs init --profile=lowpower' succeeds" '
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" --profile=lowpower
|
||||
RSA_BITS="2048" &&
|
||||
ipfs init --profile=lowpower
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs config Discovery.Routing' looks good" '
|
||||
|
||||
@ -16,7 +16,7 @@ test_expect_success "ipfs init succeeds" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
echo "IPFS_PATH: \"$IPFS_PATH\"" &&
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" >actual_init ||
|
||||
ipfs init >actual_init ||
|
||||
test_fsh cat actual_init
|
||||
'
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ test_description="Test non-standard datastores"
|
||||
|
||||
test_expect_success "'ipfs init --profile=badgerds' succeeds" '
|
||||
BITS="2048" &&
|
||||
ipfs init --bits="$BITS" --profile=badgerds
|
||||
ipfs init --profile=badgerds
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs pin ls' works" '
|
||||
|
||||
98
test/sharness/t0027-rotate.sh
Executable file
98
test/sharness/t0027-rotate.sh
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
test_description="Test rotate command"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_rotate() {
|
||||
FROM_ALG=$1
|
||||
TO_ALG=$2
|
||||
|
||||
test_expect_success "ipfs init (from $FROM_ALG, to $TO_ALG)" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
case $FROM_ALG in
|
||||
rsa)
|
||||
ipfs init --profile=test -a=rsa > /dev/null
|
||||
;;
|
||||
ed25519)
|
||||
ipfs init --profile=test -a=ed25519 > /dev/null
|
||||
;;
|
||||
*)
|
||||
ipfs init --profile=test > /dev/null
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "Save first ID and key" '
|
||||
ipfs id -f="<id>" > first_id &&
|
||||
ipfs id -f="<pubkey>" > first_key
|
||||
'
|
||||
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "rotating keys" '
|
||||
case $TO_ALG in
|
||||
rsa)
|
||||
ipfs key rotate -t=rsa -s=2048 --oldkey=oldkey
|
||||
;;
|
||||
ed25519)
|
||||
ipfs key rotate -t=ed25519 --oldkey=oldkey
|
||||
;;
|
||||
*)
|
||||
ipfs key rotate --oldkey=oldkey
|
||||
;;
|
||||
esac
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs key rotate -o self' should fail" '
|
||||
echo "Error: keystore name for back up cannot be named '\''self'\''" >expected-self
|
||||
test_must_fail ipfs key rotate -o self 2>actual-self &&
|
||||
test_cmp expected-self actual-self
|
||||
'
|
||||
|
||||
test_expect_success "Compare second ID and key to first" '
|
||||
ipfs id -f="<id>" > second_id &&
|
||||
ipfs id -f="<pubkey>" > second_key &&
|
||||
! test_cmp first_id second_id &&
|
||||
! test_cmp first_key second_key
|
||||
'
|
||||
|
||||
test_expect_success "checking ID" '
|
||||
ipfs config Identity.PeerID > expected-id &&
|
||||
ipfs id -f "<id>\n" > actual-id &&
|
||||
ipfs key list -l --ipns-base=b58mh | grep self | cut -d " " -f1 > keystore-id &&
|
||||
ipfs key list -l --ipns-base=b58mh | grep oldkey | cut -d " " -f1 | tr -d "\n" > old-keystore-id &&
|
||||
test_cmp expected-id actual-id &&
|
||||
test_cmp expected-id keystore-id &&
|
||||
test_cmp old-keystore-id first_id
|
||||
'
|
||||
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
test_expect_success "publish name with new and old keys" '
|
||||
echo "hello world" > msg &&
|
||||
ipfs add msg | cut -d " " -f2 | tr -d "\n" > msg_hash &&
|
||||
ipfs name publish --offline --allow-offline --key=self $(cat msg_hash) &&
|
||||
ipfs name publish --offline --allow-offline --key=oldkey $(cat msg_hash)
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
|
||||
}
|
||||
test_rotate 'rsa' ''
|
||||
test_rotate 'ed25519' ''
|
||||
test_rotate '' ''
|
||||
test_rotate 'rsa' 'rsa'
|
||||
test_rotate 'ed25519' 'rsa'
|
||||
test_rotate '' 'rsa'
|
||||
test_rotate 'rsa' 'ed25519'
|
||||
test_rotate 'ed25519' 'ed25519'
|
||||
test_rotate '' 'ed25519'
|
||||
|
||||
test_done
|
||||
@ -268,6 +268,41 @@ test_dag_cmd() {
|
||||
test_cmp resolve_obj_exp resolve_obj &&
|
||||
test_cmp resolve_data_exp resolve_data
|
||||
'
|
||||
|
||||
test_expect_success "dag stat of simple IPLD object" '
|
||||
ipfs dag stat $NESTED_HASH > actual_stat_inner_ipld_obj &&
|
||||
echo "Size: 15, NumBlocks: 1" > exp_stat_inner_ipld_obj &&
|
||||
test_cmp exp_stat_inner_ipld_obj actual_stat_inner_ipld_obj &&
|
||||
ipfs dag stat $HASH > actual_stat_ipld_obj &&
|
||||
echo "Size: 61, NumBlocks: 2" > exp_stat_ipld_obj &&
|
||||
test_cmp exp_stat_ipld_obj actual_stat_ipld_obj
|
||||
'
|
||||
|
||||
test_expect_success "dag stat of simple UnixFS object" '
|
||||
BASIC_UNIXFS=$(echo "1234" | ipfs add --pin=false -q) &&
|
||||
ipfs dag stat $BASIC_UNIXFS > actual_stat_basic_unixfs &&
|
||||
echo "Size: 13, NumBlocks: 1" > exp_stat_basic_unixfs &&
|
||||
test_cmp exp_stat_basic_unixfs actual_stat_basic_unixfs
|
||||
'
|
||||
|
||||
# The multiblock file is just 10000000 copies of the number 1
|
||||
# As most of its data is replicated it should have a small number of blocks
|
||||
test_expect_success "dag stat of multiblock UnixFS object" '
|
||||
MULTIBLOCK_UNIXFS=$(printf "1%.0s" {1..10000000} | ipfs add --pin=false -q) &&
|
||||
ipfs dag stat $MULTIBLOCK_UNIXFS > actual_stat_multiblock_unixfs &&
|
||||
echo "Size: 302582, NumBlocks: 3" > exp_stat_multiblock_unixfs &&
|
||||
test_cmp exp_stat_multiblock_unixfs actual_stat_multiblock_unixfs
|
||||
'
|
||||
|
||||
test_expect_success "dag stat of directory of UnixFS objects" '
|
||||
mkdir -p unixfsdir &&
|
||||
echo "1234" > unixfsdir/small.txt
|
||||
printf "1%.0s" {1..10000000} > unixfsdir/many1s.txt &&
|
||||
DIRECTORY_UNIXFS=$(ipfs add -r --pin=false -Q unixfsdir) &&
|
||||
ipfs dag stat $DIRECTORY_UNIXFS > actual_stat_directory_unixfs &&
|
||||
echo "Size: 302705, NumBlocks: 5" > exp_stat_directory_unixfs &&
|
||||
test_cmp exp_stat_directory_unixfs actual_stat_directory_unixfs
|
||||
'
|
||||
}
|
||||
|
||||
# should work offline
|
||||
|
||||
@ -128,7 +128,7 @@ test_expect_success "ipfs help output looks good" '
|
||||
# check transport is encrypted
|
||||
test_expect_success SOCAT "transport should be encrypted ( needs socat )" '
|
||||
socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-ls &&
|
||||
grep -q "/secio" swarmnc &&
|
||||
grep -q "/tls" swarmnc &&
|
||||
test_must_fail grep -q "/plaintext/1.0.0" swarmnc ||
|
||||
test_fsh cat swarmnc
|
||||
'
|
||||
|
||||
@ -8,209 +8,286 @@ test_description="Test ipfs repo operations"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_init_ipfs
|
||||
test_name_with_self() {
|
||||
SELF_ALG=$1
|
||||
|
||||
# test publishing a hash
|
||||
test_expect_success "ipfs init (variant self $SELF_ALG)" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
case $SELF_ALG in
|
||||
default)
|
||||
ipfs init --profile=test > /dev/null
|
||||
;;
|
||||
rsa)
|
||||
ipfs init --profile=test -a=rsa > /dev/null
|
||||
;;
|
||||
ed25519)
|
||||
ipfs init --profile=test -a=ed25519 > /dev/null
|
||||
;;
|
||||
esac &&
|
||||
export PEERID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
|
||||
test_check_peerid "${PEERID}"
|
||||
'
|
||||
|
||||
# test publishing a hash
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish output looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
test_expect_success "publish output looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# test publishing with -Q option
|
||||
# test publishing with -Q option
|
||||
|
||||
test_expect_success "'ipfs name publish --quieter' succeeds" '
|
||||
ipfs name publish --allow-offline -Q "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --quieter' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline -Q "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
test_expect_success "publish --quieter output looks good" '
|
||||
echo "${PEERID}" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "pubrmlish --quieter output looks good" '
|
||||
echo "${PEERID}" >expected1 &&
|
||||
test_cmp expected1 publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
# now test with a path
|
||||
|
||||
# now test with a path
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out
|
||||
'
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS/help" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS/help" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s/help\n" "$HASH_WELCOME_DOCS" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s/help\n" "$HASH_WELCOME_DOCS" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
test_expect_success "ipfs cat on published content succeeds" '
|
||||
ipfs cat "/ipfs/$HASH_WELCOME_DOCS/help" >expected &&
|
||||
ipfs cat "/ipns/$PEERID" >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "ipfs cat on published content succeeds" '
|
||||
ipfs cat "/ipfs/$HASH_WELCOME_DOCS/help" >expected &&
|
||||
ipfs cat "/ipns/$PEERID" >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
# publish with an explicit node ID
|
||||
|
||||
# publish with an explicit node ID
|
||||
test_expect_failure "'ipfs name publish --allow-offline <local-id> <hash>' succeeds" '
|
||||
echo ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" &&
|
||||
ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_failure "'ipfs name publish --allow-offline <local-id> <hash>' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
echo ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" &&
|
||||
ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
test_expect_failure "publish with our explicit node ID looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_failure "publish with our explicit node ID looks good" '
|
||||
echo "Published to ${PEERID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
# test publishing with B36CID and B58MH resolve to the same B36CID
|
||||
|
||||
# publish with an explicit node ID as key name
|
||||
test_expect_success "verify self key output" '
|
||||
B58MH_ID=`ipfs key list --ipns-base=b58mh -l | grep self | cut -d " " -f1` &&
|
||||
B36CID_ID=`ipfs key list --ipns-base=base36 -l | grep self | cut -d " " -f1` &&
|
||||
test_check_peerid "${B58MH_ID}" &&
|
||||
test_check_peerid "${B36CID_ID}"
|
||||
'
|
||||
|
||||
test_expect_success "generate and verify a new key" '
|
||||
NEWID=`ipfs key gen --type=rsa --size=2048 keyname` &&
|
||||
test_check_peerid "${NEWID}"
|
||||
'
|
||||
test_expect_success "'ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${B58MH_ID} "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_base36 &&
|
||||
ipfs name publish --allow-offline --key=${B36CID_ID} "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_base36 &&
|
||||
ipfs name publish --allow-offline --key=${B58MH_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >b58mh_published_id_b58mh &&
|
||||
ipfs name publish --allow-offline --key=${B36CID_ID} --ipns-base=b58mh "/ipfs/$HASH_WELCOME_DOCS" >base36_published_id_b58mh
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publis --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${NEWID} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
test_expect_success "publish an explicit node ID as two key in B58MH and B36CID, name looks good" '
|
||||
echo "Published to ${B36CID_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_base36 &&
|
||||
echo "Published to ${B58MH_ID}: /ipfs/$HASH_WELCOME_DOCS" >expected_published_id_b58mh &&
|
||||
test_cmp expected_published_id_base36 b58mh_published_id_base36 &&
|
||||
test_cmp expected_published_id_base36 base36_published_id_base36 &&
|
||||
test_cmp expected_published_id_b58mh b58mh_published_id_b58mh &&
|
||||
test_cmp expected_published_id_b58mh base36_published_id_b58mh
|
||||
'
|
||||
|
||||
test_expect_success "publish an explicit node ID as key name looks good" '
|
||||
echo "Published to ${NEWID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$B36CID_ID" >output
|
||||
'
|
||||
|
||||
# test IPNS + IPLD
|
||||
test_expect_success "'ipfs dag put' succeeds" '
|
||||
HELLO_HASH="$(echo "\"hello world\"" | ipfs dag put)" &&
|
||||
OBJECT_HASH="$(echo "{\"thing\": {\"/\": \"${HELLO_HASH}\" }}" | ipfs dag put)"
|
||||
'
|
||||
test_expect_success "'ipfs name publish --allow-offline /ipld/...' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline "/ipld/$OBJECT_HASH/thing" >publish_out
|
||||
'
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipld/$OBJECT_HASH/thing" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipfs/%s\n" "$HASH_WELCOME_DOCS" >expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# test publishing nothing
|
||||
# test IPNS + IPLD
|
||||
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish --allow-offline >publish_out 2>&1
|
||||
'
|
||||
test_expect_success "'ipfs dag put' succeeds" '
|
||||
HELLO_HASH="$(echo "\"hello world\"" | ipfs dag put)" &&
|
||||
OBJECT_HASH="$(echo "{\"thing\": {\"/\": \"${HELLO_HASH}\" }}" | ipfs dag put)"
|
||||
'
|
||||
test_expect_success "'ipfs name publish --allow-offline /ipld/...' succeeds" '
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline "/ipld/$OBJECT_HASH/thing" >publish_out
|
||||
'
|
||||
test_expect_success "publish a path looks good" '
|
||||
echo "Published to ${PEERID}: /ipld/$OBJECT_HASH/thing" >expected3 &&
|
||||
test_cmp expected3 publish_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (IPNS + IPLD)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
# test publishing nothing
|
||||
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish -Q --allow-offline >publish_out 2>&1
|
||||
'
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish --allow-offline >publish_out 2>&1
|
||||
'
|
||||
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --help' succeeds" '
|
||||
ipfs name publish --help
|
||||
'
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish -Q --allow-offline >publish_out 2>&1
|
||||
'
|
||||
|
||||
# test offline resolve
|
||||
test_expect_success "publish output has the correct error" '
|
||||
grep "argument \"ipfs-path\" is required" publish_out
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
test_expect_success "'ipfs name publish --help' succeeds" '
|
||||
ipfs name publish --help
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
# test offline resolve
|
||||
|
||||
test_launch_ipfs_daemon
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (offline resolve)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (offline resolve, -n)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
test_expect_success "empty request to name publish doesn't panic and returns error" '
|
||||
curl -X POST "http://$API_ADDR/api/v0/name/publish" > curl_out || true &&
|
||||
grep "argument \"ipfs-path\" is required" curl_out
|
||||
'
|
||||
test_expect_success "'ipfs name resolve --offline' succeeds" '
|
||||
ipfs name resolve --offline "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (with daemon)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
test_expect_success "'ipfs name resolve --offline -n' succeeds" '
|
||||
ipfs name resolve --offline -n "$PEERID" >output
|
||||
'
|
||||
test_expect_success "resolve output looks good (with daemon, -n)" '
|
||||
printf "/ipld/%s/thing\n" "$OBJECT_HASH" >expected4 &&
|
||||
test_cmp expected4 output
|
||||
'
|
||||
|
||||
test_expect_success "empty request to name publish doesn't panic and returns error" '
|
||||
curl -X POST "http://$API_ADDR/api/v0/name/publish" > curl_out || true &&
|
||||
grep "argument \"ipfs-path\" is required" curl_out
|
||||
'
|
||||
|
||||
# Test daemon in offline mode
|
||||
test_launch_ipfs_daemon --offline
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "'ipfs name publish' fails offline mode" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
test_expect_code 1 ipfs name publish "/ipfs/$HASH_WELCOME_DOCS"
|
||||
'
|
||||
# Test daemon in offline mode
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
test_expect_success "'ipfs name publish' fails offline mode" '
|
||||
test_expect_code 1 ipfs name publish "/ipfs/$HASH_WELCOME_DOCS"
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
}
|
||||
test_name_with_self 'default'
|
||||
test_name_with_self 'rsa'
|
||||
test_name_with_self 'ed25519'
|
||||
|
||||
test_name_with_key() {
|
||||
GEN_ALG=$1
|
||||
|
||||
test_expect_success "ipfs init (key variant $GEN_ALG)" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
ipfs init --profile=test > /dev/null
|
||||
'
|
||||
|
||||
test_expect_success "'prepare keys" '
|
||||
case $GEN_ALG in
|
||||
rsa)
|
||||
export KEY=`ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 key` &&
|
||||
export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
|
||||
;;
|
||||
ed25519_b58)
|
||||
export KEY=`ipfs key gen --ipns-base=b58mh --type=ed25519 key`
|
||||
export KEY_B36CID=`ipfs key list --ipns-base=base36 -l | grep key | cut -d " " -f1`
|
||||
;;
|
||||
ed25519_b36)
|
||||
export KEY=`ipfs key gen --ipns-base=base36 --type=ed25519 key`
|
||||
export KEY_B36CID=$KEY
|
||||
;;
|
||||
esac &&
|
||||
test_check_peerid "${KEY}"
|
||||
'
|
||||
|
||||
# publish with an explicit node ID as key name
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${KEY} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_success "publish an explicit node ID as key name looks good" '
|
||||
echo "Published to ${KEY_B36CID}: /ipfs/$HASH_WELCOME_DOCS" >expected_node_id_publish &&
|
||||
test_cmp expected_node_id_publish actual_node_id_publish
|
||||
'
|
||||
|
||||
# cleanup
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
}
|
||||
test_name_with_key 'rsa'
|
||||
test_name_with_key 'ed25519_b58'
|
||||
test_name_with_key 'ed25519_b36'
|
||||
|
||||
test_done
|
||||
|
||||
@ -63,7 +63,7 @@ test_expect_success "HTTP GET empty directory" '
|
||||
URL="http://127.0.0.1:$port/ipfs/$HASH_EMPTY_DIR/" &&
|
||||
echo "GET $URL" &&
|
||||
curl -so outfile "$URL" 2>curl_getEmpty.out &&
|
||||
grep "Index of /ipfs/$HASH_EMPTY_DIR/" outfile
|
||||
cat outfile | tr -s "\n" " " | grep "Index of /ipfs/<a href=\"/ipfs/$HASH_EMPTY_DIR\">$HASH_EMPTY_DIR</a>"
|
||||
'
|
||||
|
||||
test_expect_success "HTTP PUT file to construct a hierarchy" '
|
||||
|
||||
@ -84,7 +84,11 @@ test_hostname_gateway_response_should_contain() {
|
||||
## Start IPFS Node and prepare test CIDs
|
||||
## ============================================================================
|
||||
|
||||
test_init_ipfs
|
||||
test_expect_success "ipfs init" '
|
||||
export IPFS_PATH="$(pwd)/.ipfs" &&
|
||||
ipfs init --profile=test > /dev/null
|
||||
'
|
||||
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
# CIDv0to1 is necessary because raw-leaves are enabled by default during
|
||||
@ -94,12 +98,14 @@ test_expect_success "Add test text file" '
|
||||
CIDv1=$(echo $CID_VAL | ipfs add --cid-version 1 -Q)
|
||||
CIDv0=$(echo $CID_VAL | ipfs add --cid-version 0 -Q)
|
||||
CIDv0to1=$(echo "$CIDv0" | ipfs cid base32)
|
||||
echo CIDv0to1=${CIDv0to1}
|
||||
'
|
||||
|
||||
# Directory tree crafted to test for edge cases like "/ipfs/ipfs/ipns/bar"
|
||||
test_expect_success "Add the test directory" '
|
||||
mkdir -p testdirlisting/subdir1/subdir2 &&
|
||||
mkdir -p testdirlisting/ipfs/ipns &&
|
||||
echo "hello" > testdirlisting/hello &&
|
||||
echo "subdir2-bar" > testdirlisting/subdir1/subdir2/bar &&
|
||||
echo "text-file-content" > testdirlisting/ipfs/ipns/bar &&
|
||||
mkdir -p testdirlisting/api &&
|
||||
mkdir -p testdirlisting/ipfs &&
|
||||
echo "I am a txt file" > testdirlisting/api/file.txt &&
|
||||
@ -107,18 +113,29 @@ test_expect_success "Add the test directory" '
|
||||
DIR_CID=$(ipfs add -Qr --cid-version 1 testdirlisting)
|
||||
'
|
||||
|
||||
test_expect_success "Publish test text file to IPNS" '
|
||||
PEERID=$(ipfs id --format="<id>")
|
||||
IPNS_IDv0=$(echo "$PEERID" | ipfs cid format -v 0)
|
||||
IPNS_IDv1=$(echo "$PEERID" | ipfs cid format -v 1 --codec libp2p-key -b base32)
|
||||
IPNS_IDv1_DAGPB=$(echo "$IPNS_IDv0" | ipfs cid format -v 1 -b base32)
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
|
||||
ipfs name resolve "$PEERID" > output &&
|
||||
test_expect_success "Publish test text file to IPNS using RSA keys" '
|
||||
RSA_KEY=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 test_key_rsa | head -n1 | tr -d "\n")
|
||||
RSA_IPNS_IDv0=$(echo "$RSA_KEY" | ipfs cid format -v 0)
|
||||
RSA_IPNS_IDv1=$(echo "$RSA_KEY" | ipfs cid format -v 1 --codec libp2p-key -b base36)
|
||||
RSA_IPNS_IDv1_DAGPB=$(echo "$RSA_IPNS_IDv0" | ipfs cid format -v 1 -b base36)
|
||||
test_check_peerid "${RSA_KEY}" &&
|
||||
ipfs name publish --key test_key_rsa --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
|
||||
ipfs name resolve "$RSA_KEY" > output &&
|
||||
printf "/ipfs/%s\n" "$CIDv1" > expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
test_expect_success "Publish test text file to IPNS using ED25519 keys" '
|
||||
ED25519_KEY=$(ipfs key gen --ipns-base=b58mh --type=ed25519 test_key_ed25519 | head -n1 | tr -d "\n")
|
||||
ED25519_IPNS_IDv0=$ED25519_KEY
|
||||
ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=base36 | grep test_key_ed25519 | cut -d " " -f1 | tr -d "\n")
|
||||
ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --codec protobuf)
|
||||
test_check_peerid "${ED25519_KEY}" &&
|
||||
ipfs name publish --key test_key_ed25519 --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out &&
|
||||
ipfs name resolve "$ED25519_KEY" > output &&
|
||||
printf "/ipfs/%s\n" "$CIDv1" > expected2 &&
|
||||
test_cmp expected2 output
|
||||
'
|
||||
|
||||
# ensure we start with empty Gateway.PublicGateways
|
||||
test_expect_success 'start daemon with empty config for Gateway.PublicGateways' '
|
||||
@ -189,8 +206,13 @@ test_localhost_gateway_response_should_contain \
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for localhost/ipns/{CIDv0} redirects to CIDv1 with libp2p-key multicodec in subdomain" \
|
||||
"http://localhost:$GWAY_PORT/ipns/$IPNS_IDv0" \
|
||||
"Location: http://${IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
"http://localhost:$GWAY_PORT/ipns/$RSA_IPNS_IDv0" \
|
||||
"Location: http://${RSA_IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for localhost/ipns/{CIDv0} redirects to CIDv1 with libp2p-key multicodec in subdomain" \
|
||||
"http://localhost:$GWAY_PORT/ipns/$ED25519_IPNS_IDv0" \
|
||||
"Location: http://${ED25519_IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
|
||||
# /ipns/<dnslink-fqdn>
|
||||
|
||||
@ -248,33 +270,44 @@ DIR_HOSTNAME="${DIR_CID}.ipfs.localhost:$GWAY_PORT"
|
||||
test_expect_success "valid file and subdirectory paths in directory listing at {cid}.ipfs.localhost" '
|
||||
curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME" > list_response &&
|
||||
test_should_contain "<a href=\"/hello\">hello</a>" list_response &&
|
||||
test_should_contain "<a href=\"/subdir1\">subdir1</a>" list_response
|
||||
test_should_contain "<a href=\"/ipfs\">ipfs</a>" list_response
|
||||
'
|
||||
|
||||
test_expect_success "valid parent directory path in directory listing at {cid}.ipfs.localhost/sub/dir" '
|
||||
curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME/subdir1/subdir2/" > list_response &&
|
||||
test_should_contain "<a href=\"/subdir1/subdir2/./..\">..</a>" list_response &&
|
||||
test_should_contain "<a href=\"/subdir1/subdir2/bar\">bar</a>" list_response
|
||||
curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME/ipfs/ipns/" > list_response &&
|
||||
test_should_contain "<a href=\"/ipfs/ipns/./..\">..</a>" list_response &&
|
||||
test_should_contain "<a href=\"/ipfs/ipns/bar\">bar</a>" list_response
|
||||
'
|
||||
|
||||
test_expect_success "request for deep path resource at {cid}.ipfs.localhost/sub/dir/file" '
|
||||
curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME/subdir1/subdir2/bar" > list_response &&
|
||||
test_should_contain "subdir2-bar" list_response
|
||||
curl -s --resolve $DIR_HOSTNAME:127.0.0.1 "http://$DIR_HOSTNAME/ipfs/ipns/bar" > list_response &&
|
||||
test_should_contain "text-file-content" list_response
|
||||
'
|
||||
|
||||
|
||||
# *.ipns.localhost
|
||||
|
||||
# <libp2p-key>.ipns.localhost
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for {CIDv1-libp2p-key}.ipns.localhost returns expected payload" \
|
||||
"http://${IPNS_IDv1}.ipns.localhost:$GWAY_PORT" \
|
||||
"http://${RSA_IPNS_IDv1}.ipns.localhost:$GWAY_PORT" \
|
||||
"$CID_VAL"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"http://${IPNS_IDv1_DAGPB}.ipns.localhost:$GWAY_PORT" \
|
||||
"Location: http://${IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
"request for {CIDv1-libp2p-key}.ipns.localhost returns expected payload" \
|
||||
"http://${ED25519_IPNS_IDv1}.ipns.localhost:$GWAY_PORT" \
|
||||
"$CID_VAL"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"localhost request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"http://${RSA_IPNS_IDv1_DAGPB}.ipns.localhost:$GWAY_PORT" \
|
||||
"Location: http://${RSA_IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"localhost request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"http://${ED25519_IPNS_IDv1_DAGPB}.ipns.localhost:$GWAY_PORT" \
|
||||
"Location: http://${ED25519_IPNS_IDv1}.ipns.localhost:$GWAY_PORT/"
|
||||
|
||||
# <dnslink-fqdn>.ipns.localhost
|
||||
|
||||
@ -353,8 +386,14 @@ test_expect_success "request for http://example.com/ipfs/{CID} with X-Forwarded-
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/ipns/{CIDv0} redirects to CIDv1 with libp2p-key multicodec in subdomain" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_IDv0" \
|
||||
"Location: http://${IPNS_IDv1}.ipns.example.com/"
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$RSA_IPNS_IDv0" \
|
||||
"Location: http://${RSA_IPNS_IDv1}.ipns.example.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/ipns/{CIDv0} redirects to CIDv1 with libp2p-key multicodec in subdomain" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$ED25519_IPNS_IDv0" \
|
||||
"Location: http://${ED25519_IPNS_IDv1}.ipns.example.com/"
|
||||
|
||||
# example.com/ipns/<dnslink-fqdn>
|
||||
|
||||
@ -384,18 +423,25 @@ DIR_FQDN="${DIR_CID}.ipfs.example.com"
|
||||
test_expect_success "valid file and directory paths in directory listing at {cid}.ipfs.example.com" '
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT > list_response &&
|
||||
test_should_contain "<a href=\"/hello\">hello</a>" list_response &&
|
||||
test_should_contain "<a href=\"/subdir1\">subdir1</a>" list_response
|
||||
test_should_contain "<a href=\"/ipfs\">ipfs</a>" list_response
|
||||
'
|
||||
|
||||
test_expect_success "valid parent directory path in directory listing at {cid}.ipfs.example.com/sub/dir" '
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/subdir1/subdir2/ > list_response &&
|
||||
test_should_contain "<a href=\"/subdir1/subdir2/./..\">..</a>" list_response &&
|
||||
test_should_contain "<a href=\"/subdir1/subdir2/bar\">bar</a>" list_response
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/ > list_response &&
|
||||
test_should_contain "<a href=\"/ipfs/ipns/./..\">..</a>" list_response &&
|
||||
test_should_contain "<a href=\"/ipfs/ipns/bar\">bar</a>" list_response
|
||||
'
|
||||
|
||||
# Note we test for sneaky subdir names {cid}.ipfs.example.com/ipfs/ipns/ :^)
|
||||
test_expect_success "valid breadcrumb links in the header of directory listing at {cid}.ipfs.example.com/sub/dir" '
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/ > list_response &&
|
||||
test_should_contain "Index of" list_response &&
|
||||
test_should_contain "/ipfs/<a href=\"//example.com/ipfs/${DIR_CID}\">${DIR_CID}</a>/<a href=\"//example.com/ipfs/${DIR_CID}/ipfs\">ipfs</a>/<a href=\"//example.com/ipfs/${DIR_CID}/ipfs/ipns\">ipns</a>" list_response
|
||||
'
|
||||
|
||||
test_expect_success "request for deep path resource {cid}.ipfs.example.com/sub/dir/file" '
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/subdir1/subdir2/bar > list_response &&
|
||||
test_should_contain "subdir2-bar" list_response
|
||||
curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/bar > list_response &&
|
||||
test_should_contain "text-file-content" list_response
|
||||
'
|
||||
|
||||
# *.ipns.example.com
|
||||
@ -405,15 +451,27 @@ test_expect_success "request for deep path resource {cid}.ipfs.example.com/sub/d
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CIDv1-libp2p-key}.ipns.example.com returns expected payload" \
|
||||
"${IPNS_IDv1}.ipns.example.com" \
|
||||
"${RSA_IPNS_IDv1}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"$CID_VAL"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"${IPNS_IDv1_DAGPB}.ipns.example.com" \
|
||||
"request for {CIDv1-libp2p-key}.ipns.example.com returns expected payload" \
|
||||
"${ED25519_IPNS_IDv1}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"Location: http://${IPNS_IDv1}.ipns.example.com/"
|
||||
"$CID_VAL"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"hostname request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"${RSA_IPNS_IDv1_DAGPB}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"Location: http://${RSA_IPNS_IDv1}.ipns.example.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"hostname request for {CIDv1-dag-pb}.ipns.localhost redirects to CID with libp2p-key multicodec" \
|
||||
"${ED25519_IPNS_IDv1_DAGPB}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"Location: http://${ED25519_IPNS_IDv1}.ipns.example.com/"
|
||||
|
||||
# API on subdomain gateway example.com
|
||||
# ============================================================================
|
||||
@ -480,6 +538,66 @@ test_hostname_gateway_response_should_contain \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"$CID_VAL"
|
||||
|
||||
## Test subdomain handling of CIDs that do not fit in a single DNS Label (>63chars)
|
||||
## https://github.com/ipfs/go-ipfs/issues/7318
|
||||
## ============================================================================
|
||||
|
||||
# ed25519 fits under 63 char limit when represented in base36
|
||||
IPNS_KEY="test_key_ed25519"
|
||||
IPNS_ED25519_B58MH=$(ipfs key list -l -f b58mh | grep $IPNS_KEY | cut -d " " -f1 | tr -d "\n")
|
||||
IPNS_ED25519_B36CID=$(ipfs key list -l -f b36cid | grep $IPNS_KEY | cut -d " " -f1 | tr -d "\n")
|
||||
# sha512 will be over 63char limit, even when represented in Base36
|
||||
CIDv1_TOO_LONG=$(echo $CID_VAL | ipfs add --cid-version 1 --hash sha2-512 -Q)
|
||||
|
||||
# local: *.localhost
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for a ED25519 libp2p-key at localhost/ipns/{b58mh} returns Location HTTP header for DNS-safe subdomain redirect in browsers" \
|
||||
"http://localhost:$GWAY_PORT/ipns/$IPNS_ED25519_B58MH" \
|
||||
"Location: http://${IPNS_ED25519_B36CID}.ipns.localhost:$GWAY_PORT/"
|
||||
|
||||
# router should not redirect to hostnames that could fail due to DNS limits
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for a too long CID at localhost/ipfs/{CIDv1} returns human readable error" \
|
||||
"http://localhost:$GWAY_PORT/ipfs/$CIDv1_TOO_LONG" \
|
||||
"CID incompatible with DNS label length limit of 63"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for a too long CID at localhost/ipfs/{CIDv1} returns HTTP Error 400 Bad Request" \
|
||||
"http://localhost:$GWAY_PORT/ipfs/$CIDv1_TOO_LONG" \
|
||||
"400 Bad Request"
|
||||
|
||||
# direct request should also fail (provides the same UX as router and avoids confusion)
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for a too long CID at {CIDv1}.ipfs.localhost returns expected payload" \
|
||||
"http://$CIDv1_TOO_LONG.ipfs.localhost:$GWAY_PORT" \
|
||||
"400 Bad Request"
|
||||
|
||||
# public subdomain gateway: *.example.com
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for a ED25519 libp2p-key at example.com/ipns/{b58mh} returns Location HTTP header for DNS-safe subdomain redirect in browsers" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_ED25519_B58MH" \
|
||||
"Location: http://${IPNS_ED25519_B36CID}.ipns.example.com"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for a too long CID at example.com/ipfs/{CIDv1} returns human readable error" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1_TOO_LONG" \
|
||||
"CID incompatible with DNS label length limit of 63"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for a too long CID at example.com/ipfs/{CIDv1} returns HTTP Error 400 Bad Request" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1_TOO_LONG" \
|
||||
"400 Bad Request"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for a too long CID at {CIDv1}.ipfs.example.com returns HTTP Error 400 Bad Request" \
|
||||
"$CIDv1_TOO_LONG.ipfs.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"400 Bad Request"
|
||||
|
||||
# Disable selected Paths for the subdomain gateway hostname
|
||||
# =============================================================================
|
||||
|
||||
@ -497,16 +615,21 @@ test_launch_ipfs_daemon --offline
|
||||
# refuse requests to Paths that were not explicitly whitelisted for the hostname
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for *.ipns.example.com returns HTTP 404 Not Found when /ipns is not on Paths whitelist" \
|
||||
"${IPNS_IDv1}.ipns.example.com" \
|
||||
"${RSA_IPNS_IDv1}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"404 Not Found"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for *.ipns.example.com returns HTTP 404 Not Found when /ipns is not on Paths whitelist" \
|
||||
"${ED25519_IPNS_IDv1}.ipns.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"404 Not Found"
|
||||
|
||||
## ============================================================================
|
||||
## Test path-based requests with a custom hostname config
|
||||
## ============================================================================
|
||||
|
||||
# set explicit subdomain gateway config for the hostname
|
||||
# set explicit no-subdomain gateway config for the hostname
|
||||
ipfs config --json Gateway.PublicGateways '{
|
||||
"example.com": {
|
||||
"UseSubdomains": false,
|
||||
@ -540,7 +663,13 @@ test_hostname_gateway_response_should_contain \
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/ipns/ returns HTTP 404 Not Found when /ipns is not on Paths whitelist" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_IDv1" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$RSA_IPNS_IDv1" \
|
||||
"404 Not Found"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/ipns/ returns HTTP 404 Not Found when /ipns is not on Paths whitelist" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$ED25519_IPNS_IDv1" \
|
||||
"404 Not Found"
|
||||
|
||||
## ============================================================================
|
||||
@ -613,7 +742,13 @@ test_hostname_gateway_response_should_contain \
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {dnslink-fqdn}/ipns/{peerid} returns 404 when path is not whitelisted" \
|
||||
"$DNSLINK_FQDN" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$IPNS_IDv0" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$RSA_IPNS_IDv0" \
|
||||
"404 Not Found"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {dnslink-fqdn}/ipns/{peerid} returns 404 when path is not whitelisted" \
|
||||
"$DNSLINK_FQDN" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipns/$ED25519_IPNS_IDv0" \
|
||||
"404 Not Found"
|
||||
|
||||
# DNSLink disabled
|
||||
@ -664,9 +799,144 @@ test_hostname_gateway_response_should_contain \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"$CID_VAL"
|
||||
|
||||
## ============================================================================
|
||||
## Test support for X-Forwarded-Host
|
||||
## ============================================================================
|
||||
|
||||
# set explicit subdomain gateway config for the hostname
|
||||
ipfs config --json Gateway.PublicGateways '{
|
||||
"example.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs", "/ipns", "/api"]
|
||||
}
|
||||
}' || exit 1
|
||||
# restart daemon to apply config changes
|
||||
test_kill_ipfs_daemon
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
test_expect_success "request for http://fake.domain.com/ipfs/{CID} doesn't match the example.com gateway" "
|
||||
curl -H \"Host: fake.domain.com\" -sD - \"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1\" > response &&
|
||||
test_should_contain \"200 OK\" response
|
||||
"
|
||||
|
||||
test_expect_success "request for http://fake.domain.com/ipfs/{CID} with X-Forwarded-Host: example.com match the example.com gateway" "
|
||||
curl -H \"Host: fake.domain.com\" -H \"X-Forwarded-Host: example.com\" -sD - \"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1\" > response &&
|
||||
test_should_contain \"Location: http://$CIDv1.ipfs.example.com/\" response
|
||||
"
|
||||
|
||||
test_expect_success "request for http://fake.domain.com/ipfs/{CID} with X-Forwarded-Host: example.com and X-Forwarded-Proto: https match the example.com gateway, redirect with https" "
|
||||
curl -H \"Host: fake.domain.com\" -H \"X-Forwarded-Host: example.com\" -H \"X-Forwarded-Proto: https\" -sD - \"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1\" > response &&
|
||||
test_should_contain \"Location: https://$CIDv1.ipfs.example.com/\" response
|
||||
"
|
||||
|
||||
## ============================================================================
|
||||
## Test support for wildcards in gateway config
|
||||
## ============================================================================
|
||||
|
||||
# set explicit subdomain gateway config for the hostnames
|
||||
ipfs config --json Gateway.PublicGateways '{
|
||||
"*.example1.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs"]
|
||||
},
|
||||
"*.*.example2.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs"]
|
||||
},
|
||||
"foo.*.example3.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs"]
|
||||
},
|
||||
"foo.bar-*-boo.example4.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs"]
|
||||
}
|
||||
}' || exit 1
|
||||
# restart daemon to apply config changes
|
||||
test_kill_ipfs_daemon
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
# *.example1.com
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for foo.example1.com/ipfs/{CIDv1} produces redirect to {CIDv1}.ipfs.foo.example1.com" \
|
||||
"foo.example1.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1" \
|
||||
"Location: http://$CIDv1.ipfs.foo.example1.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CID}.ipfs.foo.example1.com should return expected payload" \
|
||||
"${CIDv1}.ipfs.foo.example1.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"$CID_VAL"
|
||||
|
||||
# *.*.example2.com
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for foo.bar.example2.com/ipfs/{CIDv1} produces redirect to {CIDv1}.ipfs.foo.bar.example2.com" \
|
||||
"foo.bar.example2.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1" \
|
||||
"Location: http://$CIDv1.ipfs.foo.bar.example2.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CID}.ipfs.foo.bar.example2.com should return expected payload" \
|
||||
"${CIDv1}.ipfs.foo.bar.example2.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"$CID_VAL"
|
||||
|
||||
# foo.*.example3.com
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for foo.bar.example3.com/ipfs/{CIDv1} produces redirect to {CIDv1}.ipfs.foo.bar.example3.com" \
|
||||
"foo.bar.example3.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1" \
|
||||
"Location: http://$CIDv1.ipfs.foo.bar.example3.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CID}.ipfs.foo.bar.example3.com should return expected payload" \
|
||||
"${CIDv1}.ipfs.foo.bar.example3.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"$CID_VAL"
|
||||
|
||||
# foo.bar-*-boo.example4.com
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for foo.bar-dev-boo.example4.com/ipfs/{CIDv1} produces redirect to {CIDv1}.ipfs.foo.bar-dev-boo.example4.com" \
|
||||
"foo.bar-dev-boo.example4.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/ipfs/$CIDv1" \
|
||||
"Location: http://$CIDv1.ipfs.foo.bar-dev-boo.example4.com/"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {CID}.ipfs.foo.bar-dev-boo.example4.com should return expected payload" \
|
||||
"${CIDv1}.ipfs.foo.bar-dev-boo.example4.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/" \
|
||||
"$CID_VAL"
|
||||
|
||||
## ============================================================================
|
||||
## Test support for overriding implicit defaults
|
||||
## ============================================================================
|
||||
|
||||
# disable subdomain gateway at localhost by removing implicit config
|
||||
ipfs config --json Gateway.PublicGateways '{
|
||||
"localhost": null
|
||||
}' || exit 1
|
||||
|
||||
# restart daemon to apply config changes
|
||||
test_kill_ipfs_daemon
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for localhost/ipfs/{CID} stays on path when subdomain gw is explicitly disabled" \
|
||||
"http://localhost:$GWAY_PORT/ipfs/$CIDv1" \
|
||||
"$CID_VAL"
|
||||
|
||||
# =============================================================================
|
||||
# ensure we end with empty Gateway.PublicGateways
|
||||
ipfs config --json Gateway.PublicGateways '{}'
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_expect_success "clean up ipfs dir" '
|
||||
rm -rf "$IPFS_PATH"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@ -123,6 +123,25 @@ test_expect_success "/p2p addresses work" '
|
||||
[ $(ipfsi 0 swarm peers | wc -l) -eq 1 ]
|
||||
'
|
||||
|
||||
test_expect_success "ipfs id is consistent for node 0" '
|
||||
ipfsi 1 id "$(iptb attr get 0 id)" > 1see0 &&
|
||||
ipfsi 0 id > 0see0 &&
|
||||
test_cmp 1see0 0see0
|
||||
'
|
||||
|
||||
test_expect_success "ipfs id is consistent for node 1" '
|
||||
ipfsi 0 id "$(iptb attr get 1 id)" > 0see1 &&
|
||||
ipfsi 1 id > 1see1 &&
|
||||
test_cmp 0see1 1see1
|
||||
'
|
||||
|
||||
test_expect_success "addresses contain /p2p/..." '
|
||||
test_should_contain "/p2p/$(iptb attr get 1 id)\"" 0see1 &&
|
||||
test_should_contain "/p2p/$(iptb attr get 1 id)\"" 1see1 &&
|
||||
test_should_contain "/p2p/$(iptb attr get 0 id)\"" 1see0 &&
|
||||
test_should_contain "/p2p/$(iptb attr get 0 id)\"" 0see0
|
||||
'
|
||||
|
||||
test_expect_success "stopping cluster" '
|
||||
iptb stop
|
||||
'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user