diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2023-09-18 17:40:01 -0400 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2023-09-18 17:40:01 -0400 |
commit | 013f25f01e729feee5db94900c61f4be4dd46869 (patch) | |
tree | 765dd5f2e06d6217ca79438e1098cefc8da627bf /src/server/server_Initialization.ts | |
parent | f5e765adff1e7b32250eb503c9724a4ac99117f3 (diff) | |
parent | 84aa8806a62e2e957e8281d7d492139e3d8225f2 (diff) |
Merge branch 'master' into sophie-report-manager
Diffstat (limited to 'src/server/server_Initialization.ts')
-rw-r--r-- | src/server/server_Initialization.ts | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index c1934451c..839091194 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -100,7 +100,7 @@ function buildWithMiddleware(server: express.Express) { passport.session(), (req: express.Request, res: express.Response, next: express.NextFunction) => { res.locals.user = req.user; - if (req.originalUrl.endsWith('.png') /*|| req.originalUrl.endsWith(".js")*/ && req.method === 'GET' && (res as any)._contentLength) { + if ((req.originalUrl.endsWith('.png') || req.originalUrl.endsWith('.jpg') || (process.env.RELEASE === 'true' && req.originalUrl.endsWith('.js'))) && req.method === 'GET') { const period = 30000; res.set('Cache-control', `public, max-age=${period}`); } else { @@ -149,53 +149,78 @@ function registerAuthenticationRoutes(server: express.Express) { function registerCorsProxy(server: express.Express) { server.use('/corsProxy', async (req, res) => { - //const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : ''; - let requrl = decodeURIComponent(req.url.substring(1)); - const qsplit = requrl.split('?q='); - const newqsplit = requrl.split('&q='); + res.setHeader('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE'); + res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers')); + const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : ''; + let requrlraw = decodeURIComponent(req.url.substring(1)); + const qsplit = requrlraw.split('?q='); + const newqsplit = requrlraw.split('&q='); if (qsplit.length > 1 && newqsplit.length > 1) { const lastq = newqsplit[newqsplit.length - 1]; - requrl = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1]; + requrlraw = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1]; + } + const requrl = requrlraw.startsWith('/') ? referer + requrlraw : requrlraw; + // cors weirdness here... + // if the referer is a cors page and the cors() route (I think) redirected to /corsProxy/<path> and the requested url path was relative, + // then we redirect again to the cors referer and just add the relative path. + if (!requrl.startsWith('http') && req.originalUrl.startsWith('/corsProxy') && referer?.includes('corsProxy')) { + res.redirect(referer + (referer.endsWith('/') ? '' : '/') + requrl); + } else { + proxyServe(req, requrl, res); } - proxyServe(req, requrl, res); }); } function proxyServe(req: any, requrl: string, response: any) { const htmlBodyMemoryStream = new (require('memorystream'))(); - var retrieveHTTPBody: any; var wasinBrFormat = false; const sendModifiedBody = () => { const header = response.headers['content-encoding']; - const httpsToCors = (match: any, href: string, offset: any, string: any) => `href="${resolvedServerUrl + '/corsProxy/http' + href}"`; - if (header?.includes('gzip')) { + const refToCors = (match: any, tag: string, sym: string, href: string, offset: any, string: any) => `${tag}=${sym + resolvedServerUrl}/corsProxy/${href + sym}`; + const relpathToCors = (match: any, href: string, offset: any, string: any) => `="${resolvedServerUrl + '/corsProxy/' + decodeURIComponent(req.originalUrl.split('/corsProxy/')[1].match(/https?:\/\/[^\/]*/)?.[0] ?? '') + '/' + href}"`; + if (header) { try { const bodyStream = htmlBodyMemoryStream.read(); if (bodyStream) { - const htmlInputText = wasinBrFormat ? Buffer.from(brotli.decompress(bodyStream)) : zlib.gunzipSync(bodyStream); + const htmlInputText = wasinBrFormat ? Buffer.from(brotli.decompress(bodyStream)) : header.includes('gzip') ? zlib.gunzipSync(bodyStream) : bodyStream; const htmlText = htmlInputText .toString('utf8') .replace('<head>', '<head> <style>[id ^= "google"] { display: none; } </style>') - // .replace(/href="https?([^"]*)"/g, httpsToCors) + .replace(/(src|href)=([\'\"])(https?[^\2\n]*)\1/g, refToCors) // replace src or href='http(s)://...' or href="http(s)://.." + //.replace(/= *"\/([^"]*)"/g, relpathToCors) .replace(/data-srcset="[^"]*"/g, '') .replace(/srcset="[^"]*"/g, '') .replace(/target="_blank"/g, ''); - response.send(zlib.gzipSync(htmlText)); + response.send(header?.includes('gzip') ? zlib.gzipSync(htmlText) : htmlText); } else { - req.pipe(request(requrl)).pipe(response); + req.pipe(request(requrl)) + .on('error', (e: any) => console.log('requrl ', e)) + .pipe(response) + .on('error', (e: any) => console.log('response pipe error', e)); console.log('EMPTY body:' + req.url); } } catch (e) { console.log('ERROR?: ', e); } } else { - req.pipe(htmlBodyMemoryStream).pipe(response); + req.pipe(htmlBodyMemoryStream) + .on('error', (e: any) => console.log('html body memorystream error', e)) + .pipe(response) + .on('error', (e: any) => console.log('html body memory stream response error', e)); } }; - retrieveHTTPBody = () => { - req.headers.cookie = ''; + const retrieveHTTPBody = () => { + //req.headers.cookie = ''; req.pipe(request(requrl)) - .on('error', (e: any) => console.log(`Malformed CORS url: ${requrl}`, e)) + .on('error', (e: any) => { + console.log(`CORS url error: ${requrl}`, e); + response.send(`<html><body bgcolor="red" link="006666" alink="8B4513" vlink="006666"> + <title>Error</title> + <div align="center"><h1>Failed to load: ${requrl} </h1></div> + <p>${e}</p> + </body></html>`); + }) .on('response', (res: any) => { res.headers; const headers = Object.keys(res.headers); @@ -218,16 +243,18 @@ function proxyServe(req: any, requrl: string, response: any) { response.headers = response._headers = res.headers; }) .on('end', sendModifiedBody) - .pipe(htmlBodyMemoryStream); + .pipe(htmlBodyMemoryStream) + .on('error', (e: any) => console.log('http body pipe error', e)); }; retrieveHTTPBody(); } function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { server.use('*', (req, res) => { + // res.setHeader('Access-Control-Allow-Origin', '*'); + // res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE'); + // res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers')); const relativeUrl = req.originalUrl; - // if (req.originalUrl === '/css/main.css' || req.originalUrl === '/favicon.ico') res.end(); - // else if (!res.headersSent && req.headers.referer?.includes('corsProxy')) { if (!req.user) res.redirect('/home'); // When no user is logged in, we interpret a relative URL as being a reference to something they don't have access to and redirect to /home // a request for something by a proxied referrer means it must be a relative reference. So construct a proxied absolute reference here. @@ -237,8 +264,8 @@ function registerEmbeddedBrowseRelativePathHandler(server: express.Express) { const actualReferUrl = proxiedRefererUrl.replace(dashServerUrl, ''); // the url of the referer without the proxy (e.g., : https://en.wikipedia.org/wiki/Engelbart) const absoluteTargetBaseUrl = actualReferUrl.match(/https?:\/\/[^\/]*/)![0]; // the base of the original url (e.g., https://en.wikipedia.org) const redirectedProxiedUrl = dashServerUrl + encodeURIComponent(absoluteTargetBaseUrl + relativeUrl); // the new proxied full url (e.g., http://localhost:<port>/corsProxy/https://en.wikipedia.org/<somethingelse>) - if (relativeUrl.startsWith('//')) res.redirect('http:' + relativeUrl); - else res.redirect(redirectedProxiedUrl); + const redirectUrl = relativeUrl.startsWith('//') ? 'http:' + relativeUrl : redirectedProxiedUrl; + res.redirect(redirectUrl); } catch (e) { console.log('Error embed: ', e); } |