download: use head for filename (nx)

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/653/head
Varun Patil 2023-05-08 20:34:24 -07:00
parent 7d1cf975aa
commit 1ffada41b1
2 changed files with 27 additions and 4 deletions

View File

@ -90,7 +90,11 @@ class DownloadController extends GenericApiController
$session = \OC::$server->get(ISession::class);
$key = "memories_download_{$handle}";
$info = $session->get($key);
// Remove handle from session unless HEAD request
if ('HEAD' !== $this->request->getMethod()) {
$session->remove($key);
}
if (null === $info) {
throw Exceptions::NotFound('handle');
@ -171,13 +175,17 @@ class DownloadController extends GenericApiController
$out->setHeader('Content-Type: '.$file->getMimeType());
// Make sure the browser downloads the file
$out->setHeader('Content-Disposition: attachment; filename="'.$file->getName().'"');
$filename = str_replace('"', '\\"', $file->getName());
$out->setHeader('Content-Disposition: attachment; filename="'.$filename.'"');
// Prevent output from being buffered
$out->setHeader('Content-Encoding: none');
$out->setHeader('X-Content-Encoded-By: none');
$out->setHeader('X-Accel-Buffering: no');
// Quit if HEAD request
if ('HEAD' === $this->request->getMethod()) return;
// Open file to send
$res = $file->fopen('rb');
@ -255,6 +263,9 @@ class DownloadController extends GenericApiController
// Create a zip file
$streamer->sendHeaders($name);
// Quit if HEAD request
if ('HEAD' === $this->request->getMethod()) return;
// Multiple files might have the same name
// So we need to add a number to the end of the name
$nameCounts = [];

View File

@ -1,3 +1,4 @@
import axios from '@nextcloud/axios';
import type { IDay, IPhoto } from './types';
const BASE_URL = 'http://127.0.0.1';
@ -17,7 +18,7 @@ export const API = {
export type NativeX = {
isNative: () => boolean;
setThemeColor: (color: string, isDark: boolean) => void;
downloadFromUrl: (url: string) => void;
downloadFromUrl: (url: string, filename: string) => void;
};
/** The native interface is a global object that is injected by the native app. */
@ -45,7 +46,18 @@ export const setTheme = (color?: string, dark?: boolean) => {
/**
* Download a file from the given URL.
*/
export const downloadFromUrl = (url: string) => nativex?.downloadFromUrl?.(url);
export const downloadFromUrl = async (url: string) => {
// Make HEAD request to get filename
const res = await axios.head(url);
let filename = res.headers['content-disposition'];
if (res.status !== 200 || !filename) return;
// Extract filename from header without quotes
filename = filename.split('filename="')[1].slice(0, -1);
// Hand off to download manager
nativex?.downloadFromUrl?.(url, filename);
};
/**
* Extend a list of days with local days.