Uploading large file to Azure Storage via JS SDK splitted into chunks throws 401, while uploading small file at once, it returns 201

Mariusz Budzisz 25 Reputation points
2023-04-02T19:53:36.8366667+00:00

Hello,

I've ran into an issue with uploading files using @azure/storage-blob JS package,
To be precise when I'll upload a blob just as a single file (simply take it from the HTML input type=file and then pass it in argument to BlockBlobClient.uploadData(file) then it works fine, returns me 201 after a while and that's it.
Problem is, what this file can be let's say 20 GB in size, then I should split it into chunks and then pass it chunk by chunk.
But after running that, I'm constantly receiving an error message:

Failed to load resource: the server responded with a status of 401 (Server failed to authenticate the request. Please refer to the information in the www-authenticate header.)
FilmUpload.js:54 RestError: Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
RequestId:5a8eb0d1-301e-006c-349a-65e7f6000000
Time:2023-04-02T19:39:58.1007251Z
    at handleErrorResponse (deserializationPolicy.ts:274:1)
    at deserializationPolicy.ts:179:1
    at async StorageRetryPolicy.attemptSendRequest (StorageRetryPolicy.ts:169:1)
    at async StorageClientContext.sendOperationRequest (serviceClient.ts:520:1)
    at async BlockBlobClient.stageBlock (Clients.ts:3964:1)
    at async uploadFilm (FilmUpload.js:51:1)

My component's code is below:

import {
  BlockBlobClient,
  AnonymousCredential,
  newPipeline,
} from "@azure/storage-blob";
import styles from "./FilmUpload.module.css";
import { useState } from "react";

const uploadFilm = async (file) => {
  const blobName = file.name;
  const account = process.env.REACT_APP_STORAGE_ACCOUNT_NAME;
  const containerName = process.env.REACT_APP_CONTAINER_NAME;
  const apiAddress = process.env.REACT_APP_API_ADDRESS;
  const response = await fetch(
    `https://${apiAddress}/api/SAS/film-upload/${blobName}`
  );
  const data = await response.json();
  const sasToken = data.sasToken;
  const blockSize = 100 * 1024 * 1024; // 100MB
  const fileSize = file.size;
  const blockCount = Math.ceil(fileSize / blockSize);
  const blobURL = `https://${account}.blob.core.windows.net/${containerName}/${encodeURIComponent(
    blobName
  )}${sasToken}`;
  const pipeline = newPipeline(new AnonymousCredential());
  const blobClient = new BlockBlobClient(blobURL, pipeline);
  const blockIds = [];
  for (let i = 0; i < blockCount; i++) {
    const start = i * blockSize;
    const end = Math.min(start + blockSize, fileSize);
    const chunk = file.slice(start, end);
    const chunkSize = end - start;
    const blockId = btoa("block-" + i.toString().padStart(6, "0"));
    blockIds.push(blockId);
    await blobClient.stageBlock(blockId, chunk, chunkSize);
  }
  await blobClient.commitBlockList(blockIds);
};
const FilmUpload = (props) => {
  const [file, setFile] = useState();
  const fileChangeHandler = (e) => {
    if (e.target.files) {
      setFile(e.target.files[0]);
    }
  };
  const fileUploadHandler = () => {
    if (!file) {
      return;
    }
    uploadFilm(file);
  };
  return (
    <div className={styles.container}>
      Upload a file below to add it into films container into{" "}
      {process.env.REACT_APP_STORAGE_ACCOUNT_NAME}
      <br />
      <input
        type="file"
        placeholder="Select film to upload"
        onChange={fileChangeHandler}
      />
      <br />
      <button type="submit" onClick={fileUploadHandler}>
        Upload
      </button>
      <br />
      <br />
      {file && <p>Title of the uploaded film: {file.name}</p>}
    </div>
  );
};
export default FilmUpload;

can you help me solve this issue ?

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
3,200 questions
0 comments No comments
{count} votes

Accepted answer
  1. deherman-MSFT 38,021 Reputation points Microsoft Employee Moderator
    2023-04-04T22:29:13.42+00:00

    @Mariusz Budzisz Glad to hear you were able to resolve this issue! Thank you so much for posting the solution that worked for you. This is valuable to our community. Please do let us know if you have any more issues.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Mariusz Budzisz 25 Reputation points
    2023-04-03T18:04:56.66+00:00

    Actually I've solved it by myself as I've gone to https://www.npmjs.com/package/js-base64 package and now it runs perfectly.
    Ticket can be closed

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.