init
This commit is contained in:
commit
159f47ff8a
12 changed files with 1217 additions and 0 deletions
90
godl/godl.go
Normal file
90
godl/godl.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Package godl provides utilities for serving files over HTTP, with MIME type
|
||||
// inference and support for setting Content-Disposition headers to control
|
||||
// whether files are served inline or as attachments.
|
||||
package godl
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
)
|
||||
|
||||
// Infer returns the MIME type of the file specified by the given path. It
|
||||
// first attempts to determine the MIME type using InferByMagic, and if
|
||||
// unsuccessful, it falls back to InferByExtension.
|
||||
func Infer(path string) string {
|
||||
m := InferByMagic(path)
|
||||
if m == "" {
|
||||
return InferByExtension(path)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// InferByExtension returns the MIME type of the file specified by the given
|
||||
// path using the file extension, or an empty string if no match is found.
|
||||
func InferByExtension(path string) string {
|
||||
return mime.TypeByExtension(filepath.Ext(path))
|
||||
}
|
||||
|
||||
// InferByMagic returns the MIME type of the file specified by the given
|
||||
// path using the mimetype module, or an empty string if no match is found.
|
||||
func InferByMagic(path string) string {
|
||||
if m, err := mimetype.DetectFile(path); err == nil {
|
||||
return m.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SetContentType sets the Content-Type header for the file specified by the
|
||||
// given path, inferred using the provided infer function.
|
||||
func SetContentType(w http.ResponseWriter, path string, infer func(string) string) {
|
||||
m := infer(path)
|
||||
if m == "" {
|
||||
m = "application/octet-stream"
|
||||
}
|
||||
w.Header().Set("Content-Type", m)
|
||||
}
|
||||
|
||||
// SetAttachment sets the Content-Disposition header to inform the client
|
||||
// that the file is an attachment, specifying the name of the file.
|
||||
func SetAttachment(w http.ResponseWriter, name string) {
|
||||
w.Header().Set(
|
||||
"Content-Disposition",
|
||||
"attachment; filename*=UTF-8''"+url.QueryEscape(name),
|
||||
)
|
||||
}
|
||||
|
||||
// ServeAttachment serves a file with the specified name and path, setting
|
||||
// the Content-Type header using the provided infer function and marking it as
|
||||
// an attachment by setting the Content-Disposition header.
|
||||
func ServeAttachment(w http.ResponseWriter, r *http.Request, path string, name string, infer func(string) string) {
|
||||
SetContentType(w, path, infer)
|
||||
SetAttachment(w, name)
|
||||
http.ServeFile(w, r, path)
|
||||
}
|
||||
|
||||
// ServeDownload serves a file with the specified name and path, setting the
|
||||
// Content-Type header using the provided infer function and determining
|
||||
// whether to show the file inline based on the list of inline types. If the
|
||||
// list is empty, all content types are treated as inline. Additionally, it
|
||||
// sets the Content-Disposition header accordingly.
|
||||
func ServeDownload(w http.ResponseWriter, r *http.Request, path string, name string, inlineTypes []string, infer func(string) string) {
|
||||
SetContentType(w, path, infer)
|
||||
|
||||
inline := len(inlineTypes) == 0
|
||||
for _, it := range inlineTypes {
|
||||
if it == w.Header().Get("Content-Type") {
|
||||
inline = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !inline {
|
||||
SetAttachment(w, name)
|
||||
}
|
||||
|
||||
http.ServeFile(w, r, path)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue