All files / dicomImageLoader/src/imageLoader/internal xhrRequest.ts

67.21% Statements 41/61
61.53% Branches 16/26
63.63% Functions 7/11
67.21% Lines 41/61

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174                            9634x   9634x                     9634x       9634x 9634x 9634x             9634x   9634x   9634x 9454x     9454x     9454x     9634x       9634x 9634x     9634x   9634x         9634x         9634x       9634x   9634x       9634x           9634x       9634x   43397x                     43397x   9634x 9634x                                 9634x   15162x           15162x 14140x 14140x     15162x               15162x     15162x       9634x         9634x       9634x     9634x   9634x        
import { getOptions } from './options';
import type {
  LoaderXhrRequestError,
  LoaderXhrRequestParams,
  LoaderXhrRequestPromise,
} from '../../types';
import { triggerEvent, eventTarget } from '@cornerstonejs/core';
 
function xhrRequest(
  url: string,
  imageId: string,
  defaultHeaders: Record<string, string> = {},
  params: LoaderXhrRequestParams = {}
): LoaderXhrRequestPromise<ArrayBuffer> {
  const options = getOptions();
 
  const errorInterceptor = (xhr: XMLHttpRequest) => {
    if (typeof options.errorInterceptor === 'function') {
      const error = new Error('request failed') as LoaderXhrRequestError;
 
      error.request = xhr;
      error.response = xhr.response;
      error.status = xhr.status;
      options.errorInterceptor(error);
    }
  };
 
  const xhr = new XMLHttpRequest();
 
  // Make the request for the DICOM P10 SOP Instance
  const promise: LoaderXhrRequestPromise<ArrayBuffer> =
    new Promise<ArrayBuffer>(async (resolve, reject) => {
      options.open(xhr, url, defaultHeaders, params);
      const beforeSendHeaders = await options.beforeSend(
        xhr,
        imageId,
        defaultHeaders,
        params
      );
 
      xhr.responseType = 'arraybuffer';
 
      const headers = Object.assign({}, defaultHeaders, beforeSendHeaders);
 
      Object.keys(headers).forEach(function (key) {
        Iif (headers[key] === null) {
          return;
        }
        Iif (key === 'Accept' && url.indexOf('accept=') !== -1) {
          return;
        }
        xhr.setRequestHeader(key, headers[key]);
      });
 
      params.deferred = {
        resolve,
        reject,
      };
      params.url = url;
      params.imageId = imageId;
 
      // Event triggered when downloading an image starts
      xhr.onloadstart = function (event) {
        // Action
        Iif (options.onloadstart) {
          options.onloadstart(event, params);
        }
 
        // Event
        const eventData = {
          url,
          imageId,
        };
 
        triggerEvent(eventTarget, 'cornerstoneimageloadstart', eventData);
      };
 
      // Event triggered when downloading an image ends
      xhr.onloadend = function (event) {
        // Action
        Iif (options.onloadend) {
          options.onloadend(event, params);
        }
 
        const eventData = {
          url,
          imageId,
        };
 
        // Event
        triggerEvent(eventTarget, 'cornerstoneimageloadend', eventData);
      };
 
      // handle response data
      xhr.onreadystatechange = function (event) {
        // Action
        Iif (options.onreadystatechange) {
          options.onreadystatechange(event, params);
 
          // This should not return, because if a hook is defined, that function
          // will be called but the image load promise will never resolve.
          // return;
        }
 
        // Default action
        // TODO: consider sending out progress messages here as we receive
        // the pixel data
        if (xhr.readyState === 4) {
          // Status OK (200) and partial content (206) are both handled
          if (xhr.status === 200 || xhr.status === 206) {
            options
              .beforeProcessing(xhr)
              .then(resolve)
              .catch(() => {
                errorInterceptor(xhr);
                // request failed, reject the Promise
                reject(xhr);
              });
          } else E{
            errorInterceptor(xhr);
            // request failed, reject the Promise
            reject(xhr);
          }
        }
      };
 
      // Event triggered when downloading an image progresses
      xhr.onprogress = function (oProgress) {
        // console.log('progress:',oProgress)
        const loaded = oProgress.loaded; // evt.loaded the bytes browser receive
 
        let total: number;
 
        let percentComplete: number;
 
        if (oProgress.lengthComputable) {
          total = oProgress.total; // evt.total the total bytes seted by the header
          percentComplete = Math.round((loaded / total) * 100);
        }
 
        const eventData = {
          url,
          imageId,
          loaded,
          total,
          percentComplete,
        };
 
        triggerEvent(eventTarget, 'cornerstoneimageloadprogress', eventData);
 
        // Action
        Iif (options.onprogress) {
          options.onprogress(oProgress, params);
        }
      };
      xhr.onerror = function () {
        errorInterceptor(xhr);
        reject(xhr);
      };
 
      xhr.onabort = function () {
        errorInterceptor(xhr);
        reject(xhr);
      };
      xhr.send();
    });
 
  promise.xhr = xhr;
 
  return promise;
}
 
export default xhrRequest;