Handle trailing slashes in static content
This commit is contained in:
		
							parent
							
								
									5fa226284b
								
							
						
					
					
						commit
						1cfe805689
					
				
					 3 changed files with 12 additions and 6 deletions
				
			
		
							
								
								
									
										8
									
								
								TODO.md
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								TODO.md
									
										
									
									
									
								
							|  | @ -1,15 +1,19 @@ | ||||||
| # To-do | # To-do | ||||||
| 
 | 
 | ||||||
|  | * split the template/content files out from `conservancy/static` into their own | ||||||
|  |   `content` directory (avoid mixing static and non-static content) | ||||||
| * ask Denver about why so many license files | * ask Denver about why so many license files | ||||||
| * serve a 400 in Apache for a hostname we don't explicitly support | * serve a 400 in Apache for a hostname we don't explicitly support | ||||||
| * use `<detail>` elements for supporter page hidden sections, rather than complex jQuery - or consider Alpine.js | * use `<detail>` elements for supporter page hidden sections, rather than | ||||||
|  |   complex jQuery - or consider Alpine.js | ||||||
| * replace `internalNavigate` with inline flexbox layout | * replace `internalNavigate` with inline flexbox layout | ||||||
| * add tests for main pages returning 200 | * add tests for main pages returning 200 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Done | # Done | ||||||
| 
 | 
 | ||||||
| * remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and HTTPS redirect is done by Apache | * remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and | ||||||
|  |   HTTPS redirect is done by Apache | ||||||
| * standardise settings to replace `settings.py` and `djangocommonsettings.py` | * standardise settings to replace `settings.py` and `djangocommonsettings.py` | ||||||
|   with `settings/prod.py` and move `SECRET_KEY` to an environment variable |   with `settings/prod.py` and move `SECRET_KEY` to an environment variable | ||||||
| * migrate to Django 4.2 LTS | * migrate to Django 4.2 LTS | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ urlpatterns = [ | ||||||
|     re_path(r'^learn/', static_views.index), |     re_path(r'^learn/', static_views.index), | ||||||
|     re_path(r'^press/', static_views.index), |     re_path(r'^press/', static_views.index), | ||||||
|     re_path(r'^projects/', static_views.index), |     re_path(r'^projects/', static_views.index), | ||||||
|     re_path(r'^GiveUpGitHub', static_views.index), |     re_path(r'^GiveUpGitHub/', static_views.index), | ||||||
|     re_path(r'^npoacct/', static_views.index, {'fundraiser_sought': 'npoacct'}), |     re_path(r'^npoacct/', static_views.index, {'fundraiser_sought': 'npoacct'}), | ||||||
|     path('contractpatch/', include('conservancy.contractpatch.urls')), |     path('contractpatch/', include('conservancy.contractpatch.urls')), | ||||||
|     re_path(r'^overview/', static_views.index), |     re_path(r'^overview/', static_views.index), | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| import mimetypes | import mimetypes | ||||||
| 
 | 
 | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.http import Http404 | from django.http import FileResponse, Http404, HttpResponseRedirect | ||||||
| from django.http import FileResponse |  | ||||||
| from django.template.response import TemplateResponse | from django.template.response import TemplateResponse | ||||||
| 
 | 
 | ||||||
| from .local_context_processors import fundgoal_lookup | from .local_context_processors import fundgoal_lookup | ||||||
|  | @ -35,7 +34,10 @@ def index(request, *args, **kwargs): | ||||||
|         path += 'index.html' |         path += 'index.html' | ||||||
|     full_path = (base_path / path).resolve() |     full_path = (base_path / path).resolve() | ||||||
|     safe_from_path_traversal = full_path.is_relative_to(base_path) |     safe_from_path_traversal = full_path.is_relative_to(base_path) | ||||||
|     if not full_path.exists() or not safe_from_path_traversal: |     if full_path.is_dir(): | ||||||
|  |         # Should have been accessed with a trailing slash. | ||||||
|  |         return HttpResponseRedirect(request.path + '/') | ||||||
|  |     elif not full_path.exists() or not safe_from_path_traversal: | ||||||
|         raise Http404() |         raise Http404() | ||||||
|     is_template = mimetypes.guess_type(full_path)[0] == 'text/html' |     is_template = mimetypes.guess_type(full_path)[0] == 'text/html' | ||||||
|     if not is_template: |     if not is_template: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue