Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDF file rendered in browser as HTML file #140

Open
SserwangaV opened this issue Oct 6, 2023 · 6 comments
Open

PDF file rendered in browser as HTML file #140

SserwangaV opened this issue Oct 6, 2023 · 6 comments

Comments

@SserwangaV
Copy link

SserwangaV commented Oct 6, 2023

I have this code that reads a PDF file as an Erlang binary and sends it to the browser

%% -*- mode: nitrogen -*-
-module(pdf_file).
-include_lib("nitrogen_core/include/wf.hrl").
-export([main/0]).

main() -> 
     wf:content_type( "application/pdf"),
     wf:download_as("document.pdf"),
     {ok, Data} = file:read_file("document.pdf"),
     Data.

What disturbs me is that it's rendered as an HTML file! Some time back the same code could render it properly.

pdf_file_rendered_as_html

@choptastic
Copy link
Member

Hi @SserwangaV!

Odd indeed. Not sure why the download_as/1 isn't working as expected. I'm looking into it.

That said, using the "Elements" tab of the inspector can be a little misleading.

If you right click the page and choose "View page source", you'll see the actual code being transmitted. The inspecter will create dummy elements to show how the DOM is actually represented internally.

You can see this at work if you look at a page like this:

https://nitrogenproject.com/demos/viewsource?module=demos_simplecontrols

In the inspector, it's creating html, head, body, and pre tags, while if you just do "View Source," it'll just show the raw code. So I wouldn't be alarmed that nitrogen is injecting HTML into your page.

Now as for why download_as isn't working as expected here, what webserver are you using?

Further, you can inspect the response in the "Network" tab, and from the "Headers" tab, you'll see what Content-Type is being received by the browser.

@SserwangaV
Copy link
Author

SserwangaV commented Oct 10, 2023

"View page source" shows a blank display (is empty).

The response headers are attached.

The Content-Type is set to text/html. I expected the Content-Type to be set to application/pdf because I set it as wf:content_type( "application/pdf").

Content-Disposition seems to be set properly. To set it, I used
wf:header("Content-Disposition", "inline; filename=\"dotShule - " ++ FileName ++ ".pdf"\"")

response headers

The console error is attached

console error

@choptastic
Copy link
Member

I'm still quite stumped here.

This is behind an nginx proxy. What is your webserver? Yaws? Is it possible that there is something going on with nginx that's changing the content-type?

If you access the nitrogen server directly with a script like this:

curl -o /dev/null -s -D headers.txt "http://127.0.0.1:8000/path/to/file"
cat headers.txt

That should return the headers of the requested file as they are returned from Nitrogen and passed to nginx.

If Nitrogen is returning the proper value, perhaps nginx is doing something with the file?

@SserwangaV
Copy link
Author

It is Nitrogen on Yaws proxied behind Nginx. Without the Nginx proxy, the content-type is set properly to application/pdf. It is the Nginx that modifies it to text/html.

I've used proxy_pass_header Content-Type; Nginx directive to keep the content-type set in the response of the proxied server, however, it is not effective. Reference

The file content-type varies and files binaries are referenced from the database using keys rather than the file names with extensions. File names and extensions (used to determine the content-type upon serving the file) are kept in the database as file metadata.

File path takes this format https://example.com/xx_file?key=1000049202021000035221627141182. The key is the file's primary key in the database.

@choptastic
Copy link
Member

Alright, that helps to clarify some things.

If nginx is changing the headers, then this is fully an nginx configuration issue (of which I'm no expert).

You could try adding the proxy_hide_header directive together with the already used proxy_pass_header.

proxy_hide_header Content-Type;
proxy_pass_header Content-Type;

@SserwangaV
Copy link
Author

Tried it, however, it didn't work.

I've a local instance of the application on my laptop and on this one Nginx doesn't modify the content-type. It only does it on the one in production.

I'm likely to think the nginx version could be an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants