Skip to content

Commit 37ef346

Browse files
committed
fix(DicomWebDataSource): set correct cross-service URLs on DICOMweb clients
The dicomweb-client library sets qidoURL, wadoURL, and stowURL all to the same base url when no prefixes are provided. This causes requests to be routed to the wrong endpoint when qidoRoot and wadoRoot differ (e.g. /qidors/ vs /wadors/). Extract applyServiceUrls into a shared utility so the production code and tests exercise the same function. After constructing the clients, call applyServiceUrls to assign the correct cross-service URLs. Also adds an optional stowRoot config field for deployments with a separate STOW endpoint. Closes #5820 Signed-off-by: Agustin Bereciartua <bereciartua.agustin@gmail.com>
1 parent d792bf7 commit 37ef346

3 files changed

Lines changed: 86 additions & 0 deletions

File tree

extensions/default/src/DicomWebDataSource/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { retrieveStudyMetadata, deleteStudyMetadataPromise } from './retrieveStu
1616
import StaticWadoClient from './utils/StaticWadoClient';
1717
import getDirectURL from '../utils/getDirectURL';
1818
import { fixBulkDataURI } from './utils/fixBulkDataURI';
19+
import { applyServiceUrls } from './utils/applyServiceUrls';
1920
import {HeadersInterface} from '@ohif/core/src/types/RequestHeaders';
2021

2122
const { DicomMetaDictionary, DicomDict } = dcmjs.data;
@@ -35,6 +36,7 @@ export type DicomWebConfig = {
3536
/** Base URL to use for QIDO requests */
3637
qidoRoot?: string;
3738
wadoRoot?: string; // - Base URL to use for WADO requests
39+
stowRoot?: string; // - Base URL to use for STOW requests (defaults to wadoRoot)
3840
wadoUri?: string; // - Base URL to use for WADO URI requests
3941
qidoSupportsIncludeField?: boolean; // - Whether QIDO supports the "Include" option to request additional fields in response
4042
imageRendering?: string; // - wadors | ? (unsure of where/how this is used)
@@ -207,6 +209,8 @@ function createDicomWebApi(dicomWebConfig: DicomWebConfig, servicesManager) {
207209
wadoDicomWebClient = dicomWebConfig.staticWado
208210
? new StaticWadoClient(wadoConfig)
209211
: new api.DICOMwebClient(wadoConfig);
212+
213+
applyServiceUrls(qidoDicomWebClient, wadoDicomWebClient, dicomWebConfig);
210214
},
211215
query: {
212216
studies: {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { applyServiceUrls } from './applyServiceUrls';
2+
3+
describe('applyServiceUrls', () => {
4+
it('should fix cross-service URLs when roots differ', () => {
5+
const qidoClient = { wadoURL: 'https://server.com/qidors/org1', stowURL: 'https://server.com/qidors/org1' };
6+
const wadoClient = { qidoURL: 'https://server.com/wadors/org1', stowURL: 'https://server.com/wadors/org1' };
7+
8+
applyServiceUrls(qidoClient, wadoClient, {
9+
qidoRoot: 'https://server.com/qidors/org1',
10+
wadoRoot: 'https://server.com/wadors/org1',
11+
});
12+
13+
expect(qidoClient.wadoURL).toBe('https://server.com/wadors/org1');
14+
expect(qidoClient.stowURL).toBe('https://server.com/wadors/org1');
15+
16+
expect(wadoClient.qidoURL).toBe('https://server.com/qidors/org1');
17+
expect(wadoClient.stowURL).toBe('https://server.com/wadors/org1');
18+
});
19+
20+
it('should use explicit stowRoot when provided', () => {
21+
const qidoClient = { wadoURL: '', stowURL: '' };
22+
const wadoClient = { qidoURL: '', stowURL: '' };
23+
24+
applyServiceUrls(qidoClient, wadoClient, {
25+
qidoRoot: 'https://server.com/qidors/org1',
26+
wadoRoot: 'https://server.com/wadors/org1',
27+
stowRoot: 'https://server.com/stowrs/org1',
28+
});
29+
30+
expect(qidoClient.stowURL).toBe('https://server.com/stowrs/org1');
31+
expect(wadoClient.stowURL).toBe('https://server.com/stowrs/org1');
32+
});
33+
34+
it('should be a no-op when qidoRoot and wadoRoot are the same', () => {
35+
const qidoClient = { wadoURL: 'https://server.com/dicomweb', stowURL: 'https://server.com/dicomweb' };
36+
const wadoClient = { qidoURL: 'https://server.com/dicomweb', stowURL: 'https://server.com/dicomweb' };
37+
38+
applyServiceUrls(qidoClient, wadoClient, {
39+
qidoRoot: 'https://server.com/dicomweb',
40+
wadoRoot: 'https://server.com/dicomweb',
41+
});
42+
43+
expect(qidoClient.wadoURL).toBe('https://server.com/dicomweb');
44+
expect(qidoClient.stowURL).toBe('https://server.com/dicomweb');
45+
expect(wadoClient.qidoURL).toBe('https://server.com/dicomweb');
46+
expect(wadoClient.stowURL).toBe('https://server.com/dicomweb');
47+
});
48+
49+
it('should default stowURL to wadoRoot when stowRoot is not provided', () => {
50+
const qidoClient = { wadoURL: '', stowURL: '' };
51+
const wadoClient = { qidoURL: '', stowURL: '' };
52+
53+
applyServiceUrls(qidoClient, wadoClient, {
54+
qidoRoot: 'https://server.com/qidors',
55+
wadoRoot: 'https://server.com/wadors',
56+
});
57+
58+
expect(qidoClient.stowURL).toBe('https://server.com/wadors');
59+
expect(wadoClient.stowURL).toBe('https://server.com/wadors');
60+
});
61+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Ensures each DICOMweb client has the correct URLs for all services.
3+
*
4+
* The dicomweb-client library sets qidoURL, wadoURL, and stowURL all to the
5+
* base `url` when no prefixes are provided. This function cross-assigns the
6+
* correct service URLs so requests are routed to the right endpoint when
7+
* qidoRoot and wadoRoot differ (e.g. /qidors/ vs /wadors/).
8+
*/
9+
export function applyServiceUrls(
10+
qidoClient: { wadoURL: string; stowURL: string },
11+
wadoClient: { qidoURL: string; stowURL: string },
12+
config: { qidoRoot?: string; wadoRoot?: string; stowRoot?: string }
13+
): void {
14+
const effectiveStowRoot = config.stowRoot || config.wadoRoot;
15+
16+
qidoClient.wadoURL = config.wadoRoot;
17+
qidoClient.stowURL = effectiveStowRoot;
18+
19+
wadoClient.qidoURL = config.qidoRoot;
20+
wadoClient.stowURL = effectiveStowRoot;
21+
}

0 commit comments

Comments
 (0)