Allowing both http and https on a specific path only

1. Caddy version (caddy version):

v2.4.5 h1:P1mRs6V2cMcagSPn+NWpD+OEYUYLIf6ecOa48cFGeUg=

2. How I run Caddy:

docker-compose

a. System environment:

docker-compose

b. Command:

docker-compose

c. Service/unit/compose file:

caddy:
  environment:
    - CADDY_TLS
    - DOMAIN_NAME
    - TZ=Europe/London
  image: caddy
  ports:
    - "443:443"
    - "80:80"
  restart: always
  volumes:
    - ./deployment/Caddyfile:/etc/caddy/Caddyfile
    - caddy_config:/config
    - caddy_data:/data
    - django_static:/app/static
    - django_media:/app/media

d. My complete Caddyfile or JSON config:

{$DOMAIN_NAME} {
	# serve some files directly from caddy rather than through django/unicorn for performance
	root * /app # needed for file_server
	file_server /static/* # assets e.g. js, css
	file_server /media/* # uploaded files e.g. OTA updates

	# various reverse proxies which strip the TLS part and pass through http
	reverse_proxy /ws rabbitmq:15675 # mqtt websocket for controllers
	reverse_proxy /rabbitmq/* rabbitmq:15672 # rabbitmq admin
	reverse_proxy /grafana/* grafana:3000 # grafana for internal use
	reverse_proxy /portal/* portal:3000 # custom grafana instance for landlord portal

	# for all other web requests and not /static or /media, proxy to Django
	@not_served {
		not path /static/* /media/*
	}
	reverse_proxy @not_served web:8000

	tls {$CADDY_TLS} # generate ssl cert automatically
	encode gzip # encode gzip for performance
	log {
		level WARN
	}
}

# don't redirect http->https for firmware as needed by some devices
http://{$DOMAIN_NAME}/media/firmware {
	root * /app
	file_server /media/firmware/*
}

3. The problem I’m having:

By default caddy redirects all http requests to https, but I would like to allow both http and https requests for just one specific path on a website. I tried to do this using the caddyfile above but when I do curl -v <address>, it shows HTTP/1.1 308 Permanent Redirect using curl -v, and is still redirecting to https.

4. Error messages and/or full log output:

See above

5. What I already tried:

See last part of caddyfile above starting with http:. I referenced this stack overflow answer but may be getting confused: caddyfile - How to serve both http and https with Caddy? - Stack Overflow

That’s an old post from 2018, for Caddy v1. Caddy v1 syntax does not apply to Caddy v2.

In Caddy v2, path matchers are exact-match, so matching on /media/firmware will only match requests to /media/firmware and not /media/firmware/foo for example. You had the path matcher essentially correct on your file_server directive, using * to match the rest.

But I would do it like this:

http://{$DOMAIN_NAME} {
	handle /media/firmware* {
		root * /app
		file_server
	}

	# Fallback to redirect
	handle {
		redir https://{host}{uri} 308
	}
}
1 Like

Thanks, that worked.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.