moinwiki/moin

wsgi error when wiki directory served not as '/'

gvlat opened this issue · 3 comments

I run moin 2.0.0b1 as wsgi application using apache-2.4.62. It is configured to serve wiki from "/wiki" directory. When the browser is pointed to "127.0.0.1/wiki" i get "Internal Server Error". The error does not occur when "127.0.0.1/wiki/" (note the trailing slash) is requested.
The following errors are shown in error.log:
error.log

[Thu Aug 22 17:08:29.866816 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] 2024-08-22 17:08:29,861 ERROR moin.signalling.log:31 'NoneType' object has no attribute 'get'
[Thu Aug 22 17:08:29.866834 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] Traceback (most recent call last):
[Thu Aug 22 17:08:29.866837 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 1473, in wsgi_app
[Thu Aug 22 17:08:29.866841 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     response = self.full_dispatch_request()
[Thu Aug 22 17:08:29.866844 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.866846 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 882, in full_dispatch_request
[Thu Aug 22 17:08:29.866849 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.handle_user_exception(e)
[Thu Aug 22 17:08:29.866852 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.866855 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 878, in full_dispatch_request
[Thu Aug 22 17:08:29.866858 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.preprocess_request()
[Thu Aug 22 17:08:29.866873 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.866875 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 1253, in preprocess_request
[Thu Aug 22 17:08:29.866877 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.ensure_sync(before_func)()
[Thu Aug 22 17:08:29.866878 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.866880 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/moin/app.py", line 316, in before_wiki
[Thu Aug 22 17:08:29.866882 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     setup_jinja_env()
[Thu Aug 22 17:08:29.866884 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/moin/themes/__init__.py", line 850, in setup_jinja_env
[Thu Aug 22 17:08:29.866886 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     "item_name": request.view_args.get("item_name", ""),
[Thu Aug 22 17:08:29.866887 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]                  ^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.866889 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] AttributeError: 'NoneType' object has no attribute 'get'
[Thu Aug 22 17:08:29.867459 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] 2024-08-22 17:08:29,866 ERROR moin:838 Exception on / [GET]
[Thu Aug 22 17:08:29.867467 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] Traceback (most recent call last):
[Thu Aug 22 17:08:29.867469 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 1473, in wsgi_app
[Thu Aug 22 17:08:29.867471 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     response = self.full_dispatch_request()
[Thu Aug 22 17:08:29.867473 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.867475 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 882, in full_dispatch_request
[Thu Aug 22 17:08:29.867477 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.handle_user_exception(e)
[Thu Aug 22 17:08:29.867479 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.867480 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 878, in full_dispatch_request
[Thu Aug 22 17:08:29.867482 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.preprocess_request()
[Thu Aug 22 17:08:29.867484 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.867486 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/flask/app.py", line 1253, in preprocess_request
[Thu Aug 22 17:08:29.867487 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     rv = self.ensure_sync(before_func)()
[Thu Aug 22 17:08:29.867489 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.867491 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/moin/app.py", line 316, in before_wiki
[Thu Aug 22 17:08:29.867493 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     setup_jinja_env()
[Thu Aug 22 17:08:29.867495 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]   File "/home/storage/moin-venv/lib64/python3.12/site-packages/moin/themes/__init__.py", line 850, in setup_jinja_env
[Thu Aug 22 17:08:29.867502 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]     "item_name": request.view_args.get("item_name", ""),
[Thu Aug 22 17:08:29.867504 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872]                  ^^^^^^^^^^^^^^^^^^^^^
[Thu Aug 22 17:08:29.867506 2024] [wsgi:error] [pid 1427:tid 1979] [client 127.0.0.1:45872] AttributeError: 'NoneType' object has no attribute 'get'

Steps to reproduce:

  1. install moin as wsgi application with "WSGIScriptAlias /wiki /path_to/moin2wsgi.py"
  2. run 'curl -f 127.0.0.1/wiki'
    The followng error appears
    curl: (22) The requested URL returned error: 500
    wsgi configuration:
WSGIDaemonProcess moin2
WSGIPythonHome /home/storage/moin-venv

WSGIScriptAlias /wiki /home/storage/wiki/moin2wsgi.py

<Directory "/home/storage/wiki">
    Require all granted
</Directory>

Software:

OS: Fedora Linux 39
Python 3.12.4
python3-mod_wsgi-4.9.4
httpd-2.4.62
moin-2.0.0b1 installed via 'pip install --pre moin'

I can reproduce the issue with nginx and uwsgi by adding

mount = /wiki=moin2.wsgi
manage-script-name = true

where moin2.wsgi is what you called moin2wsgi.py.

As a silly workaround I changed themes/init.py:

@@ -833,6 +833,13 @@ def setup_jinja_env():
     # please note that these filters are installed by flask-babel:
     # datetimeformat, dateformat, timeformat, timedeltaformat
 
+
+    if request.view_args:
+        item_name = request.view_args.get('item_name', '')
+        logging.debug(f"request.view_args item_name: {item_name}")
+    else:
+        item_name = ""
+
     app.jinja_env.globals.update(
         {
             # please note that flask-babel/jinja2.ext installs:
@@ -847,7 +854,7 @@ def setup_jinja_env():
             "storage": flaskg.storage,
             "clock": flaskg.clock,
             "cfg": app.cfg,
-            "item_name": request.view_args.get("item_name", ""),
+            "item_name": item_name,
             "url_for_item": url_for_item,
             "get_fqname": get_fqname,
             "get_editor_info": lambda meta: get_editor_info(meta),

With loglevel=DEBUG I found this in the logs (shortend):

For https://myurl/wiki/

GET /wiki/ => generated 207 bytes in 41 msecs (HTTP/1.1 302) 3 headers in 105 bytes (1 switches on core 0)
GET /wiki/Home => generated 12926 bytes in 733 msecs (HTTP/1.1 200) 3 headers in 96 bytes (1 switches on core 0)
GET /wiki/static/css/normalize.css => generated 0 bytes in 7 msecs (HTTP/1.1 304) 4 headers in 184 bytes (0 switches on core 0)
GET /wiki/static/css/variables.css => generated 0 bytes in 3 msecs (HTTP/1.1 304) 4 headers in 188 bytes (0 switches on core 0)
...

For https://myurl/wiki

GET /wiki => generated 251 bytes in 8 msecs (HTTP/1.1 308) 3 headers in 140 bytes (1 switches on core 0)
GET /wiki/ => generated 207 bytes in 4 msecs (HTTP/1.1 302) 3 headers in 105 bytes (1 switches on core 0)
GET /wiki/Home => generated 12926 bytes in 304 msecs (HTTP/1.1 200) 3 headers in 96 bytes (1 switches on core 0)
GET /wiki/static/css/normalize.css => generated 0 bytes in 13 msecs (HTTP/1.1 304) 4 headers in 184 bytes (0 switches on core 0)
GET /wiki/static/css/variables.css => generated 0 bytes in 4 msecs (HTTP/1.1 304) 4 headers in 188 bytes (0 switches on core 0)
...

It seems that there is an additional GET request for /wiki without slash where the request context is missing.
The setup_jinja_env function is called even for the 'GET /wiki/static/...' requests, where jinja should not be used.
Can somebody help and explain?

The reason for the redirect from '/wiki' to '/wiki/' is the setting of 'strict_slashes' (see https://werkzeug.palletsprojects.com/en/2.3.x/routing/#rule-format). Setting this option to False with the above change should solve the problem.

@gvlat can you please check in your environment?

This change solves the problem on my system. Thank you for your work!