Determine mime type based on (PDF-) content?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Determine mime type based on (PDF-) content?

Postby digory » Thu Mar 12, 2020 10:10 am

When I point CEF to an URL ending in the extension .pdf, CEF would open the PDF content in an integrated PDF viewer. However, if the URL does not end in .pdf, CEF would not display it, but instead call OnLoadError with ERR_ABORTED. I'm not sure, but I suspect it's because CEF does not look at the data when determining the mime type.

If I wanted to determine the mime-type based on content, how would I do this?
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Determine mime type based on (PDF-) content?

Postby magreenblatt » Thu Mar 12, 2020 11:39 am

What CEF version? What Content-Type response header is the server returning for the PDF file? How does it behave in Google Chrome at the same version?
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Determine mime type based on (PDF-) content?

Postby digory » Mon Mar 30, 2020 7:07 am

Sorry for not replying, I had other priorities.

I have now upgraded to CEF 80.0.8+gf96cd1d+chromium-80.0.3987.132. The problem is the same. Here's what happens:

Code: Select all
KisCefLifeSpanHandler::OnBeforePopup, targetUrl=***url***, extraInfo=null
KisCefLifeSpanHandler::OnAfterCreated
KisCefApp::OnBrowserCreated: 3
KisCefLoadHandler::OnLoadingStateChange: isLoading=true
KisCefRequestHandler::OnBeforeBrowse, isUserGesture=1, isRedirect=0
KisCefRequestHandler::GetResourceRequestHandler, isNavigation=1, isDownload=0, initiator=null
headers: 5
   - Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
   - Accept-Language: en-US,en;q=0.9
   - Sec-Fetch-Dest: document
   - Upgrade-Insecure-Requests: 1
   - User-Agent: Custom
KisCefClient::OnStatusMessage
KisCefLoadHandler::OnLoadError: ERR_ABORTED
KisCefLoadHandler::OnLoadingStateChange: isLoading=false


In Chrome, the PDF isn't shown inline either. A tab is opened and immediately closed, and a download starts. The PDF looks alright in SumatraPDF.

Can I tell CEF to force-open the file in the internal PDF viewer?
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Determine mime type based on (PDF-) content?

Postby magreenblatt » Mon Mar 30, 2020 10:51 am

The best option is to fix the server so that it returns the correct Content-Type, or adds the .pdf extension. Otherwise, you will need to download the file (using CefURLRequest, for example) and then stream the contents with the correct headers via CefResourceHandler. See the documentation here.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Determine mime type based on (PDF-) content?

Postby digory » Tue Mar 31, 2020 4:46 am

OK, thanks. If I wanted to download all files that cannot be directly opened (like Chrome does), how would I do this? Is there a hook that is called when CEF decides it cannot show the file in the browser? Or should I wait until OnLoadError is called, and retry and download the file?
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Determine mime type based on (PDF-) content?

Postby ndesktop » Tue Mar 31, 2020 9:31 am

Files not handled in chrome content will go thru download. Best to implement CefDownloadHandler for your purposes.
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am

Re: Determine mime type based on (PDF-) content?

Postby digory » Tue Apr 14, 2020 8:15 am

Thanks. I was able to implement CefDownloadHandler, the PDF is now downloaded. However, the user experience is still far from perfect:

  • When the user clicks the link, a blank popup window is opened.
  • A "save as" dialog is opened. The user selects the folder and clicks "OK".
  • The PDF is downloaded to the selected folder. However, the popup window stays open and shows the error message "ERR_ABORTED".

Here's what happens in code:

  • KisCefLifeSpanHandler::OnBeforePopup, the url argument is the URL of the PDF
  • KisCefLifeSpanHandler::OnAfterCreated
  • KisCefApp::OnBrowserCreated
  • KisCefLoadHandler::OnLoadingStateChange: isLoading=true
  • KisCefRequestHandler::OnBeforeBrowse, isUserGesture=1, isRedirect=0
  • KisCefRequestHandler::GetResourceRequestHandler, isNavigation=1, isDownload=0, initiator=null
  • KisCefLoadHandler::OnLoadError: ERR_ABORTED.
  • KisCefLoadHandler::OnLoadingStateChange: isLoading=false

My implementation of OnLoadError creates an error page (data URL) and loads it into the browser with LoadUrl:

  • KisCefLoadHandler::OnLoadingStateChange: isLoading=true
  • KisCefRequestHandler::OnBeforeBrowse, isUserGesture=0, isRedirect=0
  • KisCefDownloadHandler::OnBeforeDownload
  • KisCefRequestHandler::GetResourceRequestHandler, isNavigation=1, isDownload=0, initiator=null. The url is my error page (data url).

At this point, the new popup window is still blank, and the "save as" dialog is showing. When the user hits "OK":

  • KisCefApp::OnBrowserCreated
  • KisCefApp::OnContextCreated
  • KisCefDisplayHandler::OnAddressChange, the url is my error page
  • KisCefLoadHandler::OnLoadEnd, HTTP Status=200
  • KisCefLoadHandler::OnLoadingStateChange, isLoading=false

I basically want to prevent the popup from opening (but I still want the "save as" dialog, and I don't want to block popups in general). If that's not easily possible, I would at least want that the popup automatically closes when the download starts. However, OnLoadEnd with Status 200 refers to loading the error page, not to the download. I can implement OnDownloadUpdated to detect when the download completes (not sure if this would be a reliable method, though), but I can't tell if I should close the browser at this point, because the download could have been started otherwise (not via popup).

The Chrome browser seems to be able to handle this. It opens a tab and immediately closes it as the download starts. How do I do this?
digory
Expert
 
Posts: 118
Joined: Wed Oct 26, 2016 3:13 am

Re: Determine mime type based on (PDF-) content?

Postby ndesktop » Tue Apr 14, 2020 9:26 am

Most likely in the OnLoadError you should check is there is a document (I believe HasDocument has been added for such cases).
So
OnBeforeDownload => mark browser as downloading in some variable associate with browser, say it isDownloading_ = true
OnLoadError can be something like "if(IsPopup() && !HasDocument() && isDownloading_) => close browser".
ndesktop
Master
 
Posts: 750
Joined: Thu Dec 03, 2015 10:10 am


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 37 guests