Skip to content

Commit

Permalink
Extend media MINE types to support attached audios, videos, documents…
Browse files Browse the repository at this point in the history
…, and more
  • Loading branch information
Thanh Nguyen committed Jun 27, 2023
1 parent 1e9d0f5 commit 7efbe92
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 21 deletions.
1 change: 1 addition & 0 deletions be-api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
/vendor
/data/
/qnd/
/Qnd/
/.project
/.vscode/
/.settings/
Expand Down
41 changes: 41 additions & 0 deletions be-api/config/conf.d/docms.conf
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,47 @@ docms {
gtag: ""
gtag: ${?GOOGLE_TAG}
}

## Media MIME types
media_mime {
# photo files
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".gif": "image/gif",
".svg": "image/svg+xml",
# music files
".aac": "audio/aac",
".mp3": "audio/mp3",
".wav": "audio/wav",
".wma": "audio/wma",
# video files
".mp4": "audio/mp4",
".mov": "audio/mov",
".avi": "audio/avi",
# documents
".xml": "application/xml",
".json": "application/json",
".pdf": "application/pdf",
".csv": "application/csv",
".tsv": "application/tsv",
".doc": "application/doc",
".docx": "application/docx",
".xls": "application/xls",
".xlsx": "application/xlsx",
".ppt": "application/ppt",
".pptx": "application/pptx",
".odm": "application/odm",
".odt": "application/odt",
".odp": "application/odp",
".ods": "application/ods",
}
# Override the whole media MIME types with env.MIME_TYPES
# env.MIME_TYPES must be a valid JSON-encoded map, for example '{".jpg": "image/jpeg", ".gif": "image/gif"}'
media_mime = ${?MIME_TYPES}
# Add (and override some) additional media MIME types with env.MIME_TYPES_ADD
# env.MIME_TYPES_ADD must be a valid JSON-encoded map, for example '{".mp4": "video/mp4"}'
media_mime_add = ${?MIME_TYPES_ADD}
}

api {
Expand Down
17 changes: 13 additions & 4 deletions be-api/src/docms/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,27 @@ func postInitEchoSetup(e *echo.Echo) error {
return fmt.Errorf("invalid frontend template directory: %s", feTemplateDir)
}

// register handler for image files attached to documents
e.GET("/img/:tid/:did/:img", serveImage)
e.GET(fePath+"/:tid/:did/:img", serveImage)
// register handler for media files attached to documents
mediaFileMime = confToMapStringString(goapi.AppConfig, "docms.media_mime")
mediaFileMimeAdd := confToMapStringString(goapi.AppConfig, "docms.media_mime_add")
for k, v := range mediaFileMimeAdd {
mediaFileMime[k] = v
}
path1 := "/img/:tid/:did/:media"
e.GET(path1, serveMedia)
path2 := fePath + "/:tid/:did/:media"
e.GET(path2, serveMedia)
log.Printf("[%s] allowed media files <%s> are serving at <%s> and <%s>", logLevelInfo, mediaFileMime, path1, path2)

// register handler for feeds
e.GET("/feeds", serveFeeds)

// redirect / to fePath/
e.GET("/", func(c echo.Context) error {
return c.Redirect(http.StatusFound, fePath+"/")
})

// map frontend's static assets
// map frontend static assets
dirContent, err := GetDirContent(feTemplateDir, nil)
if err != nil {
return err
Expand Down
36 changes: 19 additions & 17 deletions be-api/src/docms/custom_http_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,42 +37,44 @@ func _extractQueryParam(c echo.Context, paramName string, typ reflect.Type, defV
return v
}

var imgFileMime = map[string]string{
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".gif": "image/gif",
".svg": "image/svg+xml",
}
var mediaFileMime = make(map[string]string)

// var mediaFileMime = map[string]string{
// ".jpg": "image/jpeg",
// ".jpeg": "image/jpeg",
// ".png": "image/png",
// ".gif": "image/gif",
// ".svg": "image/svg+xml",
// }

var reFilename = regexp.MustCompile(`^[0-9a-zA-Z_\-\.]+$`)

func serveImage(c echo.Context) error {
func serveMedia(c echo.Context) error {
topicId := c.Param("tid")
docId := c.Param("did")
imgName := c.Param("img")
mediaName := c.Param("media")
topicMeta := gTopicMeta[topicId]
docMeta := gDocumentMeta[topicId+":"+docId]
if topicMeta == nil || docMeta == nil || !reFilename.MatchString(imgName) {
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, imgName))
if topicMeta == nil || docMeta == nil || !reFilename.MatchString(mediaName) {
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, mediaName))
}

ext := filepath.Ext(imgName)
mimeType, ok := imgFileMime[ext]
ext := filepath.Ext(mediaName)
mimeType, ok := mediaFileMime[ext]
if !ok {
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, imgName))
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, mediaName))
}

fileName := gDataDir + "/" + topicMeta.dir + "/" + docMeta.dir + "/" + imgName
fileName := gDataDir + "/" + topicMeta.dir + "/" + docMeta.dir + "/" + mediaName
buff, err := os.ReadFile(fileName)
if err != nil {
log.Printf("[%s] Error reading file [%s]: %s", logLevelError, fileName, err)
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, imgName))
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, mediaName))
}
fi, err := os.Stat(fileName)
if err != nil {
log.Printf("[%s] Error reading file info [%s]: %s", logLevelError, fileName, err)
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, imgName))
return c.HTML(http.StatusNotFound, fmt.Sprintf("Not found: %s/%s/%s", topicId, docId, mediaName))
}

c.Response().Header().Set("Cache-Control", "1024")
Expand Down
27 changes: 27 additions & 0 deletions be-api/src/docms/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/blevesearch/bleve/v2"
"github.com/btnguyen2k/consu/reddo"
hocon "github.com/go-akka/configuration"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -612,3 +613,29 @@ func GetDirContent(path string, filter func(entry os.DirEntry) bool) ([]os.DirEn
}
return result, nil
}

/*----------------------------------------------------------------------*/

func confToMapStringString(conf *hocon.Config, confKey string) map[string]string {
emptyMap := make(map[string]string)
confNode := conf.GetNode(confKey)
if confNode == nil {
return emptyMap
}
if confNode.IsObject() {
val, err := reddo.Convert(confNode.GetObject().Unwrapped(), reflect.TypeOf(emptyMap))
if err != nil || val == nil {
return emptyMap
}
return val.(map[string]string)
}
if confNode.IsString() {
var val map[string]string
err := json.Unmarshal([]byte(confNode.GetString()), &val)
if err != nil || val == nil {
return emptyMap
}
return val
}
return emptyMap
}

0 comments on commit 7efbe92

Please sign in to comment.