// Static return a middleware for serving static files
429431
func Static(opts ...StaticOptions) HandlerFunc {
	return func(ctx *Context) {
		if ctx.Req().Method != "GET" && ctx.Req().Method != "HEAD" {
			ctx.Next()
			return
		}

		opt := prepareStaticOptions(opts)

		var rPath = ctx.Req().URL.Path
		// if defined prefix, then only check prefix
		if opt.Prefix != "" {
			if !strings.HasPrefix(ctx.Req().URL.Path, opt.Prefix) {
				ctx.Next()
				return
			}

			if len(opt.Prefix) == len(ctx.Req().URL.Path) {
				rPath = ""
			} else {
				rPath = ctx.Req().URL.Path[len(opt.Prefix):]
			}
		}

		f, err := opt.FileSystem.Open(strings.TrimLeft(rPath, "/"))
		if err != nil {
			if os.IsNotExist(err) {
				if opt.Prefix != "" {
					ctx.Result = NotFound()
				} else {
					ctx.Next()
					return
				}
			} else {
				ctx.Result = InternalServerError(err.Error())
			}
			ctx.HandleError()
			return
		}
		defer f.Close()

		finfo, err := f.Stat()
		if err != nil {
			ctx.Result = InternalServerError(err.Error())
			ctx.HandleError()
			return
		}

		if !finfo.IsDir() {
			if len(opt.FilterExts) > 0 && !opt.IsFilterExt(rPath) {
				ctx.Next()
				return
			}

			http.ServeContent(ctx, ctx.Req(), finfo.Name(), finfo.ModTime(), f)
			return
		}

		// try serving index.html or index.htm
		if len(opt.IndexFiles) > 0 {
			for _, index := range opt.IndexFiles {
				fi, err := opt.FileSystem.Open(strings.TrimLeft(path.Join(rPath, index), "/"))
				if err != nil {
					if !os.IsNotExist(err) {
						ctx.Result = InternalServerError(err.Error())
						ctx.HandleError()
						return
					}
				} else {
					finfo, err = fi.Stat()
					if err != nil {
						fi.Close()
						ctx.Result = InternalServerError(err.Error())
						ctx.HandleError()
						return
					}
					if !finfo.IsDir() {
						http.ServeContent(ctx, ctx.Req(), finfo.Name(), finfo.ModTime(), fi)
						fi.Close()
						return
					}
					fi.Close()
				}
			}
		}

		// list dir files
		if opt.ListDir {
			ctx.Header().Set("Content-Type", "text/html; charset=UTF-8")
			ctx.WriteString(`<ul style="list-style-type:none;line-height:32px;">`)
			if rPath != "/" {
				ctx.WriteString(`<li>&nbsp; &nbsp; <a href="` + path.Join("/", opt.Prefix, filepath.Dir(rPath)) + `">..</a></li>`)
			}

			fs, err := f.Readdir(0)
			if err != nil {
				ctx.Result = InternalServerError(err.Error())
				ctx.HandleError()
				return
			}

			for _, fi := range fs {
				if fi.IsDir() {
					ctx.WriteString(`<li>┖ <a href="` + path.Join("/", opt.Prefix, rPath, fi.Name()) + `">` + path.Base(fi.Name()) + `</a></li>`)
				} else {
					if len(opt.FilterExts) > 0 && !opt.IsFilterExt(fi.Name()) {
						continue
					}

					ctx.WriteString(`<li>&nbsp; &nbsp; <a href="` + path.Join("/", opt.Prefix, rPath, fi.Name()) + `">` + filepath.Base(fi.Name()) + `</a></li>`)
				}
			}
			ctx.WriteString("</ul>")
			return
		}

		ctx.Next()
	}
}
896235
func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
	// Defaults
	if config.Root == "" {
		config.Root = "." // For security we want to restrict to CWD.
	}
	if config.Skipper == nil {
		config.Skipper = DefaultStaticConfig.Skipper
	}
	if config.Index == "" {
		config.Index = DefaultStaticConfig.Index
	}

	// Index template
	t, err := template.New("index").Parse(html)
	if err != nil {
		panic(fmt.Sprintf("echo: %v", err))
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) (err error) {
			if config.Skipper(c) {
				return next(c)
			}

			p := c.Request().URL.Path
			if strings.HasSuffix(c.Path(), "*") { // When serving from a group, e.g. `/static*`.
				p = c.Param("*")
			}
			p, err = url.PathUnescape(p)
			if err != nil {
				return
			}
			name := filepath.Join(config.Root, path.Clean("/"+p)) // "/"+ for security

			fi, err := os.Stat(name)
			if err != nil {
				if os.IsNotExist(err) {
					if err = next(c); err != nil {
						if he, ok := err.(*echo.HTTPError); ok {
							if config.HTML5 && he.Code == http.StatusNotFound {
								return c.File(filepath.Join(config.Root, config.Index))
							}
						}
						return
					}
				}
				return
			}

			if fi.IsDir() {
				index := filepath.Join(name, config.Index)
				fi, err = os.Stat(index)

				if err != nil {
					if config.Browse {
						return listDir(t, name, c.Response())
					}
					if os.IsNotExist(err) {
						return next(c)
					}
					return
				}

				return c.File(index)
			}

			return c.File(name)
		}
	}
}
1130197
func (router *Router) StaticRelative(p string, relativeDir string) *Router {
	// TODO: is this needed?? ;)
	_, f, _, _ := runtime.Caller(1)
	return router.Static(p, path.Join(path.Dir(f), relativeDir))
}
796335
func (r Route) StaticPath() string {
	src := r.tmpl.Src
	bidx := strings.IndexByte(src, '{')
	if bidx == -1 || len(src) <= bidx {
		return src // no dynamic part found
	}
	if bidx == 0 { // found at first index,
		// but never happens because of the prepended slash
		return "/"
	}

	return src[:bidx]
}
483521
func (ui *UIHandler) serveFromDiskOrStatic(rw http.ResponseWriter, req *http.Request, rx *regexp.Regexp, disk http.Handler, static *fileembed.Files) {
	suffix := httputil.PathSuffix(req)
	m := rx.FindStringSubmatch(suffix)
	if m == nil {
		panic("Caller should verify that rx matches")
	}
	file := m[1]
	if disk != nil {
		req.URL.Path = "/" + file
		disk.ServeHTTP(rw, req)
	} else {
		ServeStaticFile(rw, req, static, file)
	}

}
1154541
func (s *ServeMux) Middleware(path string, middleware Middleware) {
	s.Route(path).Middleware(middleware)
}
732679
func staticHandler(ctx *Context, filePath string) {
	http.ServeFile(ctx.Response, ctx.Request, filePath)
}
1356449
func (f *Files) add(filename string, sf *staticFile) {
	if f.file == nil {
		f.file = make(map[string]*staticFile)
	}
	f.file[filename] = sf
}
732097
func (c *Config) StaticNodes() []*enode.Node {
	return c.parsePersistentNodes(&c.staticNodesWarning, c.ResolvePath(datadirStaticNodes))
}
952143
func (sf StaticFile) AsStaticSocket() (ss StaticSocket, ok bool) {
	if sf.b.ss.Type == "socket" {
		return StaticSocket{sf}, true
	}

	return
}
152135
func (api *APIBuilder) StaticContent(reqPath string, cType string, content []byte) *Route {
	modtime := time.Now()
	h := func(ctx context.Context) {
		ctx.ContentType(cType)
		if _, err := ctx.WriteWithExpiration(content, modtime); err != nil {
			ctx.StatusCode(http.StatusInternalServerError)
			// ctx.Application().Logger().Infof("error while serving []byte via StaticContent: %s", err.Error())
		}
	}

	return api.registerResourceRoute(reqPath, h)
}
265800
func (sf StaticFile) AsStaticFIFO() (fifo StaticFIFO, ok bool) {
	if sf.b.ss.Type == "fifo" {
		return StaticFIFO{sf}, true
	}

	return
}
835242
func Static(dir string, asset func(string) ([]byte, error), options ...Options) martini.Handler {
	if asset == nil {
		return func() {}
	}

	opt := retrieveOptions(options)

	modtime := time.Now()

	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		if req.Method != "GET" && req.Method != "HEAD" {
			return
		}

		url := req.URL.Path

		b, err := asset(dir + url)

		if err != nil {
			// Try to serve the index file.
			b, err = asset(path.Join(dir+url, opt.IndexFile))

			if err != nil {
				// Exit if the asset could not be found.
				return
			}
		}

		if !opt.SkipLogging {
			log.Println("[Static] Serving " + url)
		}

		http.ServeContent(res, req, url, modtime, bytes.NewReader(b))
	}
}
1180479
func Static(directory string, staticOpt ...StaticOptions) macaron.Handler {
	opt := prepareStaticOptions(directory, staticOpt)

	return func(ctx *macaron.Context, log *log.Logger) {
		staticHandler(ctx, log, opt)
	}
}
644051
func StaticFileHandler(filename string) http.Handler {
	fcontents, err := ioutil.ReadFile(filename) // cache the contents of the file, this is the difference from net/http's impl, this is used only for static files, like favicons, css and so on
	if err != nil {
		return errorHandler(http.StatusBadRequest)
	}
	return StaticContentHandler(fcontents, TypeByExtension(filename))
}
179049
func (s SourceFilesystems) MakeStaticPathRelative(filename string) string {
	for _, staticFs := range s.Static {
		rel := staticFs.MakePathRelative(filename)
		if rel != "" {
			return rel
		}
	}
	return ""
}
1100473
func init() {
	// Setup a route for our static files.
	//
	// Because our static directory is set as the root of the FileSystem,
	// we need to strip off the /static/ prefix from the request path
	// before searching the FileSystem for the given file.
	fs := http.FileServer(http.Dir("static"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	// Setup a route for the home page.
	http.HandleFunc("/", index)
}