0

I have a flask socket io application that used to work a few months ago, but I'm not sure whats happened. I've stripped it down to the basics. The output logs show a bunch of garbled nonsense that I think is supposed to be the start of a TLS handshake (from the research I've done). Console is showing a CORS related error. I don't know why that is - shouldn't the origin be the same for local host? Is the server sending secure requests?

I've tried socketio = SocketIO(app, cors_allowed_origins='*') as mentioned in this question, but the issue is still there. This is the logging output, in the past it would show the polling url: Logging output from the server.

events still being received

My application.py code:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config["SECRET_KEY"] = 'secret?'
socketio = SocketIO(app, engineio_logger=True, logger=True)

@app.route("/", methods=["GET"])
def index():
    return render_template("layout.html")

@socketio.on('message')
def handleMessage(msg):
    print(msg)
    emit(msg, broadcast=True)

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

Javascript:

document.addEventListener('DOMContentLoaded', () => {
    connectSocketIO();
    addMessage();
});

var socket;
function connectSocketIO () {
    socket = io.connect('http://' + document.domain + ':' + location.port);
    socket.on('connect', () => {
        console.log('client connected');
        socket.on('disconnect', () => console.log('client disconnected'));
    });

    socket.on('message', (data) => {
        console.log(data);
    });
}
function addMessage () {
    // emit a new message announcement when message is posted
    document.querySelector('#btn').onclick = () => {
        const message = document.querySelector('input').value;
        socket.emit('message', {'message': message});
        return false;
    };
}

requirements.txt

Flask
Flask-SocketIO
gunicorn
eventlet==0.24.1

Edit:

It appears the initial issue was caused by specifying https protocol in io.connect - changing that has solved the garbled output.
This has caused Firefox to throw an error:
Firefox can't establish a connection to the server as wss://url

In Chrome it works, but the connection changes to http. Both warn about cookies misusing the sameSite attribute
Cookie "io" will be soon rejected because it has the "sameSite" attribute set to "none" or an invalid value, without the "secure" attribute.

Heroku Procfile:
web: gunicorn --worker-class eventlet -w 1 application:app

On the server side, the logs for Heroku:

2020-07-28T12:41:43.350016+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.

2020-07-28T12:41:43.346991+00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=3&transport=polling&t=NELSMDM&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=1041f8b4-71b8-4cf5-a321-75014d2ccde7 fwd="78.146.97.151" dyno=web.1 connect=1ms service=8ms status=400 bytes=182 protocol=https

2020-07-28T12:41:44.399195+00:00 heroku[router]: at=info method=POST path="/socket.io/?EIO=3&transport=polling&t=NELSMTk&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=dba0c5f4-6afd-4621-ad7e-4c511911a714 fwd="78.146.97.151" dyno=web.1 connect=2ms service=3ms status=400 bytes=182 protocol=https

2020-07-28T12:41:44.402016+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.

2020-07-28T12:41:45.481764+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=3&transport=polling&t=NELSMkn" host=flack-messaging-app.herokuapp.com request_id=8ba7cc91-5e33-4113-a15d-84e5ceba8ca4 fwd="78.146.97.151" dyno=web.1 connect=1ms service=3ms status=200 bytes=385 protocol=https

2020-07-28T12:41:45.483979+00:00 app[web.1]: 5b1138c7e62a4ea2bff2beb55eb5241d: Sending packet OPEN data {'sid': '5b1138c7e62a4ea2bff2beb55eb5241d', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}

2020-07-28T12:41:45.484100+00:00 app[web.1]: 5b1138c7e62a4ea2bff2beb55eb5241d: Sending packet MESSAGE data 0

2020-07-28T12:41:45.571836+00:00 app[web.1]: https://flack-messaging-app.herokuapp.com is not an accepted origin.

2020-07-28T12:41:45.566552+00:00 heroku[router]: at=info method=GET path="/socket.io/?EIO=3&transport=websocket&sid=5b1138c7e62a4ea2bff2beb55eb5241d" host=flack-messaging-app.herokuapp.com request_id=d802cd1c-c875-4406-a75e-2c3ca2368de0 fwd="78.146.97.151" dyno=web.1 connect=0ms service=2ms status=400 bytes=187 protocol=https

2020-07-28T12:41:48.383640+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/socket.io/?EIO=3&transport=polling&t=NELSG6k&sid=f25e5af236d347eaa3100951014be579" host=flack-messaging-app.herokuapp.com request_id=26757146-e11f-43d6-a243-65172f72dd5e fwd="78.146.97.151" dyno=web.1 connect=1ms service=30001ms status=503 bytes=0 protocol=https
  • The 400 error is what indicates the root problem. As far as CORS goes, it’s normal and expected that a 400 error won’t have the Access-Control-Allow-Origin response header, because most server systems by default don’t add application-set response headers to 4xx and 5xx errors. – sideshowbarker Jul 27 '20 at 10:41
  • Do you have anything in between the client and the server, like a reverse proxy that is supposed to terminate SSL? My guess is that the server is receiving encrypted data even though it is not set up for that. – Miguel Grinberg Jul 27 '20 at 15:05
  • @Miguel I'm not using anything in between (using eventlet not Werkzeug, if that makes a difference) It seems like it's working locally now, but on Heroku I get the error that it can't establish a wss connection changed `socket = io.connect('http://' + document.domain + ':' + location.port);` to `socket = io.connect( window.location.protocol + '//' + document.domain + ':' + location.port);` – 5.9 protons Jul 27 '20 at 15:47
  • @5.9protonspermetrecubed things don't just stop and start working on their own, you must have changed something. Also, if you need help with Heroku you need to post the info and logs that apply to that. Are the logs you posted above Heroku? They don't appear to be. – Miguel Grinberg Jul 27 '20 at 22:02
  • @Miguel added Heroku logs - is it possible to have no cookies in flask socketio? – 5.9 protons Jul 28 '20 at 12:51

1 Answers1

2

Ok, it looks like there were two issues:

  1. In io.connect on the client side, the connect parameter used
    https:// + document.domain + location.port but the server was using http:// so was causing the garbled output. Changing https:// to window.location.protocol + '//' + 'rest_of_url' fixed the garbled output.

  2. Heroku uses https:// but my server was configured for http:// - I'm still not sure what settings to change in Flask to use one over the other but in my application.py, for the Socket constructor, adding in cors_allowed_origins='https://myurl' fixed the issue with wss unable to connect. I've since used
    cors_allowed_origins=['http://url', 'https://url'] to allow both secure and non-secure access. I'm not familiar enough with Heroku or Flask to force one over the other and this solution works well for me.

  • wow thank you so much I think that also solved all of my problems!!!! I was searching for a long time to solve these issues! – sqp_125 Nov 03 '20 at 20:19