mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	Better search for config.
Handle LastModifiedHeader better. Handle HEAD/GET.
This commit is contained in:
		
							parent
							
								
									19a85d08c6
								
							
						
					
					
						commit
						dd4de698cf
					
				@ -8,6 +8,7 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"text/template"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/mholt/caddy/middleware"
 | 
			
		||||
	"github.com/russross/blackfriday"
 | 
			
		||||
@ -65,26 +66,47 @@ type Config struct {
 | 
			
		||||
 | 
			
		||||
// ServeHTTP implements the http.Handler interface.
 | 
			
		||||
func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
			
		||||
	for _, cfg := range md.Configs {
 | 
			
		||||
		if !middleware.Path(r.URL.Path).Matches(cfg.PathScope) {
 | 
			
		||||
			continue
 | 
			
		||||
	var cfg *Config
 | 
			
		||||
	for _, c := range md.Configs {
 | 
			
		||||
		if middleware.Path(r.URL.Path).Matches(c.PathScope) { // not negated
 | 
			
		||||
			cfg = c
 | 
			
		||||
			break // or goto
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if cfg == nil {
 | 
			
		||||
		return md.Next.ServeHTTP(w, r) // exit early
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// We only deal with HEAD/GET
 | 
			
		||||
	switch r.Method {
 | 
			
		||||
	case http.MethodGet, http.MethodHead:
 | 
			
		||||
	default:
 | 
			
		||||
		return http.StatusMethodNotAllowed, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var dirents []os.FileInfo
 | 
			
		||||
	var lastModTime time.Time
 | 
			
		||||
	fpath := r.URL.Path
 | 
			
		||||
	if idx, ok := middleware.IndexFile(md.FileSys, fpath, md.IndexFiles); ok {
 | 
			
		||||
		// We're serving a directory index file, which may be a markdown
 | 
			
		||||
		// file with a template.  Let's grab a list of files this directory
 | 
			
		||||
		// URL points to, and pass that in to any possible template invocations,
 | 
			
		||||
		// so that templates can customize the look and feel of a directory.
 | 
			
		||||
 | 
			
		||||
		fdp, err := md.FileSys.Open(fpath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if os.IsPermission(err) {
 | 
			
		||||
				return http.StatusForbidden, err
 | 
			
		||||
			}
 | 
			
		||||
			return http.StatusInternalServerError, err
 | 
			
		||||
		}
 | 
			
		||||
			dirents, err = fdp.Readdir(-1)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return http.StatusInternalServerError, err
 | 
			
		||||
 | 
			
		||||
		// Grab a possible set of directory entries.  Note, we do not check
 | 
			
		||||
		// for errors here (unreadable directory, for example).  It may
 | 
			
		||||
		// still be useful to have a directory template file, without the
 | 
			
		||||
		// directory contents being present.
 | 
			
		||||
		dirents, _ = fdp.Readdir(-1)
 | 
			
		||||
		for _, d := range dirents {
 | 
			
		||||
			lastModTime = latest(lastModTime, d.ModTime())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Set path to found index file
 | 
			
		||||
@ -105,6 +127,7 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return http.StatusNotFound, nil
 | 
			
		||||
		}
 | 
			
		||||
		lastModTime = latest(lastModTime, fs.ModTime())
 | 
			
		||||
 | 
			
		||||
		body, err := ioutil.ReadAll(f)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@ -128,12 +151,26 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
 | 
			
		||||
		// 	return http.StatusInternalServerError, err
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
			middleware.SetLastModifiedHeader(w, fs.ModTime())
 | 
			
		||||
		middleware.SetLastModifiedHeader(w, lastModTime)
 | 
			
		||||
		if r.Method == "GET" {
 | 
			
		||||
			w.Write(html)
 | 
			
		||||
			return http.StatusOK, nil
 | 
			
		||||
		}
 | 
			
		||||
		return http.StatusOK, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Didn't qualify to serve as markdown; pass-thru
 | 
			
		||||
	return md.Next.ServeHTTP(w, r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// latest returns the latest time.Time
 | 
			
		||||
func latest(t ...time.Time) time.Time {
 | 
			
		||||
	var last time.Time
 | 
			
		||||
 | 
			
		||||
	for _, tt := range t {
 | 
			
		||||
		if tt.After(last) {
 | 
			
		||||
			last = tt
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return last
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user