react-doc-viewer icon indicating copy to clipboard operation
react-doc-viewer copied to clipboard

Error 404 when accessing s3 urls for docx even if it is existing

Open JmAngeles opened this issue 2 years ago • 15 comments

Hi,

Has anyone encountered this error when accessing s3 urls via DocViewerRenderers? image

The scenario is, I am passing an s3 url docx file, once I render the document, the initial response is 404 but then after a while, the document will load and everything is fine but sometimes the documents is just stuck on loading. But everytime I reopen/rerender via the react-doc-viewer, it returns a response of 404 first before loading the document. image

Appreciate all the assistance. Thank you!

JmAngeles avatar Feb 02 '23 11:02 JmAngeles

I am also seeing this issue once the application is hosted on S3. I do not see this when running locally though. What I did have to do (locally) was ensure that when loading the document to S3, it was using the proper contentType to S3:

const parsedPath = path.parse(file.originalname);
const parsedExtension = parsedPath.ext?.toLowerCase() || '';

switch (parsedExtension) {
    case '.pdf':
        contentType = 'application/pdf';
        break;
    case '.jpg':
        contentType = 'image/jpeg';
        break;
    case '.jpeg':
        contentType = 'image/jpeg';
        break;
    case '.png':
        contentType = 'image/png';
        break;
    case '.docx':
        contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
        break;
    case '.xlsx':
        contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        break;
    case '.zip':
        contentType = 'application/zip';
        break;
}

await this.s3Service.putObject({
    Bucket: this.awsConfig.s3UploadBucketName,
    Key: fileDropLocation,
    Body: fileStream,
    ContentType: contentType,
});

You may also want to be sure CORS is allowed on the bucket that is hosting the file(s):

[
    {
        "AllowedHeaders": [
            "Authorization"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]

Or more restrictive if you know what the origins will be.

If you are in the same situation as I am, I am starting to make sure it isn't network (NACL, SG) related.

jsonpj3wt avatar Feb 03 '23 05:02 jsonpj3wt

So, I did figure out the issue, and I have seen this before...

If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.

jsonpj3wt avatar Feb 03 '23 07:02 jsonpj3wt

Sorry forgot to mention that I am not using a pre-signed URL. For now we're using a public url from s3 bucket @jsonpj3wt. I am still figuring out what is the issue by going through the library/package itself.

JmAngeles avatar Feb 03 '23 13:02 JmAngeles

If you are using a public url, check the metadata on the file it is trying to render. My guess is it is not set properly for ContentType or a CORS issue.

If you go with Pre-signed URLs, the issue is AWS will append the X-Amz-Security-Token for any role that generates the URL.

My issue might be related to either the URL length or on Microsoft's end since the URL actually works to download with either URL.

jsonpj3wt avatar Feb 03 '23 17:02 jsonpj3wt

Have tried putting a handler on it? I have tried using the loadingRenderer and noRenderer api/components of the package but no luck at all. @jsonpj3wt

JmAngeles avatar Feb 03 '23 19:02 JmAngeles

Still have a problem when trying to load PDF file from S3, S3 link is public.

S3 link format:

https://<bucket_name>.s3.<aws_region>.amazonaws.com/<file_name>

otarasovqs avatar May 23 '23 16:05 otarasovqs

not sure if anyone has this issue but I had to specify a fileType to render my s3 file

const docs = [{ uri: "____ ", fileType: "pdf" }];

vdo9 avatar Jun 30 '23 18:06 vdo9

Same here, impossible to get any file from S3, no matter it's file type, it always ends with CORS errors.

BenElferink avatar Jul 13 '23 13:07 BenElferink

I have issue with Azure storage account, that my pdf could render, but not for the excel...

zhongshuai-cao avatar Oct 04 '23 20:10 zhongshuai-cao

So, I did figure out the issue, and I have seen this before...

If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.

@jsonpj3wt Do you happen to remember exactly how it was funky? I'm running into what seems like the same issue, and gone through a whole process verifying that there's not an initial request being cached, content-type is correct, and the CORS configuration is sane. We did relatively recently switch to using service accounts, but the associated policies are exactly the same as they always have been.

Strangely, only .docx, .xlsx, etc files seem to fail. .doc, .pdf, .xls, and others are all fine.

collagenial avatar Feb 07 '24 07:02 collagenial

not sure if anyone has this issue but I had to specify a fileType to render my s3 file

const docs = [{ uri: "____ ", fileType: "pdf" }];

It works for me. But I decided to investigate more and finally found a reason in the Fetch. S3 doesn't work with HEAD method. That is why I set prefetchMethod="GET" in DocViewer and now everything is ok.

shershak-adv avatar Feb 08 '24 14:02 shershak-adv

Adding prefetchMethod="GET" worked for me

<DocViewer prefetchMethod="GET" style={{ borderRadius: "10px", height: "100%" }}
      documents={[{ fileType: selectedDoc?.fileType, fileName: selectedDoc?.name, uri: selectedDoc?.uri }]}
      pluginRenderers={DocViewerRenderers}
      config={{
        loadingRenderer: {
          overrideComponent: MyLoadingRenderer,
        },
      }}
    />

ermarkar avatar Mar 04 '24 05:03 ermarkar

So, I did figure out the issue, and I have seen this before... If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.

@jsonpj3wt Do you happen to remember exactly how it was funky? I'm running into what seems like the same issue, and gone through a whole process verifying that there's not an initial request being cached, content-type is correct, and the CORS configuration is sane. We did relatively recently switch to using service accounts, but the associated policies are exactly the same as they always have been.

Strangely, only .docx, .xlsx, etc files seem to fail. .doc, .pdf, .xls, and others are all fine.

In our case, it turned out that this was a URL length issue - Microsoft did not like the URL since we switched to using a pre-signed URL, because the X-Amz-Security-Token is quite lengthy.

We implemented a custom URL shortener and now everything works fine.

collagenial avatar Mar 04 '24 17:03 collagenial

not sure if anyone has this issue but I had to specify a fileType to render my s3 file

const docs = [{ uri: "____ ", fileType: "pdf" }];

Thank you is working fine for me1

MohssineSERRAJI avatar May 10 '24 19:05 MohssineSERRAJI