espresso3389 / pdfrx

pdfrx is yet another PDF viewer implementation that built on the top of PDFium. The plugin currently supports Android, iOS, Windows, macOS, Linux, and Web.
MIT License
117 stars 55 forks source link

PdfException: Failed to load PDF document (FPDF_GetLastError=3) #166

Closed letrungdo closed 5 months ago

letrungdo commented 5 months ago

When I load this url an exception occurs.

PdfViewer.uri(
    Uri.parse("https://www.tutorialspoint.com/flutter/flutter_tutorial.pdf"),
    ...
)

Testing environment: Flutter MacOS

But when I try with another url it works fine. Ex: https://www.diva-portal.org/smash/get/diva2:1560848/FULLTEXT01.pdf

espresso3389 commented 5 months ago

Sorry, I didn't check the issue title :( Your report does not contain any info. about what exception thrown actually. Normally you should provide more specific info. for your issue.

Anyway, just testing the PDF with my environment results in

PdfException: Failed to load PDF document (FPDF_GetLastError=3).

...

And the error 3 means FPDF_ERR_FORMAT. I don't know what it means because it's a pdfium error. But opening the PDF with Google Chrome 127.0.6510.4 succeeded. So it seems to be some kind of pdfium's known issue with the pdfium version pdfex uses.

espresso3389 commented 5 months ago

Just checking the code shows me that the latest pdfrx used pdfium 6406 so it implies that upgrading the pdfium to 6510 or higher may fix the issue.

espresso3389 commented 5 months ago

~~https://github.com/bblanchon/pdfium-binaries/releases shows me that the latest pdfium binary for non-darwin platforms is 6517. OK, it may be the time to upgrade the modules...~~

espresso3389 commented 5 months ago

Futher investigation shows me that the downloading of the file failed constantly.

espresso3389 commented 5 months ago

Mmm, the server, named ECLF (I'm not sure what it is), responses with HTTP 400...

image

And, I found that my code does not have correct HTTP error handling code (that is not the cause of the issue anyway).

letrungdo commented 5 months ago

@espresso3389 I tried using InternetFile.get it returns 200


import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

typedef InternetFileProgress = void Function(
  int receivedLength,
  int contentLength,
);
class InternetFile {
  static Future<Uint8List> get(
    String url, {
    Map<String, String>? headers,
    InternetFileProgress? progress,
    bool force = false,
    String method = 'GET',
    bool debug = false,
  }) async {
    final completer = Completer<Uint8List>();
    final httpClient = http.Client();
    final request = http.Request(method, Uri.parse(url));
    if (headers != null) {
      request.headers.addAll(headers);
    }
    final response = httpClient.send(request);

    List<int> bytesList = [];
    int receivedLength = 0;

    response.asStream().listen((http.StreamedResponse request) {
      request.stream.listen(
        (List<int> chunk) {
          receivedLength += chunk.length;
          final contentLength = request.contentLength ?? receivedLength;
          final percentage = receivedLength / contentLength * 100;

          if (debug) {
            debugPrint('download progress: $receivedLength of '
                '$contentLength ($percentage%)');
          }
          progress?.call(receivedLength, contentLength);

          bytesList.addAll(chunk);
        },
        onDone: () {
          final bytes = Uint8List.fromList(bytesList);

          completer.complete(bytes);
        },
        onError: completer.completeError,
      );
    }, onError: completer.completeError);
    return completer.future;
  }
}
espresso3389 commented 5 months ago

Yes, I think the actual cause of the issue is the server's implementation (it mis-handles HTTP range requests) but I'm now working on my code to fix it.

espresso3389 commented 5 months ago

1.0.66 fixes the issue.

letrungdo commented 5 months ago

@espresso3389 Thank you so much for quick fix!

letrungdo commented 5 months ago

@espresso3389 The above error has been fixed. However, there is still a previous error. When I try with this url: https://www.kansaigaidai.ac.jp/asp/img/pdf/82/7a79c35f7ce0704dec63be82440c8182.pdf then an exception occurs: LateInitializationError: Field '_cacheBlockCount@1436474497' has not been initialized.

espresso3389 commented 5 months ago

I see. It's just another issue. OK, I'll check it.