Skip to content

Commit 34a5436

Browse files
committed
Adding upload result, isCancelled upload session property
1 parent bb319a5 commit 34a5436

File tree

2 files changed

+90
-9
lines changed

2 files changed

+90
-9
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
import { GraphResponseHandler } from "../../GraphResponseHandler";
3+
export class UploadResult {
4+
private _location: string;
5+
private _body: unknown;
6+
private _uploadSuccess: boolean;
7+
8+
public get location(): string {
9+
return this._location;
10+
}
11+
12+
public set location(location: string) {
13+
this._location = location;
14+
}
15+
16+
public get body() {
17+
return this._body;
18+
}
19+
20+
public set body(body: unknown) {
21+
// Body can be undefined. Empty body is expected.
22+
this._body = body;
23+
}
24+
25+
public async setUploadResult(response: Response) {
26+
this._location = response.headers.get("Location");
27+
this._body = await GraphResponseHandler.getResponse(response);
28+
this._uploadSuccess =
29+
}
30+
31+
}

src/tasks/LargeFileUploadTask.ts

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
* @module LargeFileUploadTask
1010
*/
1111

12+
import { GraphClientError } from "../GraphClientError";
1213
import { Client } from "../index";
1314
import { Range } from "../Range";
15+
import { ResponseType } from "../ResponseType";
16+
import { GraphResponseHandler } from "../GraphResponseHandler";
17+
import { UploadResult } from "./FileUploadUtil/UploadResult";
1418

1519
/**
1620
* @interface
@@ -50,6 +54,7 @@ export interface LargeFileUploadTaskOptions {
5054
export interface LargeFileUploadSession {
5155
url: string;
5256
expiry: Date;
57+
isCancelled?: boolean;
5358
}
5459

5560
/**
@@ -124,6 +129,7 @@ export class LargeFileUploadTask {
124129
const largeFileUploadSession: LargeFileUploadSession = {
125130
url: session.uploadUrl,
126131
expiry: new Date(session.expirationDateTime),
132+
isCancelled: false
127133
};
128134
return largeFileUploadSession;
129135
}
@@ -215,22 +221,35 @@ export class LargeFileUploadTask {
215221
* @returns The promise resolves to uploaded response
216222
*/
217223
public async upload(): Promise<any> {
218-
// eslint-disable-next-line no-constant-condition
219-
while (true) {
224+
while (!this.uploadSession.isCancelled) {
220225
const nextRange = this.getNextRange();
221226
if (nextRange.maxValue === -1) {
222227
const err = new Error("Task with which you are trying to upload is already completed, Please check for your uploaded file");
223228
err.name = "Invalid Session";
224229
throw err;
225230
}
226231
const fileSlice = this.sliceFile(nextRange);
227-
const response = await this.uploadSlice(fileSlice, nextRange, this.file.size);
228-
// Upon completion of upload process incase of onedrive, driveItem is returned, which contains id
229-
if (response.id !== undefined) {
230-
return response;
231-
} else {
232-
this.updateTaskStatus(response);
232+
const rawResponse = await this.uploadSliceGetRawResponse(fileSlice, nextRange, this.file.size);
233+
if (!rawResponse) {
234+
throw new GraphClientError("Something went wrong! Large file upload slice response is null.");
233235
}
236+
237+
const responseBody = await GraphResponseHandler.getResponse(rawResponse);
238+
if (rawResponse.status == 201 || (rawResponse.status == 200 && responseBody.id)) {
239+
const result = new UploadResult();
240+
return result.setUploadResult(rawResponse);
241+
}
242+
243+
/* Handling an API issue where the case of Outlook upload 'nextExpectedRanges' property is not uniform.
244+
* https://github.com/microsoftgraph/msgraph-sdk-serviceissues/issues/39
245+
*/
246+
const res: UploadStatusResponse = {
247+
expirationDateTime: responseBody.expirationDateTime,
248+
nextExpectedRanges: responseBody.NextExpectedRanges || responseBody.nextExpectedRanges,
249+
};
250+
251+
this.updateTaskStatus(res);
252+
this.updateTaskStatus(responseBody);
234253
}
235254
}
236255

@@ -251,6 +270,23 @@ export class LargeFileUploadTask {
251270
})
252271
.put(fileSlice);
253272
}
273+
/**
274+
* @public
275+
* @async
276+
* Uploads given slice to the server
277+
* @param {ArrayBuffer | Blob | File} fileSlice - The file slice
278+
* @param {Range} range - The range value
279+
* @param {number} totalSize - The total size of a complete file
280+
*/
281+
public async uploadSliceGetRawResponse(fileSlice: unknown, range: Range, totalSize: number): Promise<Response> {
282+
return await this.client
283+
.api(this.uploadSession.url)
284+
.headers({
285+
"Content-Length": `${range.maxValue - range.minValue + 1}`,
286+
"Content-Range": `bytes ${range.minValue}-${range.maxValue}/${totalSize}`,
287+
}).responseType(ResponseType.RAW)
288+
.put(fileSlice);
289+
}
254290

255291
/**
256292
* @public
@@ -259,7 +295,11 @@ export class LargeFileUploadTask {
259295
* @returns The promise resolves to cancelled response
260296
*/
261297
public async cancel(): Promise<any> {
262-
return await this.client.api(this.uploadSession.url).delete();
298+
const deleteResponse = await this.client.api(this.uploadSession.url).responseType(ResponseType.RAW).delete()
299+
if (deleteResponse.status && deleteResponse.status == 204) {
300+
this.uploadSession.isCancelled = true;
301+
}
302+
return deleteResponse;
263303
}
264304

265305
/**
@@ -284,4 +324,14 @@ export class LargeFileUploadTask {
284324
await this.getStatus();
285325
return await this.upload();
286326
}
327+
328+
/**
329+
* @public
330+
* @async
331+
* Get the upload session information
332+
* @returns The large file upload large file session
333+
*/
334+
public getUploadSession(): LargeFileUploadSession {
335+
return this.uploadSession;
336+
}
287337
}

0 commit comments

Comments
 (0)