perlsky is a Perl 5 implementation of an AT Protocol Personal Data Server.
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

Stop gzipping sync blob downloads

alice bdb3b823 daa33f05

+16 -1
+2
docs/DEPLOYMENT.md
··· 200 200 } 201 201 ``` 202 202 203 + `com.atproto.sync.getBlob` responses should stay uncompressed end-to-end. `perlsky` now bypasses Mojolicious dynamic gzip for blob bytes because some downstream image proxy routes will auto-decompress the body and accidentally forward a stale `Content-Encoding` header, which shows up in clients as broken image loads (`ERR_CONTENT_DECODING_FAILED`). 204 + 203 205 This still requires wildcard DNS or per-handle DNS records so public ACME validation can reach the server. 204 206 205 207 A minimal nginx site looks like:
+4 -1
lib/ATProto/PDS/API/Sync.pm
··· 128 128 $c->res->headers->header('Content-Disposition' => 'attachment; filename="' . ($c->param('cid') // q()) . '"'); 129 129 $c->res->headers->header('Content-Security-Policy' => q{default-src 'none'; sandbox}); 130 130 $c->observe_blob_egress($blob->{mime_type}, length($bytes)); 131 - $c->render(data => $bytes); 131 + # Blob bytes need to bypass Mojolicious' dynamic gzip so image proxy routes 132 + # do not see a decompressed body paired with a stale Content-Encoding header. 133 + $c->res->body($bytes); 134 + $c->rendered(200); 132 135 return; 133 136 }); 134 137
+10
t/blob-sync-surfaces.t
··· 78 78 ->status_is(200); 79 79 is($t->tx->res->body, 'blob-bytes', 'blob bytes are served back'); 80 80 like($t->tx->res->headers->content_type // '', qr{image/png}, 'blob content type preserved'); 81 + ok(!defined($t->tx->res->headers->content_encoding), 'blob download is not dynamically compressed by default'); 82 + 83 + my $gzip_blob_tx = $t->ua->build_tx( 84 + GET => '/xrpc/com.atproto.sync.getBlob?did=' . $did . '&cid=' . $blob_cid => { 85 + 'Accept-Encoding' => 'gzip', 86 + }, 87 + ); 88 + $t->request_ok($gzip_blob_tx)->status_is(200); 89 + is($t->tx->res->body, 'blob-bytes', 'blob bytes stay readable when gzip is accepted'); 90 + ok(!defined($t->tx->res->headers->content_encoding), 'blob download ignores Accept-Encoding gzip'); 81 91 82 92 $t->get_ok('/xrpc/com.atproto.sync.getLatestCommit?did=' . $did) 83 93 ->status_is(200)