示例#1
0
func servefile(c *ctx, f http.File) error {
	fi, err := f.Stat()
	if err == nil {
		http.ServeContent(c.RW, c.Request, fi.Name(), fi.ModTime(), f)
	}
	return err
}
示例#2
0
func serveContent(w http.ResponseWriter, r *http.Request, f http.File, fname string) {
	var modtime time.Time
	if fi, err := f.Stat(); err != nil {
		modtime = fi.ModTime()
	}

	http.ServeContent(w, r, fname, modtime, f)
}
示例#3
0
文件: file.go 项目: gernest/helen
// NewFromHTTPFile returns  new *StaticFile from f
func NewFromHTTPFile(f http.File) (*StaticFile, error) {
	info, err := f.Stat()
	if err != nil {
		return nil, err
	}
	b, _ := ioutil.ReadAll(f)
	return &StaticFile{rsc: bytes.NewReader(b), info: info}, nil
}
示例#4
0
// Server returns a handler that serves the files as the response content.
// The files being served are determined using the current URL path and the specified path map.
// For example, if the path map is {"/css": "/www/css", "/js": "/www/js"} and the current URL path
// "/css/main.css", the file "<working dir>/www/css/main.css" will be served.
// If a URL path matches multiple prefixes in the path map, the most specific prefix will take precedence.
// For example, if the path map contains both "/css" and "/css/img", and the URL path is "/css/img/logo.gif",
// then the path mapped by "/css/img" will be used.
//
//     import (
//         "log"
//         "github.com/go-ozzo/ozzo-routing"
//         "github.com/go-ozzo/ozzo-routing/file"
//     )
//
//     r := routing.New()
//     r.Get("/*", file.Server(file.PathMap{
//          "/css": "/ui/dist/css",
//          "/js": "/ui/dist/js",
//     }))
func Server(pathMap PathMap, opts ...ServerOptions) routing.Handler {
	var options ServerOptions
	if len(opts) > 0 {
		options = opts[0]
	}
	if !filepath.IsAbs(options.RootPath) {
		options.RootPath = filepath.Join(RootPath, options.RootPath)
	}
	from, to := parsePathMap(pathMap)

	// security measure: limit the files within options.RootPath
	dir := http.Dir(options.RootPath)

	return func(c *routing.Context) error {
		if c.Request.Method != "GET" && c.Request.Method != "HEAD" {
			return routing.NewHTTPError(http.StatusMethodNotAllowed)
		}
		path, found := matchPath(c.Request.URL.Path, from, to)
		if !found || options.Allow != nil && !options.Allow(c, path) {
			return routing.NewHTTPError(http.StatusNotFound)
		}

		var (
			file  http.File
			fstat os.FileInfo
			err   error
		)

		if file, err = dir.Open(path); err != nil {
			if options.CatchAllFile != "" {
				return serveFile(c, dir, options.CatchAllFile)
			}
			return routing.NewHTTPError(http.StatusNotFound, err.Error())
		}
		defer file.Close()

		if fstat, err = file.Stat(); err != nil {
			return routing.NewHTTPError(http.StatusNotFound, err.Error())
		}

		if fstat.IsDir() {
			if options.IndexFile == "" {
				return routing.NewHTTPError(http.StatusNotFound)
			}
			return serveFile(c, dir, filepath.Join(path, options.IndexFile))
		}

		http.ServeContent(c.Response, c.Request, path, fstat.ModTime(), file)
		return nil
	}
}
示例#5
0
文件: server.go 项目: logan/heim
func (s *Server) serveGzippedFile(w http.ResponseWriter, r *http.Request, filename string, cache bool) {
	dir := http.Dir(s.staticPath)
	var err error
	var f http.File
	gzipped := false

	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
		f, err = dir.Open(filename + ".gz")
		if err != nil {
			f = nil
		} else {
			gzipped = true
		}
	}

	if f == nil {
		f, err = dir.Open(filename)
		if err != nil {
			http.NotFound(w, r)
			return
		}
	}

	defer f.Close()

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

	name := d.Name()
	if gzipped {
		name = strings.TrimSuffix(name, ".gz")
		w = &gzipResponseWriter{
			ResponseWriter: w,
			cache:          cache,
		}
	}

	http.ServeContent(w, r, name, d.ModTime(), f)
}
示例#6
0
// Static returns a handler that serves the files under the specified folder as response content.
// For example, if root is "static" and the handler is handling the URL path "/app/index.html",
// then the content of the file "<working dir>/static/app/index.html" may be served as the response.
func Static(root string, opts ...StaticOptions) Handler {
	if !filepath.IsAbs(root) {
		root = filepath.Join(RootPath, root)
	}
	options := StaticOptions{}
	if len(opts) > 0 {
		options = opts[0]
	}
	if options.IndexFile == "" {
		options.IndexFile = "index.html"
	}

	// limit the files to be served within the specified folder
	dir := http.Dir(root)

	return func(c *Context) {
		if c.Request.Method != "GET" && c.Request.Method != "HEAD" {
			c.Next()
			return
		}
		path := c.Request.URL.Path
		if options.Prefix != "" {
			if !strings.HasPrefix(path, options.Prefix) {
				c.Next()
				return
			}
			path = path[len(options.Prefix):]
			if path != "" && path[0] != '/' {
				c.Next()
				return
			}
		}
		if options.Allow != nil && !options.Allow(c, path) {
			return
		}

		var (
			file  http.File
			fstat os.FileInfo
			err   error
		)

		if file, err = dir.Open(path); err != nil {
			c.Next()
			return
		}
		defer file.Close()

		if fstat, err = file.Stat(); err != nil {
			c.Next()
			return
		}

		// if it's a directory, try the index file
		if fstat.IsDir() {
			path = filepath.Join(path, options.IndexFile)
			if file, err = dir.Open(path); err != nil {
				c.Next()
				return
			}
			defer file.Close()

			if fstat, err = file.Stat(); err != nil || fstat.IsDir() {
				c.Next()
				return
			}
		}

		http.ServeContent(c.Response, c.Request, path, fstat.ModTime(), file)
	}
}