Flask-SocketIO: flask-socketio: 400 bad request/ Cors issue

Hi I’m getting this error at the client:

VM15520:1 GET http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Mb2_LpO 400 (Bad Request)
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Mb2_LpO' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I’m actually starting my app with gunicorn as follows:

gunicorn --workers=1 --worker-class eventlet --certfile=keys/key.crt --keyfile=keys/key.key --bind 0.0.0.0:5000 myapp.run:app and this is my run.py:

import eventlet
from myapp import create_app
eventlet.monkey_patch()
app, celery = create_app('config_prod.py')

I’m also using CORS(app) in my app factory.

I also tried adding this in one of my blueprints:

@api.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', 'http://localhost:8080')
    response.headers.add('Access-Control-Allow-Headers',
                         'Origin, X-Requested-With, Content-Type, Accept, Authorization')
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
    response.headers.add('Access-Control-Allow-Credentials', 'false')
    return response

I’m using nginx as a reverse proxy, and so I tried adding the corresponding configuration I’ve seen at flask-socketio’s docs:

location /socket.io {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_http_version 1.1;
    proxy_buffering off;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_pass https://my_backend_host/socket.io;
}

Just in case it’s useful, this is my app factory method:

socketio = SocketIO()
(...)
def create_app(config_file=None):
    app = Flask(__name__)
    app.config.from_pyfile(config_file, silent=True)

    CORS(app)
    jwt.init_app(app)
    socketio.init_app(app, message_queue='redis://redis:6379/2', async_mode='threading')

    app.register_blueprint(companies.companies_service)
    app.register_blueprint(modules.modules)
    app.register_blueprint(auth.auth)
    app.register_blueprint(api.api)

    celery.conf.update(app.config)

    from outflink.tasks import tasks
    app.register_blueprint(tasks.tasks)

    return app, celery

Any help will be appreciated, Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

hello @miguelgrinberg I resolve!!!

Your feedback was very important, I check better the configuration of app, and I notice a very strange behaviour on python. I try to explain the troubleshoot:

During the test with error on gunicorn I had a method on init.py of main module that was

import logging
from flask import Flask, request, render_template, session, copy_current_request_context
from flask_socketio import SocketIO, emit, join_room, leave_room, close_room, rooms,disconnect

app = Flask(__name__)

def create_app():

    async_mode = None
    app.config['SECRET_KEY'] = 'secret!'
    app.register_blueprint(main)
    socketio = SocketIO(app, async_mode=async_mode, cors_allowed_origins="*")
    socketio.init_app(app)
    return app

I notice that gunicorn run without problem, but raise this not found error. So I notice that gunicorn want a name instance like app and this instance must be builded outside the method, otherwise gunicorn raise an error of AttributeNotFound called app.

After your feedback, I analyze unique part of application that have problem during run of gunicorn and I following the lateral thinking I think that maybe all inizialitation of socketio needed to be execute outside the method createApp

import logging
from flask import Flask, request, render_template, session, copy_current_request_context
from flask_socketio import SocketIO, emit, join_room, leave_room, close_room, rooms,disconnect

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.register_blueprint(main)
socketio.init_app(app)

def create_app():
    socketio.init_app(app)
    return app

with this source code , where app and init app socketio are defined outside the method create_app()

I can run the app with this snippet code

import eventlet
from kinkoapp import create_app, socketio

if __name__ == '__main__':
    app = create_app()
    eventlet.monkey_patch()
    socketio.run(app, allow_unsafe_werkzeug=True)

and all work well! gunicorn want that the instance and configuration of application must be outside a method python? really?

So with this configuration I can run server on gunicorn and I can conquer the world 😃

thanks

Miguel, my bad, I’ve just found I was pointing to http instead of https from my client. I’m happy that there is no bug, and I’m so sorry!