Skip to content

Commit

Permalink
HandleDir: add Attachments options to DirOptions
Browse files Browse the repository at this point in the history
have a bit more work to do on that, if Gzip option is true then it  does not work and it's not the 'if gzip' statement inside the handler


Former-commit-id: 866578d29b6a63ee60a22b0eb9b37288c717b7e2
  • Loading branch information
kataras committed Jul 7, 2020
1 parent cba6351 commit 645da2b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
13 changes: 12 additions & 1 deletion _examples/file-server/file-server/main.go
Expand Up @@ -54,8 +54,19 @@ func main() {
filesRouter := app.Party("/files")
{
filesRouter.HandleDir("/", uploadDir, iris.DirOptions{
Gzip: true,
Gzip: false,
ShowList: true,

// Optionally, force-send files to the client inside of showing to the browser.
Attachments: iris.Attachments{
Enable: true,
// Optionally, control data sent per second:
Limit: 50.0 * iris.KB,
Burst: 100 * iris.KB,
// Change the destination name through:
// NameFunc: func(systemName string) string {...}
},

DirList: iris.DirListRich(iris.DirListRichOptions{
// Optionally, use a custom template for listing:
// Tmpl: dirListRichTemplate,
Expand Down
3 changes: 3 additions & 0 deletions aliases.go
Expand Up @@ -98,6 +98,9 @@ type (
// `FileServer` and `Party#HandleDir` can use to serve files and assets.
// A shortcut for the `router.DirOptions`, useful when `FileServer` or `HandleDir` is being used.
DirOptions = router.DirOptions
// Attachments options for files to be downloaded and saved locally by the client.
// See `DirOptions`.
Attachments = router.Attachments
// DirListRichOptions the options for the `DirListRich` helper function.
// A shortcut for the `router.DirListRichOptions`.
// Useful when `DirListRich` function is passed to `DirOptions.DirList` field.
Expand Down
35 changes: 33 additions & 2 deletions core/router/fs.go
Expand Up @@ -24,6 +24,19 @@ const indexName = "/index.html"
// DirListFunc is the function signature for customizing directory and file listing.
type DirListFunc func(ctx context.Context, dirName string, dir http.File) error

// Attachments options for files to be downloaded and saved locally by the client.
// See `DirOptions`.
type Attachments struct {
// Set to true to enable the files to be downloaded and
// saved locally by the client, instead of serving the file.
Enable bool
// Options to send files with a limit of bytes sent per second.
Limit float64
Burst int
// Use this function to change the sent filename.
NameFunc func(systemName string) (attachmentName string)
}

// DirOptions contains the optional settings that
// `FileServer` and `Party#HandleDir` can use to serve files and assets.
type DirOptions struct {
Expand All @@ -37,9 +50,16 @@ type DirOptions struct {

// List the files inside the current requested directory if `IndexName` not found.
ShowList bool
// If `ShowList` is true then this function will be used instead of the default one to show the list of files of a current requested directory(dir).
// If `ShowList` is true then this function will be used instead
// of the default one to show the list of files of a current requested directory(dir).
// See `DirListRich` package-level function too.
DirList DirListFunc

// Files downloaded and saved locally.
// Gzip option MUST be false in order for this to work.
// TODO(@kataras): find a way to make it work.
Attachments Attachments

// When embedded.
Asset func(name string) ([]byte, error) // we need this to make it compatible os.File.
AssetInfo func(name string) (os.FileInfo, error) // we need this for range support on embedded files.
Expand Down Expand Up @@ -343,6 +363,7 @@ func FileServer(directory string, opts ...DirOptions) context.Handler {
// if false then check if the dev did something like `ctx.Gzip(true)`.
_, gzip = ctx.ResponseWriter().(*context.GzipResponseWriter)
}
// ctx.Gzip(options.Gzip)

f, err := fs.Open(name)
if err != nil {
Expand Down Expand Up @@ -454,7 +475,17 @@ func FileServer(directory string, opts ...DirOptions) context.Handler {
return
}

http.ServeContent(ctx.ResponseWriter(), ctx.Request(), info.Name(), info.ModTime(), f)
if options.Attachments.Enable {
destName := info.Name()
if nameFunc := options.Attachments.NameFunc; nameFunc != nil {
destName = nameFunc(destName)
}

ctx.ResponseWriter().Header().Set(context.ContentDispositionHeaderKey, "attachment;filename="+destName)
}

// If limit is 0 then same as ServeContent.
ctx.ServeContentWithRate(f, info.Name(), info.ModTime(), options.Attachments.Limit, options.Attachments.Burst)
if serveCode := ctx.GetStatusCode(); context.StatusCodeNotSuccessful(serveCode) {
plainStatusCode(ctx, serveCode)
return
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Expand Up @@ -24,7 +24,7 @@ require (
github.com/kataras/pio v0.0.8
github.com/kataras/sitemap v0.0.5
github.com/klauspost/compress v1.10.10
github.com/mediocregopher/radix/v3 v3.5.1
github.com/mediocregopher/radix/v3 v3.5.2
github.com/microcosm-cc/bluemonday v1.0.3
github.com/ryanuber/columnize v2.1.0+incompatible
github.com/schollz/closestmatch v2.1.0+incompatible
Expand All @@ -33,7 +33,7 @@ require (
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1
go.etcd.io/bbolt v1.3.5
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/net v0.0.0-20200625001655-4c5254603344
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae
golang.org/x/text v0.3.3
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
Expand Down

0 comments on commit 645da2b

Please sign in to comment.