Skip to content

Commit

Permalink
feat: add content-location header when retrieving
Browse files Browse the repository at this point in the history
- Change, the argument of `MultipartWriter`
the `pathsOfImages` to `imagePathObjList`, the
argument is the object contains all UIDs and use for
combining the Content-Location in headers
- Fix, incorrect path of image
the path is full absolute path now, remove the
`DICOM_STORE_ROOTPATH`
- Fix, req.protocol is undefined
the req.protocol not implement in polka, use req.secure instead
- Fix, res.set is undefined
res.set is not implement in polka, use res.setHeader instead
- Chore, add @jorgeferrero/stream-to-buffer and archiver
  • Loading branch information
Chinlinlee committed May 12, 2022
1 parent c2c671e commit 6179073
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 16 deletions.
185 changes: 185 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"author": "chinlinlee",
"license": "MIT",
"dependencies": {
"@jorgeferrero/stream-to-buffer": "^2.0.6",
"archiver": "^5.3.1",
"axios": "^0.26.1",
"bcrypt": "^5.0.1",
"body-parser": "^1.20.0",
Expand Down
41 changes: 25 additions & 16 deletions utils/multipartWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,31 @@ const fs = require("fs");
const _ = require("lodash");
const dicomParser = require("dicom-parser");
const { streamToBuffer } = require("@jorgeferrero/stream-to-buffer");
const { dcm2jpegCustomCmd } = require("../models/dcmtk");
const { dcm2jpegCustomCmd } = require("../models/DICOM/dcmtk");
const { URL } = require("url");
const path = require("path");
const DICOM_STORE_ROOTPATH = process.env.DICOM_STORE_ROOTPATH;

/**
* @typedef {Object} ImagePathObj
* @property {string} studyUID
* @property {string} seriesUID
* @property {string} instanceUID
* @property {string} instancePath
*/

class MultipartWriter {
/**
*
* @param {Array<string>} pathsOfImages The path list of the images
* @param {import('express').Response} res The express response
* @param {Array<ImagePathObj>} imagePathObjList The path list of the images
* @param {import('http').ServerResponse} res The express response
* @param {import('express').Request} req
*/
constructor(pathsOfImages, res, req = {}) {
constructor(imagePathObjList, res, req = {}) {
this.BOUNDARY = `${uuid.v4()}-${uuid.v4()}-raccoon`;
this.pathsOfImages = pathsOfImages;
this.imagePathObjList = imagePathObjList;
this.res = res;
this.req = req;
//this.responseData = "";
}

/**
Expand Down Expand Up @@ -67,15 +74,16 @@ class MultipartWriter {
}

async writeContentLocation(subPath = "") {
let protocol = this.req.secure ? "https" : "http";
if (subPath) {
let urlObj = new URL(
subPath,
`${this.req.protocol}://${this.req.headers.host}`
`${protocol}://${this.req.headers.host}`
);
this.res.write(`Content-Location: ${urlObj.href}\r\n`);
} else {
this.res.write(
`Content-Location: ${this.req.protocol}://${this.req.headers.host}${this.req.originalUrl}\r\n`
`Content-Location: ${protocol}://${this.req.headers.host}${this.req.originalUrl}\r\n`
);
}
}
Expand All @@ -94,7 +102,7 @@ class MultipartWriter {
* @param {string} type the type of the whole content
*/
async setHeaderMultipartRelatedContentType(type) {
this.res.set(
this.res.setHeader(
"content-type",
`multipart/related; type="${type}"; boundary=${this.BOUNDARY}`
);
Expand All @@ -106,20 +114,21 @@ class MultipartWriter {
*/
async writeDICOMFiles(type) {
try {
if (this.pathsOfImages) {
if (this.imagePathObjList) {
this.setHeaderMultipartRelatedContentType(type);
for (let i = 0; i < this.pathsOfImages.length; i++) {
console.log(
`${DICOM_STORE_ROOTPATH}${this.pathsOfImages[i]}`
);
for (let i = 0; i < this.imagePathObjList.length; i++) {
let {studyUID, seriesUID, instanceUID} = this.imagePathObjList[i];
let imagePath = this.imagePathObjList[i].instancePath;
let fileBuffer = await streamToBuffer(
fs.createReadStream(
`${DICOM_STORE_ROOTPATH}${this.pathsOfImages[i]}`
imagePath
)
);
this.writeBoundary(i === 0);
this.writeContentType(type);
this.writeContentLength(fileBuffer.length);
let instanceUrlPath = `/dicom-web/studies/${studyUID}/series/${seriesUID}/instances/${instanceUID}`;
this.writeContentLocation(instanceUrlPath);
this.writeBufferData(fileBuffer);
}
this.writeFinalBoundary();
Expand All @@ -140,7 +149,7 @@ class MultipartWriter {
*/
async writeFrames(type, frameList) {
this.setHeaderMultipartRelatedContentType();
let dicomFilename = `${DICOM_STORE_ROOTPATH}${this.pathsOfImages[0]}`;
let dicomFilename = `${this.imagePathObjList[0].instancePath}`;
let jpegFile = dicomFilename.replace(/\.dcm\b/gi, "");
let minFrameNumber = _.min(frameList);
let maxFrameNumber = _.max(frameList);
Expand Down

0 comments on commit 6179073

Please sign in to comment.