fs: Add redirects
This commit is contained in:
		
							parent
							
								
									995769556c
								
							
						
					
					
						commit
						8eccefb8c9
					
				
							
								
								
									
										45
									
								
								fs.go
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								fs.go
									
									
									
									
									
								
							| @ -32,7 +32,7 @@ type fileServer struct { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (fs fileServer) ServeGemini(w ResponseWriter, r *Request) { | func (fs fileServer) ServeGemini(w ResponseWriter, r *Request) { | ||||||
| 	ServeFile(w, fs, path.Clean(r.URL.Path)) | 	serveFile(w, r, fs, path.Clean(r.URL.Path), true) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ServeFile responds to the request with the contents of the named file | // ServeFile responds to the request with the contents of the named file | ||||||
| @ -42,7 +42,19 @@ func (fs fileServer) ServeGemini(w ResponseWriter, r *Request) { | |||||||
| // relative to the current directory and may ascend to parent directories. If | // relative to the current directory and may ascend to parent directories. If | ||||||
| // the provided name is constructed from user input, it should be sanitized | // the provided name is constructed from user input, it should be sanitized | ||||||
| // before calling ServeFile. | // before calling ServeFile. | ||||||
| func ServeFile(w ResponseWriter, fsys fs.FS, name string) { | func ServeFile(w ResponseWriter, r *Request, fsys fs.FS, name string) { | ||||||
|  | 	serveFile(w, r, fsys, name, false) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func serveFile(w ResponseWriter, r *Request, fsys fs.FS, name string, redirect bool) { | ||||||
|  | 	const indexPage = "/index.gmi" | ||||||
|  | 
 | ||||||
|  | 	// Redirect .../index.gmi to .../ | ||||||
|  | 	if strings.HasSuffix(r.URL.Path, indexPage) { | ||||||
|  | 		w.Header(StatusPermanentRedirect, "./") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if name == "/" { | 	if name == "/" { | ||||||
| 		name = "." | 		name = "." | ||||||
| 	} else { | 	} else { | ||||||
| @ -62,9 +74,34 @@ func ServeFile(w ResponseWriter, fsys fs.FS, name string) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Redirect to canonical path | ||||||
|  | 	if redirect { | ||||||
|  | 		url := r.URL.Path | ||||||
| 		if stat.IsDir() { | 		if stat.IsDir() { | ||||||
| 		// Try opening index file | 			// Add trailing slash | ||||||
| 		index, err := fsys.Open(path.Join(name, "index.gmi")) | 			if url[len(url)-1] != '/' { | ||||||
|  | 				w.Header(StatusPermanentRedirect, path.Base(url)+"/") | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			// Remove trailing slash | ||||||
|  | 			if name[len(name)-1] == '/' { | ||||||
|  | 				w.Header(StatusPermanentRedirect, "../"+path.Base(url)) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if stat.IsDir() { | ||||||
|  | 		// Redirect if the directory name doesn't end in a slash | ||||||
|  | 		url := r.URL.Path | ||||||
|  | 		if url[len(url)-1] != '/' { | ||||||
|  | 			w.Header(StatusRedirect, path.Base(url)+"/") | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Use contents of index.gmi if present | ||||||
|  | 		index, err := fsys.Open(path.Join(name, indexPage)) | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			defer index.Close() | 			defer index.Close() | ||||||
| 			istat, err := index.Stat() | 			istat, err := index.Stat() | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user