wsgi error: Unable to get bucket brigade for request & apache2 redirects post to get?

蹲街弑〆低调 提交于 2019-12-11 17:12:21

问题


I want to handle a post request with a Flask app deployed on apache2 but I got unintended redirection. it also looses request body. I trigger a post request using a web app and access log says: 57.39.118.158 - - [22/Dec/2017:11:44:32 +0300] "POST /bridge HTTP/1.1" 301 3830 "-" "-" 57.39.118.158 - - [22/Dec/2017:11:44:32 +0300] "GET /bridge/ HTTP/1.1" 500 860 "-" "-" and error log: "[Fri Dec 22 11:44:51.864122 2017] [wsgi:error] [pid 28906:tid 139849921148672] (70008)Partial results are valid but processing is incomplete: [client 57.39.118.158:35172] mod_wsgi (pid=28906): Unable to get bucket brigade for request." Before, the problem "url not found" at 404 url not found error for flask app on apache2 is solved.

I'm using python 3.5.2, apache 2.4, OpenSSL/1.0.2g, ubuntu 16.04, mod_wsgi4.3.0 compiled for python 3.5.1+

I have a unique conf file enabled and is like this:

<VirtualHost *:443>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName newocto.org
DocumentRoot /var/www/html

SSLEngine on
SSLCertificateFile /etc/ssl/certs/newocto_org.crt
SSLCertificateKeyFile /etc/ssl/private/newocto.key
SSLCertificateChainFile /etc/ssl/certs/COMODORSAAddTrustCA.crt


# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

WSGIDaemonProcess bridge user=dogacandu group=dogacandu threads=5 home=/var/www/bridge/
WSGIScriptAlias /bridge /var/www/bridge/bridge.wsgi


<Directory /var/www/bridge>
WSGIProcessGroup bridge
WSGIApplicationGroup %{GLOBAL}
Require all granted

</Directory>

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

file at /var/www/bridge/bridge.wsgi is

#!/usr/bin/python3
import sys


sys.path.insert(0,'/var/www/bridge')

from bridge import app as application

file at /var/www/bridge/bridge.py is

#!/usr/bin/python3

from flask import Flask


app = Flask(__name__)

@app.route('/', methods =['POST'])
def deliver():
    from flask import request
    raw=request.get_json(force=True)
    import mysql.connector
    dbconn= mysql.connector.connect(host='xx.20.xxx.245',port='3306',database='xxa',user='root',password='Jxxxo')
    cursor=dbconn.cursor()
    query1="""insert into bridge_test2 (email) values ('blah')"""
    query2="""insert into bridge_test2 (email) values ('{}')""".format(raw)
    cursor.execute(query1)
    dbconn.commit()
    cursor.execute(query2)
    dbconn.commit()
    dbconn.close()
    return 'ok'

if __name__ == '__main__':
   app.run()

file permissions:

4 -rwxr-xr-x 1 root dogacandu 654 Dec 21 17:31 bridge.py  
4 -rwxr-xr-x 1 root dogacandu 117 Dec 20 18:26 bridge.wsgi

dogacandu is user with sudo privilage. enabled mods are:

access_compat.load authn_core.load authz_user.load cgid.load dir.load mime.load negotiation.load socache_shmcb.load status.load alias.conf authn_file.load autoindex.conf deflate.conf env.load mpm_event.conf rewrite.load ssl.conf wsgi.conf alias.load authz_core.load autoindex.load deflate.load filter.load mpm_event.load setenvif.conf ssl.load wsgi.load auth_basic.load authz_host.load cgid.conf dir.conf mime.conf negotiation.conf setenvif.load status.conf

may rewrite.load cause redirection problem? Any suggestions?


回答1:


I would say the behaviour is probably expected.

The mount point for then URL is /bridge and that is what you are using in the path for the URL. This gets translated to:

SCRIPT_NAME=/bridge
PATH_INFO=

when passed to Flask. With the way the route is set up, Flask is expecting to see:

SCRIPT_NAME=/bridge
PATH_INFO=/

as a result, Flask forces a redirection to force the browser to add a trailing slash.

The problem is that your handler only expects POST and usually a redirection will always result in the subsequent request being a GET which results in no handler then being found because your handler only accepts POST.

In short, it is a bad idea to have a POST handler on a route which can be the subject of automatic trailing slash redirection. In this case this is happening as you have the handler at the mount of the WSGI application when the mount point is a sub URL.

To test though that the handler worked, in your browser, use /bridge/ in your URL instead of /bridge. Better still move your POST handler to a different route other than the mount point for the WSGI application.

As to the other strange Apache errors, you can get that sometimes when connections are pulled down due to errors when secure connections are used.



来源:https://stackoverflow.com/questions/47939148/wsgi-error-unable-to-get-bucket-brigade-for-request-apache2-redirects-post-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!