0
votes

I'm facing an issue with my current flask app setup and would really appreciate some input on this. Thank you!

Flow

user --> nginx --> uwsgi --> flask app --> https call to external system (response is processed and relevant data returned to client)

Workflow

Intent My flask view/route invokes another class, within which a https (GET) call is made to an external system to retrieve data. This data is then processed (analyzed) and an appropriate response is sent to the user.

Actual User receives 502 Bad Gateway from webserver upon invoking Flask Based endpoint. This is only happening when placing the nginx and uwsgi server in front of my flask application. Initial tests on the server directly with flask's in-built server appeared to work.

Note: That analytics bit does take up some time so I increased all relevant timeouts (to no avail)

Configurations

Nginx (tried with and without TLS)

worker_processes  4;

error_log  /path/to/error.log;
pid        /path/to/nginx.pid;

events {
    worker_connections  1024;
}

http {
    default_type  application/json;
    access_log  /path/to/access.log;
    sendfile        on;
    keepalive_timeout  0; [multiple values tried]
    # HTTPS server
    server {
        listen       5555 ssl;
        server_name  my_host.domain.com;

        ssl_certificate      /path/to/server.crt;
        ssl_certificate_key  /path/to/server.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location /my_route {
            uwsgi_connect_timeout 60s;
            uwsgi_read_timeout 300s;
            client_body_timeout 300s;
            include uwsgi_params;
            uwsgi_pass unix:/path/to/my/app.sock;
        }

    }
}

uWSGI (threads reduced to 1 as part of troubleshooting attempts)

[uwsgi]
module = wsgi:app

harakiri = 300 [also added as part of troubleshooting steps]
logto = /path/to/logs/uwsgi_%n.log

master = true
processes = 1
threads = 1

socket = app.sock
chmod-socket = 766
vacuum = true
socket-timeout = 60

die-on-term = true

Code Snippets

Main Flask Class (view)

@app.route(my_route, methods=['POST'])
def my_view():
    request_json = request.json
    app.logger.debug(f"Request Received: {request_json}")
    schema = MySchema()
    try:
        schema.load(request_json)
        var1 = request_json["var1"]
        var2 = request_json["var2"]
        var3 = request_json["var3"]
        var4 = request_json["var4"]
        # begin
        execute = AnotherClass(client_home, config, var1, var2, var3, var4, mime_type)
        return jsonify(execute.result)
    except ValidationError as exception:
        error_message = json.dumps(exception.messages)
        abort(Response(error_message, 400, mimetype=mime_type))

Class which executes HTTPS GET on external system

custom_adapter = HTTPAdapter(max_retries=3)
session = requests.Session()
session.proxies = self.proxies
session.mount("https://", custom_adapter)
try:
    json_data = json.loads(session.get(process_endpoint, headers=self.headers, timeout=(3, 6)).text)

Errors

Nginx

error] 22680#0: *1 upstream prematurely closed connection while reading response header from upstream, client: client_ip, server: server_name, request: "POST /my_route HTTP/1.1", upstream: "uwsgi://unix:/path/to/my/app.sock:", host: "server_name:5555"

User gets a 502 on their end (Bad Gateway)

uWSGI

2020-04-24 16:57:23,873 - app.module.module_class - DEBUG - Endpoint: https://external_system.com/endpoint_details 2020-04-24 16:57:23,876 - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): external_system.com:443 !!! uWSGI process #### got Segmentation Fault !!! * backtrace of #### /path/to/anaconda3/bin/uwsgi(uwsgi_backtrace+0x2e) [0x610e8e] /path/to/anaconda3/bin/uwsgi(uwsgi_segfault+0x21) [0x611221] /usr/lib64/libc.so.6(+0x363f0) [0x7f6c22b813f0] /path/to/anaconda3/lib/python3.7/lib-dynload/../../libssl.so.1.0.0(ssl3_ctx_ctrl+0x170) [0x7f6c191b77b0] /path/to/anaconda3/lib/python3.7/site-packages/cryptography/hazmat/bindings/_openssl.abi3.so(+0x5a496) [0x7f6c16de2496] .... end of backtrace * DAMN ! worker 1 (pid: ####) died :( trying respawn ... Respawned uWSGI worker 1 (new pid: ####)

1

1 Answers

0
votes

SOLVED

Steps taken

update cryptography

update requests

update urllib3

add missing TLS ciphers to Py HTTP Adapter (follow this guide)