Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixing putHandler #1886

Merged
merged 2 commits into from
Oct 31, 2015
Merged

fixing putHandler #1886

merged 2 commits into from
Oct 31, 2015

Conversation

cryptix
Copy link
Contributor

@cryptix cryptix commented Oct 22, 2015

trying to finally get a working putHandler for the writable http gateway.

License: MIT
Signed-off-by: Henry [email protected]

@jbenet jbenet added the status/in-progress In progress label Oct 22, 2015
@cryptix
Copy link
Contributor Author

cryptix commented Oct 23, 2015

Since #1845 is based on 0.4, I tried my best to get the putHandler back to work.

I fixed overwriting an existing path and 'object add-link' but I'm not sure how in line this are with the old sharness tests and or if we still wont their behavior.

@cryptix
Copy link
Contributor Author

cryptix commented Oct 23, 2015

cc @jbenet @whyrusleeping

webError(w, "Could not resolve root object", err, http.StatusBadRequest)
return
}
createfunc := func() *dag.Node {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is uio.NewEmptyDirectory

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createfunc := uio.NewEmptyDirectory

@rht
Copy link
Contributor

rht commented Oct 23, 2015

Since netstat is not available in the test env, the first test should be commented out.

if err != nil {
webError(w, "Could not recursively add new node", err, http.StatusInternalServerError)
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
rootPath := path.Path(r.URL.Path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could probably use path.Parse here

return
var newPath string
if len(rsegs) > 1 {
newPath = filepath.Join(rsegs[2:]...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont want to use filepath here, on windows systems this would put forward slashes in the ipfspaths, which i dont think works like we expect it to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh, true.. I always manage to ignore that.

@whyrusleeping
Copy link
Member

just a few comments, then squash some commits so none of them break. (i think some of the earlier ones break) then LGTM

@cryptix cryptix force-pushed the fix/ThatPut branch 2 times, most recently from 51cbc49 to cfc0824 Compare October 23, 2015 18:51
@cryptix
Copy link
Contributor Author

cryptix commented Oct 23, 2015

CR adressed and squashed.

@ion1
Copy link

ion1 commented Oct 23, 2015

Please correct me if I have misunderstood the RFC text, but it seems to me like the methods should have the following semantics in this context:

POST /ipfs creates a new resource under /ipfs whose name (in this case: hash) is determined by the gateway and receives the response:

201 Created
Location: /ipfs/QmFoo

POST /ipfs/QmBar or POST /ipfs/QmBar/baz request a resource to be added under QmBar and QmBar/baz respectively. The server has to choose the name of the resource; we should dictate that the request must have a Content-Disposition: …; filename="…" header and use that for the name.

Technically the resulting resource will be added under a new /ipfs/QmQuux which is the result of patching QmBar but this might not be too great a sin. The response to POST /ipfs/QmBar/baz with filename="my-file":

201 Created
Location: /ipfs/QmQuux/baz/my-file

We will have to decide what to do if the request would overwrite an existing file in QmBar. The choices:

  • Just overwrite it and give a 201 Created response as above. Any qualms about POST apparently deleting content may be soothed by realizing that the original QmBar is still there with the original file. This would be my choice.
  • Give a 409 Conflict response and require the client to DELETE the original file first. This increases complexity, requires two round trips and results in a useless intermediate object being created.

PUT /ipfs is not meaningful (“I expect a future GET /ipfs to return this content”). 405 Method Not Allowed.

PUT /ipfs/QmFoo can only succeed if QmFoo is in fact the hash of the object being uploaded (requiring the client to compute the hash in advance). Either don’t support this and respond with 405 Method Not Allowed or check whether the hash matches and respond with 201 Created or 409 Conflict.

PUT /ipfs/QmBar/baz is not meaningful: the gateway might not know anything about QmBar under which baz is requested to be created, and if it does know, QmBar already exists and is immutable. 405 Method Not Allowed.

This can not be used to patch QmBar: a successful PUT to a resource means that a subsequent GET to the same resource will return the uploaded content, actual mutation of the resource needs to occur.

DELETE /ipfs is not meaningful. 405 Method Not Allowed.

DELETE /ipfs/QmFoo is not meaningful. 405 Method Not Allowed.

DELETE /ipfs/QmQuux/baz/my-file can be used to patch QmQuux to remove my-file. The RFC only says a successful DELETE “SHOULD” give a 202 Accepted/204 No Content/200 OK response. We should not be in violation if we create a patched object and respond with:

201 Created
Location: /ipfs/QmBar/baz

@rht
Copy link
Contributor

rht commented Oct 23, 2015

You're suggesting PUT should be used only for mutable (ipns) case?

@ion1
Copy link

ion1 commented Oct 23, 2015

PUT could be used with IPNS, yes. The rule seems to be:

After a successful PUT <location>, a subsequent GET <location> will return what you put.

This implies mutation.

@mildred
Copy link
Contributor

mildred commented Oct 27, 2015

UpdateNodeLink() in merkledag/node.go can probably be removed as part of this PR. gateway_handler was the only one using it.

Also, I'm generally liking PUT much more than POST when it can be used, but I agree that in the case of ipfs, resources are immutable and PUT doesn't makes sense except at the root when the client already knows the hash of the node it uploads. POST with Content-Disposition should probably be implemented instead.

w.Header().Set("IPFS-Hash", key.String())
http.Redirect(w, r, ipfsPathPrefix+key.String()+"/"+strings.Join(components, "/"), http.StatusCreated)
w.Header().Set("IPFS-Hash", newkey.String())
http.Redirect(w, r, filepath.Join(ipfsPathPrefix, newkey.String(), newPath), http.StatusCreated)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path.

@jbenet
Copy link
Member

jbenet commented Oct 27, 2015

The PR is hard to follow because changes change code quite a bit. i haven't read it all. but if LGTWhyrusleeping, and the tests pass, i'd be ok to merge it.

(in the end i want to split out all the gateway stuff into own repo)


i think ion covered it very well, all that SGTM.

@cryptix
Copy link
Contributor Author

cryptix commented Oct 27, 2015

@jbenet it's easier to follow if you just look at the new code.

Do we want to merge it now and do the change to POST in a follow up PR? The changes will only get bigger because the tests need to change as well. OTOH we would introduce features again that aren't there to stay..

I'd also like to introduce pure go tests for the things @ion1 brought up. I think it's easier to outline and test all those in a table based manner.

@whyrusleeping
Copy link
Member

I would be comfortable merging this as its something that is disabled by default.

I disabled this a long time ago and never refactored it. About time.

License: MIT
Signed-off-by: Henry <[email protected]>
@cryptix
Copy link
Contributor Author

cryptix commented Oct 29, 2015

rebased.

I'll start a new branch based on this one for the POST conversion, if we want to do it in this PR I can still push it here.

}
var newkey key.Key
rnode, err := core.Resolve(i.node.Context(), i.node, rootPath)
switch ev := err.(type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a switch from err casting.
This is cleaner, and should be used across the code.

In current master, where cast is used:

$ grep -rE 'err\.\(' . | grep -v Godeps
./routing/dht/ext_test.go:      if merr, ok := err.(u.MultiErr); ok && len(merr) > 0 {
./routing/dht/ext_test.go:      if merr, ok := err.(u.MultiErr); ok && len(merr) > 0 {
./routing/dht/ext_test.go:      if merr, ok := err.(u.MultiErr); ok && len(merr) > 0 {
./core/corehttp/gateway_handler.go: if _, ok := err.(path.ErrNoLink); ok {
./core/corehttp/gateway_handler.go: if _, ok := err.(path.ErrNoLink); ok {
./core/commands/add.go:     if _, ok := err.(*hiddenFileError); ok {
./p2p/net/conn/dial_test.go:            if ne, ok := err.(net.Error); ok && ne.Temporary() {
./p2p/net/conn/dial.go: if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
./p2p/net/conn/dial.go: errno, ok := err.(syscall.Errno)
./cmd/ipfs/main.go: switch e := err.(type) {

@rht
Copy link
Contributor

rht commented Oct 29, 2015

Unless I'm missing something, to implement POST for composite files on 0.3.x, doesn't it mean the code for ipfs add is duplicated almost verbatim?

@rht
Copy link
Contributor

rht commented Oct 29, 2015

How is @ion1's PUT /ipfs/QmBar/baz case addressed in test/sharness/t0111-gateway-writeable.sh#L60 ? The new hash isn't precomputed in the test.

@@ -273,116 +275,82 @@ func (i *gatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, ipfsPathPrefix+k.String(), http.StatusCreated)
}

func (i *gatewayHandler) putEmptyDirHandler(w http.ResponseWriter, r *http.Request) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happened to this part? do empty dirs still work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup - works by virtue of core.Resolve and friends iirc. There is also a sharness test that checks against the hash.

@jbenet
Copy link
Member

jbenet commented Oct 31, 2015

@cryptix a lot of people want this. eta on addressing CR?

License: MIT
Signed-off-by: Henry <[email protected]>
cryptix added a commit that referenced this pull request Oct 31, 2015
@cryptix
Copy link
Contributor Author

cryptix commented Oct 31, 2015

@jbenet done :)

@cryptix cryptix changed the title WIP: fixing putHandler fixing putHandler Oct 31, 2015
@jbenet
Copy link
Member

jbenet commented Oct 31, 2015

Thanks @cryptix ! LGTM. I'll merge this for now -- so @victorbjelkholm can use in IPFSBin and @cloutier and @didiercf can use in ipfspics. we can move from PUT to POST in the future.

jbenet added a commit that referenced this pull request Oct 31, 2015
@jbenet jbenet merged commit f703b2c into master Oct 31, 2015
@jbenet jbenet removed the status/in-progress In progress label Oct 31, 2015
@jbenet jbenet deleted the fix/ThatPut branch October 31, 2015 05:03
@rht
Copy link
Contributor

rht commented Oct 31, 2015

And ipfs-wiki, which uses python -m SimpleHTTPServer.

@jbenet
Copy link
Member

jbenet commented Oct 31, 2015

cc @jamescarlyle o/

cryptix added a commit that referenced this pull request Oct 31, 2015
cryptix added a commit that referenced this pull request Nov 3, 2015
cryptix added a commit that referenced this pull request Dec 2, 2015
cryptix added a commit that referenced this pull request Dec 15, 2015
hacdias pushed a commit to ipfs/boxo that referenced this pull request Jan 27, 2023
fixing putHandler

This commit was moved from ipfs/kubo@f703b2c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants