Closed cutecycle closed 4 years ago
👋 Hello @cutecycle. I'm not sure I 100% follow. There are two ways to mitigate CORS issues:
Access-Control-Allow-Origin
: The origin that is allowed to make the request, or * if a request can be made from any originAccess-Control-Allow-Methods
: A comma-separated list of HTTP methods that are allowedAccess-Control-Allow-Headers
: A comma-separated list of the custom headers that are allowed to be sentAccess-Control-Max-Age
: The maximum duration that the response to the preflight request can be cached before another call is madeYou can see a few examples of our own usage of these. If anything seems incorrect, let me know. They may need cleaned up:
nginx
to handle web requests, which provides a convenient place to set CORS headers. We have an nginx
configuration file lying around that should do thatnginx
+ Image Archive recipe, we show how to configure and deploy the web viewer and orthanc
. We host them at the same domain, so we don't need to set CORS headers. The nginx
config for that recipe is hiding hereHello, and Thank you.
Apologies for the misconception; I was going against the Data Source documentation.
I've set the containers to host networking mode, and set all internal communication between OHIF and orthanc to 127.0.0.1:
servers: {
dicomWeb: [
{
name: "orthanc",
wadoUriRoot: "http://127.0.0.1:8042/wado",
qidoRoot: "http://127.0.0.1:8042/dicom-web",
wadoRoot: "http://127.0.0.1:8042/dicom-web",
qidoSupportsIncludeField: false,
imageRendering: "wadors",
thumbnailRendering: "wadors",
enableStudyLazyLoad: true,
},
],
},
version: '3.6'
services:
mongo:
image: "mongo:latest"
network_mode: host
restart: always
orthanc:
image: jodogne/orthanc-plugins
restart: always
command: ["--trace","/etc/orthanc/orthanc.json" ]
network_mode: host
volumes:
- ./configs/ohif-config/orthanc.json:/etc/orthanc/orthanc.json
viewer:
image: ohif/viewer:v2.2.0.5809
restart: always
network_mode: host
ports:
- "80:80"
- "3000:3000"
environment:
- MONGO_URL=mongodb://127.0.0.1:27017/ohif
- PUBLIC_URL=http://34.220.35.158/
extra_hosts:
- "pacsip:127.0.0.1"
- "pacsIP:127.0.0.1"
volumes:
- ./configs/ohif-config/ohif.json:/app/app.json
- ./configs/ohif-config/ohif.js:/usr/share/nginx/html/app-config.js
When you say "client on the same origin," do you mean the browser as well? I thought if I had both OHIF and orthanc on 127.0.0.1, the ohif/viewers container itself would GET 127.0.0.1:8042/dicom-web
, which should be allowed.
But it looks like what's happening in newer versions is now the browser on an end-user machine is making an AJAX request to the configured DICOMweb endpoint URL, rather than the Viewers server.
Meteor/~0.4.0: OHIF backend makes the request on loopback
ESC[34mI20190826-18:46:46.732(0)? ESC[39m dicomWeb: { endpoints: [ [Object] ] },
ESC[34mI20190826-18:46:46.732(0)? ESC[39m dimse: { host: '127.0.0.1', hostAE: 'IMAGEMOVER_SCP', port: 11112 },
ESC[34mI20190826-18:46:46.732(0)? ESC[39m public: {} }
ESC[34mI20190826-19:00:22.756(0)? ESC[39mhttp://127.0.0.1:8042/dicom-web/studies?limit=20&includefield=00081030%2C00080060
ESC[34mI20190826-19:00:22.764(0)? ESC[39mhttp://127.0.0.1:8042/dicom-web/studies?limit=20&includefield=00081030%2C00080060: 8ms
ESC[34mI20190826-19:35:59.354(0)? ESC[39mhttp://127.0.0.1:8042/dicom-web/studies?limit=20&includefield=00081030%2C00080060
React/v2+: OHIF frontend makes the request on XHR
Would you say it's best for me to add an nginx container that proxies to the orthanc container and overwrites the existing CORS headers, so that an end-user machine can hit that endpoint from the XHR?
I was going against the Data Source documentation
The Data Source
documentation is specific to local development using WebPack's built in "dev server". The development configuration supports two environment variables that allow WebPack to proxy request to the PACS to avoid CORS issues.
For production usage, or any usage where the OHIF Viewer isn't served by WebPack, we need to switch up our strategy.
When you say "client on the same origin," do you mean the browser as well? I thought if I had both OHIF and orthanc on 127.0.0.1, the ohif/viewers container itself would GET 127.0.0.1:8042/dicom-web, which should be allowed.
The difference in port is what trips CORS. CORS cares about: domain
, protocol
, port
React/v2+: OHIF frontend makes the request on XHR
v2+ no longer has a "back end", hence the change.
Would you say it's best for me to add an nginx container that proxies to the orthanc container and overwrites the existing CORS headers, so that an end-user machine can hit that endpoint from the XHR?
That would probably be the best route. For local development, you can cheat and use WebPack dev server's proxying. For production/hosted, you'll likely need to proxy your PACS and set appropriate headers.
Thanks so much, I'm up and running a test system!
Should I close or do maintainers close?
🎉 Great to hear, @cutecycle! I'll close, but you're more than welcome to for future issues. Please don't hesitate to reach out if you have additional questions, suggestions, PRs, etc.
Thanks so much, I'm up and running a test system!
Should I close or do maintainers close?
@cutecycle would you mind sharing your nginx config with me?
@dannyrb is there an nginx config example for OHIF v3 and Orthanc ?
I have been pulling my hair out over the last three days trying to figure this out without any luck.....
OHIF V3 with Orthanc MPR functionality works fine on localhost but Error: Uncaught (in promise) Error: SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/ error occurs when accessing over that internet
my nginx config file is below:
worker_processes 1;
events { worker_connections 1024; }
http {
upstream orthanc-server {
server 127.0.0.1:8099;
}
server {
listen [::]:8099 default_server;
listen 8099;
# CORS Magic
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow_Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow_Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
try_files $uri $uri/ /index.html;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
add_header Cross-Origin-Opener-Policy same-origin;
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Resource-Policy same-origin;
}
location /orthanc/{
proxy_pass http://localhost:8042;
proxy_set_header Authorization "Basic YWxuYXNhcnBhY3MbyybyybNhcnBhY3M1Nzc=";
proxy_set_header Host $Host:8099/orthanc/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
# CORS Magic
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow_Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
rewrite /orthanc(.*) $1 break;
}
}
}
My app-config.js is below
window.config = {
routerBasename: "/",
extensions: [],
modes: [],
customizationService: {},
showStudyList: !0,
maxNumberOfWebWorkers: 3,
omitQuotationForMultipartRequest: !0,
showWarningMessageForCrossOrigin: !0,
showCPUFallbackMessage: !0,
showLoadingIndicator: !0,
maxNumRequests: {
interaction: 100,
thumbnail: 75,
prefetch: 10
},
dataSources: [{
friendlyName: "dcmjs DICOMWeb Server",
namespace: "@ohif/extension-default.dataSourcesModule.dicomweb",
sourceName: "dicomweb",
configuration: {
name: "aws",
wadoUriRoot: '/orthanc/wado',
qidoRoot: '/orthanc/dicom-web',
wadoRoot: '/orthanc/dicom-web',
qidoSupportsIncludeField: !1,
supportsReject: !1,
imageRendering: "wadors",
thumbnailRendering: "wadors",
enableStudyLazyLoad: !1,
supportsFuzzyMatching: !1,
supportsWildcard: !0,
staticWado: !0,
singlepart: "bulkdata,video,pdf"
}
}, {
friendlyName: "dicom json",
namespace: "@ohif/extension-default.dataSourcesModule.dicomjson",
sourceName: "dicomjson",
configuration: {
name: "json"
}
}, {
friendlyName: "dicom local",
namespace: "@ohif/extension-default.dataSourcesModule.dicomlocal",
sourceName: "dicomlocal",
configuration: {}
}],
httpErrorHandler: e => {
console.warn(e.status), console.warn("test, navigate to https://ohif.org/")
},
defaultDataSourceName: "dicomweb",
};
OHIF V3 with Orthanc MPR functionality works fine on localhost but Error: Uncaught (in promise) Error: SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/ error occurs when accessing over that internet
It should work over the internet as well as localhost
I tried using the example nginx config file here as a guide >>> https://github.com/OHIF/Viewers/blob/master/.docker/Nginx-Orthanc/config/nginx.conf but no luck.
Thanks so much, I'm up and running a test system! Should I close or do maintainers close?
@cutecycle would you mind sharing your nginx config with me?
@dannyrb is there an nginx config example for OHIF v3 and Orthanc ?
So sorry, I've been out of the OHIF world for a long time :(
I have been pulling my hair out over the last three days trying to figure this out without any luck.....
Describe the Bug
OHIF V3 with Orthanc MPR functionality works fine on localhost but Error: Uncaught (in promise) Error: SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/ error occurs when accessing over that internet
Steps to Reproduce:
- open any study on localhost and switch to MPR view. It will work find
- open any study over the internet and switch to MPR view. It will generate Error: Uncaught (in promise) Error: SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/ error in browser console and MPR will not generate.
my nginx config file is below:
worker_processes 1; events { worker_connections 1024; } http { upstream orthanc-server { server 127.0.0.1:8099; } server { listen [::]:8099 default_server; listen 8099; # CORS Magic add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow_Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow_Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } try_files $uri $uri/ /index.html; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Origin' '*'; add_header Cross-Origin-Opener-Policy same-origin; add_header Cross-Origin-Embedder-Policy require-corp; add_header Cross-Origin-Resource-Policy same-origin; } location /orthanc/{ proxy_pass http://localhost:8042; proxy_set_header Authorization "Basic YWxuYXNhcnBhY3MbyybyybNhcnBhY3M1Nzc="; proxy_set_header Host $Host:8099/orthanc/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; # CORS Magic add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow_Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; rewrite /orthanc(.*) $1 break; } } }
My app-config.js is below
window.config = { routerBasename: "/", extensions: [], modes: [], customizationService: {}, showStudyList: !0, maxNumberOfWebWorkers: 3, omitQuotationForMultipartRequest: !0, showWarningMessageForCrossOrigin: !0, showCPUFallbackMessage: !0, showLoadingIndicator: !0, maxNumRequests: { interaction: 100, thumbnail: 75, prefetch: 10 }, dataSources: [{ friendlyName: "dcmjs DICOMWeb Server", namespace: "@ohif/extension-default.dataSourcesModule.dicomweb", sourceName: "dicomweb", configuration: { name: "aws", wadoUriRoot: '/orthanc/wado', qidoRoot: '/orthanc/dicom-web', wadoRoot: '/orthanc/dicom-web', qidoSupportsIncludeField: !1, supportsReject: !1, imageRendering: "wadors", thumbnailRendering: "wadors", enableStudyLazyLoad: !1, supportsFuzzyMatching: !1, supportsWildcard: !0, staticWado: !0, singlepart: "bulkdata,video,pdf" } }, { friendlyName: "dicom json", namespace: "@ohif/extension-default.dataSourcesModule.dicomjson", sourceName: "dicomjson", configuration: { name: "json" } }, { friendlyName: "dicom local", namespace: "@ohif/extension-default.dataSourcesModule.dicomlocal", sourceName: "dicomlocal", configuration: {} }], httpErrorHandler: e => { console.warn(e.status), console.warn("test, navigate to https://ohif.org/") }, defaultDataSourceName: "dicomweb", };
The current behavior
OHIF V3 with Orthanc MPR functionality works fine on localhost but Error: Uncaught (in promise) Error: SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/ error occurs when accessing over that internet
The expected behavior
It should work over the internet as well as localhost
I tried using the example nginx config file here as a guide >>> https://github.com/OHIF/Viewers/blob/master/.docker/Nginx-Orthanc/config/nginx.conf but no luck.
Have you solved this problem?
Description
I have an older meteor-based configuration of the OHIF viewer that made requests to an Orthanc dicom-web endpoint over the loopback interface.
I'm trying to recreate this in docker-compose, but I'm seeing errors in-console from the client trying to make requests to the orthanc dicom-web endpoint and failing because of either CORS policy or a non-existent hostname.
Is going directly to DICOMweb from the ohif viewer server still supported? Should I edit the nginx configuration in the container for CORS and just do dicomweb on the client side?