Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When I upload a file with a larger size than the backend allows I don't get a 413 error #4253

Open
frederikhors opened this issue Dec 17, 2022 · 41 comments
Labels

Comments

@frederikhors
Copy link
Contributor

frederikhors commented Dec 17, 2022

I'm using the following code, but when I upload a file with a larger size than the backend allows, I don't get a 413 error (which I get instead by using Postman for the same call).

const uppy = new Uppy()
  .use(XHRUpload, {
    endpoint: "https://backend.com/upload",
    withCredentials: true,
    timeout: 0,
    formData: false,
  })
  .on("file-added", (file) => {
    uppy.setFileState(file.id, {
      xhrUpload: {
        endpoint: `https://backend.com/upload?filename=${file.name}`,
      },
    });
  })
  .on("upload-success", (file) => {
    //do something with file
  });
"@uppy/svelte": "3.0.0",
"@uppy/xhr-upload": "3.0.1",

This is the dev tools:

image

There are no Response Headers in request.

I only get a generic:

net::ERR_CONNECTION_ABORTED
"This looks like a network error, the endpoint might be blocked by an internet provider or a firewall."

Is this my fault?

@Murderlon
Copy link
Member

Murderlon commented Dec 19, 2022

Hi! Perhaps you can try to use getResponseError to get what you need?

@frederikhors
Copy link
Contributor Author

Yeah, I already tried:

const uppy = new Uppy()
  .use(XHRUpload, {
    endpoint: "https://backend.com/upload",
    withCredentials: true,
    timeout: 0,
    formData: false,
    getResponseError: (err, err2) => {
      console.log("getResponseError: err, err2", err, err2);
      return new Error(err);
    },
  })
...

image

@Murderlon
Copy link
Member

Interesting, so you do see the correct status code and error in the network tab but not from Uppy in the console?

@frederikhors
Copy link
Contributor Author

Nope. When the upload fails for 413 (payload too large) I don't see the status code in the network tab (which I need to return proper message to the user) but I do see the status code if I try the same request with postman or similar tools.

@mifi
Copy link
Contributor

mifi commented Dec 21, 2022

Do you see any CORS error in your browser? The error message This looks like a network error, the endpoint might be blocked by an internet provider or a firewall is returned if the following condition applies after a response:

(xhr.readyState !== 0 && xhr.readyState !== 4) || xhr.status === 0

Not sure why a 413 would cause that but I know that if CORS fails, it will not return the proper 413 status code to the JS code.

@frederikhors
Copy link
Contributor Author

No CORS issue at all, trust me. The call goes to the backend, in the requested handler (CORS would stop everything much earlier).

And even if it was CORS (which it isn't) the browser should tell.

@mifi
Copy link
Contributor

mifi commented Dec 22, 2022

Can you confirm the response headers with the 413 status response also contains CORS headers? Could you paste the exact response headers from chrome devtools?

what about if you right click the request in chrome devtools, then «copy as curl», then add -vvv and run it from the cli, do you see the status code and cors headers, or does curl also report something like connection aborted?
What kind of server are you running?

@mifi
Copy link
Contributor

mifi commented Dec 22, 2022

If you have a minimal reproduceable code, like a simple express server that responds with 413 and triggers this error also on my machine, then we have something more to work with. Or you can share your server url if hosted somewhere

@mifi
Copy link
Contributor

mifi commented Dec 22, 2022

I tried this now:

const http = require('http');

const server = http.createServer((req, res) => {
  if (req.method === 'OPTIONS') {
    res.writeHead(200, { 'Access-Control-Allow-Origin': '*' });
    res.end();
    return;
  }
  if (req.method === 'POST') {
    res.writeHead(413);
    // res.writeHead(413, { 'Access-Control-Allow-Origin': '*' });
    res.end();
    return;
  }

  res.writeHead(400);
  res.end();
  return;
});
server.listen(8080);

It gives:

Access to XMLHttpRequest at 'http://localhost:8080/upload' from origin 'http://127.0.0.1:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
loggers.js:17 [Uppy] [14:35:13] Failed to upload 08e7bb5af72f6f59c7cca4df563ff572.jpg This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.
loggers.js:17 [Uppy] [14:35:13] Error: This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.
index.js:591          POST http://localhost:8080/upload net::ERR_FAILED 413

If I instead comment out this line

    // res.writeHead(413);

and uncomment this:

    res.writeHead(413, { 'Access-Control-Allow-Origin': '*' });

...then I don't get the error anymore (Error: This looks like a network error, the endpoint might be blocked by an internet provider or a firewall)

@frederikhors
Copy link
Contributor Author

...then I don't get the error anymore (Error: This looks like a network error, the endpoint might be blocked by an internet provider or a firewall)

So the same as mine?

I cannot share a server/code right now. But your express code looks the same. Is not a CORS error.

@mifi
Copy link
Contributor

mifi commented Dec 22, 2022

Can you reproduce the issue with my code? res.writeHead(413, { 'Access-Control-Allow-Origin': '*' });?

@arturi arturi removed the Triage label Jul 6, 2023
@frederikhors
Copy link
Contributor Author

Sorry for the late answer.

I tried with your code and it's the same, @mifi.

@frederikhors
Copy link
Contributor Author

If I use insomnia on my PC it gets the 413 status code error, Uppy doesn't.

* Preparing request to http://localhost:3000/upload?name=test.zip
* Current time is 2024-01-09T20:51:21.366Z
* Enable automatic URL encoding
* Using default HTTP version
* Enable timeout of 30000ms
* Enable SSL validation
* Enable cookie sending with jar of 1 cookie
* Hostname localhost was found in DNS cache
*   Trying 127.0.0.1:3000...
*   Trying ::1:3000...
* Connected to localhost (::1) port 3000 (#4)

> POST /upload?name=test.zip HTTP/1.1
> Host: localhost:3000
> User-Agent: insomnia/8.5.1
> Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY
> Accept: */*
> Content-Length: 60630278

| (64 KB hidden)
| (64 KB hidden)
| (64 KB hidden)
| (64 KB hidden)

* Mark bundle as not supporting multiuse

< HTTP/1.1 413 Payload Too Large
< content-type: text/plain; charset=utf-8
< content-length: 21
< access-control-allow-origin: http://localhost:3000
< access-control-allow-credentials: true
< vary: origin
< vary: access-control-request-method
< vary: access-control-request-headers
< x-request-id: 2e923612-39ee-4c8e-a314-29259fa0b122
< date: Tue, 09 Jan 2024 20:51:21 GMT

* HTTP error before end of send, stop sending



* Received 21 B chunk
* Closing connection 4

@mifi
Copy link
Contributor

mifi commented Jan 10, 2024

ok, if you can share some code to reproduce the problem, then we could look into it

@frederikhors
Copy link
Contributor Author

I created https://github.com/frederikhors/iss-uppy-413 for you.

This is an exactly reproduction of the issue.

Steps:

  • Run with cargo run . (you need Rust installed or you can use https://codesandbox.io/p/github/frederikhors/iss-uppy-413)

  • Visit localhost:3000 (or the codesandbox page)

  • Upload a file smaller than 1 MB: it works!

  • Upload a file bigger than 1 MB: it fails without 413!

  • Use Postman or similar and the 413 status code is there in the response!

As you can see here there is no CORS involved at all.

image

@mifi
Copy link
Contributor

mifi commented Jan 15, 2024

i cannot get the codesandbox to work, but i copied the html code and made a simple node.js server, and when I respond with 413, I can see the error inside Uppy:

Screenshot 2024-01-15 at 11 19 41

I think might be something wrong with your rust code, maybe your RequestBodyLimitLayer cuts off the connection without responding with a 413 http status code. Here's my node code:

import express from 'express'

const app = express()

const html = `\
<!doctype html>
<html>
    <head>
        <link href="https://releases.transloadit.com/uppy/v3.21.0/uppy.min.css" rel="stylesheet">
    </head>
    
    <body>
        <div id="uppy"></div>

        <br><br>

        <form action="/" method="post" enctype="multipart/form-data">
            <label>
                Upload file:
                <input type="file" name="file" multiple>
            </label>

            <input type="submit" value="Upload files">
        </form>

        <script type="module">
            import { Uppy, XHRUpload, Dashboard } from "https://releases.transloadit.com/uppy/v3.21.0/uppy.min.mjs"
            
            const uppy = new Uppy()
                .use(XHRUpload, {
                    endpoint: "/",
                    bundle: true
                })
                .on('upload-success', (info) => {
                    console.log("upload-success, info:", info);
                });

            uppy.use(Dashboard, { target: '#uppy', inline: true })
        </script>
    </body>
</html>
`;

app.get('/', (req, res) => {
  res.set('content-type', 'text/html').send(html)
})

app.post('/', (req, res) => {
  console.log('post')
  res.send(413);
})

app.listen(8080);

If you can modify the node.js code to reproduce your problem, then I can look into it, but as it stands now I'm still not able to reproduce your problem, so I'm closing this for now.

@mifi mifi closed this as completed Jan 15, 2024
@frederikhors
Copy link
Contributor Author

@mifi, thanks for your answer.

I created the reproduction because if I use the same Rust code with Postman the 413 is visible in the response (se previous post), so RequestBodyLimitLayer is sending it.

I still think the problem is in Uppy.

i cannot get the codesandbox to work

Why? Can you tell me how can I help you make it work?

Did you try to make it start on codesandbox?

@mifi
Copy link
Contributor

mifi commented Jan 15, 2024

I created the reproduction because if I use the same Rust code with Postman the 413 is visible in the response (se previous post), so RequestBodyLimitLayer is sending it.

i see in your previous comment that the insomnia request is to a different server/path: POST /upload?name=test.zip vs POST / in the codesandbox. did you use insomnia against the same code that you shared in codesandbox?

Why? Can you tell me how can I help you make it work?

maybe i'm not experienced enough with codesandbox but i clicked your link but i cannot find any "play" button or any way to make the Uppy UI show up.

this is what I see:

Screenshot 2024-01-15 at 17 34 50

@frederikhors
Copy link
Contributor Author

did you use insomnia against the same code that you shared in codesandbox?

Yes, the code is a little bit different on this reproduction, but it's the same.

i cannot find any "play" button

Maybe you should fork the project on codesandbox? I believe if you don't fork it it's just read-only.

@mifi
Copy link
Contributor

mifi commented Jan 15, 2024

I cannot find any fork button

@frederikhors
Copy link
Contributor Author

  1. Go here: https://codesandbox.io/dashboard/recent
  2. Import repository "https://github.com/frederikhors/iss-uppy-413"
  3. Now you have the environment ready

image

@mifi
Copy link
Contributor

mifi commented Jan 15, 2024

seems i need to have a codesandbox account to do that. could you try to run a simple fetch request instead of uppy and see if it can correctly detect the 413 response code?

@frederikhors
Copy link
Contributor Author

could you try to run a simple fetch request instead of uppy and see if it can correctly detect the 413 response code?

Yeah, as I said I already did and it works: I get the 413. Only with uppy not.

I tried again with curl, using:

curl -v -F name=file -F upload=./document.pdf "http://localhost:3000/"

and I get:

*   Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.0.1
> Accept: */*
> Content-Length: 252
> Content-Type: multipart/form-data; boundary=------------------------e28e20e6f25c0ebf
>
< HTTP/1.1 413 Payload Too Large
< content-type: text/plain; charset=utf-8
< content-length: 21
< date: Mon, 15 Jan 2024 15:30:22 GMT
* HTTP error before end of send, stop sending
<
length limit exceeded* Closing connection 0

Do you see the HTTP/1.1 413 Payload Too Large?

@mifi
Copy link
Contributor

mifi commented Jan 16, 2024

could you run a public server that responds with 413 and reproduces the problem and share the URL? maybe the problem is specific to XMLHTTPRequest (which uppy uses)

@frederikhors
Copy link
Contributor Author

I shared the codesandbox and the GitHub repo.

Can you run a docker container with that GitHub repo?

And, please, can you reopen this issue? I'm afraid it can go lost...

@mifi
Copy link
Contributor

mifi commented Jan 16, 2024

Ok sure, how do i run this in docker? I cannot find the dockerfile

@mifi mifi reopened this Jan 16, 2024
@frederikhors
Copy link
Contributor Author

Ok sure, how do i run this in docker? I cannot find the dockerfile

The Dockerfile is not in the repo, but this should work:

FROM rust:1.75

COPY ./ ./

RUN cargo build

CMD ["./target/debug/iss-uppy-413"]

@mifi
Copy link
Contributor

mifi commented Jan 21, 2024

does it work for you? doesn't seem to work here:

[+] Building 3.7s (7/7) FINISHED                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                          0.0s
 => => transferring dockerfile: 118B                                                                          0.0s
 => [internal] load .dockerignore                                                                             0.0s
 => => transferring context: 2B                                                                               0.0s
 => [internal] load metadata for docker.io/library/rust:1.75                                                  3.4s
 => [internal] load build context                                                                             0.0s
 => => transferring context: 2B                                                                               0.0s
 => [1/3] FROM docker.io/library/rust:1.75@sha256:ac8c4cb82e317512260fbcf54e80039d9083605e3b8ea3b9fd4c39e147  0.0s
 => CACHED [2/3] COPY ./ ./                                                                                   0.0s
 => ERROR [3/3] RUN cargo build                                                                               0.3s
------                                                                                                             
 > [3/3] RUN cargo build:
0.260 error: could not find `Cargo.toml` in `/` or any parent directory
------
Dockerfile:5
--------------------
   3 |     COPY ./ ./
   4 |     
   5 | >>> RUN cargo build
   6 |     
   7 |     CMD ["./target/debug/iss-uppy-413"]
--------------------
ERROR: failed to solve: process "/bin/sh -c cargo build" did not complete successfully: exit code: 101

even though Cargo.toml exists in the current directory

@frederikhors
Copy link
Contributor Author

Yeah. It works. I tried just now.

I updated Readme, added Dockerfile and changed this: frederikhors/iss-uppy-413@5846a06.

@mifi
Copy link
Contributor

mifi commented Jan 25, 2024

It worked when I changed from docker run --rm -p 8080:8080 iss-uppy-413 to docker run --rm -p 3000:3000 iss-uppy-413.

When I upload a file less than 1mb using chrome and the docker image http://localhost:3000 I get success. When I upload a file of 41,6MB I get a 413 (Payload Too Large) error in my browser's JS console, so I cannot reproduce your issue with your docker container. Maybe you're using a different browser?

Screenshot 2024-01-25 at 12 06 51 Screenshot 2024-01-25 at 12 07 02

@mifi mifi closed this as completed Jan 25, 2024
@frederikhors
Copy link
Contributor Author

Sorry, the port is 3000 of course! :)

I get the first error too:
image

But the problem is in the console: there is no HTTP ERORR 413 CODE!

image

I'm using Chrome 120.0.6099.225 on Windows.

@mifi
Copy link
Contributor

mifi commented Jan 26, 2024

I'm on Version 120.0.6099.234 (Official Build) (arm64). Does it happen in other browsers too? I don't know how to reproduce your issue unfortunately

@frederikhors
Copy link
Contributor Author

This is happening in Firefox 122:

image

@frederikhors
Copy link
Contributor Author

I know you have to reduce open issues, but I think this is still a problem (even the fact that you cannot reproduce but I can).

Can you please re-open until we understand why?

@mifi
Copy link
Contributor

mifi commented Jan 26, 2024

could you run a server with a public URL that responds with 413 in a way that reproduces this issue? Because with your dockerfile i cannot reproduce it

@frederikhors
Copy link
Contributor Author

Okay. A moment to recap.

The problem is that on Windows PC and Chrome 120 and Firefox 122 I don't get the code 413 from server using Uppy.

That is, I cannot know the precise cause of the upload failure.

I don't think the public server is necessary because the Dockerfile serves precisely to have an objective way of launching software.

And when we both launch this software and open localhost:3000 we each have a different result when uploading files larger than 1 MB in size.

Can you tell me what operating system and version of Chrome you are trying with?

Can you try Firefox? Or Safari?

@mifi
Copy link
Contributor

mifi commented Jan 26, 2024

I shared the version, and im on macos sonoma. I tried safari and it was the same. I cannot reproduce the problem with the docker image so i dont know what else to try, that’s why i thought that if you have a server running that reproduces the problem, i could try to use that too.

@frederikhors
Copy link
Contributor Author

But if I publish a server is the same of the Dockerfile one.

Can you try with a Windows PC?

@mifi
Copy link
Contributor

mifi commented Jan 27, 2024

ok i fired up a windows 11 vm and tried with edge and got the same error, so it could possibly be a windows-specific issue
Screenshot 2024-01-27 at 12 02 31

@mifi mifi reopened this Jan 27, 2024
@frederikhors
Copy link
Contributor Author

Ok. Thanks. I'm happy now! Not because of the issue of course! 😆

@mifi
Copy link
Contributor

mifi commented Jan 29, 2024

I tried to run this code:

const http = require('http');

const html = `\
<!doctype html>
<html>
    <head>
        <link href="https://releases.transloadit.com/uppy/v3.21.0/uppy.min.css" rel="stylesheet">
    </head>
    
    <body>
        <div id="uppy"></div>

        <br><br>

        <form action="/" method="post" enctype="multipart/form-data">
            <label>
                Upload file:
                <input type="file" name="file" multiple>
            </label>

            <input type="submit" value="Upload files">
        </form>

        <script type="module">
            import { Uppy, XHRUpload, Dashboard } from "https://releases.transloadit.com/uppy/v3.21.0/uppy.min.mjs"
            
            const uppy = new Uppy()
                .use(XHRUpload, {
                    endpoint: "/",
                    bundle: true
                })
                .on('upload-success', (info) => {
                    console.log("upload-success, info:", info);
                });

            uppy.use(Dashboard, { target: '#uppy', inline: true })
        </script>
    </body>
</html>`

const server = http.createServer((req, res) => {
  if (req.method === 'POST') {
    res.writeHead(413);
    res.end();
    return;
  }

  if (req.method === 'GET' && req.url === '/') {
    res.setHeader('content-type', 'text/html');
    res.write(html)
    res.end();
    return;
  }

  res.writeHead(400);
  res.end();
  return;
});

server.listen(8080);

but i cannot reproduce the problem on windows (i'm getting 413 correctly), so I think the problem exists on Windows (browser) and Rust htttp server (probably RequestBodyLimitLayer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants