Flask redirect is not working - at least as I would - flask-socketio

This is a snippet of my code on the server side:
#app.route('/home', methods=["GET", "POST"])
def home():
return render_template('home.html')
#socketio.on('message from user')
def receive_message_from_user(message):
print ('USER MESSAGE {}'.format(message))
emit ('from Flask', message.upper(), broadcast=True)
return redirect(url_for('home'))
The client sends message from the message from user bucket. The server receives and prints it on the console, sends it back to all the connected clients (after having upperised it). But it does not execute the redirect. What is wrong with this code?

Related

How to run my Flask server so i can get to it with my domain name?

i currently have a very small http server and i would like to add it to my vm in google cloud platform, and then be able to access it with my domain name connected to it. But my server does not have permission to be on port 443 because it is already occupied how can I change this?
ERROR:
* Serving Flask app 'main'
* Debug mode: off
Address already in use
Port 443 is in use by another program. Either identify and stop that program, or start the server with a different port.```
SCRIPT:
from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)
#app.route("/") #home page
def home():
return "Hello! this is the main page <h1>HELLO<h1>"
#app.route("/admin")
def admin():
return redirect(url_for("home"))
#app.route("/<usr>")
def user(usr):
return f"<h1>{usr}<h1>"
#app.route('/login', methods=["POST","GET" ])
def login():
if request.method == "POST":
user = request.form['id']
return redirect(url_for("user", usr=user))
else:
return 'GET'
if __name__ == "__main__":
app.run('0.0.0.0',443)

VUE Front end to go server (http) and clients connected to go server (tcp) error

I'm currently creating a go TCP server that handles file sharing between multiple go clients, that works fine. However, I'm also building a front end using vue.js showing some server stats like the number of users, bytes sent, etc.
The problem occurs when I include the 'http.ListenAndServe(":3000", nil)' function handles the requests from the front end of the server. Is it impossible to have a TCP and an HTTP server on the same go file?
If so, how can a link the three (frontend, go-server, clients)
Here is the code of the 'server.go'
func main() {
// Create TCP server
serverConnection, error := net.Listen("tcp", ":8085")
// Check if an error occured
// Note: because 'go' forces you to use each variable you declare, error
// checking is not optional, and maybe that's good
if error != nil {
fmt.Println(error)
return
}
// Create server Hub
serverHb := newServerHub()
// Close the server just before the program ends
defer serverConnection.Close()
// Handle Front End requests
http.HandleFunc("/api/thumbnail", requestHandler)
fs := http.FileServer(http.Dir("../../tcp-server-frontend/dist"))
http.Handle("/", fs)
fmt.Println("Server listening on port 3000")
http.ListenAndServe(":3000", nil)
// Each client sends data, that data is received in the server by a client struct
// the client struct then sends the data, which is a request to a 'go' channel, which is similar to a queue
// Somehow this for loop runs only when a new connection is detected
for {
// Accept a new connection if a request is made
// serverConnection.Accept() blocks the for loop
// until a connection is accepted, then it blocks the for loop again!
connection, connectionError := serverConnection.Accept()
// Check if an error occurred
if connectionError != nil {
fmt.Println("1: Woah, there's a mistake here :/")
fmt.Println(connectionError)
fmt.Println("1: Woah, there's a mistake here :/")
// return
}
// Create new user
var client *Client = newClient(connection, "Unregistered_User", serverHb)
fmt.Println(client)
// Add client to serverHub
serverHb.addClient(client)
serverHb.listClients()
// go client.receiveFile()
go client.handleClientRequest()
}
}

Can't invoke Soap method with Zeep and basic auth

I am trying to access Web Service with Zeep and I get 401 in response. I checked official docs and https://stackoverflow.com/a/48861779/9187682 . I get an error when I try to call a method, like:
from requests import Session
from requests.auth import HTTPBasicAuth # or HTTPDigestAuth, or OAuth1, etc.
from zeep import Client
from zeep.transports import Transport
session = Session()
session.auth = HTTPBasicAuth(user, password)
client = Client('http://my-endpoint.com/production.svc?wsdl',
transport=Transport(session=session))
Items = client.get_type('ns1:ItemsType')
response = client.service.publishService('MyProps', Items ={ #ERROR HAPPENS HERE
'ItemInformation': {
'':''
}
})
The response I get is:
zeep.exceptions.TransportError: Server returned response (401) with invalid XML: Invalid XML content received (Start tag expected, '<' not found, line 1, column 1).
Request in itself is OK (it works without auth if it's disabled on service).
Credentials are OK as well (in fact the whole thing works in Soap UI)
Am I missing something here?

Flask/NGINX 404s on only some POST requests

I have a Flask app served by Gunicorn using NGINX as a webserver. I only have two endpoints that have POST requests, a login and a submit post. The login works flawlessly however whenever I attempt to POST using the submit post endpoint, I receive a 404. My code works running on localhost without NGINX or Gunicorn and in order to detect that the request is POST vs GET I am using WTForms validate_on_submit method. The NGINX error and access logs don't show anything out of the ordinary.
Edit: Here is the code for the endpoints with post requests
New Post:
#app.route('/newpost', methods=['GET', 'POST'])
#login_required
def new_post():
form = BlogForm()
if form.validate_on_submit():
#Omitted code for getting form data and creating form object
try:
#Omitted code for database actions
return redirect(url_for('index', _external=True))
except IntegrityError:
flash("Error inserting into database")
return('', 203)
else:
#Omitted some code for template rendering
return render_template('new_post.html')
Login:
#app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
userAuth = current_user.is_authenticated
if form.validate_on_submit():
flash("Login attempt logged")
user = User.query.filter_by(username=form.userID.data).first()
if user:
checkPass = form.password.data.encode('utf-8')
if bcrypt.checkpw(checkPass, user.password):
user.authenticated = True
login_user(user, remember=form.remember_me.data)
return redirect(url_for('index', _external=True))
else:
form.errors['password'] = 'false'
else:
form.errors['username'] = 'false'
else:
return render_template('login.html',
title='Log In',
loggedIn=userAuth,
form=form)
The problem ended up being with NGINX after all, I fixed it by changing the ownership of /var/lib/nginx from the nginx user to the user running the Flask application. Prior to doing this AWS wasn't letting me upload files from my form in new_post.

Redis long-polling Pub/Sub frequent message blocking

I'm trying to wrap my head around the Redis Pub/Sub API and setup a long-polling server.
This lua script subscribes to a 'test' channel and returns new messages received:
nginx.conf:
location /poll {
lua_need_request_body on;
default_type 'text/plain';
content_by_lua_file '/usr/local/nginx/html/poll.lua';
}
poll.lua:
local redis = require "redis";
local red = redis:new();
local cjson = require "cjson";
red:set_timeout(30000) -- 30 sec
local resCon, err = red:connect("127.0.0.1", 6379)
if not resCon then
ngx.print("error")
return
end
local resSub, err = red:subscribe('r:' .. ngx.var["arg_r"]:gsub('%W',''))
if not resSub then
ngx.print("error")
return
end
if resSub == ngx.null then
ngx.print("error")
return
end
local resMsg, err = red:read_reply()
if not resMsg then
ngx.say("0")
return
end
ngx.say(cjson.encode(resMsg))
client.js:
var tmpR = 'test';
function poll() {
$.get('/poll', {'r':tmpR}, function(data){
if (data !== "error") {
console.log(data);
window.setTimeout(function(){
poll();
},1000);
} else {
console.log('poll fail');
}
})
}
Now, if I send publish r:test hello from redis-cli, I receive the message on the client and the server responds to redis-cli with 1. But, if I send two messages quickly, the second message doesn't broadcast and the server responds with 0.
Are my channels only capable of receiving a message per second, or, is this a throttle on the frequency of messages a user can broadcast to a channel?
Is this the right way to approach this polling server on nginx assuming many users may be connected at one time? Would it be more efficient to use GET requests on a timer?
Given two consecutive messages only one is going to have a subscriber listening to the result. No subscriber is listening when the second message is sent. The only subscriber is processing the previous result and returning that to the user.
Redis is not maintaining a message queue or similar to make sure that previously listening clients will receive the missing messages upon reconnect.

Resources