Jade Han
Jade Han

Reputation: 1285

413 Request Entity Too Large nginx django

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

Answers (4)

Abayomi Olowu
Abayomi Olowu

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.

settings.py

FILE_UPLOAD_MAX_MEMORY_SIZE = 3 * 1024 * 1024 # (3MEGABYTES)
DATA_UPLOAD_MAX_MEMORY_SIZE = FILE_UPLOAD_MAX_MEMORY_SIZE

custom_validator.py

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

models.py

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

nginx.conf

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.

views.py

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

ctay
ctay

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

MdNazmulHossain
MdNazmulHossain

Reputation: 161

Open the terminal for Ubuntu

Use nano text editor:

$

sudo nano /etc/nginx/nginx.conf

set client body size to 100M

client_max_body_size 100M;

Like:

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

Joshua Craven
Joshua Craven

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

Related Questions