最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Range requests not working as expected with Dynamic API source - Stack Overflow

programmeradmin0浏览0评论

I'm implementing the range requests feature in ngx-extended-pdf-viewer to improve the loading performance of large PDF files.

Setup & expected behavior

I have added the following configuration in my Angular code:

<ngx-extended-pdf-viewer #pdfViewer
                         [src]="src"
                         [useBrowserLocale]="true">

pdfDefaultOptions.disableAutoFetch = true;  
pdfDefaultOptions.disableStream = false;  
pdfDefaultOptions.disableRange = false;  

When using a static file path, such as:

this.src = '/assets/100MB-TESTFILE.pdf'; 

The 100 MB file starts rendering after loading just 10 MB, with the remaining data fetched progressively.

Issue

However, when I use an API-generated file URL, such as:

this.src = this.apiService.getDocumentFileURl();

getDocumentFileURl() {
    return `${api_root}/document/${this.session.documentId}/version/${this.session.version}/view?language=${Helpers.getQueryParam('language', 'en')}&token=${this.session.token}`;
}

The PDF file is not displayed until 50 MB has been loaded, significantly increasing the loading time.

Back-end API implementation

The API responds to range requests using the following Java Jersey-based implementation:

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Authorized
@Path("view")
public Response view(@QueryParam("language") String language, @Context ContainerRequestContext crc) throws Exception {
    try {
        String token = Token.getToken(crc);
        UserDocument userDocument = (UserDocument) crc.getProperty(UserDocument.USER_DOCUMENT_KEY);
        String filePath = userDocument.getVersion().getFileType() == FileType.VIDEO
                          ? userDocument.getVersion().getFilePath()
                          : userDocument.getVersion().getPDFCopyPath();

        if (!Files.exists(Paths.get(filePath))) {
            return Response.status(Status.NOT_FOUND).build();
        }

        InputStream fileStream = Helpers.getFileInputStreamForRead(filePath);
        long fileLength = fileStream.available();

        String rangeHeader = crc.getHeaderString("Range");

        if (rangeHeader != null && rangeHeader.startsWith("bytes=")) {
            // Parse Range Header
            String[] ranges = rangeHeader.substring("bytes=".length()).split("-");
            long start = Long.parseLong(ranges[0]);
            long end = ranges.length > 1 ? Long.parseLong(ranges[1]) : fileLength - 1;

            // Validate range
            if (start >= fileLength || end >= fileLength) {
                return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE)
                               .header("Content-Range", "bytes */" + fileLength)
                               .build();
            }

            long contentLength = end - start + 1;
            fileStream.skip(start);

            return Response.status(Response.Status.PARTIAL_CONTENT)
                           .entity(fileStream)
                           .header("Access-Control-Expose-Headers", "Accept-Ranges")
                           .header("Access-Control-Allow-Headers", "Accept-Ranges,range")
                           .header("Content-Range", "bytes " + start + "-" + end + "/" + fileLength)
                           .header("Accept-Ranges", "bytes")
                           .header("Content-Length", contentLength)
                           .header("Content-Type", "application/pdf; charset=UTF-8")
                           .build();
        }

        // If no Range header, return the entire file
        return Response.ok()
                       .header("Access-Control-Expose-Headers", "Accept-Ranges")
                       .header("Access-Control-Allow-Headers", "Accept-Ranges,range")
                       .header("Accept-Ranges", "bytes")
                       .header("Content-Length", fileLength)
                       .header("Content-Type", "application/pdf; charset=UTF-8")
                       .entity(fileStream)
                       .build();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}

Question

How can I modify my implementation so that the dynamic API source behaves like the static source, allowing the PDF to load progressively after 10 MB, rather than requiring 50 MB before rendering begins?

Any insights into how ngx-extended-pdf-viewer handles range requests dynamically would be greatly appreciated.

发布评论

评论列表(0)

  1. 暂无评论