| 13 | const TEST_DATA_DIR = path.join(__dirname, '../cdn-proxy'); |
| 14 | |
| 15 | export async function runSandpackCDNProxy(): Promise<TestServerReturnType> { |
| 16 | const serverReady = new DeferredPromise<TestServerReturnType>(); |
| 17 | const app = setupApp(); |
| 18 | app.log.level = 'error'; |
| 19 | |
| 20 | app.get('/*', async (req, res) => { |
| 21 | console.log(`CDN Proxy: ${req.url}`); |
| 22 | const targetPath = path.join(TEST_DATA_DIR, req.url); |
| 23 | const dirname = path.dirname(targetPath); |
| 24 | try { |
| 25 | await fs.mkdir(dirname, { recursive: true }); |
| 26 | } catch (err) { |
| 27 | // do nothing |
| 28 | } |
| 29 | // Long cache ttl does not matter as it's only for tests and fetching should be near-instant |
| 30 | res.header('cache-control', 'public, max-age=900'); |
| 31 | res.header('access-control-allow-origin', '*'); |
| 32 | res.header('access-control-allow-headers', '*'); |
| 33 | res.header('access-control-allow-methods', 'GET, POST, OPTIONS'); |
| 34 | try { |
| 35 | const existingResponse = await fs.readFile(targetPath); |
| 36 | res.send(existingResponse); |
| 37 | console.log(`Served ${req.url} from local cache`); |
| 38 | } catch (err) { |
| 39 | console.log(`Fetching ${req.url} from remote`); |
| 40 | const response = await fetch('https://sandpack-cdn-v2.codesandbox.io' + req.url); |
| 41 | const buf = await response.buffer(); |
| 42 | await fs.writeFile(targetPath, buf); |
| 43 | console.log(`Served ${req.url} from remote`); |
| 44 | res.send(buf); |
| 45 | } |
| 46 | }); |
| 47 | |
| 48 | app.listen({ port: 3500 }, (error, address) => { |
| 49 | if (error) { |
| 50 | app.log.error(error); |
| 51 | serverReady.reject(error); |
| 52 | return; |
| 53 | } |
| 54 | |
| 55 | serverReady.resolve({ app, address }); |
| 56 | }); |
| 57 | |
| 58 | return serverReady; |
| 59 | } |