tine-groupware / tine

tine groupware main repository
https://www.tine-groupware.de
GNU Affero General Public License v3.0
12 stars 2 forks source link

WebDAV File Upload does not work: CONTENT_LENGTH header missing! #6

Closed sbaumgartner75 closed 1 month ago

sbaumgartner75 commented 9 months ago

Recreated the issue from the old repo and did some more testing - no ICS, no upgrades, just plain installs:

Version 2023.06.24.45:

C:\Temp>curl --verbose --user uuser --upload-file file.txt http://some.site.com:11080/webdav/Filemanager/user/myfolder/file.txt
Enter host password for user 'uuser':
*   Trying 10.42.0.1:11080...
* Connected to some.site.com (10.42.0.1) port 11080
* Server auth using Basic with user 'uuser'
> PUT /webdav/Filemanager/user/myfolder/file.txt HTTP/1.1
> Host: some.site.com:11080
> Authorization: Basic <redacted>
> User-Agent: curl/8.4.0
> Accept: */*
> Content-Length: 6
>
* We are completely uploaded and fine
< HTTP/1.1 201 Created
< Date: Thu, 28 Dec 2023 10:25:02 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Set-Cookie: TINE20SESSID=v09f9ilrfhv88148j95642d9tr; path=/; HttpOnly
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< X-API: http://www.tine20.org/apidocs/tine20/
< Content-Length: 0
< ETag: "ee2fbbba35356d43c7b185989bc507d1f43649cf"
< Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host some.site.com left intact

Result: Works

Version 2023.09.23.42:

C:\Temp>curl --verbose --user uuser --upload-file file.txt http://some.site.com:11080/webdav/Filemanager/user/myfolder/file.txt
Enter host password for user 'uuser':
*   Trying 10.42.0.1:11080...
* Connected to some.site.com (10.42.0.1) port 11080
* Server auth using Basic with user 'uuser'
> PUT /webdav/Filemanager/user/myfolder/file.txt HTTP/1.1
> Host: some.site.com:11080
> Authorization: Basic <redacted>
> User-Agent: curl/8.4.0
> Accept: */*
> Content-Length: 6
>
* We are completely uploaded and fine
< HTTP/1.1 400 Bad request
< Date: Thu, 28 Dec 2023 10:40:04 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Set-Cookie: TINE20SESSID=sofmpe323unjj621sis9ngn9nh; path=/; HttpOnly
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< X-API: http://www.tine20.org/apidocs/tine20/
< Content-Length: 224
< Connection: close
< Content-Type: application/xml; charset=utf-8
<
<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  <s:exception>Sabre\DAV\Exception\BadRequest</s:exception>
  <s:message>CONTENT_LENGTH header missing!</s:message>
</d:error>
* Closing connection

Result: failed

Version 2023.12.02.18:

C:\Temp>curl --verbose --user uuser --upload-file file.txt http://some.site.com:11080/webdav/Filemanager/user/myfolder/file.txt
Enter host password for user 'uuser':
*   Trying 10.42.0.1:11080...
* Connected to some.site.com (10.42.0.1) port 11080
* Server auth using Basic with user 'uuser'
> PUT /webdav/Filemanager/user/myfolder/file.txt HTTP/1.1
> Host: some.site.com:11080
> Authorization: Basic <redacted>
> User-Agent: curl/8.4.0
> Accept: */*
> Content-Length: 6
>
* We are completely uploaded and fine
< HTTP/1.1 400 Bad request
< Date: Thu, 28 Dec 2023 10:50:29 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Set-Cookie: TINE20SESSID=itbv6rqpk0hivjc8vgqfh2chmv; path=/; HttpOnly
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< X-API: http://www.tine20.org/apidocs/tine20/
< Content-Length: 224
< Connection: close
< Content-Type: application/xml; charset=utf-8
<
<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  <s:exception>Sabre\DAV\Exception\BadRequest</s:exception>
  <s:message>CONTENT_LENGTH header missing!</s:message>
</d:error>
* Closing connection

Result: failed

Could you please advise, how to narrow it down further?

pschuele commented 9 months ago

I see, thanks for the bugreport. the problem was introduced with this commit: 2bb55f8573ff798630cf5ebfbd8e8e53840fd300

I'll check and come back to you soon.

pschuele commented 9 months ago

fix is incoming

sbaumgartner75 commented 8 months ago

Any idea, when this commit is going to be included in a weekly-release? Or do I miss something ...

pschuele commented 8 months ago

hi, the commit should be in the latest weekly release https://github.com/tine-groupware/tine/releases/tag/weekly-2024.03.1

sbaumgartner75 commented 8 months ago

Thought so too, but shouldn‘t it then be included in the release notes/changelog?

pschuele commented 8 months ago

only commits marked as "feature" or "fix" are part of the automated changelog. the developer

but if you go to the commit, you can see the tags (releases) it is included in:

image

https://github.com/tine-groupware/tine/commit/23b4f459f562fff5ca2a28dcc31430ef0a3848b6

maybe we'll add closed github issues to the changelog, even if they are not marked as "fix". we'll discuss that.

lab-at-nohl commented 2 months ago

The fix in https://github.com/tine-groupware/tine/commit/23b4f459f562fff5ca2a28dcc31430ef0a3848b6 cannot work in standard environments where Tine is behind a reverse proxy! HTTP_CONTENT_LENGTH does not exist for PUT-Requests, only with POST requests. Thus, file upload is (still) broken.

Instead, according to the standards Apache 2.4 passes CONTENT_LENGTH env variable from the original request header. Most nginx use an /etc/nginx/fastcgi_params where CONTENT_LENGTH is passed, too. However, you won't see the difference normally, since in a POST-Request PHP will rewrite it to HTTP_CONTENT_LENGTH...

Exception message from Tinebase/Frontend/WebDAV/Directory.php (line 205) is very misleading mentioning CONTENT_LENGTH while being behind an if clause checking HTTP_CONTENT_LENGTH...


Please see PHP manual for details:

In addition to the elements listed below, PHP will create additional elements with values from request headers. These entries will be named HTTP_ followed by the header name, capitalized and with underscores instead of hyphens.

https://www.php.net/manual/en/reserved.variables.server.php

Nevertheless, as comment #15 in the manual shows (see rfc):

If requests to your PHP script send a header "Content-Type" or/ "Content-Length" it will, contrary to regular HTTP headers, not appear in $_SERVER as $_SERVER['HTTP_CONTENTTYPE']. PHP removes these (per CGI/1.1 specification[1]) from the HTTP match group.

They are still accessible, but only if the request was a POST request. When it is, it'll be available as: $_SERVER['CONTENT_LENGTH'] $_SERVER['CONTENT_TYPE']

[1] https://www.ietf.org/rfc/rfc3875


Following issues are probably related:

https://github.com/tine20/tine20/issues/7483 https://github.com/tine20/tine20/issues/7499


For Apache a workaround can set in httpd.conf or .htaccess-file, to have both variables:

SetEnvIf Content-Length "(.*)" HTTP_CONTENT_LENGTH=$1

Likely, you can do similar with nginx and fastcgi_param HTTP_CONTENT_LENGTH $content_length; (untested).

github-actions[bot] commented 1 month ago

This issue is stale because it has been open 30 days with no activity. Comment or remove the stale label. Otherwise, it will be closed in 7 days.