Skip to content

Instantly share code, notes, and snippets.

@leefsmp
Created February 24, 2017 13:44
Show Gist options
  • Save leefsmp/472ace57e421cc0a5083bd4b62b243d3 to your computer and use it in GitHub Desktop.
Save leefsmp/472ace57e421cc0a5083bd4b62b243d3 to your computer and use it in GitHub Desktop.
Forge Viewer secure proxy
/////////////////////////////////////////////////////////////////
// Forge Viewer proxy
// By Philippe Leefsma, February 2017
//
/////////////////////////////////////////////////////////////////
import ServiceManager from '../services/SvcManager'
import https from 'https'
import path from 'path'
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
const EXTENSIONS = {
gzip: [ '.json.gz', '.bin', '.pack' ],
json: [ '.json.gz', '.json' ]
}
const WHITE_LIST = [
'if-modified-since',
'if-none-match',
'accept-encoding',
'x-ads-acm-namespace', // Forge Data Management API
'x-ads-acm-check-groups' // Forge Data Management API
]
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
function fixContentHeaders (req, res) {
// DS does not return content-encoding header
// for gzip and other files that we know are gzipped,
// so we add it here. The viewer does want
// gzip files uncompressed by the browser
if ( EXTENSIONS.gzip.indexOf (path.extname (req.path)) > -1 ) {
res.set ('content-encoding', 'gzip')
}
if ( EXTENSIONS.json.indexOf (path.extname (req.path)) > -1 ){
res.set ('content-type', 'application/json')
}
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
function setCORSHeaders (res) {
res.set('access-control-allow-origin', '*')
res.set('access-control-allow-credentials', false)
res.set('access-control-allow-headers',
"Origin, X-Requested-With, Content-Type, Accept")
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
function proxyClientHeaders (clientHeaders, upstreamHeaders) {
WHITE_LIST.forEach(h => {
const hval = clientHeaders[h]
if (hval) {
upstreamHeaders[h] = hval
}
})
// fix for OSS issue not accepting the
// etag surrounded with double quotes...
const etag = upstreamHeaders['if-none-match']
if (etag) {
if(etag[0] === '"' && etag[etag.length - 1] === '"') {
upstreamHeaders['if-none-match'] =
etag.substring(1, etag.length - 1);
}
}
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
function Proxy(endpoint, authHeaders) {
this.authHeaders = authHeaders
this.endpoint = endpoint
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
Proxy.prototype.request = function(req, res, url) {
const options = {
host: this.endpoint,
port: 443,
path: url,
method: 'GET', //only proxy GET
headers: this.authHeaders
}
proxyClientHeaders(req.headers, options.headers)
const creq = https.request(options, (cres) => {
// set encoding
//cres.setEncoding('utf8');
for (let h in cres.headers) {
res.set(h, cres.headers[h])
}
fixContentHeaders(req, res)
setCORSHeaders(res)
res.writeHead(cres.statusCode)
cres.pipe(res)
cres.on('error', (e) => {
// we got an error,
// return error 500 to client and log error
debug.error(e.message)
res.end()
})
})
creq.end()
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
function proxyGet (req, res) {
const forgeSvc = ServiceManager.getService(
'ForgeSvc')
forgeSvc.get2LeggedToken().then((token) => {
const url = req.url.replace (/^\/lmv\-proxy/gm, '')
const endpoint = 'developer.api.autodesk.com'
const authHeaders = {
Authorization: `Bearer ${token.access_token}`
}
const proxy = new Proxy(endpoint, authHeaders)
proxy.request(req, res, url)
})
}
/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
exports.get = proxyGet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment