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

Incorrect Content-Type results in firmware files opening in the browser #1059

Open
0nelight opened this issue Oct 26, 2024 · 7 comments · May be fixed by #1064
Open

Incorrect Content-Type results in firmware files opening in the browser #1059

0nelight opened this issue Oct 26, 2024 · 7 comments · May be fixed by #1064

Comments

@0nelight
Copy link

0nelight commented Oct 26, 2024

Download-Links to a notable amount of built Images via the Browser-Interface of the public Firmware-Selector-Server on the public ASU are being advertised as content-type: text/stream; charset=utf-8 instead of from content-type: application/octet-stream the Webserver running on ASU.

This leads to the Issue where, when clicking on the Download-Button, instead of Firefox opening the Download-File-Dialog, it interprets the File as a Webpage and tries to render it. Workaround is clicking "Save Target as".

I am not sure if I should put this here or at firmware-selector-openwrt-org - therefore I created a Ticket there too.

While Chrome Browser seems to take care of this misconfiguration, Firefox doesn't.

@0nelight 0nelight changed the title Download Link Opens Binary File in Browser Instead of Prompting Download (Custom Images) (Firefox) Download Link Opens Binary File in Browser Instead of Prompting Download (Custom Images) Oct 26, 2024
@0nelight 0nelight changed the title (Firefox) Download Link Opens Binary File in Browser Instead of Prompting Download (Custom Images) Download Link Opens Binary File in Browser Instead of Prompting Download (Custom Images) Oct 26, 2024
@AliveDevil
Copy link

AliveDevil commented Oct 26, 2024

Context chain:

All that is to say: ASU should probably register mimetypes.add_type("application/octet-stream", ".img").
Godbolt sample

@0nelight
Copy link
Author

0nelight commented Oct 27, 2024

@AliveDevil So mimetypes not recognizing ".img" is one thing - but in my example the file ending is ".gz". It seems guess_type reads the mime-types from system files, which maybe are missing in the docker image?

python:3.6.4-slim can not guess extension well

@AliveDevil
Copy link

Check the godbolt output: Python can guess encoding and file type separately.
Any .X.Y file is checked against the encoding list of file extensions (i.e. gz, xz, bz2) - this is ignored and dropped by starlette.
So a .jpg.bz2 would be (application/jpeg, BZip).

Starlette only cares about the guessed type: in this case .img evaluates to None, which is then falled back to text/plain.

This could be fixed by editing the mime.types file, or just fixed in application code, which would be less error-prone for users.

@0nelight 0nelight changed the title Download Link Opens Binary File in Browser Instead of Prompting Download (Custom Images) Download Link Opens .IMG Files in Browser Instead of Prompting Download (Custom Images) Oct 27, 2024
@0nelight 0nelight changed the title Download Link Opens .IMG Files in Browser Instead of Prompting Download (Custom Images) Download Link Opens .IMG Files in Browser Instead of Prompting Download Oct 27, 2024
@0nelight 0nelight changed the title Download Link Opens .IMG Files in Browser Instead of Prompting Download Wrong HTTP Content-Type for .IMG-Files Oct 27, 2024
@0nelight
Copy link
Author

0nelight commented Oct 27, 2024

So this would mean we have to do mimetypes.add_type for other File Extensions too.

I queried the firmware names and found the following non-duplicated list:

Base Name Extension
netgear_wndap620-squashfs-factory.img img
netgear_wndr4700-device-tree.dtb dtb
wd_mybooklive-ext4-factory.img.gz img; gz
atmel_at91sam9263ek-ext4-root.ubi.gz ubi; gz
atmel_at91sam9263ek-fit-zImage.itb itb
atmel_at91sam9263ek-squashfs-root.ubi ubi
atmel_at91sam9g15ek-uImage
engenius_epg5000-squashfs-factory.dlf dlf
standard-squashfs.trx trx
netgear_r6200-v1-squashfs.chk chk
luxul_abr-4500-squashfs.lxl lxl
gateworks_ventana-squashfs-img.gz gz
toradex_apalis-recovery.scr scr
google_wifi-initramfs-fit-zImage.itb.vboot itb; vboot
netgear_wax218-web-ui-factory.fit fit
ctera_c200-v1-initramfs-factory.firm firm
iom_iconnect-1.1-initramfs-uImage 1-initramfs-uImage
vmlinux-initramfs.elf elf
bananapi_bpi-r3-emmc-bl31-uboot.fip fip
wevo_air-duo-initramfs.upload upload
netgear_gs750e-squashfs-factory.bix bix

So because anyway ASU provides Firmware-Files always it should always set content-type: application/octet-stream.
But because the File Extensions are not a limited set, setting it with mimetypes.add_type() would be not reliable.

Maybe something along these lines?

class FirmwareFiles(StaticFiles):
    async def get_response(self, path: str, scope):
        response = await super().get_response(path, scope)
        response.headers["Content-Type"] = "application/octet-stream"
        return response

app.mount("/store", FirmwareFiles(directory=settings.public_path / "store"), name="store")

@0nelight 0nelight changed the title Wrong HTTP Content-Type for .IMG-Files Incorrect Content-Type results in firmware files opening in the browser Oct 27, 2024
@0nelight 0nelight reopened this Oct 28, 2024
@aparcar
Copy link
Member

aparcar commented Oct 28, 2024

Hi, I love how you analyze the issue and come up with ideas. I'm currently a bit focused to spent my OpenWrt time on the APK migration so don't really do stuff for ASU. If you need anything specific, please ping me.

@aparcar
Copy link
Member

aparcar commented Oct 28, 2024

This is the current Caddyfile, maybe someone got an idea how to improve it?

(cors) {
	@cors_preflight method OPTIONS

	header {
		Access-Control-Allow-Origin "{header.origin}"
		Vary Origin
		Access-Control-Expose-Headers "Authorization"
		Access-Control-Allow-Credentials "true"
	}

	handle @cors_preflight {
		header {
			Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE"
			Access-Control-Max-Age "3600"
		}
		respond "" 204
	}
}

{
	auto_https disable_redirects
	preferred_chains {
		root_common_name "ISRG Root X1"
	}
}

asu-02.infra.openwrt.org asu-02.infra.openwrt.org:80 sysupgrade.openwrt.org sysupgrade.openwrt.org:80 {
	tls mail@aparcar.org
	root * /home/openwrt/store/
	file_server /store/* 
        import cors {header.origin}
	header Access-Control-Allow-Methods "POST, GET, OPTIONS"
	header Access-Control-Allow-Headers "*"
	header Access-Control-Allow-Origin "*"
	reverse_proxy * localhost:8000
	redir /api/overview /json/v1/overview.json
}

@AliveDevil
Copy link

Can create a PR tomorrow (CET) with an improved staticfiles handler.

the bandaid solution would be Caddy handle-path on the /store-prefix to overwrite the content-type: https://caddyserver.com/docs/caddyfile/directives/handle_path

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