Skip to content

Commit b0644c9

Browse files
committed
feat(dcmjs):Support singlepart responses
1 parent c686828 commit b0644c9

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ client.searchForStudies().then(studies => {
4949
});
5050
```
5151

52+
## Configuration Options
53+
The API can be configured with a number of custom configuration options to control the requests. These are:
54+
* url to retrieve from for the base requests
55+
* singlepart, either true or a set of parts from `bulkdata,image,video` to request as single part responses
56+
* headers to add to the retrieve
5257

5358
## For maintainers
5459

src/api.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class DICOMwebClient {
5858
* @param {Object} options.headers - HTTP headers
5959
* @param {Array.<RequestHook>} options.requestHooks - Request hooks.
6060
* @param {Object} options.verbose - print to console request warnings and errors, default true
61+
* @param {boolean|String} options.singlepart - retrieve singlepart for the named types.
62+
* The available types are: bulkdata, video, image. true means all.
6163
*/
6264
constructor(options) {
6365
this.baseURL = options.url;
@@ -96,6 +98,13 @@ class DICOMwebClient {
9698
this.stowURL = this.baseURL;
9799
}
98100

101+
if (options.singlepart) {
102+
console.log('use singlepart', options.singlepart);
103+
this.singlepart = options.singlepart === true ? 'bulkdata,video,image' : options.singlepart;
104+
} else {
105+
this.singlepart = '';
106+
}
107+
99108
if ('requestHooks' in options) {
100109
this.requestHooks = options.requestHooks;
101110
}
@@ -188,7 +197,16 @@ class DICOMwebClient {
188197
request.onreadystatechange = () => {
189198
if (request.readyState === 4) {
190199
if (request.status === 200) {
191-
resolve(request.response);
200+
const contentType = request.getResponseHeader('Content-Type');
201+
// Automatically distinguishes between multipart and singlepart in an array buffer, and
202+
// converts them into a consistent type.
203+
if (contentType && contentType.indexOf('multipart') !== -1) {
204+
resolve(multipartDecode(request.response));
205+
} else if (request.responseType === 'arraybuffer') {
206+
resolve([request.response]);
207+
} else {
208+
resolve(request.response);
209+
}
192210
} else if (request.status === 202) {
193211
if (this.verbose) {
194212
console.warn('some resources already existed: ', request);
@@ -536,9 +554,7 @@ class DICOMwebClient {
536554
supportedMediaTypes,
537555
);
538556

539-
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials).then(
540-
multipartDecode,
541-
);
557+
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials);
542558
}
543559

544560
/**
@@ -594,9 +610,7 @@ class DICOMwebClient {
594610
supportedMediaTypes,
595611
);
596612

597-
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials).then(
598-
multipartDecode,
599-
);
613+
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials);
600614
}
601615

602616
/**
@@ -646,9 +660,7 @@ class DICOMwebClient {
646660
supportedMediaTypes,
647661
);
648662

649-
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials).then(
650-
multipartDecode,
651-
);
663+
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials);
652664
}
653665

654666
/**
@@ -692,9 +704,7 @@ class DICOMwebClient {
692704
supportedMediaTypes,
693705
);
694706

695-
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials).then(
696-
multipartDecode,
697-
);
707+
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials);
698708
}
699709

700710
/**
@@ -1237,9 +1247,7 @@ class DICOMwebClient {
12371247
supportedMediaTypes,
12381248
),
12391249
};
1240-
return this._httpGet(
1241-
url, headers, 'arraybuffer', progressCallback, withCredentials,
1242-
).then(multipartDecode);
1250+
return this._httpGet(url, headers, 'arraybuffer', progressCallback, withCredentials);
12431251
}
12441252

12451253
const commonMediaType = DICOMwebClient._getCommonMediaType(mediaTypes);
@@ -1715,7 +1723,9 @@ class DICOMwebClient {
17151723
* See http://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_6.5.5.html
17161724
*
17171725
* @param {Object} options
1718-
* @param {String} BulkDataURI - URI for retrieval of bulkdata
1726+
* @param {string} options.BulkDataURI to retrieve
1727+
* @param {Array} options.mediaTypes to use to fetch the URI
1728+
* @param {string} options.byteRange to request a sub-range (only valid on single part)
17191729
* @returns {Promise<Array>} Bulkdata parts
17201730
*/
17211731
retrieveBulkData(options) {
@@ -1728,6 +1738,10 @@ class DICOMwebClient {
17281738
const { withCredentials = false } = options;
17291739
const { progressCallback = false } = options;
17301740

1741+
if (this.singlepart.indexOf('bulkdata') !== -1) {
1742+
return this._httpGet(url, options.headers, 'arraybuffer', null, withCredentials);
1743+
}
1744+
17311745
if (!mediaTypes) {
17321746
return this._httpGetMultipartApplicationOctetStream(
17331747
url,

src/message.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ function multipartEncode(
184184
* @returns {Array} The content
185185
*/
186186
function multipartDecode(response) {
187-
const message = new Uint8Array(response);
187+
// Use the raw data if it is provided in an appropriate format
188+
const message = ArrayBuffer.isView(response) ? response : new Uint8Array(response);
188189

189190
/* Set a maximum length to search for the header boundaries, otherwise
190191
findToken can run for a long time

0 commit comments

Comments
 (0)