This repository has been archived on 2024-01-28. You can view files and clone it, but cannot push or open issues/pull-requests.
gdcdn/index.js

98 lines
2.5 KiB
JavaScript

// 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'
}
})
})
)
})