func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	urlPath := r.URL.Path
	if !strings.HasPrefix(urlPath, "/") {
		urlPath = "/" + urlPath
		r.URL.Path = urlPath
	}
	p := path.Clean(urlPath)

	if s.root != "" {
		if p = strings.TrimPrefix(p, s.root); len(p) >= len(r.URL.Path) {
			s.httpError(w, r, errNotFound)
			return
		}
	}

	if s.IndexPage != "" && strings.HasSuffix(r.URL.Path, s.IndexPage) {
		redirect(w, r, "./")
		return
	}

	if (s.Hasher != nil && !s.NoHashQueryStrings) ||
		(s.Hasher != nil && s.NoHashQueryStrings && len(r.URL.RawQuery) == 0) {
		cPath := s.canonicalPath(p)
		h, cont, err := s.hash(cPath)
		switch err {
		case errNotRegularFile: // continue as usual if it is not a regular file
		case nil:
			if hPath := s.hashedPath(cPath, h); hPath != p {
				redirect(w, r, path.Join(s.root, hPath))
				return
			}
			if s.RedirectTrailingSlash && urlPath[len(urlPath)-1] == '/' {
				redirect(w, r, path.Join(s.root, p))
				return
			}
			p = cPath
			r.URL.Path = path.Join(s.root, cPath)
		default:
			if !cont {
				s.httpError(w, r, err)
				return
			}
		}
	}
	f, err := s.open(p)
	if err != nil {
		s.httpError(w, r, err)
		return
	}
	defer f.Close()

	d, err := f.Stat()
	if err != nil {
		s.httpError(w, r, err)
		return
	}

	if s.RedirectTrailingSlash {
		url := r.URL.Path
		if d.IsDir() {
			if url[len(url)-1] != '/' {
				redirect(w, r, url+"/")
				return
			}
		} else {
			if url[len(url)-1] == '/' {
				redirect(w, r, "../"+path.Base(url))
				return
			}
		}
	}

	if d.IsDir() {
		index := strings.TrimSuffix(p, "/") + s.IndexPage
		ff, err := s.open(index)
		if err == nil {
			defer ff.Close()
			dd, err := ff.Stat()
			if err == nil {
				p = index
				d = dd
				f = ff
			}
		}
	}

	if d.IsDir() {
		s.httpError(w, r, errNotFound)
		return
	}

	http.ServeContent(w, r, d.Name(), d.ModTime(), f)
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	urlPath := r.URL.Path
	if !strings.HasPrefix(urlPath, "/") {
		urlPath = "/" + urlPath
		r.URL.Path = urlPath
	}
	p := path.Clean(urlPath)

	if s.root != "" {
		if p = strings.TrimPrefix(p, s.root); len(p) >= len(r.URL.Path) {
			s.httpError(w, r, errNotFound)
			return
		}
	}

	if s.IndexPage != "" && strings.HasSuffix(r.URL.Path, s.IndexPage) {
		redirect(w, r, "./")
		return
	}

	if (s.Hasher != nil && !s.NoHashQueryStrings) ||
		(s.Hasher != nil && s.NoHashQueryStrings && len(r.URL.RawQuery) == 0) {
		cPath := s.canonicalPath(p)
		h, cont, err := s.hash(cPath)
		switch err {
		case errNotRegularFile: // continue as usual if it is not a regular file
		case nil:
			if hPath := s.hashedPath(cPath, h); hPath != p {
				redirect(w, r, path.Join(s.root, hPath))
				return
			}
			if s.RedirectTrailingSlash && urlPath[len(urlPath)-1] == '/' {
				redirect(w, r, path.Join(s.root, p))
				return
			}
			p = cPath
			r.URL.Path = path.Join(s.root, cPath)
		default:
			if !cont {
				s.httpError(w, r, err)
				return
			}
		}
	}
	f, err := s.open(p)
	if err != nil {
		s.httpError(w, r, err)
		return
	}
	defer f.Close()

	d, err := f.Stat()
	if err != nil {
		s.httpError(w, r, err)
		return
	}

	if s.RedirectTrailingSlash {
		url := r.URL.Path
		if d.IsDir() {
			if url[len(url)-1] != '/' {
				redirect(w, r, url+"/")
				return
			}
		} else {
			if url[len(url)-1] == '/' {
				redirect(w, r, "../"+path.Base(url))
				return
			}
		}
	}

	if d.IsDir() {
		index := strings.TrimSuffix(p, "/") + s.IndexPage
		ff, err := s.open(index)
		if err == nil {
			defer ff.Close()
			dd, err := ff.Stat()
			if err == nil {
				p = index
				d = dd
				f = ff
			}
		}
	}

	if d.IsDir() {
		s.httpError(w, r, errNotFound)
		return
	}

	http.ServeContent(w, r, d.Name(), d.ModTime(), f)
}
// ServeHTTP writes static files content to HTTP response.