Пример #1
1
func dirList(w http.ResponseWriter, f http.File, name string) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprintf(w, "<pre>\n")
	switch name {
	case "/":
		fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", "/", ".")
	default:
		fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", path.Clean(name+"/.."), "..")
	}
	for {
		dirs, err := f.Readdir(100)
		if err != nil || len(dirs) == 0 {
			break
		}
		sort.Sort(byName(dirs))
		for _, d := range dirs {
			name := d.Name()
			if d.IsDir() {
				name += "/"
			}
			// name may contain '?' or '#', which must be escaped to remain
			// part of the URL path, and not indicate the start of a query
			// string or fragment.
			url := url.URL{Path: name}
			fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), html.EscapeString(name))
		}
	}
	fmt.Fprintf(w, "</pre>\n")
}
Пример #2
0
func readFile(f http.File) (chan *FramebufferUpdate, error) {
	gzipReader, err := gzip.NewReader(f)
	if err != nil {
		return nil, err
	}
	bufioReader := bufio.NewReader(gzipReader)
	reader := NewRecordingReader(bufioReader)
	output := make(chan *FramebufferUpdate)

	go func() {
		defer f.Close()
		defer close(output)

		var err error
		for err == nil {
			err = readUpdate(reader, output)
		}

		if err != nil && err != io.EOF {
			log.Errorln("error decoding recording:", err)
		}
	}()

	return output, nil
}
Пример #3
0
func dirList(w http.ResponseWriter, f http.File) {
	dirs, err := f.Readdir(-1)
	if err != nil {
		// TODO: log err.Error() to the Server.ErrorLog, once it's possible
		// for a handler to get at its Server via the ResponseWriter. See
		// Issue 12438.
		http.Error(w, "Error reading directory", http.StatusInternalServerError)
		return
	}
	sort.Sort(byName(dirs))

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprintf(w, "<pre>\n")
	for _, d := range dirs {
		name := d.Name()
		if d.IsDir() {
			name += "/"
		}
		// name may contain '?' or '#', which must be escaped to remain
		// part of the URL path, and not indicate the start of a query
		// string or fragment.
		url := url.URL{Path: name}
		fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
	}
	fmt.Fprintf(w, "</pre>\n")
}
Пример #4
0
func dirList(ci inject.CopyInject, logger termlog.Logger, w http.ResponseWriter, name string, f http.File, templates *template.Template) {
	w.Header().Set("Cache-Control", "no-store, must-revalidate")
	files, err := f.Readdir(0)
	if err != nil {
		logger.Shout("Error reading directory for listing: %s", err)
		return
	}
	data := dirData{Name: name, Files: files}
	buff := bytes.NewBuffer(make([]byte, 0, 0))
	err = templates.Lookup("dirlist.html").Execute(buff, data)
	length := buff.Len()
	if err != nil {
		logger.Shout("Error producing directory listing: %s", err)
	}
	inj, err := ci.Sniff(buff)
	if err != nil {
		logger.Shout("Failed to inject in dir listing: %s", err)
		return
	}
	w.Header().Set(
		"Content-Length", fmt.Sprintf("%d", length+inj.Extra()),
	)
	_, err = inj.Copy(w)
	if err != nil {
		logger.Shout("Failed to inject in dir listing: %s", err)
		return
	}
}
Пример #5
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
}
Пример #6
0
// 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
}
Пример #7
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)
}
Пример #8
0
func readAllFiles(file http.File) ([]os.FileInfo, error) {
	files := []os.FileInfo{}
	for {
		more, err := file.Readdir(100)
		if err == io.EOF {
			return files, nil
		} else if err != nil {
			return nil, err
		}
		files = append(files, more...)
	}
}
Пример #9
0
func dirList(ci inject.CopyInject, logger termlog.Logger, w http.ResponseWriter, name string, f http.File, templates *template.Template) {
	w.Header().Set("Cache-Control", "no-store, must-revalidate")
	files, err := f.Readdir(0)
	if err != nil {
		logger.Shout("Error reading directory for listing: %s", err)
		return
	}
	data := dirData{Name: name, Files: files}
	err = ci.ServeTemplate(http.StatusOK, w, templates.Lookup("dirlist.html"), data)
	if err != nil {
		logger.Shout("Failed to generate dir listing: %s", err)
	}
}
Пример #10
0
func setContentType(w http.ResponseWriter, name string, file http.File) {
	t := mime.TypeByExtension(filepath.Ext(name))
	if t == "" {
		var buffer [512]byte
		n, _ := io.ReadFull(file, buffer[:])
		t = http.DetectContentType(buffer[:n])
		if _, err := file.Seek(0, os.SEEK_SET); err != nil {
			http.Error(w, "Can't seek", http.StatusInternalServerError)
			return
		}
	}
	w.Header().Set("Content-Type", t)
}
Пример #11
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
	}
}
Пример #12
0
func dirList(w http.ResponseWriter, f http.File, fs Filesystemhttp, name string, prefix string, auth bool) {
	//w.Header().Set("Content-Type", "text/html; charset=utf-8")
	//fmt.Fprintf(w, "<pre>\n")

	//finfo, _ := f.Stat()

	out := make(map[string]interface{})
	out["prefix"] = prefix
	out["path"] = name
	out["auth"] = auth

	authRead := auth || (!auth && !fs.ReadNeedsAuth)
	authList := auth || (!auth && !fs.ListNeedsAuth)
	authZip := auth || (!auth && !fs.ZipNeedsAuth)
	authDelete := auth || (!auth && !fs.DeleteNeedsAuth)
	authUpload := auth || (!auth && !fs.UploadNeedsAuth)
	authCreateFolder := auth || (!auth && !fs.CreateFolderNeedsAuth)

	out["authRead"] = authRead
	out["authList"] = authList
	out["authZip"] = authZip
	out["authDelete"] = authDelete
	out["authUpload"] = authUpload
	out["authCreateFolder"] = authCreateFolder

	if authList {
		files := make([]os.FileInfo, 0, 50)

		for {
			dirs, err := f.Readdir(100)
			if err != nil || len(dirs) == 0 {
				break
			}
			for _, d := range dirs {
				name := d.Name()
				if d.IsDir() {
					name += "/"
				}
				files = append(files, d)
			}
		}
		out["files"] = files
	}

	Template(TemplateFiles).Execute(w, out)

	//fmt.Fprintf(w, "</pre>\n")
}
Пример #13
0
func dirList(w http.ResponseWriter, f http.File) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprintf(w, "<pre>\n")
	for {
		dirs, err := f.Readdir(100)
		if err != nil || len(dirs) == 0 {
			break
		}
		for _, d := range dirs {
			name := d.Name()
			if d.IsDir() {
				name += "/"
			}
			escaped := html.EscapeString(name)
			fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", escaped, escaped)
		}
	}
	fmt.Fprintf(w, "</pre>\n")
}
Пример #14
0
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)
}
Пример #15
0
func (b Browse) loadDirectoryContents(requestedFilepath http.File, urlPath string) (*Listing, bool, error) {
	files, err := requestedFilepath.Readdir(-1)
	if err != nil {
		return nil, false, err
	}

	// Determine if user can browse up another folder
	var canGoUp bool
	curPathDir := path.Dir(strings.TrimSuffix(urlPath, "/"))
	for _, other := range b.Configs {
		if strings.HasPrefix(curPathDir, other.PathScope) {
			canGoUp = true
			break
		}
	}

	// Assemble listing of directory contents
	listing, hasIndex := directoryListing(files, canGoUp, urlPath)

	return &listing, hasIndex, nil
}
Пример #16
0
func dirList(w http.ResponseWriter, f http.File) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprint(w, "<style>table{border-spacing: 0;}th{text-align:left;background-color:rgba(0,0,0,.05);}th,td{padding:0.5em;border-bottom: 1px solid #cbcbcb;}tr:nth-child(odd){background-color:#f2f2f2;}</style>")
	fmt.Fprintf(w, "<table style='width:100%%;'>\n<tr><th>File</th><th>Size</th><th>Date</th></tr>\n")
	for {
		dirs, err := f.Readdir(100)
		if err != nil || len(dirs) == 0 {
			break
		}
		for _, d := range dirs {
			name := d.Name()
			if d.IsDir() {
				name += "/"
			}
			size := ByteSize(d.Size())
			date := d.ModTime().Format("2006-01-02 15:04:05")
			// TODO htmlescape
			fmt.Fprintf(w, "<tr><td style='width:60%%;'><a href=\"%s\">%s</a></td><td style='width:20%%;'>%s</td><td>%s</td></tr>\n", name, name, size.String(), date)
		}
	}
	fmt.Fprintf(w, "</table>\n")
}
Пример #17
0
func dirList(w http.ResponseWriter, f http.File) error {
	dirs, err := f.Readdir(-1)
	if err != nil {
		return err
	}
	sort.Sort(byName(dirs))

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprintf(w, "<pre>\n")
	for _, d := range dirs {
		name := d.Name()
		if d.IsDir() {
			name += "/"
		}
		// name may contain '?' or '#', which must be escaped to remain
		// part of the URL path, and not indicate the start of a query
		// string or fragment.
		url := url.URL{Path: name}
		fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), replacer.Replace(name))
	}
	fmt.Fprintf(w, "</pre>\n")
	return nil
}
Пример #18
0
func (fserver *FileServer) dirList(logger termlog.Logger, w http.ResponseWriter, name string, f http.File) {
	w.Header().Set("Cache-Control", "no-store, must-revalidate")
	files, err := f.Readdir(0)
	if err != nil {
		logger.Shout("Error reading directory for listing: %s", err)
		return
	}
	sortedFiles := fileSlice(files)
	sort.Sort(sortedFiles)
	data := dirData{
		Version: fserver.Version,
		Name:    name,
		Files:   sortedFiles,
	}
	err = fserver.Inject.ServeTemplate(
		http.StatusOK,
		w,
		fserver.Templates.Lookup("dirlist.html"),
		data,
	)
	if err != nil {
		logger.Shout("Failed to generate dir listing: %s", err)
	}
}
Пример #19
0
func dirList(reply *Reply, f http.File) {
	reply.SetHeader("Content-Type", "text/html; charset=utf-8")
	buf := bytes.NewBuffer(nil)
	buf.WriteString("<pre>\n")
	for {
		dirs, err := f.Readdir(100)
		if err != nil || len(dirs) == 0 {
			break
		}
		for _, d := range dirs {
			name := d.Name()
			if d.IsDir() {
				name += "/"
			}
			// name may contain '?' or '#', which must be escaped to remain
			// part of the URL path, and not indicate the start of a query
			// string or fragment.
			url := url.URL{Path: name}
			fmt.Fprintf(buf, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
		}
	}
	fmt.Fprintf(buf, "</pre>\n")
	reply.With(buf)
}
Пример #20
0
func listDir(d http.File, c *Context) (err error) {
	dirs, err := d.Readdir(-1)
	if err != nil {
		return err
	}

	// Create directory index
	w := c.Response()
	w.Header().Set(ContentType, TextHTMLCharsetUTF8)
	fmt.Fprintf(w, "<pre>\n")
	for _, d := range dirs {
		name := d.Name()
		color := "#212121"
		if d.IsDir() {
			color = "#e91e63"
			name += "/"
		}
		fmt.Fprintf(w, "<a href=\"%s\" style=\"color: %s;\">%s</a>\n", name, color, name)
	}
	fmt.Fprintf(w, "</pre>\n")
	return
}
Пример #21
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)
	}
}
Пример #22
0
func (f *Files) readFilesRecursive(dirname string, file http.File, results map[string][]byte, recursive bool) error {

	files, err := file.Readdir(-1)
	if err != nil {
		return err
	}

	var fpath string

	for _, fi := range files {

		fpath = dirname + fi.Name()

		newFile, err := f.dir.Open(fpath)
		if err != nil {
			return err
		}

		if fi.IsDir() {

			if !recursive {
				continue
			}

			err := f.readFilesRecursive(fpath+pathSep, newFile, results, recursive)
			if err != nil {
				return err
			}

			continue
		}

		if fi.Mode()&os.ModeSymlink == os.ModeSymlink {

			link, err := filepath.EvalSymlinks(fpath)
			if err != nil {
				log.Panic("Error Resolving Symlink", err)
			}

			fi, err := os.Stat(link)
			if err != nil {
				log.Panic(err)
			}

			if fi.IsDir() {

				if !recursive {
					continue
				}

				err := f.readFilesRecursive(fpath+pathSep, newFile, results, recursive)
				if err != nil {
					return err
				}

				continue
			}
		}

		if !f.dir.useStaticFiles {
			fpath = strings.Replace(fpath, f.dir.absPkgPath, "", 1)
		}

		results[fpath], err = ioutil.ReadAll(newFile)
		if err != nil {
			return err
		}
	}

	return nil
}
Пример #23
0
// dirList writes the directory list to the HTTP response.
//
// glog convention is that log files are created in the following format:
// "ingest.skia-testing-b.perf.log.ERROR.20141015-133007.3273"
// where the first word is the name of the app.
// glog also creates symlinks that look like "ingest.ERROR". These
// symlinks point to the latest log type.
// This method displays sorted symlinks first and then displays sorted sections for
// all apps. Files and directories not in the glog format are bucketed into an
// "unknown" app.
func dirList(w http.ResponseWriter, f http.File) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprintf(w, "<pre>\n")
	// Datastructures to populate and output.
	topLevelSymlinks := make([]os.FileInfo, 0)
	topLevelSymlinkMaxFileName := 0
	appToLogs := make(map[string][]os.FileInfo)
	appToMaxFileName := make(map[string]int)
	for {
		fileInfos, err := f.Readdir(10000)
		if err != nil || len(fileInfos) == 0 {
			break
		}
		// Prepopulate the datastructures.
		for _, fileInfo := range fileInfos {
			name := fileInfo.Name()
			nameTokens := strings.Split(name, ".")
			if len(nameTokens) == 2 {
				topLevelSymlinks = append(topLevelSymlinks, fileInfo)
				if len(fileInfo.Name()) > topLevelSymlinkMaxFileName {
					topLevelSymlinkMaxFileName = len(fileInfo.Name())
				}
			} else if len(nameTokens) > 1 {
				appToLogs[nameTokens[0]] = append(appToLogs[nameTokens[0]], fileInfo)
				if len(fileInfo.Name()) > appToMaxFileName[nameTokens[0]] {
					appToMaxFileName[nameTokens[0]] = len(fileInfo.Name())
				}
			} else {
				// File all directories or files created by something other than
				// glog under "unknown" app.
				appToLogs["unknown"] = append(appToLogs["unknown"], fileInfo)
			}
		}
	}

	// First output the top level symlinks.
	sort.Sort(FileInfoModifiedSlice{fileInfos: topLevelSymlinks, reverseSort: true})
	for _, fileInfo := range topLevelSymlinks {
		writeFileInfo(w, fileInfo, topLevelSymlinkMaxFileName)
	}
	// Second output app links to their anchors.
	var keys []string
	for k := range appToLogs {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	if len(keys) != 0 {
		fmt.Fprint(w, "\nJump to sections:\n")
	}
	for _, app := range keys {
		fmt.Fprintf(w, "<a href=\"#%s\">%s</a>\n", app, template.HTMLEscapeString(app))
	}
	fmt.Fprint(w, "\n")
	// Then output the logs of all the different apps.
	for _, app := range keys {
		appFileInfos := appToLogs[app]
		sort.Sort(FileInfoModifiedSlice{fileInfos: appFileInfos, reverseSort: true})
		fmt.Fprintf(w, "\n===== <a name=\"%s\">%s</a> =====\n\n", app, template.HTMLEscapeString(app))
		for _, fileInfo := range appFileInfos {
			writeFileInfo(w, fileInfo, appToMaxFileName[app])
		}
	}
	fmt.Fprintf(w, "</pre>\n")
}