http-rs / tide

Fast and friendly HTTP server framework for async Rust
https://docs.rs/tide
Apache License 2.0
5.04k stars 322 forks source link

Support uploads (100 Continue) #878

Open mleonhard opened 2 years ago

mleonhard commented 2 years ago

How can a Tide handler send a tide::StatusCode::Continue response with no body and then later send a full response?

I am deploying an API server which uses Tide. I'm deploying it on Heroku. When Heroku's load balancer forwards a request to a server, the server must send some data back within 30 seconds, otherwise the load balancer closes the connection with a 503 [0]. This means that when a slow client takes more than 30 seconds to send the request body, the request fails. This is a problem for clients uploading 10MB image files over unreliable mobile Internet connections. Such uploads often take more than 30 seconds. The solution is to send a 100 Continue response before reading the request body.

[0] https://devcenter.heroku.com/articles/request-timeout

jbr commented 2 years ago

Because it uses async-h1, tide should by default send a 100 continue to any client that sends an Expect: 100-continue header async-h1#110 — if it does not, that's a bug. If the client does not send the expect header, I do not believe it is valid to send a 100 continue status

mleonhard commented 2 years ago

How about adding a test for it?

jbr commented 2 years ago

It is tested in async-h1.

ArtemGr commented 1 year ago

https://gms.tf/when-curl-sends-100-continue.html mentions cURL having --expect100-timeout SECS, which is useful to test 100-continue: set the timeout to a large value and then cURL will either hang waiting for the header, or will proceed immediately if the header is present.

I've tested it with

echo 123 > 123.txt
curl --expect100-timeout 321 -vT 123.txt https://a-webdav-url

and I see tide 0.16 returning 100-continue NP (when we decide to read the body, that is)

< HTTP/1.1 100 Continue
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< content-length: 0
< date: Wed, 07 Dec 2022 14:11:10 GMT