diff --git a/lib/uploader/uploader.ts b/lib/uploader/uploader.ts index af5e5190..0b4a8c92 100644 --- a/lib/uploader/uploader.ts +++ b/lib/uploader/uploader.ts @@ -474,10 +474,11 @@ export class Uploader { // We can cast here as we handled system entries in the if above const file = fileHandle as File - // If manually disabled or if the file is too small - // TODO: support chunk uploading in public pages + // @ts-expect-error TS2339 Object has no defined properties + const supportsPublicChunking = getCapabilities().dav?.public_shares_chunking ?? false const maxChunkSize = getMaxChunksSize('size' in file ? file.size : undefined) - const disabledChunkUpload = this._isPublic + // If manually disabled or if the file is too small + const disabledChunkUpload = (this._isPublic && !supportsPublicChunking) || maxChunkSize === 0 || ('size' in file && file.size < maxChunkSize) @@ -492,7 +493,7 @@ export class Uploader { logger.debug('Initializing chunked upload', { file, upload }) // Let's initialize a chunk upload - const tempUrl = await initChunkWorkspace(encodedDestinationFile, retries) + const tempUrl = await initChunkWorkspace(encodedDestinationFile, retries, this._isPublic) const chunksQueue: Array> = [] // Generate chunks array diff --git a/lib/utils/upload.ts b/lib/utils/upload.ts index 6b2f6cf9..5535f87c 100644 --- a/lib/utils/upload.ts +++ b/lib/utils/upload.ts @@ -3,10 +3,11 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import type { AxiosProgressEvent, AxiosResponse, AxiosError } from 'axios' -import { generateRemoteUrl } from '@nextcloud/router' +import { generateRemoteUrl, getBaseUrl } from '@nextcloud/router' import { getCurrentUser } from '@nextcloud/auth' import axios from '@nextcloud/axios' import axiosRetry, { exponentialDelay, isNetworkOrIdempotentRequestError } from 'axios-retry' +import { getSharingToken } from '@nextcloud/sharing/public' import logger from './logger' @@ -114,9 +115,16 @@ export const getChunk = function(file: File, start: number, length: number): Pro * Create a temporary upload workspace to upload the chunks to * @param destinationFile The file name after finishing the chunked upload * @param retries number of retries + * @param isPublic whether this upload is in a public share or not */ -export const initChunkWorkspace = async function(destinationFile: string | undefined = undefined, retries: number = 5): Promise { - const chunksWorkspace = generateRemoteUrl(`dav/uploads/${getCurrentUser()?.uid}`) +export const initChunkWorkspace = async function(destinationFile: string | undefined = undefined, retries: number = 5, isPublic: boolean = false): Promise { + let chunksWorkspace: string + if (isPublic) { + chunksWorkspace = `${getBaseUrl()}/public.php/dav/uploads/${getSharingToken()}` + } else { + chunksWorkspace = generateRemoteUrl(`dav/uploads/${getCurrentUser()?.uid}`) + } + const hash = [...Array(16)].map(() => Math.floor(Math.random() * 16).toString(16)).join('') const tempWorkspace = `web-file-upload-${hash}` const url = `${chunksWorkspace}/${tempWorkspace}`