node-solid-server icon indicating copy to clipboard operation
node-solid-server copied to clipboard

Failed PUT to overwrite a file responds with 201

Open andydavison opened this issue 5 years ago • 12 comments

When uploading a different file type, e.g. overwriting something.jpg with something.png, it won’t actually work and the original image remains, but the server happily responds with a 201. I understand it failing, but it should tell me in the response.

andydavison avatar Aug 03 '20 13:08 andydavison

Probably it created something.png next to something.jpg since the filename is different? What happens when you upload something.png a second time?

michielbdejong avatar Aug 04 '20 07:08 michielbdejong

@andydavison can you try on https://solid.community it may be easier to debug. (Access to the file system)

bourgeoa avatar Aug 04 '20 08:08 bourgeoa

It does look like only the jpg is created (expanding that file does show the original)

Screenshot 2020-08-04 at 09 56 25

Also just to clarify, this is sending a PUT to test.jpg with a png file, e.g. https://andydavison.inrupt.net/private/test.jpg

andydavison avatar Aug 04 '20 09:08 andydavison

How did you upload (mashlib green + or programmatically) ?

I tried with mashlib green + button on https://bourgeoa.inrupt.net/private/test/ and I do not have any problem both : file.jpg and file.png are created

bourgeoa avatar Aug 04 '20 09:08 bourgeoa

Also just to clarify, this is sending a PUT to test.jpg with a png file, e.g. https://andydavison.inrupt.net/private/test.jpg

Do you mean : PUT to test.jpg with a png file content ?

bourgeoa avatar Aug 04 '20 10:08 bourgeoa

I'm uploading using a new React component I'm working on, to display an image and give the option to upload a replacement to the same path. I'm not familiar with how the mashlib green + works, but I guess for the png the request url is to [...]/file.png, so works fine as expected?

Yep, a PUT to the existing path (test.jpg) with a new png file as content. It may well be expected that this fails or succeeds, I'm not sure, but it's the mismatch between behaviour and response given that's the issue

andydavison avatar Aug 04 '20 11:08 andydavison

This curl command works every time, but then the content of the file is also updated. Maybe a 200 response would be more correct than 201 if it's overwriting, but other than that I don't see why the request should fail?

curl 'https://asdf1.inrupt.net/public/test.txt'   -X 'PUT'   -H 'Connection: keep-alive'   -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'   -H 'content-type: text/plain'   -H 'Accept: */*'   -H 'Origin: https://asdf1.inrupt.net'   -H 'Sec-Fetch-Site: same-origin'   -H 'Sec-Fetch-Mode: cors'   -H 'Sec-Fetch-Dest: empty'   -H 'Referer: https://asdf1.inrupt.net/public/'   -H 'Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7,fr-FR;q=0.6,fr;q=0.5,de-DE;q=0.4,de;q=0.3,es-ES;q=0.2,es;q=0.1,id-ID;q=0.1,id;q=0.1'   -H 'Cookie: nssidp.sid=s%3A2_yYAURQDNH5W9_0uHx0khD_vWtFND2t.LmfYquZIXnU520tjWb3%2FfnkS8CJmtOIF8f1R93DMIOc'   --data-binary $'b\n'   --compressed -v

If you change the cookie string so that the request is unsuccessful, you get a 401 response (not 201), as expected.

michielbdejong avatar Aug 04 '20 11:08 michielbdejong

Hmm. Replacing e.g. a jpg with a jpg works fine, but sending png content to an existing jpg path is giving a 201 with no update to the file for me. Is anyone else able to reproduce that specific behaviour?

andydavison avatar Aug 04 '20 11:08 andydavison

I think the name "test.jpg" should remain opaque even if the original representation was provided with image/jpeg. That will at least have test.jpg available in JPEG. Subsequent requests with image/jpeg could replace that representation even if the payload format is in PNG. Server can of course inspect the payload format and see if it is legitimate, if okay, may make it possible so that test.jpg is available with the image/png representation, otherwise, return a 409 in response to the write operation.

csarven avatar Aug 04 '20 11:08 csarven

@andydavison is your React component sending a Content-Type request header or is it leaving the server to guess the content type? In any case we should probably add a failing unit test for this if it's reproducable.

michielbdejong avatar Aug 04 '20 13:08 michielbdejong

yep, sending content-type: image/png with the correct type for the content

andydavison avatar Aug 04 '20 14:08 andydavison

I think what happens is :

  • PUT resource test.jpg with contentType image/jpeg --> stored in filesystem as test.jpg
  • PUT resource test.jpg with contentType image/png --> stored in filesystem as test.jpg$.png

This is a buggy situation because when you GET the resource test.jpg you only access the first one (I suppose test.jpg) and don't see the second one. To confirm that : you can delete resource test.jpg and you should see there is still an other resource named test.jpeg.

I already saw this issue : a Resource shall map to only one Url. resourceMapper should refuse to create a new resource with a different url if the resource name allready exists.

bourgeoa avatar Aug 05 '20 13:08 bourgeoa