Skip to content

Commit 68a9903

Browse files
authored
Merge pull request #54550 from nextcloud/jtr-refactor-main-htaccess
2 parents 3e1ce96 + 30ad57b commit 68a9903

File tree

1 file changed

+161
-81
lines changed

1 file changed

+161
-81
lines changed

.htaccess

Lines changed: 161 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,178 @@
11
<IfModule mod_headers.c>
2-
<IfModule mod_setenvif.c>
3-
<IfModule mod_fcgid.c>
4-
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
5-
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
2+
<IfModule mod_setenvif.c>
3+
<IfModule mod_fcgid.c>
4+
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
5+
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
6+
</IfModule>
7+
<IfModule mod_proxy_fcgi.c>
8+
SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
9+
</IfModule>
10+
<IfModule mod_lsapi.c>
11+
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
12+
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
13+
</IfModule>
614
</IfModule>
7-
<IfModule mod_proxy_fcgi.c>
8-
SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
9-
</IfModule>
10-
<IfModule mod_lsapi.c>
11-
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
12-
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
15+
16+
<IfModule mod_env.c>
17+
# Add security and privacy related headers
18+
# Avoid doubled headers by unsetting headers in "onsuccess" table,
19+
# then add headers to "always" table: https://github.com/nextcloud/server/pull/19002
20+
21+
<If "%{REQUEST_URI} =~ m#/login$#">
22+
# Only on the login page we need any Origin or Referer header set.
23+
Header onsuccess unset Referrer-Policy
24+
Header always set Referrer-Policy "same-origin"
25+
</If>
26+
<Else>
27+
Header onsuccess unset Referrer-Policy
28+
Header always set Referrer-Policy "no-referrer"
29+
</Else>
30+
31+
Header onsuccess unset X-Content-Type-Options
32+
Header always set X-Content-Type-Options "nosniff"
33+
34+
Header onsuccess unset X-Frame-Options
35+
Header always set X-Frame-Options "SAMEORIGIN"
36+
37+
Header onsuccess unset X-Permitted-Cross-Domain-Policies
38+
Header always set X-Permitted-Cross-Domain-Policies "none"
39+
40+
Header onsuccess unset X-Robots-Tag
41+
Header always set X-Robots-Tag "noindex, nofollow"
42+
43+
SetEnv modHeadersAvailable true
1344
</IfModule>
14-
</IfModule>
15-
16-
<IfModule mod_env.c>
17-
# Add security and privacy related headers
18-
# Avoid doubled headers by unsetting headers in "onsuccess" table,
19-
# then add headers to "always" table: https://github.com/nextcloud/server/pull/19002
20-
21-
<If "%{REQUEST_URI} =~ m#/login$#">
22-
# Only on the login page we need any Origin or Referer header set.
23-
Header onsuccess unset Referrer-Policy
24-
Header always set Referrer-Policy "same-origin"
25-
</If>
26-
<Else>
27-
Header onsuccess unset Referrer-Policy
28-
Header always set Referrer-Policy "no-referrer"
29-
</Else>
30-
31-
Header onsuccess unset X-Content-Type-Options
32-
Header always set X-Content-Type-Options "nosniff"
33-
34-
Header onsuccess unset X-Frame-Options
35-
Header always set X-Frame-Options "SAMEORIGIN"
36-
37-
Header onsuccess unset X-Permitted-Cross-Domain-Policies
38-
Header always set X-Permitted-Cross-Domain-Policies "none"
39-
40-
Header onsuccess unset X-Robots-Tag
41-
Header always set X-Robots-Tag "noindex, nofollow"
42-
43-
SetEnv modHeadersAvailable true
44-
</IfModule>
45-
46-
# Add cache control for static resources
47-
<FilesMatch "\.(css|js|mjs|svg|gif|png|jpg|webp|ico|wasm|tflite)$">
48-
<If "%{QUERY_STRING} =~ /(^|&)v=/">
49-
Header set Cache-Control "max-age=15778463, immutable"
50-
</If>
51-
<Else>
52-
Header set Cache-Control "max-age=15778463"
53-
</Else>
54-
</FilesMatch>
55-
56-
# Let browsers cache OTF and WOFF files for a week
57-
<FilesMatch "\.(otf|woff2?)$">
58-
Header set Cache-Control "max-age=604800"
59-
</FilesMatch>
45+
46+
# Add cache control for static resources
47+
<FilesMatch "\.(css|js|mjs|svg|gif|png|jpg|webp|ico|wasm|tflite)$">
48+
<If "%{QUERY_STRING} =~ /(^|&)v=/">
49+
Header set Cache-Control "max-age=15778463, immutable"
50+
</If>
51+
<Else>
52+
Header set Cache-Control "max-age=15778463"
53+
</Else>
54+
</FilesMatch>
55+
56+
# Let browsers cache OTF and WOFF files for a week
57+
<FilesMatch "\.(otf|woff2?)$">
58+
Header set Cache-Control "max-age=604800"
59+
</FilesMatch>
6060
</IfModule>
6161

6262
<IfModule mod_php.c>
63-
php_value default_charset 'UTF-8'
64-
php_value output_buffering 0
65-
<IfModule mod_env.c>
66-
SetEnv htaccessWorking true
67-
</IfModule>
63+
php_value default_charset 'UTF-8'
64+
php_value output_buffering 0
65+
<IfModule mod_env.c>
66+
SetEnv htaccessWorking true
67+
</IfModule>
6868
</IfModule>
6969

7070
<IfModule mod_mime.c>
71-
AddType image/svg+xml svg svgz
72-
AddType application/wasm wasm
73-
AddEncoding gzip svgz
74-
# Serve ESM javascript files (.mjs) with correct mime type
75-
AddType text/javascript js mjs
71+
AddType image/svg+xml svg svgz
72+
AddType application/wasm wasm
73+
AddEncoding gzip svgz
74+
# Serve ESM javascript files (.mjs) with correct mime type
75+
AddType text/javascript js mjs
7676
</IfModule>
7777

7878
<IfModule mod_dir.c>
79-
DirectoryIndex index.php index.html
79+
DirectoryIndex index.php index.html
8080
</IfModule>
8181

8282
<IfModule pagespeed_module>
83-
ModPagespeed Off
83+
ModPagespeed Off
8484
</IfModule>
8585

86+
#############
87+
#### Rewrites
88+
#############
89+
8690
<IfModule mod_rewrite.c>
87-
RewriteEngine on
88-
RewriteCond %{HTTP_USER_AGENT} DavClnt
89-
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
90-
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
91-
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
92-
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
93-
RewriteRule ^remote/(.*) remote.php [QSA,L]
94-
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
95-
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
96-
RewriteRule ^ocm-provider/?$ index.php [QSA,L]
97-
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
91+
RewriteEngine on
92+
93+
##
94+
## Rule: Workaround for WebDAV with apache+php-cgi
95+
##
96+
## Context:
97+
## - Sets the environment variable `HTTP_AUTHORIZATION` to the value of the `Authorization` request header
98+
## - Always executed before and along with other rules (no `L` used)
99+
## - XXX: *May* be replaced with an equivalent SetEnvIf in theory
100+
## - XXX: SetEnvIf approach is already in use above for mod_proxy_cgi / mod_lsapi / mod_fcgid
101+
##
102+
103+
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
104+
105+
##
106+
## Rule: Workaround for WebDAV with MS DavClnt
107+
##
108+
## Context:
109+
## - DavClnt attempts an OPTIONS request against `/` instead of the specified endpoint
110+
## - Redirects the client to the endpoint rather than the login page (which confuses DavClnt)
111+
##
112+
113+
RewriteCond %{HTTP_USER_AGENT} DavClnt
114+
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
115+
116+
##
117+
## Rule: Map the RFC 8615 / RFC 6764 compliant well-known URI for CardDAV to our Remote DAV endpoint
118+
##
119+
120+
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
121+
122+
##
123+
## Rule: Map the RFC 8615 / RFC 6764 compliant well-known URI for CalDAV to our Remote DAV endpoint
124+
##
125+
126+
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
127+
128+
##
129+
## Rule: Map /remote* --> /remote.php* including the query string
130+
##
131+
## Context:
132+
## - XXX: `QSA` seems unnecessary (no-op) here (query string is passed by default when the replacement URI doesn't contain a query string)
133+
## - XXX: Is this even used anymore? Seems a relic from <NC12
134+
##
135+
136+
RewriteRule ^remote/(.*) remote.php [QSA,L]
137+
138+
##
139+
## Rule: Prevent access to non-public files
140+
##
141+
142+
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
143+
144+
##
145+
## Rule: Maps most RFC 8615 compliant well-known URIs to our main frontend controller (/index.php) by default
146+
##
147+
## Context:
148+
## - Intentionally excludes URIs used for HTTPS certificate verifications
149+
## - RFC 8555 / ACME HTTP Challenges (acme-challenge)
150+
## - File-based Validations (pki-validation)
151+
## - XXX: `QSA` seems unnecessary (no-op) here (query string is passed by default when the replacement URI doesn't contain a query string)
152+
## - XXX: Sometimes we are using `/index.php` and other times `index.php` as our replacement URI; this may be incorrect
153+
##
154+
155+
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
156+
157+
##
158+
## Rule: Map the ocm-provider handling to our main frontend controller (/index.php)
159+
##
160+
## Context:
161+
## - XXX: `QSA` seems unnecessary (no-op) here (query string is passed by default when the replacement URI doesn't contain a query string)
162+
## - XXX: Sometimes we are using `/index.php` and other times `index.php` as our replacement URI; this may be incorrect
163+
##
164+
165+
RewriteRule ^ocm-provider/?$ index.php [QSA,L]
166+
167+
##
168+
## Rule: Prevent access to more non-public files
169+
##
170+
## Context:
171+
## - XXX It may make sense to merge some of these with the others (i.e. the ones that don't need to be last)
172+
##
173+
174+
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
175+
98176
</IfModule>
99177

100178
# Clients like xDavv5 on Android, or Cyberduck, use chunked requests.
@@ -105,16 +183,18 @@
105183
# Here are more information about the issue:
106184
# - https://docs.cyberduck.io/mountainduck/issues/fastcgi/
107185
# - https://docs.nextcloud.com/server/latest/admin_manual/issues/general_troubleshooting.html#troubleshooting-webdav
186+
108187
<IfModule mod_setenvif.c>
109-
SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1
188+
SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1
110189
</IfModule>
111190

112191
# Apache disabled the sending of the server-side content-length header
113192
# in their 2.4.59 patch updated which breaks some use-cases in Nextcloud.
114193
# Setting ap_trust_cgilike_cl allows to bring back the usual behaviour.
115194
# See https://bz.apache.org/bugzilla/show_bug.cgi?id=68973
195+
116196
<IfModule mod_env.c>
117-
SetEnv ap_trust_cgilike_cl
197+
SetEnv ap_trust_cgilike_cl
118198
</IfModule>
119199

120200
AddDefaultCharset utf-8

0 commit comments

Comments
 (0)