[{"data":1,"prerenderedAt":1362},["ShallowReactive",2],{"navigation":3,"\u002Fextensions\u002Fupload":70,"\u002Fextensions\u002Fupload-surround":1357},[4,25,55],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Building FrankenPHP","\u002Fgetting-started\u002Fbuilding-frankenphp","1.getting-started\u002F3.building-frankenphp","i-lucide-hammer",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Extensions","\u002Fextensions","2.extensions",[30,35,40,45,50],{"title":31,"path":32,"stem":33,"icon":34},"Queue","\u002Fextensions\u002Fqueue","2.extensions\u002F1.queue","i-lucide-list-checks",{"title":36,"path":37,"stem":38,"icon":39},"Scheduler","\u002Fextensions\u002Fscheduler","2.extensions\u002F2.scheduler","i-lucide-calendar-clock",{"title":41,"path":42,"stem":43,"icon":44},"Pogo","\u002Fextensions\u002Fpogo","2.extensions\u002F3.pogo","i-lucide-split",{"title":46,"path":47,"stem":48,"icon":49},"WebSocket","\u002Fextensions\u002Fwebsocket","2.extensions\u002F4.websocket","i-lucide-radio",{"title":51,"path":52,"stem":53,"icon":54},"Upload","\u002Fextensions\u002Fupload","2.extensions\u002F5.upload","i-lucide-upload",{"title":56,"icon":6,"path":57,"stem":58,"children":59,"page":6},"Reference","\u002Freference","3.reference",[60,65],{"title":61,"path":62,"stem":63,"icon":64},"Caddy Reference","\u002Freference\u002Fcaddy","3.reference\u002F1.caddy","i-lucide-settings-2",{"title":66,"path":67,"stem":68,"icon":69},"PHP API","\u002Freference\u002Fphp-api","3.reference\u002F2.php-api","i-lucide-file-code-2",{"id":71,"title":51,"body":72,"description":1350,"extension":1351,"links":1352,"meta":1353,"navigation":1354,"path":52,"seo":1355,"stem":53,"__hash__":1356},"docs\u002F2.extensions\u002F5.upload.md",{"type":73,"value":74,"toc":1339},"minimark",[75,80,84,87,91,94,97,113,116,135,139,142,198,202,208,381,384,574,578,581,584,651,662,665,690,693,802,808,812,815,818,1052,1055,1227,1230,1257,1264,1268,1288,1292,1335],[76,77,79],"h2",{"id":78},"overview","Overview",[81,82,83],"p",{},"Pogo Upload lets PHP applications create signed upload intents while a Caddy\u002FGo handler receives the raw request body, enforces limits, writes to storage, computes a checksum, and notifies a PHP worker when the upload completes or fails.",[81,85,86],{},"It is for large or controlled single-file uploads. It is not a file manager, media processor, CDN, object-storage abstraction, virus scanner, or replacement for normal framework uploads for small forms.",[76,88,90],{"id":89},"status-and-fit","Status and fit",[81,92,93],{},"Pogo Upload is experimental. Its v1 module has a local filesystem backend and process-local progress tracking.",[81,95,96],{},"Use it when:",[98,99,100,104,107,110],"ul",{},[101,102,103],"li",{},"A normal authenticated controller should authorize and create upload intents.",[101,105,106],{},"PHP should avoid spending request time moving large upload bodies.",[101,108,109],{},"One raw file per request is enough.",[101,111,112],{},"Your completion handler can be idempotent.",[81,114,115],{},"Avoid it when:",[98,117,118,121,124,127],{},[101,119,120],{},"You need multipart form parsing.",[101,122,123],{},"You need durable distributed progress.",[101,125,126],{},"You need antivirus scanning, media processing, or CDN publishing in the module.",[101,128,129,130,134],{},"Your framework needs to receive an ",[131,132,133],"code",{},"UploadedFile"," object directly.",[76,136,138],{"id":137},"build","Build",[81,140,141],{},"Compile the module into FrankenPHP:",[143,144,150],"pre",{"className":145,"code":146,"filename":147,"language":148,"meta":149,"style":149},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","xcaddy build \\\n  --with github.com\u002Fdunglas\u002Ffrankenphp@v1.12.4 \\\n  --with github.com\u002Fdunglas\u002Ffrankenphp\u002Fcaddy@v1.12.4 \\\n  --with github.com\u002Fy-l-g\u002Fupload\u002Fmodule@master\n","Terminal","bash","",[131,151,152,169,180,190],{"__ignoreMap":149},[153,154,157,161,165],"span",{"class":155,"line":156},"line",1,[153,158,160],{"class":159},"sBMFI","xcaddy",[153,162,164],{"class":163},"sfazB"," build",[153,166,168],{"class":167},"sTEyZ"," \\\n",[153,170,172,175,178],{"class":155,"line":171},2,[153,173,174],{"class":163},"  --with",[153,176,177],{"class":163}," github.com\u002Fdunglas\u002Ffrankenphp@v1.12.4",[153,179,168],{"class":167},[153,181,183,185,188],{"class":155,"line":182},3,[153,184,174],{"class":163},[153,186,187],{"class":163}," github.com\u002Fdunglas\u002Ffrankenphp\u002Fcaddy@v1.12.4",[153,189,168],{"class":167},[153,191,193,195],{"class":155,"line":192},4,[153,194,174],{"class":163},[153,196,197],{"class":163}," github.com\u002Fy-l-g\u002Fupload\u002Fmodule@master\n",[76,199,201],{"id":200},"caddy-configuration","Caddy configuration",[81,203,204,207],{},[131,205,206],{},"pogo_upload"," has two parts: a global app that defines stores, and an HTTP handler that accepts signed upload URLs for one store.",[143,209,214],{"className":210,"code":211,"filename":212,"language":213,"meta":149,"style":149},"language-caddyfile shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  frankenphp\n\n  pogo_upload {\n    store default {\n      worker public\u002Fupload-worker.php\n      signing_secret {$POGO_UPLOAD_SECRET}\n\n      backend local {\n        root storage\u002Fapp\u002Fpogo-uploads\n      }\n\n      token_ttl 15m\n      max_upload_bytes 1073741824\n      max_concurrency 32\n      read_timeout 30s\n      complete_timeout 10s\n      progress_ttl 10m\n    }\n  }\n}\n\n:80 {\n  handle \u002F_pogo\u002Fupload\u002F* {\n    pogo_upload default\n  }\n\n  php_server\n}\n","Caddyfile","caddyfile",[131,215,216,221,226,232,237,243,249,255,260,266,272,278,283,289,295,301,307,313,319,325,331,337,342,348,354,360,365,370,376],{"__ignoreMap":149},[153,217,218],{"class":155,"line":156},[153,219,220],{},"{\n",[153,222,223],{"class":155,"line":171},[153,224,225],{},"  frankenphp\n",[153,227,228],{"class":155,"line":182},[153,229,231],{"emptyLinePlaceholder":230},true,"\n",[153,233,234],{"class":155,"line":192},[153,235,236],{},"  pogo_upload {\n",[153,238,240],{"class":155,"line":239},5,[153,241,242],{},"    store default {\n",[153,244,246],{"class":155,"line":245},6,[153,247,248],{},"      worker public\u002Fupload-worker.php\n",[153,250,252],{"class":155,"line":251},7,[153,253,254],{},"      signing_secret {$POGO_UPLOAD_SECRET}\n",[153,256,258],{"class":155,"line":257},8,[153,259,231],{"emptyLinePlaceholder":230},[153,261,263],{"class":155,"line":262},9,[153,264,265],{},"      backend local {\n",[153,267,269],{"class":155,"line":268},10,[153,270,271],{},"        root storage\u002Fapp\u002Fpogo-uploads\n",[153,273,275],{"class":155,"line":274},11,[153,276,277],{},"      }\n",[153,279,281],{"class":155,"line":280},12,[153,282,231],{"emptyLinePlaceholder":230},[153,284,286],{"class":155,"line":285},13,[153,287,288],{},"      token_ttl 15m\n",[153,290,292],{"class":155,"line":291},14,[153,293,294],{},"      max_upload_bytes 1073741824\n",[153,296,298],{"class":155,"line":297},15,[153,299,300],{},"      max_concurrency 32\n",[153,302,304],{"class":155,"line":303},16,[153,305,306],{},"      read_timeout 30s\n",[153,308,310],{"class":155,"line":309},17,[153,311,312],{},"      complete_timeout 10s\n",[153,314,316],{"class":155,"line":315},18,[153,317,318],{},"      progress_ttl 10m\n",[153,320,322],{"class":155,"line":321},19,[153,323,324],{},"    }\n",[153,326,328],{"class":155,"line":327},20,[153,329,330],{},"  }\n",[153,332,334],{"class":155,"line":333},21,[153,335,336],{},"}\n",[153,338,340],{"class":155,"line":339},22,[153,341,231],{"emptyLinePlaceholder":230},[153,343,345],{"class":155,"line":344},23,[153,346,347],{},":80 {\n",[153,349,351],{"class":155,"line":350},24,[153,352,353],{},"  handle \u002F_pogo\u002Fupload\u002F* {\n",[153,355,357],{"class":155,"line":356},25,[153,358,359],{},"    pogo_upload default\n",[153,361,363],{"class":155,"line":362},26,[153,364,330],{},[153,366,368],{"class":155,"line":367},27,[153,369,231],{"emptyLinePlaceholder":230},[153,371,373],{"class":155,"line":372},28,[153,374,375],{},"  php_server\n",[153,377,379],{"class":155,"line":378},29,[153,380,336],{},[81,382,383],{},"Store directives:",[385,386,387,406],"table",{},[388,389,390],"thead",{},[391,392,393,397,400,403],"tr",{},[394,395,396],"th",{},"Directive",[394,398,399],{},"Required",[394,401,402],{},"Default",[394,404,405],{},"Description",[407,408,409,426,440,457,471,489,506,523,540,557],"tbody",{},[391,410,411,417,420,423],{},[412,413,414],"td",{},[131,415,416],{},"worker",[412,418,419],{},"Yes",[412,421,422],{},"none",[412,424,425],{},"PHP worker script that receives completion and failure events.",[391,427,428,433,435,437],{},[412,429,430],{},[131,431,432],{},"signing_secret",[412,434,419],{},[412,436,422],{},[412,438,439],{},"Secret used to sign upload URLs. Keep it stable across reloads and replicas.",[391,441,442,447,449,454],{},[412,443,444],{},[131,445,446],{},"backend local",[412,448,419],{},[412,450,451],{},[131,452,453],{},"local",[412,455,456],{},"The v1 storage backend.",[391,458,459,464,466,468],{},[412,460,461],{},[131,462,463],{},"root",[412,465,419],{},[412,467,422],{},[412,469,470],{},"Local backend root directory.",[391,472,473,478,481,486],{},[412,474,475],{},[131,476,477],{},"token_ttl",[412,479,480],{},"No",[412,482,483],{},[131,484,485],{},"15m",[412,487,488],{},"Default signed URL lifetime.",[391,490,491,496,498,503],{},[412,492,493],{},[131,494,495],{},"max_upload_bytes",[412,497,480],{},[412,499,500],{},[131,501,502],{},"1073741824",[412,504,505],{},"Store-level hard upload limit.",[391,507,508,513,515,520],{},[412,509,510],{},[131,511,512],{},"max_concurrency",[412,514,480],{},[412,516,517],{},[131,518,519],{},"32",[412,521,522],{},"Max in-flight uploads for the store.",[391,524,525,530,532,537],{},[412,526,527],{},[131,528,529],{},"read_timeout",[412,531,480],{},[412,533,534],{},[131,535,536],{},"30s",[412,538,539],{},"Max idle time while reading the request body.",[391,541,542,547,549,554],{},[412,543,544],{},[131,545,546],{},"complete_timeout",[412,548,480],{},[412,550,551],{},[131,552,553],{},"10s",[412,555,556],{},"Max wait for the PHP completion worker.",[391,558,559,564,566,571],{},[412,560,561],{},[131,562,563],{},"progress_ttl",[412,565,480],{},[412,567,568],{},[131,569,570],{},"10m",[412,572,573],{},"Time finished progress records remain visible.",[76,575,577],{"id":576},"application-integration","Application integration",[81,579,580],{},"The current repository exposes native PHP functions directly. Framework services can wrap these functions, but no Laravel or Symfony upload package is shipped here yet.",[81,582,583],{},"Create an upload intent from a normal authenticated controller:",[143,585,589],{"className":586,"code":587,"language":588,"meta":149,"style":149},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$intent = pogo_upload_create([\n    'key' => 'users\u002F'.$userId.'\u002Favatars\u002F'.$uuid.'.jpg',\n    'filename' => 'avatar.jpg',\n    'content_types' => ['image\u002Fjpeg', 'image\u002Fpng'],\n    'max_bytes' => 5242880,\n    'overwrite' => false,\n    'expires_in' => 900,\n    'metadata' => [\n        'user_id' => (string) $userId,\n        'purpose' => 'avatar',\n    ],\n]);\n","php",[131,590,591,596,601,606,611,616,621,626,631,636,641,646],{"__ignoreMap":149},[153,592,593],{"class":155,"line":156},[153,594,595],{},"$intent = pogo_upload_create([\n",[153,597,598],{"class":155,"line":171},[153,599,600],{},"    'key' => 'users\u002F'.$userId.'\u002Favatars\u002F'.$uuid.'.jpg',\n",[153,602,603],{"class":155,"line":182},[153,604,605],{},"    'filename' => 'avatar.jpg',\n",[153,607,608],{"class":155,"line":192},[153,609,610],{},"    'content_types' => ['image\u002Fjpeg', 'image\u002Fpng'],\n",[153,612,613],{"class":155,"line":239},[153,614,615],{},"    'max_bytes' => 5242880,\n",[153,617,618],{"class":155,"line":245},[153,619,620],{},"    'overwrite' => false,\n",[153,622,623],{"class":155,"line":251},[153,624,625],{},"    'expires_in' => 900,\n",[153,627,628],{"class":155,"line":257},[153,629,630],{},"    'metadata' => [\n",[153,632,633],{"class":155,"line":262},[153,634,635],{},"        'user_id' => (string) $userId,\n",[153,637,638],{"class":155,"line":268},[153,639,640],{},"        'purpose' => 'avatar',\n",[153,642,643],{"class":155,"line":274},[153,644,645],{},"    ],\n",[153,647,648],{"class":155,"line":280},[153,649,650],{},"]);\n",[81,652,653,654,657,658,661],{},"The client uploads one raw file body to the returned ",[131,655,656],{},"url"," with the returned HTTP ",[131,659,660],{},"method",".",[76,663,66],{"id":664},"php-api",[143,666,668],{"className":586,"code":667,"language":588,"meta":149,"style":149},"pogo_upload_create(array $intent, string $store = 'default'): array;\npogo_upload_progress(string $uploadId, string $store = 'default'): ?array;\npogo_upload_cancel(string $uploadId, string $store = 'default'): bool;\npogo_upload_status(?string $store = null): string;\n",[131,669,670,675,680,685],{"__ignoreMap":149},[153,671,672],{"class":155,"line":156},[153,673,674],{},"pogo_upload_create(array $intent, string $store = 'default'): array;\n",[153,676,677],{"class":155,"line":171},[153,678,679],{},"pogo_upload_progress(string $uploadId, string $store = 'default'): ?array;\n",[153,681,682],{"class":155,"line":182},[153,683,684],{},"pogo_upload_cancel(string $uploadId, string $store = 'default'): bool;\n",[153,686,687],{"class":155,"line":192},[153,688,689],{},"pogo_upload_status(?string $store = null): string;\n",[81,691,692],{},"Intent fields:",[385,694,695,706],{},[388,696,697],{},[391,698,699,702,704],{},[394,700,701],{},"Field",[394,703,399],{},[394,705,405],{},[407,707,708,720,732,748,760,776,790],{},[391,709,710,715,717],{},[412,711,712],{},[131,713,714],{},"key",[412,716,419],{},[412,718,719],{},"Backend object key. Must be relative and normalized.",[391,721,722,727,729],{},[412,723,724],{},[131,725,726],{},"filename",[412,728,480],{},[412,730,731],{},"Original filename for application metadata.",[391,733,734,739,741],{},[412,735,736],{},[131,737,738],{},"content_types",[412,740,480],{},[412,742,743,744,747],{},"Accepted request ",[131,745,746],{},"Content-Type"," values.",[391,749,750,755,757],{},[412,751,752],{},[131,753,754],{},"max_bytes",[412,756,419],{},[412,758,759],{},"Positive maximum body size.",[391,761,762,767,769],{},[412,763,764],{},[131,765,766],{},"overwrite",[412,768,480],{},[412,770,771,772,775],{},"Defaults to ",[131,773,774],{},"false","; rejects existing final keys when false.",[391,777,778,783,785],{},[412,779,780],{},[131,781,782],{},"expires_in",[412,784,480],{},[412,786,787,788,661],{},"Signed URL lifetime in seconds. Defaults to store ",[131,789,477],{},[391,791,792,797,799],{},[412,793,794],{},[131,795,796],{},"metadata",[412,798,480],{},[412,800,801],{},"String map returned unchanged in worker events.",[81,803,804,807],{},[131,805,806],{},"pogo_upload_status()"," returns JSON with readiness, configured limits, active upload counts, completed\u002Ffailed\u002Fcancelled counters, token\u002Fcontent-type\u002Fsize rejections, bytes received, backend failures, and worker event failures.",[76,809,811],{"id":810},"worker-events","Worker events",[81,813,814],{},"The worker is a normal FrankenPHP worker script that receives JSON and returns JSON.",[81,816,817],{},"Completed event:",[143,819,823],{"className":820,"code":821,"language":822,"meta":149,"style":149},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"type\": \"completed\",\n  \"upload_id\": \"upl_01jz2k4v4x9s8m1px6h0y7f2am\",\n  \"store\": \"default\",\n  \"key\": \"users\u002F123\u002Fuploads\u002Favatar.jpg\",\n  \"filename\": \"avatar.jpg\",\n  \"content_type\": \"image\u002Fjpeg\",\n  \"bytes\": 428129,\n  \"sha256\": \"1ecb9f...\",\n  \"metadata\": {\n    \"user_id\": \"123\",\n    \"purpose\": \"avatar\"\n  }\n}\n","json",[131,824,825,830,856,876,896,915,934,954,971,991,1004,1025,1044,1048],{"__ignoreMap":149},[153,826,827],{"class":155,"line":156},[153,828,220],{"class":829},"sMK4o",[153,831,832,835,839,842,845,848,851,853],{"class":155,"line":171},[153,833,834],{"class":829},"  \"",[153,836,838],{"class":837},"spNyl","type",[153,840,841],{"class":829},"\"",[153,843,844],{"class":829},":",[153,846,847],{"class":829}," \"",[153,849,850],{"class":163},"completed",[153,852,841],{"class":829},[153,854,855],{"class":829},",\n",[153,857,858,860,863,865,867,869,872,874],{"class":155,"line":182},[153,859,834],{"class":829},[153,861,862],{"class":837},"upload_id",[153,864,841],{"class":829},[153,866,844],{"class":829},[153,868,847],{"class":829},[153,870,871],{"class":163},"upl_01jz2k4v4x9s8m1px6h0y7f2am",[153,873,841],{"class":829},[153,875,855],{"class":829},[153,877,878,880,883,885,887,889,892,894],{"class":155,"line":192},[153,879,834],{"class":829},[153,881,882],{"class":837},"store",[153,884,841],{"class":829},[153,886,844],{"class":829},[153,888,847],{"class":829},[153,890,891],{"class":163},"default",[153,893,841],{"class":829},[153,895,855],{"class":829},[153,897,898,900,902,904,906,908,911,913],{"class":155,"line":239},[153,899,834],{"class":829},[153,901,714],{"class":837},[153,903,841],{"class":829},[153,905,844],{"class":829},[153,907,847],{"class":829},[153,909,910],{"class":163},"users\u002F123\u002Fuploads\u002Favatar.jpg",[153,912,841],{"class":829},[153,914,855],{"class":829},[153,916,917,919,921,923,925,927,930,932],{"class":155,"line":245},[153,918,834],{"class":829},[153,920,726],{"class":837},[153,922,841],{"class":829},[153,924,844],{"class":829},[153,926,847],{"class":829},[153,928,929],{"class":163},"avatar.jpg",[153,931,841],{"class":829},[153,933,855],{"class":829},[153,935,936,938,941,943,945,947,950,952],{"class":155,"line":251},[153,937,834],{"class":829},[153,939,940],{"class":837},"content_type",[153,942,841],{"class":829},[153,944,844],{"class":829},[153,946,847],{"class":829},[153,948,949],{"class":163},"image\u002Fjpeg",[153,951,841],{"class":829},[153,953,855],{"class":829},[153,955,956,958,961,963,965,969],{"class":155,"line":257},[153,957,834],{"class":829},[153,959,960],{"class":837},"bytes",[153,962,841],{"class":829},[153,964,844],{"class":829},[153,966,968],{"class":967},"sbssI"," 428129",[153,970,855],{"class":829},[153,972,973,975,978,980,982,984,987,989],{"class":155,"line":262},[153,974,834],{"class":829},[153,976,977],{"class":837},"sha256",[153,979,841],{"class":829},[153,981,844],{"class":829},[153,983,847],{"class":829},[153,985,986],{"class":163},"1ecb9f...",[153,988,841],{"class":829},[153,990,855],{"class":829},[153,992,993,995,997,999,1001],{"class":155,"line":268},[153,994,834],{"class":829},[153,996,796],{"class":837},[153,998,841],{"class":829},[153,1000,844],{"class":829},[153,1002,1003],{"class":829}," {\n",[153,1005,1006,1009,1012,1014,1016,1018,1021,1023],{"class":155,"line":274},[153,1007,1008],{"class":829},"    \"",[153,1010,1011],{"class":159},"user_id",[153,1013,841],{"class":829},[153,1015,844],{"class":829},[153,1017,847],{"class":829},[153,1019,1020],{"class":163},"123",[153,1022,841],{"class":829},[153,1024,855],{"class":829},[153,1026,1027,1029,1032,1034,1036,1038,1041],{"class":155,"line":280},[153,1028,1008],{"class":829},[153,1030,1031],{"class":159},"purpose",[153,1033,841],{"class":829},[153,1035,844],{"class":829},[153,1037,847],{"class":829},[153,1039,1040],{"class":163},"avatar",[153,1042,1043],{"class":829},"\"\n",[153,1045,1046],{"class":155,"line":285},[153,1047,330],{"class":829},[153,1049,1050],{"class":155,"line":291},[153,1051,336],{"class":829},[81,1053,1054],{},"Failure event:",[143,1056,1058],{"className":820,"code":1057,"language":822,"meta":149,"style":149},"{\n  \"type\": \"failed\",\n  \"upload_id\": \"upl_01jz2k4v4x9s8m1px6h0y7f2am\",\n  \"store\": \"default\",\n  \"key\": \"users\u002F123\u002Fuploads\u002Favatar.jpg\",\n  \"reason\": \"client_aborted\",\n  \"bytes_received\": 1048576,\n  \"metadata\": {\n    \"user_id\": \"123\",\n    \"purpose\": \"avatar\"\n  }\n}\n",[131,1059,1060,1064,1083,1101,1119,1137,1157,1173,1185,1203,1219,1223],{"__ignoreMap":149},[153,1061,1062],{"class":155,"line":156},[153,1063,220],{"class":829},[153,1065,1066,1068,1070,1072,1074,1076,1079,1081],{"class":155,"line":171},[153,1067,834],{"class":829},[153,1069,838],{"class":837},[153,1071,841],{"class":829},[153,1073,844],{"class":829},[153,1075,847],{"class":829},[153,1077,1078],{"class":163},"failed",[153,1080,841],{"class":829},[153,1082,855],{"class":829},[153,1084,1085,1087,1089,1091,1093,1095,1097,1099],{"class":155,"line":182},[153,1086,834],{"class":829},[153,1088,862],{"class":837},[153,1090,841],{"class":829},[153,1092,844],{"class":829},[153,1094,847],{"class":829},[153,1096,871],{"class":163},[153,1098,841],{"class":829},[153,1100,855],{"class":829},[153,1102,1103,1105,1107,1109,1111,1113,1115,1117],{"class":155,"line":192},[153,1104,834],{"class":829},[153,1106,882],{"class":837},[153,1108,841],{"class":829},[153,1110,844],{"class":829},[153,1112,847],{"class":829},[153,1114,891],{"class":163},[153,1116,841],{"class":829},[153,1118,855],{"class":829},[153,1120,1121,1123,1125,1127,1129,1131,1133,1135],{"class":155,"line":239},[153,1122,834],{"class":829},[153,1124,714],{"class":837},[153,1126,841],{"class":829},[153,1128,844],{"class":829},[153,1130,847],{"class":829},[153,1132,910],{"class":163},[153,1134,841],{"class":829},[153,1136,855],{"class":829},[153,1138,1139,1141,1144,1146,1148,1150,1153,1155],{"class":155,"line":245},[153,1140,834],{"class":829},[153,1142,1143],{"class":837},"reason",[153,1145,841],{"class":829},[153,1147,844],{"class":829},[153,1149,847],{"class":829},[153,1151,1152],{"class":163},"client_aborted",[153,1154,841],{"class":829},[153,1156,855],{"class":829},[153,1158,1159,1161,1164,1166,1168,1171],{"class":155,"line":251},[153,1160,834],{"class":829},[153,1162,1163],{"class":837},"bytes_received",[153,1165,841],{"class":829},[153,1167,844],{"class":829},[153,1169,1170],{"class":967}," 1048576",[153,1172,855],{"class":829},[153,1174,1175,1177,1179,1181,1183],{"class":155,"line":257},[153,1176,834],{"class":829},[153,1178,796],{"class":837},[153,1180,841],{"class":829},[153,1182,844],{"class":829},[153,1184,1003],{"class":829},[153,1186,1187,1189,1191,1193,1195,1197,1199,1201],{"class":155,"line":262},[153,1188,1008],{"class":829},[153,1190,1011],{"class":159},[153,1192,841],{"class":829},[153,1194,844],{"class":829},[153,1196,847],{"class":829},[153,1198,1020],{"class":163},[153,1200,841],{"class":829},[153,1202,855],{"class":829},[153,1204,1205,1207,1209,1211,1213,1215,1217],{"class":155,"line":268},[153,1206,1008],{"class":829},[153,1208,1031],{"class":159},[153,1210,841],{"class":829},[153,1212,844],{"class":829},[153,1214,847],{"class":829},[153,1216,1040],{"class":163},[153,1218,1043],{"class":829},[153,1220,1221],{"class":155,"line":274},[153,1222,330],{"class":829},[153,1224,1225],{"class":155,"line":280},[153,1226,336],{"class":829},[81,1228,1229],{},"Expected worker response:",[143,1231,1233],{"className":820,"code":1232,"language":822,"meta":149,"style":149},"{\n  \"ok\": true\n}\n",[131,1234,1235,1239,1253],{"__ignoreMap":149},[153,1236,1237],{"class":155,"line":156},[153,1238,220],{"class":829},[153,1240,1241,1243,1246,1248,1250],{"class":155,"line":171},[153,1242,834],{"class":829},[153,1244,1245],{"class":837},"ok",[153,1247,841],{"class":829},[153,1249,844],{"class":829},[153,1251,1252],{"class":829}," true\n",[153,1254,1255],{"class":155,"line":182},[153,1256,336],{"class":829},[81,1258,1259,1260,1263],{},"If the completed handler returns ",[131,1261,1262],{},"ok: false"," or times out, the module reports an upload failure to the client and attempts to delete the stored object. Failure event handler errors are logged and counted but do not change an already-failed HTTP response.",[76,1265,1267],{"id":1266},"operations","Operations",[98,1269,1270,1273,1276,1279,1282,1285],{},[101,1271,1272],{},"Treat returned upload URLs as bearer tokens.",[101,1274,1275],{},"Keep token TTLs short.",[101,1277,1278],{},"Use HTTPS in production.",[101,1280,1281],{},"Store objects outside the public web root unless the application explicitly publishes them.",[101,1283,1284],{},"Use shared signing secrets and storage roots when multiple replicas can accept uploads.",[101,1286,1287],{},"Do not expose object keys, token values, filenames, or metadata in metrics.",[76,1289,1291],{"id":1290},"troubleshooting","Troubleshooting",[98,1293,1294,1304,1315,1326],{},[101,1295,1296,1300,1301,1303],{},[1297,1298,1299],"strong",{},"Invalid token:"," check ",[131,1302,432],{},", expiry, and whether the client is using the returned upload URL unchanged.",[101,1305,1306,1309,1310,1312,1313,661],{},[1297,1307,1308],{},"Content type rejected:"," make sure the request ",[131,1311,746],{}," matches the intent's ",[131,1314,738],{},[101,1316,1317,1320,1321,1323,1324,661],{},[1297,1318,1319],{},"Upload too large:"," check both the intent ",[131,1322,754],{}," and store ",[131,1325,495],{},[101,1327,1328,1331,1332,1334],{},[1297,1329,1330],{},"Unknown progress:"," progress is process-local and can expire after ",[131,1333,563],{}," or disappear after restart.",[1336,1337,1338],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":149,"searchDepth":156,"depth":171,"links":1340},[1341,1342,1343,1344,1345,1346,1347,1348,1349],{"id":78,"depth":171,"text":79},{"id":89,"depth":171,"text":90},{"id":137,"depth":171,"text":138},{"id":200,"depth":171,"text":201},{"id":576,"depth":171,"text":577},{"id":664,"depth":171,"text":66},{"id":810,"depth":171,"text":811},{"id":1266,"depth":171,"text":1267},{"id":1290,"depth":171,"text":1291},"Signed single-file upload ingress for FrankenPHP applications.","md",null,{},{"icon":54},{"title":51,"description":1350},"UJUBcN3kSSi6Ew5d_ht7rtj0S3r6nMlXX3r_9PXTQKE",[1358,1360],{"title":46,"path":47,"stem":48,"description":1359,"icon":49,"children":-1},"Embedded Reverb\u002FPusher-compatible WebSocket runtime and Laravel broadcaster.",{"title":61,"path":62,"stem":63,"description":1361,"icon":64,"children":-1},"Directive overview for Queue, Scheduler, Pogo, Upload, and WebSocket.",1781517083513]