Skip to content

Commit

Permalink
Merge pull request #36 from clue-labs/origin
Browse files Browse the repository at this point in the history
Improve HTTP redirects to avoid exposing origin URL behind CDN
  • Loading branch information
clue committed Sep 10, 2023
2 parents 0770582 + 66c54cb commit d28410f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ the `live` branch like this:
$ make deploy
```

As a prerequisite, this should be deployed behind a CDN (Bunny CDN) that is
responsible for HTTPS certificate handling and forcing HTTPS redirects. This CDN
needs to be configured to pass the `X-Forwarded-Scheme` and `X-Forwarded-Host` HTTP
request headers to avoid exposing the origin URL in any HTTP redirects.

## Auto-Deployment

The website can be automatically deployed via the GitHub Pages feature.
Expand Down
37 changes: 24 additions & 13 deletions public/.htaccess
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
RewriteEngine On
RewriteRule ^docs/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}getting-started/ [R]

RewriteRule ^docs/getting-started/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}quickstart/ [R]
RewriteRule ^docs/best-practices/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}controllers/ [R]
RewriteRule ^docs/api/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}app/ [R]
RewriteRule ^docs/async/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}fibers/ [R]
RewriteRule ^docs/integrations/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}database/ [R]
# construct base URL for redirects from `X-Forwarded-Proto` and `X-Forwarded-Host`, otherwise empty to prefix current origin
RewriteCond %{HTTP:X-Forwarded-Proto} ^https?$
RewriteCond %{HTTP:X-Forwarded-Host} ^[a-zA-Z\d.-]+(:\d+)?$
RewriteRule .* - [ENV=BASE_URL:%{HTTP:X-Forwarded-Proto}://%{HTTP:X-Forwarded-Host}]

# redirect docs/ to right sub-directories
RewriteRule ^docs/$ %{ENV:BASE_URL}%{REQUEST_URI}getting-started/ [R]
RewriteRule ^docs/getting-started/$ %{ENV:BASE_URL}%{REQUEST_URI}quickstart/ [R]
RewriteRule ^docs/best-practices/$ %{ENV:BASE_URL}%{REQUEST_URI}controllers/ [R]
RewriteRule ^docs/api/$ %{ENV:BASE_URL}%{REQUEST_URI}app/ [R]
RewriteRule ^docs/async/$ %{ENV:BASE_URL}%{REQUEST_URI}fibers/ [R]
RewriteRule ^docs/integrations/$ %{ENV:BASE_URL}%{REQUEST_URI}database/ [R]

# redirect old "more" section (2021-11-23)
RewriteRule ^docs/more/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../getting-started/philosophy/ [R]
RewriteRule ^docs/more/philosophy/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../../getting-started/philosophy/ [R]
RewriteRule ^docs/more/architecture/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../../getting-started/philosophy/ [R]
RewriteRule ^docs/more/community/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../../getting-started/community/ [R]
RewriteRule ^docs/more/$ %{ENV:BASE_URL}%{REQUEST_URI}../getting-started/philosophy/ [R]
RewriteRule ^docs/more/philosophy/$ %{ENV:BASE_URL}%{REQUEST_URI}../../getting-started/philosophy/ [R]
RewriteRule ^docs/more/architecture/$ %{ENV:BASE_URL}%{REQUEST_URI}../../getting-started/philosophy/ [R]
RewriteRule ^docs/more/community/$ %{ENV:BASE_URL}%{REQUEST_URI}../../getting-started/community/ [R]

# redirect old "async" pages (2021-11-22)
RewriteRule ^docs/async/child-processes/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../../integrations/child-processes/ [R]
RewriteRule ^docs/async/streaming/$ %{REQUEST_SCHEME}://%{HTTP_HOST}%{REQUEST_URI}../../integrations/streaming/ [R]
RewriteRule ^docs/async/child-processes/$ %{ENV:BASE_URL}%{REQUEST_URI}../../integrations/child-processes/ [R]
RewriteRule ^docs/async/streaming/$ %{ENV:BASE_URL}%{REQUEST_URI}../../integrations/streaming/ [R]

# redirect requests to directories to self with trailing slash
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule [^/]$ %{ENV:BASE_URL}%{REQUEST_URI}/ [R=301]

# redirect requests to index pages to parent directory
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*/?)index.html$ %{REQUEST_SCHEME}://%{HTTP_HOST}/$1 [R=301]
RewriteRule ^(.*/?)index.html$ %{ENV:BASE_URL}/$1 [R=301]
13 changes: 13 additions & 0 deletions tests/acceptance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,26 @@ match() {
echo "$out" | grep "$@" >/dev/null && echo -n . || \
(echo ""; echo "Error in test $n: Unable to \"grep $@\" this output:"; echo "$out"; exit 1) || exit 1
}
skipif() {
echo "$out" | grep "$@" >/dev/null && echo -n S && return 1 || return 0
}

out=$(curl -v $base/ 2>&1); match "HTTP/.* 200" && match -iP "Content-Type: text/html[\r\n]"
out=$(curl -v $base/invalid 2>&1); match "HTTP/.* 404" && match -i "Content-Type: text/html"

out=$(curl -v $base/docs 2>&1); match "HTTP/.* 301" && match -iP "Location: .*/docs/[\r\n]"
out=$(curl -v $base/docs/ 2>&1); match "HTTP/.* 302" && match -iP "Location: .*/docs/getting-started/[\r\n]"

out=$(curl -v $base/docs -H 'X-Forwarded-Host: example.com' -H 'X-Forwarded-Proto: https' 2>&1);
match "HTTP/.* 301"
skipif -iP "Location: $base/docs/[\r\n]" &&
match -iP "Location: https://example\.com/docs/[\r\n]"

out=$(curl -v $base/docs/ -H 'X-Forwarded-Host: example.com' -H 'X-Forwarded-Proto: http' 2>&1);
match "HTTP/.* 302"
skipif -iP "Location: $base/docs/[\r\n]" &&
match -iP "Location: http://example\.com/docs/getting-started/[\r\n]"

out=$(curl -v $base/docs/getting-started/ 2>&1); match "HTTP/.* 302" && match -iP "Location: .*/docs/getting-started/quickstart/[\r\n]"
out=$(curl -v $base/docs/best-practices/ 2>&1); match "HTTP/.* 302" && match -iP "Location: .*/docs/best-practices/controllers/[\r\n]"
out=$(curl -v $base/docs/api/ 2>&1); match "HTTP/.* 302" && match -iP "Location: .*/docs/api/app/[\r\n]"
Expand Down

0 comments on commit d28410f

Please sign in to comment.