分享
一份分享是什麼、能活多久、能被取幾次
一次分享是一段文字,或一個以上的檔案,加上一組取件碼。碼給對方,對方去 /s/<碼> 取。
分享沒有永久的。它會過期,也可以限制被取幾次,兩者在建立時決定,建立之後還能改。


送出東西
一份分享裝的是文字、檔案,或一條連結。它們存的地方不同,行為也不同。
文字不管多大都在資料庫裡,上限是 share.max_text_bytes,預設 1 MB。超過會被拒絕,並叫你改用檔案送。1 MB 大約一百萬個字,塞不進去的東西已經不是一段貼文了。
檔案不管多大都存成物件,上限是 server.max_body_bytes,預設 100 MiB。一份分享可以放好幾個。角色或單一帳號可以被設一個比較小的單檔上限,見配額。
連結是一個網址,打開分享的人會被送過去。只收 http 和 https。密碼、期限和次數限制跟其他分享一樣能用,而且目的地拿不到取件碼,因為轉址時不送 referrer。
有次數限制的連結會等人按
沒有密碼、沒有次數限制的連結分享會直接把訪客送過去。有次數限制的會先出一個頁面,等人按一下才跳,因為聊天軟體在連結被貼上的當下就會去抓,直接跳的話一次性的連結在任何人打開之前就被用掉了。
除了連結以外都可以端對端加密;連結要讓伺服器讀得到才能轉址。
在終端機裡,用 tess 或單純的 curl -T 也能上傳。在任何網頁上,則可以用瀏覽器擴充功能按右鍵上傳。
多個檔案和資料夾
分享由第一個檔案建立,其餘一個一個加上去。沒有草稿要收尾,所以傳到一半斷掉,留下的是已經到的那些,不是什麼都沒有。
上傳過程中連結就是通的
在你傳完之前打開它的人會看到不完整的分享。傳完再把連結發出去。
檔名可以帶路徑,資料夾的結構就是這樣保住的。每一段都會被清理,結果一定是一條爬不出壓縮檔的相對路徑:
| 送進來 | 存下來 |
|---|---|
holiday/2024/photo.jpg | 原樣 |
../../etc/passwd | etc/passwd |
/etc/passwd | etc/passwd |
a\b\c.txt | a/b/c.txt |
反斜線也算分隔符,Windows 不收的字元會一起被拿掉。不同資料夾裡的兩個檔案就是兩個檔案,a/photo.jpg 和 b/photo.jpg 都留得住。
大檔案
上傳可以續傳。連線斷掉的話會從最後一個完整的區塊接下去,不是從頭來,而且最多只會重送一個區塊。
開了之後被放著不管的上傳,在 store 上佔著真的空間,而且算進配額。它會在 share.upload_session_ttl_hours 之後被清掉,預設一天。
用 S3 還要設一條生命週期規則
tessera 會清掉它找得到的,但清失敗的話 S3 會留著並且計費。見檔案放在哪裡。
取件碼
預設 8 個字元,字母表裡沒有 I、L、O、U。前三個是因為它們正是人們會跟 1、1、0 搞混的字;拿掉 U 之後,產生出來的碼拼不出那些沒有人想看到的字。
念出來再打回去會自動修正。ozpq0123、OZPQ0123、0ZPQ-0123 都會到同一份分享:大小寫、連字號、底線、空格都處理掉,O 和 I 會變成 0 和 1。
share.code_length 可以設 4 到 32。8 個字元大約是 1.1 × 10¹² 種組合。
調短之前先看節流
4 個字元只有一百萬種組合。同一來源查不到的碼一分鐘 60 次就會被擋,靠這個掃完要十一天左右。放在代理後面而 trusted_proxies 沒設對的話,每個請求都算在代理那一個位址上,節流等於沒有,見反向代理。
不存在的碼和格式不對的碼從外面看起來一樣。分開回答等於告訴人哪種形狀值得試。
取件
打開 /s/<碼> 會看到這份分享是什麼,不花掉任何東西。連結預覽、瀏覽器預抓、信件掃描器跟著連結走,都不會毀掉一份看過即焚的分享。
在瀏覽器裡,頁面還會直接顯示文字分享,以及只有一張圖片或一部影片的分享,而顯示出來就算一次取件。只剩一次取件的分享會等你點了才顯示,所以光是打開看過即焚的連結,不會用掉它。圖片支援 PNG、JPEG、GIF、WebP、AVIF、BMP 和 SVG,影片支援 MP4、M4V、WebM、MOV、MKV 和 OGV。影片在按下播放前會先遮住,瀏覽器解不開的影片會改成提供下載。
真的把它取走才會花掉一次,而且整段傳輸只算一次。一次下載不只一個請求,續傳和斷線之後重試都是,這些都不另外計費。
授權活得跟傳輸一樣久
讓它過期的是「沒在用」,不是時間長短:預設閒置一小時,而且每用一次就往後推。還在傳的授權要多久就有多久,傳完的一小時內就死掉。share.ticket_ttl_hours 是壓在上面的天花板,預設一天。
固定壽命必須長到讓最慢的線路傳完最大的檔案,而那剛好長到讓那份授權值得轉手給別人。
如果這台機器有掃毒,分享要等檔案掃完才能取件,試了也不花任何東西。
文字分享下載下來是一個純文字檔,檔名用它的標題,沒有標題就用取件碼。
有好幾個檔案的分享會打包成一份下載。zip 是預設,也是三大桌面系統都不用裝東西就打得開的;tar 和 7z 留給會讓使用者選的客戶端。只有一個檔案就送那個檔案。
上傳的內容永遠不會用它宣告的類型送回去
類型有記下來,但不會照著回。回了的話,一個 text/html 的上傳就是同一個網域上的 stored XSS,而那個網域放著所有人的登入 cookie。
密碼
分享可以加密碼,最少 4 個字元。比帳號密碼寬鬆,因為它是加在一條本來就猜不到的連結上的第二道鎖,而且常常要用電話念給對方。
上鎖的分享只會告訴訪客「這個存在,而且要密碼」。檔名、大小、期限都要等密碼給了才看得到,因為這三件事都在描述內容。
同一組碼加同一來源猜錯太多次會被擋一段時間。
能活多久,能取幾次
沒特別指定的話一份分享活一個禮拜,最長可以要求三十天。也可以限制被取幾次,限一次就是看過即焚。
死掉的分享不會馬上消失。紀錄還在的期間,點連結會說「已過期」而不是「沒有這組碼」,這兩件事對人來說不一樣,而且只有一個值得重打一次。內容本身在死掉之後的下一輪掃描就清掉,所以看過即焚的分享不會在被取走之後,還佔著它的完整大小一個禮拜。
掃描每小時一輪。
停在那裡。授權只涵蓋「次數用完」這一種狀態。
次數用完是你已經付過的那一次繞回來。過期是寄件人說的「這之後就不要了」,停用是管理員說的「不要再有了」,這兩個都蓋不過去。
建立之後改
已經存在的分享可以換一個期限、換一個剩餘次數,或是把密碼拿掉。內容和取件碼不會變。
次數是從現在算,不是從頭算。一份已經被取過兩次的分享設成 1,剩下的是一次,不是零次。
內容存在哪
文字是資料庫裡的一列,所以備份資料庫就等於備份了它。檔案一個存成一個物件,按年、月和一組隨機編號歸檔。見檔案放在哪裡。
配額
上限有三層,最緊的那一層說了算。
- 整台機器。
storage.max_total_bytes,預設沒設。 - 一個角色。 屬於它的人總共能存多少,以及單一檔案最大多大。
- 單一帳號。 這兩個上限都可以為某一個人單獨覆寫。
三層計的都是還活著的內容,包括存在資料庫裡的文字。已經被清掉內容的死分享不算。
這是護欄不是帳本
同時進行的上傳各自讀一次剩餘額度,所以它們可能一起越線,下一個上傳才會被擋。留跟磁碟一樣的餘裕。
想壓低佔用,把預設期限縮短比設配額有效。磁碟上的量大約是上傳速率乘以保存時間,縮短預設期限會拉低穩定值,而且不用拒絕任何人。
命令列用 tessera-server quota 設同樣的數字,下一個請求就生效:
tessera-server quota list
tessera-server quota set role member 5000000000
tessera-server quota set-file user alice 100000000
tessera-server quota set user alice noneset 是總量,set-file 是單一檔案上限,單位都是位元組。none 把數字清掉,交回上一層決定;0 是這一層不設上限。匿名上傳算在 guest 角色頭上,所以開放匿名上傳的實例一樣管得住。
不登入也能上傳
features.anonymous_upload 預設開著。沒登入建立的分享會回一個管理權杖,那是之後刪掉它的唯一方法。
管理權杖只出現這一次
權杖本身不會被存下來,只留一段拿來核對的指紋。弄丟就沒有人刪得掉那份分享,只能等它過期。
另一條路是先登入:帳號本身就是權杖,而且分享會出現在你自己的清單裡。
刪一份不屬於你的分享,看起來跟刪一份不存在的一樣。分開回答等於確認哪些碼是真的。
連結預覽
把連結貼進 Discord、Slack 這類地方會出現一張有圖的卡片。圖是伺服器畫的,因為 unfurler 不跑 JavaScript,頁面自己組出來的圖沒有人看得到。卡片用這台機器設定的語言。
畫好的卡片會留著,但是用卡片上寫的內容當 key,所以寫著「還能取兩次」的卡片,在這句話不再成立的那一刻就會被換掉。文字分享的卡片會畫出前幾行,而且上色。
卡片透露什麼,看分享是哪一種:
| 分享 | 卡片顯示 |
|---|---|
| 一般的 | 標題或檔名、大小、還剩多少 |
| 有密碼 | 只說它有密碼 |
| 端對端加密 | 只說這件事,以及大小 |
| 連結 | 說它是一條分享的連結。不顯示網址 |
| 過期或用完 | 說它已經不能用 |
預覽是給整個頻道看的,上鎖的分享在那裡講出檔名,密碼就是裝飾品。抓預覽不花任何東西。
你可以換成自己的版面,一台機器一個設計。不管版面要什麼,上鎖的分享照樣什麼都不透露:那些值在版面看到之前就被扣下來了。



設定
設定
型別
預設期限比上限長會拒絕啟動。