// vim: set noexpandtab: import mime from 'mime' import GoogleDrive from './googleDrive' self.props = { root_id: typeof(ROOT_ID) !== 'undefined' ? ROOT_ID : 'root', client_id: typeof(CLIENT_ID) !== 'undefined' ? CLIENT_ID : '202264815644.apps.googleusercontent.com', client_secret: typeof(CLIENT_SECRET) !== 'undefined' ? CLIENT_SECRET : 'X4Z3ca8xfWDb1Voo-F9a7ZxJ', refresh_token: typeof(REFRESH_TOKEN) !== 'undefined' ? REFRESH_TOKEN : '' // left here for debugging } const gd = new GoogleDrive(self.props) async function onGet(request) { let { pathname: path } = request const rootId = request.searchParams.get('rootId') || self.props.root_id const result = await gd.getMetaByPath(path, rootId) if (!result || result.mimeType.includes('vnd.google-apps')) { return new Response('404 Not Found', { headers: { 'Content-Type': 'text/plain' }, status: 404 }) } const r = await gd.download(result.id, request.headers.get('Range')) const h = new Headers(r.headers) h.set( 'Content-Disposition', `inline; filename*=UTF-8''${encodeURIComponent(result.name)}` ) return new Response(r.body, { status: r.status, headers: h }) } function encodePathComponent(path) { return path .split('/') .map(encodeURIComponent) .join('/') } async function handleRequest(request) { if (request.method === 'OPTIONS') // allow preflight request return new Response('', { status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS' } }) request = Object.assign({}, request, new URL(request.url)) request.pathname = request.pathname .split('/') .map(decodeURIComponent) .map(decodeURIComponent) // for some super special cases, browser will force encode it... eg: +αあるふぁきゅん。 - +♂.mp3 .join('/') if (request.pathname.endsWith('/')) request.pathname += 'index.html' let resp if (request.method === 'GET') resp = await onGet(request) else resp = new Response('', { status: 405 }) const obj = Object.create(null) for (const [k, v] of resp.headers.entries()) { obj[k] = v } return new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers: Object.assign(obj, { 'Access-Control-Allow-Origin': '*' }) }) } addEventListener('fetch', event => { event.respondWith( handleRequest(event.request).catch(err => { console.error(err) new Response(JSON.stringify(err.stack), { status: 500, headers: { 'Content-Type': 'application/json' } }) }) ) })