mikedeboer / jsDAV

jsDAV allows you to easily add WebDAV support to a NodeJS application. jsDAV is meant to cover the entire standard, and attempts to allow integration using an easy to understand API.
http://www.mikedeboer.nl
MIT License
681 stars 159 forks source link

upload file from browser doesnt work #79

Closed ideiudicibus closed 11 years ago

ideiudicibus commented 11 years ago

I've tried to upload a file from a browser, but jsDav reply is the following

<?xml version="1.0" encoding="utf-8"?>
[info] <d:error xmlns:d="DAV:" xmlns:a="http://ajax.org/2005/aml">
[info]     <a:exception>NotImplemented</a:exception>
[info]     <a:message>NotImplemented</a:message>
[info] <a:file></a:file>
[info] <a:line></a:line>
[info] <a:jsdav-version>0.3.2</a:jsdav-version>
[info] </d:error>'`

after a little bit of debuggin I've discovered that the POST method is not handled properly at line 151 of httpPOSTHandler method in browser.js

var postVars = Qs.parse(body);
if (!postVars.jsdavAction)
                return e.next();

the expression if (!postVars.jsdavAction) returns true then in handler.js at line 243

this.dispatchEvent("beforeMethod", method, uri, function(stop) {
            if (stop === true)
                return;
            if (stop)
                return self.handleError(stop);
            // Make sure this is a HTTP method we support
            if (internalMethods[method]) {
                self["http" + method.charAt(0) + method.toLowerCase().substr(1)]();
            }
            else {
                self.dispatchEvent("unknownMethod", method, uri, function(stop) {
....

stop is undefined and then the else part is executed. Probably the issue in in the querystring module of nodejs.

I'm using master-branch and node 0.8.2

mikedeboer commented 11 years ago

hrm, I'm curious what the content of postVars is in your case... could you console.log it and paste it in this bug?

ideiudicibus commented 11 years ago

{ '-----------------------------10039407114525152981185019459\r\nContent-Disposition: form-data; name': '"jsdavAction"\r\n\r\nput\r\n-----------------------------10039407114525152981185019459\r\nContent-Disposition: form-data; name="name"\r\n\r\ntest file name\r\n-----------------------------10039407114525152981185019459\r\nContent-Disposition: form-data; name="file"; filename="test.bin"\r\nContent-Type: application/macbinary\r\n\r\n\r\n-----------------------------10039407114525152981185019459--\r\n' }

this is the console.log(postVars). The file uploaded has been generated with the touch command.

regards

I

mikedeboer commented 11 years ago

That looks horrid. I don't know what touch does, but it's not making the NodeJS HTTP parser very happy!

My guess: this will be fine when you upload via your browser...

ideiudicibus commented 11 years ago

it might be a misunderstanding: I created the uploaded file using the touch unix command, and I posted that file, but I tried also pdf or images, using the form. I used Firefox, Chrome and Safari to see possibily different behaviours but the request is alwasy the same. I'm tryng with formidable and the request is parsed correctly. I've inspected the post with firebug and the result is the following:

-----------------------------173963131221410905262072481350 Content-Disposition: form-data; name="jsdavAction" put -----------------------------173963131221410905262072481350 Content-Disposition: form-data; name="name" -----------------------------173963131221410905262072481350 Content-Disposition: form-data; name="file"; filename="test.bin" Content-Type: application/macbinary -----------------------------173963131221410905262072481350--

posting with chrome gives the following

`------WebKitFormBoundaryAoGsMLD1PPfZ2Cvb Content-Disposition: form-data; name="jsdavAction"

put ------WebKitFormBoundaryAoGsMLD1PPfZ2Cvb Content-Disposition: form-data; name="name"

------WebKitFormBoundaryAoGsMLD1PPfZ2Cvb Content-Disposition: form-data; name="file"; filename="test.bin" Content-Type: application/macbinary`

response is still the "Not Implemeted" xml

client and server see the same.

Any suggestions?

mikedeboer commented 11 years ago

ah, right! No, what I meant is console.log("POST VARS", postVars); in browser.js... can you do that?

ideiudicibus commented 11 years ago

that's I was talking about in my first comment, anyway here is the log line 167 browser.js

POST VARS  { '-----------------------------104718410513947655702040927985\r\nContent-Disposition: form-data; name': '"jsdavAction"\r\n\r\nput\r\n-----------------------------104718410513947655702040927985\r\nContent-Disposition: form-data; name="name"\r\n\r\n\r\n-----------------------------104718410513947655702040927985\r\nContent-Disposition: form-data; name="file"; filename="test.bin"\r\nContent-Type: application/macbinary\r\n\r\n\r\n-----------------------------104718410513947655702040927985--\r\n' }
johnsonlee commented 11 years ago

I also found this issue when I use the example to upload a file to server. So, I had to write another method to parse request body instead of Qs.parse(), but there is another problem, I don't know where the postVars.tmp_file property comes from, but in jsDAV/lib/DAV/plugins/browser.js, there is a condition statement to check postVars.tmp_file

mikedeboer commented 11 years ago

Ah I now see where the problem is coming from. I'll try to make this work asap. I've been very busy with my (new) job at Mozilla, so my apologies for the delay.