Run $ curl "http://138.199.41.51/ipfs/bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu/Mexico.JPG?format=car&dag-scope=entity&bytes=0:1048575" -k -v -o mexico-1mb.car -H "Accept: application/vnd.ipld.car"
138.199.41.51 is a core node. You can also repro with a localhost L1.
The request should timeout after 2 minutes with this error message: transfer closed with outstanding read data remaining
Full output
guanzo@DESKTOP-24333KG:~$ curl "http://localhost/ipfs/bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu/Mexico.JPG?format=car&dag-scope=entity&bytes=0:1048575" -k -v -o mexico-1mb.car -H "Accept: application/vnd.ipld.car"
* Trying 127.0.0.1:80...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /ipfs/bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu/Mexico.JPG?format=car&dag-scope=entity&car-scope=file&depth=1&entity-bytes=0:1048575&bytes=0:1048575 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.81.0
> Accept: application/vnd.ipld.car
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 31 May 2023 03:08:04 GMT
< Content-Type: application/vnd.ipld.car; version=1
< Transfer-Encoding: chunked
< Connection: keep-alive
< cache-control: public, max-age=29030400, immutable
< content-disposition: attachment; filename="bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu.car"
< etag: bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu.car
< Server-Timing: fetch;dur=0.312074,indexer;dur=0.000067;candidates-found=118921159;candidates-filtered=119026583,retrieval;dur=118.942823;first-byte-received=12931692937
< Server-Timing: shim; dur=15900.205737
< Server-Timing: shim_lassie; dur=15899.976966
< Server-Timing: shim_lassie_headers; dur=15899.552953
< Server-Timing: shim_lassie_body; dur=0.63105
< x-ipfs-path: /ipfs/bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu/Mexico.JPG
< x-content-type-options: nosniff
< Saturn-Node-Id: 12926ed7-03b9-479e-a9b2-480f1d4a70b9
< Saturn-Node-Version: 0_dev
< Saturn-Transfer-Id: 60e903b530aa1d74e730d5754612db22
< Saturn-Cache-Status: HIT
< Server-Timing: nginx;dur=0, nginx_uct;dur=, nginx_uht;dur=, nginx_urt;dur=
< Timing-Allow-Origin: *
< Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, OPTIONS
< Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
< Access-Control-Expose-Headers: *
<
{ [51844 bytes data]
100 1024k 0 1024k 0 0 8722 0 --:--:-- 0:02:00 --:--:-- 0* transfer closed with outstanding read data remaining
100 1024k 0 1024k 0 0 8722 0 --:--:-- 0:02:00 --:--:-- 0
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining
I believe this is related to chunked transfer encoding. curl is waiting for the "terminating chunk" (0/r/n/r/n) so it knows the response is done.
If you remove the -o mexico-1mb.car, the request ends immediately and the error message changes to * Failed reading the chunked-encoded stream, which confirms it's related to chunked transfer encoding.
I know that nginx automatically handles chunked transfer encoding. What I don't know is how that interacts with modules that write the response body. Does nginx add the encoding before this module, after this module, or not at all if a module "claims" the response.
The expected behavior is for the curl response to end cleanly with no error. If you remove &bytes=0:1048575 from the request, it works fine because the module isn't involved.
Handling intentional missing terminating chunks.
If lassie is unable to download the full CAR, it will signal a streaming error by not sending the terminating chunk.
The L1 does the same.
Unfortunately, every http hop handler needs to explicitly forward this error signaling, I think the module may have to as well. But i'm not sure, this is something we need to investigate. What does the module see when the L1 closes uncleanly?
Action items
Run
$ curl "http://138.199.41.51/ipfs/bafybeifpz6onienrgwvb3mw5rg7piq5jh63ystjn7s5wk6ttezy2gy5xwu/Mexico.JPG?format=car&dag-scope=entity&bytes=0:1048575" -k -v -o mexico-1mb.car -H "Accept: application/vnd.ipld.car"138.199.41.51is a core node. You can also repro with a localhost L1.The request should timeout after 2 minutes with this error message:
transfer closed with outstanding read data remainingFull output
I believe this is related to chunked transfer encoding. curl is waiting for the "terminating chunk" (
0/r/n/r/n) so it knows the response is done.If you remove the
-o mexico-1mb.car, the request ends immediately and the error message changes to* Failed reading the chunked-encoded stream, which confirms it's related to chunked transfer encoding.I know that nginx automatically handles chunked transfer encoding. What I don't know is how that interacts with modules that write the response body. Does nginx add the encoding before this module, after this module, or not at all if a module "claims" the response.
The expected behavior is for the curl response to end cleanly with no error. If you remove
&bytes=0:1048575from the request, it works fine because the module isn't involved.Handling intentional missing terminating chunks.
If lassie is unable to download the full CAR, it will signal a streaming error by not sending the terminating chunk.
The L1 does the same.
Unfortunately, every http hop handler needs to explicitly forward this error signaling, I think the module may have to as well. But i'm not sure, this is something we need to investigate. What does the module see when the L1 closes uncleanly?
Action items
transfer closed with outstanding read data remainingorFailed reading the chunked-encoded stream.