Finish the Abstract of Config.
This commit is contained in:
220
code/support/tank_config.go
Normal file
220
code/support/tank_config.go
Normal file
@ -0,0 +1,220 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/json-iterator/go"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
如果你需要在本地127.0.0.1创建默认的数据库和账号,使用以下语句。
|
||||
create database tank;
|
||||
grant all privileges on tank.* to tank identified by 'tank123';
|
||||
flush privileges;
|
||||
*/
|
||||
|
||||
//依赖外部定义的变量。
|
||||
type TankConfig struct {
|
||||
//默认监听端口号
|
||||
ServerPort int
|
||||
//网站是否已经完成安装
|
||||
Installed bool
|
||||
//上传的文件路径,要求不以/结尾。如果没有指定,默认在根目录下的matter文件夹中。eg: /var/www/matter
|
||||
MatterPath string
|
||||
//数据库连接信息。
|
||||
MysqlUrl string
|
||||
//配置文件中的项
|
||||
Item *ConfigItem
|
||||
}
|
||||
|
||||
//和tank.json文件中的键值一一对应。
|
||||
type ConfigItem struct {
|
||||
//默认监听端口号
|
||||
ServerPort int
|
||||
//上传的文件路径,要求不以/结尾。如果没有指定,默认在根目录下的matter文件夹中。eg: /var/www/matter
|
||||
MatterPath string
|
||||
//mysql相关配置。
|
||||
//数据库端口
|
||||
MysqlPort int
|
||||
//数据库Host
|
||||
MysqlHost string
|
||||
//数据库名字
|
||||
MysqlSchema string
|
||||
//用户名
|
||||
MysqlUsername string
|
||||
//密码
|
||||
MysqlPassword string
|
||||
}
|
||||
|
||||
//验证配置文件的正确性。
|
||||
func (this *ConfigItem) validate() bool {
|
||||
|
||||
if this.ServerPort == 0 {
|
||||
core.LOGGER.Error("ServerPort 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlUsername == "" {
|
||||
core.LOGGER.Error("MysqlUsername 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlPassword == "" {
|
||||
core.LOGGER.Error("MysqlPassword 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlHost == "" {
|
||||
core.LOGGER.Error("MysqlHost 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlPort == 0 {
|
||||
core.LOGGER.Error("MysqlPort 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlSchema == "" {
|
||||
core.LOGGER.Error("MysqlSchema 未配置")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
//验证配置文件是否完好
|
||||
func (this *TankConfig) Init() {
|
||||
|
||||
//JSON初始化
|
||||
jsoniter.RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||
//如果使用time.UTC,那么时间会相差8小时
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.Local)
|
||||
if err != nil {
|
||||
iter.Error = err
|
||||
return
|
||||
}
|
||||
*((*time.Time)(ptr)) = t
|
||||
})
|
||||
|
||||
jsoniter.RegisterTypeEncoderFunc("time.Time", func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||
t := *((*time.Time)(ptr))
|
||||
//如果使用time.UTC,那么时间会相差8小时
|
||||
stream.WriteString(t.Local().Format("2006-01-02 15:04:05"))
|
||||
}, nil)
|
||||
|
||||
//默认从6010端口启动
|
||||
this.ServerPort = 6010
|
||||
|
||||
this.ReadFromConfigFile()
|
||||
|
||||
}
|
||||
|
||||
//系统如果安装好了就调用这个方法。
|
||||
func (this *TankConfig) ReadFromConfigFile() {
|
||||
|
||||
//读取配置文件
|
||||
filePath := util.GetConfPath() + "/tank.json"
|
||||
content, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
core.LOGGER.Warn("无法找到配置文件:%s 即将进入安装过程!", filePath)
|
||||
this.Installed = false
|
||||
} else {
|
||||
this.Item = &ConfigItem{}
|
||||
core.LOGGER.Warn("读取配置文件:%s", filePath)
|
||||
err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(content, this.Item)
|
||||
if err != nil {
|
||||
core.LOGGER.Error("配置文件格式错误! 即将进入安装过程!")
|
||||
this.Installed = false
|
||||
return
|
||||
}
|
||||
|
||||
//验证项是否齐全
|
||||
itemValidate := this.Item.validate()
|
||||
if !itemValidate {
|
||||
core.LOGGER.Error("配置文件信息不齐全! 即将进入安装过程!")
|
||||
this.Installed = false
|
||||
return
|
||||
}
|
||||
|
||||
//使用配置项中的文件路径
|
||||
if this.Item.MatterPath == "" {
|
||||
this.MatterPath = util.GetHomePath() + "/matter"
|
||||
} else {
|
||||
this.MatterPath = this.Item.MatterPath
|
||||
}
|
||||
util.MakeDirAll(this.MatterPath)
|
||||
|
||||
//使用配置项中的端口
|
||||
if this.Item.ServerPort != 0 {
|
||||
this.ServerPort = this.Item.ServerPort
|
||||
}
|
||||
|
||||
this.MysqlUrl = util.GetMysqlUrl(this.Item.MysqlPort, this.Item.MysqlHost, this.Item.MysqlSchema, this.Item.MysqlUsername, this.Item.MysqlPassword)
|
||||
this.Installed = true
|
||||
|
||||
core.LOGGER.Info("使用配置文件:%s", filePath)
|
||||
core.LOGGER.Info("上传文件存放路径:%s", this.MatterPath)
|
||||
}
|
||||
}
|
||||
|
||||
//是否已经安装
|
||||
func (this *TankConfig) IsInstalled() bool {
|
||||
return this.Installed
|
||||
}
|
||||
|
||||
//启动端口
|
||||
func (this *TankConfig) GetServerPort() int {
|
||||
return this.ServerPort
|
||||
}
|
||||
|
||||
//获取mysql链接
|
||||
func (this *TankConfig) GetMysqlUrl() string {
|
||||
return this.MysqlUrl
|
||||
}
|
||||
|
||||
//文件存放路径
|
||||
func (this *TankConfig) GetMatterPath() string {
|
||||
return this.MatterPath
|
||||
}
|
||||
|
||||
//完成安装过程,主要是要将配置写入到文件中
|
||||
func (this *TankConfig) FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string) {
|
||||
|
||||
var configItem = &ConfigItem{
|
||||
//默认监听端口号
|
||||
ServerPort: core.CONFIG.GetServerPort(),
|
||||
//上传的文件路径,要求不以/结尾。如果没有指定,默认在根目录下的matter文件夹中。eg: /var/www/matter
|
||||
MatterPath: core.CONFIG.GetMatterPath(),
|
||||
//mysql相关配置。
|
||||
//数据库端口
|
||||
MysqlPort: mysqlPort,
|
||||
//数据库Host
|
||||
MysqlHost: mysqlHost,
|
||||
//数据库名字
|
||||
MysqlSchema: mysqlSchema,
|
||||
//用户名
|
||||
MysqlUsername: mysqlUsername,
|
||||
//密码
|
||||
MysqlPassword: mysqlPassword,
|
||||
}
|
||||
|
||||
//用json的方式输出返回值。为了让格式更好看。
|
||||
jsonStr, _ := jsoniter.ConfigCompatibleWithStandardLibrary.MarshalIndent(configItem, "", " ")
|
||||
|
||||
//写入到配置文件中(不能使用os.O_APPEND 否则会追加)
|
||||
filePath := util.GetConfPath() + "/tank.json"
|
||||
f, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0777)
|
||||
util.PanicError(err)
|
||||
_, err = f.Write(jsonStr)
|
||||
util.PanicError(err)
|
||||
err = f.Close()
|
||||
util.PanicError(err)
|
||||
|
||||
this.ReadFromConfigFile()
|
||||
|
||||
}
|
@ -1 +1,220 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/rest"
|
||||
"github.com/eyebluecn/tank/code/tool/cache"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
//上下文,管理数据库连接,管理所有路由请求,管理所有的单例component.
|
||||
type TankContext struct {
|
||||
//数据库连接
|
||||
db *gorm.DB
|
||||
//session缓存
|
||||
SessionCache *cache.Table
|
||||
//各类的Bean Map。这里面是包含ControllerMap中所有元素
|
||||
BeanMap map[string]core.IBean
|
||||
//只包含了Controller的map
|
||||
ControllerMap map[string]core.IController
|
||||
//处理所有路由请求
|
||||
Router *TankRouter
|
||||
}
|
||||
|
||||
//初始化上下文
|
||||
func (this *TankContext) Init() {
|
||||
|
||||
//创建一个用于存储session的缓存。
|
||||
this.SessionCache = cache.NewTable()
|
||||
|
||||
//初始化Map
|
||||
this.BeanMap = make(map[string]core.IBean)
|
||||
this.ControllerMap = make(map[string]core.IController)
|
||||
|
||||
//注册各类Beans.在这个方法里面顺便把Controller装入ControllerMap中去。
|
||||
this.registerBeans()
|
||||
|
||||
//初始化每个bean.
|
||||
this.initBeans()
|
||||
|
||||
//初始化Router. 这个方法要在Bean注册好了之后才能。
|
||||
this.Router = NewRouter()
|
||||
|
||||
//如果数据库信息配置好了,就直接打开数据库连接 同时执行Bean的ConfigPost方法
|
||||
this.InstallOk()
|
||||
|
||||
}
|
||||
|
||||
//获取数据库对象
|
||||
func (this *TankContext) GetDB() *gorm.DB {
|
||||
return this.db
|
||||
}
|
||||
|
||||
func (this *TankContext) GetSessionCache() *cache.Table {
|
||||
return this.SessionCache
|
||||
}
|
||||
|
||||
func (this *TankContext) GetControllerMap() map[string]core.IController {
|
||||
return this.ControllerMap
|
||||
}
|
||||
|
||||
func (this *TankContext) Cleanup() {
|
||||
for _, bean := range this.BeanMap {
|
||||
bean.Cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
//响应http的能力
|
||||
func (this *TankContext) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
this.Router.ServeHTTP(writer, request)
|
||||
}
|
||||
|
||||
func (this *TankContext) OpenDb() {
|
||||
|
||||
var err error = nil
|
||||
this.db, err = gorm.Open("mysql", core.CONFIG.GetMysqlUrl())
|
||||
|
||||
if err != nil {
|
||||
core.LOGGER.Panic("failed to connect mysql database")
|
||||
}
|
||||
|
||||
//是否打开sql日志(在调试阶段可以打开,以方便查看执行的SQL)
|
||||
this.db.LogMode(false)
|
||||
}
|
||||
|
||||
func (this *TankContext) CloseDb() {
|
||||
|
||||
if this.db != nil {
|
||||
err := this.db.Close()
|
||||
if err != nil {
|
||||
core.LOGGER.Error("关闭数据库连接出错 %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//注册一个Bean
|
||||
func (this *TankContext) registerBean(bean core.IBean) {
|
||||
|
||||
typeOf := reflect.TypeOf(bean)
|
||||
typeName := typeOf.String()
|
||||
|
||||
if element, ok := bean.(core.IBean); ok {
|
||||
|
||||
err := fmt.Sprintf("【%s】已经被注册了,跳过。", typeName)
|
||||
if _, ok := this.BeanMap[typeName]; ok {
|
||||
core.LOGGER.Error(fmt.Sprintf(err))
|
||||
} else {
|
||||
this.BeanMap[typeName] = element
|
||||
|
||||
//看看是不是controller类型,如果是,那么单独放在ControllerMap中。
|
||||
if controller, ok1 := bean.(core.IController); ok1 {
|
||||
this.ControllerMap[typeName] = controller
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
core.LOGGER.Panic("注册的【%s】不是Bean类型。", typeName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//注册各个Beans
|
||||
func (this *TankContext) registerBeans() {
|
||||
|
||||
//alien
|
||||
this.registerBean(new(rest.AlienController))
|
||||
this.registerBean(new(rest.AlienService))
|
||||
|
||||
//dashboard
|
||||
this.registerBean(new(rest.DashboardController))
|
||||
this.registerBean(new(rest.DashboardDao))
|
||||
this.registerBean(new(rest.DashboardService))
|
||||
|
||||
//downloadToken
|
||||
this.registerBean(new(rest.DownloadTokenDao))
|
||||
|
||||
//imageCache
|
||||
this.registerBean(new(rest.ImageCacheController))
|
||||
this.registerBean(new(rest.ImageCacheDao))
|
||||
this.registerBean(new(rest.ImageCacheService))
|
||||
|
||||
//install
|
||||
this.registerBean(new(rest.InstallController))
|
||||
|
||||
//matter
|
||||
this.registerBean(new(rest.MatterController))
|
||||
this.registerBean(new(rest.MatterDao))
|
||||
this.registerBean(new(rest.MatterService))
|
||||
|
||||
//preference
|
||||
this.registerBean(new(rest.PreferenceController))
|
||||
this.registerBean(new(rest.PreferenceDao))
|
||||
this.registerBean(new(rest.PreferenceService))
|
||||
|
||||
//footprint
|
||||
this.registerBean(new(rest.FootprintController))
|
||||
this.registerBean(new(rest.FootprintDao))
|
||||
this.registerBean(new(rest.FootprintService))
|
||||
|
||||
//session
|
||||
this.registerBean(new(rest.SessionDao))
|
||||
this.registerBean(new(rest.SessionService))
|
||||
|
||||
//uploadToken
|
||||
this.registerBean(new(rest.UploadTokenDao))
|
||||
|
||||
//user
|
||||
this.registerBean(new(rest.UserController))
|
||||
this.registerBean(new(rest.UserDao))
|
||||
this.registerBean(new(rest.UserService))
|
||||
|
||||
//webdav
|
||||
this.registerBean(new(rest.DavController))
|
||||
this.registerBean(new(rest.DavService))
|
||||
|
||||
}
|
||||
|
||||
//从Map中获取某个Bean.
|
||||
func (this *TankContext) GetBean(bean core.IBean) core.IBean {
|
||||
|
||||
typeOf := reflect.TypeOf(bean)
|
||||
typeName := typeOf.String()
|
||||
|
||||
if val, ok := this.BeanMap[typeName]; ok {
|
||||
return val
|
||||
} else {
|
||||
core.LOGGER.Panic("【%s】没有注册。", typeName)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//初始化每个Bean
|
||||
func (this *TankContext) initBeans() {
|
||||
|
||||
for _, bean := range this.BeanMap {
|
||||
bean.Init()
|
||||
}
|
||||
}
|
||||
|
||||
//系统如果安装好了就调用这个方法。
|
||||
func (this *TankContext) InstallOk() {
|
||||
|
||||
if core.CONFIG.IsInstalled() {
|
||||
this.OpenDb()
|
||||
|
||||
for _, bean := range this.BeanMap {
|
||||
bean.Bootstrap()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//销毁的方法
|
||||
func (this *TankContext) Destroy() {
|
||||
this.CloseDb()
|
||||
}
|
||||
|
211
code/support/tank_router.go
Normal file
211
code/support/tank_router.go
Normal file
@ -0,0 +1,211 @@
|
||||
package support
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/rest"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/json-iterator/go"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//用于处理所有前来的请求
|
||||
type TankRouter struct {
|
||||
installController *rest.InstallController
|
||||
footprintService *rest.FootprintService
|
||||
userService *rest.UserService
|
||||
routeMap map[string]func(writer http.ResponseWriter, request *http.Request)
|
||||
installRouteMap map[string]func(writer http.ResponseWriter, request *http.Request)
|
||||
}
|
||||
|
||||
//构造方法
|
||||
func NewRouter() *TankRouter {
|
||||
router := &TankRouter{
|
||||
routeMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
|
||||
installRouteMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
|
||||
}
|
||||
|
||||
//installController.
|
||||
b := core.CONTEXT.GetBean(router.installController)
|
||||
if b, ok := b.(*rest.InstallController); ok {
|
||||
router.installController = b
|
||||
}
|
||||
|
||||
//装载userService.
|
||||
b = core.CONTEXT.GetBean(router.userService)
|
||||
if b, ok := b.(*rest.UserService); ok {
|
||||
router.userService = b
|
||||
}
|
||||
|
||||
//装载footprintService
|
||||
b = core.CONTEXT.GetBean(router.footprintService)
|
||||
if b, ok := b.(*rest.FootprintService); ok {
|
||||
router.footprintService = b
|
||||
}
|
||||
|
||||
//将Controller中的路由规则装载进来,InstallController中的除外
|
||||
for _, controller := range core.CONTEXT.GetControllerMap() {
|
||||
|
||||
if controller == router.installController {
|
||||
routes := controller.RegisterRoutes()
|
||||
for k, v := range routes {
|
||||
router.installRouteMap[k] = v
|
||||
}
|
||||
} else {
|
||||
routes := controller.RegisterRoutes()
|
||||
for k, v := range routes {
|
||||
router.routeMap[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return router
|
||||
|
||||
}
|
||||
|
||||
//全局的异常捕获
|
||||
func (this *TankRouter) GlobalPanicHandler(writer http.ResponseWriter, request *http.Request, startTime time.Time) {
|
||||
if err := recover(); err != nil {
|
||||
|
||||
core.LOGGER.Error("错误: %v", err)
|
||||
|
||||
var webResult *result.WebResult = nil
|
||||
if value, ok := err.(string); ok {
|
||||
//一个字符串,默认是请求错误。
|
||||
webResult = result.CustomWebResult(result.CODE_WRAPPER_BAD_REQUEST, value)
|
||||
} else if value, ok := err.(*result.WebResult); ok {
|
||||
//一个WebResult对象
|
||||
webResult = value
|
||||
} else if value, ok := err.(*result.CodeWrapper); ok {
|
||||
//一个WebResult对象
|
||||
webResult = result.ConstWebResult(value)
|
||||
} else if value, ok := err.(error); ok {
|
||||
//一个普通的错误对象
|
||||
webResult = result.CustomWebResult(result.CODE_WRAPPER_UNKNOWN, value.Error())
|
||||
} else {
|
||||
//其他不能识别的内容
|
||||
webResult = result.ConstWebResult(result.CODE_WRAPPER_UNKNOWN)
|
||||
}
|
||||
|
||||
//修改http code码
|
||||
writer.WriteHeader(result.FetchHttpStatus(webResult.Code))
|
||||
|
||||
//输出的是json格式 返回的内容申明是json,utf-8
|
||||
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
//用json的方式输出返回值。
|
||||
b, _ := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
|
||||
|
||||
//写到输出流中
|
||||
_, err := fmt.Fprintf(writer, string(b))
|
||||
if err != nil {
|
||||
fmt.Printf("输出结果时出错了\n")
|
||||
}
|
||||
|
||||
//错误情况记录。
|
||||
go util.RunWithRecovery(func() {
|
||||
this.footprintService.Trace(writer, request, time.Now().Sub(startTime), false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//让Router具有处理请求的功能。
|
||||
func (this *TankRouter) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
//每个请求的入口在这里
|
||||
//全局异常处理。
|
||||
defer this.GlobalPanicHandler(writer, request, startTime)
|
||||
|
||||
path := request.URL.Path
|
||||
if strings.HasPrefix(path, "/api") {
|
||||
|
||||
//对于IE浏览器,会自动缓存,因此设置不缓存Header.
|
||||
writer.Header().Set("Pragma", "No-cache")
|
||||
writer.Header().Set("Cache-Control", "no-cache")
|
||||
writer.Header().Set("Expires", "0")
|
||||
|
||||
if core.CONFIG.IsInstalled() {
|
||||
//已安装的模式
|
||||
|
||||
//统一处理用户的身份信息。
|
||||
this.userService.PreHandle(writer, request)
|
||||
|
||||
if handler, ok := this.routeMap[path]; ok {
|
||||
handler(writer, request)
|
||||
} else {
|
||||
//直接将请求扔给每个controller,看看他们能不能处理,如果都不能处理,那就抛出找不到的错误
|
||||
canHandle := false
|
||||
for _, controller := range core.CONTEXT.GetControllerMap() {
|
||||
if handler, exist := controller.HandleRoutes(writer, request); exist {
|
||||
canHandle = true
|
||||
handler(writer, request)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !canHandle {
|
||||
panic(result.CustomWebResult(result.CODE_WRAPPER_NOT_FOUND, fmt.Sprintf("没有找到能够处理%s的方法", path)))
|
||||
}
|
||||
}
|
||||
|
||||
//正常的访问记录会落到这里。
|
||||
go util.RunWithRecovery(func() {
|
||||
this.footprintService.Trace(writer, request, time.Now().Sub(startTime), true)
|
||||
})
|
||||
|
||||
} else {
|
||||
//未安装模式
|
||||
if handler, ok := this.installRouteMap[path]; ok {
|
||||
handler(writer, request)
|
||||
} else {
|
||||
panic(result.ConstWebResult(result.CODE_WRAPPER_NOT_INSTALLED))
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
//当作静态资源处理。默认从当前文件下面的static文件夹中取东西。
|
||||
dir := util.GetHtmlPath()
|
||||
|
||||
requestURI := request.RequestURI
|
||||
if requestURI == "" || request.RequestURI == "/" {
|
||||
requestURI = "index.html"
|
||||
}
|
||||
|
||||
filePath := dir + requestURI
|
||||
exists, _ := util.PathExists(filePath)
|
||||
if !exists {
|
||||
filePath = dir + "/index.html"
|
||||
exists, _ = util.PathExists(filePath)
|
||||
if !exists {
|
||||
panic(fmt.Sprintf("404 not found:%s", filePath))
|
||||
}
|
||||
}
|
||||
|
||||
writer.Header().Set("Content-Type", util.GetMimeType(util.GetExtension(filePath)))
|
||||
|
||||
diskFile, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
panic("cannot get file.")
|
||||
}
|
||||
defer func() {
|
||||
err := diskFile.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
_, err = io.Copy(writer, diskFile)
|
||||
if err != nil {
|
||||
panic("cannot get file.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user