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") }
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 }
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") }
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 } }
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 }
// 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 }
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) }
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...) } }
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) } }
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) }
// 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 } }
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") }
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") }
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) }
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 }
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") }
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 }
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) } }
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) }
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 }
// 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) } }
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 }
// 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") }