diff --git a/Packages/wadoproxy/package.js b/Packages/wadoproxy/package.js index abc3589fc..fea0bdf9a 100755 --- a/Packages/wadoproxy/package.js +++ b/Packages/wadoproxy/package.js @@ -11,7 +11,6 @@ Package.onUse(function(api) { api.use('standard-app-packages'); api.use('clinical:router'); - api.addFiles('server/namespace.js'); // Server-only diff --git a/Packages/wadoproxy/server/initialize.js b/Packages/wadoproxy/server/initialize.js index 1e917067a..cd6073b40 100755 --- a/Packages/wadoproxy/server/initialize.js +++ b/Packages/wadoproxy/server/initialize.js @@ -1,4 +1,3 @@ - Settings = Object.assign((Meteor.settings && Meteor.settings.proxy) ? Meteor.settings.proxy : {}, { uri : "/__wado_proxy", enabled: true diff --git a/Packages/wadoproxy/server/namespace.js b/Packages/wadoproxy/server/namespace.js index 33ea111a6..a9c3980bc 100755 --- a/Packages/wadoproxy/server/namespace.js +++ b/Packages/wadoproxy/server/namespace.js @@ -1,8 +1,12 @@ WADOProxy = {}; -WADOProxy.convertURL = function(wadoURL) { +WADOProxy.convertURL = (wadoURL, requestOptions) => { if (!Settings.enabled) { return wadoURL; } - return Settings.uri + '?' + querystring.stringify({url: wadoURL}); + if (!wadoURL) { + return null; + } + + return Settings.uri + '?' + querystring.stringify({url: wadoURL, options: requestOptions ? JSON.stringify(requestOptions) : null}); } \ No newline at end of file diff --git a/Packages/wadoproxy/server/routes.js b/Packages/wadoproxy/server/routes.js index 9cf40ba69..b12c1a9c8 100755 --- a/Packages/wadoproxy/server/routes.js +++ b/Packages/wadoproxy/server/routes.js @@ -1,33 +1,64 @@ -Router.route(Settings.uri, function () { - let response = this.response; - if (!this.params.query.url) { +// 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, function() { + const request = this.request; + const response = this.response; + const params = this.params; + const requestOptions = params.query.options ? JSON.parse(params.query.options) : {}; + + // If no Web Access to DICOM Objects (WADO) Service URL is provided + // return an error for the request. + if (!params.query.url) { response.writeHead(500); - response.end('No wado url provided'); + response.end('Error: No WADO URL was provided.\n'); return; } - let proxyRequest, - wadoUrl = url.parse(this.params.query.url, false); + // Use Node's URL parse to decode the query URL + const wadoUrl = url.parse(params.query.url); - var options = { - headers: {} + // 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, }; - //options.headers = this.request.headers; - if (this.request.headers['referer']) { - options.headers.referer = this.request.headers['referer']; + + if (request.headers['referer']) { + options.headers.referer = request.headers['referer']; } - if (this.request.headers['user-agent']) { - options.headers['user-agent'] = this.request.headers['user-agent']; + if (request.headers['user-agent']) { + options.headers['user-agent'] = request.headers['user-agent']; + } + + // 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; } - options.method = this.request.method; - options.host = wadoUrl.hostname; - options.port = wadoUrl.port ? wadoUrl.port : 80; - options.path = wadoUrl.path; - - proxyRequest = http.request(options, function (proxyResponse) { - proxyResponse.pipe(response, {end: true}); + // Use Node's HTTP API to send a request to the PACS + const proxyRequest = http.request(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); + return proxyResponse.pipe(response, {end: true}); }); - //proxyRequest.end(); - this.request.pipe(proxyRequest, {end: true}); -}, {where: 'server'}); \ No newline at end of file + + // If our request to the PACS fails, log the error message + proxyRequest.on('error', (error) => { + response.writeHead(500); + response.end(`Error: Problem with request to PACS: ${error.message}\n`); + }); + + // Stream the original request information into the request + // to the PACS + request.pipe(proxyRequest); +}, { + where: 'server' +}); \ No newline at end of file diff --git a/Packages/worklist/server/services/dimse/retrieveMetadata.js b/Packages/worklist/server/services/dimse/retrieveMetadata.js index 8f3ca1445..44fd9c4b8 100755 --- a/Packages/worklist/server/services/dimse/retrieveMetadata.js +++ b/Packages/worklist/server/services/dimse/retrieveMetadata.js @@ -111,7 +111,7 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) { // Retrieve the actual data over WADO-URI var server = Meteor.settings.servers.dicomWeb[0]; - instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom"); + instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom", server.requestOptions); series.instances.push(instanceSummary); }); diff --git a/Packages/worklist/server/services/wado/retrieveMetadata.js b/Packages/worklist/server/services/wado/retrieveMetadata.js index b08c822f9..7658cba26 100644 --- a/Packages/worklist/server/services/wado/retrieveMetadata.js +++ b/Packages/worklist/server/services/wado/retrieveMetadata.js @@ -116,7 +116,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) { }; if (server.imageRendering === 'wadouri') { - instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom'); + instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom', server.requestOptions); } else { instanceSummary.wadorsuri = server.wadoRoot + '/studies/' + studyInstanceUid + '/series/' + seriesInstanceUid + '/instances/' + sopInstanceUid + '/frames/1'; } diff --git a/config/dcm4cheeDIMSE.json b/config/dcm4cheeDIMSE.json index 4e9615ac9..450bf189a 100644 --- a/config/dcm4cheeDIMSE.json +++ b/config/dcm4cheeDIMSE.json @@ -4,7 +4,7 @@ { "name": "DCM4CHEE", "wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently", - "wadoUriRoot": "http://localhost:8043/dcm4chee-arc/aets/DCM4CHEE/wado", + "wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado", "qidoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs", "wadoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs", "qidoSupportsIncludeField": false, diff --git a/config/orthancDIMSE.json b/config/orthancDIMSE.json index 8d713c603..55e0cdd0b 100644 --- a/config/orthancDIMSE.json +++ b/config/orthancDIMSE.json @@ -4,7 +4,7 @@ { "name": "Orthanc", "wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently", - "wadoUriRoot": "http://localhost:8043/wado", + "wadoUriRoot": "http://localhost:8042/wado", "qidoRoot": "http://localhost:8042/dicom-web", "wadoRoot": "http://localhost:8042/dicom-web", "qidoSupportsIncludeField": false,