http: Add the ability to serve a directory
This commit is contained in:
		
							parent
							
								
									68c8deb269
								
							
						
					
					
						commit
						70a1194bca
					
				@ -16,6 +16,11 @@ type ErrorData struct {
 | 
			
		||||
	Message any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DirectoryData struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Entries []fs.DirEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Handler struct {
 | 
			
		||||
	Environment       *step.Environment
 | 
			
		||||
	Directories       bool
 | 
			
		||||
@ -79,10 +84,8 @@ func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// TODO: serve a directory and return
 | 
			
		||||
		// have a custom directory listing document that takes in a list
 | 
			
		||||
		// of the files in the directory and the path to the directory
 | 
			
		||||
		// as data
 | 
			
		||||
		this.serveDirectory(res, req, pat)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.serveFile(res, req, pat)
 | 
			
		||||
@ -102,6 +105,38 @@ func (this *Handler) serveFile (
 | 
			
		||||
	this.serveDocument(res, req, name)	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Handler) serveDirectory (
 | 
			
		||||
	res http.ResponseWriter,
 | 
			
		||||
	req *http.Request,
 | 
			
		||||
	pat string,
 | 
			
		||||
) {
 | 
			
		||||
	name := pathToName(pat)
 | 
			
		||||
	entries, err := readDir(this.Environment.GetFS(), name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if this.DirectoryDocument == "" {
 | 
			
		||||
		this.serveFile(res, req, pat)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	document, err := this.Environment.Parse(this.DirectoryDocument)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	err = document.Execute(res, step.ExecutionData {
 | 
			
		||||
		Data: DirectoryData {
 | 
			
		||||
			Name:    name,
 | 
			
		||||
			Entries: entries,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Handler) serveDocument (
 | 
			
		||||
	res http.ResponseWriter,
 | 
			
		||||
	req *http.Request,
 | 
			
		||||
@ -214,3 +249,16 @@ func pathToName (pat string) string {
 | 
			
		||||
	}
 | 
			
		||||
	return pat
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readDir (filesystem fs.FS, name string) ([]fs.DirEntry, error) {
 | 
			
		||||
	if filesystem, ok := filesystem.(fs.ReadDirFS); ok {
 | 
			
		||||
		return filesystem.ReadDir(name)
 | 
			
		||||
	}
 | 
			
		||||
	dir, err := filesystem.Open(name)
 | 
			
		||||
	if err != nil { return nil, err }
 | 
			
		||||
	defer dir.Close()
 | 
			
		||||
	if dir, ok := dir.(fs.ReadDirFile); ok {
 | 
			
		||||
		return dir.ReadDir(0)
 | 
			
		||||
	}
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user