Closed chriscroome closed 1 year ago
Since I wrote the above I have found this issue to cause data loss, only the first part of a document was saved no matter what I did, I ended up resorting to using ONLYOFFICE rather than the Text app because it does reliably save edits.
The "Saving..." status is shown when the document is syncing with the server, closing the document in this status will not guarantee that your latest changes will be saved.
@Raudius why do you believe that this issue has been solved, I have just tested writing to a .md
document on a development server running Nextcloud Hub 3 (25.0.1) and the issue appears to be unresolved and perhaps even worse than ever, editing Markdown files using the web interface doesn't appear to work at all, could I provide you with an account so you can see for yourself?
Furthermore I suspect that this issue might have the same underlying cause as this issue and I suspect that it might be related to the Apache / PHP-FPM configuration, but I could be wrong, I haven't been able to find anything in any logs to indicate the cause of these problems.
This is the Apache config in question:
<IfModule proxy_fcgi_module>
<Proxy "unix:/home/cloud/php-fpm.sock|fcgi://cloud">
ProxySet timeout=300
</Proxy>
</IfModule>
<IfFile "/home/cloud/sites/nextcloud">
DocumentRoot "/home/cloud/sites/nextcloud"
<Directory "/home/cloud/sites/nextcloud">
Options +MultiViews +SymLinksIfOwnerMatch
DirectoryIndex index.php
AllowOverride All
<IfModule proxy_fcgi_module>
<IfModule setenvif_module>
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://cloud"
</If>
</FilesMatch>
</IfModule>
AuthType "None"
Require all granted
</Directory>
</IfFile>
Hi Chris,
Maybe I misunderstood your initial comment, I though the issue you described was that closing a file during the "Saving..." status results in the file not being saved. This would not be surprising.
However if I understand now, you are reporting that syncing does not work at all? Do you see any messages in your browser console when using the text editor?
I will try testing it with your config to see if I get the same issue
Thanks @Raudius this is some of the output I get in the Firefox console:
File info for /New text file.md fetched
Object { filename: "/New text file.md", basename: "New text file.md", lastmod: "Wed, 16 Nov 2022 15:50:50 GMT", size: 2, type: "file", etag: null, mime: "text/markdown", getlastmodified: "Wed, 16 Nov 2022 15:50:50 GMT", getcontenttype: "text/markdown", resourcetype: "", … }
viewer-main.js:2:1424081
jQuery is deprecated: The global jQuery is deprecated. It will be removed in a later versions without another warning. Please ship your own. core-main.js:2:68390
The select2 library is deprecated! It will be removed in nextcloud 19. 2 core-main.js:2:68390
OC.getCapabilities is deprecated and will be removed in Nextcloud 21. See @nextcloud/capabilities core-main.js:2:51332
Proxying an event bus of version 2.1.1 with 3.0.2 vendors.js:2:165624
$ is deprecated: The global jQuery is deprecated. It will be removed in a later versions without another warning. Please ship your own. 12 core-main.js:2:68390
recommendations
Array []
files_sharing-files_sharing_tab.js:2:23268
This page is in Quirks Mode. Page layout may be impacted. For Standards Mode use “<!DOCTYPE html>”. vendors.js:2:1436605
This page is in Quirks Mode. Page layout may be impacted. For Standards Mode use “<!DOCTYPE html>”. core-common.js:2:9065544
Error while loading the file data
Object { message: "Request failed with status code 405", name: "AxiosError", code: "ERR_BAD_REQUEST", config: {…}, request: XMLHttpRequest, response: {…}, stack: "" }
files-sidebar.js:2:9777
Uncaught (in promise) Error: AxiosError: Request failed with status code 405
i https://nextcloud.webarch.org.uk/dist/files-sidebar.js?v=a3811f53-0:2
u https://nextcloud.webarch.org.uk/dist/core-common.js?v=a3811f53-0:2
_invoke https://nextcloud.webarch.org.uk/dist/core-common.js?v=a3811f53-0:2
C https://nextcloud.webarch.org.uk/dist/core-common.js?v=a3811f53-0:2
E https://nextcloud.webarch.org.uk/dist/files-sidebar.js?v=a3811f53-0:2
a https://nextcloud.webarch.org.uk/dist/files-sidebar.js?v=a3811f53-0:2
files-sidebar.js:2:9825
Uncaught (in promise) TypeError: e.response is undefined
getFileInfo https://nextcloud.webarch.org.uk/apps/text/js/text-files.js?v=a3811f53-0:2
text-files.js:2:48312
And this appears to the the corresponding Apache access log entry for the 405:
X.X.X.X. - - [16/Nov/2022:16:23:20 +0000] "PROPFIND /apps/dashboard/ HTTP/2.0" 405 813 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0"
And the PHP-FPM log entry:
- - 16/Nov/2022:16:23:20 +0000 "PROPFIND /index.php" 405 /home/cloud/sites/nextcloud/index.php 285.493 2048 38.53%
There are no Limit directives in the Apache config, so my understanding is that all methods, (GET, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, and UNLOCK.) are therefore allowed.
@Raudius I took the liberty to tag the issue high
and put it on our bugfix board :relaxed:
Thanks @mejo- and @Raudius here is the full Apache configuration (/etc/apache2/sites-available/cloud.conf
) for the development server (which you can have access to if needed):
# Ansible managed
# nextcloud.webarch.org.uk port 80
<VirtualHost *:80>
ServerName nextcloud.webarch.org.uk
ServerAlias www.nextcloud.webarch.org.uk
<If "%{HTTP_HOST} == 'nextcloud.webarch.org.uk'">
RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* https://nextcloud.webarch.org.uk$0
</If>
<ElseIf "%{HTTP_HOST} == 'www.nextcloud.webarch.org.uk'">
RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* https://www.nextcloud.webarch.org.uk$0
</ElseIf>
<Else>
RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* https://nextcloud.webarch.org.uk$0
</Else>
</VirtualHost>
# nextcloud.webarch.org.uk port 443
# /home/cloud/sites/nextcloud
<IfModule md_module>
MDomain nextcloud.webarch.org.uk
</IfModule>
<VirtualHost *:443>
ServerName nextcloud.webarch.org.uk
ServerAlias www.nextcloud.webarch.org.uk
SSLEngine on
SSLCertificateFile /etc/ssl/le/nextcloud.webarch.org.uk.cert.pem
SSLCertificateKeyFile /etc/ssl/le/nextcloud.webarch.org.uk.key.pem
SSLCertificateChainFile /etc/ssl/le/nextcloud.webarch.org.uk.ca.pem
ServerAdmin "chris@webarchitects.co.uk"
<IfModule headers_module>
Header always set Strict-Transport-Security "max-age=630720645;"
Header always set Permissions-Policy "interest-cohort=()"
</IfModule>
<Location "/.well-known/acme-challenge">
AuthType None
Require all granted
</Location>
IncludeOptional /etc/apache2/conf-available/robots-deny-nextcloud.conf
<IfModule proxy_fcgi_module>
<Proxy "unix:/users/cloud/home/cloud/php-fpm.sock|fcgi://cloud">
ProxySet timeout=300
</Proxy>
</IfModule>
<IfFile "/home/cloud/sites/nextcloud">
DocumentRoot "/home/cloud/sites/nextcloud"
<Directory "/home/cloud/sites/nextcloud">
Options +MultiViews +SymLinksIfOwnerMatch
DirectoryIndex index.php
AllowOverride All
<IfModule proxy_fcgi_module>
<IfModule setenvif_module>
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://cloud"
</If>
</FilesMatch>
</IfModule>
AuthType "None"
Require all granted
</Directory>
</IfFile>
# No access allowed for this directory
<IfFile "/home/cloud/sites/nextcloud/config">
<Directory "/home/cloud/sites/nextcloud/config">
Require all denied
</Directory>
</IfFile>
# No access allowed for this directory
<IfFile "/home/cloud/sites/nextcloud/data">
<Directory "/home/cloud/sites/nextcloud/data">
Require all denied
</Directory>
</IfFile>
<IfModule proxy_module>
# In reverse proxy or gateway configuration, ProxyRequests should be set to Off
ProxyRequests Off
# Enable error documents under /wsh to be served rather than proxying error responses
ProxyErrorOverride On
ProxyPass "/push/ws" "ws://127.0.0.1:7867/ws"
ProxyPass "/push/" "http://127.0.0.1:7867/"
ProxyPassReverse "/push/" "http://127.0.0.1:7867/"
</IfModule>
CustomLog /var/log/apache2/cloud_access.log bandwidth
LogLevel error
<IfFile /home/cloud/logs>
ErrorLog /home/cloud/logs/apache.error.log
CustomLog /home/cloud/logs/apache.access.log combined
</IfFile>
</VirtualHost>
# vim: set ft=apache:
This is the content of the automatically generated htaccess
file at /home/cloud/sites/nextcloud/.htaccess
:
IfModule mod_headers.c>
<IfModule mod_setenvif.c>
<IfModule mod_fcgid.c>
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
</IfModule>
<IfModule mod_proxy_fcgi.c>
SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
<IfModule mod_lsapi.c>
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
</IfModule>
</IfModule>
<IfModule mod_env.c>
# Add security and privacy related headers
# Avoid doubled headers by unsetting headers in "onsuccess" table,
# then add headers to "always" table: https://github.com/nextcloud/server/pull/19002
Header onsuccess unset Referrer-Policy
Header always set Referrer-Policy "no-referrer"
Header onsuccess unset X-Content-Type-Options
Header always set X-Content-Type-Options "nosniff"
Header onsuccess unset X-Frame-Options
Header always set X-Frame-Options "SAMEORIGIN"
Header onsuccess unset X-Permitted-Cross-Domain-Policies
Header always set X-Permitted-Cross-Domain-Policies "none"
Header onsuccess unset X-Robots-Tag
Header always set X-Robots-Tag "none"
Header onsuccess unset X-XSS-Protection
Header always set X-XSS-Protection "1; mode=block"
SetEnv modHeadersAvailable true
</IfModule>
# Add cache control for static resources
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico|wasm|tflite)$">
Header set Cache-Control "max-age=15778463"
</FilesMatch>
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico|wasm|tflite)(\?v=.*)?$">
Header set Cache-Control "max-age=15778463, immutable"
</FilesMatch>
# Let browsers cache WOFF files for a week
<FilesMatch "\.woff2?$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
</IfModule>
# PHP 7.x
<IfModule mod_php7.c>
php_value mbstring.func_overload 0
php_value default_charset 'UTF-8'
php_value output_buffering 0
<IfModule mod_env.c>
SetEnv htaccessWorking true
</IfModule>
</IfModule>
# PHP 8+
<IfModule mod_php.c>
php_value mbstring.func_overload 0
php_value default_charset 'UTF-8'
php_value output_buffering 0
<IfModule mod_env.c>
SetEnv htaccessWorking true
</IfModule>
</IfModule>
<IfModule mod_mime.c>
AddType image/svg+xml svg svgz
AddType application/wasm wasm
AddEncoding gzip svgz
</IfModule>
<IfModule mod_dir.c>
DirectoryIndex index.php index.html
</IfModule>
<IfModule pagespeed_module>
ModPagespeed Off
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} DavClnt
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>
AddDefaultCharset utf-8
Options -Indexes
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####
ErrorDocument 403 /
ErrorDocument 404 /
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav|wasm|tflite)$
RewriteCond %{REQUEST_FILENAME} !/core/ajax/update\.php
RewriteCond %{REQUEST_FILENAME} !/core/img/(favicon\.ico|manifest\.json)$
RewriteCond %{REQUEST_FILENAME} !/(cron|public|remote|status)\.php
RewriteCond %{REQUEST_FILENAME} !/ocs/v(1|2)\.php
RewriteCond %{REQUEST_FILENAME} !/robots\.txt
RewriteCond %{REQUEST_FILENAME} !/(ocm-provider|ocs-provider|updater)/
RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$
RewriteRule . index.php [PT,E=PATH_INFO:$1]
RewriteBase /
<IfModule mod_env.c>
SetEnv front_controller_active true
<IfModule mod_dir.c>
DirectorySlash off
</IfModule>
</IfModule>
</IfModule>
And this is the content of the PHP-FPM configuration at /etc/php/7.4/fpm/pool.d/cloud.conf
:
; Ansible provisioned
[cloud]
user = cloud
group = cloud
listen = /home/cloud/php-fpm.sock
access.log = /home/cloud/logs/php-fpm.access.log
slowlog = /home/cloud/logs/php-fpm.slow.log
php_admin_value[error_log] = /home/cloud/logs/fpm-php.error.log
listen.owner = root
listen.group = cloud
listen.mode = 0660
;listen.acl_users =
;listen.acl_groups =
listen.allowed_clients = 127.0.0.1
; Error log level. Possible values: alert, error, warning, notice, debug. Default value: notice.
php_admin_value[log_level] = notice
env[TMP] = /home/cloud/tmp
env[TMPDIR] = /home/cloud/tmp
env[TEMP] = /home/cloud/tmp
chdir = /home/cloud
; PHP settings passed with php_value or php_flag will overwrite php.ini values
; but defining disable_functions or disable_classes will not overwrite
; previously defined php.ini values, but will append the new value instead.
;
; https://www.php.net/install.fpm.configuration
; disable_functions set from user.value.users_phpfpm_disable_functions
php_admin_value[disable_functions] = "chgrp,chown,curl_multi_exec,dl,exec,fsockopen,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,popen,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,socket_create,symlink,system,system_exec"
; users_phpfpm_enable_open_basedir is true
; user.value.users_phpfpm_enable_open_basedir is not set to false
; open_basedir set from the users_phpfpm_open_basedir array
php_admin_value[open_basedir] = "/home/$pool/sites/:/home/$pool/tmp/:/usr/share/php"
php_admin_value[mysqli.allow_local_infile] = 0
php_admin_value[session.save_path] = /home/cloud/tmp
php_admin_value[upload_tmp_dir] = /home/cloud/tmp
php_admin_value[sys_temp_dir] = /home/cloud/tmp
php_admin_value[soap.wsdl_cache_dir] = /home/cloud/tmp
php_admin_value[uploadprogress.file.contents_template] = /home/cloud/tmp/upload_contents_%s
php_admin_value[uploadprogress.file.filename_template] = /home/cloud/tmp/upt_%s.txt
php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -fnextcloud@webarch.org.uk
php_admin_value[sendmail_from] = nextcloud@webarch.org.uk
php_admin_value[mail.log] = /home/cloud/logs/php-fpm.mail.log
pm = dynamic
pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.process_idle_timeout = 10s;
pm.max_requests = 1000
pm.status_path = /phpfpm-cloud-status
;ping.path = /ping
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
request_slowlog_timeout = 30
request_terminate_timeout = 360
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
;catch_workers_output = yes
; Decorate worker output with prefix and suffix containing information about
; the child that writes to the log and if stdout or stderr is used as well as
; log level and time. This options is used only if catch_workers_output is yes.
; Settings to "no" will output data as written to the stdout or stderr.
; Default value: yes
;decorate_workers_output = no
; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this
; pool configuration are added.
; Setting to "no" will make all environment variables available to PHP code
; via getenv(), $_ENV and $_SERVER.
; Default Value: yes
;clear_env = no
clear_env = yes
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; execute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5 .php7
security.limit_extensions = .php
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
; Note: path INI options can be relative and will be expanded with the prefix
; (pool, global or /usr)
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
; vim: set ft=dosini:
Please let me know if there is anything else I can do to help.
Dear @chriscroome, I agree that the editor displaying "saving ..." is a bit confusing.
Though, the saving indicator changed significantly with Nextcloud 26. We replaced it with a simple dot indicator.
In general, changes from the current session are written back to the filesystem in either of the following situations:
I think we should additionally allow to force-save by clicking the save indicator button.
When editing a
.md
file this text is sometimes displayed:However generally this appears:
Occasionally it displays:
To Reproduce
Steps to reproduce the behavior:
.md
fileExpected behavior
I haven't been able to demonstrate that this causes any data loss however it is confusing for users who think that their changes haven't been saved and they might lose data.
Client details:
Text app version: 3.4.1
Operating system: Debian Bullseye
Web server: Apache/2.4.53 (Debian)
Database: mariadb Ver 15.1 Distrib 10.5.15-MariaDB, for debian-linux-gnu (x86_64)
PHP version: PHP-FPM 7.4.28
Nextcloud version:
Nextcloud log (data/nextcloud.log)
I have found no corresponding log entries
Browser log
I have found no corresponding log entries (other that
200
's)