mod_http_upload behind nginx reverse proxy

I am trying to put mod_http_upload behind a nginx reverse proxy.

In nginx I just set up the usual proxy forwarding:

# remove URL prefix
rewrite /ejabberd/(.*) /$1 break;
rewrite /ejabberd$ /ejabberd/ permanent;

proxy_pass http://127.0.0.1:1234;
proxy_set_header Host $host;
proxy_buffering off;
#tcp_nodelay on;
# some more proxy headers follow…

And in the access log I even can see the requests (custom log format):

192.168.0.13 - - [SOMEDATE:23:59:21 +0100] "PUT /ejabberdNP0lC/customuploaddir/de754bb7b1e8ad30593b859b2c22bb2d942cb2e4/yyDPCEq7r5cn48AWjuUCSWwHGt46zHUOMtGX5DT4/Tux.svg HTTP/1.1" 500 23 "-" "Gajim 0.16.6"; tls: TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384; (158717) POST:"-"
192.168.0.13 - - [SOMEDATE:23:59:58 +0100] "PUT /ejabberdNP0lC/customuploaddir/de754bb7b1e8ad30593b859b2c22bb2d942cb2e4/suyqabWStayXQTuzY5QutIfv5FtF4aPMgjrQJ5zb/Tux.svg HTTP/1.1" 500 23 "-" "Gajim 0.16.6"; tls: TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384; (158717) POST:"-"
192.168.0.13 - - [SOMEDATE:00:12:06 +0100] "PUT /ejabberdNP0lC/customuploaddir/de754bb7b1e8ad30593b859b2c22bb2d942cb2e4/C1OS9S9uJWFubIJrgPa6eXXW4W3RCUlyM2WlW4Iq/Tux.svg HTTP/1.1" 500 23 "-" "Gajim 0.16.6"; tls: TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384; (158717) POST:"-"

However in ejabberd I only get errors and the upload fails with HTTP error 500 (as it can also be seen in the nginx logs):

SOMEDATE 00:12:06.835 [info] <0.506.0>@mod_http_upload:create_slot:641 Got HTTP upload slot for testuser@domain.example/Gajim (file: Tux.svg)
SOMEDATE 00:12:06.908 [info] <0.549.0>@ejabberd_listener:accept:333 (#Port<0.19517>) Accepted connection 127.0.0.1:37140 -> 127.0.0.1:1234
SOMEDATE 00:12:06.909 [info] <0.585.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19517>}
SOMEDATE 00:12:06.916 [error] <0.585.0>@mod_http_upload:process:441 Cannot handle PUT request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/customuploaddir',{use_slot,[<<"de754bb7b1e8ad30593b859b2c22bb2d942cb2e4">>,<<"C1OS9S9uJWFubIJrgPa6eXXW4W3RCUlyM2WlW4Iq">>,<<"Tux.svg">>],158435}]}}}

Now even without the nginx proxy (with a usual out url) it does not work and shows me this:

SOMEDATE 00:14:27.400 [info] <0.546.0>@ejabberd_listener:accept:333 (#Port<0.19288>) Accepted connection OTHERIP:32222 -> IP_EJABBERDSERVER:5222
SOMEDATE 00:14:27.853 [info] <0.506.0>@mod_http_upload:create_slot:641 Got HTTP upload slot for testuser@domain.example/Gajim (file: Tux.svg)
SOMEDATE 00:14:27.861 [info] <0.550.0>@ejabberd_listener:accept:333 (#Port<0.19289>) Accepted connection 192.168.0.33:56050 -> IP_EJABBERDSERVER:1234
SOMEDATE 00:14:27.862 [info] <0.562.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19289>}
SOMEDATE 00:14:28.274 [info] <0.546.0>@ejabberd_listener:accept:333 (#Port<0.19290>) Accepted connection OTHERIP:11042 -> IP_EJABBERDSERVER:5222

So my ejabberd config part is this:

-
    port: 1234
    module: ejabberd_http
    request_handlers:
    "/websocket": ejabberd_http_ws
    ##  "/pub/archive": mod_http_fileserver
      "/customuploaddir": mod_http_upload
    […]
[…]
mod_http_upload:
    host: "@HOST@"
    # name: "HTTP File Upload"
    […]
    docroot: "/home/ejabberd/dir"
    put_url: "https://domain.example:1234/customuploaddir" # (for testing, direct put url)
    #put_url: "https://domain.example:443/ejabberd/customuploaddir" # (usual nginx reverse proxy)

Finally here some other, older ejabberd logs showing the same error:

SOMEDATE 23:26:11.924 [error] <0.654.0>@mod_http_upload:process:441 Cannot handle PUT request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',{use_slot,[<<"de754bb7b1e8ad30593b859b2c22bb2d942cb2e4">>,<<"37K5b3X82B0w2svGgSX3dctIemcAeu3V0fJTHVLr">>,<<"Tux.svg">>],158435}]}}}
[…]
SOMEDATE 23:53:11.785 [info] <0.496.0>@mod_http_upload:create_slot:641 Got HTTP upload slot for testuser@domain.example/Gajim (file: Tux.svg)
SOMEDATE 23:53:12.274 [info] <0.539.0>@ejabberd_listener:accept:333 (#Port<0.19898>) Accepted connection 127.0.0.1:37121 -> 127.0.0.1:1234
SOMEDATE 23:53:12.276 [info] <0.734.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19898>}
SOMEDATE 23:53:12.283 [error] <0.734.0>@mod_http_upload:process:441 Cannot handle PUT request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',{use_slot,[<<"de754bb7b1e8ad30593b859b2c22bb2d942cb2e4">>,<<"wU7xYO9FfPRdSNQSwKYeicUdcG7tOSVSuVzbQ94c">>,<<"Tux.svg">>],158435}]}}}
SOMEDATE 23:53:38.506 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19899>) Accepted connection 192.168.0.33:41491 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:53:38.510 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19900>) Accepted connection 192.168.0.33:49642 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:54:11.136 [info] <0.539.0>@ejabberd_listener:accept:333 (#Port<0.19903>) Accepted connection 127.0.0.1:37123 -> 127.0.0.1:1234
SOMEDATE 23:54:11.138 [info] <0.739.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19903>}
SOMEDATE 23:54:11.141 [error] <0.739.0>@mod_http_upload:process:484 Cannot handle GET request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',get_docroot]}}}
SOMEDATE 23:54:19.250 [info] <0.539.0>@ejabberd_listener:accept:333 (#Port<0.19904>) Accepted connection 127.0.0.1:37125 -> 127.0.0.1:1234
SOMEDATE 23:54:19.251 [info] <0.740.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19904>}
SOMEDATE 23:54:19.254 [error] <0.740.0>@mod_http_upload:process:484 Cannot handle GET request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',get_docroot]}}}
SOMEDATE 23:54:33.046 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19905>) Accepted connection 192.168.0.33:45820 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:54:33.050 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19906>) Accepted connection 192.168.0.33:51985 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:55:47.076 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19909>) Accepted connection 192.168.0.33:46527 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:56:41.981 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19911>) Accepted connection 192.168.0.33:42521 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:57:19.587 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19913>) Accepted connection 192.168.0.33:59705 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:58:01.934 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19915>) Accepted connection 192.168.0.33:42098 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:58:01.938 [info] <0.536.0>@ejabberd_listener:accept:333 (#Port<0.19916>) Accepted connection 192.168.0.33:49623 -> IP_EJABBERDSERVER:5222
SOMEDATE 23:59:20.985 [info] <0.496.0>@mod_http_upload:create_slot:641 Got HTTP upload slot for testuser@domain.example/Gajim (file: Tux.svg)
SOMEDATE 23:59:21.244 [info] <0.539.0>@ejabberd_listener:accept:333 (#Port<0.19919>) Accepted connection 127.0.0.1:37127 -> 127.0.0.1:1234
SOMEDATE 23:59:21.246 [info] <0.757.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19919>}
SOMEDATE 23:59:21.253 [error] <0.757.0>@mod_http_upload:process:441 Cannot handle PUT request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',{use_slot,[<<"de754bb7b1e8ad30593b859b2c22bb2d942cb2e4">>,<<"yyDPCEq7r5cn48AWjuUCSWwHGt46zHUOMtGX5DT4">>,<<"Tux.svg">>],158435}]}}}
SOMEDATE 23:59:58.658 [info] <0.496.0>@mod_http_upload:create_slot:641 Got HTTP upload slot for testuser@domain.example/Gajim (file: Tux.svg)
SOMEDATE 23:59:58.713 [info] <0.539.0>@ejabberd_listener:accept:333 (#Port<0.19920>) Accepted connection 127.0.0.1:37128 -> 127.0.0.1:1234
SOMEDATE 23:59:58.714 [info] <0.758.0>@ejabberd_http:init:163 started: {gen_tcp,#Port<0.19920>}
SOMEDATE 23:59:58.721 [error] <0.758.0>@mod_http_upload:process:441 Cannot handle PUT request from 192.168.0.33 for domain.example: {'EXIT',{noproc,{gen_server,call,['mod_http_upload_domain.example/fileupload',{use_slot,[<<"de754bb7b1e8ad30593b859b2c22bb2d942cb2e4">>,<<"suyqabWStayXQTuzY5QutIfv5FtF4aPMgjrQJ5zb">>,<<"Tux.svg">>],158435}]}}}

ejabberd 16.09

I've hit the same error with

I've hit the same error with Apache mod_proxy.
But I've found a solution: I made sure the path was the same.

Try the following:

-
port: 1234
request_handlers:
[…]
"/ejabberd/customuploaddir": mod_http_upload

mod_http_upload:
[…]
put_url: "https://domain.example/ejabberd/customuploaddir"

And keep the prefix in NGinx.
Apache config would go like this:

ProxyPass /ejabberd/ http://localhost:1234/ejabberd/
ProxyPassReverse /ejabberd/ http://localhost:1234/ejabberd/

I think it also work if you get rid of the prefix everywhere.
Because I'm not sure the other features (http_bind, register, admin, captcha, ...) will work with that prefix.
I'm considering to use a "sub-vhost", like ejabberd.domain.example.com to proxy without prefix.
But it is usually less convenient...

Syndicate content