Reputation: 1285
I am making a practice web service (client's artbook display web site) The client can upload artbook images to the server.
But I get the following error when the client uploads too many images
413 Request Entity Too Large
I tried adding client_max_body_size 100M;
in nginx.conf
#user nobody;
#Defines which Linux system user will own and run the Nginx server
worker_processes 1;
#error_log logs/error.log; #error_log logs/error.log notice;
#Specifies the file where server logs.
#pid logs/nginx.pid;
#nginx will write its master process ID(PID).
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#access_log logs/access.log main;
sendfile on;
server {
listen 80;
server_name xxxx.net;
client_max_body_size 100M;
keepalive_timeout 5;
return 301 https://$server_name$request_uri;
}
# HTTPS server
#
server {
listen 443 default_server ssl;
server_name xxx.net;
ssl_certificate /etc/letsencrypt/live/xxxx.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxx.net/privkey.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
}
}
}
and tried:
sudo service nginx restart
sudo service nginx reload
and retry
runserver
but still get
413 Request Entity Too Large
Can anybody help?
Upvotes: 45
Views: 36530
Reputation: 349
This is really unrelated but i feel the right way to handle file validation is what i'm going to demonstrate here. Instead of determining the file size using nginx, you can actually do that in your project with the following procedures as this is what i did and everything works well on my projects. Advantage of this is that you would customized the message you want to be sent back to users when they upload an invalid file or file with larger size than you specified in your project configuration.
FILE_UPLOAD_MAX_MEMORY_SIZE = 3 * 1024 * 1024 # (3MEGABYTES)
DATA_UPLOAD_MAX_MEMORY_SIZE = FILE_UPLOAD_MAX_MEMORY_SIZE
def convert_to_megabyte(file_size):
file_size_in_mb = round(file_size / (1000 * 1000))
return ceil(file_size_in_mb)
def custom_file_validator(file):
file_types = ["image/png", "image/jpeg", "image/jpg", "application/pdf"]
if not file:
raise ValidationError("No file selected.....")
if file.size > FILE_UPLOAD_MAX_MEMORY_SIZE:
raise ValidationError(f"File shouldn't be larger than {convert_to_megabyte(FILE_UPLOAD_MAX_MEMORY_SIZE)}MB.")
fs = FileSystemStorage()
filename = fs.save(file.name, file)
file_type = mimetypes.guess_type(filename)[0]
if file_type not in file_types:
raise ValidationError("Invalid file, please upload an image file with extensions (png, jpg or jpeg).")
return file
then you can add the custom_file_validor to the file or image field in your django model
class Company(models.Model):
my_image = models.ImageField(upload_to="images/", blank=True, null=True,max_length=500, validators=[custom_file_validator])
my_file = models.FileField(upload_to="files/", blank=True, null=True, max_length=500, validators=[custom_file_validator])
so the above would always validate the image based on your custom validation and not on the server(nginx) validation.
On your nginx.conf, just add this to your http block
client_max_body_size 0
if your users would be uploading images or files on their end, you can simply just use the below on your view.
if request.method == 'POST' and request.FILES:
document_type = request.POST.get("document-type", None)
document = request.FILES.get("document", None)
if document.size > base.FILE_UPLOAD_MAX_MEMORY_SIZE:
messages.warning(
request, f"Document cannot be larger than {convert_to_megabyte(base.FILE_UPLOAD_MAX_MEMORY_SIZE)}MB.")
return redirect("create_company")
fs = FileSystemStorage()
filename = fs.save(document.name, document)
file_type = mimetypes.guess_type(filename)[0]
if file_type not in file_types:
messages.info(request, "Invalid file uploaded, please upload an image (jpeg, png, jpg only).")
return redirect('create_company')
so the above would use your custom validation and not the server(nginx) validation since you've made it 0. I hope this is clear enough for anyone seeing this in the future. this took me some times to figure out but works well.
Upvotes: 2
Reputation: 419
I know this has already been answered, but rather than having the "client_max_body_size 100M;" multiple times in your code under the servers, you can just add it once, under the http section - see line 2 below.
http {
client_max_body_size 100M;
...
######################
# HTTP server
######################
server {
...
listen 80;
server_name xxxx.net;
...
}
######################
# HTTPS server
######################
server {
...
listen 443 default_server ssl;
server_name xxxx.net;
...
}
}
Source: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
Upvotes: 1
Reputation: 161
Open the terminal for Ubuntu
$
sudo nano /etc/nginx/nginx.conf
client_max_body_size 100M;
http {
##
# Basic Settings
##
client_max_body_size 100M;
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
## More codes here ...
}
Upvotes: 6
Reputation: 4545
You've fixed the issue on your HTTP server, but your HTTP server is set to 301 redirect to your HTTPS server... your HTTPS server does not have client_max_body_size
configured, so it is defaulting to 1M & causing this 413 (Request Entity Too Large) error.
To fix this issue, you simply need to add client_max_body_size
to BOTH the HTTP server block and the HTTPS server block, as shown in the example below:
http {
...
######################
# HTTP server
######################
server {
...
listen 80;
server_name xxxx.net;
client_max_body_size 100M;
...
}
######################
# HTTPS server
######################
server {
...
listen 443 default_server ssl;
server_name xxxx.net;
client_max_body_size 100M;
...
}
}
More info on client_max_body_size
here: http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
Syntax: client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location
Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of client request body size.
Read More about configuring HTTPS servers here: http://nginx.org/en/docs/http/configuring_https_servers.html
Upvotes: 67