my-nextcloud-site.com {
root /var/www/nextcloud
log /var/log/nextcloud_access.log
errors /var/log/nextcloud_errors.log
fastcgi / 127.0.0.1:9000 php {
env PATH /bin
env modHeadersAvailable true
env front_controller_active true
connect_timeout 60s
read_timeout 3600s
send_timeout 300s
}
header / {
Strict-Transport-Security "max-age=15768000;"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
X-Robots-Tag "none"
X-Download-Options "noopen"
X-Permitted-Cross-Domain-Policies "none"
Referrer-Policy "no-referrer"
}
header /core/fonts {
Cache-Control "max-age=604800"
}
# checks for images
rewrite {
ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map
r ^/index.php/.*$
to /{1} /index.php?{query}
}
rewrite {
r ^/\.well-known/host-meta$
to /public.php?service=host-meta&{query}
}
rewrite {
r ^/\.well-known/host-meta\.json$
to /public.php?service=host-meta-json&{query}
}
rewrite {
r ^/\.well-known/webfinger$
to /public.php?service=webfinger&{query}
}
rewrite {
r ^/index.php/.*$
to /index.php?{query}
}
rewrite / {
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map .html .ttf
r ^/(.*)$
to /{1} /index.php{uri}
}
rewrite / {
if {path} not /core/img/favicon.ico
if {path} not /core/img/manifest.json
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
if {path} not_starts_with /cron.php
if {path} not_starts_with /core/ajax/update.php
if {path} not_starts_with /status.php
if {path} not_starts_with /ocs/v1.php
if {path} not_starts_with /ocs/v2.php
if {path} not /robots.txt
if {path} not_starts_with /updater/
if {path} not_starts_with /ocs-provider/
if {path} not_starts_with /ocm-provider/
if {path} not_starts_with /.well-known/
to /index.php{uri}
}
# client support (e.g. os x calendar / contacts)
redir /.well-known/carddav /remote.php/carddav 301
redir /.well-known/caldav /remote.php/caldav 301
# remove trailing / as it causes errors with php-fpm
rewrite {
r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
to /remote.php/{1}
}
rewrite {
r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
to /remote.php/{1}/{2}
}
rewrite {
r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
to /public.php/{1}
}
rewrite {
r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
to /public.php/{1}/{2}
}
# .htaccess / data / config / ... shouldn't be accessible from outside
status 404 {
/.htaccess
/data
/config
/db_structure
/.xml
/README
/3rdparty
/lib
/templates
/occ
/console.php
}
}
3. The problem I’m having:
I am trying to migrate the Caddyfile V1 to Caddyfile V2 but I do not understand how to migrate the following rewrite blocks :
# checks for images
rewrite {
ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map
r ^/index.php/.*$
to /{1} /index.php?{query}
}
rewrite {
r ^/\.well-known/host-meta$
to /public.php?service=host-meta&{query}
}
rewrite {
r ^/\.well-known/host-meta\.json$
to /public.php?service=host-meta-json&{query}
}
rewrite {
r ^/\.well-known/webfinger$
to /public.php?service=webfinger&{query}
}
rewrite {
r ^/index.php/.*$
to /index.php?{query}
}
rewrite / {
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
ext .png .html .ttf .ico .jpg .jpeg .css .js .woff .woff2 .svg .gif .map .html .ttf
r ^/(.*)$
to /{1} /index.php{uri}
}
rewrite / {
if {path} not /core/img/favicon.ico
if {path} not /core/img/manifest.json
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
if {path} not_starts_with /cron.php
if {path} not_starts_with /core/ajax/update.php
if {path} not_starts_with /status.php
if {path} not_starts_with /ocs/v1.php
if {path} not_starts_with /ocs/v2.php
if {path} not /robots.txt
if {path} not_starts_with /updater/
if {path} not_starts_with /ocs-provider/
if {path} not_starts_with /ocm-provider/
if {path} not_starts_with /.well-known/
to /index.php{uri}
}
# client support (e.g. os x calendar / contacts)
redir /.well-known/carddav /remote.php/carddav 301
redir /.well-known/caldav /remote.php/caldav 301
# remove trailing / as it causes errors with php-fpm
rewrite {
r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)(\/?)$
to /remote.php/{1}
}
rewrite {
r ^/remote.php/(webdav|caldav|carddav|dav)/(.+?)(\/?)(\/?)$
to /remote.php/{1}/{2}
}
rewrite {
r ^/public.php/(dav|webdav|caldav|carddav)(\/?)(\/?)$
to /public.php/{1}
}
rewrite {
r ^/public.php/(dav|webdav|caldav|carddav)/(.+)(\/?)(\/?)$
to /public.php/{1}/{2}
}
4. Error messages and/or full log output:
Nextcloud will not work as intended without a proper Caddyfile V2
5. What I already tried:
I started converting the Caddyfile without these rewrite blocks but it is not enough as NextCloud will not work as intended.
The main landing page of Nextcloud works, but the related functions behind such as the file browser do not work hence I get blank content.
For a start, I found that I get 405 errors codes in my log file such as :
“SEARCH /index.php/apps/files/ HTTP/2.0” 405 0
“PROPFIND /remote.php/dav/files/jacques/ HTTP/2.0” 405 0
I think it’s because I miss this rewrite block in my Caddyfile which I don’t know how to convert to V2 :
rewrite / {
if {path} not /core/img/favicon.ico
if {path} not /core/img/manifest.json
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
if {path} not_starts_with /cron.php
if {path} not_starts_with /core/ajax/update.php
if {path} not_starts_with /status.php
if {path} not_starts_with /ocs/v1.php
if {path} not_starts_with /ocs/v2.php
if {path} not /robots.txt
if {path} not_starts_with /updater/
if {path} not_starts_with /ocs-provider/
if {path} not_starts_with /ocm-provider/
if {path} not_starts_with /.well-known/
to /index.php{uri}
}
Sounds like you’re having the same problems as this:
I don’t think that rewrite block is necessary in v2. All PHP files will be served by fastcgi if they exist on disk. The only URLs that need or may need special rewrites from those are /.well-known/, /updater/, /ocs-provider/ and /ocm-provider/
This is a long-shot but if you turn off logging (remove those lines), does WebDav start working? We had a potentially related issue regarding logging messing with response headers. I’m not certain that’s the problem, but it’s a hunch.
@Dougy I second this. I agree it’s a long shot, since I thought the issue was originally linked only to HTTP Trailers, but we recently found that is not the case so if it fixes your case too, I’d be willing to cherry-pick the fix for v2 release. But if you can test it today or tomorrow that would be superb.
(“test it” == either removing the log directive OR building with the h2c branch, but removing the log is probably easier.)
I tried everything, I even reduced my Caddyfile to bare minimum with only a root, a file_server and a php_cgi directive but I keep getting these 405 errors with webdav requests.
I also tried to enforce HTTP 1.1 with alpn http/1.1 to see if this was a compatibility problem with HTTP2…
Hmm, well it’s beyond me what is wrong then. Nextcloud is clearly returning a 405 “Method not allowed” and I don’t know enough about Nextcloud to know why. Try asking Nextcloud? The logs should have plenty of information to help people familiar with it what is wrong. Will be happy to make any fixes in Caddy 2 if something is wrong with it.
To understand better what was the needed rewrite request, I switched back to Caddy v1 and modified this rewrite block from Caddyfile :
rewrite / {
if {path} not /core/img/favicon.ico
if {path} not /core/img/manifest.json
if {path} not_starts_with /remote.php
if {path} not_starts_with /public.php
if {path} not_starts_with /cron.php
if {path} not_starts_with /core/ajax/update.php
if {path} not_starts_with /status.php
if {path} not_starts_with /ocs/v1.php
if {path} not_starts_with /ocs/v2.php
if {path} not /robots.txt
if {path} not_starts_with /updater/
if {path} not_starts_with /ocs-provider/
if {path} not_starts_with /ocm-provider/
if {path} not_starts_with /.well-known/
to /index.php{uri}
}
I replaced it with the one below
rewrite / {
to /index.php{uri}
}
Now I get the exact same behaviour as Caddy V2 : "PROPFIND /remote.php/dav/files/jacques/ HTTP/1.1" 405 0
Thus, I just need to understand how to prevent Caddyfile v2 to rewrite a request such as /remote.php/* to be redirected to index.php
Yep that’s exactly why @Dougy, I’m just trying to think of a generalized solution so we can solve it without relying on specifically dealing with each path that involves a non-index .php file.
Once we figure that out I’ll probably look into baking it into the php_fastcgi directive so it’s generally available.
The crux of the issue is that we made the assumption that an app would only have one PHP file that would act as a router (index.php typically) but NextCloud has more than one (i.e. remote.php as well)
To clarify further, if the requested URI was something like /remote.php?p=/dav/files/jacques it would work fine because {path} would only be /remote.php because the query is not included, but in this case the actual requested URI is /remote.php/dav/files/jacques/ and Caddy doesn’t detect that the .php part denotes the end of the filename.
@Dougy are you willing to try out an early build to see if this works for you?
Seeing as you’re on FreeBSD you’d probably need to compile it yourself, let me know if you need any pointers for how to do that!
Build instructions are here:
Basically, just comment out or remove the rewrite block I had you add, and hopefully it should work with the new build. The patch changes how php_fastcgi behaves to handle your situation.