Django behind uwsgi+nginx not able to set cookies - python

I'm putting together a PoC for a side-project meal-planner tool. I'm using django running on AWS with nginx and uwsgi. The site is running and loading pages, but there is no CSRF cookie being passed to the browser.
The CSRF and Messages middleware are both enabled, and the django debug output lists a value for 'CSRF_COOKIE', and my browser has cookies enabled, so I suspect that Django is attempting to set a cookie which is getting stripped out by nginx or uwsgi.
Configuration information below:
uwsgi.ini
[uwsgi]
chdir=/opt/django/mealplanner/src/mealplanner/
module=mealplanner.wsgi:application
master=True
autoload=True
pidfile=/opt/run/mealplanner.pid
vacuum=True
max-requests=5000
socket=/opt/run/mealplanner.sock
chmod-socket=True
harakiri=120
processes=1
home=/opt/django/mealplanner/src
daemonize=/opt/log/uwsgi/mealplanner.log
nginx.conf
user www-data;
worker_processes 1;
pid /opt/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /opt/log/nginx/access.log;
error_log /opt/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
gzip_proxied any;
gzip_comp_level 2;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml \
application/xml+rss text/javascript;
server {
listen 80;
# I've also tried the dns name I access the site with as the server name.
server_name ec2-xx-xx-xx-xx.us-west-2.compute.amazonaws.com xx.xx.xx.xx;
client_max_body_size 50M;
set $home /opt/django/mealplanner;
root $home;
location / {
include uwsgi_params;
uwsgi_pass unix://opt/run/mealplanner.sock;
root $home;
}
}
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

It looks like the problem might possibly have been the server_name in nginx.conf. It suddenly started working, and the only thing I had changed was making the server_name match the domain name of the site. On the other hand, changing it back didn't seem to re-introduce the problem, so either I'm not restarting nginx properly or that wasn't the issue after all.
The site is working now, but it's one of those situations where I don't have a satisfactory understanding of the cause and solution, so if anyone can confirm this hypothesis or point out something else I'd welcome the input.

Related

NGINX server blocks doesn't work as expected

I know it's not appropriate place to ask question about nginx but I stack with some issue for a few days and still have no idea how to solve a problem.
I would like to use nginx to redirect user from domain.com:3001 to sub.domain.com. Application on port 3001 is running in docker container, I didn't add any files in directory sites-available/sites-enabled. I have added two server blocks (vhosts) in my conf.d directory. In server block I set $upstream and resolver according to record in my /etc/resolv.conf file. The problem is that when I test in browser sub.domain.com every time I receive information that IP address could not be connected with any server (DNS_PROBE_FINISHED_NXDOMAIN) or 50x errors.
However, when I run curl sub.domain.com from the server I receive 200 with index.html response, this doesn't work when I run the same command from my local PC. Server domain is in private network. Have you any idea what my configuration files lack of?? Maybe there is some issue with the listen port when app is running in docker or maybe there is something wrong with the version of nginx? When I installed nginx there was empty conf.d directory, with no default.conf. I am lost...
Any help will be highly appreciated.
Here is my configuration files:
server.conf:
server
{
listen 80;
listen 443 ssl;
server_name sub.domain.net;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
ssl_certificate /etc/nginx/ssl/cer.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
#set_real_ip_from 127.0.0.1;
#real_ip_header X-Real-IP;
#real_ip_recursive on;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
location / {
resolver 10.257.10.4;
set $upstream https://127.0.0.1:3000;
proxy_pass $upstream;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;`enter code here`
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
nginx.conf
#user nginx;
worker_processes 1;
#error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
#pid /var/run/nginx.pid;
include /etc/nginx/modules.conf.d/*.conf;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local]
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#tcp_nodelay on;
#gzip on;
#gzip_disable "MSIE [1-6]\.(?!.*SV1)";
server_tokens off;
include /etc/nginx/conf.d/*.conf;
}
# override global parameters e.g. worker_rlimit_nofile
include /etc/nginx/*global_params;

Nginx flask Gunicorn permission denied to socket file

I have this Nginx configuration file set up:
server {
listen 80;
server_name example.com www.example.com;
location /flasky {
include proxy_params;
proxy_pass http://unix:/tmp/flasky.sock;
}
}
I'm using Gunicorn to bind to the socket file while running my app. I changed the ownership of the /tmp directory to www-run:www-run but I'm still getting a permission denied error. What am I doing wrong?
Edit: Here is my Nginx.conf file. It is the default that comes loaded with Nginx when installed:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
Here is the virtual host file I'm trying to use:
server {
listen 80;
server_name mywebsite.com www.mywebsite.com;
location /flasky {
include proxy_params;
proxy_pass http://127.0.0.1:8090;
}
}
And finally, the Gunicorn command I am running is:
gunicorn -b 0.0.0.0:8090 -w 2 wsgi:applicaiton

Certbot cannot reach nginx webroot running django

I'm working through https://serversforhackers.com/video/letsencrypt-for-free-easy-ssl-certificates and https://certbot.eff.org/docs/intro.html , trying to add an ssl certificate to my site. I tried:
root#server:/opt/certbot# ./certbot-auto certonly --webroot -w /var/www/html --agree-tos --email me#yahoo.com -d mysite.com -d www.mysite.com --non-interactive
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
http-01 challenge for www.example.com
Using the webroot path /var/www/html for all unmatched domains.
...
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: example.com
Type: unauthorized
Detail: Invalid response from
example.com.well-known/acme-challenge/gygb7wEj3o-_5MIoUgraBRddmqrtZdfIM-UWMySoNl8:
Domain: www.example.com
Type: unauthorized
Detail: Invalid response from
www.example.com.well-known/acme-challenge/z8oZ1FAiHBJNwWvLTI-g9hMZ5zoLdJSZBgaQ9CSTJU0:
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A record(s) for that domain
contain(s) the right IP address.
root#server:/opt/certbot# cd .
I checked the domain name and A record and they seem to be OK. In my browser I opened the link and I see the screenshot, which makes sense since I'm running a django app.
How can I set things so that the certbot can access the webroot?
edit :
root#server:/etc/nginx# cat nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
/var/log/nginx/access.log shows:
66.133.109.36 - - [10/Feb/2017:13:16:40 -0500] "GET /.well-known/acme-challenge/-GMR_DzXR-oOTzl7LEesFiQI0H-2zCak2Bq3cDO7mTQ HTTP/1.1" 404 1080 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
66.133.109.36 - - [10/Feb/2017:13:16:40 -0500] "GET /.well-known/acme-challenge/4hTpEFaTJDTCiAS-Y9242MmNngEHM6e9cPr2WIdCL4Q HTTP/1.1" 404 1083 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
/var/log/nginx/error.log shows no errors.
Also I notice that there are no files in the .well known directory:
deploy#server:/var/www/html/.well-known$ ll
total 8
drwxrwxrwx 2 root root 4096 Feb 11 10:20 ./
drwxr-xr-x 3 root root 4096 Feb 10 09:29 ../
edit 2: In /etc/nginx/sites-available/mysite I've changed it to:
server {
listen 80;
server_name mysite.com www.mysite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/deploy/mysite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/mysite.sock;
}
location ~ /.well-known {
allow all;
}
}
restarted nginx - same error
The following worked in the site's server block:
server {
listen 80;
server_name mysite.com www.mysite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/deploy/mysite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/mysite.sock;
}
location ^~ /\.well-known {
allow all;
}
}
edit: here's another option that may work:
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/html;

Possible causes for error while saving file in python while running on nginx?

I have a .py script that saves a base64 file to a png file
# SAVE BASE64 STRING TO PNG IMAGE
timestr = time.strftime("%Y%m%d%H%M%S")
filename = "/user_score/"+self.user.username+timestr+".png"
saved_file = MEDIA_ROOT+"/"+filename
fh = open(saved_file, "wb")
fh.write(imgbase64.decode('base64'))
fh.close()
This is being called through an AJAX function to an URL like this one
http://example-domain.com/score/save_image/?img=iVBORw0KGgoAAAANSUhEUgAAA4QAAAJYCAYAAAA6xSjbAAAgAElEQVR4Xu3b0ZYUN7KGUfz%2BD92z2mMYzDRUZkkKhfLf59ZFSrFDXHyLM399fHx8fPN%2FBAgQIECAAAECBAgQIBAn8JcgjNu5gQkQIECAAAECBAgQIPC3gCD0EAgQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIAAAQIECBAgECogCEMXb2wCBAgQIECAAAECBAgIQm%2BAAAECBAgQIECAAAECoQKCMHTxxiZAgAABAgQIECBAgIAg9AYIECBAgAABAgQIECAQKiAIQxdvbAIECBAgQIAAAQIECAhCb4AAAQIECBAgQIAAAQKhAoIwdPHGJkCAAAECBAgQIECAgCD0BggQIECAAAECBAgQIBAqIAhDF29sAgQIECBAgAABAgQICEJvgAABAgQIECBAgAABAqECgjB08cYmQIAAAQIECBAgQICAIPQGCBAgQIDAAoG%2F%2FvprwVe%2Fffv4%2BFjyXR8lQIAAgUwBQZi5d1MTIECAwGSBVQH4u2sKw8kL9DkCBAiECgjC0MUbmwABAgTGBaojUByO78wXCBAgQODfAoLQiyBAgAABAjcFuoTgr9f2r4Y3F%2BnnBAgQIPBNEHoEBAgQIEDgokDXEPz5%2BqLw4jL9jAABAgT%2BFhCEHgIBAgQIPF7gM%2BRGQumEEPSvhY9%2FxgYkQIDAEgFBuITVRwkQIEBgtsBolL0ThKNnzjZ453vvzP3OOf4MAQIECJwpIAjP3JtbEyBAIE5gNM7uhNHoWR2Xc2f%2Bjvd3JwIECBBYIyAI17j6KgECBAhMFhiNtCtBNHrG5JGnf%2B6KwfRDfZAAAQIEWgsIwtbrcTkCBAgQ%2BC4wGmt%2FiqHRb5%2B0JVF40rbclQABAusFBOF6YycQIECAwASB0Wj7KoRGvzlhrG2fEIbb6B1MgACBVgKCsNU6XIYAAQIEficwGm8%2FB9Dot562JXH4tI2ahwABAtcFBOF1K78kQIAAgY0CoxH3PXpGv7ORYPnRwnA5sQMIECDQTkAQtluJCxEgQIDAVwJCru5dCMM6aycRIEBgt4Ag3L0B5xMgQIDAJQFBeIlp6o%2BE4VROHyNAgEBLAUHYci0uRYAAAQK%2FCgjCPW9CFO5xdyoBAgSqBARhlbRzCBAgQGBI4OQgHImqDnOP3H9o6f4wAQIECCwXEITLiR1AgAABAjMEOoTRnTlWRNROgxXz3PH0WwIECBBYIyAI17j6KgECBAhMFtgZQ1dHqYimnQ4V81219jsCBAgQmCMgCOc4%2BgoBAgQILBbYGUKvRtsRSrs8dsz6yt9%2FJ0CAAIH3BQTh%2B3b%2BJAECBAgUCuwKoD%2BN2CGOdrh0mLvw6TmKAAECjxYQhI9er%2BEIECDwHIEd4fM7vY5BVO3T0eA5r90kBAgQqBMQhHXWTiJAgACBAYHq4Pnqqt0jqNKou8XAU%2FNHCRAgECUgCKPWbVgCBAicK1AZO78qnRQ%2FlU4nuZz78t2cAAECawUE4VpfXydAgACBSQKVofP9yicHT4XXyT6TnqXPECBA4HgBQXj8Cg1AgACBDIGKwPlZ8kmxs9LuSU4Zf5NMSYAAgX8LCEIvggABAgSOEFgZNU8NwV8Xu8JQEB7x18clCRAg8FsBQehxECBAgMARAiti5tfBU%2BJmtmWK2xF%2FUVySAAECNwUE4U0wPydAgACBPQKzIyY1Br%2FPPdNTEO75O%2BFUAgQIzBAQhDMUfYMAAQIElgvMDJj0GPycf7anKFz%2BV8ABBAgQWCIgCJew%2BigBAgQIzBaYHTDf75ccMjNNkx1nv3XfI0CAQKWAIKzUdhYBAgQIvC0wM17E4P%2FWMMtVEL79tP1BAgQIbBUQhFv5HU6AAAECVwVmhYsY%2FH%2FxWbai8Opr9jsCBAj0ERCEfXbhJgQIECDwB4FZ0SIIv0ae4SsI%2FRUmQIDAeQKC8LyduTEBAgQiBWYEixj8%2FdOZ4SsII%2F9qGpoAgcMFBOHhC3R9AgQIpAjMCBZBKAhT%2Fr6YkwABAlcFBOFVKb8jQIAAga0CgnA9%2F6ixfyFcvyMnECBAYLaAIJwt6nsECBAgsERgNFb86%2BDrtcwwFoWvnf2CAAECnQQEYadtuAsBAgQI%2FFZgRqx8flyw%2FP6RzTDm6y8xAQIEzhIQhGfty20JECAQKzAjVgThn58P49i%2FXgYnQCBYQBAGL9%2FoBAgQOElArNRsa4azfyWs2ZVTCBAgMENAEM5Q9A0CBAgQWC4wGiqfkfL5DbGy%2Fl8JGS%2F%2F6%2BAAAgQITBMQhNMofYgAAQIEVgrMCMKV93vKt0edPx0E4VNegzkIEEgQEIQJWzYjAQIEHiAwGioi5fojYH3dyi8JECBwuoAgPH2D7k%2BAAIEQAZFSt2jWddZOIkCAwG4BQbh7A84nQIAAgUsCIuUS05QfjVp%2FXsK%2FyE5ZhY8QIEBguYAgXE7sAAIECBCYITAaKQLl%2BhZGrQXhdWu%2FJECAwG4BQbh7A84nQIAAgUsCo5EiCC8x%2F%2F2jUWtBeN3aLwkQILBbQBDu3oDzCRAgQOCSwGikCMJLzILwOpNfEiBA4BECgvARazQEAQIEni8gCGt3zLvW22kECBDYJSAId8k7lwABAgRuCQiUW1zDP%2BY9TOgDBAgQOEJAEB6xJpckQIAAAYFS%2BwZ413o7jQABArsEBOEueecSIECAwC0BgXKLa%2FjHvIcJfYAAAQJHCAjCI9bkkgQIECAgUGrfAO9ab6cRIEBgl4Ag3CXvXAIECBC4JSBQbnEN%2F5j3MKEPECBA4AgBQXjEmlySAAECBARK7RvgXevtNAIECOwSEIS75J1LgAABArcEBMotruEf8x4m9AECBAgcISAIj1iTSxIgQICAQKl9A7xrvZ1GgACBXQKCcJe8cwkQIEDgloBAucU1%2FGPew4Q%2BQIAAgSMEBOERa3JJAgQIEBAotW%2BAd6230wgQILBLQBDukncuAQIECNwSECi3uIZ%2FzHuY0AcIECBwhIAgPGJNLkmAAAECAqX2DfCu9XYaAQIEdgkIwl3yziVAgACBWwIC5RbX8I95DxP6AAECBI4QEIRHrMklCRAgQECg1L4B3rXeTiNAgMAuAUG4S965BAgQIHBLQKDc4hr%2BMe9hQh8gQIDAEQKC8Ig1uSQBAgQICJTaN8C71ttpBAgQ2CUgCHfJO5cAAQIEbgkIlFtcwz%2FmPUzoAwQIEDhCQBAesSaXJECAAAGBUvsGeNd6O40AAQK7BAThLnnnEiBAgMAtAYFyi2v4x7yHCX2AAAECRwgIwiPW5JIECBAgIFBq3wDvWm%2BnESBAYJeAINwl71wCBAgQuCUgUG5xDf%2BY9zChDxAgQOAIAUF4xJpckgABAgQESu0b4F3r7TQCBAjsEhCEu%2BSdS4AAAQK3BATKLa7hH%2FMeJvQBAgQIHCEgCI9Yk0sSIECAgECpfQO8a72dRoAAgV0CgnCXvHMJECBA4JaAQLnFNfxj3sOEPkCAAIEjBAThEWtySQIECBAQKLVvgHett9MIECCwS0AQ7pJ3LgECBAjcEhAot7iGf8x7mNAHCBAgcISAIDxiTS5JgAABAgKl9g3wrvV2GgECBHYJCMJd8s4lQIAAgVsCAuUW1%2FCPeQ8T%2BgABAgSOEBCER6zJJQkQIEBAoNS%2BAd613k4jQIDALgFBuEveuQQIECBwS0Cg3OIa%2FjHvYUIfIECAwBECgvCINbkkAQIECAiUujcwav1504%2BPj7oLO4kAAQIE3hYQhG%2FT%2BYMECBAgUCkwGikC5dq2Rp2%2Fn8L7mrdfESBAYLeAINy9AecTIECAwCWB0VARKK%2BZR41%2FPoH3a2%2B%2FIECAQAcBQdhhC%2B5AgAABAi8FRmNFoLwk%2FjZq7F8HXxv7BQECBLoJCMJuG3EfAgQIEPhSYDRWBOGfH9aor38d9BeXAAECZwoIwjP35tYECBCIExgNFkH4%2Byczavvrl1nH%2FfU0MAECBwsIwoOX5%2BoECBBIEhiNFpEiCJP%2BvpiVAAECVwUE4VUpvyNAgACBrQKCcD7%2FqOlXNxLe8%2FfkiwQIEFgpIAhX6vo2AQIECEwTGI0XofLfVYw6vloo51dC%2FjsBAgR6CQjCXvtwGwIECBD4jcBoyKSHyqjflYeZbnzFyG8IECDQTUAQdtuI%2BxAgQIDAlwKjQZMcK6N2V55ksu8VH78hQIBAVwFB2HUz7kWAAAEC%2FxIYjZrUYBl1u%2FIMU22v2PgNAQIEugsIwu4bcj8CBAgQ%2BFtgNGySomXU6s6TS3K94%2BK3BAgQOEVAEJ6yKfckQIBAuMBo5CSEy6jR3SeWYHrXxO8JECBwmoAgPG1j7kuAAIEwgVmR8%2BR4mWV092k92fSuhd8TIEDgVAFBeOrm3JsAAQIhArNi54nxMsvmnaf0RM93HPwZAgQInLI2VVQAABJKSURBVC4gCE%2FfoPsTIEDg4QKzo%2BcJITPb5O4TeoLh3Zn9ngABAk8VEIRP3ay5CBAg8BCBVfFzYtSssrj7VE60uzuj3xMgQCBFQBCmbNqcBAgQOFhgVQidEjar5n%2FnSZxi9s5s%2FgwBAgQSBQRh4tbNTIAAgcMEKoOoU%2FBUzn3lSXSyuXJfvyFAgACB1wKC8LWRXxAgQIBAA4HqONoVP9VzXlntLosrd%2FMbAgQIEBgTEIRjfv40AQIECBQJ7AilqhDaMduVtVXNf%2BUufkOAAAECawQE4RpXXyVAgACByQK7o2lmHO2e5dVqZs766iz%2FnQABAgT2CgjCvf5OJ0CAAIGLAl0i6t1Y6nL%2F33G%2FO9fF9fkZAQIECDQVEIRNF%2BNaBAgQIPBvge5BdfK%2BxODJ23N3AgQIjAkIwjE%2Ff5oAAQIEigQE4RpoMbjG1VcJECBwioAgPGVT7kmAAIFwAUE49wEIwbmevkaAAIFTBQThqZtzbwIECIQJCMLxhYvAcUNfIECAwNMEBOHTNmoeAgQIPFRAEL6%2FWCH4vp0%2FSYAAgacLCMKnb9h8BAgQeIiAILy%2FSCF438yfIECAQJqAIEzbuHkJECBwqIAgvL44IXjdyi8JECCQLiAI01%2BA%2BQkQIHCIgCC8tigxeM3JrwgQIEDgvwKC0EsgQIAAgSMEBOGf1yQEj3jGLkmAAIF2AoKw3UpciAABAgS%2BEhCE%2F68iAv1dIUCAAIFRAUE4KujPEyBAgECJwGgQfo%2Bn0e%2BUDPviECHYYQvuQIAAgWcICMJn7NEUBAgQeLzAaMh9FVGj36xEF4GV2s4iQIBAjoAgzNm1SQkQIHC0wGi8%2FSmoRr%2B9ClYErpL1XQIECBD4LiAIvQUCBAgQOEJgNNquxtXoOSOYV%2B84coY%2FS4AAAQIEfhYQhN4DAQIECBwhMBpqd2Nr9LyrqHfvdfW7fkeAAAECBK4ICMIrSn5DgAABAtsFRgPt3fAaPfdXuHfvsX0BLkCAAAECjxQQhI9cq6EIECDwPIHRMBNiz3sTJiJAgACBcQFBOG7oCwQIECBQICAIC5AdQYAAAQJxAoIwbuUGJkCAwJkCgvDMvbk1AQIECPQWEIS99%2BN2BAgQIPCPgCD0FAgQIECAwHwBQTjf1BcJECBAYIGAIFyA6pMECBAgEC8gCOOfAAACBAicISAIz9iTWxIgQIDAWQKC8Kx9uS0BAgRiBQRh7OoNToAAAQILBQThQlyfJkCAAIF5AoJwnqUvESBAgACB7wKC0FsgQIAAgSMEBOERa3JJAgQIEDhMQBAetjDXJUCAQKqAIEzdvLkJECBAYKWAIFyp69sECBAgME1AEE6j9CECBAgQIPBDQBB6DAQIECBwhIAgPGJNLkmAAAEChwkIwsMW5roECBBIFRCEqZs3NwECBAisFBCEK3V9mwABAgSmCQjCaZQ%2BRIAAAQIEfggIQo%2BBAAECBI4QEIRHrMklCRAgQOAwAUF42MJclwABAqkCgjB18%2BYmQIAAgZUCgnClrm8TIECAwDQBQTiN0ocIECBAgMAPAUHoMRAgQIDAEQKC8Ig1uSQBAgQIHCYgCA9bmOsSIEAgVUAQpm7e3AQIECCwUkAQrtT1bQIECBCYJiAIp1H6EAECBAgQ%2BCEgCD0GAgQIEDhCQBAesSaXJECAAIHDBAThYQtzXQIECKQKCMLUzZubAAECBFYKCMKVur5NgAABAtMEBOE0Sh8iQIAAAQI%2FBAShx0CAAAECRwgIwiPW5JIECBAgcJiAIDxsYa5LgACBVAFBmLp5cxMgQIDASgFBuFLXtwkQIEBgmoAgnEbpQwQIECBA4IeAIPQYCBAgQOAIAUF4xJpckgABAgQOExCEhy3MdQkQIJAqIAhTN29uAgQIEFgpIAhX6vo2AQIECEwRGI3Bz0t8fHxMuYuPECBAgACBJwkIwidt0ywECBB4qIAgfOhijUWAAAEC2wUE4fYVuAABAgQIvBIYDUL%2FOvhK2H8nQIAAgVQBQZi6eXMTIEDgIAFBeNCyXJUAAQIEjhIQhEety2UJECCQJzAag59i%2FoUw792YmAABAgSuCQjCa05%2BRYAAAQKbBAThJnjHEiBAgECEgCCMWLMhCRAgcK7AaBD618Fzd%2B%2FmBAgQILBeQBCuN3YCAQIECAwICMIBPH%2BUAAECBAi8EBCEnggBAgQItBUYjcHPwfwLYdv1uhgBAgQINBAQhA2W4AoECBAg8LWAIPQyCBAgQIDAWgFBuNbX1wkQIEBgQGA0CP3r4AC%2BP0qAAAECEQKCMGLNhiRAgMCZAoLwzL25NQECBAicIyAIz9mVmxIgQCBOQBDGrdzABAgQIFAsIAiLwR1HgAABAtcERmPw8xT%2FL6PXrP2KAAECBHIFBGHu7k1OgACB1gKCsPV6XI4AAQIEHiIgCB%2BySGMQIEDgaQKC8GkbNQ8BAgQIdBQQhB234k4ECBAg8E0QegQECBAgQGC9gCBcb%2BwEAgQIEHhDYDQI%2Fe8H30D3RwgQIEAgTkAQxq3cwAQIEDhDQBCesSe3JECAAIGzBQTh2ftzewIECDxWQBA%2BdrUGI0CAAIFGAoKw0TJchQABAgT%2BJyAIvQYCBAgQILBeQBCuN3YCAQIECEwWuBKL%2FjeEk9F9jgABAgQeKSAIH7lWQxEgQODZAoLw2fs1HQECBAjUCQjCOmsnESBAgMAkgVdB6F8HJ0H7DAECBAg8XkAQPn7FBiRAgMDzBATh83ZqIgIECBDYIyAI97g7lQABAgQGBP4UhP51cADWHyVAgACBOAFBGLdyAxMgQOB8AUF4%2Fg5NQIAAAQI9BARhjz24BQECBAjcEPgqCP3L4A1APyVAgAABAv8ICEJPgQABAgSOE%2Fg5CIXgcetzYQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgkIAgbLcNVCBAgQIAAAQIECBAgUCkgCCu1nUWAAAECBAgQIECAAIFGAoKw0TJchQABAgQIECBAgAABApUCgrBS21kECBAgQIAAAQIECBBoJCAIGy3DVQgQIECAAAECBAgQIFApIAgrtZ1FgAABAgQIECBAgACBRgKCsNEyXIUAAQIECBAgQIAAAQKVAoKwUttZBAgQIECAAAECBAgQaCQgCBstw1UIECBAgAABAgQIECBQKSAIK7WdRYAAAQIECBAgQIAAgUYCgrDRMlyFAAECBAgQIECAAAEClQKCsFLbWQQIECBAgAABAgQIEGgk8B%2B6jaetVJ6%2FbAAAAABJRU5ErkJggg%3D%3D
It is working fine when I run on django runserver, both on local and production environments.
However it gives me an 502 when running on production with NGINX.
So everything points out to NGINX.
This is the NGINX conf file, though I can't access the error logs (another programmer did the setup)
user www-data;
worker_processes 5;
pid /var/run/nginx.pid;
events {
worker_connections 6000;
multi_accept on;
use epoll;
}
http {
##
# Basic Settings
##
client_max_body_size 30M;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 300;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
#timeout
#proxy_read_timeout 1200;
uwsgi_read_timeout 1200;
client_body_timeout 120;
client_header_timeout 120;
send_timeout 100;
client_body_buffer_size 10K;
client_header_buffer_size 1k;
#client_max_body_size 8m;
large_client_header_buffers 4 32k;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Any ideas appreciated.
This was solved by a comment by ohrstrom, who linked to this answer:
https://serverfault.com/questions/564464/nginx-request-line-too-large/564468#564468
These parameters:
client_header_buffer_size 1k;
large_client_header_buffers 4 32k;
Were blocking the call.
Aside from that it was a VERY bad idea on my side sending such a large amount of data in the url. I ended up using a POST with the base64 data on the body and that solved the problem.

Deploy Flask on Raspberry Pi with Nginx

I'm trying to deploy a simple flask app on my raspberry pi using nginx. I've followed these two guides:
http://www.onurguzel.com/how-to-run-flask-applications-with-nginx-using-gunicorn/
http://www.onurguzel.com/managing-gunicorn-processes-with-supervisor/
And have got everything running without error. But when I load a web browser pointing at my PI's IP (I work over ssh) - all I see is the default "welcome to nginx" page. What's going on?
here are my files:
/home/pi/hello/hello.py
from flask import Flask
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
#app.route('/')
def hello():
return "Hello world!"
app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == '__main__':
app.run()
/etc/nginx/sites-available/hello.conf (symlinked to: /etc/nginx/sites-enabled/)
server {
listen 80;
server_name hello.itu24.com;
root /home/pi/hello/hello.py;
access_log /home/pi/hello/access.log;
error_log /home/pi/hello/error.log;
location / {
try_files $uri #gunicorn_proxy;
}
location #gunicorn_proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
}
}
Here's my nginx.conf (though I have not changed it at all)
/etc/nginx/nginx.conf
user www-data;
worker_processes 2;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
For the supervisor part:
/etc/supervisor/conf.d/hello.conf
[program:hello]
command = /home/pi/hello/bin/python /home/pi/hello/bin/gunicorn hello:app
directory = /home/pi/hello
user = pi
I can spin everything up with :
sudo supervisorctl start hello
But when I hit my Pi's IP:
http://192.168.1.28
from my macs browser
all I get is: "Welcome to nginx"
Any ideas? This is my first server that I'm running and deploying to - running it on a Ras Pi probably wasn't the best idea but I'm learning a lot so far.
You might running flask on the default port, which is 5000.
Try changing this line:
if __name__ == '__main__':
#app.run()
app.run(port=8000)
or change your supervisord command to:
command = /home/pi/hello/bin/python /home/pi/hello/bin/gunicorn hello:app -b 0.0.0.0:8000
You might want to make sure the default site is disabled. Simply delete the symlink default from sites-enabled.
Also, the default port for Flask is 5000 not 8000, so in your nginx configuration, you need to change the following:
location #gunicorn_proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:5000; # Default port
}

Categories