Fixes for using OHIF Viewer against https site over DICOMWeb
This commit is contained in:
1 parent
143d65b8c8
commit
7ec1c60bc5
12 files changed
+179
-64
No files matched your search
@@ -0,0 +1,15 @@
|
||||
const querystring = require("querystring");
|
||||
|
||||
WADOProxy.convertURL = (url, serverConfiguration) => {
|
||||
if (!Settings.enabled) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const serverId = serverConfiguration._id;
|
||||
const query = querystring.stringify({url, serverId});
|
||||
return `${Settings.uri}?${query}`;
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Settings = Object.assign({
|
||||
uri : OHIF.utils.absoluteUrl("/__wado_proxy"),
|
||||
enabled: true
|
||||
}, (Meteor.settings && Meteor.settings.proxy) ? Meteor.settings.proxy : {});
|
||||
|
||||
http = require("http");
|
||||
url = require("url");
|
||||
querystring = require("querystring");
|
||||
}, (Meteor.settings && Meteor.settings.proxy) ? Meteor.settings.proxy : {});
|
||||
@@ -1,12 +1 @@
|
||||
WADOProxy = {};
|
||||
|
||||
WADOProxy.convertURL = (wadoURL, requestOptions) => {
|
||||
if (!Settings.enabled) {
|
||||
return wadoURL;
|
||||
}
|
||||
if (!wadoURL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Settings.uri + '?' + querystring.stringify({url: wadoURL, options: requestOptions ? JSON.stringify(requestOptions) : null});
|
||||
}
|
||||
WADOProxy = {};
|
||||
@@ -1,62 +1,132 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Router } from 'meteor/iron:router';
|
||||
import { Accounts } from 'meteor/accounts-base';
|
||||
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
const url = require("url");
|
||||
const http = require("http");
|
||||
const https = require("https");
|
||||
const querystring = require("querystring");
|
||||
|
||||
const doAuth = Meteor.users.find().count() ? true : false;
|
||||
|
||||
const authenticateUser = request => {
|
||||
// Only allow logged-in users to access this route
|
||||
const userId = request.headers['x-user-id']
|
||||
const loginToken = request.headers['x-auth-token']
|
||||
if (!userId || !loginToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hashedToken = Accounts._hashLoginToken(loginToken);
|
||||
|
||||
return Meteor.users.findOne({
|
||||
_id: userId,
|
||||
'services.resume.loginTokens.hashedToken': hashedToken
|
||||
});
|
||||
}
|
||||
|
||||
// Setup a Route using Iron Router to avoid Cross-origin resource sharing
|
||||
// (CORS) errors. We only handle this route on the Server.
|
||||
Router.route(Settings.uri.replace(OHIF.utils.absoluteUrl(), ''), function() {
|
||||
const request = this.request;
|
||||
const response = this.response;
|
||||
const params = this.params;
|
||||
const requestOptions = params.query.options ? JSON.parse(params.query.options) : {};
|
||||
|
||||
let user;
|
||||
if (doAuth) {
|
||||
user = authenticateUser(request);
|
||||
if (!user) {
|
||||
response.writeHead(401);
|
||||
response.end('Error: You must be logged in to perform this action.\n');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Merge this with ohif-study-list? There is a circular dependency now...
|
||||
const server = Servers.findOne(params.query.serverId);
|
||||
if (!server) {
|
||||
response.writeHead(500);
|
||||
response.end('Error: No Server with the specified Server ID was found.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
const requestOpt = server.requestOptions;
|
||||
|
||||
// If no Web Access to DICOM Objects (WADO) Service URL is provided
|
||||
// return an error for the request.
|
||||
if (!params.query.url) {
|
||||
const wadoUrl = params.query.url;
|
||||
if (!wadoUrl) {
|
||||
response.writeHead(500);
|
||||
response.end('Error: No WADO URL was provided.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestOpt.logRequests) {
|
||||
console.log(request.url);
|
||||
}
|
||||
|
||||
if (requestOpt.logTiming) {
|
||||
console.time(request.url);
|
||||
}
|
||||
|
||||
// Use Node's URL parse to decode the query URL
|
||||
const wadoUrl = url.parse(params.query.url);
|
||||
const parsed = url.parse(wadoUrl);
|
||||
|
||||
// Create an object to hold the information required
|
||||
// for the request to the PACS.
|
||||
let options = {
|
||||
headers: {},
|
||||
method: request.method,
|
||||
hostname: wadoUrl.hostname,
|
||||
port: wadoUrl.port, //maybe null
|
||||
path: wadoUrl.path,
|
||||
hostname: parsed.hostname,
|
||||
path: parsed.path
|
||||
};
|
||||
|
||||
if (request.headers['referer']) {
|
||||
options.headers.referer = request.headers['referer'];
|
||||
let requester;
|
||||
if (parsed.protocol === 'https:') {
|
||||
requester = https.request;
|
||||
|
||||
const allowUnauthorizedAgent = new https.Agent({ rejectUnauthorized: false });
|
||||
options.agent = allowUnauthorizedAgent
|
||||
} else {
|
||||
requester = http.request;
|
||||
}
|
||||
if (request.headers['user-agent']) {
|
||||
options.headers['user-agent'] = request.headers['user-agent'];
|
||||
}
|
||||
if (request.headers['accept']) {
|
||||
options.headers['accept'] = request.headers['accept'];
|
||||
|
||||
if (parsed.port) {
|
||||
options.port = parsed.port;
|
||||
}
|
||||
|
||||
Object.keys(request.headers).forEach(entry => {
|
||||
const value = request.headers[entry];
|
||||
if (entry) {
|
||||
console.log(`${entry}: ${value}`);
|
||||
options.headers[entry] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Retrieve the authorization user:password string for the PACS,
|
||||
// if one is required, and include it in the request to the PACS.
|
||||
//const wadoAuth = 'orthanc:orthanc';
|
||||
if (requestOptions.auth) {
|
||||
options.auth = requestOptions.auth;
|
||||
if (requestOpt.auth) {
|
||||
options.auth = requestOpt.auth;
|
||||
}
|
||||
|
||||
// Use Node's HTTP API to send a request to the PACS
|
||||
const proxyRequest = http.request(options, (proxyResponse) => {
|
||||
const proxyRequest = requester(options, proxyResponse => {
|
||||
// When we receive data from the PACS, stream it as the
|
||||
// response to the original request.
|
||||
// console.log(`Got response: ${proxyResponse.statusCode}`);
|
||||
response.writeHead(proxyResponse.statusCode, proxyResponse.headers);
|
||||
|
||||
if (requestOpt.logTiming) {
|
||||
console.timeEnd(request.url);
|
||||
}
|
||||
|
||||
return proxyResponse.pipe(response, {end: true});
|
||||
});
|
||||
|
||||
// If our request to the PACS fails, log the error message
|
||||
proxyRequest.on('error', (error) => {
|
||||
proxyRequest.on('error', error => {
|
||||
response.writeHead(500);
|
||||
response.end(`Error: Problem with request to PACS: ${error.message}\n`);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user