Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
cd37b674
提交
cd37b674
authored
5月 08, 2015
作者:
Juan Batiz-Benet
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1189 from ipfs/refactor/coreResolve
core: add context.Context param to core.Resolve()
上级
d529ccbc
f640ba00
隐藏空白字符变更
内嵌
并排
正在显示
15 个修改的文件
包含
134 行增加
和
128 行删除
+134
-128
handler.go
commands/http/handler.go
+22
-5
cat.go
core/commands/cat.go
+1
-1
get.go
core/commands/get.go
+6
-5
ls.go
core/commands/ls.go
+1
-1
object.go
core/commands/object.go
+10
-41
publish.go
core/commands/publish.go
+7
-4
refs.go
core/commands/refs.go
+3
-3
gateway_handler.go
core/corehttp/gateway_handler.go
+7
-3
pinning.go
core/corerepo/pinning.go
+8
-4
cat.go
core/coreunix/cat.go
+1
-1
pathresolver.go
core/pathresolver.go
+29
-12
readonly_unix.go
fuse/readonly/readonly_unix.go
+2
-2
system.go
ipnsfs/system.go
+1
-1
resolver.go
path/resolver.go
+14
-15
x0111-gateway-writable.sh
test/sharness/x0111-gateway-writable.sh
+22
-30
没有找到文件。
commands/http/handler.go
浏览文件 @
cd37b674
...
...
@@ -9,6 +9,7 @@ import (
"strings"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
cmds
"github.com/ipfs/go-ipfs/commands"
u
"github.com/ipfs/go-ipfs/util"
)
...
...
@@ -48,11 +49,6 @@ func NewHandler(ctx cmds.Context, root *cmds.Command, origin string) *Handler {
}
func
(
i
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// create a context.Context to pass into the commands.
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
TODO
())
defer
cancel
()
i
.
ctx
.
Context
=
ctx
log
.
Debug
(
"Incoming API request: "
,
r
.
URL
)
// error on external referers (to prevent CSRF attacks)
...
...
@@ -84,6 +80,27 @@ func (i Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w
.
Write
([]
byte
(
err
.
Error
()))
return
}
// get the node's context to pass into the commands.
node
,
err
:=
i
.
ctx
.
GetNode
()
if
err
!=
nil
{
err
=
fmt
.
Errorf
(
"cmds/http: couldn't GetNode(): %s"
,
err
)
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
ctx
,
cancel
:=
context
.
WithCancel
(
node
.
Context
())
defer
cancel
()
/*
TODO(cryptix): the next line looks very fishy to me..
It looks like the the context for the command request beeing prepared here is shared across all incoming requests..
I assume it really isn't because ServeHTTP() doesn't take a pointer receiver, but it's really subtule..
Shouldn't the context be just put on the command request?
ps: take note of the name clash - commands.Context != context.Context
*/
i
.
ctx
.
Context
=
ctx
req
.
SetContext
(
i
.
ctx
)
// call the command
...
...
core/commands/cat.go
浏览文件 @
cd37b674
...
...
@@ -62,7 +62,7 @@ func cat(ctx context.Context, node *core.IpfsNode, paths []string) ([]io.Reader,
readers
:=
make
([]
io
.
Reader
,
0
,
len
(
paths
))
length
:=
uint64
(
0
)
for
_
,
fpath
:=
range
paths
{
dagnode
,
err
:=
core
.
Resolve
(
node
,
path
.
Path
(
fpath
))
dagnode
,
err
:=
core
.
Resolve
(
ctx
,
node
,
path
.
Path
(
fpath
))
if
err
!=
nil
{
return
nil
,
0
,
err
}
...
...
core/commands/get.go
浏览文件 @
cd37b674
...
...
@@ -9,13 +9,14 @@ import (
gopath
"path"
"strings"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/cheggaaa/pb"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
cmds
"github.com/ipfs/go-ipfs/commands"
core
"github.com/ipfs/go-ipfs/core"
path
"github.com/ipfs/go-ipfs/path"
tar
"github.com/ipfs/go-ipfs/thirdparty/tar"
utar
"github.com/ipfs/go-ipfs/unixfs/tar"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/cheggaaa/pb"
)
var
ErrInvalidCompressionLevel
=
errors
.
New
(
"Compression level must be between 1 and 9"
)
...
...
@@ -62,7 +63,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
return
}
reader
,
err
:=
get
(
node
,
req
.
Arguments
()[
0
],
cmplvl
)
reader
,
err
:=
get
(
req
.
Context
()
.
Context
,
node
,
req
.
Arguments
()[
0
],
cmplvl
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -165,9 +166,9 @@ func getCompressOptions(req cmds.Request) (int, error) {
return
gzip
.
NoCompression
,
nil
}
func
get
(
node
*
core
.
IpfsNode
,
p
string
,
compression
int
)
(
io
.
Reader
,
error
)
{
func
get
(
ctx
context
.
Context
,
node
*
core
.
IpfsNode
,
p
string
,
compression
int
)
(
io
.
Reader
,
error
)
{
pathToResolve
:=
path
.
Path
(
p
)
dagnode
,
err
:=
core
.
Resolve
(
node
,
pathToResolve
)
dagnode
,
err
:=
core
.
Resolve
(
ctx
,
node
,
pathToResolve
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
core/commands/ls.go
浏览文件 @
cd37b674
...
...
@@ -66,7 +66,7 @@ it contains, with the following format:
dagnodes
:=
make
([]
*
merkledag
.
Node
,
0
)
for
_
,
fpath
:=
range
paths
{
dagnode
,
err
:=
core
.
Resolve
(
node
,
path
.
Path
(
fpath
))
dagnode
,
err
:=
core
.
Resolve
(
req
.
Context
()
.
Context
,
node
,
path
.
Path
(
fpath
))
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
core/commands/object.go
浏览文件 @
cd37b674
...
...
@@ -91,12 +91,12 @@ output is the raw data of the object.
}
fpath
:=
path
.
Path
(
req
.
Arguments
()[
0
])
output
,
err
:=
objectData
(
n
,
fpath
)
node
,
err
:=
core
.
Resolve
(
req
.
Context
()
.
Context
,
n
,
fpath
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
}
res
.
SetOutput
(
output
)
res
.
SetOutput
(
bytes
.
NewReader
(
node
.
Data
)
)
},
}
...
...
@@ -121,7 +121,12 @@ multihash.
}
fpath
:=
path
.
Path
(
req
.
Arguments
()[
0
])
output
,
err
:=
objectLinks
(
n
,
fpath
)
node
,
err
:=
core
.
Resolve
(
req
.
Context
()
.
Context
,
n
,
fpath
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
}
output
,
err
:=
getOutput
(
node
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -176,7 +181,7 @@ This command outputs data in the following encodings:
fpath
:=
path
.
Path
(
req
.
Arguments
()[
0
])
object
,
err
:=
objectGet
(
n
,
fpath
)
object
,
err
:=
core
.
Resolve
(
req
.
Context
()
.
Context
,
n
,
fpath
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -242,7 +247,7 @@ var objectStatCmd = &cmds.Command{
fpath
:=
path
.
Path
(
req
.
Arguments
()[
0
])
object
,
err
:=
objectGet
(
n
,
fpath
)
object
,
err
:=
core
.
Resolve
(
req
.
Context
()
.
Context
,
n
,
fpath
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -343,42 +348,6 @@ Data should be in the format specified by the --inputenc flag.
Type
:
Object
{},
}
// objectData takes a key string and writes out the raw bytes of that node (if there is one)
func
objectData
(
n
*
core
.
IpfsNode
,
fpath
path
.
Path
)
(
io
.
Reader
,
error
)
{
dagnode
,
err
:=
core
.
Resolve
(
n
,
fpath
)
if
err
!=
nil
{
return
nil
,
err
}
log
.
Debugf
(
"objectData: found dagnode %s (# of bytes: %d - # links: %d)"
,
fpath
,
len
(
dagnode
.
Data
),
len
(
dagnode
.
Links
))
return
bytes
.
NewReader
(
dagnode
.
Data
),
nil
}
// objectLinks takes a key string and lists the links it points to
func
objectLinks
(
n
*
core
.
IpfsNode
,
fpath
path
.
Path
)
(
*
Object
,
error
)
{
dagnode
,
err
:=
core
.
Resolve
(
n
,
fpath
)
if
err
!=
nil
{
return
nil
,
err
}
log
.
Debugf
(
"objectLinks: found dagnode %s (# of bytes: %d - # links: %d)"
,
fpath
,
len
(
dagnode
.
Data
),
len
(
dagnode
.
Links
))
return
getOutput
(
dagnode
)
}
// objectGet takes a key string from args and a format option and serializes the dagnode to that format
func
objectGet
(
n
*
core
.
IpfsNode
,
fpath
path
.
Path
)
(
*
dag
.
Node
,
error
)
{
dagnode
,
err
:=
core
.
Resolve
(
n
,
fpath
)
if
err
!=
nil
{
return
nil
,
err
}
log
.
Debugf
(
"objectGet: found dagnode %s (# of bytes: %d - # links: %d)"
,
fpath
,
len
(
dagnode
.
Data
),
len
(
dagnode
.
Links
))
return
dagnode
,
nil
}
// ErrEmptyNode is returned when the input to 'ipfs object put' contains no data
var
ErrEmptyNode
=
errors
.
New
(
"no data or links in this node"
)
...
...
core/commands/publish.go
浏览文件 @
cd37b674
...
...
@@ -6,6 +6,8 @@ import (
"io"
"strings"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
cmds
"github.com/ipfs/go-ipfs/commands"
core
"github.com/ipfs/go-ipfs/core"
crypto
"github.com/ipfs/go-ipfs/p2p/crypto"
...
...
@@ -89,7 +91,8 @@ Publish an <ipfs-path> to another public key (not implemented):
}
// TODO n.Keychain.Get(name).PrivKey
output
,
err
:=
publish
(
n
,
n
.
PrivateKey
,
p
)
// TODO(cryptix): is req.Context().Context a child of n.Context()?
output
,
err
:=
publish
(
req
.
Context
()
.
Context
,
n
,
n
.
PrivateKey
,
p
)
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -106,14 +109,14 @@ Publish an <ipfs-path> to another public key (not implemented):
Type
:
IpnsEntry
{},
}
func
publish
(
n
*
core
.
IpfsNode
,
k
crypto
.
PrivKey
,
ref
path
.
Path
)
(
*
IpnsEntry
,
error
)
{
func
publish
(
ctx
context
.
Context
,
n
*
core
.
IpfsNode
,
k
crypto
.
PrivKey
,
ref
path
.
Path
)
(
*
IpnsEntry
,
error
)
{
// First, verify the path exists
_
,
err
:=
core
.
Resolve
(
n
,
ref
)
_
,
err
:=
core
.
Resolve
(
ctx
,
n
,
ref
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
n
.
Namesys
.
Publish
(
n
.
Context
()
,
k
,
ref
)
err
=
n
.
Namesys
.
Publish
(
ctx
,
k
,
ref
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
core/commands/refs.go
浏览文件 @
cd37b674
...
...
@@ -85,7 +85,7 @@ Note: list all refs recursively with -r.
return
}
objs
,
err
:=
objectsForPaths
(
n
,
req
.
Arguments
())
objs
,
err
:=
objectsForPaths
(
ctx
,
n
,
req
.
Arguments
())
if
err
!=
nil
{
res
.
SetError
(
err
,
cmds
.
ErrNormal
)
return
...
...
@@ -161,10 +161,10 @@ Displays the hashes of all local objects.
},
}
func
objectsForPaths
(
n
*
core
.
IpfsNode
,
paths
[]
string
)
([]
*
dag
.
Node
,
error
)
{
func
objectsForPaths
(
ctx
context
.
Context
,
n
*
core
.
IpfsNode
,
paths
[]
string
)
([]
*
dag
.
Node
,
error
)
{
objects
:=
make
([]
*
dag
.
Node
,
len
(
paths
))
for
i
,
p
:=
range
paths
{
o
,
err
:=
core
.
Resolve
(
n
,
path
.
Path
(
p
))
o
,
err
:=
core
.
Resolve
(
ctx
,
n
,
path
.
Path
(
p
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
core/corehttp/gateway_handler.go
浏览文件 @
cd37b674
package
corehttp
import
(
"errors"
"fmt"
"html/template"
"io"
...
...
@@ -101,7 +102,7 @@ func (i *gatewayHandler) ResolvePath(ctx context.Context, p string) (*dag.Node,
return
nil
,
""
,
err
}
node
,
err
:=
i
.
node
.
Resolver
.
ResolvePath
(
path
.
Path
(
p
))
node
,
err
:=
i
.
node
.
Resolver
.
ResolvePath
(
ctx
,
path
.
Path
(
p
))
if
err
!=
nil
{
return
nil
,
""
,
err
}
...
...
@@ -309,6 +310,9 @@ func (i *gatewayHandler) putEmptyDirHandler(w http.ResponseWriter, r *http.Reque
}
func
(
i
*
gatewayHandler
)
putHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// TODO(cryptix): will be resolved in PR#1191
webErrorWithCode
(
w
,
"Sorry, PUT is bugged right now, closing request"
,
errors
.
New
(
"handler disabled"
),
http
.
StatusInternalServerError
)
return
urlPath
:=
r
.
URL
.
Path
pathext
:=
urlPath
[
5
:
]
var
err
error
...
...
@@ -362,7 +366,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
// resolving path components into merkledag nodes. if a component does not
// resolve, create empty directories (which will be linked and populated below.)
path_nodes
,
err
:=
i
.
node
.
Resolver
.
ResolveLinks
(
rootnd
,
components
[
:
len
(
components
)
-
1
])
path_nodes
,
err
:=
i
.
node
.
Resolver
.
ResolveLinks
(
tctx
,
rootnd
,
components
[
:
len
(
components
)
-
1
])
if
_
,
ok
:=
err
.
(
path
.
ErrNoLink
);
ok
{
// Create empty directories, links will be made further down the code
for
len
(
path_nodes
)
<
len
(
components
)
{
...
...
@@ -424,7 +428,7 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
return
}
path_nodes
,
err
:=
i
.
node
.
Resolver
.
ResolveLinks
(
rootnd
,
components
[
:
len
(
components
)
-
1
])
path_nodes
,
err
:=
i
.
node
.
Resolver
.
ResolveLinks
(
tctx
,
rootnd
,
components
[
:
len
(
components
)
-
1
])
if
err
!=
nil
{
webError
(
w
,
"Could not resolve parent object"
,
err
,
http
.
StatusBadRequest
)
return
...
...
core/corerepo/pinning.go
浏览文件 @
cd37b674
...
...
@@ -26,10 +26,12 @@ import (
)
func
Pin
(
n
*
core
.
IpfsNode
,
paths
[]
string
,
recursive
bool
)
([]
u
.
Key
,
error
)
{
// TODO(cryptix): do we want a ctx as first param for (Un)Pin() as well, just like core.Resolve?
ctx
:=
n
.
Context
()
dagnodes
:=
make
([]
*
merkledag
.
Node
,
0
)
for
_
,
fpath
:=
range
paths
{
dagnode
,
err
:=
core
.
Resolve
(
n
,
path
.
Path
(
fpath
))
dagnode
,
err
:=
core
.
Resolve
(
ctx
,
n
,
path
.
Path
(
fpath
))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"pin: %s"
,
err
)
}
...
...
@@ -43,7 +45,7 @@ func Pin(n *core.IpfsNode, paths []string, recursive bool) ([]u.Key, error) {
return
nil
,
err
}
ctx
,
cancel
:=
context
.
WithTimeout
(
c
ontext
.
TODO
()
,
time
.
Minute
)
ctx
,
cancel
:=
context
.
WithTimeout
(
c
tx
,
time
.
Minute
)
defer
cancel
()
err
=
n
.
Pinning
.
Pin
(
ctx
,
dagnode
,
recursive
)
if
err
!=
nil
{
...
...
@@ -61,10 +63,12 @@ func Pin(n *core.IpfsNode, paths []string, recursive bool) ([]u.Key, error) {
}
func
Unpin
(
n
*
core
.
IpfsNode
,
paths
[]
string
,
recursive
bool
)
([]
u
.
Key
,
error
)
{
// TODO(cryptix): do we want a ctx as first param for (Un)Pin() as well, just like core.Resolve?
ctx
:=
n
.
Context
()
dagnodes
:=
make
([]
*
merkledag
.
Node
,
0
)
for
_
,
fpath
:=
range
paths
{
dagnode
,
err
:=
core
.
Resolve
(
n
,
path
.
Path
(
fpath
))
dagnode
,
err
:=
core
.
Resolve
(
ctx
,
n
,
path
.
Path
(
fpath
))
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -75,7 +79,7 @@ func Unpin(n *core.IpfsNode, paths []string, recursive bool) ([]u.Key, error) {
for
_
,
dagnode
:=
range
dagnodes
{
k
,
_
:=
dagnode
.
Key
()
ctx
,
cancel
:=
context
.
WithTimeout
(
c
ontext
.
TODO
()
,
time
.
Minute
)
ctx
,
cancel
:=
context
.
WithTimeout
(
c
tx
,
time
.
Minute
)
defer
cancel
()
err
:=
n
.
Pinning
.
Unpin
(
ctx
,
k
,
recursive
)
if
err
!=
nil
{
...
...
core/coreunix/cat.go
浏览文件 @
cd37b674
...
...
@@ -10,7 +10,7 @@ import (
func
Cat
(
n
*
core
.
IpfsNode
,
pstr
string
)
(
io
.
Reader
,
error
)
{
p
:=
path
.
FromString
(
pstr
)
dagNode
,
err
:=
n
.
Resolver
.
ResolvePath
(
p
)
dagNode
,
err
:=
n
.
Resolver
.
ResolvePath
(
n
.
ContextGroup
.
Context
(),
p
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
core/pathresolver.go
浏览文件 @
cd37b674
...
...
@@ -5,22 +5,35 @@ import (
"fmt"
"strings"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
merkledag
"github.com/ipfs/go-ipfs/merkledag"
path
"github.com/ipfs/go-ipfs/path"
)
const
maxLinks
=
32
var
ErrTooManyLinks
=
errors
.
New
(
"exceeded maximum number of links in ipns entry"
)
// errors returned by Resolve function
var
(
ErrTooManyLinks
=
errors
.
New
(
"core/resolve: exceeded maximum number of links in ipns entry"
)
ErrNoNamesys
=
errors
.
New
(
"core/resolve: no Namesys on IpfsNode - can't resolve ipns entry"
)
)
// Resolves the given path by parsing out /ipns/ entries and then going
// Resolve
resolve
s the given path by parsing out /ipns/ entries and then going
// through the /ipfs/ entries and returning the final merkledage node.
// Effectively enables /ipns/ in CLI commands.
func
Resolve
(
n
*
IpfsNode
,
p
path
.
Path
)
(
*
merkledag
.
Node
,
error
)
{
return
resolveRecurse
(
n
,
p
,
0
)
func
Resolve
(
ctx
context
.
Context
,
n
*
IpfsNode
,
p
path
.
Path
)
(
*
merkledag
.
Node
,
error
)
{
r
:=
resolver
{
ctx
,
n
,
p
}
return
r
.
resolveRecurse
(
0
)
}
func
resolveRecurse
(
n
*
IpfsNode
,
p
path
.
Path
,
depth
int
)
(
*
merkledag
.
Node
,
error
)
{
type
resolver
struct
{
ctx
context
.
Context
n
*
IpfsNode
p
path
.
Path
}
func
(
r
*
resolver
)
resolveRecurse
(
depth
int
)
(
*
merkledag
.
Node
,
error
)
{
if
depth
>=
maxLinks
{
return
nil
,
ErrTooManyLinks
}
...
...
@@ -29,29 +42,33 @@ func resolveRecurse(n *IpfsNode, p path.Path, depth int) (*merkledag.Node, error
// emerges when resolving just a <hash>. Is it meant
// to be an ipfs or an ipns resolution?
if
strings
.
HasPrefix
(
p
.
String
(),
"/ipns/"
)
{
if
strings
.
HasPrefix
(
r
.
p
.
String
(),
"/ipns/"
)
{
// TODO(cryptix): we sould be able to query the local cache for the path
if
r
.
n
.
Namesys
==
nil
{
return
nil
,
ErrNoNamesys
}
// if it's an ipns path, try to resolve it.
// if we can't, we can give that error back to the user.
seg
:=
p
.
Segments
()
seg
:=
r
.
p
.
Segments
()
if
len
(
seg
)
<
2
||
seg
[
1
]
==
""
{
// just "/ipns/"
return
nil
,
fmt
.
Errorf
(
"invalid path: %s"
,
string
(
p
))
return
nil
,
fmt
.
Errorf
(
"invalid path: %s"
,
string
(
r
.
p
))
}
ipnsPath
:=
seg
[
1
]
extensions
:=
seg
[
2
:
]
respath
,
err
:=
n
.
Namesys
.
Resolve
(
n
.
Context
()
,
ipnsPath
)
respath
,
err
:=
r
.
n
.
Namesys
.
Resolve
(
r
.
ctx
,
ipnsPath
)
if
err
!=
nil
{
return
nil
,
err
}
segments
:=
append
(
respath
.
Segments
(),
extensions
...
)
r
espath
,
err
=
path
.
FromSegments
(
segments
...
)
r
.
p
,
err
=
path
.
FromSegments
(
segments
...
)
if
err
!=
nil
{
return
nil
,
err
}
return
r
esolveRecurse
(
n
,
respath
,
depth
+
1
)
return
r
.
resolveRecurse
(
depth
+
1
)
}
// ok, we have an ipfs path now (or what we'll treat as one)
return
n
.
Resolver
.
ResolvePath
(
p
)
return
r
.
n
.
Resolver
.
ResolvePath
(
r
.
ctx
,
r
.
p
)
}
fuse/readonly/readonly_unix.go
浏览文件 @
cd37b674
...
...
@@ -56,7 +56,7 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
return
nil
,
fuse
.
ENOENT
}
nd
,
err
:=
s
.
Ipfs
.
Resolver
.
ResolvePath
(
path
.
Path
(
name
))
nd
,
err
:=
s
.
Ipfs
.
Resolver
.
ResolvePath
(
ctx
,
path
.
Path
(
name
))
if
err
!=
nil
{
// todo: make this error more versatile.
return
nil
,
fuse
.
ENOENT
...
...
@@ -124,7 +124,7 @@ func (s *Node) Attr() fuse.Attr {
// Lookup performs a lookup under this node.
func
(
s
*
Node
)
Lookup
(
ctx
context
.
Context
,
name
string
)
(
fs
.
Node
,
error
)
{
log
.
Debugf
(
"Lookup '%s'"
,
name
)
nodes
,
err
:=
s
.
Ipfs
.
Resolver
.
ResolveLinks
(
s
.
Nd
,
[]
string
{
name
})
nodes
,
err
:=
s
.
Ipfs
.
Resolver
.
ResolveLinks
(
ctx
,
s
.
Nd
,
[]
string
{
name
})
if
err
!=
nil
{
// todo: make this error more versatile.
return
nil
,
fuse
.
ENOENT
...
...
ipnsfs/system.go
浏览文件 @
cd37b674
...
...
@@ -163,7 +163,7 @@ func (fs *Filesystem) newKeyRoot(parent context.Context, k ci.PrivKey) (*KeyRoot
}
}
mnode
,
err
:=
fs
.
resolver
.
ResolvePath
(
pointsTo
)
mnode
,
err
:=
fs
.
resolver
.
ResolvePath
(
ctx
,
pointsTo
)
if
err
!=
nil
{
log
.
Errorf
(
"Failed to retrieve value '%s' for ipns entry: %s
\n
"
,
pointsTo
,
err
)
return
nil
,
err
...
...
path/resolver.go
浏览文件 @
cd37b674
//
p
ackage path implements utilities for resolving paths within ipfs.
//
P
ackage path implements utilities for resolving paths within ipfs.
package
path
import
(
...
...
@@ -7,6 +7,7 @@ import (
mh
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
merkledag
"github.com/ipfs/go-ipfs/merkledag"
u
"github.com/ipfs/go-ipfs/util"
)
...
...
@@ -57,33 +58,32 @@ func SplitAbsPath(fpath Path) (mh.Multihash, []string, error) {
// ResolvePath fetches the node for given path. It returns the last item
// returned by ResolvePathComponents.
func
(
s
*
Resolver
)
ResolvePath
(
fpath
Path
)
(
*
merkledag
.
Node
,
error
)
{
nodes
,
err
:=
s
.
ResolvePathComponents
(
fpath
)
func
(
s
*
Resolver
)
ResolvePath
(
ctx
context
.
Context
,
fpath
Path
)
(
*
merkledag
.
Node
,
error
)
{
nodes
,
err
:=
s
.
ResolvePathComponents
(
ctx
,
fpath
)
if
err
!=
nil
||
nodes
==
nil
{
return
nil
,
err
}
else
{
return
nodes
[
len
(
nodes
)
-
1
],
err
}
return
nodes
[
len
(
nodes
)
-
1
],
err
}
// ResolvePathComponents fetches the nodes for each segment of the given path.
// It uses the first path component as a hash (key) of the first node, then
// resolves all other components walking the links, with ResolveLinks.
func
(
s
*
Resolver
)
ResolvePathComponents
(
fpath
Path
)
([]
*
merkledag
.
Node
,
error
)
{
func
(
s
*
Resolver
)
ResolvePathComponents
(
ctx
context
.
Context
,
fpath
Path
)
([]
*
merkledag
.
Node
,
error
)
{
h
,
parts
,
err
:=
SplitAbsPath
(
fpath
)
if
err
!=
nil
{
return
nil
,
err
}
log
.
Debug
(
"Resolve dag get.
\n
"
)
ctx
,
cancel
:=
context
.
WithTimeout
(
c
ontext
.
TODO
()
,
time
.
Minute
)
log
.
Debug
(
"Resolve dag get."
)
ctx
,
cancel
:=
context
.
WithTimeout
(
c
tx
,
time
.
Minute
)
defer
cancel
()
nd
,
err
:=
s
.
DAG
.
Get
(
ctx
,
u
.
Key
(
h
))
if
err
!=
nil
{
return
nil
,
err
}
return
s
.
ResolveLinks
(
nd
,
parts
)
return
s
.
ResolveLinks
(
ctx
,
nd
,
parts
)
}
// ResolveLinks iteratively resolves names by walking the link hierarchy.
...
...
@@ -93,10 +93,9 @@ func (s *Resolver) ResolvePathComponents(fpath Path) ([]*merkledag.Node, error)
//
// ResolveLinks(nd, []string{"foo", "bar", "baz"})
// would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links
func
(
s
*
Resolver
)
ResolveLinks
(
ndd
*
merkledag
.
Node
,
names
[]
string
)
(
result
[]
*
merkledag
.
Node
,
err
error
)
{
func
(
s
*
Resolver
)
ResolveLinks
(
ctx
context
.
Context
,
ndd
*
merkledag
.
Node
,
names
[]
string
)
([]
*
merkledag
.
Node
,
error
)
{
result
=
make
([]
*
merkledag
.
Node
,
0
,
len
(
names
)
+
1
)
result
:
=
make
([]
*
merkledag
.
Node
,
0
,
len
(
names
)
+
1
)
result
=
append
(
result
,
ndd
)
nd
:=
ndd
// dup arg workaround
...
...
@@ -121,9 +120,9 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) (
if
nlink
.
Node
==
nil
{
// fetch object for link and assign to nd
ctx
,
cancel
:=
context
.
WithTimeout
(
c
ontext
.
TODO
()
,
time
.
Minute
)
ctx
,
cancel
:=
context
.
WithTimeout
(
c
tx
,
time
.
Minute
)
defer
cancel
()
nd
,
err
=
s
.
DAG
.
Get
(
ctx
,
next
)
nd
,
err
:
=
s
.
DAG
.
Get
(
ctx
,
next
)
if
err
!=
nil
{
return
append
(
result
,
nd
),
err
}
...
...
@@ -134,5 +133,5 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) (
result
=
append
(
result
,
nlink
.
Node
)
}
return
return
result
,
nil
}
test/sharness/
t
0111-gateway-writable.sh
→
test/sharness/
x
0111-gateway-writable.sh
浏览文件 @
cd37b674
...
...
@@ -26,35 +26,31 @@ test_expect_success "HTTP gateway gives access to sample file" '
test_expect_success
"HTTP POST file gives Hash"
'
echo "$RANDOM" >infile &&
URL="http://localhost:$port/ipfs/" &&
curl -svX POST --data-binary @infile "$URL" 2>curl.out &&
grep "HTTP/1.1 201 Created" curl.out &&
LOCATION=$(grep Location curl.out) &&
HASH=$(e
xpr "$LOCATION" : "< Location: /ipfs/\(.*\)$
")
curl -svX POST --data-binary @infile "$URL" 2>curl
_post
.out &&
grep "HTTP/1.1 201 Created" curl
_post
.out &&
LOCATION=$(grep Location curl
_post
.out) &&
HASH=$(e
cho $LOCATION | cut -d":" -f2- |tr -d " \n\r
")
'
# this is failing on osx
# claims "multihash too short. must be > 3 bytes" but the multihash is there.
test_expect_failure
"We can HTTP GET file just created"
'
URL="http://localhost:$port/ipfs/$HASH" &&
test_expect_success
"We can HTTP GET file just created"
'
URL="http://localhost:${port}${HASH}" &&
curl -so outfile "$URL" &&
test_cmp infile outfile ||
echo $URL &&
test_fsh cat outfile
test_cmp infile outfile
'
test_expect_success
"HTTP PUT empty directory"
'
URL="http://localhost:$port/ipfs/$HASH_EMPTY_DIR/" &&
echo "PUT $URL" &&
curl -svX PUT "$URL" 2>curl.out &&
cat curl.out &&
grep "Ipfs-Hash: $HASH_EMPTY_DIR" curl.out &&
grep "Location: /ipfs/$HASH_EMPTY_DIR/" curl.out &&
grep "HTTP/1.1 201 Created" curl.out
curl -svX PUT "$URL" 2>curl
_putEmpty
.out &&
cat curl
_putEmpty
.out &&
grep "Ipfs-Hash: $HASH_EMPTY_DIR" curl
_putEmpty
.out &&
grep "Location: /ipfs/$HASH_EMPTY_DIR/" curl
_putEmpty
.out &&
grep "HTTP/1.1 201 Created" curl
_putEmpty
.out
'
test_expect_success
"HTTP GET empty directory"
'
echo "GET $URL" &&
curl -so outfile "$URL" 2>curl.out &&
curl -so outfile "$URL" 2>curl
_getEmpty
.out &&
grep "Index of /ipfs/$HASH_EMPTY_DIR/" outfile
'
...
...
@@ -62,9 +58,9 @@ test_expect_success "HTTP PUT file to construct a hierarchy" '
echo "$RANDOM" >infile &&
URL="http://localhost:$port/ipfs/$HASH_EMPTY_DIR/test.txt" &&
echo "PUT $URL" &&
curl -svX PUT --data-binary @infile "$URL" 2>curl.out &&
grep "HTTP/1.1 201 Created" curl.out &&
LOCATION=$(grep Location curl.out) &&
curl -svX PUT --data-binary @infile "$URL" 2>curl
_put
.out &&
grep "HTTP/1.1 201 Created" curl
_put
.out &&
LOCATION=$(grep Location curl
_put
.out) &&
HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test.txt")
'
...
...
@@ -79,22 +75,18 @@ test_expect_success "HTTP PUT file to append to existing hierarchy" '
echo "$RANDOM" >infile2 &&
URL="http://localhost:$port/ipfs/$HASH/test/test.txt" &&
echo "PUT $URL" &&
curl -svX PUT --data-binary @infile2 "$URL" 2>curl.out &&
grep "HTTP/1.1 201 Created" curl.out &&
LOCATION=$(grep Location curl.out) &&
curl -svX PUT --data-binary @infile2 "$URL" 2>curl
_putAgain
.out &&
grep "HTTP/1.1 201 Created" curl
_putAgain
.out &&
LOCATION=$(grep Location curl
_putAgain
.out) &&
HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test/test.txt")
'
test_expect_success
"We can HTTP GET file just
cre
ated"
'
test_expect_success
"We can HTTP GET file just
upd
ated"
'
URL="http://localhost:$port/ipfs/$HASH/test/test.txt" &&
echo "GET $URL" &&
curl -so outfile2 "$URL" &&
test_cmp infile2 outfile2 &&
URL="http://localhost:$port/ipfs/$HASH/test.txt" &&
echo "GET $URL" &&
curl -so outfile "$URL" &&
test_cmp infile outfile
curl -svo outfile2 "$URL" 2>curl_getAgain.out &&
test_cmp infile2 outfile2
'
test_kill_ipfs_daemon
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论