[SOLVED] File upload above 1MB throws StringIndexOutOfBounds because of misconfiguration

I wasn’t sure exactly what category this was supposed to fit in, but since the malfunction I observe is on the android app, it probably holds the key to understanding what’s wrong in my setup.

Essentially, uploading any file from the android app bigger than 1MB fails. At first I thought about an upload limit, but after setting these things, and realizing that I can upload files as big as 2GiB on the desktop client, I discarded that idea.

My stack is as follows : an Apache2 server listens on the internet for incoming connections (redirecting http to https), and acts as a reverse proxy towards another computer on a local network, forwarding to its port 9000, which itself is mapped to the exposed port 80 of a docker container which runs a typical LAMP stack (both containers for MariaDB and Nextcloud were pulled from DockerHub and only modified slightly as explained below).

Here is the configuration file for the reverse proxy exposed to the internet :

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<IfModule mod_ssl.c>
    <VirtualHost *:443>
            ProxyPreserveHost On
            ProxyRequests Off
            ServerAdmin root@example.com
            ServerName example.com
            ServerAlias example.com
            LimitRequestBody 10737418240
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            <IfModule mod_rewrite.c>
                    RewriteEngine on
                    RewriteRule ^/\.well-known/host-meta /public.php?service=host-meta [QSA,L]
                    RewriteRule ^/\.well-known/host-meta\.json /public.php?service=host-meta-json [QSA,L]
                    RewriteRule ^/\.well-known/webfinger /public.php?service=webfinger [QSA,L]
                    RewriteRule ^/\.well-known/carddav /remote.php/dav/ [R=301,L]
                    RewriteRule ^/\.well-known/caldav /remote.php/dav/ [R=301,L]
            </IfModule>
            ProxyPass / http://10.8.1.19:9000/
            ProxyPassReverse / http://10.8.1.19:9000/
            RewriteEngine On
            RewriteCond %{HTTP:Authorization} ^(.*)
            RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
            SSLEngine on
            SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
            SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
            SSLCertificateChainFile /etc/letsencrypt/live/example.com/fullchain.pem
            SSLProxyEngine on
            <Proxy example.com:443>
                    Order deny,allow
                    Allow from all
            </Proxy>
            # Fix the HTTP Authorization header so the Android app can login (https://github.com/nextcloud/server/issues/8956)
            <IfModule mod_headers.c>
                  Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
            </IfModule>
    </VirtualHost>
</IfModule>
# HTTPs redirection ommited, it's literally a Redirect

The php.ini configuration file I added inside my nextcloud docker (to ensure a high upload limit)

upload_max_filesize=10G
post_max_size=10G
max_execution_time=3600

The apache site file for the docker front :

<VirtualHost *:80>
    LimitRequestBody 10737418240
    ServerAdmin email@example.com
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Now, the main symptoms are observed on the Android app (version 3.13.1). Uploading a file with size < 1MB gives the following logs (obtained using Logcat) : https://cloud.vulpinecitrus.info/s/eNp7yrTCnxp8mi4
While uploading (well, here, attempting to reuplod) a file with size >= 1MB gives the following logs : https://cloud.vulpinecitrus.info/s/CJSyBrdPMwXHL7B

Clearly, as shown by lines 270 and 271 of OwnCloudClient.java (android-library/OwnCloudClient.java at master · nextcloud/android-library · GitHub), the app’s library is trying to find the string called ‘AccountUtils.WEBDAV_PATH_4_0’, which is “/remote.php/webdav” in one of the redirections used to upload. The problem is that, specifically for files with size > 1MB, they use “/remote.php/dav” in their URLs (as shown in the logs), while the others use “/remote.php/webdav”.

I’m positive this is a configuration error on my end since upload works fine on https://try.nextcloud.com (which is why I’m here and not on GitHub), was reproduced on both the F-Droid and Play store versions, and even on a freshly reset android system. Having found nobody on the IRC channel, I count on your help to guide me towards what’s wrong here (and maybe try and see if the Android app isn’t doing some funky business it shouldn’t which would normally work but doesn’t with me).

Any ideas? :sweat_smile:

I frankly don’t understand how but after a week of messing around with Apache options on both the proxy and the docker web server, I managed to solve this problem… However I could not reverse-engineer exactly what bit fixed it. Since both my proxy’s config and the docker’s server’s config (which I have now reset since my stack works by deploying fresh dockers) are exactly as they were when I posted this (except for the LimitRequestBody statement on the docker’s apache server but removing it wasn’t the solution), I’m guessing it’s something I changed with nextcloud’s own configuration.
I can’t reverse engineer it now anyways, it’s too late, I installed a memcache and upgraded to NC 20 after the issue was resolved with android uploads, so… case closed for now. If I encounter this again and figure it out I’ll post it here in case anyone has the same issue.